summaryrefslogtreecommitdiff
path: root/src/chartab.c
diff options
context:
space:
mode:
authorKenichi Handa <handa@m17n.org>2002-06-12 00:14:15 +0000
committerKenichi Handa <handa@m17n.org>2002-06-12 00:14:15 +0000
commit9a1fa5fecde8f3b52b2ebee42e2020c182663fc8 (patch)
tree9a3d5dd13dd707cc78e6c1357c79068c04b508a8 /src/chartab.c
parentba8ea1f4b8e1483529bfbd4f6f1e9a36e259b57f (diff)
downloademacs-9a1fa5fecde8f3b52b2ebee42e2020c182663fc8.tar.gz
(sub_char_table_ref_and_range): New arg defalt. Fix
the previous change. (char_table_ref_and_range): Adjusted for the above change. (map_sub_char_table_for_charset): New function. (map_char_table_for_charset): New function.
Diffstat (limited to 'src/chartab.c')
-rw-r--r--src/chartab.c254
1 files changed, 212 insertions, 42 deletions
diff --git a/src/chartab.c b/src/chartab.c
index 8e942beaae8..e974824aa31 100644
--- a/src/chartab.c
+++ b/src/chartab.c
@@ -219,35 +219,77 @@ char_table_ref (table, c)
}
static Lisp_Object
-sub_char_table_ref_and_range (table, c, from, to)
+sub_char_table_ref_and_range (table, c, from, to, defalt)
Lisp_Object table;
int c;
int *from, *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);
Lisp_Object val;
- val = tbl->contents[CHARTAB_IDX (c, depth, min_char)];
- if (depth == 3)
- {
- *from = *to = c;
- }
- else if (SUB_CHAR_TABLE_P (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;
+
+ while (*from > min_char
+ && *from == min_char + index * chartab_chars[depth])
{
- val = sub_char_table_ref_and_range (val, c, from, to);
+ Lisp_Object this_val;
+ int this_from = *from - chartab_chars[depth];
+ int this_to = *from - 1;
+
+ index--;
+ this_val = tbl->contents[index];
+ if (SUB_CHAR_TABLE_P (this_val))
+ this_val = sub_char_table_ref_and_range (this_val, this_to,
+ &this_from, &this_to,
+ defalt);
+ else if (NILP (this_val))
+ this_val = defalt;
+
+ if (! EQ (this_val, val))
+ break;
+ *from = this_from;
}
- else
+ index = CHARTAB_IDX (c, depth, min_char);
+ while (*to < max_char
+ && *to == min_char + (index + 1) * chartab_chars[depth] - 1)
{
- *from = (CHARTAB_IDX (c, depth, min_char) * chartab_chars[depth]
- + min_char);
- *to = *from + chartab_chars[depth] - 1;
+ 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))
+ this_val = sub_char_table_ref_and_range (this_val, this_from,
+ &this_from, &this_to,
+ defalt);
+ else if (NILP (this_val))
+ this_val = defalt;
+ if (! EQ (this_val, val))
+ break;
+ *to = this_to;
}
+
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. */
+
Lisp_Object
char_table_ref_and_range (table, c, from, to)
Lisp_Object table;
@@ -255,44 +297,57 @@ char_table_ref_and_range (table, c, from, to)
int *from, *to;
{
struct Lisp_Char_Table *tbl = XCHAR_TABLE (table);
+ int index = CHARTAB_IDX (c, 0, 0);
Lisp_Object val;
- if (ASCII_CHAR_P (c))
+ val = tbl->contents[index];
+ *from = index * chartab_chars[0];
+ *to = *from + chartab_chars[0] - 1;
+ 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])
{
- val = tbl->ascii;
- if (SUB_CHAR_TABLE_P (val))
- {
- val = XSUB_CHAR_TABLE (val)->contents[c];
- *from = *to = c;
- }
- else
- {
- *from = 0, *to = 127;
- }
+ Lisp_Object this_val;
+ int this_from = *from - chartab_chars[0];
+ int this_to = *from - 1;
+
+ index--;
+ this_val = tbl->contents[index];
+ if (SUB_CHAR_TABLE_P (this_val))
+ this_val = sub_char_table_ref_and_range (this_val, this_to,
+ &this_from, &this_to,
+ tbl->defalt);
+ else if (NILP (this_val))
+ this_val = tbl->defalt;
+
+ if (! EQ (this_val, val))
+ break;
+ *from = this_from;
}
- else
+ while (*to < MAX_CHAR && *to == (index + 1) * chartab_chars[0] - 1)
{
- val = tbl->contents[CHARTAB_IDX (c, 0, 0)];
- if (SUB_CHAR_TABLE_P (val))
- {
- val = sub_char_table_ref_and_range (val, c, from, to);
- }
- else
- {
- *from = CHARTAB_IDX (c, 0, 0) * chartab_chars[0];
- *to = *from + chartab_chars[0] - 1;
- }
+ Lisp_Object this_val;
+ int this_from = *to + 1;
+ int this_to = this_from + chartab_chars[0] - 1;
+
+ 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,
+ tbl->defalt);
+ else if (NILP (this_val))
+ this_val = tbl->defalt;
+ if (! EQ (this_val, val))
+ break;
+ *to = this_to;
}
- if (NILP (val))
- {
- val = tbl->defalt;
- *from = 0, *to = MAX_CHAR;
- if (NILP (val) && CHAR_TABLE_P (tbl->parent))
- val = char_table_ref_and_range (tbl->parent, c, from, to);
- }
return val;
-}
+}
#define ASET_RANGE(ARRAY, FROM, TO, LIMIT, VAL) \
@@ -755,6 +810,121 @@ The key is always a possible IDX argument to `aref'. */)
return Qnil;
}
+
+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;
+{
+ struct Lisp_Sub_Char_Table *tbl = XSUB_CHAR_TABLE (table);
+ int depth = XINT (tbl->depth);
+ int c, i;
+
+ if (depth < 3)
+ for (i = 0, c = XINT (tbl->min_char); i < chartab_size[depth];
+ i++, c += chartab_chars[depth])
+ {
+ Lisp_Object this;
+
+ this = tbl->contents[i];
+ if (SUB_CHAR_TABLE_P (this))
+ map_sub_char_table_for_charset (c_function, function, this, arg,
+ range, charset, from, to);
+ else
+ {
+ if (! NILP (XCAR (range)))
+ {
+ XSETCDR (range, make_number (c - 1));
+ if (c_function)
+ (*c_function) (arg, range);
+ else
+ call2 (function, range, arg);
+ }
+ XSETCAR (range, Qnil);
+ }
+ }
+ else
+ for (i = 0, c = XINT (tbl->min_char); i < chartab_size[depth]; i++, c ++)
+ {
+ Lisp_Object this;
+ unsigned code;
+
+ this = tbl->contents[i];
+ if (NILP (this)
+ || (charset
+ && (code = ENCODE_CHAR (charset, c),
+ (code < from || code > to))))
+ {
+ if (! NILP (XCAR (range)))
+ {
+ XSETCDR (range, make_number (c - 1));
+ if (c_function)
+ (*c_function) (range, arg);
+ else
+ call2 (function, range, arg);
+ XSETCAR (range, Qnil);
+ }
+ }
+ else
+ {
+ if (NILP (XCAR (range)))
+ XSETCAR (range, make_number (c));
+ }
+ }
+}
+
+
+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;
+{
+ Lisp_Object range;
+ int c, i;
+
+ if (NILP (char_table_ref (table, 0)))
+ range = Fcons (Qnil, Qnil);
+ else
+ range = Fcons (make_number (0), make_number (0));
+
+ for (i = 0, c = 0; i < chartab_size[0]; i++, c += chartab_chars[0])
+ {
+ Lisp_Object this;
+
+ this = XCHAR_TABLE (table)->contents[i];
+ if (SUB_CHAR_TABLE_P (this))
+ map_sub_char_table_for_charset (c_function, function, this, arg,
+ range, charset, from, to);
+ else
+ {
+ if (! NILP (XCAR (range)))
+ {
+ XSETCDR (range, make_number (c - 1));
+ if (c_function)
+ (*c_function) (arg, range);
+ else
+ call2 (function, range, arg);
+ }
+ XSETCAR (range, Qnil);
+ }
+ }
+ if (! NILP (XCAR (range)))
+ {
+ XSETCDR (range, make_number (c - 1));
+ if (c_function)
+ (*c_function) (arg, range);
+ else
+ call2 (function, range, arg);
+ }
+}
+
+
#if 0
Lisp_Object