comparison src/fns.c @ 5475:248176c74e6b

Merge with trunk.
author Mats Lidell <matsl@xemacs.org>
date Sat, 23 Apr 2011 23:47:13 +0200
parents ac37a5f7e5be ccf7e84fe265
children d3e0482c7899
comparison
equal deleted inserted replaced
5474:4dee0387b9de 5475:248176c74e6b
995 995
996 /* Our callers should have filtered out non-positive COUNT. */ 996 /* Our callers should have filtered out non-positive COUNT. */
997 assert (counting >= 0); 997 assert (counting >= 0);
998 /* And we're not prepared to handle COUNT from any other caller at the 998 /* And we're not prepared to handle COUNT from any other caller at the
999 moment. */ 999 moment. */
1000 assert (EQ (caller, QremoveX)); 1000 assert (EQ (caller, QremoveX)|| EQ (caller, QdeleteX));
1001 } 1001 }
1002 1002
1003 check_test = get_check_test_function (item, &test, test_not, if_, if_not, 1003 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
1004 key, &test_not_unboundp); 1004 key, &test_not_unboundp);
1005 1005
1006 *tail_out = Qnil; 1006 *tail_out = Qnil;
1007 1007
1008 if (CONSP (sequence)) 1008 if (CONSP (sequence))
1009 { 1009 {
1010 Lisp_Object elt, tail = Qnil;
1011 struct gcpro gcpro1;
1012
1013 if (EQ (caller, Qcount) && !NILP (from_end) 1010 if (EQ (caller, Qcount) && !NILP (from_end)
1014 && (!EQ (key, Qnil) || 1011 && (!EQ (key, Qnil) ||
1015 check_test == check_other_nokey || check_test == check_if_nokey)) 1012 check_test == check_other_nokey || check_test == check_if_nokey))
1016 { 1013 {
1017 /* #'count, #'count-if, and #'count-if-not are documented to have 1014 /* #'count, #'count-if, and #'count-if-not are documented to have
1022 return list_count_from_end (item, sequence, check_test, 1019 return list_count_from_end (item, sequence, check_test,
1023 test_not_unboundp, test, key, 1020 test_not_unboundp, test, key,
1024 start, end); 1021 start, end);
1025 } 1022 }
1026 1023
1027 GCPRO1 (tail);
1028
1029 /* If COUNT is non-nil and FROM-END is t, we can give the tail 1024 /* If COUNT is non-nil and FROM-END is t, we can give the tail
1030 containing the last match, since that's what #'remove* is 1025 containing the last match, since that's what #'remove* is
1031 interested in (a zero or negative COUNT won't ever reach 1026 interested in (a zero or negative COUNT won't ever reach
1032 count_with_tail(), our callers will return immediately on seeing 1027 count_with_tail(), our callers will return immediately on seeing
1033 it). */ 1028 it). */
1035 { 1030 {
1036 counting = EMACS_INT_MAX; 1031 counting = EMACS_INT_MAX;
1037 } 1032 }
1038 1033
1039 { 1034 {
1040 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) 1035 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
1041 { 1036 {
1042 if (!(ii < ending)) 1037 if (!(ii < ending))
1043 { 1038 {
1044 break; 1039 break;
1045 } 1040 }
1056 } 1051 }
1057 } 1052 }
1058 1053
1059 ii++; 1054 ii++;
1060 } 1055 }
1056 END_GC_EXTERNAL_LIST_LOOP (elt);
1061 } 1057 }
1062
1063 UNGCPRO;
1064 1058
1065 if ((ii < starting || (ii < ending && !NILP (end))) && 1059 if ((ii < starting || (ii < ending && !NILP (end))) &&
1066 encountered != counting) 1060 encountered != counting)
1067 { 1061 {
1068 check_sequence_range (args[1], start, end, Flength (args[1])); 1062 check_sequence_range (args[1], start, end, Flength (args[1]));
2618 Boolint test_not_unboundp, 2612 Boolint test_not_unboundp,
2619 Lisp_Object test, Lisp_Object key, 2613 Lisp_Object test, Lisp_Object key,
2620 Boolint reverse_test_order, 2614 Boolint reverse_test_order,
2621 Lisp_Object start, Lisp_Object end) 2615 Lisp_Object start, Lisp_Object end)
2622 { 2616 {
2623 struct gcpro gcpro1, gcpro2; 2617 struct gcpro gcpro1;
2624 Lisp_Object elt = Qnil, tail = list, tail_before = Qnil; 2618 Lisp_Object tail_before = Qnil;
2625 Elemcount len, ii = 0, starting = XINT (start); 2619 Elemcount ii = 0, starting = XINT (start);
2626 Elemcount ending = NILP (end) ? EMACS_INT_MAX : XINT (end); 2620 Elemcount ending = NILP (end) ? EMACS_INT_MAX : XINT (end);
2627 2621
2628 GCPRO2 (elt, tail); 2622 GCPRO1 (tail_before);
2629 2623
2630 if (check_test == check_eq_nokey) 2624 if (check_test == check_eq_nokey)
2631 { 2625 {
2632 /* TEST is #'eq, no need to call any C functions, and the test order 2626 /* TEST is #'eq, no need to call any C functions, and the test order
2633 won't be visible. */ 2627 won't be visible. */
2634 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) 2628 EXTERNAL_LIST_LOOP_3 (elt, list, tail)
2635 { 2629 {
2636 if (starting <= ii && ii < ending && 2630 if (starting <= ii && ii < ending &&
2637 EQ (item, elt) == test_not_unboundp) 2631 EQ (item, elt) == test_not_unboundp)
2638 { 2632 {
2639 *cons_out = tail_before; 2633 *cons_out = tail_before;
2650 tail_before = tail; 2644 tail_before = tail;
2651 } 2645 }
2652 } 2646 }
2653 else 2647 else
2654 { 2648 {
2655 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) 2649 GC_EXTERNAL_LIST_LOOP_3 (elt, list, tail)
2656 { 2650 {
2657 if (starting <= ii && ii < ending && 2651 if (starting <= ii && ii < ending &&
2658 (reverse_test_order ? 2652 (reverse_test_order ?
2659 check_test (test, key, elt, item) : 2653 check_test (test, key, elt, item) :
2660 check_test (test, key, item, elt)) == test_not_unboundp) 2654 check_test (test, key, item, elt)) == test_not_unboundp)
2661 { 2655 {
2662 *cons_out = tail_before; 2656 *cons_out = tail_before;
2663 RETURN_UNGCPRO (make_integer (ii)); 2657 XUNGCPRO (elt);
2658 UNGCPRO;
2659 return make_integer (ii);
2664 } 2660 }
2665 else 2661 else
2666 { 2662 {
2667 if (ii >= ending) 2663 if (ii >= ending)
2668 { 2664 {
2670 } 2666 }
2671 } 2667 }
2672 ii++; 2668 ii++;
2673 tail_before = tail; 2669 tail_before = tail;
2674 } 2670 }
2671 END_GC_EXTERNAL_LIST_LOOP (elt);
2675 } 2672 }
2676 2673
2677 RETURN_UNGCPRO (Qnil); 2674 RETURN_UNGCPRO (Qnil);
2678 } 2675 }
2679 2676
2856 } 2853 }
2857 } 2854 }
2858 } 2855 }
2859 else 2856 else
2860 { 2857 {
2861 Lisp_Object tailed = alist; 2858 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
2862 struct gcpro gcpro1; 2859 {
2863 2860 if (CONSP (elt) &&
2864 GCPRO1 (tailed); 2861 check_test (test, key, item, XCAR (elt)) == test_not_unboundp)
2865 {
2866 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail)
2867 {
2868 tailed = tail;
2869
2870 if (check_test (test, key, item, elt_car) == test_not_unboundp)
2871 { 2862 {
2872 RETURN_UNGCPRO (elt); 2863 XUNGCPRO (elt);
2864 return elt;
2873 } 2865 }
2874 } 2866 }
2875 } 2867 END_GC_EXTERNAL_LIST_LOOP (elt);
2876 UNGCPRO;
2877 } 2868 }
2878 2869
2879 return Qnil; 2870 return Qnil;
2880 } 2871 }
2881 2872
2965 } 2956 }
2966 } 2957 }
2967 } 2958 }
2968 else 2959 else
2969 { 2960 {
2970 struct gcpro gcpro1; 2961 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
2971 Lisp_Object tailed = alist; 2962 {
2972 2963 if (CONSP (elt) &&
2973 GCPRO1 (tailed); 2964 check_test (test, key, item, XCDR (elt)) == test_not_unboundp)
2974 { 2965 {
2975 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) 2966 XUNGCPRO (elt);
2976 { 2967 return elt;
2977 tailed = tail; 2968 }
2978 2969 }
2979 if (check_test (test, key, item, elt_cdr) == test_not_unboundp) 2970 END_GC_EXTERNAL_LIST_LOOP (elt);
2980 {
2981 RETURN_UNGCPRO (elt);
2982 }
2983 }
2984 }
2985 UNGCPRO;
2986 } 2971 }
2987 2972
2988 return Qnil; 2973 return Qnil;
2989 } 2974 }
2990 2975
3010 2995
3011 *object_out = default_; 2996 *object_out = default_;
3012 2997
3013 if (CONSP (sequence)) 2998 if (CONSP (sequence))
3014 { 2999 {
3015 Lisp_Object elt, tail = Qnil;
3016 struct gcpro gcpro1;
3017
3018 if (!(starting < ending)) 3000 if (!(starting < ending))
3019 { 3001 {
3020 check_sequence_range (sequence, start, end, Flength (sequence)); 3002 check_sequence_range (sequence, start, end, Flength (sequence));
3021 /* starting could be equal to ending, in which case nil is what 3003 /* starting could be equal to ending, in which case nil is what
3022 we want to return. */ 3004 we want to return. */
3023 return Qnil; 3005 return Qnil;
3024 } 3006 }
3025 3007
3026 GCPRO1 (tail);
3027
3028 { 3008 {
3029 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) 3009 GC_EXTERNAL_LIST_LOOP_2 (elt, sequence)
3030 { 3010 {
3031 if (starting <= ii && ii < ending 3011 if (starting <= ii && ii < ending
3032 && check_test (test, key, item, elt) == test_not_unboundp) 3012 && check_test (test, key, item, elt) == test_not_unboundp)
3033 { 3013 {
3034 result = make_integer (ii); 3014 result = make_integer (ii);
3035 *object_out = elt; 3015 *object_out = elt;
3036 3016
3037 if (NILP (from_end)) 3017 if (NILP (from_end))
3038 { 3018 {
3039 UNGCPRO; 3019 XUNGCPRO (elt);
3040 return result; 3020 return result;
3041 } 3021 }
3042 } 3022 }
3043 else if (ii == ending) 3023 else if (ii == ending)
3044 { 3024 {
3045 break; 3025 break;
3046 } 3026 }
3047 3027
3048 ii++; 3028 ii++;
3049 } 3029 }
3030 END_GC_EXTERNAL_LIST_LOOP (elt);
3050 } 3031 }
3051
3052 UNGCPRO;
3053 3032
3054 if (ii < starting || (ii < ending && !NILP (end))) 3033 if (ii < starting || (ii < ending && !NILP (end)))
3055 { 3034 {
3056 check_sequence_range (sequence, start, end, Flength (sequence)); 3035 check_sequence_range (sequence, start, end, Flength (sequence));
3057 } 3036 }
3255 3234
3256 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT TEST-NOT) 3235 arguments: (ITEM SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT TEST-NOT)
3257 */ 3236 */
3258 (int nargs, Lisp_Object *args)) 3237 (int nargs, Lisp_Object *args))
3259 { 3238 {
3260 Lisp_Object item = args[0], sequence = args[1], tail = sequence; 3239 Lisp_Object item = args[0], sequence = args[1];
3261 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX; 3240 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX;
3262 Elemcount len, ii = 0, encountered = 0, presenting = 0; 3241 Elemcount len, ii = 0, encountered = 0, presenting = 0;
3263 Boolint test_not_unboundp = 1; 3242 Boolint test_not_unboundp = 1;
3264 check_test_func_t check_test = NULL; 3243 check_test_func_t check_test = NULL;
3265 struct gcpro gcpro1;
3266 3244
3267 PARSE_KEYWORDS (FdeleteX, nargs, args, 9, 3245 PARSE_KEYWORDS (FdeleteX, nargs, args, 9,
3268 (test, if_not, if_, test_not, key, start, end, from_end, 3246 (test, if_not, if_, test_not, key, start, end, from_end,
3269 count), (start = Qzero, count = Qunbound)); 3247 count), (start = Qzero, count = Qunbound));
3270 3248
3297 3275
3298 if (counting < 1) 3276 if (counting < 1)
3299 { 3277 {
3300 return sequence; 3278 return sequence;
3301 } 3279 }
3302 } 3280
3281 if (!NILP (from_end))
3282 {
3283 /* Sigh, this is inelegant. Force count_with_tail () to ignore
3284 the count keyword, so we get the actual number of matching
3285 elements, and can start removing from the beginning for the
3286 from-end case. */
3287 for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FdeleteX))->min_args;
3288 ii < nargs; ii += 2)
3289 {
3290 if (EQ (args[ii], Q_count))
3291 {
3292 args[ii + 1] = Qnil;
3293 break;
3294 }
3295 }
3296 ii = 0;
3297 }
3298 }
3303 } 3299 }
3304 3300
3305 check_test = get_check_test_function (item, &test, test_not, if_, if_not, 3301 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3306 key, &test_not_unboundp); 3302 key, &test_not_unboundp);
3307 3303
3308 if (CONSP (sequence)) 3304 if (CONSP (sequence))
3309 { 3305 {
3310 Lisp_Object prev_tail_list_elt = Qnil, list_elt = Qnil; 3306 Lisp_Object prev_tail_list_elt = Qnil, ignore = Qnil;
3311 Elemcount list_len = 0, deleted = 0; 3307 Elemcount list_len = 0, deleted = 0;
3308 struct gcpro gcpro1;
3312 3309
3313 if (!NILP (count) && !NILP (from_end)) 3310 if (!NILP (count) && !NILP (from_end))
3314 { 3311 {
3315 /* Both COUNT and FROM-END were specified; we need to traverse the 3312 /* Both COUNT and FROM-END were specified; we need to traverse the
3316 list twice. */ 3313 list twice. */
3317 Lisp_Object present = count_with_tail (&list_elt, nargs, args, 3314 Lisp_Object present = count_with_tail (&ignore, nargs, args,
3318 QdeleteX); 3315 QdeleteX);
3319 3316
3320 if (ZEROP (present)) 3317 if (ZEROP (present))
3321 { 3318 {
3322 return sequence; 3319 return sequence;
3330 of matching items we need to ignore before we start to 3327 of matching items we need to ignore before we start to
3331 delete. */ 3328 delete. */
3332 presenting = presenting <= counting ? 0 : presenting - counting; 3329 presenting = presenting <= counting ? 0 : presenting - counting;
3333 } 3330 }
3334 3331
3335 GCPRO1 (tail); 3332 GCPRO1 (prev_tail_list_elt);
3336 ii = -1; 3333 ii = -1;
3337 3334
3338 { 3335 {
3339 EXTERNAL_LIST_LOOP_4_NO_DECLARE (list_elt, sequence, tail, list_len) 3336 GC_EXTERNAL_LIST_LOOP_4 (list_elt, sequence, tail, list_len)
3340 { 3337 {
3341 ii++; 3338 ii++;
3342 3339
3343 if (starting <= ii && ii < ending && 3340 if (starting <= ii && ii < ending &&
3344 (check_test (test, key, item, list_elt) == test_not_unboundp) 3341 (check_test (test, key, item, list_elt) == test_not_unboundp)
3365 { 3362 {
3366 break; 3363 break;
3367 } 3364 }
3368 } 3365 }
3369 } 3366 }
3367 END_GC_EXTERNAL_LIST_LOOP (list_elt);
3370 } 3368 }
3371 3369
3372 UNGCPRO; 3370 UNGCPRO;
3373 3371
3374 if ((ii < starting || (ii < ending && !NILP (end))) && 3372 if ((ii < starting || (ii < ending && !NILP (end))) &&
3602 (int nargs, Lisp_Object *args)) 3600 (int nargs, Lisp_Object *args))
3603 { 3601 {
3604 Lisp_Object item = args[0], sequence = args[1], matched_count = Qnil, 3602 Lisp_Object item = args[0], sequence = args[1], matched_count = Qnil,
3605 tail = Qnil; 3603 tail = Qnil;
3606 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX; 3604 Elemcount starting = 0, ending = EMACS_INT_MAX, counting = EMACS_INT_MAX;
3607 Elemcount len, ii = 0, encountered = 0, presenting = 0; 3605 Elemcount ii = 0, encountered = 0, presenting = 0;
3608 Boolint test_not_unboundp = 1; 3606 Boolint test_not_unboundp = 1;
3609 check_test_func_t check_test = NULL; 3607 check_test_func_t check_test = NULL;
3610 struct gcpro gcpro1;
3611 3608
3612 PARSE_KEYWORDS (FremoveX, nargs, args, 9, 3609 PARSE_KEYWORDS (FremoveX, nargs, args, 9,
3613 (test, if_not, if_, test_not, key, start, end, from_end, 3610 (test, if_not, if_, test_not, key, start, end, from_end,
3614 count), (start = Qzero)); 3611 count), (start = Qzero));
3615 3612
3644 3641
3645 if (counting <= 0) 3642 if (counting <= 0)
3646 { 3643 {
3647 return sequence; 3644 return sequence;
3648 } 3645 }
3646
3647 if (!NILP (from_end))
3648 {
3649 /* Sigh, this is inelegant. Force count_with_tail () to ignore the
3650 count keyword, so we get the actual number of matching
3651 elements, and can start removing from the beginning for the
3652 from-end case. */
3653 for (ii = XSUBR (GET_DEFUN_LISP_OBJECT (FremoveX))->min_args;
3654 ii < nargs; ii += 2)
3655 {
3656 if (EQ (args[ii], Q_count))
3657 {
3658 args[ii + 1] = Qnil;
3659 break;
3660 }
3661 }
3662 ii = 0;
3663 }
3649 } 3664 }
3650 3665
3651 check_test = get_check_test_function (item, &test, test_not, if_, if_not, 3666 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
3652 key, &test_not_unboundp); 3667 key, &test_not_unboundp);
3653 3668
3654 matched_count = count_with_tail (&tail, nargs, args, QremoveX); 3669 matched_count = count_with_tail (&tail, nargs, args, QremoveX);
3655 3670
3656 if (!ZEROP (matched_count)) 3671 if (!ZEROP (matched_count))
3657 { 3672 {
3658 Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil; 3673 Lisp_Object result = Qnil, result_tail = Qnil;
3659 GCPRO1 (tailing); 3674 struct gcpro gcpro1, gcpro2;
3660 3675
3661 if (!NILP (count) && !NILP (from_end)) 3676 if (!NILP (count) && !NILP (from_end))
3662 { 3677 {
3663 presenting = XINT (matched_count); 3678 presenting = XINT (matched_count);
3664 3679
3668 is the number of matching items we need to ignore before we 3683 is the number of matching items we need to ignore before we
3669 start to delete. */ 3684 start to delete. */
3670 presenting = presenting <= counting ? 0 : presenting - counting; 3685 presenting = presenting <= counting ? 0 : presenting - counting;
3671 } 3686 }
3672 3687
3688 GCPRO2 (result, tail);
3673 { 3689 {
3674 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len) 3690 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tailing)
3675 { 3691 {
3676 if (EQ (tail, tailing)) 3692 if (EQ (tail, tailing))
3677 { 3693 {
3694 XUNGCPRO (elt);
3695 UNGCPRO;
3696
3678 if (NILP (result)) 3697 if (NILP (result))
3679 { 3698 {
3680 RETURN_UNGCPRO (XCDR (tail)); 3699 return XCDR (tail);
3681 } 3700 }
3682 3701
3683 XSETCDR (result_tail, XCDR (tail)); 3702 XSETCDR (result_tail, XCDR (tail));
3684 RETURN_UNGCPRO (result); 3703 return result;
3685 } 3704 }
3686 else if (starting <= ii && ii < ending && 3705 else if (starting <= ii && ii < ending &&
3687 (check_test (test, key, item, elt) == test_not_unboundp) 3706 (check_test (test, key, item, elt) == test_not_unboundp)
3688 && (presenting ? encountered++ >= presenting 3707 && (presenting ? encountered++ >= presenting
3689 : encountered++ < counting)) 3708 : encountered++ < counting))
3705 break; 3724 break;
3706 } 3725 }
3707 3726
3708 ii++; 3727 ii++;
3709 } 3728 }
3729 END_GC_EXTERNAL_LIST_LOOP (elt);
3710 } 3730 }
3711
3712 UNGCPRO; 3731 UNGCPRO;
3713 3732
3714 if (ii < starting || (ii < ending && !NILP (end))) 3733 if (ii < starting || (ii < ending && !NILP (end)))
3715 { 3734 {
3716 check_sequence_range (args[0], start, end, Flength (args[0])); 3735 check_sequence_range (args[0], start, end, Flength (args[0]));
3825 Boolint test_not_unboundp, 3844 Boolint test_not_unboundp,
3826 Lisp_Object test, Lisp_Object key, 3845 Lisp_Object test, Lisp_Object key,
3827 Lisp_Object start, 3846 Lisp_Object start,
3828 Lisp_Object end, Boolint copy) 3847 Lisp_Object end, Boolint copy)
3829 { 3848 {
3830 Lisp_Object checking = Qnil, elt, tail, result = list; 3849 Lisp_Object checking = Qnil, result = list;
3831 Lisp_Object keyed, positioned, position_cons = Qnil, result_tail; 3850 Lisp_Object keyed, positioned, position_cons = Qnil, result_tail;
3832 Elemcount len = XINT (Flength (list)), pos, starting = XINT (start); 3851 Elemcount len = XINT (Flength (list)), pos, starting = XINT (start);
3833 Elemcount ending = (NILP (end) ? len : XINT (end)), greatest_pos_seen = -1; 3852 Elemcount ending = (NILP (end) ? len : XINT (end)), greatest_pos_seen = -1;
3834 Elemcount ii = 0; 3853 Elemcount ii = 0;
3835 struct gcpro gcpro1, gcpro2; 3854 struct gcpro gcpro1;
3836 3855
3837 /* We can't delete (or remove) as we go, because that breaks START and 3856 /* We can't delete (or remove) as we go, because that breaks START and
3838 END. We could if END were nil, and that would change an ON(N + 2) 3857 END. We could if END were nil, and that would change an ON(N + 2)
3839 algorithm to an ON^2 algorithm; list_position_cons_before() would need to 3858 algorithm to an ON^2 algorithm; list_position_cons_before() would need to
3840 be modified to return the cons *before* the one containing the item for 3859 be modified to return the cons *before* the one containing the item for
3850 3869
3851 deleting->size = len; 3870 deleting->size = len;
3852 memset (&(deleting->bits), 0, 3871 memset (&(deleting->bits), 0,
3853 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len)); 3872 sizeof (long) * BIT_VECTOR_LONG_STORAGE (len));
3854 3873
3855 GCPRO2 (tail, keyed); 3874 GCPRO1 (keyed);
3856 3875
3857 { 3876 {
3858 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) 3877 GC_EXTERNAL_LIST_LOOP_3 (elt, list, tail)
3859 { 3878 {
3860 if (!(starting <= ii && ii <= ending) || bit_vector_bit (deleting, ii)) 3879 if (!(starting <= ii && ii <= ending) || bit_vector_bit (deleting, ii))
3861 { 3880 {
3862 ii++; 3881 ii++;
3863 continue; 3882 continue;
3880 XCDR (checking) : XCDR (XCDR (position_cons)); 3899 XCDR (checking) : XCDR (XCDR (position_cons));
3881 pos += 1; 3900 pos += 1;
3882 } 3901 }
3883 ii++; 3902 ii++;
3884 } 3903 }
3904 END_GC_EXTERNAL_LIST_LOOP (elt);
3885 } 3905 }
3886 3906
3887 UNGCPRO; 3907 UNGCPRO;
3888 3908
3889 ii = 0; 3909 ii = 0;
3895 result = result_tail = Fcons (XCAR (list), Qnil); 3915 result = result_tail = Fcons (XCAR (list), Qnil);
3896 list = XCDR (list); 3916 list = XCDR (list);
3897 ii = 1; 3917 ii = 1;
3898 3918
3899 { 3919 {
3900 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, list, tail, len) 3920 EXTERNAL_LIST_LOOP_3 (elt, list, tail)
3901 { 3921 {
3902 if (ii == greatest_pos_seen) 3922 if (ii == greatest_pos_seen)
3903 { 3923 {
3904 XSETCDR (result_tail, XCDR (tail)); 3924 XSETCDR (result_tail, XCDR (tail));
3905 break; 3925 break;
3913 } 3933 }
3914 } 3934 }
3915 } 3935 }
3916 else 3936 else
3917 { 3937 {
3918 EXTERNAL_LIST_LOOP_DELETE_IF (elt0, list, 3938 EXTERNAL_LIST_LOOP_DELETE_IF (elt, list,
3919 bit_vector_bit (deleting, ii++)); 3939 bit_vector_bit (deleting, ii++));
3920 } 3940 }
3921 } 3941 }
3922 3942
3923 return result; 3943 return result;
3941 3961
3942 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT) 3962 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT)
3943 */ 3963 */
3944 (int nargs, Lisp_Object *args)) 3964 (int nargs, Lisp_Object *args))
3945 { 3965 {
3946 Lisp_Object sequence = args[0], tail = sequence, keyed = Qnil, elt = Qnil; 3966 Lisp_Object sequence = args[0], keyed = Qnil;
3947 Lisp_Object elt0 = Qnil, positioned = Qnil, ignore = Qnil; 3967 Lisp_Object positioned = Qnil, ignore = Qnil;
3948 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0, jj = 0; 3968 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0, jj = 0;
3949 Boolint test_not_unboundp = 1; 3969 Boolint test_not_unboundp = 1;
3950 check_test_func_t check_test = NULL; 3970 check_test_func_t check_test = NULL;
3951 struct gcpro gcpro1, gcpro2; 3971 struct gcpro gcpro1, gcpro2;
3952 3972
3974 if (NILP (from_end)) 3994 if (NILP (from_end))
3975 { 3995 {
3976 Lisp_Object prev_tail = Qnil; 3996 Lisp_Object prev_tail = Qnil;
3977 Elemcount deleted = 0; 3997 Elemcount deleted = 0;
3978 3998
3979 GCPRO2 (tail, keyed); 3999 GCPRO2 (keyed, prev_tail);
3980 4000
3981 { 4001 {
3982 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) 4002 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
3983 { 4003 {
3984 if (starting <= ii && ii < ending) 4004 if (starting <= ii && ii < ending)
3985 { 4005 {
3986 keyed = KEY (key, elt); 4006 keyed = KEY (key, elt);
3987 positioned 4007 positioned
4008 break; 4028 break;
4009 } 4029 }
4010 4030
4011 ii++; 4031 ii++;
4012 } 4032 }
4033 END_GC_EXTERNAL_LIST_LOOP (elt);
4013 } 4034 }
4014 { 4035 {
4015 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len) 4036 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
4016 { 4037 {
4017 if (!(starting <= ii && ii <= ending)) 4038 if (!(starting <= ii && ii <= ending))
4018 { 4039 {
4019 prev_tail = tail; 4040 prev_tail = tail;
4020 ii++; 4041 ii++;
4021 continue; 4042 continue;
4022 } 4043 }
4023 4044
4024 keyed = KEY (key, elt0); 4045 keyed = KEY (key, elt);
4025 positioned 4046 positioned
4026 = list_position_cons_before (&ignore, keyed, XCDR (tail), 4047 = list_position_cons_before (&ignore, keyed, XCDR (tail),
4027 check_test, test_not_unboundp, 4048 check_test, test_not_unboundp,
4028 test, key, 0, 4049 test, key, 0,
4029 make_int (max (starting 4050 make_int (max (starting
4048 } 4069 }
4049 } 4070 }
4050 4071
4051 ii++; 4072 ii++;
4052 } 4073 }
4074 END_GC_EXTERNAL_LIST_LOOP (elt);
4053 } 4075 }
4076
4054 UNGCPRO; 4077 UNGCPRO;
4055 4078
4056 if ((ii < starting || (ii < ending && !NILP (end)))) 4079 if ((ii < starting || (ii < ending && !NILP (end))))
4057 { 4080 {
4058 check_sequence_range (args[0], start, end, 4081 check_sequence_range (args[0], start, end,
4068 0); 4091 0);
4069 } 4092 }
4070 } 4093 }
4071 else if (STRINGP (sequence)) 4094 else if (STRINGP (sequence))
4072 { 4095 {
4096 Lisp_Object elt = Qnil;
4097
4073 if (EQ (Qidentity, key)) 4098 if (EQ (Qidentity, key))
4074 { 4099 {
4075 /* We know all the elements will be characters; set check_test to 4100 /* We know all the elements will be characters; set check_test to
4076 reflect that. This isn't useful if KEY is not #'identity, since 4101 reflect that. This isn't useful if KEY is not #'identity, since
4077 it may return non-characters for the elements. */ 4102 it may return non-characters for the elements. */
4086 Bytecount byte_len = XSTRING_LENGTH (sequence), cursor_offset = 0; 4111 Bytecount byte_len = XSTRING_LENGTH (sequence), cursor_offset = 0;
4087 Ibyte *staging = alloca_ibytes (byte_len), *staging_cursor = staging; 4112 Ibyte *staging = alloca_ibytes (byte_len), *staging_cursor = staging;
4088 Ibyte *cursor = XSTRING_DATA (sequence), *startp = cursor; 4113 Ibyte *cursor = XSTRING_DATA (sequence), *startp = cursor;
4089 Elemcount deleted = 0; 4114 Elemcount deleted = 0;
4090 4115
4091 elt = Qnil;
4092 GCPRO1 (elt); 4116 GCPRO1 (elt);
4093 4117
4094 while (cursor_offset < byte_len) 4118 while (cursor_offset < byte_len)
4095 { 4119 {
4096 if (starting <= ii && ii < ending) 4120 if (starting <= ii && ii < ending)
4241 else if (VECTORP (sequence)) 4265 else if (VECTORP (sequence))
4242 { 4266 {
4243 Elemcount deleted = 0; 4267 Elemcount deleted = 0;
4244 Lisp_Object *content = XVECTOR_DATA (sequence); 4268 Lisp_Object *content = XVECTOR_DATA (sequence);
4245 struct Lisp_Bit_Vector *deleting; 4269 struct Lisp_Bit_Vector *deleting;
4270 Lisp_Object elt = Qnil;
4246 4271
4247 len = XVECTOR_LENGTH (sequence); 4272 len = XVECTOR_LENGTH (sequence);
4248 check_sequence_range (sequence, start, end, make_integer (len)); 4273 check_sequence_range (sequence, start, end, make_integer (len));
4249 4274
4250 deleting = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector) 4275 deleting = (Lisp_Bit_Vector *) ALLOCA (sizeof (struct Lisp_Bit_Vector)
4324 that's the possible number of distinct elements if EQ is regarded 4349 that's the possible number of distinct elements if EQ is regarded
4325 as identity, which it should be). But to support arbitrary TEST 4350 as identity, which it should be). But to support arbitrary TEST
4326 and KEY arguments, which may be non-deterministic from our 4351 and KEY arguments, which may be non-deterministic from our
4327 perspective, we need the same algorithm as for vectors. */ 4352 perspective, we need the same algorithm as for vectors. */
4328 struct Lisp_Bit_Vector *deleting; 4353 struct Lisp_Bit_Vector *deleting;
4354 Lisp_Object elt = Qnil;
4329 4355
4330 len = bit_vector_length (bv); 4356 len = bit_vector_length (bv);
4331 4357
4332 if (EQ (Qidentity, key)) 4358 if (EQ (Qidentity, key))
4333 { 4359 {
4425 4451
4426 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT) 4452 arguments: (SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) END FROM-END TEST-NOT)
4427 */ 4453 */
4428 (int nargs, Lisp_Object *args)) 4454 (int nargs, Lisp_Object *args))
4429 { 4455 {
4430 Lisp_Object sequence = args[0], tail = sequence, keyed, positioned = Qnil; 4456 Lisp_Object sequence = args[0], keyed, positioned = Qnil;
4431 Lisp_Object result = sequence, result_tail = result, cursor = Qnil; 4457 Lisp_Object result = sequence, result_tail = result, cursor = Qnil;
4432 Lisp_Object cons_with_shared_tail = Qnil, elt, elt0; 4458 Lisp_Object cons_with_shared_tail = Qnil;
4433 Elemcount starting = 0, ending = EMACS_INT_MAX, len, ii = 0; 4459 Elemcount starting = 0, ending = EMACS_INT_MAX, ii = 0;
4434 Boolint test_not_unboundp = 1; 4460 Boolint test_not_unboundp = 1;
4435 check_test_func_t check_test = NULL; 4461 check_test_func_t check_test = NULL;
4436 struct gcpro gcpro1, gcpro2, gcpro3; 4462 struct gcpro gcpro1, gcpro2;
4437 4463
4438 PARSE_KEYWORDS (Fremove_duplicates, nargs, args, 6, 4464 PARSE_KEYWORDS (Fremove_duplicates, nargs, args, 6,
4439 (test, key, test_not, start, end, from_end), 4465 (test, key, test_not, start, end, from_end),
4440 (start = Qzero)); 4466 (start = Qzero));
4441 4467
4465 4491
4466 if (NILP (from_end)) 4492 if (NILP (from_end))
4467 { 4493 {
4468 Lisp_Object ignore = Qnil; 4494 Lisp_Object ignore = Qnil;
4469 4495
4470 GCPRO3 (tail, keyed, result); 4496 GCPRO2 (keyed, result);
4471 4497
4472 { 4498 {
4473 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) 4499 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
4474 { 4500 {
4475 if (starting <= ii && ii <= ending) 4501 if (starting <= ii && ii <= ending)
4476 { 4502 {
4477 keyed = KEY (key, elt); 4503 keyed = KEY (key, elt);
4478 positioned 4504 positioned
4496 break; 4522 break;
4497 } 4523 }
4498 4524
4499 ii++; 4525 ii++;
4500 } 4526 }
4527 END_GC_EXTERNAL_LIST_LOOP (elt);
4501 } 4528 }
4502 4529
4503 { 4530 {
4504 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt0, sequence, tail, len) 4531 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
4505 { 4532 {
4506 if (!(starting <= ii && ii <= ending)) 4533 if (!(starting <= ii && ii <= ending))
4507 { 4534 {
4508 ii++; 4535 ii++;
4509 continue; 4536 continue;
4512 /* For this algorithm, each time we encounter an object to be 4539 /* For this algorithm, each time we encounter an object to be
4513 removed, copy the output list from the tail beyond the last 4540 removed, copy the output list from the tail beyond the last
4514 removed cons to this one. Otherwise, the tail of the output list 4541 removed cons to this one. Otherwise, the tail of the output list
4515 is shared with the input list, which is OK. */ 4542 is shared with the input list, which is OK. */
4516 4543
4517 keyed = KEY (key, elt0); 4544 keyed = KEY (key, elt);
4518 positioned 4545 positioned
4519 = list_position_cons_before (&ignore, keyed, XCDR (tail), 4546 = list_position_cons_before (&ignore, keyed, XCDR (tail),
4520 check_test, test_not_unboundp, 4547 check_test, test_not_unboundp,
4521 test, key, 0, 4548 test, key, 0,
4522 make_int (max (starting - (ii + 1), 4549 make_int (max (starting - (ii + 1),
4544 cons_with_shared_tail = result_tail; 4571 cons_with_shared_tail = result_tail;
4545 } 4572 }
4546 4573
4547 ii++; 4574 ii++;
4548 } 4575 }
4576 END_GC_EXTERNAL_LIST_LOOP (elt);
4549 } 4577 }
4578
4550 UNGCPRO; 4579 UNGCPRO;
4551 4580
4552 if ((ii < starting || (ii < ending && !NILP (end)))) 4581 if ((ii < starting || (ii < ending && !NILP (end))))
4553 { 4582 {
4554 check_sequence_range (args[0], start, end, Flength (args[0])); 4583 check_sequence_range (args[0], start, end, Flength (args[0]));
7928 } 7957 }
7929 else if (LISTP (sequence)) 7958 else if (LISTP (sequence))
7930 { 7959 {
7931 if (NILP (from_end)) 7960 if (NILP (from_end))
7932 { 7961 {
7933 struct gcpro gcpro1, gcpro2; 7962 struct gcpro gcpro1;
7934 Lisp_Object tailed = Qnil; 7963
7935 7964 GCPRO1 (accum);
7936 GCPRO2 (tailed, accum);
7937 7965
7938 if (!UNBOUNDP (initial_value)) 7966 if (!UNBOUNDP (initial_value))
7939 { 7967 {
7940 accum = initial_value; 7968 accum = initial_value;
7941 } 7969 }
7942 else if (ending - starting) 7970 else if (ending - starting)
7943 { 7971 {
7944 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) 7972 GC_EXTERNAL_LIST_LOOP_2 (elt, sequence)
7945 { 7973 {
7946 /* KEY may amputate the list behind us; make sure what
7947 remains to be processed is still reachable. */
7948 tailed = tail;
7949 if (ii == starting) 7974 if (ii == starting)
7950 { 7975 {
7951 accum = KEY (key, elt); 7976 accum = KEY (key, elt);
7952 starting++; 7977 starting++;
7953 break; 7978 break;
7954 } 7979 }
7955 ++ii; 7980 ++ii;
7956 } 7981 }
7982 END_GC_EXTERNAL_LIST_LOOP (elt);
7957 } 7983 }
7958 7984
7959 ii = 0; 7985 ii = 0;
7960 7986
7961 if (ending - starting) 7987 if (ending - starting)
7962 { 7988 {
7963 EXTERNAL_LIST_LOOP_3 (elt, sequence, tail) 7989 GC_EXTERNAL_LIST_LOOP_2 (elt, sequence)
7964 { 7990 {
7965 /* KEY or FUNCTION may amputate the list behind us; make
7966 sure what remains to be processed is still
7967 reachable. */
7968 tailed = tail;
7969 if (ii >= starting) 7991 if (ii >= starting)
7970 { 7992 {
7971 if (ii < ending) 7993 if (ii < ending)
7972 { 7994 {
7973 accum = CALL2 (function, accum, KEY (key, elt)); 7995 accum = CALL2 (function, accum, KEY (key, elt));
7977 break; 7999 break;
7978 } 8000 }
7979 } 8001 }
7980 ++ii; 8002 ++ii;
7981 } 8003 }
8004 END_GC_EXTERNAL_LIST_LOOP (elt);
7982 } 8005 }
7983 8006
7984 UNGCPRO; 8007 UNGCPRO;
7985 8008
7986 if (ii < starting || (ii < ending && !NILP (end))) 8009 if (ii < starting || (ii < ending && !NILP (end)))
8699 8722
8700 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT) 8723 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) FROM-END COUNT)
8701 */ 8724 */
8702 (int nargs, Lisp_Object *args)) 8725 (int nargs, Lisp_Object *args))
8703 { 8726 {
8704 Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil; 8727 Lisp_Object new_ = args[0], item = args[1], sequence = args[2];
8705 Lisp_Object object_, position0; 8728 Lisp_Object object_, position0;
8706 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0; 8729 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0;
8707 Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0; 8730 Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0;
8708 Boolint test_not_unboundp = 1; 8731 Boolint test_not_unboundp = 1;
8709 check_test_func_t check_test = NULL; 8732 check_test_func_t check_test = NULL;
8710 struct gcpro gcpro1;
8711 8733
8712 PARSE_KEYWORDS (Fnsubstitute, nargs, args, 9, 8734 PARSE_KEYWORDS (Fnsubstitute, nargs, args, 9,
8713 (test, if_, if_not, test_not, key, start, end, count, 8735 (test, if_, if_not, test_not, key, start, end, count,
8714 from_end), (start = Qzero)); 8736 from_end), (start = Qzero));
8715 8737
8747 check_test = get_check_test_function (item, &test, test_not, if_, if_not, 8769 check_test = get_check_test_function (item, &test, test_not, if_, if_not,
8748 key, &test_not_unboundp); 8770 key, &test_not_unboundp);
8749 8771
8750 if (CONSP (sequence)) 8772 if (CONSP (sequence))
8751 { 8773 {
8752 Lisp_Object elt;
8753
8754 if (!NILP (count) && !NILP (from_end)) 8774 if (!NILP (count) && !NILP (from_end))
8755 { 8775 {
8756 Lisp_Object present = count_with_tail (&elt, nargs - 1, args + 1, 8776 Lisp_Object present = count_with_tail (&object_, nargs - 1, args + 1,
8757 Qnsubstitute); 8777 Qnsubstitute);
8758 8778
8759 if (ZEROP (present)) 8779 if (ZEROP (present))
8760 { 8780 {
8761 return sequence; 8781 return sequence;
8763 8783
8764 presenting = XINT (present); 8784 presenting = XINT (present);
8765 presenting = presenting <= counting ? 0 : presenting - counting; 8785 presenting = presenting <= counting ? 0 : presenting - counting;
8766 } 8786 }
8767 8787
8768 GCPRO1 (tail);
8769 { 8788 {
8770 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tail, len) 8789 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
8771 { 8790 {
8772 if (!(ii < ending)) 8791 if (!(ii < ending))
8773 { 8792 {
8774 break; 8793 break;
8775 } 8794 }
8787 break; 8806 break;
8788 } 8807 }
8789 8808
8790 ii++; 8809 ii++;
8791 } 8810 }
8811 END_GC_EXTERNAL_LIST_LOOP (elt);
8792 } 8812 }
8793 UNGCPRO;
8794 8813
8795 if ((ii < starting || (ii < ending && !NILP (end))) 8814 if ((ii < starting || (ii < ending && !NILP (end)))
8796 && encountered < counting) 8815 && encountered < counting)
8797 { 8816 {
8798 check_sequence_range (args[0], start, end, Flength (args[0])); 8817 check_sequence_range (args[0], start, end, Flength (args[0]));
8960 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) COUNT) 8979 arguments: (NEW OLD SEQUENCE &key (TEST #'eql) (KEY #'identity) (START 0) (END (length SEQUENCE)) COUNT)
8961 */ 8980 */
8962 (int nargs, Lisp_Object *args)) 8981 (int nargs, Lisp_Object *args))
8963 { 8982 {
8964 Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil; 8983 Lisp_Object new_ = args[0], item = args[1], sequence = args[2], tail = Qnil;
8965 Lisp_Object elt, tailing = Qnil, result = Qnil, result_tail = Qnil; 8984 Lisp_Object result = Qnil, result_tail = Qnil;
8966 Lisp_Object object, position0, matched_count; 8985 Lisp_Object object, position0, matched_count;
8967 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0; 8986 Elemcount starting = 0, ending = EMACS_INT_MAX, encountered = 0;
8968 Elemcount len, ii = 0, counting = EMACS_INT_MAX, presenting = 0; 8987 Elemcount ii = 0, counting = EMACS_INT_MAX, presenting = 0;
8969 Boolint test_not_unboundp = 1; 8988 Boolint test_not_unboundp = 1;
8970 check_test_func_t check_test = NULL; 8989 check_test_func_t check_test = NULL;
8971 struct gcpro gcpro1; 8990 struct gcpro gcpro1;
8972 8991
8973 PARSE_KEYWORDS (Fsubstitute, nargs, args, 9, 8992 PARSE_KEYWORDS (Fsubstitute, nargs, args, 9,
9040 { 9059 {
9041 presenting = XINT (matched_count); 9060 presenting = XINT (matched_count);
9042 presenting = presenting <= counting ? 0 : presenting - counting; 9061 presenting = presenting <= counting ? 0 : presenting - counting;
9043 } 9062 }
9044 9063
9045 GCPRO1 (tailing); 9064 GCPRO1 (result);
9046 { 9065 {
9047 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, sequence, tailing, len) 9066 GC_EXTERNAL_LIST_LOOP_3 (elt, sequence, tailing)
9048 { 9067 {
9049 if (EQ (tail, tailing)) 9068 if (EQ (tail, tailing))
9050 { 9069 {
9070 XUNGCPRO (elt);
9071 UNGCPRO;
9072
9051 if (NILP (result)) 9073 if (NILP (result))
9052 { 9074 {
9053 RETURN_UNGCPRO (XCDR (tail)); 9075 return XCDR (tail);
9054 } 9076 }
9055 9077
9056 XSETCDR (result_tail, XCDR (tail)); 9078 XSETCDR (result_tail, XCDR (tail));
9057 RETURN_UNGCPRO (result); 9079 return result;
9058 } 9080 }
9059 else if (starting <= ii && ii < ending && 9081 else if (starting <= ii && ii < ending &&
9060 (check_test (test, key, item, elt) == test_not_unboundp) 9082 (check_test (test, key, item, elt) == test_not_unboundp)
9061 && (presenting ? encountered++ >= presenting 9083 && (presenting ? encountered++ >= presenting
9062 : encountered++ < counting)) 9084 : encountered++ < counting))
9086 break; 9108 break;
9087 } 9109 }
9088 9110
9089 ii++; 9111 ii++;
9090 } 9112 }
9113 END_GC_EXTERNAL_LIST_LOOP (elt);
9091 } 9114 }
9092 UNGCPRO; 9115 UNGCPRO;
9093 9116
9094 if (ii < starting || (ii < ending && !NILP (end))) 9117 if (ii < starting || (ii < ending && !NILP (end)))
9095 { 9118 {
9134 static Lisp_Object 9157 static Lisp_Object
9135 sublis (Lisp_Object alist, Lisp_Object tree, 9158 sublis (Lisp_Object alist, Lisp_Object tree,
9136 check_test_func_t check_test, Boolint test_not_unboundp, 9159 check_test_func_t check_test, Boolint test_not_unboundp,
9137 Lisp_Object test, Lisp_Object key, int depth) 9160 Lisp_Object test, Lisp_Object key, int depth)
9138 { 9161 {
9139 Lisp_Object keyed = KEY (key, tree), tailed = alist, aa, dd; 9162 Lisp_Object keyed = KEY (key, tree), aa, dd;
9140 struct gcpro gcpro1, gcpro2, gcpro3; 9163 struct gcpro gcpro1;
9141 9164
9142 if (depth + lisp_eval_depth > max_lisp_eval_depth) 9165 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9143 { 9166 {
9144 stack_overflow ("Stack overflow in sublis", tree); 9167 stack_overflow ("Stack overflow in sublis", tree);
9145 } 9168 }
9146 9169
9147 GCPRO3 (tailed, alist, tree);
9148 { 9170 {
9149 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) 9171 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
9150 { 9172 {
9151 tailed = tail; 9173 if (CONSP (elt) &&
9152 9174 check_test (test, key, XCAR (elt), keyed) == test_not_unboundp)
9153 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9154 { 9175 {
9155 /* Don't use elt_cdr, it is helpful to allow TEST or KEY to 9176 XUNGCPRO (elt);
9156 modify the alist while it executes. */ 9177 return XCDR (elt);
9157 RETURN_UNGCPRO (XCDR (elt));
9158 } 9178 }
9159 } 9179 }
9180 END_GC_EXTERNAL_LIST_LOOP (elt);
9160 } 9181 }
9182
9161 if (!CONSP (tree)) 9183 if (!CONSP (tree))
9162 { 9184 {
9163 RETURN_UNGCPRO (tree); 9185 return tree;
9164 } 9186 }
9165 9187
9166 aa = sublis (alist, XCAR (tree), check_test, test_not_unboundp, test, key, 9188 aa = sublis (alist, XCAR (tree), check_test, test_not_unboundp, test, key,
9167 depth + 1); 9189 depth + 1);
9168 dd = sublis (alist, XCDR (tree), check_test, test_not_unboundp, test, key, 9190 dd = sublis (alist, XCDR (tree), check_test, test_not_unboundp, test, key,
9169 depth + 1); 9191 depth + 1);
9170 9192
9171 if (EQ (aa, XCAR (tree)) && EQ (dd, XCDR (tree))) 9193 if (EQ (aa, XCAR (tree)) && EQ (dd, XCDR (tree)))
9172 { 9194 {
9173 RETURN_UNGCPRO (tree); 9195 return tree;
9174 } 9196 }
9175 9197
9176 RETURN_UNGCPRO (Fcons (aa, dd)); 9198 return Fcons (aa, dd);
9177 } 9199 }
9178 9200
9179 DEFUN ("sublis", Fsublis, 2, MANY, 0, /* 9201 DEFUN ("sublis", Fsublis, 2, MANY, 0, /*
9180 Perform substitutions indicated by ALIST in TREE (non-destructively). 9202 Perform substitutions indicated by ALIST in TREE (non-destructively).
9181 Return a copy of TREE with all matching elements replaced. 9203 Return a copy of TREE with all matching elements replaced.
9221 nsublis (Lisp_Object alist, Lisp_Object tree, 9243 nsublis (Lisp_Object alist, Lisp_Object tree,
9222 check_test_func_t check_test, 9244 check_test_func_t check_test,
9223 Boolint test_not_unboundp, 9245 Boolint test_not_unboundp,
9224 Lisp_Object test, Lisp_Object key, int depth) 9246 Lisp_Object test, Lisp_Object key, int depth)
9225 { 9247 {
9226 Lisp_Object tree_saved = tree, tailed = alist, tortoise = tree, keyed = Qnil; 9248 Lisp_Object tree_saved = tree, tortoise = tree, keyed = Qnil;
9227 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 9249 struct gcpro gcpro1, gcpro2;
9228 int count = 0; 9250 int count = 0;
9229 9251
9230 if (depth + lisp_eval_depth > max_lisp_eval_depth) 9252 if (depth + lisp_eval_depth > max_lisp_eval_depth)
9231 { 9253 {
9232 stack_overflow ("Stack overflow in nsublis", tree); 9254 stack_overflow ("Stack overflow in nsublis", tree);
9233 } 9255 }
9234 9256
9235 GCPRO4 (tailed, alist, tree_saved, keyed); 9257 GCPRO2 (tree_saved, keyed);
9236 9258
9237 while (CONSP (tree)) 9259 while (CONSP (tree))
9238 { 9260 {
9239 Boolint replaced = 0; 9261 Boolint replaced = 0;
9240 keyed = KEY (key, XCAR (tree)); 9262 keyed = KEY (key, XCAR (tree));
9241 9263
9242 { 9264 {
9243 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) 9265 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
9244 { 9266 {
9245 tailed = tail; 9267 if (CONSP (elt) &&
9246 9268 check_test (test, key, XCAR (elt), keyed) == test_not_unboundp)
9247 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9248 { 9269 {
9249 CHECK_LISP_WRITEABLE (tree); 9270 CHECK_LISP_WRITEABLE (tree);
9250 /* See comment in sublis() on using elt_cdr. */ 9271 /* See comment in sublis() on using elt_cdr. */
9251 XSETCAR (tree, XCDR (elt)); 9272 XSETCAR (tree, XCDR (elt));
9252 replaced = 1; 9273 replaced = 1;
9253 break; 9274 break;
9254 } 9275 }
9255 } 9276 }
9277 END_GC_EXTERNAL_LIST_LOOP (elt);
9256 } 9278 }
9257 9279
9258 if (!replaced) 9280 if (!replaced)
9259 { 9281 {
9260 if (CONSP (XCAR (tree))) 9282 if (CONSP (XCAR (tree)))
9266 9288
9267 keyed = KEY (key, XCDR (tree)); 9289 keyed = KEY (key, XCDR (tree));
9268 replaced = 0; 9290 replaced = 0;
9269 9291
9270 { 9292 {
9271 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) 9293 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
9272 { 9294 {
9273 tailed = tail; 9295 if (CONSP (elt) &&
9274 9296 check_test (test, key, XCAR (elt), keyed) == test_not_unboundp)
9275 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9276 { 9297 {
9277 CHECK_LISP_WRITEABLE (tree); 9298 CHECK_LISP_WRITEABLE (tree);
9278 /* See comment in sublis() on using elt_cdr. */
9279 XSETCDR (tree, XCDR (elt)); 9299 XSETCDR (tree, XCDR (elt));
9280 tree = Qnil; 9300 tree = Qnil;
9281 break; 9301 break;
9282 } 9302 }
9283 } 9303 }
9304 END_GC_EXTERNAL_LIST_LOOP (elt);
9284 } 9305 }
9285 9306
9286 if (!NILP (tree)) 9307 if (!NILP (tree))
9287 { 9308 {
9288 tree = XCDR (tree); 9309 tree = XCDR (tree);
9339 keyed = KEY (key, tree); 9360 keyed = KEY (key, tree);
9340 9361
9341 { 9362 {
9342 /* nsublis() won't attempt to replace a cons handed to it, do that 9363 /* nsublis() won't attempt to replace a cons handed to it, do that
9343 ourselves. */ 9364 ourselves. */
9344 EXTERNAL_ALIST_LOOP_5 (elt, elt_car, elt_cdr, alist, tail) 9365 GC_EXTERNAL_LIST_LOOP_2 (elt, alist)
9345 { 9366 {
9346 tailed = tail; 9367 if (CONSP (elt) &&
9347 9368 check_test (test, key, XCAR (elt), keyed) == test_not_unboundp)
9348 if (check_test (test, key, elt_car, keyed) == test_not_unboundp)
9349 { 9369 {
9350 /* See comment in sublis() on using elt_cdr. */ 9370 XUNGCPRO (elt);
9351 RETURN_UNGCPRO (XCDR (elt)); 9371 return XCDR (elt);
9352 } 9372 }
9353 } 9373 }
9374 END_GC_EXTERNAL_LIST_LOOP (elt);
9354 } 9375 }
9355 9376
9356 UNGCPRO; 9377 UNGCPRO;
9357 9378
9358 return nsublis (alist, tree, check_test, test_not_unboundp, test, key, 0); 9379 return nsublis (alist, tree, check_test, test_not_unboundp, test, key, 0);
10519 /* These two functions do set operations, those that can be visualised with 10540 /* These two functions do set operations, those that can be visualised with
10520 Venn diagrams. */ 10541 Venn diagrams. */
10521 static Lisp_Object 10542 static Lisp_Object
10522 venn (Lisp_Object caller, int nargs, Lisp_Object *args, Boolint intersectionp) 10543 venn (Lisp_Object caller, int nargs, Lisp_Object *args, Boolint intersectionp)
10523 { 10544 {
10524 Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil; 10545 Lisp_Object liszt1 = args[0], liszt2 = args[1];
10525 Lisp_Object result = EQ (caller, Qsubsetp) ? Qt : Qnil, result_tail = Qnil; 10546 Lisp_Object result = EQ (caller, Qsubsetp) ? Qt : Qnil, result_tail = Qnil;
10526 Lisp_Object keyed = Qnil, ignore = Qnil; 10547 Lisp_Object keyed = Qnil, ignore = Qnil;
10527 Elemcount len;
10528 Boolint test_not_unboundp = 1; 10548 Boolint test_not_unboundp = 1;
10529 check_test_func_t check_test = NULL; 10549 check_test_func_t check_test = NULL;
10530 struct gcpro gcpro1, gcpro2, gcpro3; 10550 struct gcpro gcpro1, gcpro2;
10531 10551
10532 PARSE_KEYWORDS_8 (caller, nargs, args, 4, (test, key, test_not, stable), 10552 PARSE_KEYWORDS_8 (caller, nargs, args, 4, (test, key, test_not, stable),
10533 NULL, 2, 0); 10553 NULL, 2, 0);
10534 10554
10535 CHECK_LIST (liszt1); 10555 CHECK_LIST (liszt1);
10548 } 10568 }
10549 10569
10550 get_check_match_function (&test, test_not, Qnil, Qnil, key, 10570 get_check_match_function (&test, test_not, Qnil, Qnil, key,
10551 &test_not_unboundp, &check_test); 10571 &test_not_unboundp, &check_test);
10552 10572
10553 GCPRO3 (tail, keyed, result); 10573 GCPRO2 (keyed, result);
10554 10574
10555 { 10575 {
10556 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) 10576 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1)
10557 { 10577 {
10558 keyed = KEY (key, elt); 10578 keyed = KEY (key, elt);
10559 if (NILP (list_position_cons_before (&ignore, keyed, liszt2, 10579 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10560 check_test, test_not_unboundp, 10580 check_test, test_not_unboundp,
10561 test, key, 0, Qzero, Qnil)) 10581 test, key, 0, Qzero, Qnil))
10579 XSETCDR (result_tail, Fcons (elt, Qnil)); 10599 XSETCDR (result_tail, Fcons (elt, Qnil));
10580 result_tail = XCDR (result_tail); 10600 result_tail = XCDR (result_tail);
10581 } 10601 }
10582 } 10602 }
10583 } 10603 }
10604 END_GC_EXTERNAL_LIST_LOOP (elt);
10584 } 10605 }
10585 10606
10586 UNGCPRO; 10607 UNGCPRO;
10587 10608
10588 return result; 10609 return result;
10594 Lisp_Object liszt1 = args[0], liszt2 = args[1], tortoise_elt, ignore = Qnil; 10615 Lisp_Object liszt1 = args[0], liszt2 = args[1], tortoise_elt, ignore = Qnil;
10595 Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, prev_tail = Qnil; 10616 Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, prev_tail = Qnil;
10596 Elemcount count; 10617 Elemcount count;
10597 Boolint test_not_unboundp = 1; 10618 Boolint test_not_unboundp = 1;
10598 check_test_func_t check_test = NULL; 10619 check_test_func_t check_test = NULL;
10599 struct gcpro gcpro1, gcpro2, gcpro3; 10620 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
10600 10621
10601 PARSE_KEYWORDS_8 (caller, nargs, args, 3, (test, key, test_not), 10622 PARSE_KEYWORDS_8 (caller, nargs, args, 3, (test, key, test_not),
10602 NULL, 2, 0); 10623 NULL, 2, 0);
10603 10624
10604 CHECK_LIST (liszt1); 10625 CHECK_LIST (liszt1);
10617 } 10638 }
10618 10639
10619 get_check_match_function (&test, test_not, Qnil, Qnil, key, 10640 get_check_match_function (&test, test_not, Qnil, Qnil, key,
10620 &test_not_unboundp, &check_test); 10641 &test_not_unboundp, &check_test);
10621 10642
10622 GCPRO3 (tail, keyed, liszt1); 10643 tortoise_elt = tail = liszt1, count = 0;
10623 10644
10624 tortoise_elt = tail = liszt1, count = 0; 10645 GCPRO4 (tail, keyed, liszt1, tortoise_elt);
10625 10646
10626 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 : 10647 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 :
10627 (signal_malformed_list_error (liszt1), 0)) 10648 (signal_malformed_list_error (liszt1), 0))
10628 { 10649 {
10629 keyed = KEY (key, elt); 10650 keyed = KEY (key, elt);
10791 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE) 10812 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE)
10792 */ 10813 */
10793 (int nargs, Lisp_Object *args)) 10814 (int nargs, Lisp_Object *args))
10794 { 10815 {
10795 Lisp_Object liszt1 = args[0], liszt2 = args[1], ignore = Qnil; 10816 Lisp_Object liszt1 = args[0], liszt2 = args[1], ignore = Qnil;
10796 Lisp_Object elt = Qnil, tail = Qnil, keyed = Qnil, result, result_tail; 10817 Lisp_Object keyed = Qnil, result, result_tail;
10797 Elemcount len;
10798 Boolint test_not_unboundp = 1; 10818 Boolint test_not_unboundp = 1;
10799 check_test_func_t check_test = NULL, check_match = NULL; 10819 check_test_func_t check_test = NULL, check_match = NULL;
10800 struct gcpro gcpro1, gcpro2, gcpro3; 10820 struct gcpro gcpro1, gcpro2;
10801 10821
10802 PARSE_KEYWORDS (Funion, nargs, args, 4, (test, key, test_not, stable), NULL); 10822 PARSE_KEYWORDS (Funion, nargs, args, 4, (test, key, test_not, stable), NULL);
10803 10823
10804 CHECK_LIST (liszt1); 10824 CHECK_LIST (liszt1);
10805 CHECK_LIST (liszt2); 10825 CHECK_LIST (liszt2);
10817 } 10837 }
10818 10838
10819 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, 10839 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10820 &test_not_unboundp, &check_test); 10840 &test_not_unboundp, &check_test);
10821 10841
10822 GCPRO3 (tail, keyed, result); 10842 GCPRO2 (keyed, result);
10823 10843
10824 if (NILP (stable)) 10844 if (NILP (stable))
10825 { 10845 {
10826 result = liszt2; 10846 result = liszt2;
10827 { 10847 {
10828 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) 10848 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1)
10829 { 10849 {
10830 keyed = KEY (key, elt); 10850 keyed = KEY (key, elt);
10831 if (NILP (list_position_cons_before (&ignore, keyed, liszt2, 10851 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10832 check_test, test_not_unboundp, 10852 check_test, test_not_unboundp,
10833 test, key, 0, Qzero, Qnil))) 10853 test, key, 0, Qzero, Qnil)))
10841 is called an awful lot more, so it's a space win but not 10861 is called an awful lot more, so it's a space win but not
10842 a time win. */ 10862 a time win. */
10843 result = Fcons (elt, result); 10863 result = Fcons (elt, result);
10844 } 10864 }
10845 } 10865 }
10866 END_GC_EXTERNAL_LIST_LOOP (elt);
10846 } 10867 }
10847 } 10868 }
10848 else 10869 else
10849 { 10870 {
10850 result = result_tail = Qnil; 10871 result = result_tail = Qnil;
10854 the values in backwards order. According to the CLTL2 10875 the values in backwards order. According to the CLTL2
10855 documentation, `union' is not required to preserve the ordering of 10876 documentation, `union' is not required to preserve the ordering of
10856 elements in any fashion; providing the functionality for a stable 10877 elements in any fashion; providing the functionality for a stable
10857 union is an XEmacs extension. */ 10878 union is an XEmacs extension. */
10858 { 10879 {
10859 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len) 10880 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt2)
10860 { 10881 {
10861 if (NILP (list_position_cons_before (&ignore, elt, liszt1, 10882 if (NILP (list_position_cons_before (&ignore, elt, liszt1,
10862 check_match, test_not_unboundp, 10883 check_match, test_not_unboundp,
10863 test, key, 1, Qzero, Qnil))) 10884 test, key, 1, Qzero, Qnil)))
10864 { 10885 {
10871 XSETCDR (result_tail, Fcons (elt, Qnil)); 10892 XSETCDR (result_tail, Fcons (elt, Qnil));
10872 result_tail = XCDR (result_tail); 10893 result_tail = XCDR (result_tail);
10873 } 10894 }
10874 } 10895 }
10875 } 10896 }
10897 END_GC_EXTERNAL_LIST_LOOP (elt);
10876 } 10898 }
10877 10899
10878 result = NILP (result) ? liszt1 : nconc2 (Fcopy_list (liszt1), result); 10900 result = NILP (result) ? liszt1 : nconc2 (Fcopy_list (liszt1), result);
10879 } 10901 }
10880 10902
10898 10920
10899 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE) 10921 arguments: (LIST1 LIST2 &key (TEST #'eql) (KEY #'identity) TEST-NOT STABLE)
10900 */ 10922 */
10901 (int nargs, Lisp_Object *args)) 10923 (int nargs, Lisp_Object *args))
10902 { 10924 {
10903 Lisp_Object liszt1 = args[0], liszt2 = args[1], elt = Qnil, tail = Qnil; 10925 Lisp_Object liszt1 = args[0], liszt2 = args[1];
10904 Lisp_Object result = Qnil, result_tail = Qnil, keyed = Qnil, ignore = Qnil; 10926 Lisp_Object result = Qnil, result_tail = Qnil, keyed = Qnil, ignore = Qnil;
10905 Elemcount len;
10906 Boolint test_not_unboundp = 1; 10927 Boolint test_not_unboundp = 1;
10907 check_test_func_t check_match = NULL, check_test = NULL; 10928 check_test_func_t check_match = NULL, check_test = NULL;
10908 struct gcpro gcpro1, gcpro2, gcpro3; 10929 struct gcpro gcpro1, gcpro2;
10909 10930
10910 PARSE_KEYWORDS (Fset_exclusive_or, nargs, args, 4, 10931 PARSE_KEYWORDS (Fset_exclusive_or, nargs, args, 4,
10911 (test, key, test_not, stable), NULL); 10932 (test, key, test_not, stable), NULL);
10912 10933
10913 CHECK_LIST (liszt1); 10934 CHECK_LIST (liszt1);
10921 } 10942 }
10922 10943
10923 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, 10944 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
10924 &test_not_unboundp, &check_test); 10945 &test_not_unboundp, &check_test);
10925 10946
10926 GCPRO3 (tail, keyed, result); 10947 GCPRO2 (keyed, result);
10927 { 10948 {
10928 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt1, tail, len) 10949 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt1)
10929 { 10950 {
10930 keyed = KEY (key, elt); 10951 keyed = KEY (key, elt);
10931 if (NILP (list_position_cons_before (&ignore, keyed, liszt2, 10952 if (NILP (list_position_cons_before (&ignore, keyed, liszt2,
10932 check_test, test_not_unboundp, 10953 check_test, test_not_unboundp,
10933 test, key, 0, Qzero, Qnil))) 10954 test, key, 0, Qzero, Qnil)))
10945 XSETCDR (result_tail, Fcons (elt, Qnil)); 10966 XSETCDR (result_tail, Fcons (elt, Qnil));
10946 result_tail = XCDR (result_tail); 10967 result_tail = XCDR (result_tail);
10947 } 10968 }
10948 } 10969 }
10949 } 10970 }
10971 END_GC_EXTERNAL_LIST_LOOP (elt);
10950 } 10972 }
10951 10973
10952 { 10974 {
10953 EXTERNAL_LIST_LOOP_4_NO_DECLARE (elt, liszt2, tail, len) 10975 GC_EXTERNAL_LIST_LOOP_2 (elt, liszt2)
10954 { 10976 {
10955 if (NILP (list_position_cons_before (&ignore, elt, liszt1, 10977 if (NILP (list_position_cons_before (&ignore, elt, liszt1,
10956 check_match, test_not_unboundp, 10978 check_match, test_not_unboundp,
10957 test, key, 1, Qzero, Qnil))) 10979 test, key, 1, Qzero, Qnil)))
10958 { 10980 {
10969 XSETCDR (result_tail, Fcons (elt, Qnil)); 10991 XSETCDR (result_tail, Fcons (elt, Qnil));
10970 result_tail = XCDR (result_tail); 10992 result_tail = XCDR (result_tail);
10971 } 10993 }
10972 } 10994 }
10973 } 10995 }
10996 END_GC_EXTERNAL_LIST_LOOP (elt);
10974 } 10997 }
10998
10975 UNGCPRO; 10999 UNGCPRO;
10976 11000
10977 return result; 11001 return result;
10978 } 11002 }
10979 11003
10994 Lisp_Object result = Qnil, tortoise_elt = Qnil, keyed = Qnil, swap; 11018 Lisp_Object result = Qnil, tortoise_elt = Qnil, keyed = Qnil, swap;
10995 Lisp_Object prev_tail = Qnil, ignore = Qnil; 11019 Lisp_Object prev_tail = Qnil, ignore = Qnil;
10996 Elemcount count; 11020 Elemcount count;
10997 Boolint test_not_unboundp = 1; 11021 Boolint test_not_unboundp = 1;
10998 check_test_func_t check_match = NULL, check_test = NULL; 11022 check_test_func_t check_match = NULL, check_test = NULL;
10999 struct gcpro gcpro1, gcpro2, gcpro3; 11023 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
11000 11024
11001 PARSE_KEYWORDS (Fnset_exclusive_or, nargs, args, 4, 11025 PARSE_KEYWORDS (Fnset_exclusive_or, nargs, args, 4,
11002 (test, key, test_not, stable), NULL); 11026 (test, key, test_not, stable), NULL);
11003 11027
11004 CHECK_LIST (liszt1); 11028 CHECK_LIST (liszt1);
11012 } 11036 }
11013 11037
11014 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key, 11038 check_match = get_check_match_function (&test, test_not, Qnil, Qnil, key,
11015 &test_not_unboundp, &check_test); 11039 &test_not_unboundp, &check_test);
11016 11040
11017 GCPRO3 (tail, keyed, result);
11018
11019 tortoise_elt = tail = liszt1, count = 0; 11041 tortoise_elt = tail = liszt1, count = 0;
11042
11043 GCPRO4 (tail, keyed, result, tortoise_elt);
11020 11044
11021 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 : 11045 while (CONSP (tail) ? (elt = XCAR (tail), 1) : NILP (tail) ? 0 :
11022 (signal_malformed_list_error (liszt1), 0)) 11046 (signal_malformed_list_error (liszt1), 0))
11023 { 11047 {
11024 keyed = KEY (key, elt); 11048 keyed = KEY (key, elt);