is not hard but just requires moving that stuff out of that file. */
static Lisp_Object
-mark_range_table (Lisp_Object obj, void (*markobj) (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++)
- markobj (Dynarr_at (rt->entries, i).val);
+ mark_object (Dynarr_at (rt->entries, i).val);
return Qnil;
}
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;
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))
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;
return hash;
}
+static const struct lrecord_description rte_description_1[] = {
+ { XD_LISP_OBJECT, offsetof (range_table_entry, val) },
+ { XD_END }
+};
+
+static const struct struct_description rte_description = {
+ 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_END }
+};
+
+static const struct struct_description rted_description = {
+ sizeof (range_table_entry_dynarr),
+ rted_description_1
+};
+
+static const struct lrecord_description range_table_description[] = {
+ { XD_STRUCT_PTR, offsetof (Lisp_Range_Table, entries), 1, &rted_description },
+ { XD_END }
+};
+
DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table,
mark_range_table, print_range_table, 0,
- range_table_equal, range_table_hash, 0,
- struct Lisp_Range_Table);
+ range_table_equal, range_table_hash,
+ range_table_description,
+ Lisp_Range_Table);
\f
/************************************************************************/
/* Range table operations */
#ifdef ERROR_CHECK_TYPECHECK
static void
-verify_range_table (struct Lisp_Range_Table *rt)
+verify_range_table (Lisp_Range_Table *rt)
{
int i;
())
{
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),
}
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);
{
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
}
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);
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;
}
void
syms_of_rangetab (void)
{
+ INIT_LRECORD_IMPLEMENTATION (range_table);
+
defsymbol (&Qrange_tablep, "range-table-p");
defsymbol (&Qrange_table, "range-table");