diff options
| author | Stefan Monnier | 2013-12-04 17:10:46 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-12-04 17:10:46 -0500 |
| commit | 105324ced442852eba6af80605867afe46b3dba5 (patch) | |
| tree | 3b2ec38187cc64c72df0bd5174581e59065921d8 /src | |
| parent | 39eb08995a79187ae645e06ed74953af0184c497 (diff) | |
| download | emacs-105324ced442852eba6af80605867afe46b3dba5.tar.gz emacs-105324ced442852eba6af80605867afe46b3dba5.zip | |
* src/lisp.h (FOR_EACH_TAIL): New macro.
* src/fns.c (Fdelq): Use it to avoid inf-loops; remove QUIT.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 3 | ||||
| -rw-r--r-- | src/fns.c | 13 | ||||
| -rw-r--r-- | src/lisp.h | 14 |
3 files changed, 21 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c88f48af517..2a4da678b56 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | 2013-12-04 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2013-12-04 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * lisp.h (FOR_EACH_TAIL): New macro. | ||
| 4 | * fns.c (Fdelq): Use it to avoid inf-loops; remove QUIT. | ||
| 5 | |||
| 3 | * window.c (select_window): Call second wset_redisplay before we change | 6 | * window.c (select_window): Call second wset_redisplay before we change |
| 4 | selected_window (bug#16034). | 7 | selected_window (bug#16034). |
| 5 | 8 | ||
| @@ -1537,15 +1537,12 @@ Write `(setq foo (delq element foo))' to be sure of correctly changing | |||
| 1537 | the value of a list `foo'. */) | 1537 | the value of a list `foo'. */) |
| 1538 | (register Lisp_Object elt, Lisp_Object list) | 1538 | (register Lisp_Object elt, Lisp_Object list) |
| 1539 | { | 1539 | { |
| 1540 | register Lisp_Object tail, prev; | 1540 | Lisp_Object tail, tortoise, prev = Qnil; |
| 1541 | register Lisp_Object tem; | 1541 | bool skip; |
| 1542 | 1542 | ||
| 1543 | tail = list; | 1543 | FOR_EACH_TAIL (tail, list, tortoise, skip) |
| 1544 | prev = Qnil; | ||
| 1545 | while (CONSP (tail)) | ||
| 1546 | { | 1544 | { |
| 1547 | CHECK_LIST_CONS (tail, list); | 1545 | Lisp_Object tem = XCAR (tail); |
| 1548 | tem = XCAR (tail); | ||
| 1549 | if (EQ (elt, tem)) | 1546 | if (EQ (elt, tem)) |
| 1550 | { | 1547 | { |
| 1551 | if (NILP (prev)) | 1548 | if (NILP (prev)) |
| @@ -1555,8 +1552,6 @@ the value of a list `foo'. */) | |||
| 1555 | } | 1552 | } |
| 1556 | else | 1553 | else |
| 1557 | prev = tail; | 1554 | prev = tail; |
| 1558 | tail = XCDR (tail); | ||
| 1559 | QUIT; | ||
| 1560 | } | 1555 | } |
| 1561 | return list; | 1556 | return list; |
| 1562 | } | 1557 | } |
diff --git a/src/lisp.h b/src/lisp.h index 60cbc98daf8..d8cf6b6960e 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4443,6 +4443,20 @@ extern void *record_xmalloc (size_t); | |||
| 4443 | memory_full (SIZE_MAX); \ | 4443 | memory_full (SIZE_MAX); \ |
| 4444 | } while (0) | 4444 | } while (0) |
| 4445 | 4445 | ||
| 4446 | /* Loop over all tails of a list, checking for cycles. | ||
| 4447 | FIXME: Make tortoise and n internal declarations. | ||
| 4448 | FIXME: Unroll the loop body so we don't need `n'. */ | ||
| 4449 | #define FOR_EACH_TAIL(hare, list, tortoise, n) \ | ||
| 4450 | for (tortoise = hare = (list), n = true; \ | ||
| 4451 | CONSP (hare); \ | ||
| 4452 | (hare = XCDR (hare), n = !n, \ | ||
| 4453 | (n \ | ||
| 4454 | ? ((EQ (hare, tortoise) \ | ||
| 4455 | && (xsignal1 (Qcircular_list, (list)), 0))) \ | ||
| 4456 | /* Move tortoise before the next iteration, in case */ \ | ||
| 4457 | /* the next iteration does an Fsetcdr. */ \ | ||
| 4458 | : (tortoise = XCDR (tortoise), 0)))) | ||
| 4459 | |||
| 4446 | /* Do a `for' loop over alist values. */ | 4460 | /* Do a `for' loop over alist values. */ |
| 4447 | 4461 | ||
| 4448 | #define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ | 4462 | #define FOR_EACH_ALIST_VALUE(head_var, list_var, value_var) \ |