OK, I'm confused again. The enclosed patch won't apply at all to
21.1. Kyle, is there a similar patch you want to apply for 21.1? I
can't grok what's supposed to be going on from the limited context in
the patch. The code you referenced does not appear in mapcar1 in
21.1.
- vin
>>>> On Thu, 16 Dec 1999, Kyle Jones
<kyle_jones(a)wonderworks.com> said:
Kyle> Jan Vroonhof writes:
> Here is an easier one
>
> (let ((lijst '(a b c)))
> (mapcar
> (lambda (x)
> ;; Make list shorter behind mapcar's back
> (delete 'c lijst))
> lijst))
>
> The problem is this code in in mapcar1
>
> if (LISTP (seq))
> {
> for (i = 0; i < leni; i++)
> {
> args[1] = XCAR (seq);
> seq = XCDR (seq);
> result = Ffuncall (2, args);
> if (vals) vals[gcpro1.nvars++] = result;
> }
> }
>
> It blindingly believes that XCDR(seq) will always be a cons cell,
> although it calls user code which could have modified the list it is
> iterating over.
Kyle> Here's a patch that fixes this. Recommended for 21.1 and 21.2.
Kyle> 1999-12-16 Kyle Jones <kyle_jones(a)wonderworks.com>
Kyle> * fns.c (mapcar1): when iterating over a list, check for
Kyle> CONSP each iteration because bad user code might have
Kyle> modified the list. Call Fcdr/Fcar if CONSP check fails
Kyle> so that malformed lists cause an error to be signaled
Kyle> instead of crashing.
Kyle> --- src/fns.c 1999/10/24 03:48:39 1.30.2.23
Kyle> +++ src/fns.c 1999/12/17 04:13:14
Kyle> @@ -3070,8 +3070,19 @@
Kyle> {
Kyle> for (i = 0; i < leni; i++)
Kyle> {
Kyle> - args[1] = XCAR (seq);
Kyle> - seq = XCDR (seq);
Kyle> + /* Use XCAR/XCDR to avoid function call overhead if we can.
Kyle> + Otherwise call Fcar and Fcdr to get exceptions signaled
Kyle> + if the Lisp code mangles the list. */
Kyle> + if (CONSP (seq))
Kyle> + {
Kyle> + args[1] = XCAR (seq);
Kyle> + seq = XCDR (seq);
Kyle> + }
Kyle> + else
Kyle> + {
Kyle> + args[1] = Fcar (seq);
Kyle> + seq = Fcdr (seq);
Kyle> + }
Kyle> result = Ffuncall (2, args);
Kyle> if (vals) vals[gcpro1.nvars++] = result;
Kyle> }