* src/lisp.h (FOR_EACH_TAIL): New macro.

* src/fns.c (Fdelq): Use it to avoid inf-loops; remove QUIT.
This commit is contained in:
Stefan Monnier 2013-12-04 17:10:46 -05:00
parent 39eb08995a
commit 105324ced4
3 changed files with 21 additions and 9 deletions

View file

@ -1,5 +1,8 @@
2013-12-04 Stefan Monnier <monnier@iro.umontreal.ca>
* lisp.h (FOR_EACH_TAIL): New macro.
* fns.c (Fdelq): Use it to avoid inf-loops; remove QUIT.
* window.c (select_window): Call second wset_redisplay before we change
selected_window (bug#16034).

View file

@ -1537,15 +1537,12 @@ Write `(setq foo (delq element foo))' to be sure of correctly changing
the value of a list `foo'. */)
(register Lisp_Object elt, Lisp_Object list)
{
register Lisp_Object tail, prev;
register Lisp_Object tem;
Lisp_Object tail, tortoise, prev = Qnil;
bool skip;
tail = list;
prev = Qnil;
while (CONSP (tail))
FOR_EACH_TAIL (tail, list, tortoise, skip)
{
CHECK_LIST_CONS (tail, list);
tem = XCAR (tail);
Lisp_Object tem = XCAR (tail);
if (EQ (elt, tem))
{
if (NILP (prev))
@ -1555,8 +1552,6 @@ the value of a list `foo'. */)
}
else
prev = tail;
tail = XCDR (tail);
QUIT;
}
return list;
}

View file

@ -4443,6 +4443,20 @@ extern void *record_xmalloc (size_t);
memory_full (SIZE_MAX); \
} while (0)
/* Loop over all tails of a list, checking for cycles.
FIXME: Make tortoise and n internal declarations.
FIXME: Unroll the loop body so we don't need `n'. */
#define FOR_EACH_TAIL(hare, list, tortoise, n) \
for (tortoise = hare = (list), n = true; \
CONSP (hare); \
(hare = XCDR (hare), n = !n, \
(n \
? ((EQ (hare, tortoise) \
&& (xsignal1 (Qcircular_list, (list)), 0))) \
/* Move tortoise before the next iteration, in case */ \
/* the next iteration does an Fsetcdr. */ \
: (tortoise = XCDR (tortoise), 0))))
/* Do a `for' loop over alist values. */
#define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \