comparison src/fns.c @ 5034:1b96882bdf37

Fix a multiple-value bug, mapcarX; correct a comment and a label name. src/ChangeLog addition: 2010-02-19 Aidan Kehoe <kehoea@parhasard.net> * fns.c (mapcarX): Correct this function, discarding multiple values when one SEQUENCE is supplied, choosing a better label name. Correct the comment describing the SOME_OR_EVERY argument. tests/ChangeLog addition: 2010-02-19 Aidan Kehoe <kehoea@parhasard.net> * automated/lisp-tests.el: Check that multiple values are discarded correctly with #'mapcar and one SEQUENCE.
author Aidan Kehoe <kehoea@parhasard.net>
date Fri, 19 Feb 2010 23:21:27 +0000
parents 0cd784a6ec44
children b1e48555be7d
comparison
equal deleted inserted replaced
5033:d2c3bac89ba0 5034:1b96882bdf37
3229 3229
3230 Call FUNCTION CALL_COUNT times, with NSEQUENCES arguments each time, 3230 Call FUNCTION CALL_COUNT times, with NSEQUENCES arguments each time,
3231 taking the elements from SEQUENCES. If VALS is non-NULL, store the 3231 taking the elements from SEQUENCES. If VALS is non-NULL, store the
3232 results into VALS, a C array of Lisp_Objects; else, if LISP_VALS is 3232 results into VALS, a C array of Lisp_Objects; else, if LISP_VALS is
3233 non-nil, store the results into LISP_VALS, a sequence with sufficient 3233 non-nil, store the results into LISP_VALS, a sequence with sufficient
3234 room for CALL_COUNT results. Else, do not accumulate any result. 3234 room for CALL_COUNT results (but see the documentation of SOME_OR_EVERY.)
3235 Else, do not accumulate any result.
3235 3236
3236 If VALS is non-NULL, NSEQUENCES is one, and SEQUENCES[0] is a cons, 3237 If VALS is non-NULL, NSEQUENCES is one, and SEQUENCES[0] is a cons,
3237 mapcarX will store the elements of SEQUENCES[0] in stack and GCPRO them, 3238 mapcarX will store the elements of SEQUENCES[0] in stack and GCPRO them,
3238 so FUNCTION cannot insert a non-cons into SEQUENCES[0] and throw off 3239 so FUNCTION cannot insert a non-cons into SEQUENCES[0] and throw off
3239 mapcarX. 3240 mapcarX.
3244 destructively modifies SEQUENCES in a way that might affect the ongoing 3245 destructively modifies SEQUENCES in a way that might affect the ongoing
3245 traversal operation. 3246 traversal operation.
3246 3247
3247 If SOME_OR_EVERY is SOME_OR_EVERY_SOME, return the (possibly multiple) 3248 If SOME_OR_EVERY is SOME_OR_EVERY_SOME, return the (possibly multiple)
3248 values given by FUNCTION the first time it is non-nil, and abandon the 3249 values given by FUNCTION the first time it is non-nil, and abandon the
3249 iterations. LISP_VALS in this case must be an object created by 3250 iterations. LISP_VALS must be a cons, and the return value will be
3250 make_opaque_ptr, dereferenced as pointing to a Lisp object. If 3251 stored in its car. If SOME_OR_EVERY is SOME_OR_EVERY_EVERY, store Qnil
3251 SOME_OR_EVERY is SOME_OR_EVERY_EVERY, store Qnil at the Lisp_Object 3252 in the car of LISP_VALS if FUNCTION gives nil; otherwise leave it
3252 pointer address provided by LISP_VALS if FUNCTION gives nil; otherwise 3253 alone. */
3253 leave it alone. */
3254 3254
3255 #define SOME_OR_EVERY_NEITHER 0 3255 #define SOME_OR_EVERY_NEITHER 0
3256 #define SOME_OR_EVERY_SOME 1 3256 #define SOME_OR_EVERY_SOME 1
3257 #define SOME_OR_EVERY_EVERY 2 3257 #define SOME_OR_EVERY_EVERY 2
3258 3258
3304 gcpro2.nvars = call_count; 3304 gcpro2.nvars = call_count;
3305 3305
3306 for (i = 0; i < call_count; ++i) 3306 for (i = 0; i < call_count; ++i)
3307 { 3307 {
3308 args[1] = vals[i]; 3308 args[1] = vals[i];
3309 vals[i] = Ffuncall (nsequences + 1, args); 3309 vals[i] = IGNORE_MULTIPLE_VALUES (Ffuncall (nsequences + 1, args));
3310 } 3310 }
3311 } 3311 }
3312 else 3312 else
3313 { 3313 {
3314 Binbyte *sequence_types = alloca_array (Binbyte, nsequences); 3314 Binbyte *sequence_types = alloca_array (Binbyte, nsequences);
3411 return; 3411 return;
3412 } 3412 }
3413 break; 3413 break;
3414 } 3414 }
3415 3415
3416 goto bad_show_or_every_flag; 3416 goto bad_some_or_every_flag;
3417 } 3417 }
3418 case lrecord_type_vector: 3418 case lrecord_type_vector:
3419 { 3419 {
3420 called = IGNORE_MULTIPLE_VALUES (called); 3420 called = IGNORE_MULTIPLE_VALUES (called);
3421 i < XVECTOR_LENGTH (lisp_vals) ? 3421 i < XVECTOR_LENGTH (lisp_vals) ?
3441 set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i, 3441 set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i,
3442 XINT (called)) : 3442 XINT (called)) :
3443 (void) Faset (lisp_vals, make_int (i), called); 3443 (void) Faset (lisp_vals, make_int (i), called);
3444 break; 3444 break;
3445 } 3445 }
3446 bad_show_or_every_flag: 3446 bad_some_or_every_flag:
3447 default: 3447 default:
3448 { 3448 {
3449 ABORT(); 3449 ABORT();
3450 break; 3450 break;
3451 } 3451 }