Mercurial > hg > xemacs-beta
comparison src/fns.c @ 272:c5d627a313b1 r21-0b34
Import from CVS: tag r21-0b34
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:28:48 +0200 |
parents | f955c73f5258 |
children | ca9a9ec9c1c1 |
comparison
equal
deleted
inserted
replaced
271:c7b7086b0a39 | 272:c5d627a313b1 |
---|---|
33 so make sure we don't use that name in this file. */ | 33 so make sure we don't use that name in this file. */ |
34 #undef vector | 34 #undef vector |
35 #define vector ***** | 35 #define vector ***** |
36 | 36 |
37 #include "lisp.h" | 37 #include "lisp.h" |
38 | |
39 #ifdef HAVE_UNISTD_H | |
40 #include <unistd.h> | |
41 #endif | |
38 | 42 |
39 #include "buffer.h" | 43 #include "buffer.h" |
40 #include "bytecode.h" | 44 #include "bytecode.h" |
41 #include "commands.h" | 45 #include "commands.h" |
42 #include "device.h" | 46 #include "device.h" |
49 #define FEATUREP_SYNTAX | 53 #define FEATUREP_SYNTAX |
50 | 54 |
51 Lisp_Object Qstring_lessp; | 55 Lisp_Object Qstring_lessp; |
52 Lisp_Object Qidentity; | 56 Lisp_Object Qidentity; |
53 | 57 |
54 static Lisp_Object mark_bit_vector (Lisp_Object, void (*) (Lisp_Object)); | 58 static int internal_old_equal (Lisp_Object, Lisp_Object, int); |
55 static void print_bit_vector (Lisp_Object, Lisp_Object, int); | |
56 static int bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth); | |
57 static unsigned long bit_vector_hash (Lisp_Object obj, int depth); | |
58 static int internal_old_equal (Lisp_Object o1, Lisp_Object o2, int depth); | |
59 | |
60 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("bit-vector", bit_vector, | |
61 mark_bit_vector, print_bit_vector, 0, | |
62 bit_vector_equal, bit_vector_hash, | |
63 struct Lisp_Bit_Vector); | |
64 | 59 |
65 static Lisp_Object | 60 static Lisp_Object |
66 mark_bit_vector (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 61 mark_bit_vector (Lisp_Object obj, void (*markobj) (Lisp_Object)) |
67 { | 62 { |
68 return Qnil; | 63 return Qnil; |
95 bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth) | 90 bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth) |
96 { | 91 { |
97 struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (o1); | 92 struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (o1); |
98 struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (o2); | 93 struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (o2); |
99 | 94 |
100 if (bit_vector_length (v1) != bit_vector_length (v2)) | 95 return ((bit_vector_length (v1) == bit_vector_length (v2)) && |
101 return 0; | 96 !memcmp (v1->bits, v2->bits, |
102 | 97 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) * |
103 return !memcmp (v1->bits, v2->bits, | 98 sizeof (long))); |
104 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) * | |
105 sizeof (long)); | |
106 } | 99 } |
107 | 100 |
108 static unsigned long | 101 static unsigned long |
109 bit_vector_hash (Lisp_Object obj, int depth) | 102 bit_vector_hash (Lisp_Object obj, int depth) |
110 { | 103 { |
113 memory_hash (v->bits, | 106 memory_hash (v->bits, |
114 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v)) * | 107 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v)) * |
115 sizeof (long))); | 108 sizeof (long))); |
116 } | 109 } |
117 | 110 |
111 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("bit-vector", bit_vector, | |
112 mark_bit_vector, print_bit_vector, 0, | |
113 bit_vector_equal, bit_vector_hash, | |
114 struct Lisp_Bit_Vector); | |
115 | |
118 DEFUN ("identity", Fidentity, 1, 1, 0, /* | 116 DEFUN ("identity", Fidentity, 1, 1, 0, /* |
119 Return the argument unchanged. | 117 Return the argument unchanged. |
120 */ | 118 */ |
121 (arg)) | 119 (arg)) |
122 { | 120 { |
134 With argument t, set the random number seed from the current time and pid. | 132 With argument t, set the random number seed from the current time and pid. |
135 */ | 133 */ |
136 (limit)) | 134 (limit)) |
137 { | 135 { |
138 EMACS_INT val; | 136 EMACS_INT val; |
139 Lisp_Object lispy_val; | |
140 unsigned long denominator; | 137 unsigned long denominator; |
141 | 138 |
142 if (EQ (limit, Qt)) | 139 if (EQ (limit, Qt)) |
143 seed_random (getpid () + time (NULL)); | 140 seed_random (getpid () + time (NULL)); |
144 if (NATNUMP (limit) && !ZEROP (limit)) | 141 if (NATNUMP (limit) && !ZEROP (limit)) |
155 val = get_random () / denominator; | 152 val = get_random () / denominator; |
156 while (val >= XINT (limit)); | 153 while (val >= XINT (limit)); |
157 } | 154 } |
158 else | 155 else |
159 val = get_random (); | 156 val = get_random (); |
160 XSETINT (lispy_val, val); | 157 |
161 return lispy_val; | 158 return make_int (val); |
162 } | 159 } |
163 | 160 |
164 /* Random data-structure functions */ | 161 /* Random data-structure functions */ |
165 | 162 |
166 #ifdef LOSING_BYTECODE | 163 #ifdef LOSING_BYTECODE |
199 } | 196 } |
200 | 197 |
201 DEFUN ("length", Flength, 1, 1, 0, /* | 198 DEFUN ("length", Flength, 1, 1, 0, /* |
202 Return the length of vector, bit vector, list or string SEQUENCE. | 199 Return the length of vector, bit vector, list or string SEQUENCE. |
203 */ | 200 */ |
204 (obj)) | 201 (sequence)) |
205 { | 202 { |
206 Lisp_Object tail; | |
207 int i; | |
208 | |
209 retry: | 203 retry: |
210 if (STRINGP (obj)) | 204 if (STRINGP (sequence)) |
211 return make_int (string_char_length (XSTRING (obj))); | 205 return make_int (XSTRING_CHAR_LENGTH (sequence)); |
212 else if (VECTORP (obj)) | 206 else if (CONSP (sequence)) |
213 return make_int (XVECTOR_LENGTH (obj)); | 207 { |
214 else if (BIT_VECTORP (obj)) | 208 Lisp_Object tail; |
215 return make_int (bit_vector_length (XBIT_VECTOR (obj))); | 209 int i = 0; |
216 else if (CONSP (obj)) | 210 |
217 { | 211 EXTERNAL_LIST_LOOP (tail, sequence) |
218 for (i = 0, tail = obj; !NILP (tail); i++) | |
219 { | 212 { |
220 QUIT; | 213 QUIT; |
221 tail = Fcdr (tail); | 214 i++; |
222 } | 215 } |
223 | 216 |
224 return make_int (i); | 217 return make_int (i); |
225 } | 218 } |
226 else if (NILP (obj)) | 219 else if (VECTORP (sequence)) |
227 { | 220 return make_int (XVECTOR_LENGTH (sequence)); |
228 return Qzero; | 221 else if (NILP (sequence)) |
229 } | 222 return Qzero; |
223 else if (BIT_VECTORP (sequence)) | |
224 return make_int (bit_vector_length (XBIT_VECTOR (sequence))); | |
230 else | 225 else |
231 { | 226 { |
232 check_losing_bytecode ("length", obj); | 227 check_losing_bytecode ("length", sequence); |
233 obj = wrong_type_argument (Qsequencep, obj); | 228 sequence = wrong_type_argument (Qsequencep, sequence); |
234 goto retry; | 229 goto retry; |
235 } | 230 } |
236 } | 231 } |
237 | 232 |
238 /* This does not check for quits. That is safe | 233 /* This does not check for quits. That is safe |
244 it returns 0. If LIST is circular, it returns a finite value | 239 it returns 0. If LIST is circular, it returns a finite value |
245 which is at least the number of distinct elements. | 240 which is at least the number of distinct elements. |
246 */ | 241 */ |
247 (list)) | 242 (list)) |
248 { | 243 { |
249 Lisp_Object tail, halftail, length; | 244 Lisp_Object halftail = list; /* Used to detect circular lists. */ |
245 Lisp_Object tail; | |
250 int len = 0; | 246 int len = 0; |
251 | 247 |
252 /* halftail is used to detect circular lists. */ | |
253 halftail = list; | |
254 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 248 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
255 { | 249 { |
256 if (EQ (tail, halftail) && len != 0) | 250 if (EQ (tail, halftail) && len != 0) |
257 break; | 251 break; |
258 len++; | 252 len++; |
259 if ((len & 1) == 0) | 253 if ((len & 1) == 0) |
260 halftail = XCDR (halftail); | 254 halftail = XCDR (halftail); |
261 } | 255 } |
262 | 256 |
263 XSETINT (length, len); | 257 return make_int (len); |
264 return length; | |
265 } | 258 } |
266 | 259 |
267 /*** string functions. ***/ | 260 /*** string functions. ***/ |
268 | 261 |
269 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /* | 262 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /* |
270 T if two strings have identical contents. | 263 Return t if two strings have identical contents. |
271 Case is significant. Text properties are ignored. | 264 Case is significant. Text properties are ignored. |
272 \(Under XEmacs, `equal' also ignores text properties and extents in | 265 \(Under XEmacs, `equal' also ignores text properties and extents in |
273 strings, but this is not the case under FSF Emacs 19. In FSF Emacs 20 | 266 strings, but this is not the case under FSF Emacs 19. In FSF Emacs 20 |
274 `equal' is the same as in XEmacs, in that respect.) | 267 `equal' is the same as in XEmacs, in that respect.) |
275 Symbols are also allowed; their print names are used instead. | 268 Symbols are also allowed; their print names are used instead. |
276 */ | 269 */ |
277 (s1, s2)) | 270 (s1, s2)) |
278 { | 271 { |
279 int len; | 272 Bytecount len; |
273 struct Lisp_String *p1, *p2; | |
280 | 274 |
281 if (SYMBOLP (s1)) | 275 if (SYMBOLP (s1)) |
282 XSETSTRING (s1, XSYMBOL (s1)->name); | 276 p1 = XSYMBOL (s1)->name; |
277 else | |
278 { | |
279 CHECK_STRING (s1); | |
280 p1 = XSTRING (s1); | |
281 } | |
282 | |
283 if (SYMBOLP (s2)) | 283 if (SYMBOLP (s2)) |
284 XSETSTRING (s2, XSYMBOL (s2)->name); | 284 p2 = XSYMBOL (s2)->name; |
285 CHECK_STRING (s1); | 285 else |
286 CHECK_STRING (s2); | 286 { |
287 | 287 CHECK_STRING (s2); |
288 len = XSTRING_LENGTH (s1); | 288 p2 = XSTRING (s2); |
289 if (len != XSTRING_LENGTH (s2) || | 289 } |
290 memcmp (XSTRING_DATA (s1), XSTRING_DATA (s2), len)) | 290 |
291 return Qnil; | 291 return (((len = string_length (p1)) == string_length (p2)) && |
292 return Qt; | 292 !memcmp (string_data (p1), string_data (p2), len)) ? Qt : Qnil; |
293 } | 293 } |
294 | 294 |
295 | 295 |
296 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /* | 296 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /* |
297 T if first arg string is less than second in lexicographic order. | 297 Return t if first arg string is less than second in lexicographic order. |
298 If I18N2 support (but not Mule support) was compiled in, ordering is | 298 If I18N2 support (but not Mule support) was compiled in, ordering is |
299 determined by the locale. (Case is significant for the default C locale.) | 299 determined by the locale. (Case is significant for the default C locale.) |
300 In all other cases, comparison is simply done on a character-by- | 300 In all other cases, comparison is simply done on a character-by- |
301 character basis using the numeric value of a character. (Note that | 301 character basis using the numeric value of a character. (Note that |
302 this may not produce particularly meaningful results under Mule if | 302 this may not produce particularly meaningful results under Mule if |
317 */ | 317 */ |
318 (s1, s2)) | 318 (s1, s2)) |
319 { | 319 { |
320 struct Lisp_String *p1, *p2; | 320 struct Lisp_String *p1, *p2; |
321 Charcount end, len2; | 321 Charcount end, len2; |
322 int i; | |
322 | 323 |
323 if (SYMBOLP (s1)) | 324 if (SYMBOLP (s1)) |
324 XSETSTRING (s1, XSYMBOL (s1)->name); | 325 p1 = XSYMBOL (s1)->name; |
326 else | |
327 { | |
328 CHECK_STRING (s1); | |
329 p1 = XSTRING (s1); | |
330 } | |
331 | |
325 if (SYMBOLP (s2)) | 332 if (SYMBOLP (s2)) |
326 XSETSTRING (s2, XSYMBOL (s2)->name); | 333 p2 = XSYMBOL (s2)->name; |
327 CHECK_STRING (s1); | 334 else |
328 CHECK_STRING (s2); | 335 { |
329 | 336 CHECK_STRING (s2); |
330 p1 = XSTRING (s1); | 337 p2 = XSTRING (s2); |
331 p2 = XSTRING (s2); | 338 } |
332 end = string_char_length (XSTRING (s1)); | 339 |
333 len2 = string_char_length (XSTRING (s2)); | 340 end = string_char_length (p1); |
341 len2 = string_char_length (p2); | |
334 if (end > len2) | 342 if (end > len2) |
335 end = len2; | 343 end = len2; |
336 | 344 |
337 { | |
338 int i; | |
339 | |
340 #if defined (I18N2) && !defined (MULE) | 345 #if defined (I18N2) && !defined (MULE) |
341 /* There is no hope of this working under Mule. Even if we converted | 346 /* There is no hope of this working under Mule. Even if we converted |
342 the data into an external format so that strcoll() processed it | 347 the data into an external format so that strcoll() processed it |
343 properly, it would still not work because strcoll() does not | 348 properly, it would still not work because strcoll() does not |
344 handle multiple locales. This is the fundamental flaw in the | 349 handle multiple locales. This is the fundamental flaw in the |
345 locale model. */ | 350 locale model. */ |
346 Bytecount bcend = charcount_to_bytecount (string_data (p1), end); | 351 Bytecount bcend = charcount_to_bytecount (string_data (p1), end); |
347 /* Compare strings using collation order of locale. */ | 352 /* Compare strings using collation order of locale. */ |
348 /* Need to be tricky to handle embedded nulls. */ | 353 /* Need to be tricky to handle embedded nulls. */ |
349 | 354 |
350 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1) | 355 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1) |
351 { | 356 { |
352 int val = strcoll ((char *) string_data (p1) + i, | 357 int val = strcoll ((char *) string_data (p1) + i, |
353 (char *) string_data (p2) + i); | 358 (char *) string_data (p2) + i); |
354 if (val < 0) | 359 if (val < 0) |
355 return Qt; | 360 return Qt; |
356 if (val > 0) | 361 if (val > 0) |
357 return Qnil; | 362 return Qnil; |
358 } | 363 } |
359 #else /* not I18N2, or MULE */ | 364 #else /* not I18N2, or MULE */ |
360 /* #### It is not really necessary to do this: We could compare | 365 /* #### It is not really necessary to do this: We could compare |
361 byte-by-byte and still get a reasonable comparison, since this | 366 byte-by-byte and still get a reasonable comparison, since this |
362 would compare characters with a charset in the same way. | 367 would compare characters with a charset in the same way. |
363 With a little rearrangement of the leading bytes, we could | 368 With a little rearrangement of the leading bytes, we could |
364 make most inter-charset comparisons work out the same, too; | 369 make most inter-charset comparisons work out the same, too; |
365 even if some don't, this is not a big deal because inter-charset | 370 even if some don't, this is not a big deal because inter-charset |
366 comparisons aren't really well-defined anyway. */ | 371 comparisons aren't really well-defined anyway. */ |
367 for (i = 0; i < end; i++) | 372 for (i = 0; i < end; i++) |
368 { | 373 { |
369 if (string_char (p1, i) != string_char (p2, i)) | 374 if (string_char (p1, i) != string_char (p2, i)) |
370 return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil; | 375 return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil; |
371 } | 376 } |
372 #endif /* not I18N2, or MULE */ | 377 #endif /* not I18N2, or MULE */ |
373 /* Can't do i < len2 because then comparison between "foo" and "foo^@" | 378 /* Can't do i < len2 because then comparison between "foo" and "foo^@" |
374 won't work right in I18N2 case */ | 379 won't work right in I18N2 case */ |
375 return end < len2 ? Qt : Qnil; | 380 return end < len2 ? Qt : Qnil; |
376 } | |
377 } | 381 } |
378 | 382 |
379 DEFUN ("string-modified-tick", Fstring_modified_tick, 1, 1, 0, /* | 383 DEFUN ("string-modified-tick", Fstring_modified_tick, 1, 1, 0, /* |
380 Return STRING's tick counter, incremented for each change to the string. | 384 Return STRING's tick counter, incremented for each change to the string. |
381 Each string has a tick counter which is incremented each time the contents | 385 Each string has a tick counter which is incremented each time the contents |
590 | 594 |
591 /* Check and coerce the arguments. */ | 595 /* Check and coerce the arguments. */ |
592 for (argnum = 0; argnum < nargs; argnum++) | 596 for (argnum = 0; argnum < nargs; argnum++) |
593 { | 597 { |
594 Lisp_Object seq = args[argnum]; | 598 Lisp_Object seq = args[argnum]; |
595 if (CONSP (seq) || NILP (seq)) | 599 if (LISTP (seq)) |
596 ; | 600 ; |
597 else if (VECTORP (seq) || STRINGP (seq) || BIT_VECTORP (seq)) | 601 else if (VECTORP (seq) || STRINGP (seq) || BIT_VECTORP (seq)) |
598 ; | 602 ; |
599 #ifdef LOSING_BYTECODE | 603 #ifdef LOSING_BYTECODE |
600 else if (COMPILED_FUNCTIONP (seq)) | 604 else if (COMPILED_FUNCTIONP (seq)) |
789 are shared, however. | 793 are shared, however. |
790 Elements of ALIST that are not conses are also shared. | 794 Elements of ALIST that are not conses are also shared. |
791 */ | 795 */ |
792 (alist)) | 796 (alist)) |
793 { | 797 { |
794 Lisp_Object tem; | 798 Lisp_Object tail; |
795 | 799 |
796 CHECK_LIST (alist); | |
797 if (NILP (alist)) | 800 if (NILP (alist)) |
798 return alist; | 801 return alist; |
802 CHECK_CONS (alist); | |
803 | |
799 alist = concat (1, &alist, c_cons, 0); | 804 alist = concat (1, &alist, c_cons, 0); |
800 for (tem = alist; CONSP (tem); tem = XCDR (tem)) | 805 for (tail = alist; CONSP (tail); tail = XCDR (tail)) |
801 { | 806 { |
802 Lisp_Object car; | 807 Lisp_Object car = XCAR (tail); |
803 car = XCAR (tem); | |
804 | 808 |
805 if (CONSP (car)) | 809 if (CONSP (car)) |
806 XCAR (tem) = Fcons (XCAR (car), XCDR (car)); | 810 XCAR (tail) = Fcons (XCAR (car), XCDR (car)); |
807 } | 811 } |
808 return alist; | 812 return alist; |
809 } | 813 } |
810 | 814 |
811 DEFUN ("copy-tree", Fcopy_tree, 1, 2, 0, /* | 815 DEFUN ("copy-tree", Fcopy_tree, 1, 2, 0, /* |
887 int len, f, t; | 891 int len, f, t; |
888 | 892 |
889 if (STRINGP (seq)) | 893 if (STRINGP (seq)) |
890 return Fsubstring (seq, from, to); | 894 return Fsubstring (seq, from, to); |
891 | 895 |
892 if (CONSP (seq) || NILP (seq)) | 896 if (!LISTP (seq) && !VECTORP (seq) && !BIT_VECTORP (seq)) |
893 ; | |
894 else if (VECTORP (seq) || BIT_VECTORP (seq)) | |
895 ; | |
896 else | |
897 { | 897 { |
898 check_losing_bytecode ("subseq", seq); | 898 check_losing_bytecode ("subseq", seq); |
899 seq = wrong_type_argument (Qsequencep, seq); | 899 seq = wrong_type_argument (Qsequencep, seq); |
900 } | 900 } |
901 | 901 |
957 } | 957 } |
958 } | 958 } |
959 | 959 |
960 | 960 |
961 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /* | 961 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /* |
962 Take cdr N times on LIST, returns the result. | 962 Take cdr N times on LIST, and return the result. |
963 */ | 963 */ |
964 (n, list)) | 964 (n, list)) |
965 { | 965 { |
966 REGISTER int i, num; | 966 REGISTER int i; |
967 CHECK_INT (n); | 967 CHECK_NATNUM (n); |
968 num = XINT (n); | 968 for (i = XINT (n); i; i--) |
969 for (i = 0; i < num && !NILP (list); i++) | 969 { |
970 { | 970 if (NILP (list)) |
971 return list; | |
972 CHECK_CONS (list); | |
973 list = XCDR (list); | |
971 QUIT; | 974 QUIT; |
972 list = Fcdr (list); | |
973 } | 975 } |
974 return list; | 976 return list; |
975 } | 977 } |
976 | 978 |
977 DEFUN ("nth", Fnth, 2, 2, 0, /* | 979 DEFUN ("nth", Fnth, 2, 2, 0, /* |
984 } | 986 } |
985 | 987 |
986 DEFUN ("elt", Felt, 2, 2, 0, /* | 988 DEFUN ("elt", Felt, 2, 2, 0, /* |
987 Return element of SEQUENCE at index N. | 989 Return element of SEQUENCE at index N. |
988 */ | 990 */ |
989 (seq, n)) | 991 (sequence, n)) |
990 { | 992 { |
991 retry: | 993 retry: |
992 CHECK_INT_COERCE_CHAR (n); /* yuck! */ | 994 CHECK_INT_COERCE_CHAR (n); /* yuck! */ |
993 if (CONSP (seq) || NILP (seq)) | 995 if (LISTP (sequence)) |
994 { | 996 { |
995 Lisp_Object tem = Fnthcdr (n, seq); | 997 Lisp_Object tem = Fnthcdr (n, sequence); |
996 /* #### Utterly, completely, fucking disgusting. | 998 /* #### Utterly, completely, fucking disgusting. |
997 * #### The whole point of "elt" is that it operates on | 999 * #### The whole point of "elt" is that it operates on |
998 * #### sequences, and does error- (bounds-) checking. | 1000 * #### sequences, and does error- (bounds-) checking. |
999 */ | 1001 */ |
1000 if (CONSP (tem)) | 1002 if (CONSP (tem)) |
1003 #if 1 | 1005 #if 1 |
1004 /* This is The Way It Has Always Been. */ | 1006 /* This is The Way It Has Always Been. */ |
1005 return Qnil; | 1007 return Qnil; |
1006 #else | 1008 #else |
1007 /* This is The Way Mly Says It Should Be. */ | 1009 /* This is The Way Mly Says It Should Be. */ |
1008 args_out_of_range (seq, n); | 1010 args_out_of_range (sequence, n); |
1009 #endif | 1011 #endif |
1010 } | 1012 } |
1011 else if (STRINGP (seq) | 1013 else if (STRINGP (sequence) |
1012 || VECTORP (seq) | 1014 || VECTORP (sequence) |
1013 || BIT_VECTORP (seq)) | 1015 || BIT_VECTORP (sequence)) |
1014 return Faref (seq, n); | 1016 return Faref (sequence, n); |
1015 #ifdef LOSING_BYTECODE | 1017 #ifdef LOSING_BYTECODE |
1016 else if (COMPILED_FUNCTIONP (seq)) | 1018 else if (COMPILED_FUNCTIONP (sequence)) |
1017 { | 1019 { |
1018 int idx = XINT (n); | 1020 int idx = XINT (n); |
1019 if (idx < 0) | 1021 if (idx < 0) |
1020 { | 1022 { |
1021 lose: | 1023 lose: |
1022 args_out_of_range (seq, n); | 1024 args_out_of_range (sequence, n); |
1023 } | 1025 } |
1024 /* Utter perversity */ | 1026 /* Utter perversity */ |
1025 { | 1027 { |
1026 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (seq); | 1028 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (sequence); |
1027 switch (idx) | 1029 switch (idx) |
1028 { | 1030 { |
1029 case COMPILED_ARGLIST: | 1031 case COMPILED_ARGLIST: |
1030 return b->arglist; | 1032 return b->arglist; |
1031 case COMPILED_BYTECODE: | 1033 case COMPILED_BYTECODE: |
1050 } | 1052 } |
1051 } | 1053 } |
1052 #endif /* LOSING_BYTECODE */ | 1054 #endif /* LOSING_BYTECODE */ |
1053 else | 1055 else |
1054 { | 1056 { |
1055 check_losing_bytecode ("elt", seq); | 1057 check_losing_bytecode ("elt", sequence); |
1056 seq = wrong_type_argument (Qsequencep, seq); | 1058 sequence = wrong_type_argument (Qsequencep, sequence); |
1057 goto retry; | 1059 goto retry; |
1058 } | 1060 } |
1059 } | 1061 } |
1060 | 1062 |
1061 DEFUN ("member", Fmember, 2, 2, 0, /* | 1063 DEFUN ("member", Fmember, 2, 2, 0, /* |
1062 Return non-nil if ELT is an element of LIST. Comparison done with `equal'. | 1064 Return non-nil if ELT is an element of LIST. Comparison done with `equal'. |
1063 The value is actually the tail of LIST whose car is ELT. | 1065 The value is actually the tail of LIST whose car is ELT. |
1064 */ | 1066 */ |
1065 (elt, list)) | 1067 (elt, list)) |
1066 { | 1068 { |
1067 REGISTER Lisp_Object tail, tem; | 1069 REGISTER Lisp_Object tail; |
1068 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1070 LIST_LOOP (tail, list) |
1069 { | 1071 { |
1070 tem = Fcar (tail); | 1072 CONCHECK_CONS (tail); |
1071 if (internal_equal (elt, tem, 0)) | 1073 if (internal_equal (elt, XCAR (tail), 0)) |
1072 return tail; | 1074 return tail; |
1073 QUIT; | 1075 QUIT; |
1074 } | 1076 } |
1075 return Qnil; | 1077 return Qnil; |
1076 } | 1078 } |
1077 | 1079 |
1081 This function is provided only for byte-code compatibility with v19. | 1083 This function is provided only for byte-code compatibility with v19. |
1082 Do not use it. | 1084 Do not use it. |
1083 */ | 1085 */ |
1084 (elt, list)) | 1086 (elt, list)) |
1085 { | 1087 { |
1086 REGISTER Lisp_Object tail, tem; | 1088 REGISTER Lisp_Object tail; |
1087 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1089 LIST_LOOP (tail, list) |
1088 { | 1090 { |
1089 tem = Fcar (tail); | 1091 CONCHECK_CONS (tail); |
1090 if (internal_old_equal (elt, tem, 0)) | 1092 if (internal_old_equal (elt, XCAR (tail), 0)) |
1091 return tail; | 1093 return tail; |
1092 QUIT; | 1094 QUIT; |
1093 } | 1095 } |
1094 return Qnil; | 1096 return Qnil; |
1095 } | 1097 } |
1096 | 1098 |
1098 Return non-nil if ELT is an element of LIST. Comparison done with `eq'. | 1100 Return non-nil if ELT is an element of LIST. Comparison done with `eq'. |
1099 The value is actually the tail of LIST whose car is ELT. | 1101 The value is actually the tail of LIST whose car is ELT. |
1100 */ | 1102 */ |
1101 (elt, list)) | 1103 (elt, list)) |
1102 { | 1104 { |
1103 REGISTER Lisp_Object tail, tem; | 1105 REGISTER Lisp_Object tail; |
1104 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1106 LIST_LOOP (tail, list) |
1105 { | 1107 { |
1106 tem = Fcar (tail); | 1108 REGISTER Lisp_Object tem; |
1107 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) return tail; | 1109 CONCHECK_CONS (tail); |
1110 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) | |
1111 return tail; | |
1108 QUIT; | 1112 QUIT; |
1109 } | 1113 } |
1110 return Qnil; | 1114 return Qnil; |
1111 } | 1115 } |
1112 | 1116 |
1116 This function is provided only for byte-code compatibility with v19. | 1120 This function is provided only for byte-code compatibility with v19. |
1117 Do not use it. | 1121 Do not use it. |
1118 */ | 1122 */ |
1119 (elt, list)) | 1123 (elt, list)) |
1120 { | 1124 { |
1121 REGISTER Lisp_Object tail, tem; | 1125 REGISTER Lisp_Object tail; |
1122 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1126 LIST_LOOP (tail, list) |
1123 { | 1127 { |
1124 tem = Fcar (tail); | 1128 REGISTER Lisp_Object tem; |
1125 if (HACKEQ_UNSAFE (elt, tem)) return tail; | 1129 CONCHECK_CONS (tail); |
1130 if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem)) | |
1131 return tail; | |
1126 QUIT; | 1132 QUIT; |
1127 } | 1133 } |
1128 return Qnil; | 1134 return Qnil; |
1129 } | 1135 } |
1130 | 1136 |
1131 Lisp_Object | 1137 Lisp_Object |
1132 memq_no_quit (Lisp_Object elt, Lisp_Object list) | 1138 memq_no_quit (Lisp_Object elt, Lisp_Object list) |
1133 { | 1139 { |
1134 REGISTER Lisp_Object tail, tem; | 1140 REGISTER Lisp_Object tail; |
1135 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1141 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1136 { | 1142 { |
1137 tem = XCAR (tail); | 1143 REGISTER Lisp_Object tem; |
1138 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) return tail; | 1144 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1145 return tail; | |
1139 } | 1146 } |
1140 return Qnil; | 1147 return Qnil; |
1141 } | 1148 } |
1142 | 1149 |
1143 DEFUN ("assoc", Fassoc, 2, 2, 0, /* | 1150 DEFUN ("assoc", Fassoc, 2, 2, 0, /* |
1145 The value is actually the element of LIST whose car equals KEY. | 1152 The value is actually the element of LIST whose car equals KEY. |
1146 */ | 1153 */ |
1147 (key, list)) | 1154 (key, list)) |
1148 { | 1155 { |
1149 /* This function can GC. */ | 1156 /* This function can GC. */ |
1150 REGISTER Lisp_Object tail, elt; | 1157 REGISTER Lisp_Object tail; |
1151 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1158 LIST_LOOP (tail, list) |
1152 { | 1159 { |
1153 elt = Fcar (tail); | 1160 REGISTER Lisp_Object elt; |
1154 if (!CONSP (elt)) | 1161 CONCHECK_CONS (tail); |
1155 continue; | 1162 elt = XCAR (tail); |
1156 if (internal_equal (XCAR (elt), key, 0)) | 1163 if (CONSP (elt) && internal_equal (XCAR (elt), key, 0)) |
1157 return elt; | 1164 return elt; |
1158 QUIT; | 1165 QUIT; |
1159 } | 1166 } |
1160 return Qnil; | 1167 return Qnil; |
1161 } | 1168 } |
1165 The value is actually the element of LIST whose car equals KEY. | 1172 The value is actually the element of LIST whose car equals KEY. |
1166 */ | 1173 */ |
1167 (key, list)) | 1174 (key, list)) |
1168 { | 1175 { |
1169 /* This function can GC. */ | 1176 /* This function can GC. */ |
1170 REGISTER Lisp_Object tail, elt; | 1177 REGISTER Lisp_Object tail; |
1171 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1178 LIST_LOOP (tail, list) |
1172 { | 1179 { |
1173 elt = Fcar (tail); | 1180 REGISTER Lisp_Object elt; |
1174 if (!CONSP (elt)) | 1181 CONCHECK_CONS (tail); |
1175 continue; | 1182 elt = XCAR (tail); |
1176 if (internal_old_equal (XCAR (elt), key, 0)) | 1183 if (CONSP (elt) && internal_old_equal (XCAR (elt), key, 0)) |
1177 return elt; | 1184 return elt; |
1178 QUIT; | 1185 QUIT; |
1179 } | 1186 } |
1180 return Qnil; | 1187 return Qnil; |
1181 } | 1188 } |
1193 The value is actually the element of LIST whose car is KEY. | 1200 The value is actually the element of LIST whose car is KEY. |
1194 Elements of LIST that are not conses are ignored. | 1201 Elements of LIST that are not conses are ignored. |
1195 */ | 1202 */ |
1196 (key, list)) | 1203 (key, list)) |
1197 { | 1204 { |
1198 REGISTER Lisp_Object tail, elt, tem; | 1205 REGISTER Lisp_Object tail; |
1199 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1206 LIST_LOOP (tail, list) |
1200 { | 1207 { |
1201 elt = Fcar (tail); | 1208 REGISTER Lisp_Object elt, tem; |
1202 if (!CONSP (elt)) | 1209 CONCHECK_CONS (tail); |
1203 continue; | 1210 elt = XCAR (tail); |
1204 /* Note: we use a temporary variable to avoid multiple | 1211 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) |
1205 evaluations of XCAR (elt). */ | |
1206 tem = XCAR (elt); | |
1207 if (EQ_WITH_EBOLA_NOTICE (key, tem)) | |
1208 return elt; | 1212 return elt; |
1209 QUIT; | 1213 QUIT; |
1210 } | 1214 } |
1211 return Qnil; | 1215 return Qnil; |
1212 } | 1216 } |
1218 This function is provided only for byte-code compatibility with v19. | 1222 This function is provided only for byte-code compatibility with v19. |
1219 Do not use it. | 1223 Do not use it. |
1220 */ | 1224 */ |
1221 (key, list)) | 1225 (key, list)) |
1222 { | 1226 { |
1223 REGISTER Lisp_Object tail, elt, tem; | 1227 REGISTER Lisp_Object tail; |
1224 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1228 LIST_LOOP (tail, list) |
1225 { | 1229 { |
1226 elt = Fcar (tail); | 1230 REGISTER Lisp_Object elt, tem; |
1227 if (!CONSP (elt)) | 1231 CONCHECK_CONS (tail); |
1228 continue; | 1232 elt = XCAR (tail); |
1229 tem = XCAR (elt); | 1233 if (CONSP (elt) && (tem = XCAR (elt), HACKEQ_UNSAFE (key, tem))) |
1230 if (HACKEQ_UNSAFE (key, tem)) | |
1231 return elt; | 1234 return elt; |
1232 QUIT; | 1235 QUIT; |
1233 } | 1236 } |
1234 return Qnil; | 1237 return Qnil; |
1235 } | 1238 } |
1239 | 1242 |
1240 Lisp_Object | 1243 Lisp_Object |
1241 assq_no_quit (Lisp_Object key, Lisp_Object list) | 1244 assq_no_quit (Lisp_Object key, Lisp_Object list) |
1242 { | 1245 { |
1243 /* This cannot GC. */ | 1246 /* This cannot GC. */ |
1244 REGISTER Lisp_Object tail, elt, tem; | 1247 REGISTER Lisp_Object tail; |
1245 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1248 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1246 { | 1249 { |
1250 REGISTER Lisp_Object tem, elt; | |
1247 elt = XCAR (tail); | 1251 elt = XCAR (tail); |
1248 if (!CONSP (elt)) continue; | 1252 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) |
1249 tem = XCAR (elt); | 1253 return elt; |
1250 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; | |
1251 } | 1254 } |
1252 return Qnil; | 1255 return Qnil; |
1253 } | 1256 } |
1254 | 1257 |
1255 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* | 1258 DEFUN ("rassoc", Frassoc, 2, 2, 0, /* |
1257 The value is actually the element of LIST whose cdr equals KEY. | 1260 The value is actually the element of LIST whose cdr equals KEY. |
1258 */ | 1261 */ |
1259 (key, list)) | 1262 (key, list)) |
1260 { | 1263 { |
1261 REGISTER Lisp_Object tail; | 1264 REGISTER Lisp_Object tail; |
1262 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1265 LIST_LOOP (tail, list) |
1263 { | 1266 { |
1264 REGISTER Lisp_Object elt; | 1267 REGISTER Lisp_Object elt; |
1265 elt = Fcar (tail); | 1268 CONCHECK_CONS (tail); |
1266 if (!CONSP (elt)) | 1269 elt = XCAR (tail); |
1267 continue; | 1270 if (CONSP (elt) && internal_equal (XCDR (elt), key, 0)) |
1268 if (internal_equal (XCDR (elt), key, 0)) | |
1269 return elt; | 1271 return elt; |
1270 QUIT; | 1272 QUIT; |
1271 } | 1273 } |
1272 return Qnil; | 1274 return Qnil; |
1273 } | 1275 } |
1277 The value is actually the element of LIST whose cdr equals KEY. | 1279 The value is actually the element of LIST whose cdr equals KEY. |
1278 */ | 1280 */ |
1279 (key, list)) | 1281 (key, list)) |
1280 { | 1282 { |
1281 REGISTER Lisp_Object tail; | 1283 REGISTER Lisp_Object tail; |
1282 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1284 LIST_LOOP (tail, list) |
1283 { | 1285 { |
1284 REGISTER Lisp_Object elt; | 1286 REGISTER Lisp_Object elt; |
1285 elt = Fcar (tail); | 1287 CONCHECK_CONS (tail); |
1286 if (!CONSP (elt)) | 1288 elt = XCAR (tail); |
1287 continue; | 1289 if (CONSP (elt) && internal_old_equal (XCDR (elt), key, 0)) |
1288 if (internal_old_equal (XCDR (elt), key, 0)) | |
1289 return elt; | 1290 return elt; |
1290 QUIT; | 1291 QUIT; |
1291 } | 1292 } |
1292 return Qnil; | 1293 return Qnil; |
1293 } | 1294 } |
1296 Return non-nil if KEY is `eq' to the cdr of an element of LIST. | 1297 Return non-nil if KEY is `eq' to the cdr of an element of LIST. |
1297 The value is actually the element of LIST whose cdr is KEY. | 1298 The value is actually the element of LIST whose cdr is KEY. |
1298 */ | 1299 */ |
1299 (key, list)) | 1300 (key, list)) |
1300 { | 1301 { |
1301 REGISTER Lisp_Object tail, elt, tem; | 1302 REGISTER Lisp_Object tail; |
1302 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1303 LIST_LOOP (tail, list) |
1303 { | 1304 { |
1304 elt = Fcar (tail); | 1305 REGISTER Lisp_Object elt, tem; |
1305 if (!CONSP (elt)) | 1306 CONCHECK_CONS (tail); |
1306 continue; | 1307 elt = XCAR (tail); |
1307 tem = XCDR (elt); | 1308 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) |
1308 if (EQ_WITH_EBOLA_NOTICE (key, tem)) | |
1309 return elt; | 1309 return elt; |
1310 QUIT; | 1310 QUIT; |
1311 } | 1311 } |
1312 return Qnil; | 1312 return Qnil; |
1313 } | 1313 } |
1316 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST. | 1316 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST. |
1317 The value is actually the element of LIST whose cdr is KEY. | 1317 The value is actually the element of LIST whose cdr is KEY. |
1318 */ | 1318 */ |
1319 (key, list)) | 1319 (key, list)) |
1320 { | 1320 { |
1321 REGISTER Lisp_Object tail, elt, tem; | 1321 REGISTER Lisp_Object tail; |
1322 for (tail = list; !NILP (tail); tail = Fcdr (tail)) | 1322 LIST_LOOP (tail, list) |
1323 { | 1323 { |
1324 elt = Fcar (tail); | 1324 REGISTER Lisp_Object elt, tem; |
1325 if (!CONSP (elt)) | 1325 CONCHECK_CONS (tail); |
1326 continue; | 1326 elt = XCAR (tail); |
1327 tem = XCDR (elt); | 1327 if (CONSP (elt) && (tem = XCDR (elt), HACKEQ_UNSAFE (key, tem))) |
1328 if (HACKEQ_UNSAFE (key, tem)) | |
1329 return elt; | 1328 return elt; |
1330 QUIT; | 1329 QUIT; |
1331 } | 1330 } |
1332 return Qnil; | 1331 return Qnil; |
1333 } | 1332 } |
1334 | 1333 |
1335 Lisp_Object | 1334 Lisp_Object |
1336 rassq_no_quit (Lisp_Object key, Lisp_Object list) | 1335 rassq_no_quit (Lisp_Object key, Lisp_Object list) |
1337 { | 1336 { |
1338 REGISTER Lisp_Object tail, elt, tem; | 1337 REGISTER Lisp_Object tail; |
1339 for (tail = list; CONSP (tail); tail = XCDR (tail)) | 1338 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1340 { | 1339 { |
1340 REGISTER Lisp_Object elt, tem; | |
1341 elt = XCAR (tail); | 1341 elt = XCAR (tail); |
1342 if (!CONSP (elt)) continue; | 1342 if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) |
1343 tem = XCDR (elt); | 1343 return elt; |
1344 if (EQ_WITH_EBOLA_NOTICE (key, tem)) return elt; | |
1345 } | 1344 } |
1346 return Qnil; | 1345 return Qnil; |
1347 } | 1346 } |
1348 | 1347 |
1349 | 1348 |
1355 of changing the value of `foo'. | 1354 of changing the value of `foo'. |
1356 Also see: `remove'. | 1355 Also see: `remove'. |
1357 */ | 1356 */ |
1358 (elt, list)) | 1357 (elt, list)) |
1359 { | 1358 { |
1360 REGISTER Lisp_Object tail, prev; | 1359 REGISTER Lisp_Object tail = list; |
1361 | 1360 REGISTER Lisp_Object prev = Qnil; |
1362 tail = list; | 1361 |
1363 prev = Qnil; | |
1364 while (!NILP (tail)) | 1362 while (!NILP (tail)) |
1365 { | 1363 { |
1366 if (internal_equal (elt, Fcar (tail), 0)) | 1364 CONCHECK_CONS (tail); |
1365 if (internal_equal (elt, XCAR (tail), 0)) | |
1367 { | 1366 { |
1368 if (NILP (prev)) | 1367 if (NILP (prev)) |
1369 list = Fcdr (tail); | 1368 list = XCDR (tail); |
1370 else | 1369 else |
1371 Fsetcdr (prev, Fcdr (tail)); | 1370 XCDR (prev) = XCDR (tail); |
1372 } | 1371 } |
1373 else | 1372 else |
1374 prev = tail; | 1373 prev = tail; |
1375 tail = Fcdr (tail); | 1374 tail = XCDR (tail); |
1376 QUIT; | 1375 QUIT; |
1377 } | 1376 } |
1378 return list; | 1377 return list; |
1379 } | 1378 } |
1380 | 1379 |
1381 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /* | 1380 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /* |
1382 Delete by side effect any occurrences of ELT as a member of LIST. | 1381 Delete by side effect any occurrences of ELT as a member of LIST. |
1383 The modified LIST is returned. Comparison is done with `old-equal'. | 1382 The modified LIST is returned. Comparison is done with `old-equal'. |
1384 If the first member of LIST is ELT, there is no way to remove it by side | 1383 If the first member of LIST is ELT, there is no way to remove it by side |
1385 effect; therefore, write `(setq foo (delete element foo))' to be sure | 1384 effect; therefore, write `(setq foo (old-delete element foo))' to be sure |
1386 of changing the value of `foo'. | 1385 of changing the value of `foo'. |
1387 */ | 1386 */ |
1388 (elt, list)) | 1387 (elt, list)) |
1389 { | 1388 { |
1390 REGISTER Lisp_Object tail, prev; | 1389 REGISTER Lisp_Object tail = list; |
1391 | 1390 REGISTER Lisp_Object prev = Qnil; |
1392 tail = list; | 1391 |
1393 prev = Qnil; | |
1394 while (!NILP (tail)) | 1392 while (!NILP (tail)) |
1395 { | 1393 { |
1396 if (internal_old_equal (elt, Fcar (tail), 0)) | 1394 CONCHECK_CONS (tail); |
1395 if (internal_old_equal (elt, XCAR (tail), 0)) | |
1397 { | 1396 { |
1398 if (NILP (prev)) | 1397 if (NILP (prev)) |
1399 list = Fcdr (tail); | 1398 list = XCDR (tail); |
1400 else | 1399 else |
1401 Fsetcdr (prev, Fcdr (tail)); | 1400 XCDR (prev) = XCDR (tail); |
1402 } | 1401 } |
1403 else | 1402 else |
1404 prev = tail; | 1403 prev = tail; |
1405 tail = Fcdr (tail); | 1404 tail = XCDR (tail); |
1406 QUIT; | 1405 QUIT; |
1407 } | 1406 } |
1408 return list; | 1407 return list; |
1409 } | 1408 } |
1410 | 1409 |
1415 effect; therefore, write `(setq foo (delq element foo))' to be sure of | 1414 effect; therefore, write `(setq foo (delq element foo))' to be sure of |
1416 changing the value of `foo'. | 1415 changing the value of `foo'. |
1417 */ | 1416 */ |
1418 (elt, list)) | 1417 (elt, list)) |
1419 { | 1418 { |
1420 REGISTER Lisp_Object tail, prev; | 1419 REGISTER Lisp_Object tail = list; |
1421 REGISTER Lisp_Object tem; | 1420 REGISTER Lisp_Object prev = Qnil; |
1422 | 1421 |
1423 tail = list; | |
1424 prev = Qnil; | |
1425 while (!NILP (tail)) | 1422 while (!NILP (tail)) |
1426 { | 1423 { |
1427 tem = Fcar (tail); | 1424 REGISTER Lisp_Object tem; |
1428 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) | 1425 CONCHECK_CONS (tail); |
1426 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) | |
1429 { | 1427 { |
1430 if (NILP (prev)) | 1428 if (NILP (prev)) |
1431 list = Fcdr (tail); | 1429 list = XCDR (tail); |
1432 else | 1430 else |
1433 Fsetcdr (prev, Fcdr (tail)); | 1431 XCDR (prev) = XCDR (tail); |
1434 } | 1432 } |
1435 else | 1433 else |
1436 prev = tail; | 1434 prev = tail; |
1437 tail = Fcdr (tail); | 1435 tail = XCDR (tail); |
1438 QUIT; | 1436 QUIT; |
1439 } | 1437 } |
1440 return list; | 1438 return list; |
1441 } | 1439 } |
1442 | 1440 |
1443 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /* | 1441 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /* |
1444 Delete by side effect any occurrences of ELT as a member of LIST. | 1442 Delete by side effect any occurrences of ELT as a member of LIST. |
1445 The modified LIST is returned. Comparison is done with `old-eq'. | 1443 The modified LIST is returned. Comparison is done with `old-eq'. |
1446 If the first member of LIST is ELT, there is no way to remove it by side | 1444 If the first member of LIST is ELT, there is no way to remove it by side |
1447 effect; therefore, write `(setq foo (delq element foo))' to be sure of | 1445 effect; therefore, write `(setq foo (old-delq element foo))' to be sure of |
1448 changing the value of `foo'. | 1446 changing the value of `foo'. |
1449 */ | 1447 */ |
1450 (elt, list)) | 1448 (elt, list)) |
1451 { | 1449 { |
1452 REGISTER Lisp_Object tail, prev; | 1450 REGISTER Lisp_Object tail = list; |
1453 REGISTER Lisp_Object tem; | 1451 REGISTER Lisp_Object prev = Qnil; |
1454 | 1452 |
1455 tail = list; | |
1456 prev = Qnil; | |
1457 while (!NILP (tail)) | 1453 while (!NILP (tail)) |
1458 { | 1454 { |
1459 tem = Fcar (tail); | 1455 REGISTER Lisp_Object tem; |
1460 if (HACKEQ_UNSAFE (elt, tem)) | 1456 CONCHECK_CONS (tail); |
1457 if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem)) | |
1461 { | 1458 { |
1462 if (NILP (prev)) | 1459 if (NILP (prev)) |
1463 list = Fcdr (tail); | 1460 list = XCDR (tail); |
1464 else | 1461 else |
1465 Fsetcdr (prev, Fcdr (tail)); | 1462 XCDR (prev) = XCDR (tail); |
1466 } | 1463 } |
1467 else | 1464 else |
1468 prev = tail; | 1465 prev = tail; |
1469 tail = Fcdr (tail); | 1466 tail = XCDR (tail); |
1470 QUIT; | 1467 QUIT; |
1471 } | 1468 } |
1472 return list; | 1469 return list; |
1473 } | 1470 } |
1474 | 1471 |
1475 /* no quit, no errors; be careful */ | 1472 /* no quit, no errors; be careful */ |
1476 | 1473 |
1477 Lisp_Object | 1474 Lisp_Object |
1478 delq_no_quit (Lisp_Object elt, Lisp_Object list) | 1475 delq_no_quit (Lisp_Object elt, Lisp_Object list) |
1479 { | 1476 { |
1480 REGISTER Lisp_Object tail, prev; | 1477 REGISTER Lisp_Object tail = list; |
1481 REGISTER Lisp_Object tem; | 1478 REGISTER Lisp_Object prev = Qnil; |
1482 | 1479 |
1483 tail = list; | |
1484 prev = Qnil; | |
1485 while (CONSP (tail)) | 1480 while (CONSP (tail)) |
1486 { | 1481 { |
1487 tem = XCAR (tail); | 1482 REGISTER Lisp_Object tem; |
1488 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) | 1483 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1489 { | 1484 { |
1490 if (NILP (prev)) | 1485 if (NILP (prev)) |
1491 list = XCDR (tail); | 1486 list = XCDR (tail); |
1492 else | 1487 else |
1493 XCDR (prev) = XCDR (tail); | 1488 XCDR (prev) = XCDR (tail); |
1507 the actual list doesn't escape beyond known code bounds. */ | 1502 the actual list doesn't escape beyond known code bounds. */ |
1508 | 1503 |
1509 Lisp_Object | 1504 Lisp_Object |
1510 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list) | 1505 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list) |
1511 { | 1506 { |
1512 REGISTER Lisp_Object tail, prev; | 1507 REGISTER Lisp_Object tail = list; |
1513 REGISTER Lisp_Object tem; | 1508 REGISTER Lisp_Object prev = Qnil; |
1514 | 1509 struct Lisp_Cons *cons_to_free = NULL; |
1515 tail = list; | 1510 |
1516 prev = Qnil; | |
1517 while (CONSP (tail)) | 1511 while (CONSP (tail)) |
1518 { | 1512 { |
1519 Lisp_Object cons_to_free = Qnil; | 1513 REGISTER Lisp_Object tem; |
1520 tem = XCAR (tail); | 1514 if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem)) |
1521 if (EQ_WITH_EBOLA_NOTICE (elt, tem)) | |
1522 { | 1515 { |
1523 if (NILP (prev)) | 1516 if (NILP (prev)) |
1524 list = XCDR (tail); | 1517 list = XCDR (tail); |
1525 else | 1518 else |
1526 XCDR (prev) = XCDR (tail); | 1519 XCDR (prev) = XCDR (tail); |
1527 cons_to_free = tail; | 1520 cons_to_free = XCONS (tail); |
1528 } | 1521 } |
1529 else | 1522 else |
1530 prev = tail; | 1523 prev = tail; |
1531 tail = XCDR (tail); | 1524 tail = XCDR (tail); |
1532 if (!NILP (cons_to_free)) | 1525 if (cons_to_free) |
1533 free_cons (XCONS (cons_to_free)); | 1526 { |
1527 free_cons (cons_to_free); | |
1528 cons_to_free = NULL; | |
1529 } | |
1534 } | 1530 } |
1535 return list; | 1531 return list; |
1536 } | 1532 } |
1537 | 1533 |
1538 DEFUN ("remassoc", Fremassoc, 2, 2, 0, /* | 1534 DEFUN ("remassoc", Fremassoc, 2, 2, 0, /* |
1542 therefore, write `(setq foo (remassoc key foo))' to be sure of changing | 1538 therefore, write `(setq foo (remassoc key foo))' to be sure of changing |
1543 the value of `foo'. | 1539 the value of `foo'. |
1544 */ | 1540 */ |
1545 (key, list)) | 1541 (key, list)) |
1546 { | 1542 { |
1547 REGISTER Lisp_Object tail, prev; | 1543 REGISTER Lisp_Object tail = list; |
1548 | 1544 REGISTER Lisp_Object prev = Qnil; |
1549 tail = list; | 1545 |
1550 prev = Qnil; | |
1551 while (!NILP (tail)) | 1546 while (!NILP (tail)) |
1552 { | 1547 { |
1553 Lisp_Object elt = Fcar (tail); | 1548 REGISTER Lisp_Object elt; |
1549 CONCHECK_CONS (tail); | |
1550 elt = XCAR (tail); | |
1554 if (CONSP (elt) && internal_equal (key, XCAR (elt), 0)) | 1551 if (CONSP (elt) && internal_equal (key, XCAR (elt), 0)) |
1555 { | 1552 { |
1556 if (NILP (prev)) | 1553 if (NILP (prev)) |
1557 list = Fcdr (tail); | 1554 list = XCDR (tail); |
1558 else | 1555 else |
1559 Fsetcdr (prev, Fcdr (tail)); | 1556 XCDR (prev) = XCDR (tail); |
1560 } | 1557 } |
1561 else | 1558 else |
1562 prev = tail; | 1559 prev = tail; |
1563 tail = Fcdr (tail); | 1560 tail = XCDR (tail); |
1564 QUIT; | 1561 QUIT; |
1565 } | 1562 } |
1566 return list; | 1563 return list; |
1567 } | 1564 } |
1568 | 1565 |
1581 therefore, write `(setq foo (remassq key foo))' to be sure of changing | 1578 therefore, write `(setq foo (remassq key foo))' to be sure of changing |
1582 the value of `foo'. | 1579 the value of `foo'. |
1583 */ | 1580 */ |
1584 (key, list)) | 1581 (key, list)) |
1585 { | 1582 { |
1586 REGISTER Lisp_Object tail, prev; | 1583 REGISTER Lisp_Object tail = list; |
1587 | 1584 REGISTER Lisp_Object prev = Qnil; |
1588 tail = list; | 1585 |
1589 prev = Qnil; | |
1590 while (!NILP (tail)) | 1586 while (!NILP (tail)) |
1591 { | 1587 { |
1592 Lisp_Object elt = Fcar (tail); | 1588 REGISTER Lisp_Object elt, tem; |
1593 if (CONSP (elt) && EQ_WITH_EBOLA_NOTICE (key, Fcar (elt))) | 1589 CONCHECK_CONS (tail); |
1590 elt = XCAR (tail); | |
1591 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) | |
1594 { | 1592 { |
1595 if (NILP (prev)) | 1593 if (NILP (prev)) |
1596 list = Fcdr (tail); | 1594 list = XCDR (tail); |
1597 else | 1595 else |
1598 Fsetcdr (prev, Fcdr (tail)); | 1596 XCDR (prev) = XCDR (tail); |
1599 } | 1597 } |
1600 else | 1598 else |
1601 prev = tail; | 1599 prev = tail; |
1602 tail = Fcdr (tail); | 1600 tail = XCDR (tail); |
1603 QUIT; | 1601 QUIT; |
1604 } | 1602 } |
1605 return list; | 1603 return list; |
1606 } | 1604 } |
1607 | 1605 |
1608 /* no quit, no errors; be careful */ | 1606 /* no quit, no errors; be careful */ |
1609 | 1607 |
1610 Lisp_Object | 1608 Lisp_Object |
1611 remassq_no_quit (Lisp_Object key, Lisp_Object list) | 1609 remassq_no_quit (Lisp_Object key, Lisp_Object list) |
1612 { | 1610 { |
1613 REGISTER Lisp_Object tail, prev; | 1611 REGISTER Lisp_Object tail = list; |
1614 REGISTER Lisp_Object tem; | 1612 REGISTER Lisp_Object prev = Qnil; |
1615 | 1613 |
1616 tail = list; | |
1617 prev = Qnil; | |
1618 while (CONSP (tail)) | 1614 while (CONSP (tail)) |
1619 { | 1615 { |
1620 tem = XCAR (tail); | 1616 REGISTER Lisp_Object elt, tem; |
1621 if (CONSP (tem) && EQ_WITH_EBOLA_NOTICE (key, XCAR (tem))) | 1617 elt = XCAR (tail); |
1618 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem))) | |
1622 { | 1619 { |
1623 if (NILP (prev)) | 1620 if (NILP (prev)) |
1624 list = XCDR (tail); | 1621 list = XCDR (tail); |
1625 else | 1622 else |
1626 XCDR (prev) = XCDR (tail); | 1623 XCDR (prev) = XCDR (tail); |
1639 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing | 1636 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing |
1640 the value of `foo'. | 1637 the value of `foo'. |
1641 */ | 1638 */ |
1642 (value, list)) | 1639 (value, list)) |
1643 { | 1640 { |
1644 REGISTER Lisp_Object tail, prev; | 1641 REGISTER Lisp_Object tail = list; |
1645 | 1642 REGISTER Lisp_Object prev = Qnil; |
1646 tail = list; | 1643 |
1647 prev = Qnil; | |
1648 while (!NILP (tail)) | 1644 while (!NILP (tail)) |
1649 { | 1645 { |
1650 Lisp_Object elt = Fcar (tail); | 1646 REGISTER Lisp_Object elt; |
1647 CONCHECK_CONS (tail); | |
1648 elt = XCAR (tail); | |
1651 if (CONSP (elt) && internal_equal (value, XCDR (elt), 0)) | 1649 if (CONSP (elt) && internal_equal (value, XCDR (elt), 0)) |
1652 { | 1650 { |
1653 if (NILP (prev)) | 1651 if (NILP (prev)) |
1654 list = Fcdr (tail); | 1652 list = XCDR (tail); |
1655 else | 1653 else |
1656 Fsetcdr (prev, Fcdr (tail)); | 1654 XCDR (prev) = XCDR (tail); |
1657 } | 1655 } |
1658 else | 1656 else |
1659 prev = tail; | 1657 prev = tail; |
1660 tail = Fcdr (tail); | 1658 tail = XCDR (tail); |
1661 QUIT; | 1659 QUIT; |
1662 } | 1660 } |
1663 return list; | 1661 return list; |
1664 } | 1662 } |
1665 | 1663 |
1670 therefore, write `(setq foo (remrassq value foo))' to be sure of changing | 1668 therefore, write `(setq foo (remrassq value foo))' to be sure of changing |
1671 the value of `foo'. | 1669 the value of `foo'. |
1672 */ | 1670 */ |
1673 (value, list)) | 1671 (value, list)) |
1674 { | 1672 { |
1675 REGISTER Lisp_Object tail, prev; | 1673 REGISTER Lisp_Object tail = list; |
1676 | 1674 REGISTER Lisp_Object prev = Qnil; |
1677 tail = list; | 1675 |
1678 prev = Qnil; | |
1679 while (!NILP (tail)) | 1676 while (!NILP (tail)) |
1680 { | 1677 { |
1681 Lisp_Object elt = Fcar (tail); | 1678 REGISTER Lisp_Object elt, tem; |
1682 if (CONSP (elt) && EQ_WITH_EBOLA_NOTICE (value, Fcdr (elt))) | 1679 CONCHECK_CONS (tail); |
1683 { | 1680 elt = XCAR (tail); |
1684 if (NILP (prev)) | 1681 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (value, tem))) |
1685 list = Fcdr (tail); | |
1686 else | |
1687 Fsetcdr (prev, Fcdr (tail)); | |
1688 } | |
1689 else | |
1690 prev = tail; | |
1691 tail = Fcdr (tail); | |
1692 QUIT; | |
1693 } | |
1694 return list; | |
1695 } | |
1696 | |
1697 /* no quit, no errors; be careful */ | |
1698 | |
1699 Lisp_Object | |
1700 remrassq_no_quit (Lisp_Object value, Lisp_Object list) | |
1701 { | |
1702 REGISTER Lisp_Object tail, prev; | |
1703 REGISTER Lisp_Object tem; | |
1704 | |
1705 tail = list; | |
1706 prev = Qnil; | |
1707 while (CONSP (tail)) | |
1708 { | |
1709 tem = XCAR (tail); | |
1710 if (CONSP (tem) && EQ_WITH_EBOLA_NOTICE (value, XCDR (tem))) | |
1711 { | 1682 { |
1712 if (NILP (prev)) | 1683 if (NILP (prev)) |
1713 list = XCDR (tail); | 1684 list = XCDR (tail); |
1714 else | 1685 else |
1715 XCDR (prev) = XCDR (tail); | 1686 XCDR (prev) = XCDR (tail); |
1716 } | 1687 } |
1717 else | 1688 else |
1718 prev = tail; | 1689 prev = tail; |
1719 tail = XCDR (tail); | 1690 tail = XCDR (tail); |
1691 QUIT; | |
1720 } | 1692 } |
1721 return list; | 1693 return list; |
1722 } | 1694 } |
1723 | 1695 |
1696 /* no quit, no errors; be careful */ | |
1697 | |
1698 Lisp_Object | |
1699 remrassq_no_quit (Lisp_Object value, Lisp_Object list) | |
1700 { | |
1701 REGISTER Lisp_Object tail = list; | |
1702 REGISTER Lisp_Object prev = Qnil; | |
1703 | |
1704 while (CONSP (tail)) | |
1705 { | |
1706 REGISTER Lisp_Object elt, tem; | |
1707 elt = XCAR (tail); | |
1708 if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (value, tem))) | |
1709 { | |
1710 if (NILP (prev)) | |
1711 list = XCDR (tail); | |
1712 else | |
1713 XCDR (prev) = XCDR (tail); | |
1714 } | |
1715 else | |
1716 prev = tail; | |
1717 tail = XCDR (tail); | |
1718 } | |
1719 return list; | |
1720 } | |
1721 | |
1724 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /* | 1722 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /* |
1725 Reverse LIST by modifying cdr pointers. | 1723 Reverse LIST by destructively modifying cdr pointers. |
1726 Returns the beginning of the reversed list. | 1724 Return the beginning of the reversed list. |
1727 Also see: `reverse'. | 1725 Also see: `reverse'. |
1728 */ | 1726 */ |
1729 (list)) | 1727 (list)) |
1730 { | 1728 { |
1731 Lisp_Object prev, tail, next; | |
1732 struct gcpro gcpro1, gcpro2; | 1729 struct gcpro gcpro1, gcpro2; |
1730 REGISTER Lisp_Object prev = Qnil; | |
1731 REGISTER Lisp_Object tail = list; | |
1733 | 1732 |
1734 /* We gcpro our args; see `nconc' */ | 1733 /* We gcpro our args; see `nconc' */ |
1735 prev = Qnil; | |
1736 tail = list; | |
1737 GCPRO2 (prev, tail); | 1734 GCPRO2 (prev, tail); |
1738 while (!NILP (tail)) | 1735 while (!NILP (tail)) |
1739 { | 1736 { |
1737 REGISTER Lisp_Object next; | |
1740 QUIT; | 1738 QUIT; |
1741 CHECK_CONS (tail); | 1739 CONCHECK_CONS (tail); |
1742 next = XCDR (tail); | 1740 next = XCDR (tail); |
1743 XCDR (tail) = prev; | 1741 XCDR (tail) = prev; |
1744 prev = tail; | 1742 prev = tail; |
1745 tail = next; | 1743 tail = next; |
1746 } | 1744 } |
1747 UNGCPRO; | 1745 UNGCPRO; |
1748 return prev; | 1746 return prev; |
1749 } | 1747 } |
1750 | 1748 |
1751 DEFUN ("reverse", Freverse, 1, 1, 0, /* | 1749 DEFUN ("reverse", Freverse, 1, 1, 0, /* |
1752 Reverse LIST, copying. Returns the beginning of the reversed list. | 1750 Reverse LIST, copying. Return the beginning of the reversed list. |
1753 See also the function `nreverse', which is used more often. | 1751 See also the function `nreverse', which is used more often. |
1754 */ | 1752 */ |
1755 (list)) | 1753 (list)) |
1756 { | 1754 { |
1757 Lisp_Object new; | 1755 REGISTER Lisp_Object tail; |
1758 | 1756 Lisp_Object new = Qnil; |
1759 for (new = Qnil; CONSP (list); list = XCDR (list)) | 1757 |
1760 new = Fcons (XCAR (list), new); | 1758 for (tail = list; CONSP (tail); tail = XCDR (tail)) |
1761 if (!NILP (list)) | 1759 { |
1762 list = wrong_type_argument (Qconsp, list); | 1760 new = Fcons (XCAR (tail), new); |
1761 QUIT; | |
1762 } | |
1763 if (!NILP (tail)) | |
1764 dead_wrong_type_argument (Qlistp, tail); | |
1763 return new; | 1765 return new; |
1764 } | 1766 } |
1765 | 1767 |
1766 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2, | 1768 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2, |
1767 Lisp_Object lisp_arg, | 1769 Lisp_Object lisp_arg, |
1772 list_sort (Lisp_Object list, | 1774 list_sort (Lisp_Object list, |
1773 Lisp_Object lisp_arg, | 1775 Lisp_Object lisp_arg, |
1774 int (*pred_fn) (Lisp_Object, Lisp_Object, | 1776 int (*pred_fn) (Lisp_Object, Lisp_Object, |
1775 Lisp_Object lisp_arg)) | 1777 Lisp_Object lisp_arg)) |
1776 { | 1778 { |
1777 Lisp_Object front, back; | |
1778 Lisp_Object len, tem; | |
1779 struct gcpro gcpro1, gcpro2, gcpro3; | 1779 struct gcpro gcpro1, gcpro2, gcpro3; |
1780 int length; | 1780 Lisp_Object back, tem; |
1781 | 1781 Lisp_Object front = list; |
1782 front = list; | 1782 Lisp_Object len = Flength (list); |
1783 len = Flength (list); | 1783 int length = XINT (len); |
1784 length = XINT (len); | 1784 |
1785 if (length < 2) | 1785 if (length < 2) |
1786 return list; | 1786 return list; |
1787 | 1787 |
1788 XSETINT (len, (length / 2) - 1); | 1788 XSETINT (len, (length / 2) - 1); |
1789 tem = Fnthcdr (len, list); | 1789 tem = Fnthcdr (len, list); |
2085 | 2085 |
2086 void | 2086 void |
2087 internal_plist_put (Lisp_Object *plist, Lisp_Object property, | 2087 internal_plist_put (Lisp_Object *plist, Lisp_Object property, |
2088 Lisp_Object value) | 2088 Lisp_Object value) |
2089 { | 2089 { |
2090 Lisp_Object tail = *plist; | 2090 Lisp_Object tail; |
2091 | 2091 |
2092 for (; !NILP (tail); tail = XCDR (XCDR (tail))) | 2092 for (tail = *plist; !NILP (tail); tail = XCDR (XCDR (tail))) |
2093 { | 2093 { |
2094 struct Lisp_Cons *c = XCONS (tail); | 2094 if (EQ (XCAR (tail), property)) |
2095 if (EQ (c->car, property)) | 2095 { |
2096 { | 2096 XCAR (XCDR (tail)) = value; |
2097 XCAR (c->cdr) = value; | |
2098 return; | 2097 return; |
2099 } | 2098 } |
2100 } | 2099 } |
2101 | 2100 |
2102 *plist = Fcons (property, Fcons (value, *plist)); | 2101 *plist = Fcons (property, Fcons (value, *plist)); |
2646 static Lisp_Object | 2645 static Lisp_Object |
2647 symbol_getprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object default_) | 2646 symbol_getprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object default_) |
2648 { | 2647 { |
2649 Lisp_Object val = external_plist_get (&XSYMBOL (sym)->plist, propname, | 2648 Lisp_Object val = external_plist_get (&XSYMBOL (sym)->plist, propname, |
2650 0, ERROR_ME); | 2649 0, ERROR_ME); |
2651 if (UNBOUNDP (val)) | 2650 return UNBOUNDP (val) ? default_ : val; |
2652 return default_; | |
2653 return val; | |
2654 } | 2651 } |
2655 | 2652 |
2656 static void | 2653 static void |
2657 symbol_putprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object value) | 2654 symbol_putprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object value) |
2658 { | 2655 { |
2684 if (CONSP (*ptr) && INTP (XCAR (*ptr))) | 2681 if (CONSP (*ptr) && INTP (XCAR (*ptr))) |
2685 ptr = &XCDR (*ptr); | 2682 ptr = &XCDR (*ptr); |
2686 return ptr; | 2683 return ptr; |
2687 } | 2684 } |
2688 | 2685 |
2689 Lisp_Object | 2686 static Lisp_Object |
2690 string_getprop (struct Lisp_String *s, Lisp_Object property, | 2687 string_getprop (struct Lisp_String *s, Lisp_Object property, |
2691 Lisp_Object default_) | 2688 Lisp_Object default_) |
2692 { | 2689 { |
2693 Lisp_Object val = external_plist_get (string_plist_ptr (s), property, 0, | 2690 Lisp_Object val = external_plist_get (string_plist_ptr (s), property, 0, |
2694 ERROR_ME); | 2691 ERROR_ME); |
2695 if (UNBOUNDP (val)) | 2692 return UNBOUNDP (val) ? default_ : val; |
2696 return default_; | 2693 } |
2697 return val; | 2694 |
2698 } | 2695 static void |
2699 | |
2700 void | |
2701 string_putprop (struct Lisp_String *s, Lisp_Object property, | 2696 string_putprop (struct Lisp_String *s, Lisp_Object property, |
2702 Lisp_Object value) | 2697 Lisp_Object value) |
2703 { | 2698 { |
2704 external_plist_put (string_plist_ptr (s), property, value, 0, ERROR_ME); | 2699 external_plist_put (string_plist_ptr (s), property, value, 0, ERROR_ME); |
2705 } | 2700 } |
2900 } | 2895 } |
2901 #endif | 2896 #endif |
2902 #ifndef LRECORD_VECTOR | 2897 #ifndef LRECORD_VECTOR |
2903 else if (VECTORP (o1)) | 2898 else if (VECTORP (o1)) |
2904 { | 2899 { |
2905 int indice; | 2900 Lisp_Object *v1 = XVECTOR_DATA (o1); |
2901 Lisp_Object *v2 = XVECTOR_DATA (o2); | |
2906 int len = XVECTOR_LENGTH (o1); | 2902 int len = XVECTOR_LENGTH (o1); |
2907 if (len != XVECTOR_LENGTH (o2)) | 2903 if (len != XVECTOR_LENGTH (o2)) |
2908 return 0; | 2904 return 0; |
2909 for (indice = 0; indice < len; indice++) | 2905 while (len--) |
2910 { | 2906 if (!internal_equal (*v1++, *v2++, depth + 1)) |
2911 Lisp_Object v1, v2; | 2907 return 0; |
2912 v1 = XVECTOR_DATA (o1) [indice]; | |
2913 v2 = XVECTOR_DATA (o2) [indice]; | |
2914 if (!internal_equal (v1, v2, depth + 1)) | |
2915 return 0; | |
2916 } | |
2917 return 1; | 2908 return 1; |
2918 } | 2909 } |
2919 #endif | 2910 #endif |
2920 #ifndef LRECORD_STRING | 2911 #ifndef LRECORD_STRING |
2921 else if (STRINGP (o1)) | 2912 else if (STRINGP (o1)) |
2922 { | 2913 { |
2923 Bytecount len = XSTRING_LENGTH (o1); | 2914 Bytecount len; |
2924 if (len != XSTRING_LENGTH (o2)) | 2915 return (((len = XSTRING_LENGTH (o1)) == XSTRING_LENGTH (o2)) && |
2925 return 0; | 2916 !memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)); |
2926 if (memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len)) | |
2927 return 0; | |
2928 return 1; | |
2929 } | 2917 } |
2930 #endif | 2918 #endif |
2931 else if (LRECORDP (o1)) | 2919 else if (LRECORDP (o1)) |
2932 { | 2920 { |
2933 CONST struct lrecord_implementation | 2921 CONST struct lrecord_implementation |
3018 | 3006 |
3019 return 0; | 3007 return 0; |
3020 } | 3008 } |
3021 | 3009 |
3022 DEFUN ("equal", Fequal, 2, 2, 0, /* | 3010 DEFUN ("equal", Fequal, 2, 2, 0, /* |
3023 T if two Lisp objects have similar structure and contents. | 3011 Return t if two Lisp objects have similar structure and contents. |
3024 They must have the same data type. | 3012 They must have the same data type. |
3025 Conses are compared by comparing the cars and the cdrs. | 3013 Conses are compared by comparing the cars and the cdrs. |
3026 Vectors and strings are compared element by element. | 3014 Vectors and strings are compared element by element. |
3027 Numbers are compared by value. Symbols must match exactly. | 3015 Numbers are compared by value. Symbols must match exactly. |
3028 */ | 3016 */ |
3030 { | 3018 { |
3031 return internal_equal (o1, o2, 0) ? Qt : Qnil; | 3019 return internal_equal (o1, o2, 0) ? Qt : Qnil; |
3032 } | 3020 } |
3033 | 3021 |
3034 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /* | 3022 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /* |
3035 T if two Lisp objects have similar structure and contents. | 3023 Return t if two Lisp objects have similar structure and contents. |
3036 They must have the same data type. | 3024 They must have the same data type. |
3037 \(Note, however, that an exception is made for characters and integers; | 3025 \(Note, however, that an exception is made for characters and integers; |
3038 this is known as the "char-int confoundance disease." See `eq' and | 3026 this is known as the "char-int confoundance disease." See `eq' and |
3039 `old-eq'.) | 3027 `old-eq'.) |
3040 This function is provided only for byte-code compatibility with v19. | 3028 This function is provided only for byte-code compatibility with v19. |
3053 (array, item)) | 3041 (array, item)) |
3054 { | 3042 { |
3055 retry: | 3043 retry: |
3056 if (STRINGP (array)) | 3044 if (STRINGP (array)) |
3057 { | 3045 { |
3058 Charcount len; | 3046 Emchar charval; |
3047 struct Lisp_String *s = XSTRING (array); | |
3048 Charcount len = string_char_length (s); | |
3059 Charcount i; | 3049 Charcount i; |
3060 Emchar charval; | |
3061 struct Lisp_String *s; | |
3062 CHECK_CHAR_COERCE_INT (item); | 3050 CHECK_CHAR_COERCE_INT (item); |
3063 CHECK_IMPURE (array); | 3051 CHECK_IMPURE (array); |
3064 charval = XCHAR (item); | 3052 charval = XCHAR (item); |
3065 s = XSTRING (array); | |
3066 len = string_char_length (s); | |
3067 for (i = 0; i < len; i++) | 3053 for (i = 0; i < len; i++) |
3068 set_string_char (s, i, charval); | 3054 set_string_char (s, i, charval); |
3069 bump_string_modiff (array); | 3055 bump_string_modiff (array); |
3070 } | 3056 } |
3071 else if (VECTORP (array)) | 3057 else if (VECTORP (array)) |
3072 { | 3058 { |
3073 Lisp_Object *p; | 3059 Lisp_Object *p = XVECTOR_DATA (array); |
3074 int len; | 3060 int len = XVECTOR_LENGTH (array); |
3075 int i; | |
3076 CHECK_IMPURE (array); | 3061 CHECK_IMPURE (array); |
3077 len = XVECTOR_LENGTH (array); | 3062 while (len--) |
3078 p = XVECTOR_DATA (array); | 3063 *p++ = item; |
3079 for (i = 0; i < len; i++) | |
3080 p[i] = item; | |
3081 } | 3064 } |
3082 else if (BIT_VECTORP (array)) | 3065 else if (BIT_VECTORP (array)) |
3083 { | 3066 { |
3084 struct Lisp_Bit_Vector *v; | 3067 struct Lisp_Bit_Vector *v = XBIT_VECTOR (array); |
3085 int len; | 3068 int len = bit_vector_length (v); |
3086 int i; | 3069 int bit; |
3087 CHECK_BIT (item); | 3070 CHECK_BIT (item); |
3088 CHECK_IMPURE (array); | 3071 CHECK_IMPURE (array); |
3089 v = XBIT_VECTOR (array); | 3072 bit = XINT (item); |
3090 len = bit_vector_length (v); | 3073 while (len--) |
3091 for (i = 0; i < len; i++) | 3074 set_bit_vector_bit (v, len, bit); |
3092 set_bit_vector_bit (v, i, XINT (item)); | |
3093 } | 3075 } |
3094 else | 3076 else |
3095 { | 3077 { |
3096 array = wrong_type_argument (Qarrayp, array); | 3078 array = wrong_type_argument (Qarrayp, array); |
3097 goto retry; | 3079 goto retry; |
3110 | 3092 |
3111 DEFUN ("nconc", Fnconc, 0, MANY, 0, /* | 3093 DEFUN ("nconc", Fnconc, 0, MANY, 0, /* |
3112 Concatenate any number of lists by altering them. | 3094 Concatenate any number of lists by altering them. |
3113 Only the last argument is not altered, and need not be a list. | 3095 Only the last argument is not altered, and need not be a list. |
3114 Also see: `append'. | 3096 Also see: `append'. |
3097 If the first argument is nil, there is no way to modify it by side | |
3098 effect; therefore, write `(setq foo (nconc foo list))' to be sure of | |
3099 changing the value of `foo'. | |
3115 */ | 3100 */ |
3116 (int nargs, Lisp_Object *args)) | 3101 (int nargs, Lisp_Object *args)) |
3117 { | 3102 { |
3118 int argnum; | 3103 int argnum = 0; |
3119 Lisp_Object tail, tem, val; | |
3120 struct gcpro gcpro1; | 3104 struct gcpro gcpro1; |
3121 | 3105 |
3122 /* The modus operandi in Emacs is "caller gc-protects args". | 3106 /* The modus operandi in Emacs is "caller gc-protects args". |
3123 However, nconc (particularly nconc2 ()) is called many times | 3107 However, nconc (particularly nconc2 ()) is called many times |
3124 in Emacs on freshly created stuff (e.g. you see the idiom | 3108 in Emacs on freshly created stuff (e.g. you see the idiom |
3125 nconc2 (Fcopy_sequence (foo), bar) a lot). So we help those | 3109 nconc2 (Fcopy_sequence (foo), bar) a lot). So we help those |
3126 callers out by protecting the args ourselves to save them | 3110 callers out by protecting the args ourselves to save them |
3127 a lot of temporary-variable grief. */ | 3111 a lot of temporary-variable grief. */ |
3128 | 3112 |
3129 again: | |
3130 | |
3131 GCPRO1 (args[0]); | 3113 GCPRO1 (args[0]); |
3132 gcpro1.nvars = nargs; | 3114 gcpro1.nvars = nargs; |
3133 | 3115 |
3134 val = Qnil; | 3116 while (argnum < nargs) |
3135 | 3117 { |
3136 for (argnum = 0; argnum < nargs; argnum++) | 3118 Lisp_Object val = args[argnum]; |
3137 { | 3119 if (CONSP (val)) |
3138 tem = args[argnum]; | 3120 { |
3139 if (NILP (tem)) continue; | 3121 /* Found the first cons, which will be our return value. */ |
3140 | 3122 Lisp_Object last = val; |
3141 if (NILP (val)) | 3123 |
3142 val = tem; | 3124 for (argnum++; argnum < nargs; argnum++) |
3143 | 3125 { |
3144 if (argnum + 1 == nargs) break; | 3126 Lisp_Object next = args[argnum]; |
3145 | 3127 redo: |
3146 if (!CONSP (tem)) | 3128 if (CONSP (next) || argnum == nargs -1) |
3147 { | 3129 { |
3148 tem = wrong_type_argument (Qlistp, tem); | 3130 /* (setcdr (last val) next) */ |
3149 goto again; | 3131 while (CONSP (XCDR (last))) |
3150 } | 3132 { |
3151 | 3133 last = XCDR (last); |
3152 while (CONSP (tem)) | 3134 QUIT; |
3153 { | 3135 } |
3154 tail = tem; | 3136 XCDR (last) = next; |
3155 tem = XCDR (tail); | 3137 } |
3156 QUIT; | 3138 else if (NILP (next)) |
3157 } | 3139 { |
3158 | 3140 continue; |
3159 tem = args[argnum + 1]; | 3141 } |
3160 Fsetcdr (tail, tem); | 3142 else |
3161 if (NILP (tem)) | 3143 { |
3162 args[argnum + 1] = tail; | 3144 next = wrong_type_argument (next, Qlistp); |
3163 } | 3145 goto redo; |
3164 | 3146 } |
3165 RETURN_UNGCPRO (val); | 3147 } |
3148 RETURN_UNGCPRO (val); | |
3149 } | |
3150 else if (NILP (val)) | |
3151 argnum++; | |
3152 else if (argnum == nargs - 1) /* last arg? */ | |
3153 RETURN_UNGCPRO (val); | |
3154 else | |
3155 args[argnum] = wrong_type_argument (val, Qlistp); | |
3156 } | |
3157 RETURN_UNGCPRO (Qnil); /* No non-nil args provided. */ | |
3166 } | 3158 } |
3167 | 3159 |
3168 | 3160 |
3169 /* This is the guts of all mapping functions. | 3161 /* This is the guts of all mapping functions. |
3170 Apply fn to each element of seq, one by one, | 3162 Apply fn to each element of seq, one by one, |
3248 Thus, " " as SEP results in spaces between the values returned by FN. | 3240 Thus, " " as SEP results in spaces between the values returned by FN. |
3249 */ | 3241 */ |
3250 (fn, seq, sep)) | 3242 (fn, seq, sep)) |
3251 { | 3243 { |
3252 int len = XINT (Flength (seq)); | 3244 int len = XINT (Flength (seq)); |
3253 int nargs; | |
3254 Lisp_Object *args; | 3245 Lisp_Object *args; |
3255 int i; | 3246 int i; |
3256 struct gcpro gcpro1; | 3247 struct gcpro gcpro1; |
3257 | 3248 int nargs = len + len - 1; |
3258 nargs = len + len - 1; | 3249 |
3259 if (nargs < 0) return build_string (""); | 3250 if (nargs < 0) return build_string (""); |
3260 | 3251 |
3261 args = alloca_array (Lisp_Object, nargs); | 3252 args = alloca_array (Lisp_Object, nargs); |
3262 | 3253 |
3263 GCPRO1 (sep); | 3254 GCPRO1 (sep); |
3330 then converted to integer. | 3321 then converted to integer. |
3331 | 3322 |
3332 If the 5-minute or 15-minute load averages are not available, return a | 3323 If the 5-minute or 15-minute load averages are not available, return a |
3333 shortened list, containing only those averages which are available. | 3324 shortened list, containing only those averages which are available. |
3334 | 3325 |
3335 On some systems, this won't work due to permissions on /dev/kmem in | 3326 On some systems, this won't work due to permissions on /dev/kmem, |
3336 which case you can't use this. | 3327 in which case you can't use this. |
3337 */ | 3328 */ |
3338 ()) | 3329 ()) |
3339 { | 3330 { |
3340 double load_ave[10]; /* hey, just in case */ | 3331 double load_ave[3]; |
3341 int loads = getloadavg (load_ave, 3); | 3332 int loads = getloadavg (load_ave, countof (load_ave)); |
3342 Lisp_Object ret; | |
3343 | 3333 |
3344 if (loads == -2) | 3334 if (loads == -2) |
3345 error ("load-average not implemented for this operating system."); | 3335 error ("load-average not implemented for this operating system."); |
3346 else if (loads < 0) | 3336 else if (loads < 0) |
3347 error ("could not get load-average; check permissions."); | 3337 error ("could not get load-average; check permissions."); |
3348 | 3338 |
3349 ret = Qnil; | 3339 { |
3350 while (loads > 0) | 3340 Lisp_Object ret = Qnil; |
3351 ret = Fcons (make_int ((int) (load_ave[--loads] * 100.0)), ret); | 3341 while (loads > 0) |
3352 | 3342 ret = Fcons (make_int ((int) (load_ave[--loads] * 100.0)), ret); |
3353 return ret; | 3343 return ret; |
3344 } | |
3354 } | 3345 } |
3355 | 3346 |
3356 | 3347 |
3357 Lisp_Object Vfeatures; | 3348 Lisp_Object Vfeatures; |
3358 | 3349 |
3395 { | 3386 { |
3396 #ifndef FEATUREP_SYNTAX | 3387 #ifndef FEATUREP_SYNTAX |
3397 CHECK_SYMBOL (fexp); | 3388 CHECK_SYMBOL (fexp); |
3398 return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt; | 3389 return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt; |
3399 #else /* FEATUREP_SYNTAX */ | 3390 #else /* FEATUREP_SYNTAX */ |
3400 extern Lisp_Object Vemacs_major_version, Vemacs_minor_version; | |
3401 extern Lisp_Object Qfeaturep; | |
3402 static double featurep_emacs_version; | 3391 static double featurep_emacs_version; |
3403 | 3392 |
3404 /* Brute force translation from Erik Naggum's lisp function. */ | 3393 /* Brute force translation from Erik Naggum's lisp function. */ |
3405 if (SYMBOLP(fexp)) | 3394 if (SYMBOLP (fexp)) |
3406 { | 3395 { |
3407 /* Original definition */ | 3396 /* Original definition */ |
3408 return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt; | 3397 return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt; |
3409 } | 3398 } |
3410 else if (INTP(fexp) || FLOATP(fexp)) | 3399 else if (INTP (fexp) || FLOATP (fexp)) |
3411 { | 3400 { |
3412 double d = extract_float(fexp); | 3401 double d = extract_float (fexp); |
3413 | 3402 |
3414 if (featurep_emacs_version == 0.0) | 3403 if (featurep_emacs_version == 0.0) |
3415 { | 3404 { |
3416 featurep_emacs_version = XINT (Vemacs_major_version) + | 3405 featurep_emacs_version = XINT (Vemacs_major_version) + |
3417 (XINT (Vemacs_minor_version) / 100.0); | 3406 (XINT (Vemacs_minor_version) / 100.0); |
3418 } | 3407 } |
3419 return featurep_emacs_version >= d ? Qt : Qnil; | 3408 return featurep_emacs_version >= d ? Qt : Qnil; |
3420 } | 3409 } |
3421 else if (CONSP(fexp)) | 3410 else if (CONSP (fexp)) |
3422 { | 3411 { |
3423 Lisp_Object tem; | 3412 Lisp_Object tem = XCAR (fexp); |
3424 | 3413 if (EQ (tem, Qnot)) |
3425 tem = XCAR(fexp); | |
3426 if (EQ(tem, Qnot)) | |
3427 { | 3414 { |
3428 Lisp_Object negate; | 3415 Lisp_Object negate; |
3429 | 3416 |
3430 tem = XCDR (fexp); | 3417 tem = XCDR (fexp); |
3431 negate = Fcar (tem); | 3418 negate = Fcar (tem); |
3432 if (!NILP (tem)) | 3419 if (!NILP (tem)) |
3433 return NILP (call1 (Qfeaturep, negate)) ? Qt : Qnil; | 3420 return NILP (call1 (Qfeaturep, negate)) ? Qt : Qnil; |
3434 else | 3421 else |
3435 return Fsignal (Qinvalid_read_syntax, list1 (tem)); | 3422 return Fsignal (Qinvalid_read_syntax, list1 (tem)); |
3436 } | 3423 } |
3437 else if (EQ(tem, Qand)) | 3424 else if (EQ (tem, Qand)) |
3438 { | 3425 { |
3439 tem = XCDR(fexp); | 3426 tem = XCDR (fexp); |
3440 /* Use Fcar/Fcdr for error-checking. */ | 3427 /* Use Fcar/Fcdr for error-checking. */ |
3441 while (!NILP (tem) && !NILP (call1 (Qfeaturep, Fcar (tem)))) | 3428 while (!NILP (tem) && !NILP (call1 (Qfeaturep, Fcar (tem)))) |
3442 { | 3429 { |
3443 tem = Fcdr (tem); | 3430 tem = Fcdr (tem); |
3444 } | 3431 } |
3445 return NILP(tem) ? Qt : Qnil; | 3432 return NILP (tem) ? Qt : Qnil; |
3446 } | 3433 } |
3447 else if (EQ(tem, Qor)) | 3434 else if (EQ (tem, Qor)) |
3448 { | 3435 { |
3449 tem = XCDR (fexp); | 3436 tem = XCDR (fexp); |
3450 /* Use Fcar/Fcdr for error-checking. */ | 3437 /* Use Fcar/Fcdr for error-checking. */ |
3451 while (!NILP (tem) && NILP (call1 (Qfeaturep, Fcar (tem)))) | 3438 while (!NILP (tem) && NILP (call1 (Qfeaturep, Fcar (tem)))) |
3452 { | 3439 { |
3453 tem = Fcdr (tem); | 3440 tem = Fcdr (tem); |
3454 } | 3441 } |
3455 return NILP(tem) ? Qnil : Qt; | 3442 return NILP (tem) ? Qnil : Qt; |
3456 } | 3443 } |
3457 else | 3444 else |
3458 { | 3445 { |
3459 return Fsignal(Qinvalid_read_syntax, list1(XCDR(fexp))); | 3446 return Fsignal (Qinvalid_read_syntax, list1 (XCDR (fexp))); |
3460 } | 3447 } |
3461 } | 3448 } |
3462 else | 3449 else |
3463 { | 3450 { |
3464 return Fsignal(Qinvalid_read_syntax, list1 (fexp)); | 3451 return Fsignal (Qinvalid_read_syntax, list1 (fexp)); |
3465 } | 3452 } |
3466 } | 3453 } |
3467 #endif /* FEATUREP_SYNTAX */ | 3454 #endif /* FEATUREP_SYNTAX */ |
3468 | 3455 |
3469 DEFUN ("provide", Fprovide, 1, 1, 0, /* | 3456 DEFUN ("provide", Fprovide, 1, 1, 0, /* |