comparison src/fns.c @ 4996:c17c857e20bf

Merge.
author Aidan Kehoe <kehoea@parhasard.net>
date Wed, 03 Feb 2010 20:18:53 +0000
parents 6bc1f3f6cf0d 8431b52e43b1
children 8800b5350a13
comparison
equal deleted inserted replaced
4927:5274591ce707 4996:c17c857e20bf
54 /* NOTE: This symbol is also used in lread.c */ 54 /* NOTE: This symbol is also used in lread.c */
55 #define FEATUREP_SYNTAX 55 #define FEATUREP_SYNTAX
56 56
57 Lisp_Object Qstring_lessp; 57 Lisp_Object Qstring_lessp;
58 Lisp_Object Qidentity; 58 Lisp_Object Qidentity;
59 Lisp_Object Qvector, Qarray, Qstring, Qlist, Qbit_vector;
59 60
60 Lisp_Object Qbase64_conversion_error; 61 Lisp_Object Qbase64_conversion_error;
61 62
62 Lisp_Object Vpath_separator; 63 Lisp_Object Vpath_separator;
63 64
980 */ 981 */
981 (sequence, start, end)) 982 (sequence, start, end))
982 { 983 {
983 EMACS_INT len, s, e; 984 EMACS_INT len, s, e;
984 985
986 CHECK_SEQUENCE (sequence);
987
985 if (STRINGP (sequence)) 988 if (STRINGP (sequence))
986 return Fsubstring (sequence, start, end); 989 return Fsubstring (sequence, start, end);
987 990
988 len = XINT (Flength (sequence)); 991 len = XINT (Flength (sequence));
989 992
1041 bit_vector_bit (XBIT_VECTOR (sequence), i)); 1044 bit_vector_bit (XBIT_VECTOR (sequence), i));
1042 return result; 1045 return result;
1043 } 1046 }
1044 else 1047 else
1045 { 1048 {
1046 ABORT (); /* unreachable, since Flength (sequence) did not get 1049 ABORT (); /* unreachable, since CHECK_SEQUENCE (sequence) did not
1047 an error */ 1050 error */
1048 return Qnil; 1051 return Qnil;
1049 } 1052 }
1050 } 1053 }
1051 1054
1052 /* Split STRING into a list of substrings. The substrings are the 1055 /* Split STRING into a list of substrings. The substrings are the
3221 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */ 3224 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */
3222 } 3225 }
3223 3226
3224 3227
3225 /* This is the guts of several mapping functions. 3228 /* This is the guts of several mapping functions.
3226 Apply FUNCTION to each element of SEQUENCE, one by one, 3229
3227 storing the results into elements of VALS, a C vector of Lisp_Objects. 3230 Call FUNCTION CALL_COUNT times, with NSEQUENCES arguments each time,
3228 LENI is the length of VALS, which should also be the length of SEQUENCE. 3231 taking the elements from SEQUENCES. If VALS is non-NULL, store the
3229 3232 results into VALS, a C array of Lisp_Objects; else, if LISP_VALS is
3230 If VALS is a null pointer, do not accumulate the results. */ 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.
3235
3236 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 so FUNCTION cannot insert a non-cons into SEQUENCES[0] and throw off
3239 mapcarX.
3240
3241 Otherwise, mapcarX signals a wrong-type-error if it encounters a
3242 non-cons, non-array when traversing SEQUENCES. Common Lisp specifies in
3243 MAPPING-DESTRUCTIVE-INTERACTION that it is an error when FUNCTION
3244 destructively modifies SEQUENCES in a way that might affect the ongoing
3245 traversal operation. */
3231 3246
3232 static void 3247 static void
3233 mapcar1 (Elemcount leni, Lisp_Object *vals, 3248 mapcarX (Elemcount call_count, Lisp_Object *vals, Lisp_Object lisp_vals,
3234 Lisp_Object function, Lisp_Object sequence) 3249 Lisp_Object function, int nsequences, Lisp_Object *sequences)
3235 { 3250 {
3236 Lisp_Object result; 3251 Lisp_Object called, *args;
3237 Lisp_Object args[2]; 3252 struct gcpro gcpro1, gcpro2;
3238 struct gcpro gcpro1; 3253 int i, j;
3239 3254 enum lrecord_type lisp_vals_type;
3240 if (vals) 3255
3241 { 3256 assert (LRECORDP (lisp_vals));
3242 GCPRO1 (vals[0]); 3257 lisp_vals_type = XRECORD_LHEADER (lisp_vals)->type;
3243 gcpro1.nvars = 0; 3258
3244 } 3259 args = alloca_array (Lisp_Object, nsequences + 1);
3245
3246 args[0] = function; 3260 args[0] = function;
3247 3261 for (i = 1; i <= nsequences; ++i)
3248 if (LISTP (sequence)) 3262 {
3249 { 3263 args[i] = Qnil;
3250 /* A devious `function' could either: 3264 }
3251 - insert garbage into the list in front of us, causing XCDR to crash 3265
3252 - amputate the list behind us using (setcdr), causing the remaining 3266 if (vals != NULL)
3253 elts to lose their GCPRO status. 3267 {
3254 3268 GCPRO2 (args[0], vals[0]);
3255 if (vals != 0) we avoid this by copying the elts into the 3269 gcpro1.nvars = nsequences + 1;
3256 `vals' array. By a stroke of luck, `vals' is exactly large 3270 gcpro2.nvars = 0;
3257 enough to hold the elts left to be traversed as well as the 3271 }
3258 results computed so far. 3272 else
3259 3273 {
3260 if (vals == 0) we don't have any free space available and 3274 GCPRO1 (args[0]);
3261 don't want to eat up any more stack with ALLOCA (). 3275 gcpro1.nvars = nsequences + 1;
3262 So we use EXTERNAL_LIST_LOOP_3_NO_DECLARE and GCPRO the tail. */ 3276 }
3263 3277
3264 if (vals) 3278 /* Be extra nice in the event that we've been handed one list and one
3265 { 3279 only; make it possible for FUNCTION to set cdrs not yet processed to
3266 Lisp_Object *val = vals; 3280 non-cons, non-nil objects without ill-effect, if we have been handed
3267 Elemcount i; 3281 the stack space to do that. */
3268 3282 if (vals != NULL && 1 == nsequences && CONSP (sequences[0]))
3269 LIST_LOOP_2 (elt, sequence) 3283 {
3270 *val++ = elt; 3284 Lisp_Object lst = sequences[0];
3271 3285 Lisp_Object *val = vals;
3272 gcpro1.nvars = leni; 3286 for (i = 0; i < call_count; ++i)
3273 3287 {
3274 for (i = 0; i < leni; i++) 3288 *val++ = XCAR (lst);
3289 lst = XCDR (lst);
3290 }
3291 gcpro2.nvars = call_count;
3292
3293 for (i = 0; i < call_count; ++i)
3294 {
3295 args[1] = vals[i];
3296 vals[i] = Ffuncall (nsequences + 1, args);
3297 }
3298 }
3299 else
3300 {
3301 Binbyte *sequence_types = alloca_array (Binbyte, nsequences);
3302 for (j = 0; j < nsequences; ++j)
3303 {
3304 sequence_types[j] = XRECORD_LHEADER (sequences[j])->type;
3305 }
3306
3307 for (i = 0; i < call_count; ++i)
3308 {
3309 for (j = 0; j < nsequences; ++j)
3275 { 3310 {
3276 args[1] = vals[i]; 3311 switch (sequence_types[j])
3277 vals[i] = Ffuncall (2, args); 3312 {
3313 case lrecord_type_cons:
3314 {
3315 if (!CONSP (sequences[j]))
3316 {
3317 /* This means FUNCTION has probably messed
3318 around with a cons in one of the sequences,
3319 since we checked the type
3320 (CHECK_SEQUENCE()) and the length and
3321 structure (with Flength()) correctly in our
3322 callers. */
3323 dead_wrong_type_argument (Qconsp, sequences[j]);
3324 }
3325 args[j + 1] = XCAR (sequences[j]);
3326 sequences[j] = XCDR (sequences[j]);
3327 break;
3328 }
3329 case lrecord_type_vector:
3330 {
3331 args[j + 1] = XVECTOR_DATA (sequences[j])[i];
3332 break;
3333 }
3334 case lrecord_type_string:
3335 {
3336 args[j + 1] = make_char (string_ichar (sequences[j], i));
3337 break;
3338 }
3339 case lrecord_type_bit_vector:
3340 {
3341 args[j + 1]
3342 = make_int (bit_vector_bit (XBIT_VECTOR (sequences[j]),
3343 i));
3344 break;
3345 }
3346 default:
3347 ABORT();
3348 }
3278 } 3349 }
3279 } 3350 called = Ffuncall (nsequences + 1, args);
3280 else 3351 if (vals != NULL)
3281 { 3352 {
3282 Lisp_Object elt, tail; 3353 vals[i] = called;
3283 EMACS_INT len_unused; 3354 gcpro2.nvars += 1;
3284 struct gcpro ngcpro1; 3355 }
3285 3356 else
3286 NGCPRO1 (tail); 3357 {
3287 3358 switch (lisp_vals_type)
3288 { 3359 {
3289 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len_unused) 3360 case lrecord_type_symbol:
3290 { 3361 break;
3291 args[1] = elt; 3362 case lrecord_type_cons:
3292 Ffuncall (2, args); 3363 {
3293 } 3364 if (!CONSP (lisp_vals))
3294 } 3365 {
3295 3366 /* If FUNCTION has inserted a non-cons non-nil cdr
3296 NUNGCPRO; 3367 into the list before we've processed the relevant
3297 } 3368 part, error. */
3298 } 3369 dead_wrong_type_argument (Qconsp, lisp_vals);
3299 else if (VECTORP (sequence)) 3370 }
3300 { 3371
3301 Lisp_Object *objs = XVECTOR_DATA (sequence); 3372 XSETCAR (lisp_vals, called);
3302 Elemcount i; 3373 lisp_vals = XCDR (lisp_vals);
3303 for (i = 0; i < leni; i++) 3374 break;
3304 { 3375 }
3305 args[1] = *objs++; 3376 case lrecord_type_vector:
3306 result = Ffuncall (2, args); 3377 {
3307 if (vals) vals[gcpro1.nvars++] = result; 3378 i < XVECTOR_LENGTH (lisp_vals) ?
3308 } 3379 (XVECTOR_DATA (lisp_vals)[i] = called) :
3309 } 3380 /* Let #'aset error. */
3310 else if (STRINGP (sequence)) 3381 Faset (lisp_vals, make_int (i), called);
3311 { 3382 break;
3312 /* The string data of `sequence' might be relocated during GC. */ 3383 }
3313 Bytecount slen = XSTRING_LENGTH (sequence); 3384 case lrecord_type_string:
3314 Ibyte *p = alloca_ibytes (slen); 3385 {
3315 Ibyte *end = p + slen; 3386 /* If this ever becomes a code hotspot, we can keep
3316 3387 around pointers into the data of the string, checking
3317 memcpy (p, XSTRING_DATA (sequence), slen); 3388 each time that it hasn't been relocated. */
3318 3389 Faset (lisp_vals, make_int (i), called);
3319 while (p < end) 3390 break;
3320 { 3391 }
3321 args[1] = make_char (itext_ichar (p)); 3392 case lrecord_type_bit_vector:
3322 INC_IBYTEPTR (p); 3393 {
3323 result = Ffuncall (2, args); 3394 (BITP (called) &&
3324 if (vals) vals[gcpro1.nvars++] = result; 3395 i < bit_vector_length (XBIT_VECTOR (lisp_vals))) ?
3325 } 3396 set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i,
3326 } 3397 XINT (called)) :
3327 else if (BIT_VECTORP (sequence)) 3398 Faset (lisp_vals, make_int (i), called);
3328 { 3399 break;
3329 Lisp_Bit_Vector *v = XBIT_VECTOR (sequence); 3400 }
3330 Elemcount i; 3401 default:
3331 for (i = 0; i < leni; i++) 3402 {
3332 { 3403 ABORT();
3333 args[1] = make_int (bit_vector_bit (v, i)); 3404 break;
3334 result = Ffuncall (2, args); 3405 }
3335 if (vals) vals[gcpro1.nvars++] = result; 3406 }
3336 } 3407 }
3337 } 3408 }
3338 else 3409 }
3339 ABORT (); /* unreachable, since Flength (sequence) did not get an error */ 3410 UNGCPRO;
3340 3411 }
3341 if (vals) 3412
3342 UNGCPRO; 3413 DEFUN ("mapconcat", Fmapconcat, 3, MANY, 0, /*
3343 } 3414 Call FUNCTION on each element of SEQUENCE, and concat results to a string.
3344
3345 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /*
3346 Apply FUNCTION to each element of SEQUENCE, and concat the results to a string.
3347 Between each pair of results, insert SEPARATOR. 3415 Between each pair of results, insert SEPARATOR.
3348 3416
3349 Each result, and SEPARATOR, should be strings. Thus, using " " as SEPARATOR 3417 Each result, and SEPARATOR, should be strings. Thus, using " " as SEPARATOR
3350 results in spaces between the values returned by FUNCTION. SEQUENCE itself 3418 results in spaces between the values returned by FUNCTION. SEQUENCE itself
3351 may be a list, a vector, a bit vector, or a string. 3419 may be a list, a vector, a bit vector, or a string.
3352 */ 3420
3353 (function, sequence, separator)) 3421 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3354 { 3422 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3355 EMACS_INT len = XINT (Flength (sequence)); 3423 from each sequence will be used each time FUNCTION is called, and
3356 Lisp_Object *args; 3424 `mapconcat' will give up once the shortest sequence is exhausted.
3357 EMACS_INT i; 3425
3358 EMACS_INT nargs = len + len - 1; 3426 arguments: (FUNCTION SEQUENCE SEPARATOR &rest SEQUENCES)
3427 */
3428 (int nargs, Lisp_Object *args))
3429 {
3430 Lisp_Object function = args[0];
3431 Lisp_Object sequence = args[1];
3432 Lisp_Object separator = args[2];
3433 Elemcount len = EMACS_INT_MAX;
3434 Lisp_Object *args0;
3435 EMACS_INT i, nargs0;
3436
3437 args[2] = sequence;
3438 args[1] = separator;
3439
3440 for (i = 2; i < nargs; ++i)
3441 {
3442 CHECK_SEQUENCE (args[i]);
3443 len = min (len, XINT (Flength (args[i])));
3444 }
3359 3445
3360 if (len == 0) return build_string (""); 3446 if (len == 0) return build_string ("");
3361 3447
3362 args = alloca_array (Lisp_Object, nargs); 3448 nargs0 = len + len - 1;
3363 3449 args0 = alloca_array (Lisp_Object, nargs0);
3364 mapcar1 (len, args, function, sequence); 3450
3451 /* Special-case this, it's very common and doesn't require any
3452 funcalls. Upside of doing it here, instead of cl-macs.el: no consing,
3453 apart from the final string, we allocate everything on the stack. */
3454 if (EQ (function, Qidentity) && 3 == nargs && CONSP (sequence))
3455 {
3456 for (i = 0; i < len; ++i)
3457 {
3458 args0[i] = XCAR (sequence);
3459 sequence = XCDR (sequence);
3460 }
3461 }
3462 else
3463 {
3464 mapcarX (len, args0, Qnil, function, nargs - 2, args + 2);
3465 }
3365 3466
3366 for (i = len - 1; i >= 0; i--) 3467 for (i = len - 1; i >= 0; i--)
3367 args[i + i] = args[i]; 3468 args0[i + i] = args0[i];
3368 3469
3369 for (i = 1; i < nargs; i += 2) 3470 for (i = 1; i < nargs0; i += 2)
3370 args[i] = separator; 3471 args0[i] = separator;
3371 3472
3372 return Fconcat (nargs, args); 3473 return Fconcat (nargs0, args0);
3373 } 3474 }
3374 3475
3375 DEFUN ("mapcar", Fmapcar, 2, 2, 0, /* 3476 DEFUN ("mapcar*", FmapcarX, 2, MANY, 0, /*
3376 Apply FUNCTION to each element of SEQUENCE; return a list of the results. 3477 Call FUNCTION on each element of SEQUENCE; return a list of the results.
3377 The result is a list of the same length as SEQUENCE. 3478 The result is a list of the same length as SEQUENCE.
3378 SEQUENCE may be a list, a vector, a bit vector, or a string. 3479 SEQUENCE may be a list, a vector, a bit vector, or a string.
3379 */ 3480
3380 (function, sequence)) 3481 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3381 { 3482 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3382 Elemcount len = XINT (Flength (sequence)); 3483 from each sequence will be used each time FUNCTION is called, and `mapcar'
3383 Lisp_Object *args = alloca_array (Lisp_Object, len); 3484 stops calling FUNCTION once the shortest sequence is exhausted.
3384 3485
3385 mapcar1 (len, args, function, sequence); 3486 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3386 3487 */
3387 return Flist ((int) len, args); 3488 (int nargs, Lisp_Object *args))
3388 } 3489 {
3389 3490 Lisp_Object function = args[0];
3390 DEFUN ("mapvector", Fmapvector, 2, 2, 0, /* 3491 Elemcount len = EMACS_INT_MAX;
3391 Apply FUNCTION to each element of SEQUENCE; return a vector of the results. 3492 Lisp_Object *args0;
3493 int i;
3494
3495 for (i = 1; i < nargs; ++i)
3496 {
3497 CHECK_SEQUENCE (args[i]);
3498 len = min (len, XINT (Flength (args[i])));
3499 }
3500
3501 args0 = alloca_array (Lisp_Object, len);
3502 mapcarX (len, args0, Qnil, function, nargs - 1, args + 1);
3503
3504 return Flist ((int) len, args0);
3505 }
3506
3507 DEFUN ("mapvector", Fmapvector, 2, MANY, 0, /*
3508 Call FUNCTION on each element of SEQUENCE; return a vector of the results.
3392 The result is a vector of the same length as SEQUENCE. 3509 The result is a vector of the same length as SEQUENCE.
3393 SEQUENCE may be a list, a vector, a bit vector, or a string. 3510 SEQUENCE may be a list, a vector, a bit vector, or a string.
3394 */ 3511
3395 (function, sequence)) 3512 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3396 { 3513 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3397 Elemcount len = XINT (Flength (sequence)); 3514 from each sequence will be used each time FUNCTION is called, and
3398 Lisp_Object result = make_vector (len, Qnil); 3515 `mapvector' stops calling FUNCTION once the shortest sequence is exhausted.
3516
3517 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3518 */
3519 (int nargs, Lisp_Object *args))
3520 {
3521 Lisp_Object function = args[0];
3522 Elemcount len = EMACS_INT_MAX;
3523 Lisp_Object result;
3399 struct gcpro gcpro1; 3524 struct gcpro gcpro1;
3400 3525 int i;
3526
3527 for (i = 1; i < nargs; ++i)
3528 {
3529 CHECK_SEQUENCE (args[i]);
3530 len = min (len, XINT (Flength (args[i])));
3531 }
3532
3533 result = make_vector (len, Qnil);
3401 GCPRO1 (result); 3534 GCPRO1 (result);
3402 mapcar1 (len, XVECTOR_DATA (result), function, sequence); 3535 /* Don't pass result as the lisp_object argument, we want mapcarX to protect
3536 a single list argument's elements from being garbage-collected. */
3537 mapcarX (len, XVECTOR_DATA (result), Qnil, function, nargs - 1, args +1);
3403 UNGCPRO; 3538 UNGCPRO;
3404 3539
3405 return result; 3540 return result;
3406 } 3541 }
3407 3542
3408 DEFUN ("mapc-internal", Fmapc_internal, 2, 2, 0, /* 3543 DEFUN ("mapcan", Fmapcan, 2, MANY, 0, /*
3409 Apply FUNCTION to each element of SEQUENCE. 3544 Call FUNCTION on each element of SEQUENCE; chain the results together.
3545
3546 FUNCTION must normally return a list; the results will be concatenated
3547 together using `nconc'.
3548
3549 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3550 there are SEQUENCES, plus one for the element from SEQUENCE. One element
3551 from each sequence will be used each time FUNCTION is called, and
3552 `mapcan' stops calling FUNCTION once the shortest sequence is exhausted.
3553
3554 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3555 */
3556 (int nargs, Lisp_Object *args))
3557 {
3558 Lisp_Object function = args[0], nconcing;
3559 Elemcount len = EMACS_INT_MAX;
3560 Lisp_Object *args0;
3561 struct gcpro gcpro1;
3562 int i;
3563
3564 for (i = 1; i < nargs; ++i)
3565 {
3566 CHECK_SEQUENCE (args[i]);
3567 len = min (len, XINT (Flength (args[i])));
3568 }
3569
3570 args0 = alloca_array (Lisp_Object, len + 1);
3571 mapcarX (len, args0 + 1, Qnil, function, nargs - 1, args + 1);
3572
3573 if (len < 2)
3574 {
3575 return len ? args0[1] : Qnil;
3576 }
3577
3578 /* bytecode_nconc2 can signal and return, we need to GCPRO the args, since
3579 mapcarX is no longer doing this for us. */
3580 args0[0] = Fcons (Qnil, Qnil);
3581 GCPRO1 (args0[0]);
3582 gcpro1.nvars = len + 1;
3583
3584 for (i = 0; i < len; ++i)
3585 {
3586 nconcing = bytecode_nconc2 (args0 + i);
3587 args0[i + 1] = nconcing;
3588 }
3589
3590 RETURN_UNGCPRO (XCDR (nconcing));
3591 }
3592
3593 DEFUN ("mapc", Fmapc, 2, MANY, 0, /*
3594 Call FUNCTION on each element of SEQUENCE.
3595
3410 SEQUENCE may be a list, a vector, a bit vector, or a string. 3596 SEQUENCE may be a list, a vector, a bit vector, or a string.
3411 This function is like `mapcar' but does not accumulate the results, 3597 This function is like `mapcar' but does not accumulate the results,
3412 which is more efficient if you do not use the results. 3598 which is more efficient if you do not use the results.
3413 3599
3414 The difference between this and `mapc' is that `mapc' supports all 3600 With optional SEQUENCES, call FUNCTION each time with as many arguments as
3415 the spiffy Common Lisp arguments. You should normally use `mapc'. 3601 there are SEQUENCES, plus one for the elements from SEQUENCE. One element
3416 */ 3602 from each sequence will be used each time FUNCTION is called, and
3417 (function, sequence)) 3603 `mapc' stops calling FUNCTION once the shortest sequence is exhausted.
3418 { 3604
3419 mapcar1 (XINT (Flength (sequence)), 0, function, sequence); 3605 Return SEQUENCE.
3420 3606
3421 return sequence; 3607 arguments: (FUNCTION SEQUENCE &rest SEQUENCES)
3422 } 3608 */
3423 3609 (int nargs, Lisp_Object *args))
3610 {
3611 Elemcount len = EMACS_INT_MAX;
3612 Lisp_Object sequence = args[1];
3613 struct gcpro gcpro1;
3614 int i;
3615
3616 for (i = 1; i < nargs; ++i)
3617 {
3618 CHECK_SEQUENCE (args[i]);
3619 len = min (len, XINT (Flength (args[i])));
3620 }
3621
3622 /* We need to GCPRO sequence, because mapcarX will modify the
3623 elements of the args array handed to it, and this may involve
3624 elements of sequence getting garbage collected. */
3625 GCPRO1 (sequence);
3626 mapcarX (len, NULL, Qnil, args[0], nargs - 1, args + 1);
3627 RETURN_UNGCPRO (sequence);
3628 }
3629
3630 DEFUN ("map", Fmap, 3, MANY, 0, /*
3631 Map FUNCTION across one or more sequences, returning a sequence.
3632
3633 TYPE is the sequence type to return, FUNCTION is the function, SEQUENCE is
3634 the first argument sequence, SEQUENCES are the other argument sequences.
3635
3636 FUNCTION will be called with (1+ (length SEQUENCES)) arguments, and must be
3637 capable of accepting this number of arguments.
3638
3639 Certain TYPEs are recognised internally by `map', but others are not, and
3640 `coerce' may throw an error on an attempt to convert to a TYPE it does not
3641 understand. A null TYPE means do not accumulate any values.
3642
3643 arguments: (TYPE FUNCTION SEQUENCE &rest SEQUENCES)
3644 */
3645 (int nargs, Lisp_Object *args))
3646 {
3647 Lisp_Object type = args[0];
3648 Lisp_Object function = args[1];
3649 Lisp_Object result = Qnil;
3650 Lisp_Object *args0 = NULL;
3651 Elemcount len = EMACS_INT_MAX;
3652 int i;
3653 struct gcpro gcpro1;
3654
3655 for (i = 2; i < nargs; ++i)
3656 {
3657 CHECK_SEQUENCE (args[i]);
3658 len = min (len, XINT (Flength (args[i])));
3659 }
3660
3661 if (!NILP (type))
3662 {
3663 args0 = alloca_array (Lisp_Object, len);
3664 }
3665
3666 mapcarX (len, args0, Qnil, function, nargs - 2, args + 2);
3667
3668 if (EQ (type, Qnil))
3669 {
3670 return result;
3671 }
3672
3673 if (EQ (type, Qvector) || EQ (type, Qarray))
3674 {
3675 result = Fvector (len, args0);
3676 }
3677 else if (EQ (type, Qstring))
3678 {
3679 result = Fstring (len, args0);
3680 }
3681 else if (EQ (type, Qlist))
3682 {
3683 result = Flist (len, args0);
3684 }
3685 else if (EQ (type, Qbit_vector))
3686 {
3687 result = Fbit_vector (len, args0);
3688 }
3689 else
3690 {
3691 result = Flist (len, args0);
3692 GCPRO1 (result);
3693 result = call2 (Qcoerce, result, type);
3694 UNGCPRO;
3695 }
3696
3697 return result;
3698 }
3699
3700 DEFUN ("map-into", Fmap_into, 2, MANY, 0, /*
3701 Modify RESULT-SEQUENCE using the return values of FUNCTION on SEQUENCES.
3702
3703 RESULT-SEQUENCE and SEQUENCES can be lists or arrays.
3704
3705 FUNCTION must accept at least as many arguments as there are SEQUENCES
3706 \(possibly zero). If RESULT-SEQUENCE and the elements of SEQUENCES are not
3707 the same length, stop when the shortest is exhausted; any elements of
3708 RESULT-SEQUENCE beyond that are unmodified.
3709
3710 Return RESULT-SEQUENCE.
3711
3712 arguments: (RESULT-SEQUENCE FUNCTION &rest SEQUENCES)
3713 */
3714 (int nargs, Lisp_Object *args))
3715 {
3716 Elemcount len = EMACS_INT_MAX;
3717 Lisp_Object result_sequence = args[0];
3718 Lisp_Object function = args[1];
3719 int i;
3720
3721 args[0] = function;
3722 args[1] = result_sequence;
3723
3724 for (i = 1; i < nargs; ++i)
3725 {
3726 CHECK_SEQUENCE (args[i]);
3727 len = min (len, XINT (Flength (args[i])));
3728 }
3729
3730 mapcarX (len, NULL, result_sequence, function, nargs - 2, args + 2);
3731
3732 return result_sequence;
3733 }
3734
3735 /* Call FUNCTION with NLISTS arguments repeatedly, each Nth argument
3736 corresponding to the result of calling (nthcdr ITERATION-COUNT LISTS[N]),
3737 until that #'nthcdr expression gives nil for some element of LISTS.
3738
3739 If MAPLP is zero, return LISTS[0]. Otherwise, return a list of the return
3740 values from FUNCTION; if NCONCP is non-zero, nconc them together.
3741
3742 In contrast to mapcarX, we don't require our callers to check LISTS for
3743 well-formedness, we signal wrong-type-argument if it's not a list, or
3744 circular-list if it's circular. */
3745
3746 static Lisp_Object
3747 maplist (Lisp_Object function, int nlists, Lisp_Object *lists, int maplp,
3748 int nconcp)
3749 {
3750 Lisp_Object result = maplp ? lists[0] : Fcons (Qnil, Qnil), funcalled;
3751 Lisp_Object nconcing[2], accum = result, *args;
3752 struct gcpro gcpro1, gcpro2, gcpro3;
3753 int i, j, continuing = (nlists > 0), called_count = 0;
3754
3755 args = alloca_array (Lisp_Object, nlists + 1);
3756 args[0] = function;
3757 for (i = 1; i <= nlists; ++i)
3758 {
3759 args[i] = Qnil;
3760 }
3761
3762 if (nconcp)
3763 {
3764 nconcing[0] = result;
3765 nconcing[1] = Qnil;
3766 GCPRO3 (args[0], nconcing[0], result);
3767 gcpro1.nvars = 1;
3768 gcpro2.nvars = 2;
3769 }
3770 else
3771 {
3772 GCPRO2 (args[0], result);
3773 gcpro1.nvars = 1;
3774 }
3775
3776 while (continuing)
3777 {
3778 for (j = 0; j < nlists; ++j)
3779 {
3780 if (CONSP (lists[j]))
3781 {
3782 args[j + 1] = lists[j];
3783 lists[j] = XCDR (lists[j]);
3784 }
3785 else if (NILP (lists[j]))
3786 {
3787 continuing = 0;
3788 break;
3789 }
3790 else
3791 {
3792 dead_wrong_type_argument (Qlistp, lists[j]);
3793 }
3794 }
3795 if (!continuing) break;
3796 funcalled = Ffuncall (nlists + 1, args);
3797 if (!maplp)
3798 {
3799 if (nconcp)
3800 {
3801 /* This order of calls means we check that each list is
3802 well-formed once and once only. The last result does
3803 not have to be a list. */
3804 nconcing[1] = funcalled;
3805 nconcing[0] = bytecode_nconc2 (nconcing);
3806 }
3807 else
3808 {
3809 /* Add to the end, avoiding the need to call nreverse
3810 once we're done: */
3811 XSETCDR (accum, Fcons (funcalled, Qnil));
3812 accum = XCDR (accum);
3813 }
3814 }
3815
3816 if (++called_count % CIRCULAR_LIST_SUSPICION_LENGTH) continue;
3817
3818 for (j = 0; j < nlists; ++j)
3819 {
3820 EXTERNAL_LIST_LOOP_1 (lists[j])
3821 {
3822 /* Just check the lists aren't circular, using the
3823 EXTERNAL_LIST_LOOP_1 macro. */
3824 }
3825 }
3826 }
3827
3828 if (!maplp)
3829 {
3830 result = XCDR (result);
3831 }
3832
3833 RETURN_UNGCPRO (result);
3834 }
3835
3836 DEFUN ("maplist", Fmaplist, 2, MANY, 0, /*
3837 Call FUNCTION on each sublist of LIST and LISTS.
3838 Like `mapcar', except applies to lists and their cdr's rather than to
3839 the elements themselves."
3840
3841 arguments: (FUNCTION LIST &rest LISTS)
3842 */
3843 (int nargs, Lisp_Object *args))
3844 {
3845 return maplist (args[0], nargs - 1, args + 1, 0, 0);
3846 }
3847
3848 DEFUN ("mapl", Fmapl, 2, MANY, 0, /*
3849 Like `maplist', but do not accumulate values returned by the function.
3850
3851 arguments: (FUNCTION LIST &rest LISTS)
3852 */
3853 (int nargs, Lisp_Object *args))
3854 {
3855 return maplist (args[0], nargs - 1, args + 1, 1, 0);
3856 }
3857
3858 DEFUN ("mapcon", Fmapcon, 2, MANY, 0, /*
3859 Like `maplist', but chains together the values returned by FUNCTION.
3860
3861 FUNCTION must return a list (unless it happens to be the last
3862 iteration); the results will be concatenated together using `nconc'.
3863
3864 arguments: (FUNCTION LIST &rest LISTS)
3865 */
3866 (int nargs, Lisp_Object *args))
3867 {
3868 return maplist (args[0], nargs - 1, args + 1, 0, 1);
3869 }
3424 3870
3425 /* Extra random functions */ 3871 /* Extra random functions */
3426 3872
3427 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /* 3873 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /*
3428 Destructively replace the list OLD with NEW. 3874 Destructively replace the list OLD with NEW.
3462 old = Qnil; 3908 old = Qnil;
3463 3909
3464 return old; 3910 return old;
3465 } 3911 }
3466 3912
3913
3467 Lisp_Object 3914 Lisp_Object
3468 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string) 3915 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string)
3469 { 3916 {
3470 return Fintern (concat2 (Fsymbol_name (symbol), 3917 return Fintern (concat2 (Fsymbol_name (symbol),
3471 build_string (ascii_string)), 3918 build_string (ascii_string)),
4100 { 4547 {
4101 INIT_LRECORD_IMPLEMENTATION (bit_vector); 4548 INIT_LRECORD_IMPLEMENTATION (bit_vector);
4102 4549
4103 DEFSYMBOL (Qstring_lessp); 4550 DEFSYMBOL (Qstring_lessp);
4104 DEFSYMBOL (Qidentity); 4551 DEFSYMBOL (Qidentity);
4552 DEFSYMBOL (Qvector);
4553 DEFSYMBOL (Qarray);
4554 DEFSYMBOL (Qstring);
4555 DEFSYMBOL (Qlist);
4556 DEFSYMBOL (Qbit_vector);
4557
4105 DEFSYMBOL (Qyes_or_no_p); 4558 DEFSYMBOL (Qyes_or_no_p);
4106 4559
4107 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error); 4560 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error);
4108 4561
4109 DEFSUBR (Fidentity); 4562 DEFSUBR (Fidentity);
4177 DEFSUBR (Fequal); 4630 DEFSUBR (Fequal);
4178 DEFSUBR (Fequalp); 4631 DEFSUBR (Fequalp);
4179 DEFSUBR (Fold_equal); 4632 DEFSUBR (Fold_equal);
4180 DEFSUBR (Ffillarray); 4633 DEFSUBR (Ffillarray);
4181 DEFSUBR (Fnconc); 4634 DEFSUBR (Fnconc);
4182 DEFSUBR (Fmapcar); 4635 DEFSUBR (FmapcarX);
4183 DEFSUBR (Fmapvector); 4636 DEFSUBR (Fmapvector);
4184 DEFSUBR (Fmapc_internal); 4637 DEFSUBR (Fmapcan);
4638 DEFSUBR (Fmapc);
4185 DEFSUBR (Fmapconcat); 4639 DEFSUBR (Fmapconcat);
4640 DEFSUBR (Fmap);
4641 DEFSUBR (Fmap_into);
4642 Ffset (intern ("mapc-internal"), Fsymbol_function (intern ("mapc")));
4643 Ffset (intern ("mapcar"), Fsymbol_function (intern ("mapcar*")));
4644 DEFSUBR (Fmaplist);
4645 DEFSUBR (Fmapl);
4646 DEFSUBR (Fmapcon);
4647
4186 DEFSUBR (Freplace_list); 4648 DEFSUBR (Freplace_list);
4187 DEFSUBR (Fload_average); 4649 DEFSUBR (Fload_average);
4188 DEFSUBR (Ffeaturep); 4650 DEFSUBR (Ffeaturep);
4189 DEFSUBR (Frequire); 4651 DEFSUBR (Frequire);
4190 DEFSUBR (Fprovide); 4652 DEFSUBR (Fprovide);