Add 2009 to copyright years.
[bpt/emacs.git] / src / chartab.c
index 7e43aa4..89f6379 100644 (file)
@@ -1,5 +1,5 @@
 /* chartab.c -- char-table support
 /* chartab.c -- char-table support
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
 
@@ -229,66 +229,60 @@ sub_char_table_ref_and_range (table, c, from, to, defalt)
   int depth = XINT (tbl->depth);
   int min_char = XINT (tbl->min_char);
   int max_char = min_char + chartab_chars[depth - 1] - 1;
   int depth = XINT (tbl->depth);
   int min_char = XINT (tbl->min_char);
   int max_char = min_char + chartab_chars[depth - 1] - 1;
-  int index = CHARTAB_IDX (c, depth, min_char);
+  int index = CHARTAB_IDX (c, depth, min_char), idx;
   Lisp_Object val;
 
   val = tbl->contents[index];
   Lisp_Object val;
 
   val = tbl->contents[index];
-  *from = min_char + index * chartab_chars[depth];
-  *to = *from + chartab_chars[depth] - 1;
   if (SUB_CHAR_TABLE_P (val))
     val = sub_char_table_ref_and_range (val, c, from, to, defalt);
   else if (NILP (val))
     val = defalt;
 
   if (SUB_CHAR_TABLE_P (val))
     val = sub_char_table_ref_and_range (val, c, from, to, defalt);
   else if (NILP (val))
     val = defalt;
 
-  while (*from > min_char
-        && *from == min_char + index * chartab_chars[depth])
+  idx = index;
+  while (idx > 0 && *from < min_char + idx * chartab_chars[depth])
     {
       Lisp_Object this_val;
     {
       Lisp_Object this_val;
-      int this_from = *from - chartab_chars[depth];
-      int this_to = *from - 1;
 
 
-      index--;
-      this_val = tbl->contents[index];
+      c = min_char + idx * chartab_chars[depth] - 1;
+      idx--;
+      this_val = tbl->contents[idx];
       if (SUB_CHAR_TABLE_P (this_val))
       if (SUB_CHAR_TABLE_P (this_val))
-       this_val = sub_char_table_ref_and_range (this_val, this_to,
-                                                &this_from, &this_to,
-                                                defalt);
+       this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt);
       else if (NILP (this_val))
        this_val = defalt;
 
       if (! EQ (this_val, val))
       else if (NILP (this_val))
        this_val = defalt;
 
       if (! EQ (this_val, val))
-       break;
-      *from = this_from;
+       {
+         *from = c + 1;
+         break;
+       }
     }
     }
-  index = CHARTAB_IDX (c, depth, min_char);
-  while (*to < max_char
-        && *to == min_char + (index + 1) * chartab_chars[depth] - 1)
+  while ((c = min_char + (index + 1) * chartab_chars[depth]) < max_char
+        && *to >= c)
     {
       Lisp_Object this_val;
     {
       Lisp_Object this_val;
-      int this_from = *to + 1;
-      int this_to = this_from + chartab_chars[depth] - 1;
 
       index++;
       this_val = tbl->contents[index];
       if (SUB_CHAR_TABLE_P (this_val))
 
       index++;
       this_val = tbl->contents[index];
       if (SUB_CHAR_TABLE_P (this_val))
-       this_val = sub_char_table_ref_and_range (this_val, this_from,
-                                                &this_from, &this_to,
-                                                defalt);
+       this_val = sub_char_table_ref_and_range (this_val, c, from, to, defalt);
       else if (NILP (this_val))
        this_val = defalt;
       if (! EQ (this_val, val))
       else if (NILP (this_val))
        this_val = defalt;
       if (! EQ (this_val, val))
-       break;
-      *to = this_to;
+       {
+         *to = c - 1;
+         break;
+       }
     }
 
   return val;
 }
 
 
     }
 
   return val;
 }
 
 
-/* Return the value for C in char-table TABLE.  Set *FROM and *TO to
-   the range of characters (containing C) that have the same value as
-   C.  It is not assured that the value of (*FROM - 1) and (*TO + 1)
-   is different from that of C.  */
+/* Return the value for C in char-table TABLE.  Shrink the range *FROM
+   and *TO to cover characters (containing C) that have the same value
+   as C.  It is not assured that the values of (*FROM - 1) and (*TO +
+   1) are different from that of C.  */
 
 Lisp_Object
 char_table_ref_and_range (table, c, from, to)
 
 Lisp_Object
 char_table_ref_and_range (table, c, from, to)
