* character.c, charset.c, chartab.c: Use bool for booleans.
[bpt/emacs.git] / src / charset.c
index 2451c55..0673790 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic character set support.
-   Copyright (C) 2001-2011  Free Software Foundation, Inc.
+   Copyright (C) 2001-2012  Free Software Foundation, Inc.
    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
      2005, 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
@@ -26,12 +26,14 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 
+#define CHARSET_INLINE EXTERN_INLINE
+
 #include <stdio.h>
 #include <unistd.h>
-#include <ctype.h>
 #include <limits.h>
 #include <sys/types.h>
 #include <setjmp.h>
+#include <c-ctype.h>
 #include "lisp.h"
 #include "character.h"
 #include "charset.h"
@@ -163,13 +165,13 @@ static struct
   /* 1 iff the following table is used for encoder.  */
   short for_encoder;
 
-  /* When the following table is used for encoding, mininum and
-     maxinum character of the current charset.  */
+  /* When the following table is used for encoding, minimum and
+     maximum character of the current charset.  */
   int min_char, max_char;
 
-  /* A Unicode character correspoinding to the code indice 0 (i.e. the
+  /* A Unicode character corresponding to the code index 0 (i.e. the
      minimum code-point) of the current charset, or -1 if the code
-     indice 0 is not a Unicode character.  This is checked when
+     index 0 is not a Unicode character.  This is checked when
      table.encoder[CHAR] is zero.  */
   int zero_index_char;
 
@@ -213,7 +215,7 @@ static struct
 
 /* Set to 1 to warn that a charset map is loaded and thus a buffer
    text and a string data may be relocated.  */
