Mercurial > hg > xemacs-beta
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); |