@@ -297,53 +291,56 @@ char_table_ref_and_range (table, c, from, to)
      int *from, *to;
 {
   struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
      int *from, *to;
 {
   struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
-  int index = CHARTAB_IDX (c, 0, 0);
+  int index = CHARTAB_IDX (c, 0, 0), idx;
   Lisp_Object val;
 
   val = tbl->contents[index];
   Lisp_Object val;
 
   val = tbl->contents[index];
-  *from = index * chartab_chars[0];
-  *to = *from + chartab_chars[0] - 1;
+  if (*from < 0)
+    *from = 0;
+  if (*to < 0)
+    *to = MAX_CHAR;
   if (SUB_CHAR_TABLE_P (val))
     val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt);
   else if (NILP (val))
     val = tbl->defalt;
 
   if (SUB_CHAR_TABLE_P (val))
     val = sub_char_table_ref_and_range (val, c, from, to, tbl->defalt);
   else if (NILP (val))
     val = tbl->defalt;
 
-  while (*from > 0 && *from == index * chartab_chars[0])
+  idx = index;
+  while (*from < idx * chartab_chars[0])
     {
       Lisp_Object this_val;
     {
       Lisp_Object this_val;
-      int this_from = *from - chartab_chars[0];
-      int this_to = *from - 1;
 
 
-      index--;
-      this_val = tbl->contents[index];
+      c = idx * chartab_chars[0] - 1;
+      idx--;
+      this_val = tbl->contents[idx];
       if (SUB_CHAR_TABLE_P (this_val))
       if (SUB_CHAR_TABLE_P (this_val))
-       this_val = sub_char_table_ref_and_range (this_val, this_to,
-                                                &this_from, &this_to,
+       this_val = sub_char_table_ref_and_range (this_val, c, from, to,
                                                 tbl->defalt);
       else if (NILP (this_val))
        this_val = tbl->defalt;
 
       if (! EQ (this_val, val))
                                                 tbl->defalt);
       else if (NILP (this_val))
        this_val = tbl->defalt;
 
       if (! EQ (this_val, val))
-       break;
-      *from = this_from;
+       {
+         *from = c + 1;
+         break;
+       }
     }
     }
-  while (*to < MAX_CHAR && *to == (index + 1) * chartab_chars[0] - 1)
+  while (*to >= (index + 1) * chartab_chars[0])
     {
       Lisp_Object this_val;
     {
       Lisp_Object this_val;
-      int this_from = *to + 1;
-      int this_to = this_from + chartab_chars[0] - 1;
 
       index++;
 
       index++;
+      c = index * chartab_chars[0];
       this_val = tbl->contents[index];
       if (SUB_CHAR_TABLE_P (this_val))
       this_val = tbl->contents[index];
       if (SUB_CHAR_TABLE_P (this_val))
-       this_val = sub_char_table_ref_and_range (this_val, this_from,
-                                                &this_from, &this_to,
+       this_val = sub_char_table_ref_and_range (this_val, c, from, to,
                                                 tbl->defalt);
       else if (NILP (this_val))
        this_val = tbl->defalt;
       if (! EQ (this_val, val))
                                                 tbl->defalt);
       else if (NILP (this_val))
        this_val = tbl->defalt;
       if (! EQ (this_val, val))
-       break;
-      *to = this_to;
+       {
+         *to = c - 1;
+         break;
+       }
     }
 
   return val;
     }
 
   return val;
@@ -660,28 +657,27 @@ optimize_sub_char_table (table, test)
   struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
   int depth = XINT (tbl->depth);
   Lisp_Object elt, this;
   struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
   int depth = XINT (tbl->depth);
   Lisp_Object elt, this;
-  int i;
+  int i, optimizable;
 
   elt = XSUB_CHAR_TABLE (table)->contents[0];
   if (SUB_CHAR_TABLE_P (elt))
     elt = XSUB_CHAR_TABLE (table)->contents[0]
       = optimize_sub_char_table (elt, test);
 
   elt = XSUB_CHAR_TABLE (table)->contents[0];
   if (SUB_CHAR_TABLE_P (elt))
     elt = XSUB_CHAR_TABLE (table)->contents[0]
       = optimize_sub_char_table (elt, test);
-  if (SUB_CHAR_TABLE_P (elt))
-    return table;
+  optimizable = SUB_CHAR_TABLE_P (elt) ? 0 : 1;
   for (i = 1; i < chartab_size[depth]; i++)
     {
       this = XSUB_CHAR_TABLE (table)->contents[i];
       if (SUB_CHAR_TABLE_P (this))
        this = XSUB_CHAR_TABLE (table)->contents[i]
          = optimize_sub_char_table (this, test);
   for (i = 1; i < chartab_size[depth]; i++)
     {
       this = XSUB_CHAR_TABLE (table)->contents[i];
       if (SUB_CHAR_TABLE_P (this))
        this = XSUB_CHAR_TABLE (table)->contents[i]
          = optimize_sub_char_table (this, test);
-      if (SUB_CHAR_TABLE_P (this)
-         || (NILP (test) ? NILP (Fequal (this, elt)) /* defaults to `equal'. */
+      if (optimizable
+         && (NILP (test) ? NILP (Fequal (this, elt)) /* defaults to `equal'. */
              : EQ (test, Qeq) ? !EQ (this, elt)      /* Optimize `eq' case.  */
              : NILP (call2 (test, this, elt))))
              : EQ (test, Qeq) ? !EQ (this, elt)      /* Optimize `eq' case.  */
              : NILP (call2 (test, this, elt))))
-       break;
+       optimizable = 0;
     }
 
     }
 
-  return (i < chartab_size[depth] ? table : elt);
+  return (optimizable ? elt : table);
 }
 
 DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
 }
 
 DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