-int charset_map_loaded;
+bool charset_map_loaded;
 
 struct charset_map_entries
 {
@@ -254,7 +256,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
 {
   Lisp_Object vec IF_LINT (= Qnil), table IF_LINT (= Qnil);
   unsigned max_code = CHARSET_MAX_CODE (charset);
-  int ascii_compatible_p = charset->ascii_compatible_p;
+  bool ascii_compatible_p = charset->ascii_compatible_p;
   int min_char, max_char, nonascii_min_char;
   int i;
   unsigned char *fast_map = charset->fast_map;
@@ -272,8 +274,8 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
                {
                  int n = CODE_POINT_TO_INDEX (charset, max_code) + 1;
 
-                 vec = CHARSET_DECODER (charset)
-                   = Fmake_vector (make_number (n), make_number (-1));
+                 vec = Fmake_vector (make_number (n), make_number (-1));
+                 set_charset_attr (charset, charset_decoder, vec);
                }
              else
                {
@@ -285,16 +287,16 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
          else
            {
              table = Fmake_char_table (Qnil, Qnil);
-             if (charset->method == CHARSET_METHOD_MAP)
-               CHARSET_ENCODER (charset) = table;
-             else
-               CHARSET_DEUNIFIER (charset) = table;
+             set_charset_attr (charset,
+                               (charset->method == CHARSET_METHOD_MAP
+                                ? charset_encoder : charset_deunifier),
+                               table);
            }
        }
       else
        {
          if (! temp_charset_work)
-           temp_charset_work = xmalloc (sizeof (*temp_charset_work));
+           temp_charset_work = xmalloc (sizeof *temp_charset_work);
          if (control_flag == 1)
            {
              memset (temp_charset_work->table.decoder, -1,
@@ -421,7 +423,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
    paying attention to comment character '#'.  */
 
 static inline unsigned
-read_hex (FILE *fp, int *eof, int *overflow)
+read_hex (FILE *fp, bool *eof, bool *overflow)
 {
   int c;
   unsigned n;
@@ -444,7 +446,7 @@ read_hex (FILE *fp, int *eof, int *overflow)
       return 0;
     }
   n = 0;
-  while (isxdigit (c = getc (fp)))
+  while (c_isxdigit (c = getc (fp)))
     {
       if (UINT_MAX >> 4 < n)
        *overflow = 1;
@@ -501,8 +503,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
 
   /* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
      large (larger than MAX_ALLOCA).  */
-  SAFE_ALLOCA (head, struct charset_map_entries *,
-              sizeof (struct charset_map_entries));
+  head = SAFE_ALLOCA (sizeof *head);
   entries = head;
   memset (entries, 0, sizeof (struct charset_map_entries));
 
@@ -511,7 +512,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
     {
       unsigned from, to, c;
       int idx;
-      int eof = 0, overflow = 0;
+      bool eof = 0, overflow = 0;
 
       from = read_hex (fp, &eof, &overflow);
       if (eof)
@@ -533,8 +534,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
 
       if (n_entries > 0 && (n_entries % 0x10000) == 0)
        {
-         SAFE_ALLOCA (entries->next, struct charset_map_entries *,
-                      sizeof (struct charset_map_entries));
+         entries->next = SAFE_ALLOCA (sizeof *entries->next);
          entries = entries->next;
          memset (entries, 0, sizeof (struct charset_map_entries));
          n_entries = 0;
@@ -570,8 +570,7 @@ load_charset_map_from_vector (struct charset *charset, Lisp_Object vec, int cont
 
   /* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
      large (larger than MAX_ALLOCA).  */
-  SAFE_ALLOCA (head, struct charset_map_entries *,
-              sizeof (struct charset_map_entries));
+  head = SAFE_ALLOCA (sizeof *head);
   entries = head;
   memset (entries, 0, sizeof (struct charset_map_entries));
 
@@ -602,8 +601,7 @@ load_charset_map_from_vector (struct charset *charset, Lisp_Object vec, int cont
 
       if (n_entries > 0 && (n_entries % 0x10000) == 0)
        {
-         SAFE_ALLOCA (entries->next, struct charset_map_entries *,
-                      sizeof (struct charset_map_entries));
+         entries->next = SAFE_ALLOCA (sizeof *entries->next);
          entries = entries->next;
          memset (entries, 0, sizeof (struct charset_map_entries));
        }
@@ -719,10 +717,8 @@ map_charset_chars (void (*c_function)(Lisp_Object, Lisp_Object), Lisp_Object fun
                   Lisp_Object arg, struct charset *charset, unsigned from, unsigned to)
 {
   Lisp_Object range;
-  int partial;
-
-  partial = (from > CHARSET_MIN_CODE (charset)
-            || to < CHARSET_MAX_CODE (charset));
+  bool partial = (from > CHARSET_MIN_CODE (charset)
+                 || to < CHARSET_MAX_CODE (charset));
 
   if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET)
     {
@@ -857,7 +853,7 @@ usage: (define-charset-internal ...)  */)
   struct charset charset;
   int id;
   int dimension;
-  int new_definition_p;
+  bool new_definition_p;
   int nchars;
 
   if (nargs != charset_arg_max)
@@ -878,9 +874,9 @@ usage: (define-charset-internal ...)  */)
 
       min_byte_obj = Faref (val, make_number (i * 2));
       max_byte_obj = Faref (val, make_number (i * 2 + 1));
-      CHECK_RANGED_INTEGER (0, min_byte_obj, 255);
+      CHECK_RANGED_INTEGER (min_byte_obj, 0, 255);
       min_byte = XINT (min_byte_obj);
-      CHECK_RANGED_INTEGER (min_byte, max_byte_obj, 255);
+      CHECK_RANGED_INTEGER (max_byte_obj, min_byte, 255);
       max_byte = XINT (max_byte_obj);
       charset.code_space[i * 4] = min_byte;
       charset.code_space[i * 4 + 1] = max_byte;
@@ -898,7 +894,7 @@ usage: (define-charset-internal ...)  */)
     charset.dimension = dimension;
   else
     {
-      CHECK_RANGED_INTEGER (1, val, 4);
+      CHECK_RANGED_INTEGER (val, 1, 4);
       charset.dimension = XINT (val);
     }
 
@@ -912,8 +908,7 @@ usage: (define-charset-internal ...)  */)
 
   if (! charset.code_linear_p)
     {
-      charset.code_space_mask = (unsigned char *) xmalloc (256);
-      memset (charset.code_space_mask, 0, 256);
+      charset.code_space_mask = xzalloc (256);
       for (i = 0; i < 4; i++)
        for (j = charset.code_space[i * 4]; j <= charset.code_space[i * 4 + 1];
             j++)
@@ -991,7 +986,7 @@ usage: (define-charset-internal ...)  */)
     charset.iso_revision = -1;
   else
     {
-      CHECK_RANGED_INTEGER (-1, val, 63);
+      CHECK_RANGED_INTEGER (val, -1, 63);
       charset.iso_revision = XINT (val);
     }
 
@@ -1134,7 +1129,7 @@ usage: (define-charset-internal ...)  */)
     {
       new_definition_p = 0;
       id = XFASTINT (CHARSET_SYMBOL_ID (args[charset_arg_name]));
-      HASH_VALUE (hash_table, charset.hash_index) = attrs;
+      set_hash_value_slot (hash_table, charset.hash_index, attrs);
     }
   else
     {
@@ -1154,10 +1149,10 @@ usage: (define-charset-internal ...)  */)
                     sizeof *charset_table);
          memcpy (new_table, charset_table, old_size * sizeof *new_table);
          charset_table = new_table;
-         /* FIXME: Doesn't this leak memory?  The old charset_table becomes
-            unreachable.  It could be that this is intentional, because the
-            old charset table may be in a dumped emacs, and reallocating such
-            a table may not work.  If the memory leak is intentional, a
+         /* FIXME: This leaks memory, as the old charset_table becomes
+            unreachable.  If the old charset table is charset_table_init
+            then this leak is intentional; otherwise, it's unclear.
+            If the latter memory leak is intentional, a
             comment should be added to explain this.  If not, the old
             charset_table should be freed, by passing it as the 1st argument
             to xpalloc and removing the memcpy.  */
@@ -1253,12 +1248,11 @@ define_charset_internal (Lisp_Object name,
                         const char *code_space_chars,
                         unsigned min_code, unsigned max_code,
                         int iso_final, int iso_revision, int emacs_mule_id,
-                        int ascii_compatible, int supplementary,
+                        bool ascii_compatible, bool supplementary,
                         int code_offset)
 {
   const unsigned char *code_space = (const unsigned char *) code_space_chars;
   Lisp_Object args[charset_arg_max];
-  Lisp_Object plist[14];
   Lisp_Object val;
   int i;
 
@@ -1284,22 +1278,22 @@ define_charset_internal (Lisp_Object name,
   args[charset_arg_superset] = Qnil;
   args[charset_arg_unify_map] = Qnil;
 
-  plist[0] = intern_c_string (":name");
-  plist[1] = args[charset_arg_name];
-  plist[2] = intern_c_string (":dimension");
-  plist[3] = args[charset_arg_dimension];
-  plist[4] = intern_c_string (":code-space");
-  plist[5] = args[charset_arg_code_space];
-  plist[6] = intern_c_string (":iso-final-char");
-  plist[7] = args[charset_arg_iso_final];
-  plist[8] = intern_c_string (":emacs-mule-id");
-  plist[9] = args[charset_arg_emacs_mule_id];
-  plist[10] = intern_c_string (":ascii-compatible-p");
-  plist[11] = args[charset_arg_ascii_compatible_p];
-  plist[12] = intern_c_string (":code-offset");
-  plist[13] = args[charset_arg_code_offset];
-
-  args[charset_arg_plist] = Flist (14, plist);
+  args[charset_arg_plist] =
+    listn (CONSTYPE_HEAP, 14,
+          intern_c_string (":name"),
+          args[charset_arg_name],
+          intern_c_string (":dimension"),
+          args[charset_arg_dimension],
+          intern_c_string (":code-space"),
+          args[charset_arg_code_space],
+          intern_c_string (":iso-final-char"),
+          args[charset_arg_iso_final],
+          intern_c_string (":emacs-mule-id"),
+          args[charset_arg_emacs_mule_id],
+          intern_c_string (":ascii-compatible-p"),
+          args[charset_arg_ascii_compatible_p],
+          intern_c_string (":code-offset"),
+          args[charset_arg_code_offset]);
   Fdefine_charset_internal (charset_arg_max, args);
 
   return XINT (CHARSET_SYMBOL_ID (name));
@@ -1338,7 +1332,7 @@ DEFUN ("set-charset-plist", Fset_charset_plist, Sset_charset_plist, 2, 2, 0,
   Lisp_Object attrs;
 
   CHECK_CHARSET_GET_ATTR (charset, attrs);
-  CHARSET_ATTR_PLIST (attrs) = plist;
+  ASET (attrs, charset_plist, plist);
   return plist;
 }
 
@@ -1377,7 +1371,7 @@ Optional third argument DEUNIFY, if non-nil, means to de-unify CHARSET.  */)
        {
          if (! STRINGP (unify_map) && ! VECTORP (unify_map))
            signal_error ("Bad unify-map", unify_map);
-         CHARSET_UNIFY_MAP (cs) = unify_map;
+         set_charset_attr (cs, charset_unify_map, unify_map);
        }
       if (NILP (Vchar_unify_table))
        Vchar_unify_table = Fmake_char_table (Qnil, Qnil);
@@ -1452,7 +1446,7 @@ if CHARSET is designated instead.  */)
   (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char, Lisp_Object charset)
 {
   int id;
-  int chars_flag;
+  bool chars_flag;
 
   CHECK_CHARSET_GET_ID (charset, id);
   check_iso_charset_parameter (dimension, chars, final_char);
@@ -1503,7 +1497,9 @@ string_xstring_p (Lisp_Object string)
    It may lookup a translation table TABLE if supplied.  */
 
 static void
-find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars, ptrdiff_t nbytes, Lisp_Object charsets, Lisp_Object table, int multibyte)
+find_charsets_in_text (const unsigned char *ptr, ptrdiff_t nchars,
+                      ptrdiff_t nbytes, Lisp_Object charsets,
+                      Lisp_Object table, bool multibyte)
 {
   const unsigned char *pend = ptr + nbytes;
 
@@ -1553,7 +1549,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'.  */)
   ptrdiff_t from, from_byte, to, stop, stop_byte;
   int i;
   Lisp_Object val;
-  int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
+  bool multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
 
   validate_region (&beg, &end);
   from = XFASTINT (beg);
@@ -1633,6 +1629,12 @@ maybe_unify_char (int c, Lisp_Object val)
     return c;
 
   CHECK_CHARSET_GET_CHARSET (val, charset);
+#ifdef REL_ALLOC
+  /* The call to load_charset below can allocate memory, which screws
+     callers of this function through STRING_CHAR_* macros that hold C
+     pointers to buffer text, if REL_ALLOC is used.  */
+  r_alloc_inhibit_buffer_relocation (1);
+#endif
   load_charset (charset, 1);
   if (! inhibit_load_charset_map)
     {
@@ -1648,11 +1650,14 @@ maybe_unify_char (int c, Lisp_Object val)
       if (unified > 0)
        c = unified;
     }
+#ifdef REL_ALLOC
+  r_alloc_inhibit_buffer_relocation (0);
+#endif
   return c;
 }
 
 
-/* Return a character correponding to the code-point CODE of
+/* Return a character corresponding to the code-point CODE of
    CHARSET.  */
 
 int
@@ -1730,7 +1735,7 @@ decode_char (struct charset *charset, unsigned int code)
 /* Variable used temporarily by the macro ENCODE_CHAR.  */
 Lisp_Object charset_work;
 
-/* Return a code-point of CHAR in CHARSET.  If CHAR doesn't belong to
+/* Return a code-point of C in CHARSET.  If C doesn't belong to
    CHARSET, return CHARSET_INVALID_CODE (CHARSET).  If STRICT is true,
    use CHARSET's strict_max_char instead of max_char.  */
 
@@ -1832,8 +1837,9 @@ encode_char (struct charset *charset, int c)
     }
   else                         /* method == CHARSET_METHOD_OFFSET */
     {
-      code = c - CHARSET_CODE_OFFSET (charset);
-      code = INDEX_TO_CODE_POINT (charset, code);
+      unsigned code_index = c - CHARSET_CODE_OFFSET (charset);
+
+      code = INDEX_TO_CODE_POINT (charset, code_index);
     }
 
   return code;
@@ -1972,7 +1978,7 @@ is specified.  */)
 struct charset *
 char_charset (int c, Lisp_Object charset_list, unsigned int *code_return)
 {
-  int maybe_null = 0;
+  bool maybe_null = 0;
 
   if (NILP (charset_list))
     charset_list = Vcharset_ordered_list;
@@ -2073,7 +2079,7 @@ that case, find the charset from what supported by that coding system.  */)
 DEFUN ("charset-after", Fcharset_after, Scharset_after, 0, 1, 0,
        doc: /*
 Return charset of a character in the current buffer at position POS.
-If POS is nil, it defauls to the current point.
+If POS is nil, it defaults to the current point.
 If POS is out of range, the value is nil.  */)
   (Lisp_Object pos)
 {
@@ -2100,7 +2106,7 @@ DIMENSION, CHARS, and FINAL-CHAR.  */)
   (Lisp_Object dimension, Lisp_Object chars, Lisp_Object final_char)
 {
   int id;
-  int chars_flag;
+  bool chars_flag;
 
   check_iso_charset_parameter (dimension, chars, final_char);
   chars_flag = XFASTINT (chars) == 96;
@@ -2286,11 +2292,15 @@ init_charset (void)
   tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
   if (access (SSDATA (tempdir), 0) < 0)
     {
-      dir_warning ("Error: charsets directory (%s) does not exist.\n\
+      /* This used to be non-fatal (dir_warning), but it should not
+         happen, and if it does sooner or later it will cause some
+         obscure problem (eg bug#6401), so better abort.  */
+      fprintf (stderr, "Error: charsets directory not found:\n\
+%s\n\
 Emacs will not function correctly without the character map files.\n\
 Please check your installation!\n",
-                   tempdir);
-      /* TODO should this be a fatal error?  (Bug#909)  */
+                   SDATA (tempdir));
+      exit (1);
     }
 
   Vcharset_map_path = Fcons (tempdir, Qnil);
@@ -2318,20 +2328,21 @@ init_charset_once (void)
 
 #ifdef emacs
 
+/* Allocate an initial charset table that is large enough to handle
+   Emacs while it is bootstrapping.  As of September 2011, the size
+   needs to be at least 166; make it a bit bigger to allow for future
+   expansion.
+
+   Don't make the value so small that the table is reallocated during
+   bootstrapping, as glibc malloc calls larger than just under 64 KiB
+   during an initial bootstrap wreak havoc after dumping; see the
+   M_MMAP_THRESHOLD value in alloc.c, plus there is a extra overhead
+   internal to glibc malloc and perhaps to Emacs malloc debugging.  */
+static struct charset charset_table_init[180];
+
 void
 syms_of_charset (void)
 {
-  /* Allocate an initial charset table that is just under 64 KiB in size.
-     This should be large enough so that the charset table need not be
-     reallocated during an initial bootstrap.  Allocating anything larger than
-     64 KiB in an initial run may not work, because glibc malloc might use
-     mmap for larger allocations, and these don't work well across dumped
-     systems.  */
-  enum {
-    initial_malloc_max = (1 << 16) - 1,
-    charset_table_size_init = initial_malloc_max / sizeof (struct charset)
-  };
-
   DEFSYM (Qcharsetp, "charsetp");
 
   DEFSYM (Qascii, "ascii");
@@ -2364,9 +2375,8 @@ syms_of_charset (void)
     Vcharset_hash_table = Fmake_hash_table (2, args);
   }
 
-  charset_table = (struct charset *) xmalloc (sizeof (struct charset)
-                                             * charset_table_size_init);
-  charset_table_size = charset_table_size_init;
+  charset_table = charset_table_init;
+  charset_table_size = sizeof charset_table_init / sizeof *charset_table_init;
   charset_table_used = 0;
 
   defsubr (&Scharsetp);
@@ -2394,7 +2404,7 @@ syms_of_charset (void)
   defsubr (&Ssort_charsets);
 
   DEFVAR_LISP ("charset-map-path", Vcharset_map_path,
-              doc: /* *List of directories to search for charset map files.  */);
+              doc: /* List of directories to search for charset map files.  */);
   Vcharset_map_path = Qnil;
 
   DEFVAR_BOOL ("inhibit-load-charset-map", inhibit_load_charset_map,