comparison src/fns.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents d883f39b8495
children bbff43aa5eb7
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
41 #endif 41 #endif
42 #include <errno.h> 42 #include <errno.h>
43 43
44 #include "buffer.h" 44 #include "buffer.h"
45 #include "bytecode.h" 45 #include "bytecode.h"
46 #include "commands.h"
47 #include "device.h" 46 #include "device.h"
48 #include "events.h" 47 #include "events.h"
49 #include "extents.h" 48 #include "extents.h"
50 #include "frame.h" 49 #include "frame.h"
51 #include "systime.h" 50 #include "systime.h"
89 if (last != len) 88 if (last != len)
90 write_c_string ("...", printcharfun); 89 write_c_string ("...", printcharfun);
91 } 90 }
92 91
93 static int 92 static int
94 bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth) 93 bit_vector_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
95 { 94 {
96 struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (o1); 95 struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (obj1);
97 struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (o2); 96 struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (obj2);
98 97
99 return ((bit_vector_length (v1) == bit_vector_length (v2)) && 98 return ((bit_vector_length (v1) == bit_vector_length (v2)) &&
100 !memcmp (v1->bits, v2->bits, 99 !memcmp (v1->bits, v2->bits,
101 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) * 100 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) *
102 sizeof (long))); 101 sizeof (long)));
176 { 175 {
177 if (!COMPILED_FUNCTIONP (seq)) 176 if (!COMPILED_FUNCTIONP (seq))
178 return XINT (Flength (seq)); 177 return XINT (Flength (seq));
179 else 178 else
180 { 179 {
181 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (seq); 180 struct Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (seq);
182 181
183 return (b->flags.interactivep ? COMPILED_INTERACTIVE : 182 return (f->flags.interactivep ? COMPILED_INTERACTIVE :
184 b->flags.domainp ? COMPILED_DOMAIN : 183 f->flags.domainp ? COMPILED_DOMAIN :
185 COMPILED_DOC_STRING) 184 COMPILED_DOC_STRING)
186 + 1; 185 + 1;
187 } 186 }
188 } 187 }
189 188
207 retry: 206 retry:
208 if (STRINGP (sequence)) 207 if (STRINGP (sequence))
209 return make_int (XSTRING_CHAR_LENGTH (sequence)); 208 return make_int (XSTRING_CHAR_LENGTH (sequence));
210 else if (CONSP (sequence)) 209 else if (CONSP (sequence))
211 { 210 {
212 Lisp_Object tail; 211 int len;
213 int i = 0; 212 GET_EXTERNAL_LIST_LENGTH (sequence, len);
214 213 return make_int (len);
215 EXTERNAL_LIST_LOOP (tail, sequence)
216 {
217 QUIT;
218 i++;
219 }
220
221 return make_int (i);
222 } 214 }
223 else if (VECTORP (sequence)) 215 else if (VECTORP (sequence))
224 return make_int (XVECTOR_LENGTH (sequence)); 216 return make_int (XVECTOR_LENGTH (sequence));
225 else if (NILP (sequence)) 217 else if (NILP (sequence))
226 return Qzero; 218 return Qzero;
232 sequence = wrong_type_argument (Qsequencep, sequence); 224 sequence = wrong_type_argument (Qsequencep, sequence);
233 goto retry; 225 goto retry;
234 } 226 }
235 } 227 }
236 228
237 /* This does not check for quits. That is safe
238 since it must terminate. */
239
240 DEFUN ("safe-length", Fsafe_length, 1, 1, 0, /* 229 DEFUN ("safe-length", Fsafe_length, 1, 1, 0, /*
241 Return the length of a list, but avoid error or infinite loop. 230 Return the length of a list, but avoid error or infinite loop.
242 This function never gets an error. If LIST is not really a list, 231 This function never gets an error. If LIST is not really a list,
243 it returns 0. If LIST is circular, it returns a finite value 232 it returns 0. If LIST is circular, it returns a finite value
244 which is at least the number of distinct elements. 233 which is at least the number of distinct elements.
245 */ 234 */
246 (list)) 235 (list))
247 { 236 {
248 Lisp_Object halftail = list; /* Used to detect circular lists. */ 237 Lisp_Object hare, tortoise;
249 Lisp_Object tail; 238 int len;
250 int len = 0; 239
251 240 for (hare = tortoise = list, len = 0;
252 for (tail = list; CONSP (tail); tail = XCDR (tail)) 241 CONSP (hare) && (! EQ (hare, tortoise) || len == 0);
253 { 242 hare = XCDR (hare), len++)
254 if (EQ (tail, halftail) && len != 0) 243 {
255 break; 244 if (len & 1)
256 len++; 245 tortoise = XCDR (tortoise);
257 if ((len & 1) == 0)
258 halftail = XCDR (halftail);
259 } 246 }
260 247
261 return make_int (len); 248 return make_int (len);
262 } 249 }
263 250
509 (int nargs, Lisp_Object *args)) 496 (int nargs, Lisp_Object *args))
510 { 497 {
511 return concat (nargs, args, c_bit_vector, 0); 498 return concat (nargs, args, c_bit_vector, 0);
512 } 499 }
513 500
501 /* Copy a (possibly dotted) list. LIST must be a cons.
502 Can't use concat (1, &alist, c_cons, 0) - doesn't handle dotted lists. */
503 static Lisp_Object
504 copy_list (Lisp_Object list)
505 {
506 Lisp_Object list_copy = Fcons (XCAR (list), XCDR (list));
507 Lisp_Object last = list_copy;
508 Lisp_Object hare, tortoise;
509 int len;
510
511 for (tortoise = hare = XCDR (list), len = 1;
512 CONSP (hare);
513 hare = XCDR (hare), len++)
514 {
515 XCDR (last) = Fcons (XCAR (hare), XCDR (hare));
516 last = XCDR (last);
517
518 if (len < CIRCULAR_LIST_SUSPICION_LENGTH)
519 continue;
520 if (len & 1)
521 tortoise = XCDR (tortoise);
522 if (EQ (tortoise, hare))
523 signal_circular_list_error (list);
524 }
525
526 return list_copy;
527 }
528
529 DEFUN ("copy-list", Fcopy_list, 1, 1, 0, /*
530 Return a copy of list LIST, which may be a dotted list.
531 The elements of LIST are not copied; they are shared
532 with the original.
533 */
534 (list))
535 {
536 again:
537 if (NILP (list)) return list;
538 if (CONSP (list)) return copy_list (list);
539
540 list = wrong_type_argument (Qlistp, list);
541 goto again;
542 }
543
514 DEFUN ("copy-sequence", Fcopy_sequence, 1, 1, 0, /* 544 DEFUN ("copy-sequence", Fcopy_sequence, 1, 1, 0, /*
515 Return a copy of a list, vector, bit vector or string. 545 Return a copy of list, vector, bit vector or string SEQUENCE.
516 The elements of a list or vector are not copied; they are shared 546 The elements of a list or vector are not copied; they are shared
517 with the original. 547 with the original. SEQUENCE may be a dotted list.
518 */ 548 */
519 (arg)) 549 (sequence))
520 { 550 {
521 again: 551 again:
522 if (NILP (arg)) return arg; 552 if (NILP (sequence)) return sequence;
523 /* We handle conses separately because concat() is big and hairy and 553 if (CONSP (sequence)) return copy_list (sequence);
524 doesn't handle (copy-sequence '(a b . c)) and it's easier to redo this 554 if (STRINGP (sequence)) return concat (1, &sequence, c_string, 0);
525 than to fix concat() without worrying about breaking other things. 555 if (VECTORP (sequence)) return concat (1, &sequence, c_vector, 0);
526 */ 556 if (BIT_VECTORP (sequence)) return concat (1, &sequence, c_bit_vector, 0);
527 if (CONSP (arg)) 557
528 { 558 check_losing_bytecode ("copy-sequence", sequence);
529 Lisp_Object head = Fcons (XCAR (arg), XCDR (arg)); 559 sequence = wrong_type_argument (Qsequencep, sequence);
530 Lisp_Object tail = head;
531
532 for (arg = XCDR (arg); CONSP (arg); arg = XCDR (arg))
533 {
534 XCDR (tail) = Fcons (XCAR (arg), XCDR (arg));
535 tail = XCDR (tail);
536 QUIT;
537 }
538 return head;
539 }
540 if (STRINGP (arg)) return concat (1, &arg, c_string, 0);
541 if (VECTORP (arg)) return concat (1, &arg, c_vector, 0);
542 if (BIT_VECTORP (arg)) return concat (1, &arg, c_bit_vector, 0);
543
544 check_losing_bytecode ("copy-sequence", arg);
545 arg = wrong_type_argument (Qsequencep, arg);
546 goto again; 560 goto again;
547 } 561 }
548 562
549 struct merge_string_extents_struct 563 struct merge_string_extents_struct
550 { 564 {
869 Charcount ccfr, ccto; 883 Charcount ccfr, ccto;
870 Bytecount bfr, bto; 884 Bytecount bfr, bto;
871 Lisp_Object val; 885 Lisp_Object val;
872 886
873 CHECK_STRING (string); 887 CHECK_STRING (string);
874 /* Historically, FROM could not be omitted. Whatever ... */
875 CHECK_INT (from); 888 CHECK_INT (from);
876 get_string_range_char (string, from, to, &ccfr, &ccto, 889 get_string_range_char (string, from, to, &ccfr, &ccto,
877 GB_HISTORICAL_STRING_BEHAVIOR); 890 GB_HISTORICAL_STRING_BEHAVIOR);
878 bfr = charcount_to_bytecount (XSTRING_DATA (string), ccfr); 891 bfr = charcount_to_bytecount (XSTRING_DATA (string), ccfr);
879 bto = charcount_to_bytecount (XSTRING_DATA (string), ccto); 892 bto = charcount_to_bytecount (XSTRING_DATA (string), ccto);
1021 #else 1034 #else
1022 /* This is The Way Mly and Cltl2 say It Should Be. */ 1035 /* This is The Way Mly and Cltl2 say It Should Be. */
1023 args_out_of_range (sequence, n); 1036 args_out_of_range (sequence, n);
1024 #endif 1037 #endif
1025 } 1038 }
1026 else if (STRINGP (sequence) 1039 else if (STRINGP (sequence) ||
1027 || VECTORP (sequence) 1040 VECTORP (sequence) ||
1028 || BIT_VECTORP (sequence)) 1041 BIT_VECTORP (sequence))
1029 return Faref (sequence, n); 1042 return Faref (sequence, n);
1030 #ifdef LOSING_BYTECODE 1043 #ifdef LOSING_BYTECODE
1031 else if (COMPILED_FUNCTIONP (sequence)) 1044 else if (COMPILED_FUNCTIONP (sequence))
1032 { 1045 {
1033 int idx = XINT (n); 1046 int idx = XINT (n);
1036 lose: 1049 lose:
1037 args_out_of_range (sequence, n); 1050 args_out_of_range (sequence, n);
1038 } 1051 }
1039 /* Utter perversity */ 1052 /* Utter perversity */
1040 { 1053 {
1041 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (sequence); 1054 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (sequence);
1042 switch (idx) 1055 switch (idx)
1043 { 1056 {
1044 case COMPILED_ARGLIST: 1057 case COMPILED_ARGLIST:
1045 return b->arglist; 1058 return compiled_function_arglist (f);
1046 case COMPILED_BYTECODE: 1059 case COMPILED_INSTRUCTIONS:
1047 return b->bytecodes; 1060 return compiled_function_instructions (f);
1048 case COMPILED_CONSTANTS: 1061 case COMPILED_CONSTANTS:
1049 return b->constants; 1062 return compiled_function_constants (f);
1050 case COMPILED_STACK_DEPTH: 1063 case COMPILED_STACK_DEPTH:
1051 return make_int (b->maxdepth); 1064 return compiled_function_stack_depth (f);
1052 case COMPILED_DOC_STRING: 1065 case COMPILED_DOC_STRING:
1053 return compiled_function_documentation (b); 1066 return compiled_function_documentation (f);
1054 case COMPILED_DOMAIN: 1067 case COMPILED_DOMAIN:
1055 return compiled_function_domain (b); 1068 return compiled_function_domain (f);
1056 case COMPILED_INTERACTIVE: 1069 case COMPILED_INTERACTIVE:
1057 if (b->flags.interactivep) 1070 if (f->flags.interactivep)
1058 return compiled_function_interactive (b); 1071 return compiled_function_interactive (f);
1059 /* if we return nil, can't tell interactive with no args 1072 /* if we return nil, can't tell interactive with no args
1060 from noninteractive. */ 1073 from noninteractive. */
1061 goto lose; 1074 goto lose;
1062 default: 1075 default:
1063 goto lose; 1076 goto lose;
1071 sequence = wrong_type_argument (Qsequencep, sequence); 1084 sequence = wrong_type_argument (Qsequencep, sequence);
1072 goto retry; 1085 goto retry;
1073 } 1086 }
1074 } 1087 }
1075 1088
1089 DEFUN ("last", Flast, 1, 2, 0, /*
1090 Return the tail of list LIST, of length N (default 1).
1091 LIST may be a dotted list, but not a circular list.
1092 Optional argument N must be a non-negative integer.
1093 If N is zero, then the atom that terminates the list is returned.
1094 If N is greater than the length of LIST, then LIST itself is returned.
1095 */
1096 (list, n))
1097 {
1098 int int_n, count;
1099 Lisp_Object retval, tortoise, hare;
1100
1101 CHECK_LIST (list);
1102
1103 if (NILP (n))
1104 int_n = 1;
1105 else
1106 {
1107 CHECK_NATNUM (n);
1108 int_n = XINT (n);
1109 }
1110
1111 for (retval = tortoise = hare = list, count = 0;
1112 CONSP (hare);
1113 hare = XCDR (hare),
1114 (int_n-- <= 0 ? ((void) (retval = XCDR (retval))) : (void)0),
1115 count++)
1116 {
1117 if (count < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
1118
1119 if (count & 1)
1120 tortoise = XCDR (tortoise);
1121 if (EQ (hare, tortoise))
1122 signal_circular_list_error (list);
1123 }
1124
1125 return retval;
1126 }
1127
1128 DEFUN ("nbutlast", Fnbutlast, 1, 2, 0, /*
1129 Modify LIST to remove the last N (default 1) elements.
1130 If LIST has N or fewer elements, nil is returned and LIST is unmodified.
1131 */
1132 (list, n))
1133 {
1134 int int_n;
1135
1136 CHECK_LIST (list);
1137
1138 if (NILP (n))
1139 int_n = 1;
1140 else
1141 {
1142 CHECK_NATNUM (n);
1143 int_n = XINT (n);
1144 }
1145
1146 {
1147 Lisp_Object last_cons = list;
1148
1149 EXTERNAL_LIST_LOOP_1 (list)
1150 {
1151 if (int_n-- < 0)
1152 last_cons = XCDR (last_cons);
1153 }
1154
1155 if (int_n >= 0)
1156 return Qnil;
1157
1158 XCDR (last_cons) = Qnil;
1159 return list;
1160 }
1161 }
1162
1163 DEFUN ("butlast", Fbutlast, 1, 2, 0, /*
1164 Return a copy of LIST with the last N (default 1) elements removed.
1165 If LIST has N or fewer elements, nil is returned.
1166 */
1167 (list, n))
1168 {
1169 int int_n;
1170
1171 CHECK_LIST (list);
1172
1173 if (NILP (n))
1174 int_n = 1;
1175 else
1176 {
1177 CHECK_NATNUM (n);
1178 int_n = XINT (n);
1179 }
1180
1181 {
1182 Lisp_Object retval = Qnil;
1183 Lisp_Object tail = list;
1184
1185 EXTERNAL_LIST_LOOP_1 (list)
1186 {
1187 if (--int_n < 0)
1188 {
1189 retval = Fcons (XCAR (tail), retval);
1190 tail = XCDR (tail);
1191 }
1192 }
1193
1194 return Fnreverse (retval);
1195 }
1196 }
1197
1076 DEFUN ("member", Fmember, 2, 2, 0, /* 1198 DEFUN ("member", Fmember, 2, 2, 0, /*
1077 Return non-nil if ELT is an element of LIST. Comparison done with `equal'. 1199 Return non-nil if ELT is an element of LIST. Comparison done with `equal'.
1078 The value is actually the tail of LIST whose car is ELT. 1200 The value is actually the tail of LIST whose car is ELT.
1079 */ 1201 */
1080 (elt, list)) 1202 (elt, list))
1081 { 1203 {
1082 REGISTER Lisp_Object tail; 1204 Lisp_Object list_elt, tail;
1083 LIST_LOOP (tail, list) 1205 EXTERNAL_LIST_LOOP_3 (list_elt, list, tail)
1084 { 1206 {
1085 CONCHECK_CONS (tail); 1207 if (internal_equal (elt, list_elt, 0))
1086 if (internal_equal (elt, XCAR (tail), 0))
1087 return tail; 1208 return tail;
1088 QUIT;
1089 } 1209 }
1090 return Qnil; 1210 return Qnil;
1091 } 1211 }
1092 1212
1093 DEFUN ("old-member", Fold_member, 2, 2, 0, /* 1213 DEFUN ("old-member", Fold_member, 2, 2, 0, /*
1096 This function is provided only for byte-code compatibility with v19. 1216 This function is provided only for byte-code compatibility with v19.
1097 Do not use it. 1217 Do not use it.
1098 */ 1218 */
1099 (elt, list)) 1219 (elt, list))
1100 { 1220 {
1101 REGISTER Lisp_Object tail; 1221 Lisp_Object list_elt, tail;
1102 LIST_LOOP (tail, list) 1222 EXTERNAL_LIST_LOOP_3 (list_elt, list, tail)
1103 { 1223 {
1104 CONCHECK_CONS (tail); 1224 if (internal_old_equal (elt, list_elt, 0))
1105 if (internal_old_equal (elt, XCAR (tail), 0))
1106 return tail; 1225 return tail;
1107 QUIT;
1108 } 1226 }
1109 return Qnil; 1227 return Qnil;
1110 } 1228 }
1111 1229
1112 DEFUN ("memq", Fmemq, 2, 2, 0, /* 1230 DEFUN ("memq", Fmemq, 2, 2, 0, /*
1113 Return non-nil if ELT is an element of LIST. Comparison done with `eq'. 1231 Return non-nil if ELT is an element of LIST. Comparison done with `eq'.
1114 The value is actually the tail of LIST whose car is ELT. 1232 The value is actually the tail of LIST whose car is ELT.
1115 */ 1233 */
1116 (elt, list)) 1234 (elt, list))
1117 { 1235 {
1118 REGISTER Lisp_Object tail; 1236 Lisp_Object list_elt, tail;
1119 LIST_LOOP (tail, list) 1237 EXTERNAL_LIST_LOOP_3 (list_elt, list, tail)
1120 { 1238 {
1121 REGISTER Lisp_Object tem; 1239 if (EQ_WITH_EBOLA_NOTICE (elt, list_elt))
1122 CONCHECK_CONS (tail);
1123 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1124 return tail; 1240 return tail;
1125 QUIT;
1126 } 1241 }
1127 return Qnil; 1242 return Qnil;
1128 } 1243 }
1129 1244
1130 DEFUN ("old-memq", Fold_memq, 2, 2, 0, /* 1245 DEFUN ("old-memq", Fold_memq, 2, 2, 0, /*
1133 This function is provided only for byte-code compatibility with v19. 1248 This function is provided only for byte-code compatibility with v19.
1134 Do not use it. 1249 Do not use it.
1135 */ 1250 */
1136 (elt, list)) 1251 (elt, list))
1137 { 1252 {
1138 REGISTER Lisp_Object tail; 1253 Lisp_Object list_elt, tail;
1139 LIST_LOOP (tail, list) 1254 EXTERNAL_LIST_LOOP_3 (list_elt, list, tail)
1140 { 1255 {
1141 REGISTER Lisp_Object tem; 1256 if (HACKEQ_UNSAFE (elt, list_elt))
1142 CONCHECK_CONS (tail);
1143 if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem))
1144 return tail; 1257 return tail;
1145 QUIT;
1146 } 1258 }
1147 return Qnil; 1259 return Qnil;
1148 } 1260 }
1149 1261
1150 Lisp_Object 1262 Lisp_Object
1151 memq_no_quit (Lisp_Object elt, Lisp_Object list) 1263 memq_no_quit (Lisp_Object elt, Lisp_Object list)
1152 { 1264 {
1153 REGISTER Lisp_Object tail; 1265 Lisp_Object list_elt, tail;
1154 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1266 LIST_LOOP_3 (list_elt, list, tail)
1155 { 1267 {
1156 REGISTER Lisp_Object tem; 1268 if (EQ_WITH_EBOLA_NOTICE (elt, list_elt))
1157 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1158 return tail; 1269 return tail;
1159 } 1270 }
1160 return Qnil; 1271 return Qnil;
1161 } 1272 }
1162 1273
1165 The value is actually the element of LIST whose car equals KEY. 1276 The value is actually the element of LIST whose car equals KEY.
1166 */ 1277 */
1167 (key, list)) 1278 (key, list))
1168 { 1279 {
1169 /* This function can GC. */ 1280 /* This function can GC. */
1170 REGISTER Lisp_Object tail; 1281 Lisp_Object elt, elt_car, elt_cdr;
1171 LIST_LOOP (tail, list) 1282 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1172 { 1283 {
1173 REGISTER Lisp_Object elt; 1284 if (internal_equal (key, elt_car, 0))
1174 CONCHECK_CONS (tail);
1175 elt = XCAR (tail);
1176 if (CONSP (elt) && internal_equal (XCAR (elt), key, 0))
1177 return elt; 1285 return elt;
1178 QUIT;
1179 } 1286 }
1180 return Qnil; 1287 return Qnil;
1181 } 1288 }
1182 1289
1183 DEFUN ("old-assoc", Fold_assoc, 2, 2, 0, /* 1290 DEFUN ("old-assoc", Fold_assoc, 2, 2, 0, /*
1185 The value is actually the element of LIST whose car equals KEY. 1292 The value is actually the element of LIST whose car equals KEY.
1186 */ 1293 */
1187 (key, list)) 1294 (key, list))
1188 { 1295 {
1189 /* This function can GC. */ 1296 /* This function can GC. */
1190 REGISTER Lisp_Object tail; 1297 Lisp_Object elt, elt_car, elt_cdr;
1191 LIST_LOOP (tail, list) 1298 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1192 { 1299 {
1193 REGISTER Lisp_Object elt; 1300 if (internal_old_equal (key, elt_car, 0))
1194 CONCHECK_CONS (tail);
1195 elt = XCAR (tail);
1196 if (CONSP (elt) && internal_old_equal (XCAR (elt), key, 0))
1197 return elt; 1301 return elt;
1198 QUIT;
1199 } 1302 }
1200 return Qnil; 1303 return Qnil;
1201 } 1304 }
1202 1305
1203 Lisp_Object 1306 Lisp_Object
1213 The value is actually the element of LIST whose car is KEY. 1316 The value is actually the element of LIST whose car is KEY.
1214 Elements of LIST that are not conses are ignored. 1317 Elements of LIST that are not conses are ignored.
1215 */ 1318 */
1216 (key, list)) 1319 (key, list))
1217 { 1320 {
1218 REGISTER Lisp_Object tail; 1321 Lisp_Object elt, elt_car, elt_cdr;
1219 LIST_LOOP (tail, list) 1322 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1220 { 1323 {
1221 REGISTER Lisp_Object elt, tem; 1324 if (EQ_WITH_EBOLA_NOTICE (key, elt_car))
1222 CONCHECK_CONS (tail);
1223 elt = XCAR (tail);
1224 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1225 return elt; 1325 return elt;
1226 QUIT;
1227 } 1326 }
1228 return Qnil; 1327 return Qnil;
1229 } 1328 }
1230 1329
1231 DEFUN ("old-assq", Fold_assq, 2, 2, 0, /* 1330 DEFUN ("old-assq", Fold_assq, 2, 2, 0, /*
1235 This function is provided only for byte-code compatibility with v19. 1334 This function is provided only for byte-code compatibility with v19.
1236 Do not use it. 1335 Do not use it.
1237 */ 1336 */
1238 (key, list)) 1337 (key, list))
1239 { 1338 {
1240 REGISTER Lisp_Object tail; 1339 Lisp_Object elt, elt_car, elt_cdr;
1241 LIST_LOOP (tail, list) 1340 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1242 { 1341 {
1243 REGISTER Lisp_Object elt, tem; 1342 if (HACKEQ_UNSAFE (key, elt_car))
1244 CONCHECK_CONS (tail);
1245 elt = XCAR (tail);
1246 if (CONSP (elt) && (tem = XCAR (elt), HACKEQ_UNSAFE (key, tem)))
1247 return elt; 1343 return elt;
1248 QUIT;
1249 } 1344 }
1250 return Qnil; 1345 return Qnil;
1251 } 1346 }
1252 1347
1253 /* Like Fassq but never report an error and do not allow quits. 1348 /* Like Fassq but never report an error and do not allow quits.
1255 1350
1256 Lisp_Object 1351 Lisp_Object
1257 assq_no_quit (Lisp_Object key, Lisp_Object list) 1352 assq_no_quit (Lisp_Object key, Lisp_Object list)
1258 { 1353 {
1259 /* This cannot GC. */ 1354 /* This cannot GC. */
1260 REGISTER Lisp_Object tail; 1355 Lisp_Object elt;
1261 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1356 LIST_LOOP_2 (elt, list)
1262 { 1357 {
1263 REGISTER Lisp_Object tem, elt; 1358 Lisp_Object elt_car = XCAR (elt);
1264 elt = XCAR (tail); 1359 if (EQ_WITH_EBOLA_NOTICE (key, elt_car))
1265 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) 1360 return elt;
1266 return elt;
1267 } 1361 }
1268 return Qnil; 1362 return Qnil;
1269 } 1363 }
1270 1364
1271 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* 1365 DEFUN ("rassoc", Frassoc, 2, 2, 0, /*
1272 Return non-nil if KEY is `equal' to the cdr of an element of LIST. 1366 Return non-nil if KEY is `equal' to the cdr of an element of LIST.
1273 The value is actually the element of LIST whose cdr equals KEY. 1367 The value is actually the element of LIST whose cdr equals KEY.
1274 */ 1368 */
1275 (key, list)) 1369 (key, list))
1276 { 1370 {
1277 REGISTER Lisp_Object tail; 1371 Lisp_Object elt, elt_car, elt_cdr;
1278 LIST_LOOP (tail, list) 1372 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1279 { 1373 {
1280 REGISTER Lisp_Object elt; 1374 if (internal_equal (key, elt_cdr, 0))
1281 CONCHECK_CONS (tail);
1282 elt = XCAR (tail);
1283 if (CONSP (elt) && internal_equal (XCDR (elt), key, 0))
1284 return elt; 1375 return elt;
1285 QUIT;
1286 } 1376 }
1287 return Qnil; 1377 return Qnil;
1288 } 1378 }
1289 1379
1290 DEFUN ("old-rassoc", Fold_rassoc, 2, 2, 0, /* 1380 DEFUN ("old-rassoc", Fold_rassoc, 2, 2, 0, /*
1291 Return non-nil if KEY is `old-equal' to the cdr of an element of LIST. 1381 Return non-nil if KEY is `old-equal' to the cdr of an element of LIST.
1292 The value is actually the element of LIST whose cdr equals KEY. 1382 The value is actually the element of LIST whose cdr equals KEY.
1293 */ 1383 */
1294 (key, list)) 1384 (key, list))
1295 { 1385 {
1296 REGISTER Lisp_Object tail; 1386 Lisp_Object elt, elt_car, elt_cdr;
1297 LIST_LOOP (tail, list) 1387 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1298 { 1388 {
1299 REGISTER Lisp_Object elt; 1389 if (internal_old_equal (key, elt_cdr, 0))
1300 CONCHECK_CONS (tail);
1301 elt = XCAR (tail);
1302 if (CONSP (elt) && internal_old_equal (XCDR (elt), key, 0))
1303 return elt; 1390 return elt;
1304 QUIT;
1305 } 1391 }
1306 return Qnil; 1392 return Qnil;
1307 } 1393 }
1308 1394
1309 DEFUN ("rassq", Frassq, 2, 2, 0, /* 1395 DEFUN ("rassq", Frassq, 2, 2, 0, /*
1310 Return non-nil if KEY is `eq' to the cdr of an element of LIST. 1396 Return non-nil if KEY is `eq' to the cdr of an element of LIST.
1311 The value is actually the element of LIST whose cdr is KEY. 1397 The value is actually the element of LIST whose cdr is KEY.
1312 */ 1398 */
1313 (key, list)) 1399 (key, list))
1314 { 1400 {
1315 REGISTER Lisp_Object tail; 1401 Lisp_Object elt, elt_car, elt_cdr;
1316 LIST_LOOP (tail, list) 1402 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1317 { 1403 {
1318 REGISTER Lisp_Object elt, tem; 1404 if (EQ_WITH_EBOLA_NOTICE (key, elt_cdr))
1319 CONCHECK_CONS (tail);
1320 elt = XCAR (tail);
1321 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1322 return elt; 1405 return elt;
1323 QUIT;
1324 } 1406 }
1325 return Qnil; 1407 return Qnil;
1326 } 1408 }
1327 1409
1328 DEFUN ("old-rassq", Fold_rassq, 2, 2, 0, /* 1410 DEFUN ("old-rassq", Fold_rassq, 2, 2, 0, /*
1329 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST. 1411 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST.
1330 The value is actually the element of LIST whose cdr is KEY. 1412 The value is actually the element of LIST whose cdr is KEY.
1331 */ 1413 */
1332 (key, list)) 1414 (key, list))
1333 { 1415 {
1334 REGISTER Lisp_Object tail; 1416 Lisp_Object elt, elt_car, elt_cdr;
1335 LIST_LOOP (tail, list) 1417 EXTERNAL_ALIST_LOOP_4 (elt, elt_car, elt_cdr, list)
1336 { 1418 {
1337 REGISTER Lisp_Object elt, tem; 1419 if (HACKEQ_UNSAFE (key, elt_cdr))
1338 CONCHECK_CONS (tail);
1339 elt = XCAR (tail);
1340 if (CONSP (elt) && (tem = XCDR (elt), HACKEQ_UNSAFE (key, tem)))
1341 return elt; 1420 return elt;
1342 QUIT;
1343 } 1421 }
1344 return Qnil; 1422 return Qnil;
1345 } 1423 }
1346 1424
1425 /* Like Frassq, but caller must ensure that LIST is properly
1426 nil-terminated and ebola-free. */
1347 Lisp_Object 1427 Lisp_Object
1348 rassq_no_quit (Lisp_Object key, Lisp_Object list) 1428 rassq_no_quit (Lisp_Object key, Lisp_Object list)
1349 { 1429 {
1350 REGISTER Lisp_Object tail; 1430 Lisp_Object elt;
1351 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1431 LIST_LOOP_2 (elt, list)
1352 { 1432 {
1353 REGISTER Lisp_Object elt, tem; 1433 Lisp_Object elt_cdr = XCDR (elt);
1354 elt = XCAR (tail); 1434 if (EQ_WITH_EBOLA_NOTICE (key, elt_cdr))
1355 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1356 return elt; 1435 return elt;
1357 } 1436 }
1358 return Qnil; 1437 return Qnil;
1359 } 1438 }
1360 1439
1367 of changing the value of `foo'. 1446 of changing the value of `foo'.
1368 Also see: `remove'. 1447 Also see: `remove'.
1369 */ 1448 */
1370 (elt, list)) 1449 (elt, list))
1371 { 1450 {
1372 REGISTER Lisp_Object tail = list; 1451 Lisp_Object list_elt;
1373 REGISTER Lisp_Object prev = Qnil; 1452 EXTERNAL_LIST_LOOP_DELETE_IF (list_elt, list,
1374 1453 (internal_equal (elt, list_elt, 0)));
1375 while (!NILP (tail))
1376 {
1377 CONCHECK_CONS (tail);
1378 if (internal_equal (elt, XCAR (tail), 0))
1379 {
1380 if (NILP (prev))
1381 list = XCDR (tail);
1382 else
1383 XCDR (prev) = XCDR (tail);
1384 }
1385 else
1386 prev = tail;
1387 tail = XCDR (tail);
1388 QUIT;
1389 }
1390 return list; 1454 return list;
1391 } 1455 }
1392 1456
1393 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /* 1457 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /*
1394 Delete by side effect any occurrences of ELT as a member of LIST. 1458 Delete by side effect any occurrences of ELT as a member of LIST.
1397 effect; therefore, write `(setq foo (old-delete element foo))' to be sure 1461 effect; therefore, write `(setq foo (old-delete element foo))' to be sure
1398 of changing the value of `foo'. 1462 of changing the value of `foo'.
1399 */ 1463 */
1400 (elt, list)) 1464 (elt, list))
1401 { 1465 {
1402 REGISTER Lisp_Object tail = list; 1466 Lisp_Object list_elt;
1403 REGISTER Lisp_Object prev = Qnil; 1467 EXTERNAL_LIST_LOOP_DELETE_IF (list_elt, list,
1404 1468 (internal_old_equal (elt, list_elt, 0)));
1405 while (!NILP (tail))
1406 {
1407 CONCHECK_CONS (tail);
1408 if (internal_old_equal (elt, XCAR (tail), 0))
1409 {
1410 if (NILP (prev))
1411 list = XCDR (tail);
1412 else
1413 XCDR (prev) = XCDR (tail);
1414 }
1415 else
1416 prev = tail;
1417 tail = XCDR (tail);
1418 QUIT;
1419 }
1420 return list; 1469 return list;
1421 } 1470 }
1422 1471
1423 DEFUN ("delq", Fdelq, 2, 2, 0, /* 1472 DEFUN ("delq", Fdelq, 2, 2, 0, /*
1424 Delete by side effect any occurrences of ELT as a member of LIST. 1473 Delete by side effect any occurrences of ELT as a member of LIST.
1427 effect; therefore, write `(setq foo (delq element foo))' to be sure of 1476 effect; therefore, write `(setq foo (delq element foo))' to be sure of
1428 changing the value of `foo'. 1477 changing the value of `foo'.
1429 */ 1478 */
1430 (elt, list)) 1479 (elt, list))
1431 { 1480 {
1432 REGISTER Lisp_Object tail = list; 1481 Lisp_Object list_elt;
1433 REGISTER Lisp_Object prev = Qnil; 1482 EXTERNAL_LIST_LOOP_DELETE_IF (list_elt, list,
1434 1483 (EQ_WITH_EBOLA_NOTICE (elt, list_elt)));
1435 while (!NILP (tail))
1436 {
1437 REGISTER Lisp_Object tem;
1438 CONCHECK_CONS (tail);
1439 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1440 {
1441 if (NILP (prev))
1442 list = XCDR (tail);
1443 else
1444 XCDR (prev) = XCDR (tail);
1445 }
1446 else
1447 prev = tail;
1448 tail = XCDR (tail);
1449 QUIT;
1450 }
1451 return list; 1484 return list;
1452 } 1485 }
1453 1486
1454 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /* 1487 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /*
1455 Delete by side effect any occurrences of ELT as a member of LIST. 1488 Delete by side effect any occurrences of ELT as a member of LIST.
1458 effect; therefore, write `(setq foo (old-delq element foo))' to be sure of 1491 effect; therefore, write `(setq foo (old-delq element foo))' to be sure of
1459 changing the value of `foo'. 1492 changing the value of `foo'.
1460 */ 1493 */
1461 (elt, list)) 1494 (elt, list))
1462 { 1495 {
1463 REGISTER Lisp_Object tail = list; 1496 Lisp_Object list_elt;
1464 REGISTER Lisp_Object prev = Qnil; 1497 EXTERNAL_LIST_LOOP_DELETE_IF (list_elt, list,
1465 1498 (HACKEQ_UNSAFE (elt, list_elt)));
1466 while (!NILP (tail))
1467 {
1468 REGISTER Lisp_Object tem;
1469 CONCHECK_CONS (tail);
1470 if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem))
1471 {
1472 if (NILP (prev))
1473 list = XCDR (tail);
1474 else
1475 XCDR (prev) = XCDR (tail);
1476 }
1477 else
1478 prev = tail;
1479 tail = XCDR (tail);
1480 QUIT;
1481 }
1482 return list; 1499 return list;
1483 } 1500 }
1484 1501
1485 /* no quit, no errors; be careful */ 1502 /* Like Fdelq, but caller must ensure that LIST is properly
1503 nil-terminated and ebola-free. */
1486 1504
1487 Lisp_Object 1505 Lisp_Object
1488 delq_no_quit (Lisp_Object elt, Lisp_Object list) 1506 delq_no_quit (Lisp_Object elt, Lisp_Object list)
1489 { 1507 {
1490 REGISTER Lisp_Object tail = list; 1508 Lisp_Object list_elt;
1491 REGISTER Lisp_Object prev = Qnil; 1509 LIST_LOOP_DELETE_IF (list_elt, list,
1492 1510 (EQ_WITH_EBOLA_NOTICE (elt, list_elt)));
1493 while (CONSP (tail))
1494 {
1495 REGISTER Lisp_Object tem;
1496 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1497 {
1498 if (NILP (prev))
1499 list = XCDR (tail);
1500 else
1501 XCDR (prev) = XCDR (tail);
1502 }
1503 else
1504 prev = tail;
1505 tail = XCDR (tail);
1506 }
1507 return list; 1511 return list;
1508 } 1512 }
1509 1513
1510 /* Be VERY careful with this. This is like delq_no_quit() but 1514 /* Be VERY careful with this. This is like delq_no_quit() but
1511 also calls free_cons() on the removed conses. You must be SURE 1515 also calls free_cons() on the removed conses. You must be SURE
1517 Lisp_Object 1521 Lisp_Object
1518 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list) 1522 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list)
1519 { 1523 {
1520 REGISTER Lisp_Object tail = list; 1524 REGISTER Lisp_Object tail = list;
1521 REGISTER Lisp_Object prev = Qnil; 1525 REGISTER Lisp_Object prev = Qnil;
1522 struct Lisp_Cons *cons_to_free = NULL; 1526
1523 1527 while (!NILP (tail))
1524 while (CONSP (tail)) 1528 {
1525 { 1529 REGISTER Lisp_Object tem = XCAR (tail);
1526 REGISTER Lisp_Object tem; 1530 if (EQ (elt, tem))
1527 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) 1531 {
1528 { 1532 Lisp_Object cons_to_free = tail;
1529 if (NILP (prev)) 1533 if (NILP (prev))
1530 list = XCDR (tail); 1534 list = XCDR (tail);
1531 else 1535 else
1532 XCDR (prev) = XCDR (tail); 1536 XCDR (prev) = XCDR (tail);
1533 cons_to_free = XCONS (tail); 1537 tail = XCDR (tail);
1538 free_cons (XCONS (cons_to_free));
1534 } 1539 }
1535 else 1540 else
1536 prev = tail; 1541 {
1537 tail = XCDR (tail); 1542 prev = tail;
1538 if (cons_to_free) 1543 tail = XCDR (tail);
1539 {
1540 free_cons (cons_to_free);
1541 cons_to_free = NULL;
1542 } 1544 }
1543 } 1545 }
1544 return list; 1546 return list;
1545 } 1547 }
1546 1548
1551 therefore, write `(setq foo (remassoc key foo))' to be sure of changing 1553 therefore, write `(setq foo (remassoc key foo))' to be sure of changing
1552 the value of `foo'. 1554 the value of `foo'.
1553 */ 1555 */
1554 (key, list)) 1556 (key, list))
1555 { 1557 {
1556 REGISTER Lisp_Object tail = list; 1558 Lisp_Object elt;
1557 REGISTER Lisp_Object prev = Qnil; 1559 EXTERNAL_LIST_LOOP_DELETE_IF (elt, list,
1558 1560 (CONSP (elt) &&
1559 while (!NILP (tail)) 1561 internal_equal (key, XCAR (elt), 0)));
1560 {
1561 REGISTER Lisp_Object elt;
1562 CONCHECK_CONS (tail);
1563 elt = XCAR (tail);
1564 if (CONSP (elt) && internal_equal (key, XCAR (elt), 0))
1565 {
1566 if (NILP (prev))
1567 list = XCDR (tail);
1568 else
1569 XCDR (prev) = XCDR (tail);
1570 }
1571 else
1572 prev = tail;
1573 tail = XCDR (tail);
1574 QUIT;
1575 }
1576 return list; 1562 return list;
1577 } 1563 }
1578 1564
1579 Lisp_Object 1565 Lisp_Object
1580 remassoc_no_quit (Lisp_Object key, Lisp_Object list) 1566 remassoc_no_quit (Lisp_Object key, Lisp_Object list)
1591 therefore, write `(setq foo (remassq key foo))' to be sure of changing 1577 therefore, write `(setq foo (remassq key foo))' to be sure of changing
1592 the value of `foo'. 1578 the value of `foo'.
1593 */ 1579 */
1594 (key, list)) 1580 (key, list))
1595 { 1581 {
1596 REGISTER Lisp_Object tail = list; 1582 Lisp_Object elt;
1597 REGISTER Lisp_Object prev = Qnil; 1583 EXTERNAL_LIST_LOOP_DELETE_IF (elt, list,
1598 1584 (CONSP (elt) &&
1599 while (!NILP (tail)) 1585 EQ_WITH_EBOLA_NOTICE (key, XCAR (elt))));
1600 {
1601 REGISTER Lisp_Object elt, tem;
1602 CONCHECK_CONS (tail);
1603 elt = XCAR (tail);
1604 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1605 {
1606 if (NILP (prev))
1607 list = XCDR (tail);
1608 else
1609 XCDR (prev) = XCDR (tail);
1610 }
1611 else
1612 prev = tail;
1613 tail = XCDR (tail);
1614 QUIT;
1615 }
1616 return list; 1586 return list;
1617 } 1587 }
1618 1588
1619 /* no quit, no errors; be careful */ 1589 /* no quit, no errors; be careful */
1620 1590
1621 Lisp_Object 1591 Lisp_Object
1622 remassq_no_quit (Lisp_Object key, Lisp_Object list) 1592 remassq_no_quit (Lisp_Object key, Lisp_Object list)
1623 { 1593 {
1624 REGISTER Lisp_Object tail = list; 1594 Lisp_Object elt;
1625 REGISTER Lisp_Object prev = Qnil; 1595 LIST_LOOP_DELETE_IF (elt, list,
1626 1596 (CONSP (elt) &&
1627 while (CONSP (tail)) 1597 EQ_WITH_EBOLA_NOTICE (key, XCAR (elt))));
1628 {
1629 REGISTER Lisp_Object elt, tem;
1630 elt = XCAR (tail);
1631 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1632 {
1633 if (NILP (prev))
1634 list = XCDR (tail);
1635 else
1636 XCDR (prev) = XCDR (tail);
1637 }
1638 else
1639 prev = tail;
1640 tail = XCDR (tail);
1641 }
1642 return list; 1598 return list;
1643 } 1599 }
1644 1600
1645 DEFUN ("remrassoc", Fremrassoc, 2, 2, 0, /* 1601 DEFUN ("remrassoc", Fremrassoc, 2, 2, 0, /*
1646 Delete by side effect any elements of LIST whose cdr is `equal' to VALUE. 1602 Delete by side effect any elements of LIST whose cdr is `equal' to VALUE.
1649 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing 1605 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing
1650 the value of `foo'. 1606 the value of `foo'.
1651 */ 1607 */
1652 (value, list)) 1608 (value, list))
1653 { 1609 {
1654 REGISTER Lisp_Object tail = list; 1610 Lisp_Object elt;
1655 REGISTER Lisp_Object prev = Qnil; 1611 EXTERNAL_LIST_LOOP_DELETE_IF (elt, list,
1656 1612 (CONSP (elt) &&
1657 while (!NILP (tail)) 1613 internal_equal (value, XCDR (elt), 0)));
1658 {
1659 REGISTER Lisp_Object elt;
1660 CONCHECK_CONS (tail);
1661 elt = XCAR (tail);
1662 if (CONSP (elt) && internal_equal (value, XCDR (elt), 0))
1663 {
1664 if (NILP (prev))
1665 list = XCDR (tail);
1666 else
1667 XCDR (prev) = XCDR (tail);
1668 }
1669 else
1670 prev = tail;
1671 tail = XCDR (tail);
1672 QUIT;
1673 }
1674 return list; 1614 return list;
1675 } 1615 }
1676 1616
1677 DEFUN ("remrassq", Fremrassq, 2, 2, 0, /* 1617 DEFUN ("remrassq", Fremrassq, 2, 2, 0, /*
1678 Delete by side effect any elements of LIST whose cdr is `eq' to VALUE. 1618 Delete by side effect any elements of LIST whose cdr is `eq' to VALUE.
1681 therefore, write `(setq foo (remrassq value foo))' to be sure of changing 1621 therefore, write `(setq foo (remrassq value foo))' to be sure of changing
1682 the value of `foo'. 1622 the value of `foo'.
1683 */ 1623 */
1684 (value, list)) 1624 (value, list))
1685 { 1625 {
1686 REGISTER Lisp_Object tail = list; 1626 Lisp_Object elt;
1687 REGISTER Lisp_Object prev = Qnil; 1627 EXTERNAL_LIST_LOOP_DELETE_IF (elt, list,
1688 1628 (CONSP (elt) &&
1689 while (!NILP (tail)) 1629 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt))));
1690 {
1691 REGISTER Lisp_Object elt, tem;
1692 CONCHECK_CONS (tail);
1693 elt = XCAR (tail);
1694 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
1695 {
1696 if (NILP (prev))
1697 list = XCDR (tail);
1698 else
1699 XCDR (prev) = XCDR (tail);
1700 }
1701 else
1702 prev = tail;
1703 tail = XCDR (tail);
1704 QUIT;
1705 }
1706 return list; 1630 return list;
1707 } 1631 }
1708 1632
1709 /* no quit, no errors; be careful */ 1633 /* Like Fremrassq, fast and unsafe; be careful */
1710
1711 Lisp_Object 1634 Lisp_Object
1712 remrassq_no_quit (Lisp_Object value, Lisp_Object list) 1635 remrassq_no_quit (Lisp_Object value, Lisp_Object list)
1713 { 1636 {
1714 REGISTER Lisp_Object tail = list; 1637 Lisp_Object elt;
1715 REGISTER Lisp_Object prev = Qnil; 1638 LIST_LOOP_DELETE_IF (elt, list,
1716 1639 (CONSP (elt) &&
1717 while (CONSP (tail)) 1640 EQ_WITH_EBOLA_NOTICE (value, XCDR (elt))));
1718 {
1719 REGISTER Lisp_Object elt, tem;
1720 elt = XCAR (tail);
1721 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
1722 {
1723 if (NILP (prev))
1724 list = XCDR (tail);
1725 else
1726 XCDR (prev) = XCDR (tail);
1727 }
1728 else
1729 prev = tail;
1730 tail = XCDR (tail);
1731 }
1732 return list; 1641 return list;
1733 } 1642 }
1734 1643
1735 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /* 1644 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /*
1736 Reverse LIST by destructively modifying cdr pointers. 1645 Reverse LIST by destructively modifying cdr pointers.
1746 /* We gcpro our args; see `nconc' */ 1655 /* We gcpro our args; see `nconc' */
1747 GCPRO2 (prev, tail); 1656 GCPRO2 (prev, tail);
1748 while (!NILP (tail)) 1657 while (!NILP (tail))
1749 { 1658 {
1750 REGISTER Lisp_Object next; 1659 REGISTER Lisp_Object next;
1751 QUIT;
1752 CONCHECK_CONS (tail); 1660 CONCHECK_CONS (tail);
1753 next = XCDR (tail); 1661 next = XCDR (tail);
1754 XCDR (tail) = prev; 1662 XCDR (tail) = prev;
1755 prev = tail; 1663 prev = tail;
1756 tail = next; 1664 tail = next;
1763 Reverse LIST, copying. Return the beginning of the reversed list. 1671 Reverse LIST, copying. Return the beginning of the reversed list.
1764 See also the function `nreverse', which is used more often. 1672 See also the function `nreverse', which is used more often.
1765 */ 1673 */
1766 (list)) 1674 (list))
1767 { 1675 {
1768 REGISTER Lisp_Object tail; 1676 Lisp_Object reversed_list = Qnil;
1769 Lisp_Object new = Qnil; 1677 Lisp_Object elt;
1770 1678 EXTERNAL_LIST_LOOP_2 (elt, list)
1771 for (tail = list; CONSP (tail); tail = XCDR (tail)) 1679 {
1772 { 1680 reversed_list = Fcons (elt, reversed_list);
1773 new = Fcons (XCAR (tail), new); 1681 }
1774 QUIT; 1682 return reversed_list;
1775 }
1776 if (!NILP (tail))
1777 dead_wrong_type_argument (Qlistp, tail);
1778 return new;
1779 } 1683 }
1780 1684
1781 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2, 1685 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
1782 Lisp_Object lisp_arg, 1686 Lisp_Object lisp_arg,
1783 int (*pred_fn) (Lisp_Object, Lisp_Object, 1687 int (*pred_fn) (Lisp_Object, Lisp_Object,
2079 */ 1983 */
2080 1984
2081 Lisp_Object 1985 Lisp_Object
2082 internal_plist_get (Lisp_Object plist, Lisp_Object property) 1986 internal_plist_get (Lisp_Object plist, Lisp_Object property)
2083 { 1987 {
2084 Lisp_Object tail = plist; 1988 Lisp_Object tail;
2085 1989
2086 for (; !NILP (tail); tail = XCDR (XCDR (tail))) 1990 for (tail = plist; !NILP (tail); tail = XCDR (XCDR (tail)))
2087 { 1991 {
2088 struct Lisp_Cons *c = XCONS (tail); 1992 if (EQ (XCAR (tail), property))
2089 if (EQ (c->car, property)) 1993 return XCAR (XCDR (tail));
2090 return XCAR (c->cdr);
2091 } 1994 }
2092 1995
2093 return Qunbound; 1996 return Qunbound;
2094 } 1997 }
2095 1998
2115 } 2018 }
2116 2019
2117 int 2020 int
2118 internal_remprop (Lisp_Object *plist, Lisp_Object property) 2021 internal_remprop (Lisp_Object *plist, Lisp_Object property)
2119 { 2022 {
2120 Lisp_Object tail = *plist; 2023 Lisp_Object tail, prev;
2121 2024
2122 if (NILP (tail)) 2025 for (tail = *plist, prev = Qnil;
2123 return 0; 2026 !NILP (tail);
2124
2125 if (EQ (XCAR (tail), property))
2126 {
2127 *plist = XCDR (XCDR (tail));
2128 return 1;
2129 }
2130
2131 for (tail = XCDR (tail); !NILP (XCDR (tail));
2132 tail = XCDR (XCDR (tail))) 2027 tail = XCDR (XCDR (tail)))
2133 { 2028 {
2134 struct Lisp_Cons *c = XCONS (tail); 2029 if (EQ (XCAR (tail), property))
2135 if (EQ (XCAR (c->cdr), property)) 2030 {
2136 { 2031 if (NILP (prev))
2137 c->cdr = XCDR (XCDR (c->cdr)); 2032 *plist = XCDR (XCDR (tail));
2033 else
2034 XCDR (XCDR (prev)) = XCDR (XCDR (tail));
2138 return 1; 2035 return 1;
2139 } 2036 }
2037 else
2038 prev = tail;
2140 } 2039 }
2141 2040
2142 return 0; 2041 return 0;
2143 } 2042 }
2144 2043
2209 { 2108 {
2210 int i; 2109 int i;
2211 Lisp_Object *tortsave = *tortoise; 2110 Lisp_Object *tortsave = *tortoise;
2212 2111
2213 /* Note that our "fixing" may be more brutal than necessary, 2112 /* Note that our "fixing" may be more brutal than necessary,
2214 but it's the user's own problem, not ours. if they went in and 2113 but it's the user's own problem, not ours, if they went in and
2215 manually fucked up a plist. */ 2114 manually fucked up a plist. */
2216 2115
2217 for (i = 0; i < 2; i++) 2116 for (i = 0; i < 2; i++)
2218 { 2117 {
2219 /* This is a standard iteration of a defensive-loop-checking 2118 /* This is a standard iteration of a defensive-loop-checking
2383 one of the properties on the list. 2282 one of the properties on the list.
2384 */ 2283 */
2385 (plist, prop, default_)) 2284 (plist, prop, default_))
2386 { 2285 {
2387 Lisp_Object val = external_plist_get (&plist, prop, 0, ERROR_ME); 2286 Lisp_Object val = external_plist_get (&plist, prop, 0, ERROR_ME);
2388 if (UNBOUNDP (val)) 2287 return UNBOUNDP (val) ? default_ : val;
2389 return default_;
2390 return val;
2391 } 2288 }
2392 2289
2393 DEFUN ("plist-put", Fplist_put, 3, 3, 0, /* 2290 DEFUN ("plist-put", Fplist_put, 3, 3, 0, /*
2394 Change value in PLIST of PROP to VAL. 2291 Change value in PLIST of PROP to VAL.
2395 PLIST is a property list, which is a list of the form \(PROP1 VALUE1 2292 PLIST is a property list, which is a list of the form \(PROP1 VALUE1
2421 DEFUN ("plist-member", Fplist_member, 2, 2, 0, /* 2318 DEFUN ("plist-member", Fplist_member, 2, 2, 0, /*
2422 Return t if PROP has a value specified in PLIST. 2319 Return t if PROP has a value specified in PLIST.
2423 */ 2320 */
2424 (plist, prop)) 2321 (plist, prop))
2425 { 2322 {
2426 return UNBOUNDP (Fplist_get (plist, prop, Qunbound)) ? Qnil : Qt; 2323 Lisp_Object val = Fplist_get (plist, prop, Qunbound);
2324 return UNBOUNDP (val) ? Qnil : Qt;
2427 } 2325 }
2428 2326
2429 DEFUN ("check-valid-plist", Fcheck_valid_plist, 1, 1, 0, /* 2327 DEFUN ("check-valid-plist", Fcheck_valid_plist, 1, 1, 0, /*
2430 Given a plist, signal an error if there is anything wrong with it. 2328 Given a plist, signal an error if there is anything wrong with it.
2431 This means that it's a malformed or circular plist. 2329 This means that it's a malformed or circular plist.
2510 continue; 2408 continue;
2511 } 2409 }
2512 /* external_remprop returns 1 if it removed any property. 2410 /* external_remprop returns 1 if it removed any property.
2513 We have to loop till it didn't remove anything, in case 2411 We have to loop till it didn't remove anything, in case
2514 the property occurs many times. */ 2412 the property occurs many times. */
2515 while (external_remprop (&XCDR (next), prop, 0, ERROR_ME)); 2413 while (external_remprop (&XCDR (next), prop, 0, ERROR_ME))
2414 DO_NOTHING;
2516 plist = Fcdr (next); 2415 plist = Fcdr (next);
2517 } 2416 }
2518 2417
2519 return head; 2418 return head;
2520 } 2419 }
2521 2420
2522 DEFUN ("lax-plist-get", Flax_plist_get, 2, 3, 0, /* 2421 DEFUN ("lax-plist-get", Flax_plist_get, 2, 3, 0, /*
2523 Extract a value from a lax property list. 2422 Extract a value from a lax property list.
2524 2423
2525 LAX-PLIST is a lax property list, which is a list of the form \(PROP1 2424 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2526 VALUE1 PROP2 VALUE2...), where comparions between properties is done 2425 VALUE1 PROP2 VALUE2...), where comparisons between properties is done
2527 using `equal' instead of `eq'. This function returns the value 2426 using `equal' instead of `eq'. This function returns the value
2528 corresponding to the given PROP, or DEFAULT if PROP is not one of the 2427 corresponding to the given PROP, or DEFAULT if PROP is not one of the
2529 properties on the list. 2428 properties on the list.
2530 */ 2429 */
2531 (lax_plist, prop, default_)) 2430 (lax_plist, prop, default_))
2537 } 2436 }
2538 2437
2539 DEFUN ("lax-plist-put", Flax_plist_put, 3, 3, 0, /* 2438 DEFUN ("lax-plist-put", Flax_plist_put, 3, 3, 0, /*
2540 Change value in LAX-PLIST of PROP to VAL. 2439 Change value in LAX-PLIST of PROP to VAL.
2541 LAX-PLIST is a lax property list, which is a list of the form \(PROP1 2440 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2542 VALUE1 PROP2 VALUE2...), where comparions between properties is done 2441 VALUE1 PROP2 VALUE2...), where comparisons between properties is done
2543 using `equal' instead of `eq'. PROP is usually a symbol and VAL is 2442 using `equal' instead of `eq'. PROP is usually a symbol and VAL is
2544 any object. If PROP is already a property on the list, its value is 2443 any object. If PROP is already a property on the list, its value is
2545 set to VAL, otherwise the new PROP VAL pair is added. The new plist 2444 set to VAL, otherwise the new PROP VAL pair is added. The new plist
2546 is returned; use `(setq x (lax-plist-put x prop val))' to be sure to 2445 is returned; use `(setq x (lax-plist-put x prop val))' to be sure to
2547 use the new value. The LAX-PLIST is modified by side effects. 2446 use the new value. The LAX-PLIST is modified by side effects.
2553 } 2452 }
2554 2453
2555 DEFUN ("lax-plist-remprop", Flax_plist_remprop, 2, 2, 0, /* 2454 DEFUN ("lax-plist-remprop", Flax_plist_remprop, 2, 2, 0, /*
2556 Remove from LAX-PLIST the property PROP and its value. 2455 Remove from LAX-PLIST the property PROP and its value.
2557 LAX-PLIST is a lax property list, which is a list of the form \(PROP1 2456 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2558 VALUE1 PROP2 VALUE2...), where comparions between properties is done 2457 VALUE1 PROP2 VALUE2...), where comparisons between properties is done
2559 using `equal' instead of `eq'. PROP is usually a symbol. The new 2458 using `equal' instead of `eq'. PROP is usually a symbol. The new
2560 plist is returned; use `(setq x (lax-plist-remprop x prop val))' to be 2459 plist is returned; use `(setq x (lax-plist-remprop x prop val))' to be
2561 sure to use the new value. The LAX-PLIST is modified by side effects. 2460 sure to use the new value. The LAX-PLIST is modified by side effects.
2562 */ 2461 */
2563 (lax_plist, prop)) 2462 (lax_plist, prop))
2567 } 2466 }
2568 2467
2569 DEFUN ("lax-plist-member", Flax_plist_member, 2, 2, 0, /* 2468 DEFUN ("lax-plist-member", Flax_plist_member, 2, 2, 0, /*
2570 Return t if PROP has a value specified in LAX-PLIST. 2469 Return t if PROP has a value specified in LAX-PLIST.
2571 LAX-PLIST is a lax property list, which is a list of the form \(PROP1 2470 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2572 VALUE1 PROP2 VALUE2...), where comparions between properties is done 2471 VALUE1 PROP2 VALUE2...), where comparisons between properties is done
2573 using `equal' instead of `eq'. 2472 using `equal' instead of `eq'.
2574 */ 2473 */
2575 (lax_plist, prop)) 2474 (lax_plist, prop))
2576 { 2475 {
2577 return UNBOUNDP (Flax_plist_get (lax_plist, prop, Qunbound)) ? Qnil : Qt; 2476 return UNBOUNDP (Flax_plist_get (lax_plist, prop, Qunbound)) ? Qnil : Qt;
2610 continue; 2509 continue;
2611 } 2510 }
2612 /* external_remprop returns 1 if it removed any property. 2511 /* external_remprop returns 1 if it removed any property.
2613 We have to loop till it didn't remove anything, in case 2512 We have to loop till it didn't remove anything, in case
2614 the property occurs many times. */ 2513 the property occurs many times. */
2615 while (external_remprop (&XCDR (next), prop, 1, ERROR_ME)); 2514 while (external_remprop (&XCDR (next), prop, 1, ERROR_ME))
2515 DO_NOTHING;
2616 lax_plist = Fcdr (next); 2516 lax_plist = Fcdr (next);
2617 } 2517 }
2618 2518
2619 return head; 2519 return head;
2620 } 2520 }
2731 \(which defaults to `nil'). OBJECT can be a symbol, face, extent, 2631 \(which defaults to `nil'). OBJECT can be a symbol, face, extent,
2732 or string. See also `put', `remprop', and `object-plist'. 2632 or string. See also `put', `remprop', and `object-plist'.
2733 */ 2633 */
2734 (object, propname, default_)) 2634 (object, propname, default_))
2735 { 2635 {
2736 Lisp_Object val;
2737
2738 /* Various places in emacs call Fget() and expect it not to quit, 2636 /* Various places in emacs call Fget() and expect it not to quit,
2739 so don't quit. */ 2637 so don't quit. */
2740 2638
2741 /* It's easiest to treat symbols specially because they may not 2639 /* It's easiest to treat symbols specially because they may not
2742 be an lrecord */ 2640 be an lrecord */
2743 if (SYMBOLP (object)) 2641 if (SYMBOLP (object))
2744 val = symbol_getprop (object, propname, default_); 2642 return symbol_getprop (object, propname, default_);
2745 else if (STRINGP (object)) 2643 else if (STRINGP (object))
2746 val = string_getprop (XSTRING (object), propname, default_); 2644 return string_getprop (XSTRING (object), propname, default_);
2747 else if (LRECORDP (object)) 2645 else if (LRECORDP (object))
2748 { 2646 {
2749 CONST struct lrecord_implementation 2647 CONST struct lrecord_implementation *imp
2750 *imp = XRECORD_LHEADER_IMPLEMENTATION (object); 2648 = XRECORD_LHEADER_IMPLEMENTATION (object);
2751 if (imp->getprop) 2649 if (!imp->getprop)
2752 {
2753 val = (imp->getprop) (object, propname);
2754 if (UNBOUNDP (val))
2755 val = default_;
2756 }
2757 else
2758 goto noprops; 2650 goto noprops;
2651
2652 {
2653 Lisp_Object val = (imp->getprop) (object, propname);
2654 if (UNBOUNDP (val))
2655 val = default_;
2656 return val;
2657 }
2759 } 2658 }
2760 else 2659 else
2761 { 2660 {
2762 noprops: 2661 noprops:
2763 signal_simple_error ("Object type has no properties", object); 2662 signal_simple_error ("Object type has no properties", object);
2764 } 2663 return Qnil; /* Not reached */
2765 2664 }
2766 return val;
2767 } 2665 }
2768 2666
2769 DEFUN ("put", Fput, 3, 3, 0, /* 2667 DEFUN ("put", Fput, 3, 3, 0, /*
2770 Store OBJECT's PROPNAME property with value VALUE. 2668 Store OBJECT's PROPNAME property with value VALUE.
2771 It can be retrieved with `(get OBJECT PROPNAME)'. OBJECT can be a 2669 It can be retrieved with `(get OBJECT PROPNAME)'. OBJECT can be a
2882 return Qnil; 2780 return Qnil;
2883 } 2781 }
2884 2782
2885 2783
2886 int 2784 int
2887 internal_equal (Lisp_Object o1, Lisp_Object o2, int depth) 2785 internal_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
2888 { 2786 {
2889 if (depth > 200) 2787 if (depth > 200)
2890 error ("Stack overflow in equal"); 2788 error ("Stack overflow in equal");
2891 #ifndef LRECORD_CONS 2789 #ifndef LRECORD_CONS
2892 do_cdr: 2790 do_cdr:
2893 #endif 2791 #endif
2894 QUIT; 2792 QUIT;
2895 if (EQ_WITH_EBOLA_NOTICE (o1, o2)) 2793 if (EQ_WITH_EBOLA_NOTICE (obj1, obj2))
2896 return 1; 2794 return 1;
2897 /* Note that (equal 20 20.0) should be nil */ 2795 /* Note that (equal 20 20.0) should be nil */
2898 else if (XTYPE (o1) != XTYPE (o2)) 2796 if (XTYPE (obj1) != XTYPE (obj2))
2899 return 0; 2797 return 0;
2900 #ifndef LRECORD_CONS 2798 #ifndef LRECORD_CONS
2901 else if (CONSP (o1)) 2799 if (CONSP (obj1))
2902 { 2800 {
2903 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1)) 2801 if (!internal_equal (XCAR (obj1), XCAR (obj2), depth + 1))
2904 return 0; 2802 return 0;
2905 o1 = XCDR (o1); 2803 obj1 = XCDR (obj1);
2906 o2 = XCDR (o2); 2804 obj2 = XCDR (obj2);
2907 goto do_cdr; 2805 goto do_cdr;
2908 } 2806 }
2909 #endif 2807 #endif
2910 #ifndef LRECORD_VECTOR 2808 #ifndef LRECORD_VECTOR
2911 else if (VECTORP (o1)) 2809 if (VECTORP (obj1))
2912 { 2810 {
2913 Lisp_Object *v1 = XVECTOR_DATA (o1); 2811 Lisp_Object *v1 = XVECTOR_DATA (obj1);
2914 Lisp_Object *v2 = XVECTOR_DATA (o2); 2812 Lisp_Object *v2 = XVECTOR_DATA (obj2);
2915 int len = XVECTOR_LENGTH (o1); 2813 int len = XVECTOR_LENGTH (obj1);
2916 if (len != XVECTOR_LENGTH (o2)) 2814 if (len != XVECTOR_LENGTH (obj2))
2917 return 0; 2815 return 0;
2918 while (len--) 2816 while (len--)
2919 if (!internal_equal (*v1++, *v2++, depth + 1)) 2817 if (!internal_equal (*v1++, *v2++, depth + 1))
2920 return 0; 2818 return 0;
2921 return 1; 2819 return 1;
2922 } 2820 }
2923 #endif 2821 #endif
2924 #ifndef LRECORD_STRING 2822 #ifndef LRECORD_STRING
2925 else if (STRINGP (o1)) 2823 if (STRINGP (obj1))
2926 { 2824 {
2927 Bytecount len; 2825 Bytecount len;
2928 return (((len = XSTRING_LENGTH (o1)) == XSTRING_LENGTH (o2)) && 2826 return (((len = XSTRING_LENGTH (obj1)) == XSTRING_LENGTH (obj2)) &&
2929 !memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)); 2827 !memcmp (XSTRING_DATA (obj1), XSTRING_DATA (obj2), len));
2930 } 2828 }
2931 #endif 2829 #endif
2932 else if (LRECORDP (o1)) 2830 if (LRECORDP (obj1))
2933 { 2831 {
2934 CONST struct lrecord_implementation 2832 CONST struct lrecord_implementation
2935 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (o1), 2833 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (obj1),
2936 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (o2); 2834 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (obj2);
2937 if (imp1 != imp2) 2835
2938 return 0; 2836 return (imp1 == imp2) &&
2939 else if (imp1->equal == 0)
2940 /* EQ-ness of the objects was noticed above */ 2837 /* EQ-ness of the objects was noticed above */
2941 return 0; 2838 (imp1->equal && (imp1->equal) (obj1, obj2, depth));
2942 else
2943 return (imp1->equal) (o1, o2, depth);
2944 } 2839 }
2945 2840
2946 return 0; 2841 return 0;
2947 } 2842 }
2948 2843
2950 internal_equal() (instead of internal_old_equal()). Oh well. 2845 internal_equal() (instead of internal_old_equal()). Oh well.
2951 We will get an Ebola note if there's any possibility of confusion, 2846 We will get an Ebola note if there's any possibility of confusion,
2952 but that seems unlikely. */ 2847 but that seems unlikely. */
2953 2848
2954 static int 2849 static int
2955 internal_old_equal (Lisp_Object o1, Lisp_Object o2, int depth) 2850 internal_old_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
2956 { 2851 {
2957 if (depth > 200) 2852 if (depth > 200)
2958 error ("Stack overflow in equal"); 2853 error ("Stack overflow in equal");
2959 #ifndef LRECORD_CONS 2854 #ifndef LRECORD_CONS
2960 do_cdr: 2855 do_cdr:
2961 #endif 2856 #endif
2962 QUIT; 2857 QUIT;
2963 if (HACKEQ_UNSAFE (o1, o2)) 2858 if (HACKEQ_UNSAFE (obj1, obj2))
2964 return 1; 2859 return 1;
2965 /* Note that (equal 20 20.0) should be nil */ 2860 /* Note that (equal 20 20.0) should be nil */
2966 else if (XTYPE (o1) != XTYPE (o2)) 2861 if (XTYPE (obj1) != XTYPE (obj2))
2967 return 0; 2862 return 0;
2968 #ifndef LRECORD_CONS 2863 #ifndef LRECORD_CONS
2969 else if (CONSP (o1)) 2864 if (CONSP (obj1))
2970 { 2865 {
2971 if (!internal_old_equal (XCAR (o1), XCAR (o2), depth + 1)) 2866 if (!internal_old_equal (XCAR (obj1), XCAR (obj2), depth + 1))
2972 return 0; 2867 return 0;
2973 o1 = XCDR (o1); 2868 obj1 = XCDR (obj1);
2974 o2 = XCDR (o2); 2869 obj2 = XCDR (obj2);
2975 goto do_cdr; 2870 goto do_cdr;
2976 } 2871 }
2977 #endif 2872 #endif
2978 #ifndef LRECORD_VECTOR 2873 #ifndef LRECORD_VECTOR
2979 else if (VECTORP (o1)) 2874 if (VECTORP (obj1))
2980 { 2875 {
2981 int indice; 2876 Lisp_Object *v1 = XVECTOR_DATA (obj1);
2982 int len = XVECTOR_LENGTH (o1); 2877 Lisp_Object *v2 = XVECTOR_DATA (obj2);
2983 if (len != XVECTOR_LENGTH (o2)) 2878 int len = XVECTOR_LENGTH (obj1);
2879 if (len != XVECTOR_LENGTH (obj2))
2984 return 0; 2880 return 0;
2985 for (indice = 0; indice < len; indice++) 2881 while (len--)
2986 { 2882 if (!internal_old_equal (*v1++, *v2++, depth + 1))
2987 if (!internal_old_equal (XVECTOR_DATA (o1) [indice], 2883 return 0;
2988 XVECTOR_DATA (o2) [indice],
2989 depth + 1))
2990 return 0;
2991 }
2992 return 1; 2884 return 1;
2993 } 2885 }
2994 #endif 2886 #endif
2995 #ifndef LRECORD_STRING 2887
2996 else if (STRINGP (o1)) 2888 return internal_equal (obj1, obj2, depth);
2997 {
2998 Bytecount len = XSTRING_LENGTH (o1);
2999 if (len != XSTRING_LENGTH (o2))
3000 return 0;
3001 if (memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len))
3002 return 0;
3003 return 1;
3004 }
3005 #endif
3006 else if (LRECORDP (o1))
3007 {
3008 CONST struct lrecord_implementation
3009 *imp1 = XRECORD_LHEADER_IMPLEMENTATION (o1),
3010 *imp2 = XRECORD_LHEADER_IMPLEMENTATION (o2);
3011 if (imp1 != imp2)
3012 return 0;
3013 else if (imp1->equal == 0)
3014 /* EQ-ness of the objects was noticed above */
3015 return 0;
3016 else
3017 return (imp1->equal) (o1, o2, depth);
3018 }
3019
3020 return 0;
3021 } 2889 }
3022 2890
3023 DEFUN ("equal", Fequal, 2, 2, 0, /* 2891 DEFUN ("equal", Fequal, 2, 2, 0, /*
3024 Return t if two Lisp objects have similar structure and contents. 2892 Return t if two Lisp objects have similar structure and contents.
3025 They must have the same data type. 2893 They must have the same data type.
3026 Conses are compared by comparing the cars and the cdrs. 2894 Conses are compared by comparing the cars and the cdrs.
3027 Vectors and strings are compared element by element. 2895 Vectors and strings are compared element by element.
3028 Numbers are compared by value. Symbols must match exactly. 2896 Numbers are compared by value. Symbols must match exactly.
3029 */ 2897 */
3030 (o1, o2)) 2898 (obj1, obj2))
3031 { 2899 {
3032 return internal_equal (o1, o2, 0) ? Qt : Qnil; 2900 return internal_equal (obj1, obj2, 0) ? Qt : Qnil;
3033 } 2901 }
3034 2902
3035 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /* 2903 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /*
3036 Return t if two Lisp objects have similar structure and contents. 2904 Return t if two Lisp objects have similar structure and contents.
3037 They must have the same data type. 2905 They must have the same data type.
3039 this is known as the "char-int confoundance disease." See `eq' and 2907 this is known as the "char-int confoundance disease." See `eq' and
3040 `old-eq'.) 2908 `old-eq'.)
3041 This function is provided only for byte-code compatibility with v19. 2909 This function is provided only for byte-code compatibility with v19.
3042 Do not use it. 2910 Do not use it.
3043 */ 2911 */
3044 (o1, o2)) 2912 (obj1, obj2))
3045 { 2913 {
3046 return internal_old_equal (o1, o2, 0) ? Qt : Qnil; 2914 return internal_old_equal (obj1, obj2, 0) ? Qt : Qnil;
3047 } 2915 }
3048 2916
3049 2917
3050 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /* 2918 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /*
3051 Store each element of ARRAY with ITEM. 2919 Store each element of ARRAY with ITEM.
3093 } 2961 }
3094 return array; 2962 return array;
3095 } 2963 }
3096 2964
3097 Lisp_Object 2965 Lisp_Object
3098 nconc2 (Lisp_Object s1, Lisp_Object s2) 2966 nconc2 (Lisp_Object arg1, Lisp_Object arg2)
3099 { 2967 {
3100 Lisp_Object args[2]; 2968 Lisp_Object args[2];
3101 args[0] = s1; 2969 struct gcpro gcpro1;
3102 args[1] = s2; 2970 args[0] = arg1;
3103 return Fnconc (2, args); 2971 args[1] = arg2;
2972
2973 GCPRO1 (args[0]);
2974 gcpro1.nvars = 2;
2975
2976 RETURN_UNGCPRO (bytecode_nconc2 (args));
2977 }
2978
2979 Lisp_Object
2980 bytecode_nconc2 (Lisp_Object *args)
2981 {
2982 retry:
2983
2984 if (CONSP (args[0]))
2985 {
2986 /* (setcdr (last args[0]) args[1]) */
2987 Lisp_Object tortoise, hare;
2988 int count;
2989
2990 for (hare = tortoise = args[0], count = 0;
2991 CONSP (XCDR (hare));
2992 hare = XCDR (hare), count++)
2993 {
2994 if (count < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
2995
2996 if (count & 1)
2997 tortoise = XCDR (tortoise);
2998 if (EQ (hare, tortoise))
2999 signal_circular_list_error (args[0]);
3000 }
3001 XCDR (hare) = args[1];
3002 return args[0];
3003 }
3004 else if (NILP (args[0]))
3005 {
3006 return args[1];
3007 }
3008 else
3009 {
3010 args[0] = wrong_type_argument (args[0], Qlistp);
3011 goto retry;
3012 }
3104 } 3013 }
3105 3014
3106 DEFUN ("nconc", Fnconc, 0, MANY, 0, /* 3015 DEFUN ("nconc", Fnconc, 0, MANY, 0, /*
3107 Concatenate any number of lists by altering them. 3016 Concatenate any number of lists by altering them.
3108 Only the last argument is not altered, and need not be a list. 3017 Only the last argument is not altered, and need not be a list.
3129 while (argnum < nargs) 3038 while (argnum < nargs)
3130 { 3039 {
3131 Lisp_Object val = args[argnum]; 3040 Lisp_Object val = args[argnum];
3132 if (CONSP (val)) 3041 if (CONSP (val))
3133 { 3042 {
3134 /* Found the first cons, which will be our return value. */ 3043 /* `val' is the first cons, which will be our return value. */
3135 Lisp_Object last = val; 3044 /* `last_cons' will be the cons cell to mutate. */
3045 Lisp_Object last_cons = val;
3046 Lisp_Object tortoise = val;
3136 3047
3137 for (argnum++; argnum < nargs; argnum++) 3048 for (argnum++; argnum < nargs; argnum++)
3138 { 3049 {
3139 Lisp_Object next = args[argnum]; 3050 Lisp_Object next = args[argnum];
3140 redo: 3051 retry:
3141 if (CONSP (next) || argnum == nargs -1) 3052 if (CONSP (next) || argnum == nargs -1)
3142 { 3053 {
3143 /* (setcdr (last val) next) */ 3054 /* (setcdr (last val) next) */
3144 while (CONSP (XCDR (last))) 3055 int count;
3056
3057 for (count = 0;
3058 CONSP (XCDR (last_cons));
3059 last_cons = XCDR (last_cons), count++)
3145 { 3060 {
3146 last = XCDR (last); 3061 if (count < CIRCULAR_LIST_SUSPICION_LENGTH) continue;
3147 QUIT; 3062
3063 if (count & 1)
3064 tortoise = XCDR (tortoise);
3065 if (EQ (last_cons, tortoise))
3066 signal_circular_list_error (args[argnum-1]);
3148 } 3067 }
3149 XCDR (last) = next; 3068 XCDR (last_cons) = next;
3150 } 3069 }
3151 else if (NILP (next)) 3070 else if (NILP (next))
3152 { 3071 {
3153 continue; 3072 continue;
3154 } 3073 }
3155 else 3074 else
3156 { 3075 {
3157 next = wrong_type_argument (next, Qlistp); 3076 next = wrong_type_argument (next, Qlistp);
3158 goto redo; 3077 goto retry;
3159 } 3078 }
3160 } 3079 }
3161 RETURN_UNGCPRO (val); 3080 RETURN_UNGCPRO (val);
3162 } 3081 }
3163 else if (NILP (val)) 3082 else if (NILP (val))
3769 3688
3770 /* We need to setup proper unwinding, because there is a number of 3689 /* We need to setup proper unwinding, because there is a number of
3771 ways these functions can blow up, and we don't want to have memory 3690 ways these functions can blow up, and we don't want to have memory
3772 leaks in those cases. */ 3691 leaks in those cases. */
3773 #define XMALLOC_OR_ALLOCA(ptr, len, type) do { \ 3692 #define XMALLOC_OR_ALLOCA(ptr, len, type) do { \
3774 if ((len) > MAX_ALLOCA) \ 3693 size_t XOA_len = (len); \
3694 if (XOA_len > MAX_ALLOCA) \
3775 { \ 3695 { \
3776 ptr = (type *)xmalloc ((len) * sizeof (type)); \ 3696 ptr = xnew_array (type, XOA_len); \
3777 speccount = specpdl_depth (); \
3778 record_unwind_protect (free_malloced_ptr, \ 3697 record_unwind_protect (free_malloced_ptr, \
3779 make_opaque_ptr ((void *)ptr)); \ 3698 make_opaque_ptr ((void *)ptr)); \
3780 } \ 3699 } \
3781 else \ 3700 else \
3782 ptr = alloca_array (type, len); \ 3701 ptr = alloca_array (type, XOA_len); \
3783 } while (0) 3702 } while (0)
3784 3703
3785 #define XMALLOC_UNBIND(ptr, len) do { \ 3704 #define XMALLOC_UNBIND(ptr, len, speccount) do { \
3786 if ((len) > MAX_ALLOCA) \ 3705 if ((len) > MAX_ALLOCA) \
3787 unbind_to (speccount, Qnil); \ 3706 unbind_to (speccount, Qnil); \
3788 } while (0) 3707 } while (0)
3789 3708
3790 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /* 3709 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /*
3791 Base64-encode the region between BEG and END. 3710 Base64-encode the region between BEG and END.
3792 Return the length of the encoded text. 3711 Return the length of the encoded text.
3799 Bytind encoded_length; 3718 Bytind encoded_length;
3800 Charcount allength, length; 3719 Charcount allength, length;
3801 struct buffer *buf = current_buffer; 3720 struct buffer *buf = current_buffer;
3802 Bufpos begv, zv, old_pt = BUF_PT (buf); 3721 Bufpos begv, zv, old_pt = BUF_PT (buf);
3803 Lisp_Object input; 3722 Lisp_Object input;
3804 int speccount; 3723 int speccount = specpdl_depth();
3805 3724
3806 get_buffer_range_char (buf, beg, end, &begv, &zv, 0); 3725 get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
3726 barf_if_buffer_read_only (buf, begv, zv);
3807 3727
3808 /* We need to allocate enough room for encoding the text. 3728 /* We need to allocate enough room for encoding the text.
3809 We need 33 1/3% more space, plus a newline every 76 3729 We need 33 1/3% more space, plus a newline every 76
3810 characters, and then we round up. */ 3730 characters, and then we round up. */
3811 length = zv - begv; 3731 length = zv - begv;
3823 Lstream_delete (XLSTREAM (input)); 3743 Lstream_delete (XLSTREAM (input));
3824 3744
3825 /* Now we have encoded the region, so we insert the new contents 3745 /* Now we have encoded the region, so we insert the new contents
3826 and delete the old. (Insert first in order to preserve markers.) */ 3746 and delete the old. (Insert first in order to preserve markers.) */
3827 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0); 3747 buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0);
3828 XMALLOC_UNBIND (encoded, allength); 3748 XMALLOC_UNBIND (encoded, allength, speccount);
3829 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0); 3749 buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0);
3830 3750
3831 /* Simulate FSF Emacs: if point was in the region, place it at the 3751 /* Simulate FSF Emacs: if point was in the region, place it at the
3832 beginning. */ 3752 beginning. */
3833 if (old_pt >= begv && old_pt < zv) 3753 if (old_pt >= begv && old_pt < zv)
3844 { 3764 {
3845 Charcount allength, length; 3765 Charcount allength, length;
3846 Bytind encoded_length; 3766 Bytind encoded_length;
3847 Bufbyte *encoded; 3767 Bufbyte *encoded;
3848 Lisp_Object input, result; 3768 Lisp_Object input, result;
3849 int speccount; 3769 int speccount = specpdl_depth();
3850 3770
3851 CHECK_STRING (string); 3771 CHECK_STRING (string);
3852 3772
3853 length = XSTRING_CHAR_LENGTH (string); 3773 length = XSTRING_CHAR_LENGTH (string);
3854 allength = length + length/3 + 1 + 6; 3774 allength = length + length/3 + 1 + 6;
3858 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 0); 3778 encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 0);
3859 if (encoded_length > allength) 3779 if (encoded_length > allength)
3860 abort (); 3780 abort ();
3861 Lstream_delete (XLSTREAM (input)); 3781 Lstream_delete (XLSTREAM (input));
3862 result = make_string (encoded, encoded_length); 3782 result = make_string (encoded, encoded_length);
3863 XMALLOC_UNBIND (encoded, allength); 3783 XMALLOC_UNBIND (encoded, allength, speccount);
3864 return result; 3784 return result;
3865 } 3785 }
3866 3786
3867 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /* 3787 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /*
3868 Base64-decode the region between BEG and END. 3788 Base64-decode the region between BEG and END.
3875 Bufpos begv, zv, old_pt = BUF_PT (buf); 3795 Bufpos begv, zv, old_pt = BUF_PT (buf);
3876 Bufbyte *decoded; 3796 Bufbyte *decoded;
3877 Bytind decoded_length; 3797 Bytind decoded_length;
3878 Charcount length, cc_decoded_length; 3798 Charcount length, cc_decoded_length;
3879 Lisp_Object input; 3799 Lisp_Object input;
3880 int speccount; 3800 int speccount = specpdl_depth();
3881 3801
3882 get_buffer_range_char (buf, beg, end, &begv, &zv, 0); 3802 get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
3803 barf_if_buffer_read_only (buf, begv, zv);
3804
3883 length = zv - begv; 3805 length = zv - begv;
3884 3806
3885 input = make_lisp_buffer_input_stream (buf, begv, zv, 0); 3807 input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
3886 /* We need to allocate enough room for decoding the text. */ 3808 /* We need to allocate enough room for decoding the text. */
3887 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte); 3809 XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte);
3891 Lstream_delete (XLSTREAM (input)); 3813 Lstream_delete (XLSTREAM (input));
3892 3814
3893 if (decoded_length < 0) 3815 if (decoded_length < 0)
3894 { 3816 {
3895 /* The decoding wasn't possible. */ 3817 /* The decoding wasn't possible. */
3896 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN); 3818 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount);
3897 return Qnil; 3819 return Qnil;
3898 } 3820 }
3899 3821
3900 /* Now we have decoded the region, so we insert the new contents 3822 /* Now we have decoded the region, so we insert the new contents
3901 and delete the old. (Insert first in order to preserve markers.) */ 3823 and delete the old. (Insert first in order to preserve markers.) */
3902 BUF_SET_PT (buf, begv); 3824 BUF_SET_PT (buf, begv);
3903 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0); 3825 buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0);
3904 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN); 3826 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount);
3905 buffer_delete_range (buf, begv + cc_decoded_length, 3827 buffer_delete_range (buf, begv + cc_decoded_length,
3906 zv + cc_decoded_length, 0); 3828 zv + cc_decoded_length, 0);
3907 3829
3908 /* Simulate FSF Emacs: if point was in the region, place it at the 3830 /* Simulate FSF Emacs: if point was in the region, place it at the
3909 beginning. */ 3831 beginning. */
3920 { 3842 {
3921 Bufbyte *decoded; 3843 Bufbyte *decoded;
3922 Bytind decoded_length; 3844 Bytind decoded_length;
3923 Charcount length, cc_decoded_length; 3845 Charcount length, cc_decoded_length;
3924 Lisp_Object input, result; 3846 Lisp_Object input, result;
3925 int speccount; 3847 int speccount = specpdl_depth();
3926 3848
3927 CHECK_STRING (string); 3849 CHECK_STRING (string);
3928 3850
3929 length = XSTRING_CHAR_LENGTH (string); 3851 length = XSTRING_CHAR_LENGTH (string);
3930 /* We need to allocate enough room for decoding the text. */ 3852 /* We need to allocate enough room for decoding the text. */
3937 abort (); 3859 abort ();
3938 Lstream_delete (XLSTREAM (input)); 3860 Lstream_delete (XLSTREAM (input));
3939 3861
3940 if (decoded_length < 0) 3862 if (decoded_length < 0)
3941 { 3863 {
3864 /* The decoding wasn't possible. */
3865 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount);
3942 return Qnil; 3866 return Qnil;
3943 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
3944 } 3867 }
3945 3868
3946 result = make_string (decoded, decoded_length); 3869 result = make_string (decoded, decoded_length);
3947 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN); 3870 XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN, speccount);
3948 return result; 3871 return result;
3949 } 3872 }
3950 3873
3951 Lisp_Object Qyes_or_no_p; 3874 Lisp_Object Qyes_or_no_p;
3952 3875
3966 DEFSUBR (Fstring_modified_tick); 3889 DEFSUBR (Fstring_modified_tick);
3967 DEFSUBR (Fappend); 3890 DEFSUBR (Fappend);
3968 DEFSUBR (Fconcat); 3891 DEFSUBR (Fconcat);
3969 DEFSUBR (Fvconcat); 3892 DEFSUBR (Fvconcat);
3970 DEFSUBR (Fbvconcat); 3893 DEFSUBR (Fbvconcat);
3894 DEFSUBR (Fcopy_list);
3971 DEFSUBR (Fcopy_sequence); 3895 DEFSUBR (Fcopy_sequence);
3972 DEFSUBR (Fcopy_alist); 3896 DEFSUBR (Fcopy_alist);
3973 DEFSUBR (Fcopy_tree); 3897 DEFSUBR (Fcopy_tree);
3974 DEFSUBR (Fsubstring); 3898 DEFSUBR (Fsubstring);
3975 DEFSUBR (Fsubseq); 3899 DEFSUBR (Fsubseq);
3976 DEFSUBR (Fnthcdr); 3900 DEFSUBR (Fnthcdr);
3977 DEFSUBR (Fnth); 3901 DEFSUBR (Fnth);
3978 DEFSUBR (Felt); 3902 DEFSUBR (Felt);
3903 DEFSUBR (Flast);
3904 DEFSUBR (Fbutlast);
3905 DEFSUBR (Fnbutlast);
3979 DEFSUBR (Fmember); 3906 DEFSUBR (Fmember);
3980 DEFSUBR (Fold_member); 3907 DEFSUBR (Fold_member);
3981 DEFSUBR (Fmemq); 3908 DEFSUBR (Fmemq);
3982 DEFSUBR (Fold_memq); 3909 DEFSUBR (Fold_memq);
3983 DEFSUBR (Fassoc); 3910 DEFSUBR (Fassoc);