@@ -704,6 +700,9 @@ equivalent and can be merged.  It defaults to `equal'.  */)
        XCHAR_TABLE (char_table)->contents[i]
          = optimize_sub_char_table (elt, test);
     }
        XCHAR_TABLE (char_table)->contents[i]
          = optimize_sub_char_table (elt, test);
     }
+  /* Reset the `ascii' cache, in case it got optimized away.  */
+  XCHAR_TABLE (char_table)->ascii = char_table_ascii (char_table);
+
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -978,6 +977,27 @@ map_sub_char_table_for_charset (c_function, function, table, arg, range,
 }
 
 
 }
 
 
+/* Support function for `map-charset-chars'.  Map C_FUNCTION or
+   FUNCTION over TABLE, calling it for each character or a group of
+   succeeding characters that have non-nil value in TABLE.  TABLE is a
+   "mapping table" or a "deunifier table" of a certain charset.
+
+   If CHARSET is not NULL (this is the case that `map-charset-chars'
+   is called with non-nil FROM-CODE and TO-CODE), it is a charset who
+   owns TABLE, and the function is called only on a character in the
+   range FROM and TO.  FROM and TO are not character codes, but code
+   points of a character in CHARSET.
+
+   This function is called in these two cases:
+
+   (1) A charset has a mapping file name in :map property.
+
+   (2) A charset has an upper code space in :offset property and a
+   mapping file name in :unify-map property.  In this case, this
+   function is called only for characters in the Unicode code space.
+   Characters in upper code space are handled directly in
+   map_charset_chars.  */
+
 void
 map_char_table_for_charset (c_function, function, table, arg,
                            charset, from, to)
 void
 map_char_table_for_charset (c_function, function, table, arg,
                            charset, from, to)