/* chartab.c -- char-table support
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
National Institute of Advanced Industrial Science and Technology (AIST)
Registration Number H13PRO009
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
+#include <setjmp.h>
#include "lisp.h"
#include "character.h"
#include "charset.h"
property, the property's value should be an integer between 0 and 10
that specifies how many extra slots the char-table has. Otherwise,
the char-table has no extra slot. */)
- (purpose, init)
- register Lisp_Object purpose, init;
+ (register Lisp_Object purpose, Lisp_Object init)
{
Lisp_Object vector;
Lisp_Object n;
}
static Lisp_Object
-make_sub_char_table (depth, min_char, defalt)
- int depth, min_char;
- Lisp_Object defalt;
+make_sub_char_table (int depth, int min_char, Lisp_Object defalt)
{
Lisp_Object table;
int size = VECSIZE (struct Lisp_Sub_Char_Table) - 1 + chartab_size[depth];
}
static Lisp_Object
-char_table_ascii (table)
- Lisp_Object table;
+char_table_ascii (Lisp_Object table)
{
Lisp_Object sub;
return XSUB_CHAR_TABLE (sub)->contents[0];
}
-Lisp_Object
-copy_sub_char_table (table)
- Lisp_Object table;
+static Lisp_Object
+copy_sub_char_table (Lisp_Object table)
{
Lisp_Object copy;
int depth = XINT (XSUB_CHAR_TABLE (table)->depth);
Lisp_Object
-copy_char_table (table)
- Lisp_Object table;
+copy_char_table (Lisp_Object table)
{
Lisp_Object copy;
int size = XCHAR_TABLE (table)->size & PSEUDOVECTOR_SIZE_MASK;
return copy;
}
-Lisp_Object
-sub_char_table_ref (table, c)
- Lisp_Object table;
- int c;
+static Lisp_Object
+sub_char_table_ref (Lisp_Object table, int c)
{
struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
int depth = XINT (tbl->depth);
}
Lisp_Object
-char_table_ref (table, c)
- Lisp_Object table;
- int c;
+char_table_ref (Lisp_Object table, int c)
{
struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
Lisp_Object val;
}
static Lisp_Object
-sub_char_table_ref_and_range (table, c, from, to, defalt)
- Lisp_Object table;
- int c;
- int *from, *to;
- Lisp_Object defalt;
+sub_char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to, Lisp_Object defalt)
{
struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
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 chartab_idx = CHARTAB_IDX (c, depth, min_char), idx;
Lisp_Object val;
- val = tbl->contents[index];
- *from = min_char + index * chartab_chars[depth];
- *to = *from + chartab_chars[depth] - 1;
+ val = tbl->contents[chartab_idx];
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 = chartab_idx;
+ while (idx > 0 && *from < min_char + idx * chartab_chars[depth])
{
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))
- 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))
- 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 = (chartab_idx + 1) * chartab_chars[depth])
+ < chartab_chars[depth - 1])
+ && (c += min_char) <= *to)
{
Lisp_Object this_val;
- int this_from = *to + 1;
- int this_to = this_from + chartab_chars[depth] - 1;
- index++;
- this_val = tbl->contents[index];
+ chartab_idx++;
+ this_val = tbl->contents[chartab_idx];
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))
- break;
- *to = this_to;
+ {
+ *to = c - 1;
+ break;
+ }
}
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 table;
- int c;
- int *from, *to;
+char_table_ref_and_range (Lisp_Object table, int c, int *from, int *to)
{
struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
- int index = CHARTAB_IDX (c, 0, 0);
+ int chartab_idx = CHARTAB_IDX (c, 0, 0), idx;
Lisp_Object val;
- val = tbl->contents[index];
- *from = index * chartab_chars[0];
- *to = *from + chartab_chars[0] - 1;
+ val = tbl->contents[chartab_idx];
+ 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;
- while (*from > 0 && *from == index * chartab_chars[0])
+ idx = chartab_idx;
+ while (*from < idx * chartab_chars[0])
{
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))
- 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))
- break;
- *from = this_from;
+ {
+ *from = c + 1;
+ break;
+ }
}
- while (*to < MAX_CHAR && *to == (index + 1) * chartab_chars[0] - 1)
+ while (*to >= (chartab_idx + 1) * chartab_chars[0])
{
Lisp_Object this_val;
- int this_from = *to + 1;
- int this_to = this_from + chartab_chars[0] - 1;
- index++;
- this_val = tbl->contents[index];
+ chartab_idx++;
+ c = chartab_idx * chartab_chars[0];
+ this_val = tbl->contents[chartab_idx];
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))
- break;
- *to = this_to;
+ {
+ *to = c - 1;
+ break;
+ }
}
return val;
}
-#define ASET_RANGE(ARRAY, FROM, TO, LIMIT, VAL) \
- do { \
- int limit = (TO) < (LIMIT) ? (TO) : (LIMIT); \
- for (; (FROM) < limit; (FROM)++) (ARRAY)->contents[(FROM)] = (VAL); \
- } while (0)
-
-#define GET_SUB_CHAR_TABLE(TABLE, SUBTABLE, IDX, DEPTH, MIN_CHAR) \
- do { \
- (SUBTABLE) = (TABLE)->contents[(IDX)]; \
- if (!SUB_CHAR_TABLE_P (SUBTABLE)) \
- (SUBTABLE) = make_sub_char_table ((DEPTH), (MIN_CHAR), (SUBTABLE)); \
- } while (0)
-
-
static void
-sub_char_table_set (table, c, val)
- Lisp_Object table;
- int c;
- Lisp_Object val;
+sub_char_table_set (Lisp_Object table, int c, Lisp_Object val)
{
struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
int depth = XINT ((tbl)->depth);
}
Lisp_Object
-char_table_set (table, c, val)
- Lisp_Object table;
- int c;
- Lisp_Object val;
+char_table_set (Lisp_Object table, int c, Lisp_Object val)
{
struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
}
static void
-sub_char_table_set_range (table, depth, min_char, from, to, val)
- Lisp_Object *table;
- int depth;
- int min_char;
- int from, to;
- Lisp_Object val;
+sub_char_table_set_range (Lisp_Object *table, int depth, int min_char, int from, int to, Lisp_Object val)
{
int max_char = min_char + chartab_chars[depth] - 1;
Lisp_Object
-char_table_set_range (table, from, to, val)
- Lisp_Object table;
- int from, to;
- Lisp_Object val;
+char_table_set_range (Lisp_Object table, int from, int to, Lisp_Object val)
{
struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
Lisp_Object *contents = tbl->contents;
1, 1, 0,
doc: /*
Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
- (char_table)
- Lisp_Object char_table;
+ (Lisp_Object char_table)
{
CHECK_CHAR_TABLE (char_table);
If CHAR-TABLE holds nil for a given character,
then the actual applicable value is inherited from the parent char-table
\(or from its parents, if necessary). */)
- (char_table)
- Lisp_Object char_table;
+ (Lisp_Object char_table)
{
CHECK_CHAR_TABLE (char_table);
2, 2, 0,
doc: /* Set the parent char-table of CHAR-TABLE to PARENT.
Return PARENT. PARENT must be either nil or another char-table. */)
- (char_table, parent)
- Lisp_Object char_table, parent;
+ (Lisp_Object char_table, Lisp_Object parent)
{
Lisp_Object temp;
DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
2, 2, 0,
doc: /* Return the value of CHAR-TABLE's extra-slot number N. */)
- (char_table, n)
- Lisp_Object char_table, n;
+ (Lisp_Object char_table, Lisp_Object n)
{
CHECK_CHAR_TABLE (char_table);
CHECK_NUMBER (n);
Sset_char_table_extra_slot,
3, 3, 0,
doc: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
- (char_table, n, value)
- Lisp_Object char_table, n, value;
+ (Lisp_Object char_table, Lisp_Object n, Lisp_Object value)
{
CHECK_CHAR_TABLE (char_table);
CHECK_NUMBER (n);
doc: /* Return the value in CHAR-TABLE for a range of characters RANGE.
RANGE should be nil (for the default value),
a cons of character codes (for characters in the range), or a character code. */)
- (char_table, range)
- Lisp_Object char_table, range;
+ (Lisp_Object char_table, Lisp_Object range)
{
Lisp_Object val;
CHECK_CHAR_TABLE (char_table);
RANGE should be t (for all characters), nil (for the default value),
a cons of character codes (for characters in the range),
or a character code. Return VALUE. */)
- (char_table, range, value)
- Lisp_Object char_table, range, value;
+ (Lisp_Object char_table, Lisp_Object range, Lisp_Object value)
{
CHECK_CHAR_TABLE (char_table);
if (EQ (range, Qt))
Sset_char_table_default, 3, 3, 0,
doc: /*
This function is obsolete and has no effect. */)
- (char_table, ch, value)
- Lisp_Object char_table, ch, value;
+ (Lisp_Object char_table, Lisp_Object ch, Lisp_Object value)
{
return Qnil;
}
integer. If the element is not a character, return CH itself. */
int
-char_table_translate (table, ch)
- Lisp_Object table;
- int ch;
+char_table_translate (Lisp_Object table, int ch)
{
Lisp_Object value;
value = Faref (table, make_number (ch));
}
static Lisp_Object
-optimize_sub_char_table (table, test)
- Lisp_Object table, test;
+optimize_sub_char_table (Lisp_Object table, Lisp_Object test)
{
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);
- 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);
- 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))))
- break;
+ optimizable = 0;
}
- return (i < chartab_size[depth] ? table : elt);
+ return (optimizable ? elt : table);
}
DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
doc: /* Optimize CHAR-TABLE.
TEST is the comparison function used to decide whether two entries are
equivalent and can be merged. It defaults to `equal'. */)
- (char_table, test)
- Lisp_Object char_table, test;
+ (Lisp_Object char_table, Lisp_Object test)
{
Lisp_Object elt;
int i;
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;
}
following characters in TABLE have the same value. */
static Lisp_Object
-map_sub_char_table (c_function, function, table, arg, val, range,
- default_val, parent)
- void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
- Lisp_Object function, table, arg, val, range, default_val, parent;
+map_sub_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object),
+ Lisp_Object function, Lisp_Object table, Lisp_Object arg, Lisp_Object val,
+ Lisp_Object range, Lisp_Object default_val, Lisp_Object parent)
{
/* Pointer to the elements of TABLE. */
Lisp_Object *contents;
ARG is passed to C_FUNCTION when that is called. */
void
-map_char_table (c_function, function, table, arg)
- void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
- Lisp_Object function, table, arg;
+map_char_table (void (*c_function) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object function, Lisp_Object table, Lisp_Object arg)
{
Lisp_Object range, val;
struct gcpro gcpro1, gcpro2, gcpro3;
FUNCTION is called with two arguments--a key and a value.
The key is a character code or a cons of character codes specifying a
range of characters that have the same value. */)
- (function, char_table)
- Lisp_Object function, char_table;
+ (Lisp_Object function, Lisp_Object char_table)
{
CHECK_CHAR_TABLE (char_table);
static void
-map_sub_char_table_for_charset (c_function, function, table, arg, range,
- charset, from, to)
- void (*c_function) P_ ((Lisp_Object, Lisp_Object));
- Lisp_Object function, table, arg, range;
- struct charset *charset;
- unsigned from, to;
+map_sub_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
+ Lisp_Object function, Lisp_Object table, Lisp_Object arg,
+ Lisp_Object range, struct charset *charset,
+ unsigned from, unsigned to)
{
struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
int depth = XINT (tbl->depth);
}
+/* 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 (*c_function) P_ ((Lisp_Object, Lisp_Object));
- Lisp_Object function, table, arg;
- struct charset *charset;
- unsigned from, to;
+map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Object),
+ Lisp_Object function, Lisp_Object table, Lisp_Object arg,
+ struct charset *charset,
+ unsigned from, unsigned to)
{
Lisp_Object range;
int c, i;
\f
void
-syms_of_chartab ()
+syms_of_chartab (void)
{
defsubr (&Smake_char_table);
defsubr (&Schar_table_parent);
defsubr (&Soptimize_char_table);
defsubr (&Smap_char_table);
}
-
-/* arch-tag: 18b5b560-7ab5-4108-b09e-d5dd65dc6fda
- (do not change this comment) */