Mercurial > hg > xemacs-beta
diff src/fns.c @ 5475:248176c74e6b
Merge with trunk.
author | Mats Lidell <matsl@xemacs.org> |
---|---|
date | Sat, 23 Apr 2011 23:47:13 +0200 |
parents | ac37a5f7e5be ccf7e84fe265 |
children | d3e0482c7899 |
line wrap: on
line diff
--- a/src/fns.c Tue Mar 29 00:02:47 2011 +0200 +++ b/src/fns.c Sat Apr 23 23:47:13 2011 +0200 @@ -997,7 +997,7 @@ assert (counting >= 0); /* And we're not prepared to handle COUNT from any other caller at the moment. */ - assert (EQ (caller, QremoveX)); + assert (EQ (caller, QremoveX)|| EQ (caller, QdeleteX)); } check_test = get_check_test_function (item, &test, test_not, if_, if_not, @@ -1007,9 +1007,6 @@ if (CONSP (sequence)) { - Lisp_Object elt, tail = Qnil; - struct gcpro gcpro1; - if (EQ (caller, Qcount) && !NILP (from_end) && (!EQ (key, Qnil) || check_test == check_other_nokey || check_test == check_if_nokey)) @@ -1024,8 +1021,6 @@ start, end); } - GCPRO1 (tail); - /* If COUNT is non-nil and FROM-END is t, we can give the tail containing the last match, since that's what #'remove* is interested in (a zero or negative COUNT won't ever reach @@ -1037,7 +1032,7 @@ } { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (!(ii < ending)) { @@ -1058,10 +1053,9 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } - UNGCPRO; - if ((ii < starting || (ii < ending && !NILP (end))) && encountered != counting) { @@ -2620,18 +2614,18 @@ Boolint reverse_test_order, Lisp_Object start, Lisp_Object end) { - struct gcpro gcpro1, gcpro2; - Lisp_Object elt = Qnil, tail = list, tail_before = Qnil; - Elemcount len, ii = 0, starting = XINT (start); + struct gcpro gcpro1; + Lisp_Object tail_before = Qnil; + Elemcount ii = 0, starting = XINT (start); Elemcount ending = NILP (end) ? EMACS_INT_MAX : XINT (end); - GCPRO2 (elt, tail); + GCPRO1 (tail_before); if (check_test == check_eq_nokey) { /* TEST is #'eq, no need to call any C functions, and the test order won't be visible. */ - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) + EXTERNAL_LIST_LOOP_3 (elt, list, tail) { if (starting <= ii && ii < ending && EQ (item, elt) == test_not_unboundp) @@ -2652,15 +2646,17 @@ } else { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, list, tail) { if (starting <= ii && ii < ending && (reverse_test_order ? check_test (test, key, elt, item) : - check_test (test, key, item, elt)) == test_not_unboundp) + check_test (test, key, item, elt)) == test_not_unboundp) { *cons_out = tail_before; - RETURN_UNGCPRO (make_integer (ii)); + XUNGCPRO (elt); + UNGCPRO; + return make_integer (ii); } else { @@ -2672,6 +2668,7 @@ ii++; tail_before = tail; } + END_GC_EXTERNAL_LIST_LOOP (elt); } RETURN_UNGCPRO (Qnil); @@ -2858,22 +2855,16 @@ } else { - Lisp_Object tailed = alist; - struct gcpro gcpro1; - - GCPRO1 (tailed); - { - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) - { - tailed = tail; - - if (check_test (test, key, item, elt_car) == test_not_unboundp) + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) + { + if (CONSP (elt) && + check_test (test, key, item, XCAR (elt)) == test_not_unboundp) { - RETURN_UNGCPRO (elt); + XUNGCPRO (elt); + return elt; } - } - } - UNGCPRO; + } + END_GC_EXTERNAL_LIST_LOOP (elt); } return Qnil; @@ -2967,22 +2958,16 @@ } else { - struct gcpro gcpro1; - Lisp_Object tailed = alist; - - GCPRO1 (tailed); - { - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) - { - tailed = tail; - - if (check_test (test, key, item, elt_cdr) == test_not_unboundp) - { - RETURN_UNGCPRO (elt); - } - } - } - UNGCPRO; + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) + { + if (CONSP (elt) && + check_test (test, key, item, XCDR (elt)) == test_not_unboundp) + { + XUNGCPRO (elt); + return elt; + } + } + END_GC_EXTERNAL_LIST_LOOP (elt); } return Qnil; @@ -3012,9 +2997,6 @@ if (CONSP (sequence)) { - Lisp_Object elt, tail = Qnil; - struct gcpro gcpro1; - if (!(starting < ending)) { check_sequence_range (sequence, start, end, Flength (sequence)); @@ -3023,10 +3005,8 @@ return Qnil; } - GCPRO1 (tail); - { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, sequence) { if (starting <= ii && ii < ending && check_test (test, key, item, elt) == test_not_unboundp) @@ -3036,7 +3016,7 @@ if (NILP (from_end)) { - UNGCPRO; + XUNGCPRO (elt); return result; } } @@ -3047,10 +3027,9 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } - UNGCPRO; - if (ii < starting || (ii < ending && !NILP (end))) { check_sequence_range (sequence, start, end, Flength (sequence)); @@ -3257,12 +3236,11 @@ */ (int nargs, Lisp_Object *args)) { - Lisp_Object item = args[0], sequence = args[1], tail = sequence; + Lisp_Object item = args[0], sequence = args[1]; Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX; Elemcount len, ii = 0, encountered = 0, presenting = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1; PARSE_KEYWORDS (FdeleteX, nargs, args, 9, (test, if_not, if_, test_not, key, start, end, from_end, @@ -3299,7 +3277,25 @@ { return sequence; } - } + + if (!NILP (from_end)) + { + /* Sigh, this is inelegant. Force count_with_tail () to ignore + the count keyword, so we get the actual number of matching + elements, and can start removing from the beginning for the + from-end case. */ + for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FdeleteX))->min_args; + ii < nargs; ii += 2) + { + if (EQ (args[ii], Q_count)) + { + args[ii + 1] = Qnil; + break; + } + } + ii = 0; + } + } } check_test = get_check_test_function (item, &test, test_not, if_, if_not, @@ -3307,14 +3303,15 @@ if (CONSP (sequence)) { - Lisp_Object prev_tail_list_elt = Qnil, list_elt = Qnil; + Lisp_Object prev_tail_list_elt = Qnil, ignore = Qnil; Elemcount list_len = 0, deleted = 0; + struct gcpro gcpro1; if (!NILP (count) && !NILP (from_end)) { /* Both COUNT and FROM-END were specified; we need to traverse the list twice. */ - Lisp_Object present = count_with_tail (&list_elt, nargs, args, + Lisp_Object present = count_with_tail (&ignore, nargs, args, QdeleteX); if (ZEROP (present)) @@ -3332,11 +3329,11 @@ presenting = presenting <= counting ? 0 : presenting - counting; } - GCPRO1 (tail); + GCPRO1 (prev_tail_list_elt); ii = -1; { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (list_elt, sequence, tail, list_len) + GC_EXTERNAL_LIST_LOOP_4 (list_elt, sequence, tail, list_len) { ii++; @@ -3367,6 +3364,7 @@ } } } + END_GC_EXTERNAL_LIST_LOOP (list_elt); } UNGCPRO; @@ -3604,10 +3602,9 @@ Lisp_Object item = args[0], sequence = args[1], matched_count = Qnil, tail = Qnil; Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX; - Elemcount len, ii = 0, encountered = 0, presenting = 0; + Elemcount ii = 0, encountered = 0, presenting = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1; PARSE_KEYWORDS (FremoveX, nargs, args, 9, (test, if_not, if_, test_not, key, start, end, from_end, @@ -3646,6 +3643,24 @@ { return sequence; } + + if (!NILP (from_end)) + { + /* Sigh, this is inelegant. Force count_with_tail () to ignore the + count keyword, so we get the actual number of matching + elements, and can start removing from the beginning for the + from-end case. */ + for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FremoveX))->min_args; + ii < nargs; ii += 2) + { + if (EQ (args[ii], Q_count)) + { + args[ii + 1] = Qnil; + break; + } + } + ii = 0; + } } check_test = get_check_test_function (item, &test, test_not, if_, if_not, @@ -3655,8 +3670,8 @@ if (!ZEROP (matched_count)) { - Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil; - GCPRO1 (tailing); + Lisp_Object result = Qnil, result_tail = Qnil; + struct gcpro gcpro1, gcpro2; if (!NILP (count) && !NILP (from_end)) { @@ -3670,18 +3685,22 @@ presenting = presenting <= counting ? 0 : presenting - counting; } + GCPRO2 (result, tail); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tailing) { if (EQ (tail, tailing)) { + XUNGCPRO (elt); + UNGCPRO; + if (NILP (result)) { - RETURN_UNGCPRO (XCDR (tail)); + return XCDR (tail); } XSETCDR (result_tail, XCDR (tail)); - RETURN_UNGCPRO (result); + return result; } else if (starting <= ii && ii < ending && (check_test (test, key, item, elt) == test_not_unboundp) @@ -3707,8 +3726,8 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } - UNGCPRO; if (ii < starting || (ii < ending && !NILP (end))) @@ -3827,12 +3846,12 @@ Lisp_Object start, Lisp_Object end, Boolint copy) { - Lisp_Object checking = Qnil, elt, tail, result = list; + Lisp_Object checking = Qnil, result = list; Lisp_Object keyed, positioned, position_cons = Qnil, result_tail; Elemcount len = XINT (Flength (list)), pos, starting = XINT (start); Elemcount ending = (NILP (end) ? len : XINT (end)), greatest_pos_seen = -1; Elemcount ii = 0; - struct gcpro gcpro1, gcpro2; + struct gcpro gcpro1; /* We can't delete (or remove) as we go, because that breaks START and END. We could if END were nil, and that would change an ON(N + 2) @@ -3852,10 +3871,10 @@ memset (&(deleting->bits), 0, sizeof (long) * BIT_VECTOR_LONG_STORAGE (len)); - GCPRO2 (tail, keyed); + GCPRO1 (keyed); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, list, tail) { if (!(starting <= ii && ii <= ending) || bit_vector_bit (deleting, ii)) { @@ -3882,6 +3901,7 @@ } ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } UNGCPRO; @@ -3897,7 +3917,7 @@ ii = 1; { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) + EXTERNAL_LIST_LOOP_3 (elt, list, tail) { if (ii == greatest_pos_seen) { @@ -3915,7 +3935,7 @@ } else { - EXTERNAL_LIST_LOOP_DELETE_IF (elt0, list, + EXTERNAL_LIST_LOOP_DELETE_IF (elt, list, bit_vector_bit (deleting, ii++)); } } @@ -3943,8 +3963,8 @@ */ (int nargs, Lisp_Object *args)) { - Lisp_Object sequence = args[0], tail = sequence, keyed = Qnil, elt = Qnil; - Lisp_Object elt0 = Qnil, positioned = Qnil, ignore = Qnil; + Lisp_Object sequence = args[0], keyed = Qnil; + Lisp_Object positioned = Qnil, ignore = Qnil; Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0, jj = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; @@ -3976,10 +3996,10 @@ Lisp_Object prev_tail = Qnil; Elemcount deleted = 0; - GCPRO2 (tail, keyed); + GCPRO2 (keyed, prev_tail); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (starting <= ii && ii < ending) { @@ -4010,9 +4030,10 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (!(starting <= ii && ii <= ending)) { @@ -4021,7 +4042,7 @@ continue; } - keyed = KEY (key, elt0); + keyed = KEY (key, elt); positioned = list_position_cons_before (&ignore, keyed, XCDR (tail), check_test, test_not_unboundp, @@ -4050,7 +4071,9 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } + UNGCPRO; if ((ii < starting || (ii < ending && !NILP (end)))) @@ -4070,6 +4093,8 @@ } else if (STRINGP (sequence)) { + Lisp_Object elt = Qnil; + if (EQ (Qidentity, key)) { /* We know all the elements will be characters; set check_test to @@ -4088,7 +4113,6 @@ Ibyte *cursor = XSTRING_DATA (sequence), *startp = cursor; Elemcount deleted = 0; - elt = Qnil; GCPRO1 (elt); while (cursor_offset < byte_len) @@ -4243,6 +4267,7 @@ Elemcount deleted = 0; Lisp_Object *content = XVECTOR_DATA (sequence); struct Lisp_Bit_Vector *deleting; + Lisp_Object elt = Qnil; len = XVECTOR_LENGTH (sequence); check_sequence_range (sequence, start, end, make_integer (len)); @@ -4326,6 +4351,7 @@ and KEY arguments, which may be non-deterministic from our perspective, we need the same algorithm as for vectors. */ struct Lisp_Bit_Vector *deleting; + Lisp_Object elt = Qnil; len = bit_vector_length (bv); @@ -4427,13 +4453,13 @@ */ (int nargs, Lisp_Object *args)) { - Lisp_Object sequence = args[0], tail = sequence, keyed, positioned = Qnil; + Lisp_Object sequence = args[0], keyed, positioned = Qnil; Lisp_Object result = sequence, result_tail = result, cursor = Qnil; - Lisp_Object cons_with_shared_tail = Qnil, elt, elt0; - Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0; + Lisp_Object cons_with_shared_tail = Qnil; + Elemcount starting = 0, ending = EMACS_INT_MAX, ii = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2; PARSE_KEYWORDS (Fremove_duplicates, nargs, args, 6, (test, key, test_not, start, end, from_end), @@ -4467,10 +4493,10 @@ { Lisp_Object ignore = Qnil; - GCPRO3 (tail, keyed, result); + GCPRO2 (keyed, result); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (starting <= ii && ii <= ending) { @@ -4498,10 +4524,11 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (!(starting <= ii && ii <= ending)) { @@ -4514,7 +4541,7 @@ removed cons to this one. Otherwise, the tail of the output list is shared with the input list, which is OK. */ - keyed = KEY (key, elt0); + keyed = KEY (key, elt); positioned = list_position_cons_before (&ignore, keyed, XCDR (tail), check_test, test_not_unboundp, @@ -4546,7 +4573,9 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } + UNGCPRO; if ((ii < starting || (ii < ending && !NILP (end)))) @@ -7930,10 +7959,9 @@ { if (NILP (from_end)) { - struct gcpro gcpro1, gcpro2; - Lisp_Object tailed = Qnil; - - GCPRO2 (tailed, accum); + struct gcpro gcpro1; + + GCPRO1 (accum); if (!UNBOUNDP (initial_value)) { @@ -7941,11 +7969,8 @@ } else if (ending - starting) { - EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, sequence) { - /* KEY may amputate the list behind us; make sure what - remains to be processed is still reachable. */ - tailed = tail; if (ii == starting) { accum = KEY (key, elt); @@ -7954,18 +7979,15 @@ } ++ii; } + END_GC_EXTERNAL_LIST_LOOP (elt); } ii = 0; if (ending - starting) { - EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, sequence) { - /* KEY or FUNCTION may amputate the list behind us; make - sure what remains to be processed is still - reachable. */ - tailed = tail; if (ii >= starting) { if (ii < ending) @@ -7979,6 +8001,7 @@ } ++ii; } + END_GC_EXTERNAL_LIST_LOOP (elt); } UNGCPRO; @@ -8701,13 +8724,12 @@ */ (int nargs, Lisp_Object *args)) { - Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil; + Lisp_Object new_ = args[0], item = args[1], sequence = args[2]; Lisp_Object object_, position0; Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0; Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1; PARSE_KEYWORDS (Fnsubstitute, nargs, args, 9, (test, if_, if_not, test_not, key, start, end, count, @@ -8749,11 +8771,9 @@ if (CONSP (sequence)) { - Lisp_Object elt; - if (!NILP (count) && !NILP (from_end)) { - Lisp_Object present = count_with_tail (&elt, nargs - 1, args + 1, + Lisp_Object present = count_with_tail (&object_, nargs - 1, args + 1, Qnsubstitute); if (ZEROP (present)) @@ -8765,9 +8785,8 @@ presenting = presenting <= counting ? 0 : presenting - counting; } - GCPRO1 (tail); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) { if (!(ii < ending)) { @@ -8789,8 +8808,8 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } - UNGCPRO; if ((ii < starting || (ii < ending && !NILP (end))) && encountered < counting) @@ -8962,10 +8981,10 @@ (int nargs, Lisp_Object *args)) { Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil; - Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil; + Lisp_Object result = Qnil, result_tail = Qnil; Lisp_Object object, position0, matched_count; Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0; - Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0; + Elemcount ii = 0, counting = EMACS_INT_MAX, presenting = 0; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; struct gcpro gcpro1; @@ -9042,19 +9061,22 @@ presenting = presenting <= counting ? 0 : presenting - counting; } - GCPRO1 (tailing); + GCPRO1 (result); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len) + GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tailing) { if (EQ (tail, tailing)) { + XUNGCPRO (elt); + UNGCPRO; + if (NILP (result)) { - RETURN_UNGCPRO (XCDR (tail)); + return XCDR (tail); } XSETCDR (result_tail, XCDR (tail)); - RETURN_UNGCPRO (result); + return result; } else if (starting <= ii && ii < ending && (check_test (test, key, item, elt) == test_not_unboundp) @@ -9088,6 +9110,7 @@ ii++; } + END_GC_EXTERNAL_LIST_LOOP (elt); } UNGCPRO; @@ -9136,31 +9159,30 @@ check_test_func_t check_test, Boolint test_not_unboundp, Lisp_Object test, Lisp_Object key, int depth) { - Lisp_Object keyed = KEY (key, tree), tailed = alist, aa, dd; - struct gcpro gcpro1, gcpro2, gcpro3; + Lisp_Object keyed = KEY (key, tree), aa, dd; + struct gcpro gcpro1; if (depth + lisp_eval_depth > max_lisp_eval_depth) { stack_overflow ("Stack overflow in sublis", tree); } - GCPRO3 (tailed, alist, tree); { - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) { - tailed = tail; - - if (check_test (test, key, elt_car, keyed) == test_not_unboundp) + if (CONSP (elt) && + check_test (test, key, XCAR (elt), keyed) == test_not_unboundp) { - /* Don't use elt_cdr, it is helpful to allow TEST or KEY to - modify the alist while it executes. */ - RETURN_UNGCPRO (XCDR (elt)); + XUNGCPRO (elt); + return XCDR (elt); } } + END_GC_EXTERNAL_LIST_LOOP (elt); } + if (!CONSP (tree)) { - RETURN_UNGCPRO (tree); + return tree; } aa = sublis (alist, XCAR (tree), check_test, test_not_unboundp, test, key, @@ -9170,10 +9192,10 @@ if (EQ (aa, XCAR (tree)) && EQ (dd, XCDR (tree))) { - RETURN_UNGCPRO (tree); - } - - RETURN_UNGCPRO (Fcons (aa, dd)); + return tree; + } + + return Fcons (aa, dd); } DEFUN ("sublis", Fsublis, 2, MANY, 0, /* @@ -9223,8 +9245,8 @@ Boolint test_not_unboundp, Lisp_Object test, Lisp_Object key, int depth) { - Lisp_Object tree_saved = tree, tailed = alist, tortoise = tree, keyed = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + Lisp_Object tree_saved = tree, tortoise = tree, keyed = Qnil; + struct gcpro gcpro1, gcpro2; int count = 0; if (depth + lisp_eval_depth > max_lisp_eval_depth) @@ -9232,7 +9254,7 @@ stack_overflow ("Stack overflow in nsublis", tree); } - GCPRO4 (tailed, alist, tree_saved, keyed); + GCPRO2 (tree_saved, keyed); while (CONSP (tree)) { @@ -9240,11 +9262,10 @@ keyed = KEY (key, XCAR (tree)); { - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) { - tailed = tail; - - if (check_test (test, key, elt_car, keyed) == test_not_unboundp) + if (CONSP (elt) && + check_test (test, key, XCAR (elt), keyed) == test_not_unboundp) { CHECK_LISP_WRITEABLE (tree); /* See comment in sublis() on using elt_cdr. */ @@ -9253,6 +9274,7 @@ break; } } + END_GC_EXTERNAL_LIST_LOOP (elt); } if (!replaced) @@ -9268,19 +9290,18 @@ replaced = 0; { - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) { - tailed = tail; - - if (check_test (test, key, elt_car, keyed) == test_not_unboundp) + if (CONSP (elt) && + check_test (test, key, XCAR (elt), keyed) == test_not_unboundp) { CHECK_LISP_WRITEABLE (tree); - /* See comment in sublis() on using elt_cdr. */ XSETCDR (tree, XCDR (elt)); tree = Qnil; break; } } + END_GC_EXTERNAL_LIST_LOOP (elt); } if (!NILP (tree)) @@ -9341,16 +9362,16 @@ { /* nsublis() won't attempt to replace a cons handed to it, do that ourselves. */ - EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) + GC_EXTERNAL_LIST_LOOP_2 (elt, alist) { - tailed = tail; - - if (check_test (test, key, elt_car, keyed) == test_not_unboundp) + if (CONSP (elt) && + check_test (test, key, XCAR (elt), keyed) == test_not_unboundp) { - /* See comment in sublis() on using elt_cdr. */ - RETURN_UNGCPRO (XCDR (elt)); + XUNGCPRO (elt); + return XCDR (elt); } } + END_GC_EXTERNAL_LIST_LOOP (elt); } UNGCPRO; @@ -10521,13 +10542,12 @@ static Lisp_Object venn (Lisp_Object caller, int nargs, Lisp_Object *args, Boolint intersectionp) { - Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil; + Lisp_Object liszt1 = args[0], liszt2 = args[1]; Lisp_Object result = EQ (caller, Qsubsetp) ? Qt : Qnil, result_tail = Qnil; Lisp_Object keyed = Qnil, ignore = Qnil; - Elemcount len; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2; PARSE_KEYWORDS_8 (caller, nargs, args, 4, (test, key, test_not, stable), NULL, 2, 0); @@ -10550,10 +10570,10 @@ get_check_match_function (&test, test_not, Qnil, Qnil, key, &test_not_unboundp, &check_test); - GCPRO3 (tail, keyed, result); + GCPRO2 (keyed, result); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1) { keyed = KEY (key, elt); if (NILP (list_position_cons_before (&ignore, keyed, liszt2, @@ -10581,6 +10601,7 @@ } } } + END_GC_EXTERNAL_LIST_LOOP (elt); } UNGCPRO; @@ -10596,7 +10617,7 @@ Elemcount count; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; PARSE_KEYWORDS_8 (caller, nargs, args, 3, (test, key, test_not), NULL, 2, 0); @@ -10619,9 +10640,9 @@ get_check_match_function (&test, test_not, Qnil, Qnil, key, &test_not_unboundp, &check_test); - GCPRO3 (tail, keyed, liszt1); - - tortoise_elt = tail = liszt1, count = 0; + tortoise_elt = tail = liszt1, count = 0; + + GCPRO4 (tail, keyed, liszt1, tortoise_elt); while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 : (signal_malformed_list_error (liszt1), 0)) @@ -10793,11 +10814,10 @@ (int nargs, Lisp_Object *args)) { Lisp_Object liszt1 = args[0], liszt2 = args[1], ignore = Qnil; - Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, result, result_tail; - Elemcount len; + Lisp_Object keyed = Qnil, result, result_tail; Boolint test_not_unboundp = 1; check_test_func_t check_test = NULL, check_match = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2; PARSE_KEYWORDS (Funion, nargs, args, 4, (test, key, test_not, stable), NULL); @@ -10819,13 +10839,13 @@ check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, &test_not_unboundp, &check_test); - GCPRO3 (tail, keyed, result); + GCPRO2 (keyed, result); if (NILP (stable)) { result = liszt2; { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1) { keyed = KEY (key, elt); if (NILP (list_position_cons_before (&ignore, keyed, liszt2, @@ -10843,6 +10863,7 @@ result = Fcons (elt, result); } } + END_GC_EXTERNAL_LIST_LOOP (elt); } } else @@ -10856,7 +10877,7 @@ elements in any fashion; providing the functionality for a stable union is an XEmacs extension. */ { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, liszt2) { if (NILP (list_position_cons_before (&ignore, elt, liszt1, check_match, test_not_unboundp, @@ -10873,6 +10894,7 @@ } } } + END_GC_EXTERNAL_LIST_LOOP (elt); } result = NILP (result) ? liszt1 : nconc2 (Fcopy_list (liszt1), result); @@ -10900,12 +10922,11 @@ */ (int nargs, Lisp_Object *args)) { - Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil; + Lisp_Object liszt1 = args[0], liszt2 = args[1]; Lisp_Object result = Qnil, result_tail = Qnil, keyed = Qnil, ignore = Qnil; - Elemcount len; Boolint test_not_unboundp = 1; check_test_func_t check_match = NULL, check_test = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2; PARSE_KEYWORDS (Fset_exclusive_or, nargs, args, 4, (test, key, test_not, stable), NULL); @@ -10923,9 +10944,9 @@ check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, &test_not_unboundp, &check_test); - GCPRO3 (tail, keyed, result); + GCPRO2 (keyed, result); { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1) { keyed = KEY (key, elt); if (NILP (list_position_cons_before (&ignore, keyed, liszt2, @@ -10947,10 +10968,11 @@ } } } + END_GC_EXTERNAL_LIST_LOOP (elt); } { - EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len) + GC_EXTERNAL_LIST_LOOP_2 (elt, liszt2) { if (NILP (list_position_cons_before (&ignore, elt, liszt1, check_match, test_not_unboundp, @@ -10971,7 +10993,9 @@ } } } + END_GC_EXTERNAL_LIST_LOOP (elt); } + UNGCPRO; return result; @@ -10996,7 +11020,7 @@ Elemcount count; Boolint test_not_unboundp = 1; check_test_func_t check_match = NULL, check_test = NULL; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; PARSE_KEYWORDS (Fnset_exclusive_or, nargs, args, 4, (test, key, test_not, stable), NULL); @@ -11014,10 +11038,10 @@ check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, &test_not_unboundp, &check_test); - GCPRO3 (tail, keyed, result); - tortoise_elt = tail = liszt1, count = 0; + GCPRO4 (tail, keyed, result, tortoise_elt); + while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 : (signal_malformed_list_error (liszt1), 0)) {