X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Frangetab.c;h=50a87350d12182e9e75a0bced93f3b0966c3c058;hp=8d5bdba6a35bd6f79c4eb0a48698d96f7abd3851;hb=f7019bf646d0d4e750e0186d6e912ec7a3b9da90;hpb=ea1ea793fe6e244ef5555ed983423a204101af13 diff --git a/src/rangetab.c b/src/rangetab.c index 8d5bdba..50a8735 100644 --- a/src/rangetab.c +++ b/src/rangetab.c @@ -43,7 +43,7 @@ Lisp_Object Qrange_table; static Lisp_Object mark_range_table (Lisp_Object obj) { - struct Lisp_Range_Table *rt = XRANGE_TABLE (obj); + Lisp_Range_Table *rt = XRANGE_TABLE (obj); int i; for (i = 0; i < Dynarr_length (rt->entries); i++) @@ -54,7 +54,7 @@ mark_range_table (Lisp_Object obj) static void print_range_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) { - struct Lisp_Range_Table *rt = XRANGE_TABLE (obj); + Lisp_Range_Table *rt = XRANGE_TABLE (obj); char buf[200]; int i; @@ -77,8 +77,8 @@ print_range_table (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) static int range_table_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) { - struct Lisp_Range_Table *rt1 = XRANGE_TABLE (obj1); - struct Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2); + Lisp_Range_Table *rt1 = XRANGE_TABLE (obj1); + Lisp_Range_Table *rt2 = XRANGE_TABLE (obj2); int i; if (Dynarr_length (rt1->entries) != Dynarr_length (rt2->entries)) @@ -107,7 +107,7 @@ range_table_entry_hash (struct range_table_entry *rte, int depth) static unsigned long range_table_hash (Lisp_Object obj, int depth) { - struct Lisp_Range_Table *rt = XRANGE_TABLE (obj); + Lisp_Range_Table *rt = XRANGE_TABLE (obj); int i; int size = Dynarr_length (rt->entries); unsigned long hash = size; @@ -133,27 +133,27 @@ range_table_hash (Lisp_Object obj, int depth) } static const struct lrecord_description rte_description_1[] = { - { XD_LISP_OBJECT, offsetof(range_table_entry, val), 1 }, + { XD_LISP_OBJECT, offsetof (range_table_entry, val) }, { XD_END } }; static const struct struct_description rte_description = { - sizeof(range_table_entry), + sizeof (range_table_entry), rte_description_1 }; static const struct lrecord_description rted_description_1[] = { - XD_DYNARR_DESC(range_table_entry_dynarr, &rte_description), + XD_DYNARR_DESC (range_table_entry_dynarr, &rte_description), { XD_END } }; static const struct struct_description rted_description = { - sizeof(range_table_entry_dynarr), + sizeof (range_table_entry_dynarr), rted_description_1 }; static const struct lrecord_description range_table_description[] = { - { XD_STRUCT_PTR, offsetof(struct Lisp_Range_Table, entries), 1, &rted_description }, + { XD_STRUCT_PTR, offsetof (Lisp_Range_Table, entries), 1, &rted_description }, { XD_END } }; @@ -161,7 +161,7 @@ DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table, mark_range_table, print_range_table, 0, range_table_equal, range_table_hash, range_table_description, - struct Lisp_Range_Table); + Lisp_Range_Table); /************************************************************************/ /* Range table operations */ @@ -170,7 +170,7 @@ DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table, #ifdef ERROR_CHECK_TYPECHECK static void -verify_range_table (struct Lisp_Range_Table *rt) +verify_range_table (Lisp_Range_Table *rt) { int i; @@ -233,26 +233,27 @@ You can manipulate it using `put-range-table', `get-range-table', ()) { Lisp_Object obj; - struct Lisp_Range_Table *rt = alloc_lcrecord_type (struct Lisp_Range_Table, - &lrecord_range_table); + Lisp_Range_Table *rt = alloc_lcrecord_type (Lisp_Range_Table, + &lrecord_range_table); rt->entries = Dynarr_new (range_table_entry); XSETRANGE_TABLE (obj, rt); return obj; } DEFUN ("copy-range-table", Fcopy_range_table, 1, 1, 0, /* -Make a new range table which contains the same values for the same -ranges as the given table. The values will not themselves be copied. +Return a new range table which is a copy of RANGE-TABLE. +It will contain the same values for the same ranges as RANGE-TABLE. +The values will not themselves be copied. */ - (old_table)) + (range_table)) { - struct Lisp_Range_Table *rt, *rtnew; + Lisp_Range_Table *rt, *rtnew; Lisp_Object obj; - CHECK_RANGE_TABLE (old_table); - rt = XRANGE_TABLE (old_table); + CHECK_RANGE_TABLE (range_table); + rt = XRANGE_TABLE (range_table); - rtnew = alloc_lcrecord_type (struct Lisp_Range_Table, &lrecord_range_table); + rtnew = alloc_lcrecord_type (Lisp_Range_Table, &lrecord_range_table); rtnew->entries = Dynarr_new (range_table_entry); Dynarr_add_many (rtnew->entries, Dynarr_atp (rt->entries, 0), @@ -262,15 +263,15 @@ ranges as the given table. The values will not themselves be copied. } DEFUN ("get-range-table", Fget_range_table, 2, 3, 0, /* -Find value for position POS in TABLE. +Find value for position POS in RANGE-TABLE. If there is no corresponding value, return DEFAULT (defaults to nil). */ - (pos, table, default_)) + (pos, range_table, default_)) { - struct Lisp_Range_Table *rt; + Lisp_Range_Table *rt; - CHECK_RANGE_TABLE (table); - rt = XRANGE_TABLE (table); + CHECK_RANGE_TABLE (range_table); + rt = XRANGE_TABLE (range_table); CHECK_INT_COERCE_CHAR (pos); @@ -284,7 +285,7 @@ put_range_table (Lisp_Object table, EMACS_INT first, { int i; int insert_me_here = -1; - struct Lisp_Range_Table *rt = XRANGE_TABLE (table); + Lisp_Range_Table *rt = XRANGE_TABLE (table); /* Now insert in the proper place. This gets tricky because we may be overlapping one or more existing ranges and need @@ -403,13 +404,13 @@ put_range_table (Lisp_Object table, EMACS_INT first, } DEFUN ("put-range-table", Fput_range_table, 4, 4, 0, /* -Set the value for range (START, END) to be VAL in TABLE. +Set the value for range (START, END) to be VALUE in RANGE-TABLE. */ - (start, end, val, table)) + (start, end, value, range_table)) { EMACS_INT first, last; - CHECK_RANGE_TABLE (table); + CHECK_RANGE_TABLE (range_table); CHECK_INT_COERCE_CHAR (start); first = XINT (start); CHECK_INT_COERCE_CHAR (end); @@ -417,36 +418,73 @@ Set the value for range (START, END) to be VAL in TABLE. if (first > last) signal_simple_error_2 ("start must be <= end", start, end); - put_range_table (table, first, last, val); - verify_range_table (XRANGE_TABLE (table)); + put_range_table (range_table, first, last, value); + verify_range_table (XRANGE_TABLE (range_table)); return Qnil; } DEFUN ("remove-range-table", Fremove_range_table, 3, 3, 0, /* -Remove the value for range (START, END) in TABLE. +Remove the value for range (START, END) in RANGE-TABLE. */ - (start, end, table)) + (start, end, range_table)) { - return Fput_range_table (start, end, Qunbound, table); + return Fput_range_table (start, end, Qunbound, range_table); } DEFUN ("clear-range-table", Fclear_range_table, 1, 1, 0, /* -Flush TABLE. +Flush RANGE-TABLE. */ - (table)) + (range_table)) { - CHECK_RANGE_TABLE (table); - Dynarr_reset (XRANGE_TABLE (table)->entries); + CHECK_RANGE_TABLE (range_table); + Dynarr_reset (XRANGE_TABLE (range_table)->entries); return Qnil; } DEFUN ("map-range-table", Fmap_range_table, 2, 2, 0, /* -Map FUNCTION over entries in TABLE, calling it with three args, +Map FUNCTION over entries in RANGE-TABLE, calling it with three args, the beginning and end of the range and the corresponding value. + +Results are guaranteed to be correct (i.e. each entry processed +exactly once) if FUNCTION modifies or deletes the current entry +\(i.e. passes the current range to `put-range-table' or +`remove-range-table'), but not otherwise. */ - (function, table)) + (function, range_table)) { - error ("not yet implemented"); + Lisp_Range_Table *rt; + int i; + + CHECK_RANGE_TABLE (range_table); + CHECK_FUNCTION (function); + + rt = XRANGE_TABLE (range_table); + + /* Do not "optimize" by pulling out the length computation below! + FUNCTION may have changed the table. */ + for (i = 0; i < Dynarr_length (rt->entries); i++) + { + struct range_table_entry *entry = Dynarr_atp (rt->entries, i); + EMACS_INT first, last; + Lisp_Object args[4]; + int oldlen; + + again: + first = entry->first; + last = entry->last; + oldlen = Dynarr_length (rt->entries); + args[0] = function; + args[1] = make_int (first); + args[2] = make_int (last); + args[3] = entry->val; + Ffuncall (countof (args), args); + /* Has FUNCTION removed the entry? */ + if (oldlen > Dynarr_length (rt->entries) + && i < Dynarr_length (rt->entries) + && (first != entry->first || last != entry->last)) + goto again; + } + return Qnil; } @@ -704,6 +742,8 @@ unified_range_table_get_range (void *unrangetab, int offset, void syms_of_rangetab (void) { + INIT_LRECORD_IMPLEMENTATION (range_table); + defsymbol (&Qrange_tablep, "range-table-p"); defsymbol (&Qrange_table, "range-table");