comparison src/fns.c @ 5448:89331fa1c819

Merged with trunk.
author Mats Lidell <matsl@xemacs.org>
date Thu, 06 Jan 2011 00:35:22 +0100
parents 771bf922ab2b 1dbc93b7ba19
children a9094f28f9a9
comparison
equal deleted inserted replaced
5447:4b08f375e2fb 5448:89331fa1c819
50 #include "opaque.h" 50 #include "opaque.h"
51 51
52 /* NOTE: This symbol is also used in lread.c */ 52 /* NOTE: This symbol is also used in lread.c */
53 #define FEATUREP_SYNTAX 53 #define FEATUREP_SYNTAX
54 54
55 Lisp_Object Qstring_lessp, Qsort, Qmerge, Qfill, Qreplace; 55 Lisp_Object Qstring_lessp, Qmerge, Qfill, Qreplace, QassocX, QrassocX;
56 Lisp_Object Qidentity; 56 Lisp_Object Qposition, Qfind, QdeleteX, QremoveX, Qidentity, Qadjoin;
57 Lisp_Object Qvector, Qarray, Qbit_vector, QsortX, Q_from_end, Q_initial_value; 57 Lisp_Object Qvector, Qarray, Qbit_vector, QsortX, Q_from_end, Q_initial_value;
58 Lisp_Object Qmapconcat, QmapcarX, Qmapvector, Qmapcan, Qmapc, Qmap, Qmap_into; 58 Lisp_Object Qmapconcat, QmapcarX, Qmapvector, Qmapcan, Qmapc, Qmap, Qmap_into;
59 Lisp_Object Qsome, Qevery, Qmaplist, Qmapl, Qmapcon, Qreduce; 59 Lisp_Object Qsome, Qevery, Qmaplist, Qmapl, Qmapcon, Qreduce, Qsubstitute;
60 Lisp_Object Q_start1, Q_start2, Q_end1, Q_end2; 60 Lisp_Object Q_start1, Q_start2, Q_end1, Q_end2, Q_if_, Q_if_not, Q_stable;
61 Lisp_Object Q_test_not, Q_count, Qnsubstitute, Qdelete_duplicates, Qmismatch;
62
63 Lisp_Object Qintersection, Qset_difference, Qnset_difference;
64 Lisp_Object Qnunion, Qnintersection, Qsubsetp;
61 65
62 Lisp_Object Qbase64_conversion_error; 66 Lisp_Object Qbase64_conversion_error;
63 67
64 Lisp_Object Vpath_separator; 68 Lisp_Object Vpath_separator;
69
70 extern Fixnum max_lisp_eval_depth;
71 extern int lisp_eval_depth;
65 72
66 static int internal_old_equal (Lisp_Object, Lisp_Object, int); 73 static int internal_old_equal (Lisp_Object, Lisp_Object, int);
67 Lisp_Object safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth); 74 Lisp_Object safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth);
68 75
69 static DOESNT_RETURN 76 static DOESNT_RETURN
195 bit_vector_equal, 202 bit_vector_equal,
196 bit_vector_hash, 203 bit_vector_hash,
197 bit_vector_description, 204 bit_vector_description,
198 size_bit_vector, 205 size_bit_vector,
199 Lisp_Bit_Vector); 206 Lisp_Bit_Vector);
207
208 /* Various test functions for #'member*, #'assoc* and the other functions
209 that take both TEST and KEY arguments. */
210
211 typedef Boolint (*check_test_func_t) (Lisp_Object test, Lisp_Object key,
212 Lisp_Object item, Lisp_Object elt);
213
214 static Boolint
215 check_eq_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
216 Lisp_Object item, Lisp_Object elt)
217 {
218 return EQ (item, elt);
219 }
220
221 static Boolint
222 check_eq_key (Lisp_Object UNUSED (test), Lisp_Object key, Lisp_Object item,
223 Lisp_Object elt)
224 {
225 elt = IGNORE_MULTIPLE_VALUES (call1 (key, elt));
226 return EQ (item, elt);
227 }
228
229 /* The next two are not used by #'member* and #'assoc*, since we can decide
230 on #'eq vs. #'equal when we have the type of ITEM. */
231 static Boolint
232 check_eql_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
233 Lisp_Object elt1, Lisp_Object elt2)
234 {
235 return EQ (elt1, elt2)
236 || (NON_FIXNUM_NUMBER_P (elt1) && internal_equal (elt1, elt2, 0));
237 }
238
239 static Boolint
240 check_eql_key (Lisp_Object UNUSED (test), Lisp_Object key, Lisp_Object item,
241 Lisp_Object elt)
242 {
243 elt = IGNORE_MULTIPLE_VALUES (call1 (key, elt));
244 return EQ (item, elt)
245 || (NON_FIXNUM_NUMBER_P (item) && internal_equal (item, elt, 0));
246 }
247
248 static Boolint
249 check_equal_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
250 Lisp_Object item, Lisp_Object elt)
251 {
252 return internal_equal (item, elt, 0);
253 }
254
255 static Boolint
256 check_equal_key (Lisp_Object UNUSED (test), Lisp_Object key, Lisp_Object item,
257 Lisp_Object elt)
258 {
259 elt = IGNORE_MULTIPLE_VALUES (call1 (key, elt));
260 return internal_equal (item, elt, 0);
261 }
262
263 static Boolint
264 check_equalp_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
265 Lisp_Object item, Lisp_Object elt)
266 {
267 return internal_equalp (item, elt, 0);
268 }
269
270 static Boolint
271 check_equalp_key (Lisp_Object UNUSED (test), Lisp_Object key,
272 Lisp_Object item, Lisp_Object elt)
273 {
274 elt = IGNORE_MULTIPLE_VALUES (call1 (key, elt));
275 return internal_equalp (item, elt, 0);
276 }
277
278 static Boolint
279 check_string_match_nokey (Lisp_Object UNUSED (test), Lisp_Object UNUSED (key),
280 Lisp_Object item, Lisp_Object elt)
281 {
282 return !NILP (Fstring_match (item, elt, Qnil, Qnil));
283 }
284
285 static Boolint
286 check_string_match_key (Lisp_Object UNUSED (test), Lisp_Object key,
287 Lisp_Object item, Lisp_Object elt)
288 {
289 elt = IGNORE_MULTIPLE_VALUES (call1 (key, elt));
290 return !NILP (Fstring_match (item, elt, Qnil, Qnil));
291 }
292
293 static Boolint
294 check_other_nokey (Lisp_Object test, Lisp_Object UNUSED (key),
295 Lisp_Object item, Lisp_Object elt)
296 {
297 Lisp_Object args[] = { test, item, elt };
298 struct gcpro gcpro1;
299
300 GCPRO1 (args[0]);
301 gcpro1.nvars = countof (args);
302 item = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args), args));
303 UNGCPRO;
304
305 return !NILP (item);
306 }
307
308 static Boolint
309 check_other_key (Lisp_Object test, Lisp_Object key,
310 Lisp_Object item, Lisp_Object elt)
311 {
312 Lisp_Object args[] = { item, key, elt };
313 struct gcpro gcpro1;
314
315 GCPRO1 (args[0]);
316 gcpro1.nvars = countof (args);
317 args[2] = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args) - 1, args + 1));
318 args[1] = item;
319 args[0] = test;
320 item = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args), args));
321 UNGCPRO;
322
323 return !NILP (item);
324 }
325
326 static Boolint
327 check_if_nokey (Lisp_Object test, Lisp_Object UNUSED (key),
328 Lisp_Object UNUSED (item), Lisp_Object elt)
329 {
330 elt = IGNORE_MULTIPLE_VALUES (call1 (test, elt));
331 return !NILP (elt);
332 }
333
334 static Boolint
335 check_if_key (Lisp_Object test, Lisp_Object key,
336 Lisp_Object UNUSED (item), Lisp_Object elt)
337 {
338 Lisp_Object args[] = { key, elt };
339 struct gcpro gcpro1;
340
341 GCPRO1 (args[0]);
342 gcpro1.nvars = countof (args);
343 args[1] = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args), args));
344 args[0] = test;
345 elt = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args), args));
346 UNGCPRO;
347
348 return !NILP (elt);
349 }
350
351 static Boolint
352 check_match_eq_key (Lisp_Object UNUSED (test), Lisp_Object key,
353 Lisp_Object elt1, Lisp_Object elt2)
354 {
355 Lisp_Object args[] = { key, elt1, elt2 };
356 struct gcpro gcpro1;
357
358 GCPRO1 (args[0]);
359 gcpro1.nvars = countof (args);
360 args[0] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args));
361 args[1] = key;
362 args[1] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args + 1));
363 UNGCPRO;
364
365 return EQ (args[0], args[1]);
366 }
367
368 static Boolint
369 check_match_eql_key (Lisp_Object UNUSED (test), Lisp_Object key,
370 Lisp_Object elt1, Lisp_Object elt2)
371 {
372 Lisp_Object args[] = { key, elt1, elt2 };
373 struct gcpro gcpro1;
374
375 GCPRO1 (args[0]);
376 gcpro1.nvars = countof (args);
377 args[0] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args));
378 args[1] = key;
379 args[1] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args + 1));
380 UNGCPRO;
381
382 return EQ (args[0], args[1]) ||
383 (NON_FIXNUM_NUMBER_P (args[0]) && internal_equal (args[0], args[1], 0));
384 }
385
386 static Boolint
387 check_match_equal_key (Lisp_Object UNUSED (test), Lisp_Object key,
388 Lisp_Object elt1, Lisp_Object elt2)
389 {
390 Lisp_Object args[] = { key, elt1, elt2 };
391 struct gcpro gcpro1;
392
393 GCPRO1 (args[0]);
394 gcpro1.nvars = countof (args);
395 args[0] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args));
396 args[1] = key;
397 args[1] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args + 1));
398 UNGCPRO;
399
400 return internal_equal (args[0], args[1], 0);
401 }
402
403 static Boolint
404 check_match_equalp_key (Lisp_Object UNUSED (test), Lisp_Object key,
405 Lisp_Object elt1, Lisp_Object elt2)
406 {
407 Lisp_Object args[] = { key, elt1, elt2 };
408 struct gcpro gcpro1;
409
410 GCPRO1 (args[0]);
411 gcpro1.nvars = countof (args);
412 args[0] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args));
413 args[1] = key;
414 args[1] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args + 1));
415 UNGCPRO;
416
417 return internal_equalp (args[0], args[1], 0);
418 }
419
420 static Boolint
421 check_match_other_key (Lisp_Object test, Lisp_Object key,
422 Lisp_Object elt1, Lisp_Object elt2)
423 {
424 Lisp_Object args[] = { key, elt1, elt2 };
425 struct gcpro gcpro1;
426
427 GCPRO1 (args[0]);
428 gcpro1.nvars = countof (args);
429 args[0] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args));
430 args[1] = key;
431 args[2] = IGNORE_MULTIPLE_VALUES (Ffuncall (2, args + 1));
432 args[1] = args[0];
433 args[0] = test;
434
435 elt1 = IGNORE_MULTIPLE_VALUES (Ffuncall (countof (args), args));
436 UNGCPRO;
437
438 return !NILP (elt1);
439 }
440
441 static check_test_func_t
442 get_check_match_function_1 (Lisp_Object item,
443 Lisp_Object *test_inout, Lisp_Object test_not,
444 Lisp_Object if_, Lisp_Object if_not,
445 Lisp_Object key, Boolint *test_not_unboundp_out,
446 check_test_func_t *test_func_out)
447 {
448 Lisp_Object test = *test_inout;
449 check_test_func_t result = NULL, test_func = NULL;
450 Boolint force_if = 0;
451
452 if (!NILP (if_))
453 {
454 if (!(NILP (test) && NILP (test_not) && NILP (if_not)))
455 {
456 invalid_argument ("only one keyword among :test :test-not "
457 ":if :if-not allowed", if_);
458 }
459
460 test = *test_inout = if_;
461 force_if = 1;
462 }
463 else if (!NILP (if_not))
464 {
465 if (!(NILP (test) && NILP (test_not)))
466 {
467 invalid_argument ("only one keyword among :test :test-not "
468 ":if :if-not allowed", if_not);
469 }
470
471 test_not = if_not;
472 force_if = 1;
473 }
474
475 if (NILP (test))
476 {
477 if (!NILP (test_not))
478 {
479 test = *test_inout = test_not;
480 if (NULL != test_not_unboundp_out)
481 {
482 *test_not_unboundp_out = 0;
483 }
484 }
485 else
486 {
487 test = Qeql;
488 if (NULL != test_not_unboundp_out)
489 {
490 *test_not_unboundp_out = 1;
491 }
492 }
493 }
494 else if (!NILP (test_not))
495 {
496 invalid_argument_2 ("conflicting :test and :test-not keyword arguments",
497 test, test_not);
498 }
499
500 test = indirect_function (test, 1);
501
502 if (NILP (key) ||
503 EQ (indirect_function (key, 1), XSYMBOL_FUNCTION (Qidentity)))
504 {
505 key = Qidentity;
506 }
507
508 if (force_if)
509 {
510 result = EQ (key, Qidentity) ? check_if_nokey : check_if_key;
511
512 if (NULL != test_func_out)
513 {
514 *test_func_out = result;
515 }
516
517 return result;
518 }
519
520 if (!UNBOUNDP (item) && EQ (test, XSYMBOL_FUNCTION (Qeql)))
521 {
522 test = XSYMBOL_FUNCTION (NON_FIXNUM_NUMBER_P (item) ? Qequal : Qeq);
523 }
524
525 #define FROB(known_test, eq_condition) \
526 if (EQ (test, XSYMBOL_FUNCTION (Q##known_test))) do \
527 { \
528 if (eq_condition) \
529 { \
530 test = XSYMBOL_FUNCTION (Qeq); \
531 goto force_eq_check; \
532 } \
533 \
534 if (!EQ (Qidentity, key)) \
535 { \
536 test_func = check_##known_test##_key; \
537 result = check_match_##known_test##_key; \
538 } \
539 else \
540 { \
541 result = test_func = check_##known_test##_nokey; \
542 } \
543 } while (0)
544
545 FROB (eql, 0);
546 else if (SUBRP (test))
547 {
548 force_eq_check:
549 FROB (eq, 0);
550 else FROB (equal, (SYMBOLP (item) || INTP (item) || CHARP (item)));
551 else FROB (equalp, (SYMBOLP (item)));
552 else if (EQ (test, XSYMBOL_FUNCTION (Qstring_match)))
553 {
554 if (EQ (Qidentity, key))
555 {
556 test_func = result = check_string_match_nokey;
557 }
558 else
559 {
560 test_func = check_string_match_key;
561 result = check_other_key;
562 }
563 }
564 }
565
566 if (NULL == result)
567 {
568 if (EQ (Qidentity, key))
569 {
570 test_func = result = check_other_nokey;
571 }
572 else
573 {
574 test_func = check_other_key;
575 result = check_match_other_key;
576 }
577 }
578
579 if (NULL != test_func_out)
580 {
581 *test_func_out = test_func;
582 }
583
584 return result;
585 }
586 #undef FROB
587
588 /* Given TEST, TEST_NOT, IF, IF_NOT, KEY, and ITEM, return a C function
589 pointer appropriate for use in deciding whether a given element of a
590 sequence satisfies TEST.
591
592 Set *test_not_unboundp_out to 1 if TEST_NOT was not bound; set it to zero
593 if it was bound, and set *test_inout to the value it was bound to. If
594 TEST was not bound, leave *test_inout alone; the value is not used by
595 check_eq_*key() or check_equal_*key(), which are the defaults, depending
596 on the type of ITEM.
597
598 The returned function takes arguments (TEST, KEY, ITEM, ELT), where ITEM
599 is the item being searched for and ELT is the element of the sequence
600 being examined.
601
602 Error if both TEST and TEST_NOT were specified, which Common Lisp says is
603 undefined behaviour. */
604
605 static check_test_func_t
606 get_check_test_function (Lisp_Object item,
607 Lisp_Object *test_inout, Lisp_Object test_not,
608 Lisp_Object if_, Lisp_Object if_not,
609 Lisp_Object key, Boolint *test_not_unboundp_out)
610 {
611 check_test_func_t result = NULL;
612 get_check_match_function_1 (item, test_inout, test_not, if_, if_not,
613 key, test_not_unboundp_out, &result);
614 return result;
615 }
616
617 /* Given TEST, TEST_NOT, IF, IF_NOT and KEY, return a C function pointer
618 appropriate for use in deciding whether two given elements of a sequence
619 satisfy TEST.
620
621 Set *test_not_unboundp_out to 1 if TEST_NOT was not bound; set it to zero
622 if it was bound, and set *test_inout to the value it was bound to. If
623 TEST was not bound, leave *test_inout alone; the value is not used by
624 check_eql_*key().
625
626 The returned function takes arguments (TEST, KEY, ELT1, ELT2), where ELT1
627 and ELT2 are elements of the sequence being examined.
628
629 The value that would be given by get_check_test_function() is returned in
630 *TEST_FUNC_OUT, which allows calling functions to do their own key checks
631 if they're processing one element at a time.
632
633 Error if both TEST and TEST_NOT were specified, which Common Lisp says is
634 undefined behaviour. */
635
636 static check_test_func_t
637 get_check_match_function (Lisp_Object *test_inout, Lisp_Object test_not,
638 Lisp_Object if_, Lisp_Object if_not,
639 Lisp_Object key, Boolint *test_not_unboundp_out,
640 check_test_func_t *test_func_out)
641 {
642 return get_check_match_function_1 (Qunbound, test_inout, test_not,
643 if_, if_not, key,
644 test_not_unboundp_out, test_func_out);
645 }
200 646
201 647
202 DEFUN ("identity", Fidentity, 1, 1, 0, /* 648 DEFUN ("identity", Fidentity, 1, 1, 0, /*
203 Return the argument unchanged. 649 Return the argument unchanged.
204 */ 650 */
362 signal_malformed_list_error (list); 808 signal_malformed_list_error (list);
363 } 809 }
364 810
365 return EQ (hare, tortoise) && len != 0 ? Qnil : make_int (len); 811 return EQ (hare, tortoise) && len != 0 ? Qnil : make_int (len);
366 } 812 }
367 813
814 static Lisp_Object string_count_from_end (Lisp_Object, Lisp_Object ,
815 check_test_func_t, Boolint,
816 Lisp_Object, Lisp_Object,
817 Lisp_Object, Lisp_Object);
818
819 static Lisp_Object list_count_from_end (Lisp_Object, Lisp_Object,
820 check_test_func_t, Boolint,
821 Lisp_Object, Lisp_Object,
822 Lisp_Object, Lisp_Object);
823
824 /* Count the number of occurrences of ITEM in SEQUENCE; if SEQUENCE is a
825 list, store the cons cell of which the car is the last ITEM in SEQUENCE,
826 at the address given by tail_out. */
827
828 static Lisp_Object
829 count_with_tail (Lisp_Object *tail_out, int nargs, Lisp_Object *args,
830 Lisp_Object caller)
831 {
832 Lisp_Object item = args[0], sequence = args[1];
833 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0;
834 Elemcount len, ii = 0, counting = EMACS_INT_MAX;
835 Boolint test_not_unboundp = 1;
836 check_test_func_t check_test = NULL;
837
838 PARSE_KEYWORDS_8 (caller, nargs, args, 9,
839 (test, key, start, end, from_end, test_not, count,
840 if_, if_not), (start = Qzero), 2, 0);
841
842 CHECK_SEQUENCE (sequence);
843 CHECK_NATNUM (start);
844 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
845
846 if (!NILP (end))
847 {
848 CHECK_NATNUM (end);
849 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
850 }
851
852 if (!NILP (count))
853 {
854 CHECK_INTEGER (count);
855 counting = BIGNUMP (count) ? EMACS_INT_MAX + 1 : XINT (count);
856
857 /* Our callers should have filtered out non-positive COUNT. */
858 assert (counting >= 0);
859 /* And we're not prepared to handle COUNT from any other caller at the
860 moment. */
861 assert (EQ (caller, QremoveX));
862 }
863
864 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
865 key, &test_not_unboundp);
866
867 *tail_out = Qnil;
868
869 if (CONSP (sequence))
870 {
871 Lisp_Object elt, tail = Qnil;
872 struct gcpro gcpro1;
873
874 if (EQ (caller, Qcount) && !NILP (from_end)
875 && (!EQ (key, Qnil) ||
876 check_test == check_other_nokey || check_test == check_if_nokey))
877 {
878 /* #'count, #'count-if, and #'count-if-not are documented to have
879 a given traversal order if :from-end t is passed in, even
880 though forward traversal of the sequence has the same result
881 and is algorithmically less expensive for lists and strings.
882 This order isn't necessary for other callers, though. */
883 return list_count_from_end (item, sequence, check_test,
884 test_not_unboundp, test, key,
885 start, end);
886 }
887
888 GCPRO1 (tail);
889
890 /* If COUNT is non-nil and FROM-END is t, we can give the tail
891 containing the last match, since that's what #'remove* is
892 interested in (a zero or negative COUNT won't ever reach
893 count_with_tail(), our callers will return immediately on seeing
894 it). */
895 if (!NILP (count) && !NILP (from_end))
896 {
897 counting = EMACS_INT_MAX;
898 }
899
900 {
901 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len)
902 {
903 if (!(ii < ending))
904 {
905 break;
906 }
907
908 if (starting <= ii &&
909 check_test (test, key, item, elt) == test_not_unboundp)
910 {
911 encountered++;
912 *tail_out = tail;
913
914 if (encountered == counting)
915 {
916 break;
917 }
918 }
919
920 ii++;
921 }
922 }
923
924 UNGCPRO;
925
926 if ((ii < starting || (ii < ending && !NILP (end))) &&
927 encountered != counting)
928 {
929 check_sequence_range (args[1], start, end, Flength (args[1]));
930 }
931 }
932 else if (STRINGP (sequence))
933 {
934 Ibyte *startp = XSTRING_DATA (sequence), *cursor = startp;
935 Bytecount byte_len = XSTRING_LENGTH (sequence), cursor_offset = 0;
936 Lisp_Object character = Qnil;
937
938 if (EQ (caller, Qcount) && !NILP (from_end)
939 && (!EQ (key, Qnil) ||
940 check_test == check_other_nokey || check_test == check_if_nokey))
941 {
942 /* See comment above in the list code. */
943 return string_count_from_end (item, sequence,
944 check_test, test_not_unboundp,
945 test, key, start, end);
946 }
947
948 while (cursor_offset < byte_len && ii < ending && encountered < counting)
949 {
950 if (ii >= starting)
951 {
952 character = make_char (itext_ichar (cursor));
953
954 if (check_test (test, key, item, character)
955 == test_not_unboundp)
956 {
957 encountered++;
958 }
959
960 startp = XSTRING_DATA (sequence);
961 cursor = startp + cursor_offset;
962 if (byte_len != XSTRING_LENGTH (sequence)
963 || !valid_ibyteptr_p (cursor))
964 {
965 mapping_interaction_error (caller, sequence);
966 }
967 }
968
969 INC_IBYTEPTR (cursor);
970 cursor_offset = cursor - startp;
971 ii++;
972 }
973
974 if (ii < starting || (ii < ending && !NILP (end)))
975 {
976 check_sequence_range (sequence, start, end, Flength (sequence));
977 }
978 }
979 else
980 {
981 Lisp_Object object = Qnil;
982
983 len = XINT (Flength (sequence));
984 check_sequence_range (sequence, start, end, make_int (len));
985
986 ending = min (ending, len);
987 if (0 == len)
988 {
989 /* Catches the case where we have nil. */
990 return make_integer (encountered);
991 }
992
993 if (NILP (from_end))
994 {
995 for (ii = starting; ii < ending && encountered < counting; ii++)
996 {
997 object = Faref (sequence, make_int (ii));
998 if (check_test (test, key, item, object) == test_not_unboundp)
999 {
1000 encountered++;
1001 }
1002 }
1003 }
1004 else
1005 {
1006 for (ii = ending - 1; ii >= starting && encountered < counting; ii--)
1007 {
1008 object = Faref (sequence, make_int (ii));
1009 if (check_test (test, key, item, object) == test_not_unboundp)
1010 {
1011 encountered++;
1012 }
1013 }
1014 }
1015 }
1016
1017 return make_integer (encountered);
1018 }
1019
1020 static Lisp_Object
1021 list_count_from_end (Lisp_Object item, Lisp_Object sequence,
1022 check_test_func_t check_test, Boolint test_not_unboundp,
1023 Lisp_Object test, Lisp_Object key,
1024 Lisp_Object start, Lisp_Object end)
1025 {
1026 Elemcount length = XINT (Flength (sequence)), ii = 0, starting = XINT (start);
1027 Elemcount ending = NILP (end) ? length : XINT (end), encountered = 0;
1028 Lisp_Object *storage;
1029 struct gcpro gcpro1;
1030
1031 check_sequence_range (sequence, start, end, make_integer (length));
1032
1033 storage = alloca_array (Lisp_Object, ending - starting);
1034
1035 {
1036 EXTERNAL_LIST_LOOP_2 (elt, sequence)
1037 {
1038 if (starting <= ii && ii < ending)
1039 {
1040 storage[ii - starting] = elt;
1041 }
1042 ii++;
1043 }
1044 }
1045
1046 GCPRO1 (storage[0]);
1047 gcpro1.nvars = ending - starting;
1048
1049 for (ii = ending - 1; ii >= starting; ii--)
1050 {
1051 if (check_test (test, key, item, storage[ii - starting])
1052 == test_not_unboundp)
1053 {
1054 encountered++;
1055 }
1056 }
1057
1058 UNGCPRO;
1059
1060 return make_integer (encountered);
1061 }
1062
1063 static Lisp_Object
1064 string_count_from_end (Lisp_Object item, Lisp_Object sequence,
1065 check_test_func_t check_test, Boolint test_not_unboundp,
1066 Lisp_Object test, Lisp_Object key,
1067 Lisp_Object start, Lisp_Object end)
1068 {
1069 Elemcount length = string_char_length (sequence), ii = 0;
1070 Elemcount starting = XINT (start), ending = NILP (end) ? length : XINT (end);
1071 Elemcount encountered = 0;
1072 Ibyte *cursor = XSTRING_DATA (sequence);
1073 Ibyte *endp = cursor + XSTRING_LENGTH (sequence);
1074 Ichar *storage;
1075
1076 check_sequence_range (sequence, start, end, make_integer (length));
1077
1078 storage = alloca_array (Ichar, ending - starting);
1079
1080 while (cursor < endp && ii < ending)
1081 {
1082 if (starting <= ii && ii < ending)
1083 {
1084 storage [ii - starting] = itext_ichar (cursor);
1085 }
1086
1087 ii++;
1088 INC_IBYTEPTR (cursor);
1089 }
1090
1091 for (ii = ending - 1; ii >= starting; ii--)
1092 {
1093 if (check_test (test, key, item, make_char (storage [ii - starting]))
1094 == test_not_unboundp)
1095 {
1096 encountered++;
1097 }
1098 }
1099
1100 return make_integer (encountered);
1101 }
1102
1103 DEFUN ("count", Fcount, 2, MANY, 0, /*
1104 Count the number of occurrences of ITEM in SEQUENCE.
1105
1106 See `remove*' for the meaning of the keywords.
1107
1108 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT)
1109 */
1110 (int nargs, Lisp_Object *args))
1111 {
1112 Lisp_Object tail = Qnil;
1113
1114 /* count_with_tail() accepts more keywords than we do, check those we've
1115 been given. */
1116 PARSE_KEYWORDS (Fcount, nargs, args, 8,
1117 (test, test_not, if_, if_not, key, start, end, from_end),
1118 NULL);
1119
1120 return count_with_tail (&tail, nargs, args, Qcount);
1121 }
1122
368 /*** string functions. ***/ 1123 /*** string functions. ***/
369 1124
370 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /* 1125 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /*
371 Return t if two strings have identical contents. 1126 Return t if two strings have identical contents.
372 Case is significant. Text properties are ignored. 1127 Case is significant. Text properties are ignored.
998 } 1753 }
999 1754
1000 Lisp_Object 1755 Lisp_Object
1001 safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth) 1756 safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth)
1002 { 1757 {
1003 if (depth > 200) 1758 if (depth + lisp_eval_depth > max_lisp_eval_depth)
1004 stack_overflow ("Stack overflow in copy-tree", arg); 1759 stack_overflow ("Stack overflow in copy-tree", arg);
1005 1760
1006 if (CONSP (arg)) 1761 if (CONSP (arg))
1007 { 1762 {
1008 Lisp_Object rest; 1763 Lisp_Object rest;
1738 return tail; 2493 return tail;
1739 } 2494 }
1740 return Qnil; 2495 return Qnil;
1741 } 2496 }
1742 2497
2498 /* Return the first index of ITEM in LIST. In CONS_OUT, return the cons cell
2499 before that containing the element. If the element is in the first cons
2500 cell, return Qnil in CONS_OUT. TEST, KEY, START, END are as in
2501 #'remove*; CHECK_TEST and TEST_NOT_UNBOUNDP should have been initialized
2502 with get_check_match_function() or get_check_test_function(). A non-zero
2503 REVERSE_TEST_ORDER means call TEST with the element from LIST as its
2504 first argument and ITEM as its second. Error if LIST is ill-formed, or
2505 circular. */
2506 static Lisp_Object
2507 list_position_cons_before (Lisp_Object *cons_out,
2508 Lisp_Object item, Lisp_Object list,
2509 check_test_func_t check_test,
2510 Boolint test_not_unboundp,
2511 Lisp_Object test, Lisp_Object key,
2512 Boolint reverse_test_order,
2513 Lisp_Object start, Lisp_Object end)
2514 {
2515 struct gcpro gcpro1, gcpro2;
2516 Lisp_Object elt = Qnil, tail = list, tail_before = Qnil;
2517 Elemcount len, ii = 0, starting = XINT (start);
2518 Elemcount ending = NILP (end) ? EMACS_INT_MAX : XINT (end);
2519
2520 GCPRO2 (elt, tail);
2521
2522 if (check_test == check_eq_nokey)
2523 {
2524 /* TEST is #'eq, no need to call any C functions, and the test order
2525 won't be visible. */
2526 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len)
2527 {
2528 if (starting <= ii && ii < ending &&
2529 EQ (item, elt) == test_not_unboundp)
2530 {
2531 *cons_out = tail_before;
2532 RETURN_UNGCPRO (make_integer (ii));
2533 }
2534 else
2535 {
2536 if (ii >= ending)
2537 {
2538 break;
2539 }
2540 }
2541 ii++;
2542 tail_before = tail;
2543 }
2544 }
2545 else
2546 {
2547 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len)
2548 {
2549 if (starting <= ii && ii < ending &&
2550 (reverse_test_order ?
2551 check_test (test, key, elt, item) :
2552 check_test (test, key, item, elt)) == test_not_unboundp)
2553 {
2554 *cons_out = tail_before;
2555 RETURN_UNGCPRO (make_integer (ii));
2556 }
2557 else
2558 {
2559 if (ii >= ending)
2560 {
2561 break;
2562 }
2563 }
2564 ii++;
2565 tail_before = tail;
2566 }
2567 }
2568
2569 RETURN_UNGCPRO (Qnil);
2570 }
2571
2572 DEFUN ("member*", FmemberX, 2, MANY, 0, /*
2573 Return the first sublist of LIST with car ITEM, or nil if no such sublist.
2574
2575 The keyword :test specifies a two-argument function that is used to compare
2576 ITEM with elements in LIST; if omitted, it defaults to `eql'.
2577
2578 The keyword :test-not is similar, but specifies a negated function. That
2579 is, ITEM is considered equal to an element in LIST if the given function
2580 returns nil. Common Lisp deprecates :test-not, and if both are specified,
2581 XEmacs signals an error.
2582
2583 :key specifies a one-argument function that transforms elements of LIST into
2584 \"comparison keys\" before the test predicate is applied. For example,
2585 if :key is #'car, then ITEM is compared with the car of elements from LIST.
2586 The :key function, however, is not applied to ITEM, and does not affect the
2587 elements in the returned list, which are taken directly from the elements in
2588 LIST.
2589
2590 arguments: (ITEM LIST &key (TEST #'eql) TEST-NOT (KEY #'identity))
2591 */
2592 (int nargs, Lisp_Object *args))
2593 {
2594 Lisp_Object item = args[0], list = args[1], result = Qnil, position0;
2595 Boolint test_not_unboundp = 1;
2596 check_test_func_t check_test = NULL;
2597
2598 PARSE_KEYWORDS (FmemberX, nargs, args, 5, (test, if_not, if_, test_not, key),
2599 NULL);
2600 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
2601 key, &test_not_unboundp);
2602 position0
2603 = list_position_cons_before (&result, item, list, check_test,
2604 test_not_unboundp, test, key, 0, Qzero, Qnil);
2605
2606 return CONSP (result) ? XCDR (result) : ZEROP (position0) ? list : Qnil;
2607 }
2608
2609 /* This macro might eventually find a better home than here. */
2610
2611 #define CHECK_KEY_ARGUMENT(key) \
2612 do { \
2613 if (NILP (key)) \
2614 { \
2615 key = Qidentity; \
2616 } \
2617 \
2618 if (!EQ (key, Qidentity)) \
2619 { \
2620 key = indirect_function (key, 1); \
2621 if (EQ (key, XSYMBOL_FUNCTION (Qidentity))) \
2622 { \
2623 key = Qidentity; \
2624 } \
2625 } \
2626 } while (0)
2627
2628 #define KEY(key, item) (EQ (Qidentity, key) ? item : \
2629 IGNORE_MULTIPLE_VALUES (call1 (key, item)))
2630
2631 DEFUN ("adjoin", Fadjoin, 2, MANY, 0, /*
2632 Return ITEM consed onto the front of LIST, if not already in LIST.
2633
2634 Otherwise, return LIST unmodified.
2635
2636 See `member*' for the meaning of the keywords.
2637
2638 arguments: (ITEM LIST &key (TEST #'eql) (KEY #'identity) TEST-NOT)
2639 */
2640 (int nargs, Lisp_Object *args))
2641 {
2642 Lisp_Object item = args[0], list = args[1], keyed = Qnil, ignore = Qnil;
2643 struct gcpro gcpro1;
2644 Boolint test_not_unboundp = 1;
2645 check_test_func_t check_test = NULL;
2646
2647 PARSE_KEYWORDS (Fadjoin, nargs, args, 3, (test, key, test_not),
2648 NULL);
2649
2650 CHECK_KEY_ARGUMENT (key);
2651
2652 keyed = KEY (key, item);
2653
2654 GCPRO1 (keyed);
2655 check_test = get_check_test_function (keyed, &test, test_not, Qnil, Qnil,
2656 key, &test_not_unboundp);
2657 if (NILP (list_position_cons_before (&ignore, keyed, list, check_test,
2658 test_not_unboundp, test, key, 0, Qzero,
2659 Qnil)))
2660 {
2661 RETURN_UNGCPRO (Fcons (item, list));
2662 }
2663
2664 RETURN_UNGCPRO (list);
2665 }
2666
1743 DEFUN ("assoc", Fassoc, 2, 2, 0, /* 2667 DEFUN ("assoc", Fassoc, 2, 2, 0, /*
1744 Return non-nil if KEY is `equal' to the car of an element of ALIST. 2668 Return non-nil if KEY is `equal' to the car of an element of ALIST.
1745 The value is actually the element of ALIST whose car equals KEY. 2669 The value is actually the element of ALIST whose car equals KEY.
1746 */ 2670 */
1747 (key, alist)) 2671 (key, alist))
1824 return elt; 2748 return elt;
1825 } 2749 }
1826 return Qnil; 2750 return Qnil;
1827 } 2751 }
1828 2752
2753 DEFUN ("assoc*", FassocX, 2, MANY, 0, /*
2754 Find the first item whose car matches ITEM in ALIST.
2755
2756 See `member*' for the meaning of :test, :test-not and :key.
2757
2758 arguments: (ITEM ALIST &key (TEST #'eql) (KEY #'identity) TEST-NOT)
2759 */
2760 (int nargs, Lisp_Object *args))
2761 {
2762 Lisp_Object item = args[0], alist = args[1];
2763 Boolint test_not_unboundp = 1;
2764 check_test_func_t check_test = NULL;
2765
2766 PARSE_KEYWORDS (FassocX, nargs, args, 5, (test, if_, if_not, test_not, key),
2767 NULL);
2768
2769 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
2770 key, &test_not_unboundp);
2771
2772 if (check_test == check_eq_nokey)
2773 {
2774 /* TEST is #'eq, no need to call any C functions. */
2775 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, alist)
2776 {
2777 if (EQ (item, elt_car) == test_not_unboundp)
2778 {
2779 return elt;
2780 }
2781 }
2782 }
2783 else
2784 {
2785 Lisp_Object tailed = alist;
2786 struct gcpro gcpro1;
2787
2788 GCPRO1 (tailed);
2789 {
2790 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
2791 {
2792 tailed = tail;
2793
2794 if (check_test (test, key, item, elt_car) == test_not_unboundp)
2795 {
2796 RETURN_UNGCPRO (elt);
2797 }
2798 }
2799 }
2800 UNGCPRO;
2801 }
2802
2803 return Qnil;
2804 }
2805
1829 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* 2806 DEFUN ("rassoc", Frassoc, 2, 2, 0, /*
1830 Return non-nil if VALUE is `equal' to the cdr of an element of ALIST. 2807 Return non-nil if VALUE is `equal' to the cdr of an element of ALIST.
1831 The value is actually the element of ALIST whose cdr equals VALUE. 2808 The value is actually the element of ALIST whose cdr equals VALUE.
1832 */ 2809 */
1833 (value, alist)) 2810 (value, alist))
1894 return elt; 2871 return elt;
1895 } 2872 }
1896 return Qnil; 2873 return Qnil;
1897 } 2874 }
1898 2875
2876 DEFUN ("rassoc*", FrassocX, 2, MANY, 0, /*
2877 Find the first item whose cdr matches ITEM in ALIST.
2878
2879 See `member*' for the meaning of :test, :test-not and :key.
2880
2881 arguments: (ITEM ALIST &key (TEST #'eql) (KEY #'identity) TEST-NOT)
2882 */
2883 (int nargs, Lisp_Object *args))
2884 {
2885 Lisp_Object item = args[0], alist = args[1];
2886 Boolint test_not_unboundp = 1;
2887 check_test_func_t check_test = NULL;
2888
2889 PARSE_KEYWORDS (FrassocX, nargs, args, 5, (test, if_, if_not, test_not, key),
2890 NULL);
2891
2892 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
2893 key, &test_not_unboundp);
2894
2895 if (check_test == check_eq_nokey)
2896 {
2897 /* TEST is #'eq, no need to call any C functions. */
2898 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, alist)
2899 {
2900 if (EQ (item, elt_cdr) == test_not_unboundp)
2901 {
2902 return elt;
2903 }
2904 }
2905 }
2906 else
2907 {
2908 struct gcpro gcpro1;
2909 Lisp_Object tailed = alist;
2910
2911 GCPRO1 (tailed);
2912 {
2913 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
2914 {
2915 tailed = tail;
2916
2917 if (check_test (test, key, item, elt_cdr) == test_not_unboundp)
2918 {
2919 RETURN_UNGCPRO (elt);
2920 }
2921 }
2922 }
2923 UNGCPRO;
2924 }
2925
2926 return Qnil;
2927 }
2928
2929 /* This is the implementation of both #'find and #'position. */
2930 static Lisp_Object
2931 position (Lisp_Object *object_out, Lisp_Object item, Lisp_Object sequence,
2932 check_test_func_t check_test, Boolint test_not_unboundp,
2933 Lisp_Object test, Lisp_Object key, Lisp_Object start, Lisp_Object end,
2934 Lisp_Object from_end, Lisp_Object default_, Lisp_Object caller)
2935 {
2936 Lisp_Object result = Qnil;
2937 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0;
2938
2939 CHECK_SEQUENCE (sequence);
2940 CHECK_NATNUM (start);
2941 starting = INTP (start) ? XINT (start) : 1 + EMACS_INT_MAX;
2942
2943 if (!NILP (end))
2944 {
2945 CHECK_NATNUM (end);
2946 ending = INTP (end) ? XINT (end) : 1 + EMACS_INT_MAX;
2947 }
2948
2949 *object_out = default_;
2950
2951 if (CONSP (sequence))
2952 {
2953 Lisp_Object elt, tail = Qnil;
2954 struct gcpro gcpro1;
2955
2956 if (!(starting < ending))
2957 {
2958 check_sequence_range (sequence, start, end, Flength (sequence));
2959 /* starting could be equal to ending, in which case nil is what
2960 we want to return. */
2961 return Qnil;
2962 }
2963
2964 GCPRO1 (tail);
2965
2966 {
2967 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len)
2968 {
2969 if (starting <= ii && ii < ending
2970 && check_test (test, key, item, elt) == test_not_unboundp)
2971 {
2972 result = make_integer (ii);
2973 *object_out = elt;
2974
2975 if (NILP (from_end))
2976 {
2977 UNGCPRO;
2978 return result;
2979 }
2980 }
2981 else if (ii == ending)
2982 {
2983 break;
2984 }
2985
2986 ii++;
2987 }
2988 }
2989
2990 UNGCPRO;
2991
2992 if (ii < starting || (ii < ending && !NILP (end)))
2993 {
2994 check_sequence_range (sequence, start, end, Flength (sequence));
2995 }
2996 }
2997 else if (STRINGP (sequence))
2998 {
2999 Ibyte *startp = XSTRING_DATA (sequence), *cursor = startp;
3000 Bytecount byte_len = XSTRING_LENGTH (sequence), cursor_offset = 0;
3001 Lisp_Object character = Qnil;
3002
3003 while (cursor_offset < byte_len && ii < ending)
3004 {
3005 if (ii >= starting)
3006 {
3007 character = make_char (itext_ichar (cursor));
3008
3009 if (check_test (test, key, item, character) == test_not_unboundp)
3010 {
3011 result = make_integer (ii);
3012 *object_out = character;
3013
3014 if (NILP (from_end))
3015 {
3016 return result;
3017 }
3018 }
3019
3020 startp = XSTRING_DATA (sequence);
3021 cursor = startp + cursor_offset;
3022 if (byte_len != XSTRING_LENGTH (sequence)
3023 || !valid_ibyteptr_p (cursor))
3024 {
3025 mapping_interaction_error (caller, sequence);
3026 }
3027 }
3028
3029 INC_IBYTEPTR (cursor);
3030 cursor_offset = cursor - startp;
3031 ii++;
3032 }
3033
3034 if (ii < starting || (ii < ending && !NILP (end)))
3035 {
3036 check_sequence_range (sequence, start, end, Flength (sequence));
3037 }
3038 }
3039 else
3040 {
3041 Lisp_Object object = Qnil;
3042 len = XINT (Flength (sequence));
3043 check_sequence_range (sequence, start, end, make_int (len));
3044
3045 ending = min (ending, len);
3046 if (0 == len)
3047 {
3048 /* Catches the case where we have nil. */
3049 return result;
3050 }
3051
3052 if (NILP (from_end))
3053 {
3054 for (ii = starting; ii < ending; ii++)
3055 {
3056 object = Faref (sequence, make_int (ii));
3057 if (check_test (test, key, item, object) == test_not_unboundp)
3058 {
3059 result = make_integer (ii);
3060 *object_out = object;
3061 return result;
3062 }
3063 }
3064 }
3065 else
3066 {
3067 for (ii = ending - 1; ii >= starting; ii--)
3068 {
3069 object = Faref (sequence, make_int (ii));
3070 if (check_test (test, key, item, object) == test_not_unboundp)
3071 {
3072 result = make_integer (ii);
3073 *object_out = object;
3074 return result;
3075 }
3076 }
3077 }
3078 }
3079
3080 return result;
3081 }
3082
3083 DEFUN ("position", Fposition, 2, MANY, 0, /*
3084 Return the index of the first occurrence of ITEM in SEQUENCE.
3085
3086 Return nil if not found. See `remove*' for the meaning of the keywords.
3087
3088 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END TEST-NOT)
3089 */
3090 (int nargs, Lisp_Object *args))
3091 {
3092 Lisp_Object object = Qnil, item = args[0], sequence = args[1];
3093 Boolint test_not_unboundp = 1;
3094 check_test_func_t check_test = NULL;
3095
3096 PARSE_KEYWORDS (Fposition, nargs, args, 8,
3097 (test, if_, test_not, if_not, key, start, end, from_end),
3098 (start = Qzero));
3099
3100 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3101 key, &test_not_unboundp);
3102
3103 return position (&object, item, sequence, check_test, test_not_unboundp,
3104 test, key, start, end, from_end, Qnil, Qposition);
3105 }
3106
3107 DEFUN ("find", Ffind, 2, MANY, 0, /*
3108 Find the first occurrence of ITEM in SEQUENCE.
3109
3110 Return the matching ITEM, or nil if not found. See `remove*' for the
3111 meaning of the keywords.
3112
3113 The keyword :default, not specified by Common Lisp, designates an object to
3114 return instead of nil if ITEM is not found.
3115
3116 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) DEFAULT FROM-END TEST-NOT)
3117 */
3118 (int nargs, Lisp_Object *args))
3119 {
3120 Lisp_Object object = Qnil, item = args[0], sequence = args[1];
3121 Boolint test_not_unboundp = 1;
3122 check_test_func_t check_test = NULL;
3123
3124 PARSE_KEYWORDS (Fposition, nargs, args, 9,
3125 (test, if_, test_not, if_not, key, start, end, from_end,
3126 default_),
3127 (start = Qzero));
3128
3129 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3130 key, &test_not_unboundp);
3131
3132 position (&object, item, sequence, check_test, test_not_unboundp,
3133 test, key, start, end, from_end, Qnil, Qposition);
3134
3135 return object;
3136 }
1899 3137
1900 DEFUN ("delete", Fdelete, 2, 2, 0, /* 3138 DEFUN ("delete", Fdelete, 2, 2, 0, /*
1901 Delete by side effect any occurrences of ELT as a member of LIST. 3139 Delete by side effect any occurrences of ELT as a member of LIST.
1902 The modified LIST is returned. Comparison is done with `equal'. 3140 The modified LIST is returned. Comparison is done with `equal'.
1903 If the first member of LIST is ELT, there is no way to remove it by side 3141 If the first member of LIST is ELT, there is no way to remove it by side
1998 } 3236 }
1999 } 3237 }
2000 return list; 3238 return list;
2001 } 3239 }
2002 3240
3241 DEFUN ("delete*", FdeleteX, 2, MANY, 0, /*
3242 Remove all occurrences of ITEM in SEQUENCE, destructively.
3243
3244 If SEQUENCE is a non-nil list, this modifies the list directly. A non-list
3245 SEQUENCE will not be destructively modified, rather, if ITEM occurs in it, a
3246 new SEQUENCE of the same type without ITEM will be returned.
3247
3248 See `remove*' for a non-destructive alternative, and for explanation of the
3249 keyword arguments.
3250
3251 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT TEST-NOT)
3252 */
3253 (int nargs, Lisp_Object *args))
3254 {
3255 Lisp_Object item = args[0], sequence = args[1], tail = sequence;
3256 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX;
3257 Elemcount len, ii = 0, encountered = 0, presenting = 0;
3258 Boolint test_not_unboundp = 1;
3259 check_test_func_t check_test = NULL;
3260 struct gcpro gcpro1;
3261
3262 PARSE_KEYWORDS (FdeleteX, nargs, args, 9,
3263 (test, if_not, if_, test_not, key, start, end, from_end,
3264 count), (start = Qzero, count = Qunbound));
3265
3266 CHECK_SEQUENCE (sequence);
3267 CHECK_NATNUM (start);
3268 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
3269
3270 if (!NILP (end))
3271 {
3272 CHECK_NATNUM (end);
3273 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
3274 }
3275
3276 if (!UNBOUNDP (count))
3277 {
3278 if (!NILP (count))
3279 {
3280 CHECK_INTEGER (count);
3281 if (INTP (count))
3282 {
3283 counting = XINT (count);
3284 }
3285 #ifdef HAVE_BIGNUM
3286 else
3287 {
3288 counting = bignum_sign (XBIGNUM_DATA (count)) > 0 ?
3289 1 + EMACS_INT_MAX : EMACS_INT_MIN - 1;
3290 }
3291 #endif
3292
3293 if (counting < 1)
3294 {
3295 return sequence;
3296 }
3297 }
3298 }
3299
3300 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3301 key, &test_not_unboundp);
3302
3303 if (CONSP (sequence))
3304 {
3305 Lisp_Object prev_tail_list_elt = Qnil, list_elt = Qnil;
3306 Elemcount list_len = 0, deleted = 0;
3307
3308 if (!NILP (count) && !NILP (from_end))
3309 {
3310 /* Both COUNT and FROM-END were specified; we need to traverse the
3311 list twice. */
3312 Lisp_Object present = count_with_tail (&list_elt, nargs, args,
3313 QdeleteX);
3314
3315 if (ZEROP (present))
3316 {
3317 return sequence;
3318 }
3319
3320 presenting = XINT (present);
3321
3322 /* If there are fewer items in the list than we have permission to
3323 delete, we don't need to differentiate between the :from-end
3324 nil and :from-end t cases. Otherwise, presenting is the number
3325 of matching items we need to ignore before we start to
3326 delete. */
3327 presenting = presenting <= counting ? 0 : presenting - counting;
3328 }
3329
3330 GCPRO1 (tail);
3331 ii = -1;
3332
3333 {
3334 EXTERNAL_LIST_LOOP_4_NO_DECLARE (list_elt, sequence, tail, list_len)
3335 {
3336 ii++;
3337
3338 if (starting <= ii && ii < ending &&
3339 (check_test (test, key, item, list_elt) == test_not_unboundp)
3340 && (presenting ? encountered++ >= presenting
3341 : encountered++ < counting))
3342 {
3343 if (NILP (prev_tail_list_elt))
3344 {
3345 sequence = XCDR (tail);
3346 }
3347 else
3348 {
3349 XSETCDR (prev_tail_list_elt, XCDR (tail));
3350 }
3351
3352 /* Keep tortoise from ever passing hare. */
3353 list_len = 0;
3354 deleted++;
3355 }
3356 else
3357 {
3358 prev_tail_list_elt = tail;
3359 if (ii >= ending || (!presenting && encountered > counting))
3360 {
3361 break;
3362 }
3363 }
3364 }
3365 }
3366
3367 UNGCPRO;
3368
3369 if ((ii < starting || (ii < ending && !NILP (end))) &&
3370 !(presenting ? encountered == presenting : encountered == counting))
3371 {
3372 check_sequence_range (args[1], start, end,
3373 make_int (deleted + XINT (Flength (args[1]))));
3374 }
3375
3376 return sequence;
3377 }
3378 else if (STRINGP (sequence))
3379 {
3380 Ibyte *staging = alloca_ibytes (XSTRING_LENGTH (sequence));
3381 Ibyte *staging_cursor = staging, *startp = XSTRING_DATA (sequence);
3382 Ibyte *cursor = startp;
3383 Bytecount cursor_offset = 0, byte_len = XSTRING_LENGTH (sequence);
3384 Lisp_Object character, result = sequence;
3385
3386 if (!NILP (count) && !NILP (from_end))
3387 {
3388 Lisp_Object present = count_with_tail (&character, nargs, args,
3389 QdeleteX);
3390
3391 if (ZEROP (present))
3392 {
3393 return sequence;
3394 }
3395
3396 presenting = XINT (present);
3397
3398 /* If there are fewer items in the list than we have permission to
3399 delete, we don't need to differentiate between the :from-end
3400 nil and :from-end t cases. Otherwise, presenting is the number
3401 of matching items we need to ignore before we start to
3402 delete. */
3403 presenting = presenting <= counting ? 0 : presenting - counting;
3404 }
3405
3406 ii = 0;
3407 while (cursor_offset < byte_len)
3408 {
3409 if (ii >= starting && ii < ending)
3410 {
3411 character = make_char (itext_ichar (cursor));
3412
3413 if ((check_test (test, key, item, character)
3414 == test_not_unboundp)
3415 && (presenting ? encountered++ >= presenting :
3416 encountered++ < counting))
3417 {
3418 DO_NOTHING;
3419 }
3420 else
3421 {
3422 staging_cursor
3423 += set_itext_ichar (staging_cursor, XCHAR (character));
3424 }
3425
3426 startp = XSTRING_DATA (sequence);
3427 cursor = startp + cursor_offset;
3428 if (byte_len != XSTRING_LENGTH (sequence)
3429 || !valid_ibyteptr_p (cursor))
3430 {
3431 mapping_interaction_error (QdeleteX, sequence);
3432 }
3433 }
3434 else
3435 {
3436 staging_cursor += itext_copy_ichar (cursor, staging_cursor);
3437 }
3438
3439 INC_IBYTEPTR (cursor);
3440 cursor_offset = cursor - startp;
3441 ii++;
3442 }
3443
3444 if (ii < starting || (ii < ending && !NILP (end)))
3445 {
3446 check_sequence_range (sequence, start, end, Flength (sequence));
3447 }
3448
3449 if (0 != encountered)
3450 {
3451 result = make_string (staging, staging_cursor - staging);
3452 copy_string_extents (result, sequence, 0, 0,
3453 staging_cursor - staging);
3454 sequence = result;
3455 }
3456
3457 return sequence;
3458 }
3459 else
3460 {
3461 Lisp_Object position0 = Qnil, object = Qnil;
3462 Lisp_Object *staging = NULL, *staging_cursor, *staging_limit;
3463 Elemcount positioning;
3464
3465 len = XINT (Flength (sequence));
3466
3467 check_sequence_range (sequence, start, end, make_int (len));
3468
3469 position0 = position (&object, item, sequence, check_test,
3470 test_not_unboundp, test, key, start, end,
3471 from_end, Qnil, QdeleteX);
3472 if (NILP (position0))
3473 {
3474 return sequence;
3475 }
3476
3477 ending = min (ending, len);
3478 positioning = XINT (position0);
3479 encountered = 1;
3480
3481 if (NILP (from_end))
3482 {
3483 staging = alloca_array (Lisp_Object, len - 1);
3484 staging_cursor = staging;
3485
3486 ii = 0;
3487 while (ii < positioning)
3488 {
3489 *staging_cursor++ = Faref (sequence, make_int (ii));
3490 ii++;
3491 }
3492
3493 ii = positioning + 1;
3494 while (ii < ending)
3495 {
3496 object = Faref (sequence, make_int (ii));
3497 if (encountered < counting
3498 && (check_test (test, key, item, object)
3499 == test_not_unboundp))
3500 {
3501 encountered++;
3502 }
3503 else
3504 {
3505 *staging_cursor++ = object;
3506 }
3507 ii++;
3508 }
3509
3510 while (ii < len)
3511 {
3512 *staging_cursor++ = Faref (sequence, make_int (ii));
3513 ii++;
3514 }
3515 }
3516 else
3517 {
3518 staging = alloca_array (Lisp_Object, len - 1);
3519 staging_cursor = staging_limit = staging + len - 1;
3520
3521 ii = len - 1;
3522 while (ii > positioning)
3523 {
3524 *--staging_cursor = Faref (sequence, make_int (ii));
3525 ii--;
3526 }
3527
3528 ii = positioning - 1;
3529 while (ii >= starting)
3530 {
3531 object = Faref (sequence, make_int (ii));
3532 if (encountered < counting
3533 && (check_test (test, key, item, object) ==
3534 test_not_unboundp))
3535 {
3536 encountered++;
3537 }
3538 else
3539 {
3540 *--staging_cursor = object;
3541 }
3542
3543 ii--;
3544 }
3545
3546 while (ii >= 0)
3547 {
3548 *--staging_cursor = Faref (sequence, make_int (ii));
3549 ii--;
3550 }
3551
3552 staging = staging_cursor;
3553 staging_cursor = staging_limit;
3554 }
3555
3556 if (VECTORP (sequence))
3557 {
3558 return Fvector (staging_cursor - staging, staging);
3559 }
3560 else if (BIT_VECTORP (sequence))
3561 {
3562 return Fbit_vector (staging_cursor - staging, staging);
3563 }
3564
3565 /* A nil sequence will have given us a nil #'position,
3566 above. */
3567 ABORT ();
3568
3569 return Qnil;
3570 }
3571 }
3572
3573 DEFUN ("remove*", FremoveX, 2, MANY, 0, /*
3574 Remove all occurrences of ITEM in SEQUENCE, non-destructively.
3575
3576 If SEQUENCE is a list, `remove*' makes a copy if that is necessary to avoid
3577 corrupting the original SEQUENCE.
3578
3579 The keywords :test and :test-not specify two-argument test and negated-test
3580 predicates, respectively; :test defaults to `eql'. :key specifies a
3581 one-argument function that transforms elements of SEQUENCE into \"comparison
3582 keys\" before the test predicate is applied. See `member*' for more
3583 information on these keywords.
3584
3585 :start and :end, if given, specify indices of a subsequence of SEQUENCE to
3586 be processed. Indices are 0-based and processing involves the subsequence
3587 starting at the index given by :start and ending just before the index given
3588 by :end.
3589
3590 :count, if given, limits the number of items removed to the number
3591 specified. :from-end, if given, causes processing to proceed starting from
3592 the end instead of the beginning; in this case, this matters only if :count
3593 is given.
3594
3595 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT TEST-NOT)
3596 */
3597 (int nargs, Lisp_Object *args))
3598 {
3599 Lisp_Object item = args[0], sequence = args[1], matched_count = Qnil,
3600 tail = Qnil;
3601 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX;
3602 Elemcount len, ii = 0, encountered = 0, presenting = 0;
3603 Boolint test_not_unboundp = 1;
3604 check_test_func_t check_test = NULL;
3605 struct gcpro gcpro1;
3606
3607 PARSE_KEYWORDS (FremoveX, nargs, args, 9,
3608 (test, if_not, if_, test_not, key, start, end, from_end,
3609 count), (start = Qzero));
3610
3611 if (!CONSP (sequence))
3612 {
3613 return FdeleteX (nargs, args);
3614 }
3615
3616 CHECK_NATNUM (start);
3617 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
3618
3619 if (!NILP (end))
3620 {
3621 CHECK_NATNUM (end);
3622 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
3623 }
3624
3625 if (!NILP (count))
3626 {
3627 CHECK_INTEGER (count);
3628 if (INTP (count))
3629 {
3630 counting = XINT (count);
3631 }
3632 #ifdef HAVE_BIGNUM
3633 else
3634 {
3635 counting = bignum_sign (XBIGNUM_DATA (count)) > 0 ?
3636 1 + EMACS_INT_MAX : -1 + EMACS_INT_MIN;
3637 }
3638 #endif
3639
3640 if (counting <= 0)
3641 {
3642 return sequence;
3643 }
3644 }
3645
3646 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3647 key, &test_not_unboundp);
3648
3649 matched_count = count_with_tail (&tail, nargs, args, QremoveX);
3650
3651 if (!ZEROP (matched_count))
3652 {
3653 Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil;
3654 GCPRO1 (tailing);
3655
3656 if (!NILP (count) && !NILP (from_end))
3657 {
3658 presenting = XINT (matched_count);
3659
3660 /* If there are fewer matching elements in the list than we have
3661 permission to delete, we don't need to differentiate between
3662 the :from-end nil and :from-end t cases. Otherwise, presenting
3663 is the number of matching items we need to ignore before we
3664 start to delete. */
3665 presenting = presenting <= counting ? 0 : presenting - counting;
3666 }
3667
3668 {
3669 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len)
3670 {
3671 if (EQ (tail, tailing))
3672 {
3673 if (NILP (result))
3674 {
3675 RETURN_UNGCPRO (XCDR (tail));
3676 }
3677
3678 XSETCDR (result_tail, XCDR (tail));
3679 RETURN_UNGCPRO (result);
3680 }
3681 else if (starting <= ii && ii < ending &&
3682 (check_test (test, key, item, elt) == test_not_unboundp)
3683 && (presenting ? encountered++ >= presenting
3684 : encountered++ < counting))
3685 {
3686 DO_NOTHING;
3687 }
3688 else if (NILP (result))
3689 {
3690 result = result_tail = Fcons (elt, Qnil);
3691 }
3692 else
3693 {
3694 XSETCDR (result_tail, Fcons (elt, Qnil));
3695 result_tail = XCDR (result_tail);
3696 }
3697
3698 if (ii == ending)
3699 {
3700 break;
3701 }
3702
3703 ii++;
3704 }
3705 }
3706
3707 UNGCPRO;
3708
3709 if (ii < starting || (ii < ending && !NILP (end)))
3710 {
3711 check_sequence_range (args[0], start, end, Flength (args[0]));
3712 }
3713
3714 return result;
3715 }
3716
3717 return sequence;
3718 }
3719
2003 DEFUN ("remassoc", Fremassoc, 2, 2, 0, /* 3720 DEFUN ("remassoc", Fremassoc, 2, 2, 0, /*
2004 Delete by side effect any elements of ALIST whose car is `equal' to KEY. 3721 Delete by side effect any elements of ALIST whose car is `equal' to KEY.
2005 The modified ALIST is returned. If the first member of ALIST has a car 3722 The modified ALIST is returned. If the first member of ALIST has a car
2006 that is `equal' to KEY, there is no way to remove it by side effect; 3723 that is `equal' to KEY, there is no way to remove it by side effect;
2007 therefore, write `(setq foo (remassoc key foo))' to be sure of changing 3724 therefore, write `(setq foo (remassoc key foo))' to be sure of changing
2086 LIST_LOOP_DELETE_IF (elt, alist, 3803 LIST_LOOP_DELETE_IF (elt, alist,
2087 (CONSP (elt) && 3804 (CONSP (elt) &&
2088 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt)))); 3805 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt))));
2089 return alist; 3806 return alist;
2090 } 3807 }
2091 3808
3809 /* Remove duplicate elements between START and END from LIST, a non-nil
3810 list; if COPY is zero, do so destructively. Items to delete are selected
3811 according to the algorithm used when :from-end t is passed to
3812 #'delete-duplicates. Error if LIST is ill-formed or circular.
3813
3814 TEST and KEY are as in #'remove*; CHECK_TEST and TEST_NOT_UNBOUNDP should
3815 reflect them, having been initialised with get_check_match_function() or
3816 get_check_test_function(). */
3817 static Lisp_Object
3818 list_delete_duplicates_from_end (Lisp_Object list,
3819 check_test_func_t check_test,
3820 Boolint test_not_unboundp,
3821 Lisp_Object test, Lisp_Object key,
3822 Lisp_Object start,
3823 Lisp_Object end, Boolint copy)
3824 {
3825 Lisp_Object checking = Qnil, elt, tail, result = list;
3826 Lisp_Object keyed, positioned, position_cons = Qnil, result_tail;
3827 Elemcount len = XINT (Flength (list)), pos, starting = XINT (start);
3828 Elemcount ending = (NILP (end) ? len : XINT (end)), greatest_pos_seen = -1;
3829 Elemcount ii = 0;
3830 struct gcpro gcpro1, gcpro2;
3831
3832 /* We can't delete (or remove) as we go, because that breaks START and
3833 END. We could if END were nil, and that would change an ON(N + 2)
3834 algorithm to an ON^2 algorithm; list_position_cons_before() would need to
3835 be modified to return the cons *before* the one containing the item for
3836 that. Here and now it doesn't matter, though, #'delete-duplicates is
3837 relatively expensive no matter what. */
3838 struct Lisp_Bit_Vector *deleting
3839 = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector)
3840 + (sizeof (long)
3841 * (BIT_VECTOR_LONG_STORAGE (len)
3842 - 1)));
3843
3844 check_sequence_range (list, start, end, make_integer (len));
3845
3846 deleting->size = len;
3847 memset (&(deleting->bits), 0,
3848 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len));
3849
3850 GCPRO2 (tail, keyed);
3851
3852 {
3853 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len)
3854 {
3855 if (!(starting <= ii && ii <= ending) || bit_vector_bit (deleting, ii))
3856 {
3857 ii++;
3858 continue;
3859 }
3860
3861 keyed = KEY (key, elt);
3862 checking = XCDR (tail);
3863 pos = ii + 1;
3864
3865 while (!NILP ((positioned = list_position_cons_before
3866 (&position_cons, keyed, checking, check_test,
3867 test_not_unboundp, test, key, 0,
3868 make_int (max (starting - pos, 0)),
3869 make_int (ending - pos)))))
3870 {
3871 pos = XINT (positioned) + pos;
3872 set_bit_vector_bit (deleting, pos, 1);
3873 greatest_pos_seen = max (greatest_pos_seen, pos);
3874 checking = NILP (position_cons) ?
3875 XCDR (checking) : XCDR (XCDR (position_cons));
3876 pos += 1;
3877 }
3878 ii++;
3879 }
3880 }
3881
3882 UNGCPRO;
3883
3884 ii = 0;
3885
3886 if (greatest_pos_seen > -1)
3887 {
3888 if (copy)
3889 {
3890 result = result_tail = Fcons (XCAR (list), Qnil);
3891 list = XCDR (list);
3892 ii = 1;
3893
3894 {
3895 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len)
3896 {
3897 if (ii == greatest_pos_seen)
3898 {
3899 XSETCDR (result_tail, XCDR (tail));
3900 break;
3901 }
3902 else if (!bit_vector_bit (deleting, ii))
3903 {
3904 XSETCDR (result_tail, Fcons (elt, Qnil));
3905 result_tail = XCDR (result_tail);
3906 }
3907 ii++;
3908 }
3909 }
3910 }
3911 else
3912 {
3913 EXTERNAL_LIST_LOOP_DELETE_IF (elt0, list,
3914 bit_vector_bit (deleting, ii++));
3915 }
3916 }
3917
3918 return result;
3919 }
3920
3921 DEFUN ("delete-duplicates", Fdelete_duplicates, 1, MANY, 0, /*
3922 Remove all duplicate elements from SEQUENCE, destructively.
3923
3924 If SEQUENCE is a list and has duplicates, modify and return it. Note that
3925 SEQUENCE may start with an element to be deleted; because of this, if
3926 modifying a variable, be sure to write `(setq VARIABLE (delete-duplicates
3927 VARIABLE))' to be certain to have a list without duplicate elements.
3928
3929 If SEQUENCE is an array and has duplicates, return a newly-allocated array
3930 of the same type comprising all unique elements of SEQUENCE.
3931
3932 If there are no duplicate elements in SEQUENCE, return it unmodified.
3933
3934 See `remove*' for the meaning of the keywords. See `remove-duplicates' for
3935 a non-destructive version of this function.
3936
3937 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT)
3938 */
3939 (int nargs, Lisp_Object *args))
3940 {
3941 Lisp_Object sequence = args[0], tail = sequence, keyed = Qnil, elt = Qnil;
3942 Lisp_Object elt0 = Qnil, positioned = Qnil, ignore = Qnil;
3943 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0, jj = 0;
3944 Boolint test_not_unboundp = 1;
3945 check_test_func_t check_test = NULL;
3946 struct gcpro gcpro1, gcpro2;
3947
3948 PARSE_KEYWORDS (Fdelete_duplicates, nargs, args, 6,
3949 (test, key, test_not, start, end, from_end),
3950 (start = Qzero));
3951
3952 CHECK_SEQUENCE (sequence);
3953 CHECK_NATNUM (start);
3954 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
3955
3956 if (!NILP (end))
3957 {
3958 CHECK_NATNUM (end);
3959 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
3960 }
3961
3962 CHECK_KEY_ARGUMENT (key);
3963
3964 get_check_match_function (&test, test_not, Qnil, Qnil, key,
3965 &test_not_unboundp, &check_test);
3966
3967 if (CONSP (sequence))
3968 {
3969 if (NILP (from_end))
3970 {
3971 Lisp_Object prev_tail = Qnil;
3972 Elemcount deleted = 0;
3973
3974 GCPRO2 (tail, keyed);
3975
3976 {
3977 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len)
3978 {
3979 if (starting <= ii && ii < ending)
3980 {
3981 keyed = KEY (key, elt);
3982 positioned
3983 = list_position_cons_before (&ignore, keyed,
3984 XCDR (tail), check_test,
3985 test_not_unboundp, test, key,
3986 0, make_int (max (starting
3987 - (ii + 1),
3988 0)),
3989 make_int (ending
3990 - (ii + 1)));
3991 if (!NILP (positioned))
3992 {
3993 sequence = XCDR (tail);
3994 deleted++;
3995 }
3996 else
3997 {
3998 break;
3999 }
4000 }
4001 else
4002 {
4003 break;
4004 }
4005
4006 ii++;
4007 }
4008 }
4009 {
4010 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len)
4011 {
4012 if (!(starting <= ii && ii <= ending))
4013 {
4014 prev_tail = tail;
4015 ii++;
4016 continue;
4017 }
4018
4019 keyed = KEY (key, elt0);
4020 positioned
4021 = list_position_cons_before (&ignore, keyed, XCDR (tail),
4022 check_test, test_not_unboundp,
4023 test, key, 0,
4024 make_int (max (starting
4025 - (ii + 1), 0)),
4026 make_int (ending - (ii + 1)));
4027 if (!NILP (positioned))
4028 {
4029 /* We know this isn't the first iteration of the loop,
4030 because we advanced above to the point where we have at
4031 least one non-duplicate entry at the head of the
4032 list. */
4033 XSETCDR (prev_tail, XCDR (tail));
4034 len = 0;
4035 deleted++;
4036 }
4037 else
4038 {
4039 prev_tail = tail;
4040 if (ii >= ending)
4041 {
4042 break;
4043 }
4044 }
4045
4046 ii++;
4047 }
4048 }
4049 UNGCPRO;
4050
4051 if ((ii < starting || (ii < ending && !NILP (end))))
4052 {
4053 check_sequence_range (args[0], start, end,
4054 make_int (deleted
4055 + XINT (Flength (args[0]))));
4056 }
4057 }
4058 else
4059 {
4060 sequence = list_delete_duplicates_from_end (sequence, check_test,
4061 test_not_unboundp,
4062 test, key, start, end,
4063 0);
4064 }
4065 }
4066 else if (STRINGP (sequence))
4067 {
4068 if (EQ (Qidentity, key))
4069 {
4070 /* We know all the elements will be characters; set check_test to
4071 reflect that. This isn't useful if KEY is not #'identity, since
4072 it may return non-characters for the elements. */
4073 check_test = get_check_test_function (make_char ('a'),
4074 &test, test_not,
4075 Qnil, Qnil, key,
4076 &test_not_unboundp);
4077 }
4078
4079 if (NILP (from_end))
4080 {
4081 Bytecount byte_len = XSTRING_LENGTH (sequence), cursor_offset = 0;
4082 Ibyte *staging = alloca_ibytes (byte_len), *staging_cursor = staging;
4083 Ibyte *cursor = XSTRING_DATA (sequence), *startp = cursor;
4084 Elemcount deleted = 0;
4085
4086 elt = Qnil;
4087 GCPRO1 (elt);
4088
4089 while (cursor_offset < byte_len)
4090 {
4091 if (starting <= ii && ii < ending)
4092 {
4093 Ibyte *cursor0 = cursor;
4094 Bytecount cursor0_offset;
4095 Boolint delete_this = 0;
4096
4097 elt = KEY (key, make_char (itext_ichar (cursor)));
4098 INC_IBYTEPTR (cursor0);
4099 cursor0_offset = cursor0 - startp;
4100
4101 for (jj = ii + 1; jj < ending && cursor0_offset < byte_len;
4102 jj++)
4103 {
4104 if (check_test (test, key, elt,
4105 make_char (itext_ichar (cursor0)))
4106 == test_not_unboundp)
4107 {
4108 delete_this = 1;
4109 deleted++;
4110 break;
4111 }
4112
4113 startp = XSTRING_DATA (sequence);
4114 cursor0 = startp + cursor0_offset;
4115 if (byte_len != XSTRING_LENGTH (sequence)
4116 || !valid_ibyteptr_p (cursor0))
4117 {
4118 mapping_interaction_error (Qdelete_duplicates,
4119 sequence);
4120 }
4121
4122 INC_IBYTEPTR (cursor0);
4123 cursor0_offset = cursor0 - startp;
4124 }
4125
4126 startp = XSTRING_DATA (sequence);
4127 cursor = startp + cursor_offset;
4128
4129 if (byte_len != XSTRING_LENGTH (sequence)
4130 || !valid_ibyteptr_p (cursor))
4131 {
4132 mapping_interaction_error (Qdelete_duplicates, sequence);
4133 }
4134
4135 if (!delete_this)
4136 {
4137 staging_cursor
4138 += itext_copy_ichar (cursor, staging_cursor);
4139
4140 }
4141 }
4142 else
4143 {
4144 staging_cursor += itext_copy_ichar (cursor, staging_cursor);
4145 }
4146
4147 INC_IBYTEPTR (cursor);
4148 cursor_offset = cursor - startp;
4149 ii++;
4150 }
4151
4152 UNGCPRO;
4153
4154 if (ii < starting || (ii < ending && !NILP (end)))
4155 {
4156 check_sequence_range (sequence, start, end, Flength (sequence));
4157 }
4158
4159 if (0 != deleted)
4160 {
4161 sequence = make_string (staging, staging_cursor - staging);
4162 }
4163 }
4164 else
4165 {
4166 Elemcount deleted = 0;
4167 Ibyte *staging = alloca_ibytes ((len = string_char_length (sequence))
4168 * MAX_ICHAR_LEN);
4169 Ibyte *staging_cursor = staging, *startp = XSTRING_DATA (sequence);
4170 Ibyte *endp = startp + XSTRING_LENGTH (sequence);
4171 struct Lisp_Bit_Vector *deleting
4172 = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector)
4173 + (sizeof (long)
4174 * (BIT_VECTOR_LONG_STORAGE (len)
4175 - 1)));
4176
4177 check_sequence_range (sequence, start, end, make_integer (len));
4178
4179 /* For the from_end t case; transform contents to an array with
4180 elements addressable in constant time, use the same algorithm
4181 as for vectors. */
4182 deleting->size = len;
4183 memset (&(deleting->bits), 0,
4184 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len));
4185
4186 while (startp < endp)
4187 {
4188 itext_copy_ichar (startp, staging + (ii * MAX_ICHAR_LEN));
4189 INC_IBYTEPTR (startp);
4190 ii++;
4191 }
4192
4193 GCPRO1 (elt);
4194
4195 ending = min (ending, len);
4196
4197 for (ii = ending - 1; ii >= starting; ii--)
4198 {
4199 elt = KEY (key, make_char (itext_ichar (staging +
4200 (ii * MAX_ICHAR_LEN))));
4201 for (jj = ii - 1; jj >= starting; jj--)
4202 {
4203 if (check_test (test, key, elt,
4204 make_char (itext_ichar
4205 (staging + (jj * MAX_ICHAR_LEN))))
4206 == test_not_unboundp)
4207 {
4208 set_bit_vector_bit (deleting, ii, 1);
4209 deleted++;
4210 break;
4211 }
4212 }
4213 }
4214
4215 UNGCPRO;
4216
4217 if (0 != deleted)
4218 {
4219 startp = XSTRING_DATA (sequence);
4220
4221 for (ii = 0; ii < len; ii++)
4222 {
4223 if (!bit_vector_bit (deleting, ii))
4224 {
4225 staging_cursor
4226 += itext_copy_ichar (startp, staging_cursor);
4227 }
4228
4229 INC_IBYTEPTR (startp);
4230 }
4231
4232 sequence = make_string (staging, staging_cursor - staging);
4233 }
4234 }
4235 }
4236 else if (VECTORP (sequence))
4237 {
4238 Elemcount deleted = 0;
4239 Lisp_Object *content = XVECTOR_DATA (sequence);
4240 struct Lisp_Bit_Vector *deleting;
4241
4242 len = XVECTOR_LENGTH (sequence);
4243 check_sequence_range (sequence, start, end, make_integer (len));
4244
4245 deleting = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector)
4246 + (sizeof (long)
4247 * (BIT_VECTOR_LONG_STORAGE (len)
4248 - 1)));
4249 deleting->size = len;
4250 memset (&(deleting->bits), 0,
4251 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len));
4252
4253 GCPRO1 (elt);
4254
4255 ending = min (ending, len);
4256
4257 if (NILP (from_end))
4258 {
4259 for (ii = starting; ii < ending; ii++)
4260 {
4261 elt = KEY (key, content[ii]);
4262
4263 for (jj = ii + 1; jj < ending; jj++)
4264 {
4265 if (check_test (test, key, elt, content[jj])
4266 == test_not_unboundp)
4267 {
4268 set_bit_vector_bit (deleting, ii, 1);
4269 deleted++;
4270 break;
4271 }
4272 }
4273 }
4274 }
4275 else
4276 {
4277 for (ii = ending - 1; ii >= starting; ii--)
4278 {
4279 elt = KEY (key, content[ii]);
4280
4281 for (jj = ii - 1; jj >= starting; jj--)
4282 {
4283 if (check_test (test, key, elt, content[jj])
4284 == test_not_unboundp)
4285 {
4286 set_bit_vector_bit (deleting, ii, 1);
4287 deleted++;
4288 break;
4289 }
4290 }
4291 }
4292 }
4293
4294 UNGCPRO;
4295
4296 if (deleted)
4297 {
4298 Lisp_Object res = make_vector (len - deleted, Qnil),
4299 *res_content = XVECTOR_DATA (res);
4300
4301 for (ii = jj = 0; ii < len; ii++)
4302 {
4303 if (!bit_vector_bit (deleting, ii))
4304 {
4305 res_content[jj++] = content[ii];
4306 }
4307 }
4308
4309 sequence = res;
4310 }
4311 }
4312 else if (BIT_VECTORP (sequence))
4313 {
4314 Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence);
4315 Elemcount deleted = 0;
4316 /* I'm a little irritated at this. Basically, the only reasonable
4317 thing delete-duplicates should do if handed a bit vector is return
4318 something of maximum length two and minimum length 0 (because
4319 that's the possible number of distinct elements if EQ is regarded
4320 as identity, which it should be). But to support arbitrary TEST
4321 and KEY arguments, which may be non-deterministic from our
4322 perspective, we need the same algorithm as for vectors. */
4323 struct Lisp_Bit_Vector *deleting;
4324
4325 len = bit_vector_length (bv);
4326
4327 if (EQ (Qidentity, key))
4328 {
4329 /* We know all the elements will be bits; set check_test to
4330 reflect that. This isn't useful if KEY is not #'identity, since
4331 it may return non-bits for the elements. */
4332 check_test = get_check_test_function (Qzero, &test, test_not,
4333 Qnil, Qnil, key,
4334 &test_not_unboundp);
4335 }
4336
4337 check_sequence_range (sequence, start, end, make_integer (len));
4338
4339 deleting = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector)
4340 + (sizeof (long)
4341 * (BIT_VECTOR_LONG_STORAGE (len)
4342 - 1)));
4343 deleting->size = len;
4344 memset (&(deleting->bits), 0,
4345 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len));
4346
4347 ending = min (ending, len);
4348
4349 GCPRO1 (elt);
4350
4351 if (NILP (from_end))
4352 {
4353 for (ii = starting; ii < ending; ii++)
4354 {
4355 elt = KEY (key, make_int (bit_vector_bit (bv, ii)));
4356
4357 for (jj = ii + 1; jj < ending; jj++)
4358 {
4359 if (check_test (test, key, elt,
4360 make_int (bit_vector_bit (bv, jj)))
4361 == test_not_unboundp)
4362 {
4363 set_bit_vector_bit (deleting, ii, 1);
4364 deleted++;
4365 break;
4366 }
4367 }
4368 }
4369 }
4370 else
4371 {
4372 for (ii = ending - 1; ii >= starting; ii--)
4373 {
4374 elt = KEY (key, make_int (bit_vector_bit (bv, ii)));
4375
4376 for (jj = ii - 1; jj >= starting; jj--)
4377 {
4378 if (check_test (test, key, elt,
4379 make_int (bit_vector_bit (bv, jj)))
4380 == test_not_unboundp)
4381 {
4382 set_bit_vector_bit (deleting, ii, 1);
4383 deleted++;
4384 break;
4385 }
4386 }
4387 }
4388 }
4389
4390 UNGCPRO;
4391
4392 if (deleted)
4393 {
4394 Lisp_Object res = make_bit_vector (len - deleted, Qzero);
4395 Lisp_Bit_Vector *resbv = XBIT_VECTOR (res);
4396
4397 for (ii = jj = 0; ii < len; ii++)
4398 {
4399 if (!bit_vector_bit (deleting, ii))
4400 {
4401 set_bit_vector_bit (resbv, jj++, bit_vector_bit (bv, ii));
4402 }
4403 }
4404
4405 sequence = res;
4406 }
4407 }
4408
4409 return sequence;
4410 }
4411
4412 DEFUN ("remove-duplicates", Fremove_duplicates, 1, MANY, 0, /*
4413 Remove duplicate elements from SEQUENCE, non-destructively.
4414
4415 If there are no duplicate elements in SEQUENCE, return it unmodified;
4416 otherwise, return a new object. If SEQUENCE is a list, the new object may
4417 share list structure with SEQUENCE.
4418
4419 See `remove*' for the meaning of the keywords.
4420
4421 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT)
4422 */
4423 (int nargs, Lisp_Object *args))
4424 {
4425 Lisp_Object sequence = args[0], tail = sequence, keyed, positioned = Qnil;
4426 Lisp_Object result = sequence, result_tail = result, cursor = Qnil;
4427 Lisp_Object cons_with_shared_tail = Qnil, elt, elt0;
4428 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0;
4429 Boolint test_not_unboundp = 1;
4430 check_test_func_t check_test = NULL;
4431 struct gcpro gcpro1, gcpro2, gcpro3;
4432
4433 PARSE_KEYWORDS (Fremove_duplicates, nargs, args, 6,
4434 (test, key, test_not, start, end, from_end),
4435 (start = Qzero));
4436
4437 CHECK_SEQUENCE (sequence);
4438
4439 if (!CONSP (sequence))
4440 {
4441 return Fdelete_duplicates (nargs, args);
4442 }
4443
4444 CHECK_NATNUM (start);
4445 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
4446
4447 if (!NILP (end))
4448 {
4449 CHECK_NATNUM (end);
4450 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
4451 }
4452
4453 if (NILP (key))
4454 {
4455 key = Qidentity;
4456 }
4457
4458 get_check_match_function (&test, test_not, Qnil, Qnil, key,
4459 &test_not_unboundp, &check_test);
4460
4461 if (NILP (from_end))
4462 {
4463 Lisp_Object ignore = Qnil;
4464
4465 GCPRO3 (tail, keyed, result);
4466
4467 {
4468 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len)
4469 {
4470 if (starting <= ii && ii <= ending)
4471 {
4472 keyed = KEY (key, elt);
4473 positioned
4474 = list_position_cons_before (&ignore, keyed, XCDR (tail),
4475 check_test, test_not_unboundp,
4476 test, key, 0,
4477 make_int (max (starting
4478 - (ii + 1), 0)),
4479 make_int (ending - (ii + 1)));
4480 if (!NILP (positioned))
4481 {
4482 sequence = result = result_tail = XCDR (tail);
4483 }
4484 else
4485 {
4486 break;
4487 }
4488 }
4489 else
4490 {
4491 break;
4492 }
4493
4494 ii++;
4495 }
4496 }
4497
4498 {
4499 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len)
4500 {
4501 if (!(starting <= ii && ii <= ending))
4502 {
4503 ii++;
4504 continue;
4505 }
4506
4507 /* For this algorithm, each time we encounter an object to be
4508 removed, copy the output list from the tail beyond the last
4509 removed cons to this one. Otherwise, the tail of the output list
4510 is shared with the input list, which is OK. */
4511
4512 keyed = KEY (key, elt0);
4513 positioned
4514 = list_position_cons_before (&ignore, keyed, XCDR (tail),
4515 check_test, test_not_unboundp,
4516 test, key, 0,
4517 make_int (max (starting - (ii + 1),
4518 0)),
4519 make_int (ending - (ii + 1)));
4520 if (!NILP (positioned))
4521 {
4522 if (EQ (result, sequence))
4523 {
4524 result = cons_with_shared_tail
4525 = Fcons (XCAR (sequence), XCDR (sequence));
4526 }
4527
4528 result_tail = cons_with_shared_tail;
4529 cursor = XCDR (cons_with_shared_tail);
4530
4531 while (!EQ (cursor, tail) && !NILP (cursor))
4532 {
4533 XSETCDR (result_tail, Fcons (XCAR (cursor), Qnil));
4534 result_tail = XCDR (result_tail);
4535 cursor = XCDR (cursor);
4536 }
4537
4538 XSETCDR (result_tail, XCDR (tail));
4539 cons_with_shared_tail = result_tail;
4540 }
4541
4542 ii++;
4543 }
4544 }
4545 UNGCPRO;
4546
4547 if ((ii < starting || (ii < ending && !NILP (end))))
4548 {
4549 check_sequence_range (args[0], start, end, Flength (args[0]));
4550 }
4551 }
4552 else
4553 {
4554 result = list_delete_duplicates_from_end (sequence, check_test,
4555 test_not_unboundp, test, key,
4556 start, end, 1);
4557 }
4558
4559 return result;
4560 }
4561 #undef KEY
4562
2092 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /* 4563 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /*
2093 Reverse SEQUENCE, destructively. 4564 Reverse SEQUENCE, destructively.
2094 4565
2095 Return the beginning of the reversed sequence, which will be a distinct Lisp 4566 Return the beginning of the reversed sequence, which will be a distinct Lisp
2096 object if SEQUENCE is a list with length greater than one. See also 4567 object if SEQUENCE is a list with length greater than one. See also
2710 for (counter = 0; counter < len; ++counter) \ 5181 for (counter = 0; counter < len; ++counter) \
2711 { \ 5182 { \
2712 c_array[counter] = make_int (bit_vector_bit (v, counter)); \ 5183 c_array[counter] = make_int (bit_vector_bit (v, counter)); \
2713 } \ 5184 } \
2714 } while (0) 5185 } while (0)
2715
2716 /* This macro might eventually find a better home than here. */
2717
2718 #define CHECK_KEY_ARGUMENT(key) \
2719 do { \
2720 if (NILP (key)) \
2721 { \
2722 key = Qidentity; \
2723 } \
2724 \
2725 if (!EQ (key, Qidentity)) \
2726 { \
2727 key = indirect_function (key, 1); \
2728 } \
2729 } while (0)
2730 5186
2731 DEFUN ("merge", Fmerge, 4, MANY, 0, /* 5187 DEFUN ("merge", Fmerge, 4, MANY, 0, /*
2732 Destructively merge SEQUENCE-ONE and SEQUENCE-TWO, producing a new sequence. 5188 Destructively merge SEQUENCE-ONE and SEQUENCE-TWO, producing a new sequence.
2733 5189
2734 TYPE is the type of sequence to return. PREDICATE is a `less-than' 5190 TYPE is the type of sequence to return. PREDICATE is a `less-than'
3940 } 6396 }
3941 6397
3942 int 6398 int
3943 internal_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 6399 internal_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
3944 { 6400 {
3945 if (depth > 200) 6401 if (depth + lisp_eval_depth > max_lisp_eval_depth)
3946 stack_overflow ("Stack overflow in equal", Qunbound); 6402 stack_overflow ("Stack overflow in equal", Qunbound);
3947 QUIT; 6403 QUIT;
3948 if (EQ_WITH_EBOLA_NOTICE (obj1, obj2)) 6404 if (EQ_WITH_EBOLA_NOTICE (obj1, obj2))
3949 return 1; 6405 return 1;
3950 /* Note that (equal 20 20.0) should be nil */ 6406 /* Note that (equal 20 20.0) should be nil */
3985 } 6441 }
3986 6442
3987 int 6443 int
3988 internal_equalp (Lisp_Object obj1, Lisp_Object obj2, int depth) 6444 internal_equalp (Lisp_Object obj1, Lisp_Object obj2, int depth)
3989 { 6445 {
3990 if (depth > 200) 6446 if (depth + lisp_eval_depth > max_lisp_eval_depth)
3991 stack_overflow ("Stack overflow in equalp", Qunbound); 6447 stack_overflow ("Stack overflow in equalp", Qunbound);
3992 QUIT; 6448 QUIT;
3993 6449
3994 /* 1. Objects that are `eq' are equal. This will catch the common case 6450 /* 1. Objects that are `eq' are equal. This will catch the common case
3995 of two equal fixnums or the same object seen twice. */ 6451 of two equal fixnums or the same object seen twice. */
4061 but that seems unlikely. */ 6517 but that seems unlikely. */
4062 6518
4063 static int 6519 static int
4064 internal_old_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) 6520 internal_old_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
4065 { 6521 {
4066 if (depth > 200) 6522 if (depth + lisp_eval_depth > max_lisp_eval_depth)
4067 stack_overflow ("Stack overflow in equal", Qunbound); 6523 stack_overflow ("Stack overflow in equal", Qunbound);
4068 QUIT; 6524 QUIT;
4069 if (HACKEQ_UNSAFE (obj1, obj2)) 6525 if (HACKEQ_UNSAFE (obj1, obj2))
4070 return 1; 6526 return 1;
4071 /* Note that (equal 20 20.0) should be nil */ 6527 /* Note that (equal 20 20.0) should be nil */
4227 } 6683 }
4228 else if (LISTP (sequence)) 6684 else if (LISTP (sequence))
4229 { 6685 {
4230 Elemcount counting = 0; 6686 Elemcount counting = 0;
4231 6687
4232 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) 6688 {
4233 { 6689 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
4234 if (counting >= starting) 6690 {
4235 { 6691 if (counting >= starting)
4236 if (counting < ending) 6692 {
4237 { 6693 if (counting < ending)
4238 XSETCAR (tail, item); 6694 {
4239 } 6695 XSETCAR (tail, item);
4240 else if (counting == ending) 6696 }
4241 { 6697 else if (counting == ending)
4242 break; 6698 {
4243 } 6699 break;
4244 } 6700 }
4245 ++counting; 6701 }
4246 } 6702 ++counting;
6703 }
6704 }
4247 6705
4248 if (counting < starting || (counting != ending && !NILP (end))) 6706 if (counting < starting || (counting != ending && !NILP (end)))
4249 { 6707 {
4250 check_sequence_range (args[0], start, end, Flength (args[0])); 6708 check_sequence_range (args[0], start, end, Flength (args[0]));
4251 } 6709 }
6075 { 8533 {
6076 Ibyte *p2 = XSTRING_DATA (sequence2), 8534 Ibyte *p2 = XSTRING_DATA (sequence2),
6077 *p2end = p2 + XSTRING_LENGTH (sequence2), *p2cursor; 8535 *p2end = p2 + XSTRING_LENGTH (sequence2), *p2cursor;
6078 Charcount ii = 0, len1 = string_char_length (sequence1); 8536 Charcount ii = 0, len1 = string_char_length (sequence1);
6079 8537
8538 check_sequence_range (sequence1, start1, end1, make_int (len1));
8539
6080 while (ii < starting2 && p2 < p2end) 8540 while (ii < starting2 && p2 < p2end)
6081 { 8541 {
6082 INC_IBYTEPTR (p2); 8542 INC_IBYTEPTR (p2);
6083 ii++; 8543 ii++;
6084 } 8544 }
6184 } 8644 }
6185 8645
6186 return result; 8646 return result;
6187 } 8647 }
6188 8648
8649 DEFUN ("nsubstitute", Fnsubstitute, 3, MANY, 0, /*
8650 Substitute NEW for OLD in SEQUENCE.
8651
8652 This is a destructive function; it reuses the storage of SEQUENCE whenever
8653 possible. See `remove*' for the meaning of the keywords.
8654
8655 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT)
8656 */
8657 (int nargs, Lisp_Object *args))
8658 {
8659 Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil;
8660 Lisp_Object object_, position0;
8661 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0;
8662 Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0;
8663 Boolint test_not_unboundp = 1;
8664 check_test_func_t check_test = NULL;
8665 struct gcpro gcpro1;
8666
8667 PARSE_KEYWORDS (Fnsubstitute, nargs, args, 9,
8668 (test, if_, if_not, test_not, key, start, end, count,
8669 from_end), (start = Qzero));
8670
8671 CHECK_SEQUENCE (sequence);
8672 CHECK_NATNUM (start);
8673 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
8674
8675 if (!NILP (end))
8676 {
8677 CHECK_NATNUM (end);
8678 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
8679 }
8680
8681 if (!NILP (count))
8682 {
8683 CHECK_INTEGER (count);
8684 if (INTP (count))
8685 {
8686 counting = XINT (count);
8687 }
8688 #ifdef HAVE_BIGNUM
8689 else
8690 {
8691 counting = bignum_sign (XBIGNUM_DATA (count)) > 0 ?
8692 1 + EMACS_INT_MAX : -1 + EMACS_INT_MIN;
8693 }
8694 #endif
8695
8696 if (counting <= 0)
8697 {
8698 return sequence;
8699 }
8700 }
8701
8702 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
8703 key, &test_not_unboundp);
8704
8705 if (CONSP (sequence))
8706 {
8707 Lisp_Object elt;
8708
8709 if (!NILP (count) && !NILP (from_end))
8710 {
8711 Lisp_Object present = count_with_tail (&elt, nargs - 1, args + 1,
8712 Qnsubstitute);
8713
8714 if (ZEROP (present))
8715 {
8716 return sequence;
8717 }
8718
8719 presenting = XINT (present);
8720 presenting = presenting <= counting ? 0 : presenting - counting;
8721 }
8722
8723 GCPRO1 (tail);
8724 {
8725 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len)
8726 {
8727 if (!(ii < ending))
8728 {
8729 break;
8730 }
8731
8732 if (starting <= ii &&
8733 check_test (test, key, item, elt) == test_not_unboundp
8734 && (presenting ? encountered++ >= presenting
8735 : encountered++ < counting))
8736 {
8737 CHECK_LISP_WRITEABLE (tail);
8738 XSETCAR (tail, new_);
8739 }
8740 else if (!presenting && encountered >= counting)
8741 {
8742 break;
8743 }
8744
8745 ii++;
8746 }
8747 }
8748 UNGCPRO;
8749
8750 if ((ii < starting || (ii < ending && !NILP (end)))
8751 && encountered < counting)
8752 {
8753 check_sequence_range (args[0], start, end, Flength (args[0]));
8754 }
8755 }
8756 else if (STRINGP (sequence))
8757 {
8758 Ibyte *staging, new_bytes[MAX_ICHAR_LEN], *staging_cursor;
8759 Ibyte *startp = XSTRING_DATA (sequence), *cursor = startp;
8760 Bytecount cursor_offset = 0, byte_len = XSTRING_LENGTH (sequence);
8761 Bytecount new_len;
8762 Lisp_Object character;
8763
8764 CHECK_CHAR_COERCE_INT (new_);
8765
8766 new_len = set_itext_ichar (new_bytes, XCHAR (new_));
8767
8768 /* Worst case scenario; new char is four octets long, all the old ones
8769 were one octet long, all the old ones match. */
8770 staging = alloca_ibytes (XSTRING_LENGTH (sequence) * new_len);
8771 staging_cursor = staging;
8772
8773 if (!NILP (count) && !NILP (from_end))
8774 {
8775 Lisp_Object present = count_with_tail (&character, nargs - 1,
8776 args + 1, Qnsubstitute);
8777
8778 if (ZEROP (present))
8779 {
8780 return sequence;
8781 }
8782
8783 presenting = XINT (present);
8784
8785 /* If there are fewer items in the string than we have
8786 permission to change, we don't need to differentiate
8787 between the :from-end nil and :from-end t
8788 cases. Otherwise, presenting is the number of matching
8789 items we need to ignore before we start to change. */
8790 presenting = presenting <= counting ? 0 : presenting - counting;
8791 }
8792
8793 ii = 0;
8794 while (cursor_offset < byte_len && ii < ending)
8795 {
8796 if (ii >= starting)
8797 {
8798 character = make_char (itext_ichar (cursor));
8799
8800 if ((check_test (test, key, item, character)
8801 == test_not_unboundp)
8802 && (presenting ? encountered++ >= presenting :
8803 encountered++ < counting))
8804 {
8805 staging_cursor
8806 += itext_copy_ichar (new_bytes, staging_cursor);
8807 }
8808 else
8809 {
8810 staging_cursor
8811 += itext_copy_ichar (cursor, staging_cursor);
8812 }
8813
8814 startp = XSTRING_DATA (sequence);
8815 cursor = startp + cursor_offset;
8816
8817 if (byte_len != XSTRING_LENGTH (sequence)
8818 || !valid_ibyteptr_p (cursor))
8819 {
8820 mapping_interaction_error (Qnsubstitute, sequence);
8821 }
8822 }
8823 else
8824 {
8825 staging_cursor += itext_copy_ichar (cursor, staging_cursor);
8826 }
8827
8828 INC_IBYTEPTR (cursor);
8829 cursor_offset = cursor - startp;
8830 ii++;
8831 }
8832
8833 if (ii < starting || (ii < ending && !NILP (end)))
8834 {
8835 check_sequence_range (sequence, start, end, Flength (sequence));
8836 }
8837
8838 if (0 != encountered)
8839 {
8840 CHECK_LISP_WRITEABLE (sequence);
8841 replace_string_range (sequence, Qzero, make_int (ii),
8842 staging, staging_cursor);
8843 }
8844 }
8845 else
8846 {
8847 Elemcount positioning;
8848 Lisp_Object object = Qnil;
8849
8850 len = XINT (Flength (sequence));
8851 check_sequence_range (sequence, start, end, make_int (len));
8852
8853 position0 = position (&object, item, sequence, check_test,
8854 test_not_unboundp, test, key, start, end, from_end,
8855 Qnil, Qnsubstitute);
8856
8857 if (NILP (position0))
8858 {
8859 return sequence;
8860 }
8861
8862 positioning = XINT (position0);
8863 ending = min (len, ending);
8864
8865 Faset (sequence, position0, new_);
8866 encountered = 1;
8867
8868 if (NILP (from_end))
8869 {
8870 for (ii = positioning + 1; ii < ending; ii++)
8871 {
8872 object_ = Faref (sequence, make_int (ii));
8873
8874 if (check_test (test, key, item, object_) == test_not_unboundp
8875 && encountered++ < counting)
8876 {
8877 Faset (sequence, make_int (ii), new_);
8878 }
8879 else if (encountered == counting)
8880 {
8881 break;
8882 }
8883 }
8884 }
8885 else
8886 {
8887 for (ii = positioning - 1; ii >= starting; ii--)
8888 {
8889 object_ = Faref (sequence, make_int (ii));
8890
8891 if (check_test (test, key, item, object_) == test_not_unboundp
8892 && encountered++ < counting)
8893 {
8894 Faset (sequence, make_int (ii), new_);
8895 }
8896 else if (encountered == counting)
8897 {
8898 break;
8899 }
8900 }
8901 }
8902 }
8903
8904 return sequence;
8905 }
8906
8907 DEFUN ("substitute", Fsubstitute, 3, MANY, 0, /*
8908 Substitute NEW for OLD in SEQUENCE.
8909
8910 This is a non-destructive function; it makes a copy of SEQUENCE if necessary
8911 to avoid corrupting the original SEQUENCE.
8912
8913 See `remove*' for the meaning of the keywords.
8914
8915 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) COUNT)
8916 */
8917 (int nargs, Lisp_Object *args))
8918 {
8919 Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil;
8920 Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil;
8921 Lisp_Object object, position0, matched_count;
8922 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0;
8923 Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0;
8924 Boolint test_not_unboundp = 1;
8925 check_test_func_t check_test = NULL;
8926 struct gcpro gcpro1;
8927
8928 PARSE_KEYWORDS (Fsubstitute, nargs, args, 9,
8929 (test, if_, if_not, test_not, key, start, end, count,
8930 from_end), (start = Qzero, count = Qunbound));
8931
8932 CHECK_SEQUENCE (sequence);
8933
8934 CHECK_NATNUM (start);
8935 starting = BIGNUMP (start) ? 1 + EMACS_INT_MAX : XINT (start);
8936
8937 if (!NILP (end))
8938 {
8939 CHECK_NATNUM (end);
8940 ending = BIGNUMP (end) ? 1 + EMACS_INT_MAX : XINT (end);
8941 }
8942
8943 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
8944 key, &test_not_unboundp);
8945
8946 if (!UNBOUNDP (count))
8947 {
8948 if (!NILP (count))
8949 {
8950 CHECK_INTEGER (count);
8951 if (INTP (count))
8952 {
8953 counting = XINT (count);
8954 }
8955 #ifdef HAVE_BIGNUM
8956 else
8957 {
8958 counting = bignum_sign (XBIGNUM_DATA (count)) > 0 ?
8959 1 + EMACS_INT_MAX : -1 + EMACS_INT_MIN;
8960 }
8961 #endif
8962
8963 if (counting <= 0)
8964 {
8965 return sequence;
8966 }
8967 }
8968 }
8969
8970 if (!CONSP (sequence))
8971 {
8972 position0 = position (&object, item, sequence, check_test,
8973 test_not_unboundp, test, key, start, end, from_end,
8974 Qnil, Qsubstitute);
8975
8976 if (NILP (position0))
8977 {
8978 return sequence;
8979 }
8980 else
8981 {
8982 args[2] = Fcopy_sequence (sequence);
8983 return Fnsubstitute (nargs, args);
8984 }
8985 }
8986
8987 matched_count = count_with_tail (&tail, nargs - 1, args + 1, Qsubstitute);
8988
8989 if (ZEROP (matched_count))
8990 {
8991 return sequence;
8992 }
8993
8994 if (!NILP (count) && !NILP (from_end))
8995 {
8996 presenting = XINT (matched_count);
8997 presenting = presenting <= counting ? 0 : presenting - counting;
8998 }
8999
9000 GCPRO1 (tailing);
9001 {
9002 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len)
9003 {
9004 if (EQ (tail, tailing))
9005 {
9006 if (NILP (result))
9007 {
9008 RETURN_UNGCPRO (XCDR (tail));
9009 }
9010
9011 XSETCDR (result_tail, XCDR (tail));
9012 RETURN_UNGCPRO (result);
9013 }
9014 else if (starting <= ii && ii < ending &&
9015 (check_test (test, key, item, elt) == test_not_unboundp)
9016 && (presenting ? encountered++ >= presenting
9017 : encountered++ < counting))
9018 {
9019 if (NILP (result))
9020 {
9021 result = result_tail = Fcons (new_, Qnil);
9022 }
9023 else
9024 {
9025 XSETCDR (result_tail, Fcons (new_, Qnil));
9026 result_tail = XCDR (result_tail);
9027 }
9028 }
9029 else if (NILP (result))
9030 {
9031 result = result_tail = Fcons (elt, Qnil);
9032 }
9033 else
9034 {
9035 XSETCDR (result_tail, Fcons (elt, Qnil));
9036 result_tail = XCDR (result_tail);
9037 }
9038
9039 if (ii == ending)
9040 {
9041 break;
9042 }
9043
9044 ii++;
9045 }
9046 }
9047 UNGCPRO;
9048
9049 if (ii < starting || (ii < ending && !NILP (end)))
9050 {
9051 check_sequence_range (args[0], start, end, Flength (args[0]));
9052 }
9053
9054 return result;
9055 }
9056
9057 static Lisp_Object
9058 subst (Lisp_Object new_, Lisp_Object old, Lisp_Object tree, int depth)
9059 {
9060 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9061 {
9062 stack_overflow ("Stack overflow in subst", tree);
9063 }
9064
9065 if (EQ (tree, old))
9066 {
9067 return new_;
9068 }
9069 else if (CONSP (tree))
9070 {
9071 Lisp_Object aa = subst (new_, old, XCAR (tree), depth + 1);
9072 Lisp_Object dd = subst (new_, old, XCDR (tree), depth + 1);
9073
9074 if (EQ (aa, XCAR (tree)) && EQ (dd, XCDR (tree)))
9075 {
9076 return tree;
9077 }
9078 else
9079 {
9080 return Fcons (aa, dd);
9081 }
9082 }
9083 else
9084 {
9085 return tree;
9086 }
9087 }
9088
9089 static Lisp_Object
9090 sublis (Lisp_Object alist, Lisp_Object tree,
9091 check_test_func_t check_test, Boolint test_not_unboundp,
9092 Lisp_Object test, Lisp_Object key, int depth)
9093 {
9094 Lisp_Object keyed = KEY (key, tree), tailed = alist, aa, dd;
9095 struct gcpro gcpro1, gcpro2, gcpro3;
9096
9097 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9098 {
9099 stack_overflow ("Stack overflow in sublis", tree);
9100 }
9101
9102 GCPRO3 (tailed, alist, tree);
9103 {
9104 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
9105 {
9106 tailed = tail;
9107
9108 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9109 {
9110 /* Don't use elt_cdr, it is helpful to allow TEST or KEY to
9111 modify the alist while it executes. */
9112 RETURN_UNGCPRO (XCDR (elt));
9113 }
9114 }
9115 }
9116 if (!CONSP (tree))
9117 {
9118 RETURN_UNGCPRO (tree);
9119 }
9120
9121 aa = sublis (alist, XCAR (tree), check_test, test_not_unboundp, test, key,
9122 depth + 1);
9123 dd = sublis (alist, XCDR (tree), check_test, test_not_unboundp, test, key,
9124 depth + 1);
9125
9126 if (EQ (aa, XCAR (tree)) && EQ (dd, XCDR (tree)))
9127 {
9128 RETURN_UNGCPRO (tree);
9129 }
9130
9131 RETURN_UNGCPRO (Fcons (aa, dd));
9132 }
9133
9134 DEFUN ("sublis", Fsublis, 2, MANY, 0, /*
9135 Perform substitutions indicated by ALIST in TREE (non-destructively).
9136 Return a copy of TREE with all matching elements replaced.
9137
9138 See `member*' for the meaning of :test, :test-not and :key.
9139
9140 arguments: (ALIST TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT)
9141 */
9142 (int nargs, Lisp_Object *args))
9143 {
9144 Lisp_Object alist = args[0], tree = args[1];
9145 Boolint test_not_unboundp = 1;
9146 check_test_func_t check_test = NULL;
9147
9148 PARSE_KEYWORDS (Fsublis, nargs, args, 5, (test, if_, test_not, if_not, key),
9149 (key = Qidentity));
9150
9151 if (NILP (key))
9152 {
9153 key = Qidentity;
9154 }
9155
9156 get_check_match_function (&test, test_not, if_, if_not,
9157 /* sublis() is going to apply the key, don't ask
9158 for a match function that will do it for
9159 us. */
9160 Qidentity, &test_not_unboundp, &check_test);
9161
9162 if (CONSP (alist) && NILP (XCDR (alist)) && CONSP (XCAR (alist))
9163 && EQ (key, Qidentity) && 1 == test_not_unboundp
9164 && (check_eq_nokey == check_test ||
9165 (check_eql_nokey == check_test &&
9166 !NON_FIXNUM_NUMBER_P (XCAR (XCAR (alist))))))
9167 {
9168 /* #'subst with #'eq is very cheap indeed; call it. */
9169 return subst (XCDR (XCAR (alist)), XCAR (XCAR (alist)), tree, 0);
9170 }
9171
9172 return sublis (alist, tree, check_test, test_not_unboundp, test, key, 0);
9173 }
9174
9175 static Lisp_Object
9176 nsublis (Lisp_Object alist, Lisp_Object tree,
9177 check_test_func_t check_test,
9178 Boolint test_not_unboundp,
9179 Lisp_Object test, Lisp_Object key, int depth)
9180 {
9181 Lisp_Object tree_saved = tree, tailed = alist, tortoise = tree, keyed = Qnil;
9182 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9183 int count = 0;
9184
9185 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9186 {
9187 stack_overflow ("Stack overflow in nsublis", tree);
9188 }
9189
9190 GCPRO4 (tailed, alist, tree_saved, keyed);
9191
9192 while (CONSP (tree))
9193 {
9194 Boolint replaced = 0;
9195 keyed = KEY (key, XCAR (tree));
9196
9197 {
9198 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
9199 {
9200 tailed = tail;
9201
9202 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9203 {
9204 CHECK_LISP_WRITEABLE (tree);
9205 /* See comment in sublis() on using elt_cdr. */
9206 XSETCAR (tree, XCDR (elt));
9207 replaced = 1;
9208 break;
9209 }
9210 }
9211 }
9212
9213 if (!replaced)
9214 {
9215 if (CONSP (XCAR (tree)))
9216 {
9217 nsublis (alist, XCAR (tree), check_test, test_not_unboundp,
9218 test, key, depth + 1);
9219 }
9220 }
9221
9222 keyed = KEY (key, XCDR (tree));
9223 replaced = 0;
9224
9225 {
9226 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
9227 {
9228 tailed = tail;
9229
9230 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9231 {
9232 CHECK_LISP_WRITEABLE (tree);
9233 /* See comment in sublis() on using elt_cdr. */
9234 XSETCDR (tree, XCDR (elt));
9235 tree = Qnil;
9236 break;
9237 }
9238 }
9239 }
9240
9241 if (!NILP (tree))
9242 {
9243 tree = XCDR (tree);
9244 }
9245
9246 if (++count > CIRCULAR_LIST_SUSPICION_LENGTH)
9247 {
9248 if (count & 1)
9249 {
9250 tortoise = XCDR (tortoise);
9251 }
9252
9253 if (EQ (tortoise, tree))
9254 {
9255 signal_circular_list_error (tree);
9256 }
9257 }
9258 }
9259
9260 RETURN_UNGCPRO (tree_saved);
9261 }
9262
9263 DEFUN ("nsublis", Fnsublis, 2, MANY, 0, /*
9264 Perform substitutions indicated by ALIST in TREE (destructively).
9265 Any matching element of TREE is changed via a call to `setcar'.
9266
9267 See `member*' for the meaning of :test, :test-not and :key.
9268
9269 arguments: (ALIST TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT)
9270 */
9271 (int nargs, Lisp_Object *args))
9272 {
9273 Lisp_Object alist = args[0], tree = args[1], tailed = Qnil, keyed = Qnil;
9274 Boolint test_not_unboundp = 1;
9275 check_test_func_t check_test = NULL;
9276 struct gcpro gcpro1, gcpro2;
9277
9278 PARSE_KEYWORDS (Fnsublis, nargs, args, 5, (test, if_, test_not, if_not, key),
9279 (key = Qidentity));
9280
9281 if (NILP (key))
9282 {
9283 key = Qidentity;
9284 }
9285
9286 get_check_match_function (&test, test_not, if_, if_not,
9287 /* nsublis() is going to apply the key, don't ask
9288 for a match function that will do it for
9289 us. */
9290 Qidentity, &test_not_unboundp, &check_test);
9291
9292 GCPRO2 (tailed, keyed);
9293
9294 keyed = KEY (key, tree);
9295
9296 {
9297 /* nsublis() won't attempt to replace a cons handed to it, do that
9298 ourselves. */
9299 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
9300 {
9301 tailed = tail;
9302
9303 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9304 {
9305 /* See comment in sublis() on using elt_cdr. */
9306 RETURN_UNGCPRO (XCDR (elt));
9307 }
9308 }
9309 }
9310
9311 UNGCPRO;
9312
9313 return nsublis (alist, tree, check_test, test_not_unboundp, test, key, 0);
9314 }
9315
9316 DEFUN ("subst", Fsubst, 3, MANY, 0, /*
9317 Substitute NEW for OLD everywhere in TREE (non-destructively).
9318
9319 Return a copy of TREE with all elements `eql' to OLD replaced by NEW.
9320
9321 See `member*' for the meaning of :test, :test-not and :key.
9322
9323 arguments: (NEW OLD TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT)
9324 */
9325 (int nargs, Lisp_Object *args))
9326 {
9327 Lisp_Object result, alist = noseeum_cons (noseeum_cons (args[1], args[0]),
9328 Qnil);
9329 args[1] = alist;
9330 result = Fsublis (nargs - 1, args + 1);
9331 free_cons (XCAR (alist));
9332 free_cons (alist);
9333
9334 return result;
9335 }
9336
9337 DEFUN ("nsubst", Fnsubst, 3, MANY, 0, /*
9338 Substitute NEW for OLD everywhere in TREE (destructively).
9339
9340 Any element of TREE which is `eql' to OLD is changed to NEW (via a call to
9341 `setcar').
9342
9343 See `member*' for the meaning of the keywords.
9344
9345 arguments: (NEW OLD TREE &key (TEST #'eql) (KEY #'identity) TEST-NOT)
9346 */
9347 (int nargs, Lisp_Object *args))
9348 {
9349 Lisp_Object result, alist = noseeum_cons (noseeum_cons (args[1], args[0]),
9350 Qnil);
9351 args[1] = alist;
9352 result = Fnsublis (nargs - 1, args + 1);
9353 free_cons (XCAR (alist));
9354 free_cons (alist);
9355
9356 return result;
9357 }
9358
9359 static Boolint
9360 tree_equal (Lisp_Object tree1, Lisp_Object tree2,
9361 check_test_func_t check_test, Boolint test_not_unboundp,
9362 Lisp_Object test, Lisp_Object key, int depth)
9363 {
9364 Lisp_Object tortoise1 = tree1, tortoise2 = tree2;
9365 struct gcpro gcpro1, gcpro2;
9366 int count = 0;
9367 Boolint result;
9368
9369 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9370 {
9371 stack_overflow ("Stack overflow in tree-equal", tree1);
9372 }
9373
9374 GCPRO2 (tree1, tree2);
9375
9376 while (CONSP (tree1) && CONSP (tree2)
9377 && tree_equal (XCAR (tree1), XCAR (tree2), check_test,
9378 test_not_unboundp, test, key, depth + 1))
9379 {
9380 tree1 = XCDR (tree1);
9381 tree2 = XCDR (tree2);
9382
9383 if (++count > CIRCULAR_LIST_SUSPICION_LENGTH)
9384 {
9385 if (count & 1)
9386 {
9387 tortoise1 = XCDR (tortoise1);
9388 tortoise2 = XCDR (tortoise2);
9389 }
9390
9391 if (EQ (tortoise1, tree1))
9392 {
9393 signal_circular_list_error (tree1);
9394 }
9395
9396 if (EQ (tortoise2, tree2))
9397 {
9398 signal_circular_list_error (tree2);
9399 }
9400 }
9401 }
9402
9403 if (CONSP (tree1) || CONSP (tree2))
9404 {
9405 UNGCPRO;
9406 return 0;
9407 }
9408
9409 result = check_test (test, key, tree1, tree2) == test_not_unboundp;
9410 UNGCPRO;
9411
9412 return result;
9413 }
9414
9415 DEFUN ("tree-equal", Ftree_equal, 2, MANY, 0, /*
9416 Return t if TREE1 and TREE2 have `eql' leaves.
9417
9418 Atoms are compared by `eql', unless another test is specified using
9419 :test; cons cells are compared recursively.
9420
9421 See `union' for the meaning of :test, :test-not and :key.
9422
9423 arguments: (TREE1 TREE2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
9424 */
9425 (int nargs, Lisp_Object *args))
9426 {
9427 Lisp_Object tree1 = args[0], tree2 = args[1];
9428 Boolint test_not_unboundp = 1;
9429 check_test_func_t check_test = NULL;
9430
9431 PARSE_KEYWORDS (Ftree_equal, nargs, args, 3, (test, key, test_not),
9432 (key = Qidentity));
9433
9434 get_check_match_function (&test, test_not, Qnil, Qnil, key,
9435 &test_not_unboundp, &check_test);
9436
9437 return tree_equal (tree1, tree2, check_test, test_not_unboundp, test, key,
9438 0) ? Qt : Qnil;
9439 }
9440
9441 static Lisp_Object
9442 mismatch_from_end (Lisp_Object sequence1, Lisp_Object start1, Lisp_Object end1,
9443 Lisp_Object sequence2, Lisp_Object start2, Lisp_Object end2,
9444 check_test_func_t check_match, Boolint test_not_unboundp,
9445 Lisp_Object test, Lisp_Object key,
9446 Boolint UNUSED (return_sequence1_index))
9447 {
9448 Elemcount sequence1_len = XINT (Flength (sequence1));
9449 Elemcount sequence2_len = XINT (Flength (sequence2)), ii = 0;
9450 Elemcount starting1, ending1, starting2, ending2;
9451 Lisp_Object *sequence1_storage = NULL, *sequence2_storage = NULL;
9452 struct gcpro gcpro1, gcpro2;
9453
9454 check_sequence_range (sequence1, start1, end1, make_int (sequence1_len));
9455 starting1 = XINT (start1);
9456 ending1 = INTP (end1) ? XINT (end1) : 1 + EMACS_INT_MAX;
9457 ending1 = min (ending1, sequence1_len);
9458
9459 check_sequence_range (sequence2, start2, end2, make_int (sequence2_len));
9460 starting2 = XINT (start2);
9461 ending2 = INTP (end2) ? XINT (end2) : 1 + EMACS_INT_MAX;
9462 ending2 = min (ending2, sequence2_len);
9463
9464 if (LISTP (sequence1))
9465 {
9466 Lisp_Object *saving;
9467 sequence1_storage = saving
9468 = alloca_array (Lisp_Object, ending1 - starting1);
9469
9470 {
9471 EXTERNAL_LIST_LOOP_2 (elt, sequence1)
9472 {
9473 if (starting1 <= ii && ii < ending1)
9474 {
9475 *saving++ = elt;
9476 }
9477 else if (ii == ending1)
9478 {
9479 break;
9480 }
9481
9482 ++ii;
9483 }
9484 }
9485 }
9486 else if (STRINGP (sequence1))
9487 {
9488 const Ibyte *cursor = string_char_addr (sequence1, starting1);
9489
9490 STRING_DATA_TO_OBJECT_ARRAY (cursor, sequence1_storage, ii,
9491 ending1 - starting1);
9492
9493 }
9494 else if (BIT_VECTORP (sequence1))
9495 {
9496 Lisp_Bit_Vector *vv = XBIT_VECTOR (sequence1);
9497 sequence1_storage = alloca_array (Lisp_Object, ending1 - starting1);
9498 for (ii = starting1; ii < ending1; ++ii)
9499 {
9500 sequence1_storage[ii - starting1]
9501 = make_int (bit_vector_bit (vv, ii));
9502 }
9503 }
9504 else
9505 {
9506 sequence1_storage = XVECTOR_DATA (sequence1) + starting1;
9507 }
9508
9509 ii = 0;
9510
9511 if (LISTP (sequence2))
9512 {
9513 Lisp_Object *saving;
9514 sequence2_storage = saving
9515 = alloca_array (Lisp_Object, ending2 - starting2);
9516
9517 {
9518 EXTERNAL_LIST_LOOP_2 (elt, sequence2)
9519 {
9520 if (starting2 <= ii && ii < ending2)
9521 {
9522 *saving++ = elt;
9523 }
9524 else if (ii == ending2)
9525 {
9526 break;
9527 }
9528
9529 ++ii;
9530 }
9531 }
9532 }
9533 else if (STRINGP (sequence2))
9534 {
9535 const Ibyte *cursor = string_char_addr (sequence2, starting2);
9536
9537 STRING_DATA_TO_OBJECT_ARRAY (cursor, sequence2_storage, ii,
9538 ending2 - starting2);
9539
9540 }
9541 else if (BIT_VECTORP (sequence2))
9542 {
9543 Lisp_Bit_Vector *vv = XBIT_VECTOR (sequence2);
9544 sequence2_storage = alloca_array (Lisp_Object, ending2 - starting2);
9545 for (ii = starting2; ii < ending2; ++ii)
9546 {
9547 sequence2_storage[ii - starting2]
9548 = make_int (bit_vector_bit (vv, ii));
9549 }
9550 }
9551 else
9552 {
9553 sequence2_storage = XVECTOR_DATA (sequence2) + starting2;
9554 }
9555
9556 GCPRO2 (sequence1_storage[0], sequence2_storage[0]);
9557 gcpro1.nvars = ending1 - starting1;
9558 gcpro2.nvars = ending2 - starting2;
9559
9560 while (ending1 > starting1 && ending2 > starting2)
9561 {
9562 --ending1;
9563 --ending2;
9564
9565 if (check_match (test, key, sequence1_storage[ending1 - starting1],
9566 sequence2_storage[ending2 - starting2])
9567 != test_not_unboundp)
9568 {
9569 UNGCPRO;
9570 return make_integer (ending1 + 1);
9571 }
9572 }
9573
9574 UNGCPRO;
9575
9576 if (ending1 > starting1 || ending2 > starting2)
9577 {
9578 return make_integer (ending1);
9579 }
9580
9581 return Qnil;
9582 }
9583
9584 static Lisp_Object
9585 mismatch_list_list (Lisp_Object sequence1, Lisp_Object start1, Lisp_Object end1,
9586 Lisp_Object sequence2, Lisp_Object start2, Lisp_Object end2,
9587 check_test_func_t check_match, Boolint test_not_unboundp,
9588 Lisp_Object test, Lisp_Object key,
9589 Boolint UNUSED (return_list_index))
9590 {
9591 Lisp_Object sequence1_tortoise = sequence1, sequence2_tortoise = sequence2;
9592 Lisp_Object orig_sequence1 = sequence1, orig_sequence2 = sequence2;
9593 Elemcount ending1 = EMACS_INT_MAX, ending2 = EMACS_INT_MAX;
9594 Elemcount starting1, starting2, counting, startcounting;
9595 Elemcount shortest_len = 0;
9596 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
9597
9598 starting1 = INTP (start1) ? XINT (start1) : 1 + EMACS_INT_MAX;
9599 starting2 = INTP (start2) ? XINT (start2) : 1 + EMACS_INT_MAX;
9600
9601 if (!NILP (end1))
9602 {
9603 ending1 = INTP (end1) ? XINT (end1) : 1 + EMACS_INT_MAX;
9604 }
9605
9606 if (!NILP (end2))
9607 {
9608 ending2 = INTP (end2) ? XINT (end2) : 1 + EMACS_INT_MAX;
9609 }
9610
9611 if (!ZEROP (start1))
9612 {
9613 sequence1 = Fnthcdr (start1, sequence1);
9614
9615 if (NILP (sequence1))
9616 {
9617 check_sequence_range (sequence1_tortoise, start1, end1,
9618 Flength (sequence1_tortoise));
9619 /* Give up early here. */
9620 return Qnil;
9621 }
9622
9623 ending1 -= starting1;
9624 starting1 = 0;
9625 sequence1_tortoise = sequence1;
9626 }
9627
9628 if (!ZEROP (start2))
9629 {
9630 sequence2 = Fnthcdr (start2, sequence2);
9631
9632 if (NILP (sequence2))
9633 {
9634 check_sequence_range (sequence2_tortoise, start2, end2,
9635 Flength (sequence2_tortoise));
9636 return Qnil;
9637 }
9638
9639 ending2 -= starting2;
9640 starting2 = 0;
9641 sequence2_tortoise = sequence2;
9642 }
9643
9644 GCPRO4 (sequence1, sequence2, sequence1_tortoise, sequence2_tortoise);
9645
9646 counting = startcounting = min (ending1, ending2);
9647
9648 while (counting-- > 0 && !NILP (sequence1) && !NILP (sequence2))
9649 {
9650 if (check_match (test, key,
9651 CONSP (sequence1) ? XCAR (sequence1)
9652 : Fcar (sequence1),
9653 CONSP (sequence2) ? XCAR (sequence2)
9654 : Fcar (sequence2) ) != test_not_unboundp)
9655 {
9656 UNGCPRO;
9657 return make_integer (XINT (start1) + shortest_len);
9658 }
9659
9660 sequence1 = CONSP (sequence1) ? XCDR (sequence1) : Fcdr (sequence1);
9661 sequence2 = CONSP (sequence2) ? XCDR (sequence2) : Fcdr (sequence2);
9662
9663 shortest_len++;
9664
9665 if (startcounting - counting > CIRCULAR_LIST_SUSPICION_LENGTH)
9666 {
9667 if (counting & 1)
9668 {
9669 sequence1_tortoise = XCDR (sequence1_tortoise);
9670 sequence2_tortoise = XCDR (sequence2_tortoise);
9671 }
9672
9673 if (EQ (sequence1, sequence1_tortoise))
9674 {
9675 signal_circular_list_error (sequence1);
9676 }
9677
9678 if (EQ (sequence2, sequence2_tortoise))
9679 {
9680 signal_circular_list_error (sequence2);
9681 }
9682 }
9683 }
9684
9685 UNGCPRO;
9686
9687 if (NILP (sequence1))
9688 {
9689 Lisp_Object args[] = { start1, make_int (shortest_len) };
9690 check_sequence_range (orig_sequence1, start1, end1,
9691 Fplus (countof (args), args));
9692 }
9693
9694 if (NILP (sequence2))
9695 {
9696 Lisp_Object args[] = { start2, make_int (shortest_len) };
9697 check_sequence_range (orig_sequence2, start2, end2,
9698 Fplus (countof (args), args));
9699 }
9700
9701 if ((!NILP (end1) && shortest_len != ending1 - starting1) ||
9702 (!NILP (end2) && shortest_len != ending2 - starting2))
9703 {
9704 return make_integer (XINT (start1) + shortest_len);
9705 }
9706
9707 if ((NILP (end1) && CONSP (sequence1)) || (NILP (end2) && CONSP (sequence2)))
9708 {
9709 return make_integer (XINT (start1) + shortest_len);
9710 }
9711
9712 return Qnil;
9713 }
9714
9715 static Lisp_Object
9716 mismatch_list_string (Lisp_Object list, Lisp_Object list_start,
9717 Lisp_Object list_end,
9718 Lisp_Object string, Lisp_Object string_start,
9719 Lisp_Object string_end,
9720 check_test_func_t check_match,
9721 Boolint test_not_unboundp,
9722 Lisp_Object test, Lisp_Object key,
9723 Boolint return_list_index)
9724 {
9725 Ibyte *string_data = XSTRING_DATA (string), *startp = string_data;
9726 Bytecount string_offset = 0, string_len = XSTRING_LENGTH (string);
9727 Elemcount char_count = 0, list_starting, list_ending;
9728 Elemcount string_starting, string_ending;
9729 Lisp_Object character, orig_list = list;
9730 struct gcpro gcpro1;
9731
9732 list_ending = INTP (list_end) ? XINT (list_end) : 1 + EMACS_INT_MAX;
9733 list_starting = INTP (list_start) ? XINT (list_start) : 1 + EMACS_INT_MAX;
9734
9735 string_ending = INTP (string_end) ? XINT (string_end) : 1 + EMACS_INT_MAX;
9736 string_starting
9737 = INTP (string_start) ? XINT (string_start) : 1 + EMACS_INT_MAX;
9738
9739 while (char_count < string_starting && string_offset < string_len)
9740 {
9741 INC_IBYTEPTR (string_data);
9742 string_offset = string_data - startp;
9743 char_count++;
9744 }
9745
9746 if (!ZEROP (list_start))
9747 {
9748 list = Fnthcdr (list_start, list);
9749 if (NILP (list))
9750 {
9751 check_sequence_range (orig_list, list_start, list_end,
9752 Flength (orig_list));
9753 return Qnil;
9754 }
9755
9756 list_ending -= list_starting;
9757 list_starting = 0;
9758 }
9759
9760 GCPRO1 (list);
9761
9762 while (list_starting < list_ending && string_starting < string_ending
9763 && string_offset < string_len && !NILP (list))
9764 {
9765 character = make_char (itext_ichar (string_data));
9766
9767 if (return_list_index)
9768 {
9769 if (check_match (test, key, CONSP (list) ? XCAR (list) : Fcar (list),
9770 character)
9771 != test_not_unboundp)
9772 {
9773 UNGCPRO;
9774 return make_integer (XINT (list_start) + char_count);
9775 }
9776 }
9777 else
9778 {
9779 if (check_match (test, key, character,
9780 CONSP (list) ? XCAR (list) : Fcar (list))
9781 != test_not_unboundp)
9782 {
9783 UNGCPRO;
9784 return make_integer (char_count);
9785 }
9786 }
9787
9788 list = CONSP (list) ? XCDR (list) : Fcdr (list);
9789
9790 startp = XSTRING_DATA (string);
9791 string_data = startp + string_offset;
9792 if (string_len != XSTRING_LENGTH (string)
9793 || !valid_ibyteptr_p (string_data))
9794 {
9795 mapping_interaction_error (Qmismatch, string);
9796 }
9797
9798 list_starting++;
9799 string_starting++;
9800 char_count++;
9801 INC_IBYTEPTR (string_data);
9802 string_offset = string_data - startp;
9803 }
9804
9805 UNGCPRO;
9806
9807 if (NILP (list))
9808 {
9809 Lisp_Object args[] = { list_start, make_int (char_count) };
9810 check_sequence_range (orig_list, list_start, list_end,
9811 Fplus (countof (args), args));
9812 }
9813
9814 if (string_data == XSTRING_DATA (string) + XSTRING_LENGTH (string))
9815 {
9816 check_sequence_range (string, string_start, string_end,
9817 make_int (char_count));
9818 }
9819
9820 if ((NILP (string_end) ?
9821 string_offset < string_len : string_starting < string_ending) ||
9822 (NILP (list_end) ? !NILP (list) : list_starting < list_ending))
9823 {
9824 return make_integer (return_list_index ? XINT (list_start) + char_count :
9825 char_count);
9826 }
9827
9828 return Qnil;
9829 }
9830
9831 static Lisp_Object
9832 mismatch_list_array (Lisp_Object list, Lisp_Object list_start,
9833 Lisp_Object list_end,
9834 Lisp_Object array, Lisp_Object array_start,
9835 Lisp_Object array_end,
9836 check_test_func_t check_match,
9837 Boolint test_not_unboundp,
9838 Lisp_Object test, Lisp_Object key,
9839 Boolint return_list_index)
9840 {
9841 Elemcount ii = 0, list_starting, list_ending;
9842 Elemcount array_starting, array_ending, array_len;
9843 Lisp_Object orig_list = list;
9844 struct gcpro gcpro1;
9845
9846 list_ending = INTP (list_end) ? XINT (list_end) : 1 + EMACS_INT_MAX;
9847 list_starting = INTP (list_start) ? XINT (list_start) : 1 + EMACS_INT_MAX;
9848
9849 array_ending = INTP (array_end) ? XINT (array_end) : 1 + EMACS_INT_MAX;
9850 array_starting = INTP (array_start) ? XINT (array_start) : 1 + EMACS_INT_MAX;
9851 array_len = XINT (Flength (array));
9852
9853 array_ending = min (array_ending, array_len);
9854
9855 check_sequence_range (array, array_start, array_end, make_int (array_len));
9856
9857 if (!ZEROP (list_start))
9858 {
9859 list = Fnthcdr (list_start, list);
9860 if (NILP (list))
9861 {
9862 check_sequence_range (orig_list, list_start, list_end,
9863 Flength (orig_list));
9864 return Qnil;
9865 }
9866
9867 list_ending -= list_starting;
9868 list_starting = 0;
9869 }
9870
9871 GCPRO1 (list);
9872
9873 while (list_starting < list_ending && array_starting < array_ending
9874 && !NILP (list))
9875 {
9876 if (return_list_index)
9877 {
9878 if (check_match (test, key, CONSP (list) ? XCAR (list) : Fcar (list),
9879 Faref (array, make_int (array_starting)))
9880 != test_not_unboundp)
9881 {
9882 UNGCPRO;
9883 return make_integer (XINT (list_start) + ii);
9884 }
9885 }
9886 else
9887 {
9888 if (check_match (test, key, Faref (array, make_int (array_starting)),
9889 CONSP (list) ? XCAR (list) : Fcar (list))
9890 != test_not_unboundp)
9891 {
9892 UNGCPRO;
9893 return make_integer (array_starting);
9894 }
9895 }
9896
9897 list = CONSP (list) ? XCDR (list) : Fcdr (list);
9898 list_starting++;
9899 array_starting++;
9900 ii++;
9901 }
9902
9903 UNGCPRO;
9904
9905 if (NILP (list))
9906 {
9907 Lisp_Object args[] = { list_start, make_int (ii) };
9908 check_sequence_range (orig_list, list_start, list_end,
9909 Fplus (countof (args), args));
9910 }
9911
9912 if (array_starting < array_ending ||
9913 (NILP (list_end) ? !NILP (list) : list_starting < list_ending))
9914 {
9915 return make_integer (return_list_index ? XINT (list_start) + ii :
9916 array_starting);
9917 }
9918
9919 return Qnil;
9920 }
9921
9922 static Lisp_Object
9923 mismatch_string_array (Lisp_Object string, Lisp_Object string_start,
9924 Lisp_Object string_end,
9925 Lisp_Object array, Lisp_Object array_start,
9926 Lisp_Object array_end,
9927 check_test_func_t check_match, Boolint test_not_unboundp,
9928 Lisp_Object test, Lisp_Object key,
9929 Boolint return_string_index)
9930 {
9931 Ibyte *string_data = XSTRING_DATA (string), *startp = string_data;
9932 Bytecount string_offset = 0, string_len = XSTRING_LENGTH (string);
9933 Elemcount char_count = 0, array_starting, array_ending, array_length;
9934 Elemcount string_starting, string_ending;
9935 Lisp_Object character;
9936
9937 array_starting = INTP (array_start) ? XINT (array_start) : 1 + EMACS_INT_MAX;
9938 array_ending = INTP (array_end) ? XINT (array_end) : 1 + EMACS_INT_MAX;
9939 array_length = XINT (Flength (array));
9940 check_sequence_range (array, array_start, array_end, make_int (array_length));
9941 array_ending = min (array_ending, array_length);
9942
9943 string_ending = INTP (string_end) ? XINT (string_end) : 1 + EMACS_INT_MAX;
9944 string_starting
9945 = INTP (string_start) ? XINT (string_start) : 1 + EMACS_INT_MAX;
9946
9947 while (char_count < string_starting && string_offset < string_len)
9948 {
9949 INC_IBYTEPTR (string_data);
9950 string_offset = string_data - startp;
9951 char_count++;
9952 }
9953
9954 while (array_starting < array_ending && string_starting < string_ending
9955 && string_offset < string_len)
9956 {
9957 character = make_char (itext_ichar (string_data));
9958
9959 if (return_string_index)
9960 {
9961 if (check_match (test, key, character,
9962 Faref (array, make_int (array_starting)))
9963 != test_not_unboundp)
9964 {
9965 return make_integer (char_count);
9966 }
9967 }
9968 else
9969 {
9970 if (check_match (test, key,
9971 Faref (array, make_int (array_starting)),
9972 character)
9973 != test_not_unboundp)
9974 {
9975 return make_integer (XINT (array_start) + char_count);
9976 }
9977 }
9978
9979 startp = XSTRING_DATA (string);
9980 string_data = startp + string_offset;
9981 if (string_len != XSTRING_LENGTH (string)
9982 || !valid_ibyteptr_p (string_data))
9983 {
9984 mapping_interaction_error (Qmismatch, string);
9985 }
9986
9987 array_starting++;
9988 string_starting++;
9989 char_count++;
9990 INC_IBYTEPTR (string_data);
9991 string_offset = string_data - startp;
9992 }
9993
9994 if (string_data == XSTRING_DATA (string) + XSTRING_LENGTH (string))
9995 {
9996 check_sequence_range (string, string_start, string_end,
9997 make_int (char_count));
9998 }
9999
10000 if ((NILP (string_end) ?
10001 string_offset < string_len : string_starting < string_ending) ||
10002 (NILP (array_end) ? !NILP (array) : array_starting < array_ending))
10003 {
10004 return make_integer (return_string_index ? char_count :
10005 XINT (array_start) + char_count);
10006 }
10007
10008 return Qnil;
10009 }
10010
10011 static Lisp_Object
10012 mismatch_string_string (Lisp_Object string1,
10013 Lisp_Object string1_start, Lisp_Object string1_end,
10014 Lisp_Object string2, Lisp_Object string2_start,
10015 Lisp_Object string2_end,
10016 check_test_func_t check_match,
10017 Boolint test_not_unboundp,
10018 Lisp_Object test, Lisp_Object key,
10019 Boolint UNUSED (return_string1_index))
10020 {
10021 Ibyte *string1_data = XSTRING_DATA (string1), *startp1 = string1_data;
10022 Bytecount string1_offset = 0, string1_len = XSTRING_LENGTH (string1);
10023 Ibyte *string2_data = XSTRING_DATA (string2), *startp2 = string2_data;
10024 Bytecount string2_offset = 0, string2_len = XSTRING_LENGTH (string2);
10025 Elemcount char_count1 = 0, string1_starting, string1_ending;
10026 Elemcount char_count2 = 0, string2_starting, string2_ending;
10027 Lisp_Object character1, character2;
10028
10029 string1_ending = INTP (string1_end) ? XINT (string1_end) : 1 + EMACS_INT_MAX;
10030 string1_starting
10031 = INTP (string1_start) ? XINT (string1_start) : 1 + EMACS_INT_MAX;
10032
10033 string2_starting
10034 = INTP (string2_start) ? XINT (string2_start) : 1 + EMACS_INT_MAX;
10035 string2_ending = INTP (string2_end) ? XINT (string2_end) : 1 + EMACS_INT_MAX;
10036
10037 while (char_count1 < string1_starting && string1_offset < string1_len)
10038 {
10039 INC_IBYTEPTR (string1_data);
10040 string1_offset = string1_data - startp1;
10041 char_count1++;
10042 }
10043
10044 while (char_count2 < string2_starting && string2_offset < string2_len)
10045 {
10046 INC_IBYTEPTR (string2_data);
10047 string2_offset = string2_data - startp2;
10048 char_count2++;
10049 }
10050
10051 while (string2_starting < string2_ending && string1_starting < string1_ending
10052 && string1_offset < string1_len && string2_offset < string2_len)
10053 {
10054 character1 = make_char (itext_ichar (string1_data));
10055 character2 = make_char (itext_ichar (string2_data));
10056
10057 if (check_match (test, key, character1, character2)
10058 != test_not_unboundp)
10059 {
10060 return make_integer (char_count1);
10061 }
10062
10063 startp1 = XSTRING_DATA (string1);
10064 string1_data = startp1 + string1_offset;
10065 if (string1_len != XSTRING_LENGTH (string1)
10066 || !valid_ibyteptr_p (string1_data))
10067 {
10068 mapping_interaction_error (Qmismatch, string1);
10069 }
10070
10071 startp2 = XSTRING_DATA (string2);
10072 string2_data = startp2 + string2_offset;
10073 if (string2_len != XSTRING_LENGTH (string2)
10074 || !valid_ibyteptr_p (string2_data))
10075 {
10076 mapping_interaction_error (Qmismatch, string2);
10077 }
10078
10079 string2_starting++;
10080 string1_starting++;
10081 char_count1++;
10082 char_count2++;
10083 INC_IBYTEPTR (string1_data);
10084 string1_offset = string1_data - startp1;
10085 INC_IBYTEPTR (string2_data);
10086 string2_offset = string2_data - startp2;
10087 }
10088
10089 if (string1_data == XSTRING_DATA (string1) + XSTRING_LENGTH (string1))
10090 {
10091 check_sequence_range (string1, string1_start, string1_end,
10092 make_int (char_count1));
10093 }
10094
10095 if (string2_data == XSTRING_DATA (string2) + XSTRING_LENGTH (string2))
10096 {
10097 check_sequence_range (string2, string2_start, string2_end,
10098 make_int (char_count2));
10099 }
10100
10101 if ((!NILP (string1_end) && string1_starting < string1_ending) ||
10102 (!NILP (string2_end) && string2_starting < string2_ending))
10103 {
10104 return make_integer (char_count1);
10105 }
10106
10107 if ((NILP (string1_end) && string1_data
10108 < (XSTRING_DATA (string1) + XSTRING_LENGTH (string1))) ||
10109 (NILP (string2_end) && string2_data
10110 < (XSTRING_DATA (string2) + XSTRING_LENGTH (string2))))
10111 {
10112 return make_integer (char_count1);
10113 }
10114
10115 return Qnil;
10116 }
10117
10118 static Lisp_Object
10119 mismatch_array_array (Lisp_Object array1, Lisp_Object start1, Lisp_Object end1,
10120 Lisp_Object array2, Lisp_Object start2, Lisp_Object end2,
10121 check_test_func_t check_match, Boolint test_not_unboundp,
10122 Lisp_Object test, Lisp_Object key,
10123 Boolint UNUSED (return_array1_index))
10124 {
10125 Elemcount len1 = XINT (Flength (array1)), len2 = XINT (Flength (array2));
10126 Elemcount ending1 = EMACS_INT_MAX, ending2 = EMACS_INT_MAX;
10127 Elemcount starting1, starting2;
10128
10129 check_sequence_range (array1, start1, end1, make_int (len1));
10130 check_sequence_range (array2, start2, end2, make_int (len2));
10131
10132 starting1 = INTP (start1) ? XINT (start1) : 1 + EMACS_INT_MAX;
10133 starting2 = INTP (start2) ? XINT (start2) : 1 + EMACS_INT_MAX;
10134
10135 if (!NILP (end1))
10136 {
10137 ending1 = INTP (end1) ? XINT (end1) : 1 + EMACS_INT_MAX;
10138 }
10139
10140 if (!NILP (end2))
10141 {
10142 ending2 = INTP (end2) ? XINT (end2) : 1 + EMACS_INT_MAX;
10143 }
10144
10145 ending1 = min (ending1, len1);
10146 ending2 = min (ending2, len2);
10147
10148 while (starting1 < ending1 && starting2 < ending2)
10149 {
10150 if (check_match (test, key, Faref (array1, make_int (starting1)),
10151 Faref (array2, make_int (starting2)))
10152 != test_not_unboundp)
10153 {
10154 return make_integer (starting1);
10155 }
10156 starting1++;
10157 starting2++;
10158 }
10159
10160 if (starting1 < ending1 || starting2 < ending2)
10161 {
10162 return make_integer (starting1);
10163 }
10164
10165 return Qnil;
10166 }
10167
10168 typedef Lisp_Object
10169 (*mismatch_func_t) (Lisp_Object sequence1, Lisp_Object start1, Lisp_Object end1,
10170 Lisp_Object sequence2, Lisp_Object start2, Lisp_Object end2,
10171 check_test_func_t check_match, Boolint test_not_unboundp,
10172 Lisp_Object test, Lisp_Object key,
10173 Boolint return_list_index);
10174
10175 static mismatch_func_t
10176 get_mismatch_func (Lisp_Object sequence1, Lisp_Object sequence2,
10177 Lisp_Object from_end, Boolint *return_sequence1_index_out)
10178 {
10179 CHECK_SEQUENCE (sequence1);
10180 CHECK_SEQUENCE (sequence2);
10181
10182 if (!NILP (from_end))
10183 {
10184 *return_sequence1_index_out = 1;
10185 return mismatch_from_end;
10186 }
10187
10188 if (LISTP (sequence1))
10189 {
10190 if (LISTP (sequence2))
10191 {
10192 *return_sequence1_index_out = 1;
10193 return mismatch_list_list;
10194 }
10195
10196 if (STRINGP (sequence2))
10197 {
10198 *return_sequence1_index_out = 1;
10199 return mismatch_list_string;
10200 }
10201
10202 *return_sequence1_index_out = 1;
10203 return mismatch_list_array;
10204 }
10205
10206 if (STRINGP (sequence1))
10207 {
10208 if (STRINGP (sequence2))
10209 {
10210 *return_sequence1_index_out = 1;
10211 return mismatch_string_string;
10212 }
10213
10214 if (LISTP (sequence2))
10215 {
10216 *return_sequence1_index_out = 0;
10217 return mismatch_list_string;
10218 }
10219
10220 *return_sequence1_index_out = 1;
10221 return mismatch_string_array;
10222 }
10223
10224 if (ARRAYP (sequence1))
10225 {
10226 if (STRINGP (sequence2))
10227 {
10228 *return_sequence1_index_out = 0;
10229 return mismatch_string_array;
10230 }
10231
10232 if (LISTP (sequence2))
10233 {
10234 *return_sequence1_index_out = 0;
10235 return mismatch_list_array;
10236 }
10237
10238 *return_sequence1_index_out = 1;
10239 return mismatch_array_array;
10240 }
10241
10242 RETURN_NOT_REACHED (NULL);
10243 return NULL;
10244 }
10245
10246 DEFUN ("mismatch", Fmismatch, 2, MANY, 0, /*
10247 Compare SEQUENCE1 with SEQUENCE2, return index of first mismatching element.
10248
10249 Return nil if the sequences match. If one sequence is a prefix of the
10250 other, the return value indicates the end of the shorter sequence. A
10251 non-nil return value always reflects an index into SEQUENCE1.
10252
10253 See `search' for the meaning of the keywords."
10254
10255 arguments: (SEQUENCE1 SEQUENCE2 &key (TEST #'eql) (KEY #'identity) (START1 0) END1 (START2 0) END2 FROM-END TEST-NOT)
10256 */
10257 (int nargs, Lisp_Object *args))
10258 {
10259 Lisp_Object sequence1 = args[0], sequence2 = args[1];
10260 Boolint test_not_unboundp = 1, return_first_index = 0;
10261 check_test_func_t check_match = NULL;
10262 mismatch_func_t mismatch = NULL;
10263
10264 PARSE_KEYWORDS (Fmismatch, nargs, args, 8,
10265 (test, key, from_end, start1, end1, start2, end2, test_not),
10266 (start1 = start2 = Qzero));
10267
10268 CHECK_SEQUENCE (sequence1);
10269 CHECK_SEQUENCE (sequence2);
10270
10271 CHECK_NATNUM (start1);
10272 CHECK_NATNUM (start2);
10273
10274 if (!NILP (end1))
10275 {
10276 CHECK_NATNUM (end1);
10277 }
10278
10279 if (!NILP (end2))
10280 {
10281 CHECK_NATNUM (end2);
10282 }
10283
10284 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10285 &test_not_unboundp, NULL);
10286 mismatch = get_mismatch_func (sequence1, sequence2, from_end,
10287 &return_first_index);
10288
10289 if (return_first_index)
10290 {
10291 return mismatch (sequence1, start1, end1, sequence2, start2, end2,
10292 check_match, test_not_unboundp, test, key, 1);
10293 }
10294
10295 return mismatch (sequence2, start2, end2, sequence1, start1, end1,
10296 check_match, test_not_unboundp, test, key, 0);
10297 }
10298
10299 DEFUN ("search", Fsearch, 2, MANY, 0, /*
10300 Search for SEQUENCE1 as a subsequence of SEQUENCE2.
10301
10302 Return the index of the leftmost element of the first match found; return
10303 nil if there are no matches.
10304
10305 In this function, :start1 and :end1 specify a subsequence of SEQUENCE1, and
10306 :start2 and :end2 specify a subsequence of SEQUENCE2. See `remove*' for
10307 details of the other keywords.
10308
10309 arguments: (SEQUENCE1 SEQUENCE2 &key (TEST #'eql) (KEY #'identity) (START1 0) END1 (START2 0) END2 FROM-END TEST-NOT)
10310 */
10311 (int nargs, Lisp_Object *args))
10312 {
10313 Lisp_Object sequence1 = args[0], sequence2 = args[1], position0 = Qnil;
10314 Boolint test_not_unboundp = 1, return_first = 0;
10315 check_test_func_t check_test = NULL, check_match = NULL;
10316 mismatch_func_t mismatch = NULL;
10317 Elemcount starting1 = 0, ending1 = 1 + EMACS_INT_MAX, starting2 = 0;
10318 Elemcount ending2 = 1 + EMACS_INT_MAX, ii = 0;
10319 Elemcount length1;
10320 Lisp_Object object = Qnil;
10321 struct gcpro gcpro1, gcpro2;
10322
10323 PARSE_KEYWORDS (Fsearch, nargs, args, 8,
10324 (test, key, from_end, start1, end1, start2, end2, test_not),
10325 (start1 = start2 = Qzero));
10326
10327 CHECK_SEQUENCE (sequence1);
10328 CHECK_SEQUENCE (sequence2);
10329 CHECK_KEY_ARGUMENT (key);
10330
10331 CHECK_NATNUM (start1);
10332 starting1 = INTP (start1) ? XINT (start1) : 1 + EMACS_INT_MAX;
10333 CHECK_NATNUM (start2);
10334 starting2 = INTP (start2) ? XINT (start2) : 1 + EMACS_INT_MAX;
10335
10336 if (!NILP (end1))
10337 {
10338 Lisp_Object len1 = Flength (sequence1);
10339
10340 CHECK_NATNUM (end1);
10341 check_sequence_range (sequence1, start1, end1, len1);
10342 ending1 = min (XINT (end1), XINT (len1));
10343 }
10344 else
10345 {
10346 end1 = Flength (sequence1);
10347 check_sequence_range (sequence1, start1, end1, end1);
10348 ending1 = XINT (end1);
10349 }
10350
10351 length1 = ending1 - starting1;
10352
10353 if (!NILP (end2))
10354 {
10355 Lisp_Object len2 = Flength (sequence2);
10356
10357 CHECK_NATNUM (end2);
10358 check_sequence_range (sequence2, start2, end2, len2);
10359 ending2 = min (XINT (end2), XINT (len2));
10360 }
10361 else
10362 {
10363 end2 = Flength (sequence2);
10364 check_sequence_range (sequence2, start2, end2, end2);
10365 ending2 = XINT (end2);
10366 }
10367
10368 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10369 &test_not_unboundp, &check_test);
10370 mismatch = get_mismatch_func (sequence1, sequence2, from_end, &return_first);
10371
10372 if (bytecode_arithcompare (start1, make_integer (ending1)) >= 0)
10373 {
10374 if (NILP (from_end))
10375 {
10376 return start2;
10377 }
10378
10379 if (NILP (end2))
10380 {
10381 return Flength (sequence2);
10382 }
10383
10384 return end2;
10385 }
10386
10387 if (NILP (from_end))
10388 {
10389 Lisp_Object mismatch_start1 = Fadd1 (start1);
10390 Lisp_Object first = KEY (key, Felt (sequence1, start1));
10391 GCPRO2 (first, mismatch_start1);
10392
10393 ii = starting2;
10394 while (ii < ending2)
10395 {
10396 position0 = position (&object, first, sequence2, check_test,
10397 test_not_unboundp, test, key, make_int (ii),
10398 end2, Qnil, Qnil, Qsearch);
10399 if (NILP (position0))
10400 {
10401 UNGCPRO;
10402 return Qnil;
10403 }
10404
10405 if (length1 + XINT (position0) <= ending2 &&
10406 (return_first ?
10407 NILP (mismatch (sequence1, mismatch_start1, end1,
10408 sequence2,
10409 make_int (1 + XINT (position0)),
10410 make_int (length1 + XINT (position0)),
10411 check_match, test_not_unboundp, test, key, 1)) :
10412 NILP (mismatch (sequence2,
10413 make_int (1 + XINT (position0)),
10414 make_int (length1 + XINT (position0)),
10415 sequence1, mismatch_start1, end1,
10416 check_match, test_not_unboundp, test, key, 0))))
10417
10418
10419 {
10420 UNGCPRO;
10421 return position0;
10422 }
10423
10424 ii = XINT (position0) + 1;
10425 }
10426
10427 UNGCPRO;
10428 }
10429 else
10430 {
10431 Lisp_Object mismatch_end1 = make_integer (ending1 - 1);
10432 Lisp_Object last = KEY (key, Felt (sequence1, mismatch_end1));
10433 GCPRO2 (last, mismatch_end1);
10434
10435 ii = ending2;
10436 while (ii > starting2)
10437 {
10438 position0 = position (&object, last, sequence2, check_test,
10439 test_not_unboundp, test, key, start2,
10440 make_int (ii), Qt, Qnil, Qsearch);
10441
10442 if (NILP (position0))
10443 {
10444 UNGCPRO;
10445 return Qnil;
10446 }
10447
10448 if (XINT (position0) - length1 + 1 >= starting2 &&
10449 (return_first ?
10450 NILP (mismatch (sequence1, start1, mismatch_end1,
10451 sequence2,
10452 make_int (XINT (position0) - length1 + 1),
10453 make_int (XINT (position0)),
10454 check_match, test_not_unboundp, test, key, 1)) :
10455 NILP (mismatch (sequence2,
10456 make_int (XINT (position0) - length1 + 1),
10457 make_int (XINT (position0)),
10458 sequence1, start1, mismatch_end1,
10459 check_match, test_not_unboundp, test, key, 0))))
10460 {
10461 UNGCPRO;
10462 return make_int (XINT (position0) - length1 + 1);
10463 }
10464
10465 ii = XINT (position0);
10466 }
10467
10468 UNGCPRO;
10469 }
10470
10471 return Qnil;
10472 }
10473
10474 /* These two functions do set operations, those that can be visualised with
10475 Venn diagrams. */
10476 static Lisp_Object
10477 venn (Lisp_Object caller, int nargs, Lisp_Object *args, Boolint intersectionp)
10478 {
10479 Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil;
10480 Lisp_Object result = EQ (caller, Qsubsetp) ? Qt : Qnil, result_tail = Qnil;
10481 Lisp_Object keyed = Qnil, ignore = Qnil;
10482 Elemcount len;
10483 Boolint test_not_unboundp = 1;
10484 check_test_func_t check_test = NULL;
10485 struct gcpro gcpro1, gcpro2, gcpro3;
10486
10487 PARSE_KEYWORDS_8 (caller, nargs, args, 4, (test, key, test_not, stable),
10488 NULL, 2, 0);
10489
10490 CHECK_LIST (liszt1);
10491 CHECK_LIST (liszt2);
10492
10493 CHECK_KEY_ARGUMENT (key);
10494
10495 if (NILP (liszt1) && intersectionp)
10496 {
10497 return Qnil;
10498 }
10499
10500 if (NILP (liszt2))
10501 {
10502 return intersectionp ? Qnil : liszt1;
10503 }
10504
10505 get_check_match_function (&test, test_not, Qnil, Qnil, key,
10506 &test_not_unboundp, &check_test);
10507
10508 GCPRO3 (tail, keyed, result);
10509
10510 {
10511 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len)
10512 {
10513 keyed = KEY (key, elt);
10514 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10515 check_test, test_not_unboundp,
10516 test, key, 0, Qzero, Qnil))
10517 != intersectionp)
10518 {
10519 if (EQ (Qsubsetp, caller))
10520 {
10521 result = Qnil;
10522 break;
10523 }
10524 else if (NILP (stable))
10525 {
10526 result = Fcons (elt, result);
10527 }
10528 else if (NILP (result))
10529 {
10530 result = result_tail = Fcons (elt, Qnil);
10531 }
10532 else
10533 {
10534 XSETCDR (result_tail, Fcons (elt, Qnil));
10535 result_tail = XCDR (result_tail);
10536 }
10537 }
10538 }
10539 }
10540
10541 UNGCPRO;
10542
10543 return result;
10544 }
10545
10546 static Lisp_Object
10547 nvenn (Lisp_Object caller, int nargs, Lisp_Object *args, Boolint intersectionp)
10548 {
10549 Lisp_Object liszt1 = args[0], liszt2 = args[1], tortoise_elt, ignore = Qnil;
10550 Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, prev_tail = Qnil;
10551 Elemcount count;
10552 Boolint test_not_unboundp = 1;
10553 check_test_func_t check_test = NULL;
10554 struct gcpro gcpro1, gcpro2, gcpro3;
10555
10556 PARSE_KEYWORDS_8 (caller, nargs, args, 3, (test, key, test_not),
10557 NULL, 2, 0);
10558
10559 CHECK_LIST (liszt1);
10560 CHECK_LIST (liszt2);
10561
10562 CHECK_KEY_ARGUMENT (key);
10563
10564 if (NILP (liszt1) && intersectionp)
10565 {
10566 return Qnil;
10567 }
10568
10569 if (NILP (liszt2))
10570 {
10571 return intersectionp ? Qnil : liszt1;
10572 }
10573
10574 get_check_match_function (&test, test_not, Qnil, Qnil, key,
10575 &test_not_unboundp, &check_test);
10576
10577 GCPRO3 (tail, keyed, liszt1);
10578
10579 tortoise_elt = tail = liszt1, count = 0;
10580
10581 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 :
10582 (signal_malformed_list_error (liszt1), 0))
10583 {
10584 keyed = KEY (key, elt);
10585 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10586 check_test, test_not_unboundp,
10587 test, key, 0, Qzero, Qnil))
10588 == intersectionp)
10589 {
10590 if (NILP (prev_tail))
10591 {
10592 liszt1 = XCDR (tail);
10593 }
10594 else
10595 {
10596 XSETCDR (prev_tail, XCDR (tail));
10597 }
10598
10599 tail = XCDR (tail);
10600 /* List is definitely not circular now! */
10601 count = 0;
10602 }
10603 else
10604 {
10605 prev_tail = tail;
10606 tail = XCDR (tail);
10607 }
10608
10609 if (count++ < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
10610
10611 if (count & 1)
10612 {
10613 tortoise_elt = XCDR (tortoise_elt);
10614 }
10615
10616 if (EQ (elt, tortoise_elt))
10617 {
10618 signal_circular_list_error (liszt1);
10619 }
10620 }
10621
10622 UNGCPRO;
10623
10624 return liszt1;
10625 }
10626
10627 DEFUN ("intersection", Fintersection, 2, MANY, 0, /*
10628 Combine LIST1 and LIST2 using a set-intersection operation.
10629
10630 The result list contains all items that appear in both LIST1 and LIST2.
10631 This is a non-destructive function; it makes a copy of the data if necessary
10632 to avoid corrupting the original LIST1 and LIST2.
10633
10634 A non-nil value for the :stable keyword, not specified by Common Lisp, means
10635 return the items in the order they appear in LIST1.
10636
10637 See `union' for the meaning of :test, :test-not and :key."
10638
10639 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE)
10640 */
10641 (int nargs, Lisp_Object *args))
10642 {
10643 return venn (Qintersection, nargs, args, 1);
10644 }
10645
10646 DEFUN ("nintersection", Fnintersection, 2, MANY, 0, /*
10647 Combine LIST1 and LIST2 using a set-intersection operation.
10648
10649 The result list contains all items that appear in both LIST1 and LIST2.
10650 This is a destructive function; it reuses the storage of LIST1 whenever
10651 possible.
10652
10653 See `union' for the meaning of :test, :test-not and :key."
10654
10655 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10656 */
10657 (int nargs, Lisp_Object *args))
10658 {
10659 return nvenn (Qnintersection, nargs, args, 1);
10660 }
10661
10662 DEFUN ("subsetp", Fsubsetp, 2, MANY, 0, /*
10663 Return non-nil if every element of LIST1 also appears in LIST2.
10664
10665 See `union' for the meaning of the keyword arguments.
10666
10667 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10668 */
10669 (int nargs, Lisp_Object *args))
10670 {
10671 return venn (Qsubsetp, nargs, args, 0);
10672 }
10673
10674 DEFUN ("set-difference", Fset_difference, 2, MANY, 0, /*
10675 Combine LIST1 and LIST2 using a set-difference operation.
10676
10677 The result list contains all items that appear in LIST1 but not LIST2. This
10678 is a non-destructive function; it makes a copy of the data if necessary to
10679 avoid corrupting the original LIST1 and LIST2.
10680
10681 See `union' for the meaning of :test, :test-not and :key.
10682
10683 A non-nil value for the :stable keyword, not specified by Common Lisp, means
10684 return the items in the order they appear in LIST1.
10685
10686 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE)
10687 */
10688 (int nargs, Lisp_Object *args))
10689 {
10690 return venn (Qset_difference, nargs, args, 0);
10691 }
10692
10693 DEFUN ("nset-difference", Fnset_difference, 2, MANY, 0, /*
10694 Combine LIST1 and LIST2 using a set-difference operation.
10695
10696 The result list contains all items that appear in LIST1 but not LIST2. This
10697 is a destructive function; it reuses the storage of LIST1 whenever possible.
10698
10699 See `union' for the meaning of :test, :test-not and :key."
10700
10701 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10702 */
10703 (int nargs, Lisp_Object *args))
10704 {
10705 return nvenn (Qnset_difference, nargs, args, 0);
10706 }
10707
10708 DEFUN ("nunion", Fnunion, 2, MANY, 0, /*
10709 Combine LIST1 and LIST2 using a set-union operation.
10710 The result list contains all items that appear in either LIST1 or LIST2.
10711
10712 This is a destructive function, it reuses the storage of LIST1 whenever
10713 possible.
10714
10715 See `union' for the meaning of :test, :test-not and :key.
10716
10717 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10718 */
10719 (int nargs, Lisp_Object *args))
10720 {
10721 args[0] = nvenn (Qnunion, nargs, args, 0);
10722 return bytecode_nconc2 (args);
10723 }
10724
10725 DEFUN ("union", Funion, 2, MANY, 0, /*
10726 Combine LIST1 and LIST2 using a set-union operation.
10727 The result list contains all items that appear in either LIST1 or LIST2.
10728 This is a non-destructive function; it makes a copy of the data if necessary
10729 to avoid corrupting the original LIST1 and LIST2.
10730
10731 The keywords :test and :test-not specify two-argument test and negated-test
10732 predicates, respectively; :test defaults to `eql'. See `member*' for more
10733 information.
10734
10735 :key specifies a one-argument function that transforms elements of LIST1
10736 and LIST2 into \"comparison keys\" before the test predicate is applied.
10737 For example, if :key is #'car, then the car of elements from LIST1 is
10738 compared with the car of elements from LIST2. The :key function, however,
10739 does not affect the elements in the returned list, which are taken directly
10740 from the elements in LIST1 and LIST2.
10741
10742 A non-nil value for the :stable keyword, not specified by Common Lisp, means
10743 return the items of LIST1 in order, followed by the remaining items of LIST2
10744 in the order they occur in LIST2.
10745
10746 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE)
10747 */
10748 (int nargs, Lisp_Object *args))
10749 {
10750 Lisp_Object liszt1 = args[0], liszt2 = args[1], ignore = Qnil;
10751 Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, result, result_tail;
10752 Elemcount len;
10753 Boolint test_not_unboundp = 1;
10754 check_test_func_t check_test = NULL, check_match = NULL;
10755 struct gcpro gcpro1, gcpro2, gcpro3;
10756
10757 PARSE_KEYWORDS (Funion, nargs, args, 4, (test, key, test_not, stable), NULL);
10758
10759 CHECK_LIST (liszt1);
10760 CHECK_LIST (liszt2);
10761
10762 CHECK_KEY_ARGUMENT (key);
10763
10764 if (NILP (liszt1))
10765 {
10766 return liszt2;
10767 }
10768
10769 if (NILP (liszt2))
10770 {
10771 return liszt1;
10772 }
10773
10774 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10775 &test_not_unboundp, &check_test);
10776
10777 GCPRO3 (tail, keyed, result);
10778
10779 if (NILP (stable))
10780 {
10781 result = liszt2;
10782 {
10783 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len)
10784 {
10785 keyed = KEY (key, elt);
10786 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10787 check_test, test_not_unboundp,
10788 test, key, 0, Qzero, Qnil)))
10789 {
10790 /* The Lisp version of #'union used to check which list was
10791 longer, and use that as the tail of the constructed
10792 list. That fails when the order of arguments to TEST is
10793 specified, as is the case for these functions. We could
10794 pass the reverse_check argument to
10795 list_position_cons_before, but that means any key argument
10796 is called an awful lot more, so it's a space win but not
10797 a time win. */
10798 result = Fcons (elt, result);
10799 }
10800 }
10801 }
10802 }
10803 else
10804 {
10805 result = result_tail = Qnil;
10806
10807 /* The standard `union' doesn't produce a "stable" union -- it
10808 iterates over the second list instead of the first one, and returns
10809 the values in backwards order. According to the CLTL2
10810 documentation, `union' is not required to preserve the ordering of
10811 elements in any fashion; providing the functionality for a stable
10812 union is an XEmacs extension. */
10813 {
10814 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len)
10815 {
10816 if (NILP (list_position_cons_before (&ignore, elt, liszt1,
10817 check_match, test_not_unboundp,
10818 test, key, 1, Qzero, Qnil)))
10819 {
10820 if (NILP (result))
10821 {
10822 result = result_tail = Fcons (elt, Qnil);
10823 }
10824 else
10825 {
10826 XSETCDR (result_tail, Fcons (elt, Qnil));
10827 result_tail = XCDR (result_tail);
10828 }
10829 }
10830 }
10831 }
10832
10833 result = NILP (result) ? liszt1 : nconc2 (Fcopy_list (liszt1), result);
10834 }
10835
10836 UNGCPRO;
10837
10838 return result;
10839 }
10840
10841 DEFUN ("set-exclusive-or", Fset_exclusive_or, 2, MANY, 0, /*
10842 Combine LIST1 and LIST2 using a set-exclusive-or operation.
10843
10844 The result list contains all items that appear in exactly one of LIST1, LIST2.
10845 This is a non-destructive function; it makes a copy of the data if necessary
10846 to avoid corrupting the original LIST1 and LIST2.
10847
10848 See `union' for the meaning of :test, :test-not and :key.
10849
10850 A non-nil value for the :stable keyword, not specified by Common Lisp, means
10851 return the items in the order they appear in LIST1, followed by the
10852 remaining items in the order they appear in LIST2.
10853
10854 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10855 */
10856 (int nargs, Lisp_Object *args))
10857 {
10858 Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil;
10859 Lisp_Object result = Qnil, result_tail = Qnil, keyed = Qnil, ignore = Qnil;
10860 Elemcount len;
10861 Boolint test_not_unboundp = 1;
10862 check_test_func_t check_match = NULL, check_test = NULL;
10863 struct gcpro gcpro1, gcpro2, gcpro3;
10864
10865 PARSE_KEYWORDS (Fset_exclusive_or, nargs, args, 4,
10866 (test, key, test_not, stable), NULL);
10867
10868 CHECK_LIST (liszt1);
10869 CHECK_LIST (liszt2);
10870
10871 CHECK_KEY_ARGUMENT (key);
10872
10873 if (NILP (liszt2))
10874 {
10875 return liszt1;
10876 }
10877
10878 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10879 &test_not_unboundp, &check_test);
10880
10881 GCPRO3 (tail, keyed, result);
10882 {
10883 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len)
10884 {
10885 keyed = KEY (key, elt);
10886 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10887 check_test, test_not_unboundp,
10888 test, key, 0, Qzero, Qnil)))
10889 {
10890 if (NILP (stable))
10891 {
10892 result = Fcons (elt, result);
10893 }
10894 else if (NILP (result))
10895 {
10896 result = result_tail = Fcons (elt, Qnil);
10897 }
10898 else
10899 {
10900 XSETCDR (result_tail, Fcons (elt, Qnil));
10901 result_tail = XCDR (result_tail);
10902 }
10903 }
10904 }
10905 }
10906
10907 {
10908 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len)
10909 {
10910 if (NILP (list_position_cons_before (&ignore, elt, liszt1,
10911 check_match, test_not_unboundp,
10912 test, key, 1, Qzero, Qnil)))
10913 {
10914 if (NILP (stable))
10915 {
10916 result = Fcons (elt, result);
10917 }
10918 else if (NILP (result))
10919 {
10920 result = result_tail = Fcons (elt, Qnil);
10921 }
10922 else
10923 {
10924 XSETCDR (result_tail, Fcons (elt, Qnil));
10925 result_tail = XCDR (result_tail);
10926 }
10927 }
10928 }
10929 }
10930 UNGCPRO;
10931
10932 return result;
10933 }
10934
10935 DEFUN ("nset-exclusive-or", Fnset_exclusive_or, 2, MANY, 0, /*
10936 Combine LIST1 and LIST2 using a set-exclusive-or operation.
10937
10938 The result list contains all items that appear in exactly one of LIST1 and
10939 LIST2. This is a destructive function; it reuses the storage of LIST1 and
10940 LIST2 whenever possible.
10941
10942 See `union' for the meaning of :test, :test-not and :key.
10943
10944 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT)
10945 */
10946 (int nargs, Lisp_Object *args))
10947 {
10948 Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil;
10949 Lisp_Object result = Qnil, tortoise_elt = Qnil, keyed = Qnil, swap;
10950 Lisp_Object prev_tail = Qnil, ignore = Qnil;
10951 Elemcount count;
10952 Boolint test_not_unboundp = 1;
10953 check_test_func_t check_match = NULL, check_test = NULL;
10954 struct gcpro gcpro1, gcpro2, gcpro3;
10955
10956 PARSE_KEYWORDS (Fnset_exclusive_or, nargs, args, 4,
10957 (test, key, test_not, stable), NULL);
10958
10959 CHECK_LIST (liszt1);
10960 CHECK_LIST (liszt2);
10961
10962 CHECK_KEY_ARGUMENT (key);
10963
10964 if (NILP (liszt2))
10965 {
10966 return liszt1;
10967 }
10968
10969 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10970 &test_not_unboundp, &check_test);
10971
10972 GCPRO3 (tail, keyed, result);
10973
10974 tortoise_elt = tail = liszt1, count = 0;
10975
10976 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 :
10977 (signal_malformed_list_error (liszt1), 0))
10978 {
10979 keyed = KEY (key, elt);
10980 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10981 check_test, test_not_unboundp,
10982 test, key, 0, Qzero, Qnil)))
10983 {
10984 swap = XCDR (tail);
10985
10986 if (NILP (prev_tail))
10987 {
10988 liszt1 = XCDR (tail);
10989 }
10990 else
10991 {
10992 XSETCDR (prev_tail, swap);
10993 }
10994
10995 XSETCDR (tail, result);
10996 result = tail;
10997 tail = swap;
10998
10999 /* List is definitely not circular now! */
11000 count = 0;
11001 }
11002 else
11003 {
11004 prev_tail = tail;
11005 tail = XCDR (tail);
11006 }
11007
11008 if (count++ < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
11009
11010 if (count & 1)
11011 {
11012 tortoise_elt = XCDR (tortoise_elt);
11013 }
11014
11015 if (EQ (elt, tortoise_elt))
11016 {
11017 signal_circular_list_error (liszt1);
11018 }
11019 }
11020
11021 tortoise_elt = tail = liszt2, count = 0;
11022
11023 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 :
11024 (signal_malformed_list_error (liszt2), 0))
11025 {
11026 /* Need to leave the key calculation to list_position_cons_before(). */
11027 if (NILP (list_position_cons_before (&ignore, elt, liszt1,
11028 check_match, test_not_unboundp,
11029 test, key, 1, Qzero, Qnil)))
11030 {
11031 swap = XCDR (tail);
11032 XSETCDR (tail, result);
11033 result = tail;
11034 tail = swap;
11035 count = 0;
11036 }
11037 else
11038 {
11039 tail = XCDR (tail);
11040 }
11041
11042 if (count++ < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
11043
11044 if (count & 1)
11045 {
11046 tortoise_elt = XCDR (tortoise_elt);
11047 }
11048
11049 if (EQ (elt, tortoise_elt))
11050 {
11051 signal_circular_list_error (liszt1);
11052 }
11053 }
11054
11055 UNGCPRO;
11056
11057 return result;
11058 }
11059
11060
6189 Lisp_Object 11061 Lisp_Object
6190 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string) 11062 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string)
6191 { 11063 {
6192 return Fintern (concat2 (Fsymbol_name (symbol), 11064 return Fintern (concat2 (Fsymbol_name (symbol),
6193 build_ascstring (ascii_string)), 11065 build_ascstring (ascii_string)),
6199 { 11071 {
6200 return Fintern (concat2 (build_ascstring (ascii_string), 11072 return Fintern (concat2 (build_ascstring (ascii_string),
6201 Fsymbol_name (symbol)), 11073 Fsymbol_name (symbol)),
6202 Qnil); 11074 Qnil);
6203 } 11075 }
6204
6205 11076
6206 /* #### this function doesn't belong in this file! */ 11077 /* #### this function doesn't belong in this file! */
6207 11078
6208 #ifdef HAVE_GETLOADAVG 11079 #ifdef HAVE_GETLOADAVG
6209 #ifdef HAVE_SYS_LOADAVG_H 11080 #ifdef HAVE_SYS_LOADAVG_H
6817 syms_of_fns (void) 11688 syms_of_fns (void)
6818 { 11689 {
6819 INIT_LISP_OBJECT (bit_vector); 11690 INIT_LISP_OBJECT (bit_vector);
6820 11691
6821 DEFSYMBOL (Qstring_lessp); 11692 DEFSYMBOL (Qstring_lessp);
6822 DEFSYMBOL (Qsort);
6823 DEFSYMBOL (Qmerge); 11693 DEFSYMBOL (Qmerge);
6824 DEFSYMBOL (Qfill); 11694 DEFSYMBOL (Qfill);
6825 DEFSYMBOL (Qidentity); 11695 DEFSYMBOL (Qidentity);
6826 DEFSYMBOL (Qvector); 11696 DEFSYMBOL (Qvector);
6827 DEFSYMBOL (Qarray); 11697 DEFSYMBOL (Qarray);
6829 DEFSYMBOL (Qlist); 11699 DEFSYMBOL (Qlist);
6830 DEFSYMBOL (Qbit_vector); 11700 DEFSYMBOL (Qbit_vector);
6831 defsymbol (&QsortX, "sort*"); 11701 defsymbol (&QsortX, "sort*");
6832 DEFSYMBOL (Qreduce); 11702 DEFSYMBOL (Qreduce);
6833 DEFSYMBOL (Qreplace); 11703 DEFSYMBOL (Qreplace);
11704 DEFSYMBOL (Qposition);
11705 DEFSYMBOL (Qfind);
11706 defsymbol (&QdeleteX, "delete*");
11707 defsymbol (&QremoveX, "remove*");
6834 11708
6835 DEFSYMBOL (Qmapconcat); 11709 DEFSYMBOL (Qmapconcat);
6836 defsymbol (&QmapcarX, "mapcar*"); 11710 defsymbol (&QmapcarX, "mapcar*");
6837 DEFSYMBOL (Qmapvector); 11711 DEFSYMBOL (Qmapvector);
6838 DEFSYMBOL (Qmapcan); 11712 DEFSYMBOL (Qmapcan);
6842 DEFSYMBOL (Qsome); 11716 DEFSYMBOL (Qsome);
6843 DEFSYMBOL (Qevery); 11717 DEFSYMBOL (Qevery);
6844 DEFSYMBOL (Qmaplist); 11718 DEFSYMBOL (Qmaplist);
6845 DEFSYMBOL (Qmapl); 11719 DEFSYMBOL (Qmapl);
6846 DEFSYMBOL (Qmapcon); 11720 DEFSYMBOL (Qmapcon);
11721 DEFSYMBOL (Qnsubstitute);
11722 DEFSYMBOL (Qdelete_duplicates);
11723 DEFSYMBOL (Qsubstitute);
11724 DEFSYMBOL (Qmismatch);
11725 DEFSYMBOL (Qintersection);
11726 DEFSYMBOL (Qnintersection);
11727 DEFSYMBOL (Qsubsetp);
11728 DEFSYMBOL (Qset_difference);
11729 DEFSYMBOL (Qnset_difference);
11730 DEFSYMBOL (Qnunion);
6847 11731
6848 DEFKEYWORD (Q_from_end); 11732 DEFKEYWORD (Q_from_end);
6849 DEFKEYWORD (Q_initial_value); 11733 DEFKEYWORD (Q_initial_value);
6850 DEFKEYWORD (Q_start1); 11734 DEFKEYWORD (Q_start1);
6851 DEFKEYWORD (Q_start2); 11735 DEFKEYWORD (Q_start2);
6852 DEFKEYWORD (Q_end1); 11736 DEFKEYWORD (Q_end1);
6853 DEFKEYWORD (Q_end2); 11737 DEFKEYWORD (Q_end2);
11738 defkeyword (&Q_if_, ":if");
11739 DEFKEYWORD (Q_if_not);
11740 DEFKEYWORD (Q_test_not);
11741 DEFKEYWORD (Q_count);
11742 DEFKEYWORD (Q_stable);
6854 11743
6855 DEFSYMBOL (Qyes_or_no_p); 11744 DEFSYMBOL (Qyes_or_no_p);
6856 11745
6857 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error); 11746 DEFERROR_STANDARD (Qbase64_conversion_error, Qconversion_error);
6858 11747
6859 DEFSUBR (Fidentity); 11748 DEFSUBR (Fidentity);
6860 DEFSUBR (Frandom); 11749 DEFSUBR (Frandom);
6861 DEFSUBR (Flength); 11750 DEFSUBR (Flength);
6862 DEFSUBR (Fsafe_length); 11751 DEFSUBR (Fsafe_length);
6863 DEFSUBR (Flist_length); 11752 DEFSUBR (Flist_length);
11753 DEFSUBR (Fcount);
6864 DEFSUBR (Fstring_equal); 11754 DEFSUBR (Fstring_equal);
6865 DEFSUBR (Fcompare_strings); 11755 DEFSUBR (Fcompare_strings);
6866 DEFSUBR (Fstring_lessp); 11756 DEFSUBR (Fstring_lessp);
6867 DEFSUBR (Fstring_modified_tick); 11757 DEFSUBR (Fstring_modified_tick);
6868 DEFSUBR (Fappend); 11758 DEFSUBR (Fappend);
6882 DEFSUBR (Fnbutlast); 11772 DEFSUBR (Fnbutlast);
6883 DEFSUBR (Fmember); 11773 DEFSUBR (Fmember);
6884 DEFSUBR (Fold_member); 11774 DEFSUBR (Fold_member);
6885 DEFSUBR (Fmemq); 11775 DEFSUBR (Fmemq);
6886 DEFSUBR (Fold_memq); 11776 DEFSUBR (Fold_memq);
11777 DEFSUBR (FmemberX);
11778 DEFSUBR (Fadjoin);
6887 DEFSUBR (Fassoc); 11779 DEFSUBR (Fassoc);
6888 DEFSUBR (Fold_assoc); 11780 DEFSUBR (Fold_assoc);
6889 DEFSUBR (Fassq); 11781 DEFSUBR (Fassq);
6890 DEFSUBR (Fold_assq); 11782 DEFSUBR (Fold_assq);
6891 DEFSUBR (Frassoc); 11783 DEFSUBR (Frassoc);
6892 DEFSUBR (Fold_rassoc); 11784 DEFSUBR (Fold_rassoc);
6893 DEFSUBR (Frassq); 11785 DEFSUBR (Frassq);
6894 DEFSUBR (Fold_rassq); 11786 DEFSUBR (Fold_rassq);
11787
11788 DEFSUBR (Fposition);
11789 DEFSUBR (Ffind);
11790
6895 DEFSUBR (Fdelete); 11791 DEFSUBR (Fdelete);
6896 DEFSUBR (Fold_delete); 11792 DEFSUBR (Fold_delete);
6897 DEFSUBR (Fdelq); 11793 DEFSUBR (Fdelq);
6898 DEFSUBR (Fold_delq); 11794 DEFSUBR (Fold_delq);
11795 DEFSUBR (FdeleteX);
11796 DEFSUBR (FremoveX);
6899 DEFSUBR (Fremassoc); 11797 DEFSUBR (Fremassoc);
6900 DEFSUBR (Fremassq); 11798 DEFSUBR (Fremassq);
6901 DEFSUBR (Fremrassoc); 11799 DEFSUBR (Fremrassoc);
6902 DEFSUBR (Fremrassq); 11800 DEFSUBR (Fremrassq);
11801 DEFSUBR (Fdelete_duplicates);
11802 DEFSUBR (Fremove_duplicates);
6903 DEFSUBR (Fnreverse); 11803 DEFSUBR (Fnreverse);
6904 DEFSUBR (Freverse); 11804 DEFSUBR (Freverse);
6905 DEFSUBR (FsortX); 11805 DEFSUBR (FsortX);
6906 Ffset (intern ("sort"), QsortX);
6907 DEFSUBR (Fmerge); 11806 DEFSUBR (Fmerge);
6908 DEFSUBR (Fplists_eq); 11807 DEFSUBR (Fplists_eq);
6909 DEFSUBR (Fplists_equal); 11808 DEFSUBR (Fplists_equal);
6910 DEFSUBR (Flax_plists_eq); 11809 DEFSUBR (Flax_plists_eq);
6911 DEFSUBR (Flax_plists_equal); 11810 DEFSUBR (Flax_plists_equal);
6929 DEFSUBR (Fobject_setplist); 11828 DEFSUBR (Fobject_setplist);
6930 DEFSUBR (Fequal); 11829 DEFSUBR (Fequal);
6931 DEFSUBR (Fequalp); 11830 DEFSUBR (Fequalp);
6932 DEFSUBR (Fold_equal); 11831 DEFSUBR (Fold_equal);
6933 DEFSUBR (Ffill); 11832 DEFSUBR (Ffill);
6934 Ffset (intern ("fillarray"), Qfill); 11833
11834 DEFSUBR (FassocX);
11835 DEFSUBR (FrassocX);
6935 11836
6936 DEFSUBR (Fnconc); 11837 DEFSUBR (Fnconc);
6937 DEFSUBR (FmapcarX); 11838 DEFSUBR (FmapcarX);
6938 DEFSUBR (Fmapvector); 11839 DEFSUBR (Fmapvector);
6939 DEFSUBR (Fmapcan); 11840 DEFSUBR (Fmapcan);
6941 DEFSUBR (Fmapconcat); 11842 DEFSUBR (Fmapconcat);
6942 DEFSUBR (Fmap); 11843 DEFSUBR (Fmap);
6943 DEFSUBR (Fmap_into); 11844 DEFSUBR (Fmap_into);
6944 DEFSUBR (Fsome); 11845 DEFSUBR (Fsome);
6945 DEFSUBR (Fevery); 11846 DEFSUBR (Fevery);
6946 Ffset (intern ("mapc-internal"), Fsymbol_function (intern ("mapc"))); 11847 Ffset (intern ("mapc-internal"), Qmapc);
6947 Ffset (intern ("mapcar"), Fsymbol_function (intern ("mapcar*"))); 11848 Ffset (intern ("mapcar"), QmapcarX);
6948 DEFSUBR (Fmaplist); 11849 DEFSUBR (Fmaplist);
6949 DEFSUBR (Fmapl); 11850 DEFSUBR (Fmapl);
6950 DEFSUBR (Fmapcon); 11851 DEFSUBR (Fmapcon);
6951 11852
6952 DEFSUBR (Freduce); 11853 DEFSUBR (Freduce);
6953 DEFSUBR (Freplace_list); 11854 DEFSUBR (Freplace_list);
6954 DEFSUBR (Freplace); 11855 DEFSUBR (Freplace);
11856 DEFSUBR (Fsubsetp);
11857 DEFSUBR (Fnsubstitute);
11858 DEFSUBR (Fsubstitute);
11859 DEFSUBR (Fsublis);
11860 DEFSUBR (Fnsublis);
11861 DEFSUBR (Fsubst);
11862 DEFSUBR (Fnsubst);
11863 DEFSUBR (Ftree_equal);
11864 DEFSUBR (Fmismatch);
11865 DEFSUBR (Fsearch);
11866 DEFSUBR (Funion);
11867 DEFSUBR (Fnunion);
11868 DEFSUBR (Fintersection);
11869 DEFSUBR (Fnintersection);
11870 DEFSUBR (Fset_difference);
11871 DEFSUBR (Fnset_difference);
11872 DEFSUBR (Fset_exclusive_or);
11873 DEFSUBR (Fnset_exclusive_or);
11874
6955 DEFSUBR (Fload_average); 11875 DEFSUBR (Fload_average);
6956 DEFSUBR (Ffeaturep); 11876 DEFSUBR (Ffeaturep);
6957 DEFSUBR (Frequire); 11877 DEFSUBR (Frequire);
6958 DEFSUBR (Fprovide); 11878 DEFSUBR (Fprovide);
6959 DEFSUBR (Fbase64_encode_region); 11879 DEFSUBR (Fbase64_encode_region);