comparison src/fns.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* Synched up with: Mule 2.0, FSF 19.30. */
23
24 /* This file has been Mule-ized. */
25
26 /* Note: FSF 19.30 has bool vectors. We have bit vectors. */
27
28 /* Hacked on for Mule by Ben Wing, December 1994, January 1995. */
29
30 #include <config.h>
31
32 /* Note on some machines this defines `vector' as a typedef,
33 so make sure we don't use that name in this file. */
34 #undef vector
35 #define vector *****
36
37 #include "lisp.h"
38
39 #include "buffer.h"
40 #include "bytecode.h"
41 #include "commands.h"
42 #include "device.h"
43 #include "events.h"
44 #include "extents.h"
45 #include "frame.h"
46 #include "systime.h"
47
48 Lisp_Object Qstring_lessp;
49 Lisp_Object Qidentity;
50
51 static Lisp_Object mark_bit_vector (Lisp_Object, void (*) (Lisp_Object));
52 static void print_bit_vector (Lisp_Object, Lisp_Object, int);
53 static int bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth);
54 static unsigned long bit_vector_hash (Lisp_Object obj, int depth);
55 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("bit-vector", bit_vector,
56 mark_bit_vector, print_bit_vector, 0,
57 bit_vector_equal, bit_vector_hash,
58 struct Lisp_Bit_Vector);
59
60 static Lisp_Object
61 mark_bit_vector (Lisp_Object obj, void (*markobj) (Lisp_Object))
62 {
63 return (Qnil);
64 }
65
66 static void
67 print_bit_vector (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
68 {
69 int i;
70 struct Lisp_Bit_Vector *v = XBIT_VECTOR (obj);
71 int len = bit_vector_length (v);
72 int last = len;
73
74 if (INTP (Vprint_length))
75 last = min (len, XINT (Vprint_length));
76 write_c_string ("#*", printcharfun);
77 for (i = 0; i < last; i++)
78 {
79 if (bit_vector_bit (v, i))
80 write_c_string ("1", printcharfun);
81 else
82 write_c_string ("0", printcharfun);
83 }
84
85 if (last != len)
86 write_c_string ("...", printcharfun);
87 }
88
89 static int
90 bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth)
91 {
92 struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (o1);
93 struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (o2);
94
95 if (bit_vector_length (v1) != bit_vector_length (v2))
96 return 0;
97
98 return !memcmp (v1->bits, v2->bits,
99 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) *
100 sizeof (long));
101 }
102
103 static unsigned long
104 bit_vector_hash (Lisp_Object obj, int depth)
105 {
106 struct Lisp_Bit_Vector *v = XBIT_VECTOR (obj);
107 return HASH2 (bit_vector_length (v),
108 memory_hash (v->bits,
109 BIT_VECTOR_LONG_STORAGE (bit_vector_length (v)) *
110 sizeof (long)));
111 }
112
113 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0 /*
114 Return the argument unchanged.
115 */ )
116 (arg)
117 Lisp_Object arg;
118 {
119 return arg;
120 }
121
122 extern long get_random (void);
123 extern void seed_random (long arg);
124
125 DEFUN ("random", Frandom, Srandom, 0, 1, 0 /*
126 Return a pseudo-random number.
127 All integers representable in Lisp are equally likely.\n\
128 On most systems, this is 28 bits' worth.\n\
129 With positive integer argument N, return random number in interval [0,N).\n\
130 With argument t, set the random number seed from the current time and pid.
131 */ )
132 (limit)
133 Lisp_Object limit;
134 {
135 EMACS_INT val;
136 Lisp_Object lispy_val;
137 unsigned long denominator;
138
139 if (EQ (limit, Qt))
140 seed_random (getpid () + time (NULL));
141 if (NATNUMP (limit) && !ZEROP (limit))
142 {
143 /* Try to take our random number from the higher bits of VAL,
144 not the lower, since (says Gentzel) the low bits of `random'
145 are less random than the higher ones. We do this by using the
146 quotient rather than the remainder. At the high end of the RNG
147 it's possible to get a quotient larger than limit; discarding
148 these values eliminates the bias that would otherwise appear
149 when using a large limit. */
150 denominator = ((unsigned long)1 << VALBITS) / XINT (limit);
151 do
152 val = get_random () / denominator;
153 while (val >= XINT (limit));
154 }
155 else
156 val = get_random ();
157 XSETINT (lispy_val, val);
158 return lispy_val;
159 }
160
161 /* Random data-structure functions */
162
163 #ifdef LOSING_BYTECODE
164
165 /* #### Delete this shit */
166
167 /* Charcount is a misnomer here as we might be dealing with the
168 length of a vector or list, but emphasizes that we're not dealing
169 with Bytecounts in strings */
170 static Charcount
171 length_with_bytecode_hack (Lisp_Object seq)
172 {
173 if (!COMPILED_FUNCTIONP (seq))
174 return (XINT (Flength (seq)));
175 else
176 {
177 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (seq);
178 int intp = b->flags.interactivep;
179 int domainp = b->flags.domainp;
180
181 if (intp)
182 return (COMPILED_INTERACTIVE + 1);
183 else if (domainp)
184 return (COMPILED_DOMAIN + 1);
185 else
186 return (COMPILED_DOC_STRING + 1);
187 }
188 }
189
190 #endif /* LOSING_BYTECODE */
191
192 void
193 check_losing_bytecode (CONST char *function, Lisp_Object seq)
194 {
195 if (COMPILED_FUNCTIONP (seq))
196 error_with_frob
197 (seq,
198 "As of 19.14, `%s' no longer works with compiled-function objects",
199 function);
200 }
201
202 DEFUN ("length", Flength, Slength, 1, 1, 0 /*
203 Return the length of vector, bit vector, list or string SEQUENCE.
204 */ )
205 (obj)
206 Lisp_Object obj;
207 {
208 Lisp_Object tail;
209 int i;
210
211 retry:
212 if (STRINGP (obj))
213 return (make_int (string_char_length (XSTRING (obj))));
214 else if (VECTORP (obj))
215 return (make_int (vector_length (XVECTOR (obj))));
216 else if (BIT_VECTORP (obj))
217 return (make_int (bit_vector_length (XBIT_VECTOR (obj))));
218 else if (CONSP (obj))
219 {
220 for (i = 0, tail = obj; !NILP (tail); i++)
221 {
222 QUIT;
223 tail = Fcdr (tail);
224 }
225
226 return (make_int (i));
227 }
228 else if (NILP (obj))
229 {
230 return (Qzero);
231 }
232 else
233 {
234 check_losing_bytecode ("length", obj);
235 obj = wrong_type_argument (Qsequencep, obj);
236 goto retry;
237 }
238 }
239
240 /* This does not check for quits. That is safe
241 since it must terminate. */
242
243 DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0 /*
244 Return the length of a list, but avoid error or infinite loop.
245 This function never gets an error. If LIST is not really a list,
246 it returns 0. If LIST is circular, it returns a finite value
247 which is at least the number of distinct elements.
248 */ )
249 (list)
250 Lisp_Object list;
251 {
252 Lisp_Object tail, halftail, length;
253 int len = 0;
254
255 /* halftail is used to detect circular lists. */
256 halftail = list;
257 for (tail = list; CONSP (tail); tail = XCDR (tail))
258 {
259 if (EQ (tail, halftail) && len != 0)
260 break;
261 len++;
262 if ((len & 1) == 0)
263 halftail = XCDR (halftail);
264 }
265
266 XSETINT (length, len);
267 return length;
268 }
269
270 /*** string functions. ***/
271
272 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0 /*
273 T if two strings have identical contents.
274 Case is significant. Text properties are ignored.
275 (Under XEmacs, `equal' also ignores text properties and extents in
276 strings, but this is not the case under FSF Emacs.)
277 Symbols are also allowed; their print names are used instead.
278 */ )
279 (s1, s2)
280 Lisp_Object s1, s2;
281 {
282 int len;
283
284 if (SYMBOLP (s1))
285 XSETSTRING (s1, XSYMBOL (s1)->name);
286 if (SYMBOLP (s2))
287 XSETSTRING (s2, XSYMBOL (s2)->name);
288 CHECK_STRING (s1);
289 CHECK_STRING (s2);
290
291 len = string_length (XSTRING (s1));
292 if (len != string_length (XSTRING (s2)) ||
293 memcmp (string_data (XSTRING (s1)), string_data (XSTRING (s2)), len))
294 return Qnil;
295 return Qt;
296 }
297
298
299 DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0 /*
300 T if first arg string is less than second in lexicographic order.
301 If I18N2 support was compiled in, ordering is determined by the locale.
302 Case is significant for the default C locale.
303 Symbols are also allowed; their print names are used instead.
304 */ )
305 (s1, s2)
306 Lisp_Object s1, s2;
307 {
308 struct Lisp_String *p1, *p2;
309 Charcount end, len2;
310
311 if (SYMBOLP (s1))
312 XSETSTRING (s1, XSYMBOL (s1)->name);
313 if (SYMBOLP (s2))
314 XSETSTRING (s2, XSYMBOL (s2)->name);
315 CHECK_STRING (s1);
316 CHECK_STRING (s2);
317
318 p1 = XSTRING (s1);
319 p2 = XSTRING (s2);
320 end = string_char_length (XSTRING (s1));
321 len2 = string_char_length (XSTRING (s2));
322 if (end > len2)
323 end = len2;
324
325 {
326 int i;
327
328 #ifdef I18N2
329 Bytecount bcend = charcount_to_bytecount (string_data (p1), end);
330 /* Compare strings using collation order of locale. */
331 /* Need to be tricky to handle embedded nulls. */
332
333 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1)
334 {
335 int val = strcoll ((char *) string_data (p1) + i,
336 (char *) string_data (p2) + i);
337 if (val < 0)
338 return Qt;
339 if (val > 0)
340 return Qnil;
341 }
342 #else /* not I18N2 */
343 for (i = 0; i < end; i++)
344 {
345 if (string_char (p1, i) != string_char (p2, i))
346 return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil;
347 }
348 #endif /* not I18N2 */
349 /* Can't do i < len2 because then comparison between "foo" and "foo^@"
350 won't work right in I18N2 case */
351 return ((end < len2) ? Qt : Qnil);
352 }
353 }
354
355 DEFUN ("string-modified-tick", Fstring_modified_tick, Sstring_modified_tick,
356 1, 1, 0 /*
357 Return STRING's tick counter, incremented for each change to the string.
358 Each string has a tick counter which is incremented each time the contents
359 of the string are changed (e.g. with `aset'). It wraps around occasionally.
360 */ )
361 (string)
362 Lisp_Object string;
363 {
364 struct Lisp_String *s;
365
366 CHECK_STRING (string);
367 s = XSTRING (string);
368 if (CONSP (s->plist) && INTP (XCAR (s->plist)))
369 return XCAR (s->plist);
370 else
371 return Qzero;
372 }
373
374 void
375 bump_string_modiff (Lisp_Object str)
376 {
377 struct Lisp_String *s = XSTRING (str);
378 Lisp_Object *ptr = &s->plist;
379
380 #ifdef I18N3
381 /* #### remove the `string-translatable' property from the string,
382 if there is one. */
383 #endif
384 /* skip over extent info if it's there */
385 if (CONSP (*ptr) && EXTENT_INFOP (XCAR (*ptr)))
386 ptr = &XCDR (*ptr);
387 if (CONSP (*ptr) && INTP (XCAR (*ptr)))
388 XSETINT (XCAR (*ptr), 1+XINT (XCAR (*ptr)));
389 else
390 *ptr = Fcons (make_int (1), *ptr);
391 }
392
393
394 enum concat_target_type { c_cons, c_string, c_vector, c_bit_vector };
395 static Lisp_Object concat (int nargs, Lisp_Object *args,
396 enum concat_target_type target_type,
397 int last_special);
398
399 Lisp_Object
400 concat2 (Lisp_Object s1, Lisp_Object s2)
401 {
402 Lisp_Object args[2];
403 args[0] = s1;
404 args[1] = s2;
405 return concat (2, args, c_string, 0);
406 }
407
408 Lisp_Object
409 concat3 (Lisp_Object s1, Lisp_Object s2, Lisp_Object s3)
410 {
411 Lisp_Object args[3];
412 args[0] = s1;
413 args[1] = s2;
414 args[2] = s3;
415 return concat (3, args, c_string, 0);
416 }
417
418 Lisp_Object
419 vconcat2 (Lisp_Object s1, Lisp_Object s2)
420 {
421 Lisp_Object args[2];
422 args[0] = s1;
423 args[1] = s2;
424 return concat (2, args, c_vector, 0);
425 }
426
427 Lisp_Object
428 vconcat3 (Lisp_Object s1, Lisp_Object s2, Lisp_Object s3)
429 {
430 Lisp_Object args[3];
431 args[0] = s1;
432 args[1] = s2;
433 args[2] = s3;
434 return concat (3, args, c_vector, 0);
435 }
436
437 DEFUN ("append", Fappend, Sappend, 0, MANY, 0 /*
438 Concatenate all the arguments and make the result a list.
439 The result is a list whose elements are the elements of all the arguments.
440 Each argument may be a list, vector, bit vector, or string.
441 The last argument is not copied, just used as the tail of the new list.
442 */ )
443 (nargs, args)
444 int nargs;
445 Lisp_Object *args;
446 {
447 return concat (nargs, args, c_cons, 1);
448 }
449
450 DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0 /*
451 Concatenate all the arguments and make the result a string.
452 The result is a string whose elements are the elements of all the arguments.
453 Each argument may be a string or a list or vector of characters (integers).
454
455 Do not use individual integers as arguments!
456 The behavior of `concat' in that case will be changed later!
457 If your program passes an integer as an argument to `concat',
458 you should change it right away not to do so.
459 */ )
460 (nargs, args)
461 int nargs;
462 Lisp_Object *args;
463 {
464 return concat (nargs, args, c_string, 0);
465 }
466
467 DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0 /*
468 Concatenate all the arguments and make the result a vector.
469 The result is a vector whose elements are the elements of all the arguments.
470 Each argument may be a list, vector, bit vector, or string.
471 */ )
472 (nargs, args)
473 int nargs;
474 Lisp_Object *args;
475 {
476 return concat (nargs, args, c_vector, 0);
477 }
478
479 DEFUN ("bvconcat", Fbvconcat, Sbvconcat, 0, MANY, 0 /*
480 Concatenate all the arguments and make the result a bit vector.
481 The result is a bit vector whose elements are the elements of all the
482 arguments. Each argument may be a list, vector, bit vector, or string.
483 */ )
484 (nargs, args)
485 int nargs;
486 Lisp_Object *args;
487 {
488 return concat (nargs, args, c_bit_vector, 0);
489 }
490
491 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0 /*
492 Return a copy of a list, vector, bit vector or string.
493 The elements of a list or vector are not copied; they are shared
494 with the original.
495 */ )
496 (arg)
497 Lisp_Object arg;
498 {
499 again:
500 if (NILP (arg)) return arg;
501 /* We handle conses separately because concat() is big and hairy and
502 doesn't handle (copy-sequence '(a b . c)) and it's easier to redo this
503 than to fix concat() without worrying about breaking other things.
504 */
505 if (CONSP (arg))
506 {
507 Lisp_Object rest = arg;
508 Lisp_Object head, tail;
509 tail = Qnil;
510 while (CONSP (rest))
511 {
512 Lisp_Object new = Fcons (XCAR (rest), XCDR (rest));
513 if (NILP (tail))
514 head = tail = new;
515 else
516 XCDR (tail) = new, tail = new;
517 rest = XCDR (rest);
518 QUIT;
519 }
520 if (!NILP (tail))
521 XCDR (tail) = rest;
522 return head;
523 }
524 else if (STRINGP (arg))
525 return concat (1, &arg, c_string, 0);
526 else if (VECTORP (arg))
527 return concat (1, &arg, c_vector, 0);
528 else if (BIT_VECTORP (arg))
529 return concat (1, &arg, c_bit_vector, 0);
530 else
531 {
532 check_losing_bytecode ("copy-sequence", arg);
533 arg = wrong_type_argument (Qsequencep, arg);
534 goto again;
535 }
536 }
537
538 struct merge_string_extents_struct
539 {
540 Lisp_Object string;
541 Bytecount entry_offset;
542 Bytecount entry_length;
543 };
544
545 static Lisp_Object
546 concat (int nargs, Lisp_Object *args,
547 enum concat_target_type target_type,
548 int last_special)
549 {
550 Lisp_Object val;
551 Lisp_Object tail = Qnil;
552 int toindex;
553 int argnum;
554 Lisp_Object last_tail;
555 Lisp_Object prev;
556 struct merge_string_extents_struct *args_mse = 0;
557 Bufbyte *string_result = 0;
558 Bufbyte *string_result_ptr = 0;
559 struct gcpro gcpro1;
560
561 /* The modus operandi in Emacs is "caller gc-protects args".
562 However, concat is called many times in Emacs on freshly
563 created stuff. So we help those callers out by protecting
564 the args ourselves to save them a lot of temporary-variable
565 grief. */
566
567 GCPRO1 (args[0]);
568 gcpro1.nvars = nargs;
569
570 #ifdef I18N3
571 /* #### if the result is a string and any of the strings have a string
572 for the `string-translatable' property, then concat should also
573 concat the args but use the `string-translatable' strings, and store
574 the result in the returned string's `string-translatable' property. */
575 #endif
576 if (target_type == c_string)
577 {
578 args_mse = ((struct merge_string_extents_struct *)
579 alloca (nargs *
580 sizeof (struct merge_string_extents_struct)));
581 }
582
583 /* In append, the last arg isn't treated like the others */
584 if (last_special && nargs > 0)
585 {
586 nargs--;
587 last_tail = args[nargs];
588 }
589 else
590 last_tail = Qnil;
591
592 /* Check and coerce the arguments. */
593 for (argnum = 0; argnum < nargs; argnum++)
594 {
595 Lisp_Object seq = args[argnum];
596 if (CONSP (seq) || NILP (seq))
597 ;
598 else if (VECTORP (seq) || STRINGP (seq) || BIT_VECTORP (seq))
599 ;
600 #ifdef LOSING_BYTECODE
601 else if (COMPILED_FUNCTIONP (seq))
602 /* Urk! We allow this, for "compatibility"... */
603 ;
604 #endif
605 else if (INTP (seq))
606 /* This is too revolting to think about but maintains
607 compatibility with FSF (and lots and lots of old code). */
608 args[argnum] = Fnumber_to_string (seq);
609 else
610 {
611 check_losing_bytecode ("concat", seq);
612 args[argnum] = wrong_type_argument (Qsequencep, seq);
613 }
614
615 if (args_mse)
616 {
617 if (STRINGP (seq))
618 args_mse[argnum].string = seq;
619 else
620 args_mse[argnum].string = Qnil;
621 }
622 }
623
624 {
625 /* Charcount is a misnomer here as we might be dealing with the
626 length of a vector or list, but emphasizes that we're not dealing
627 with Bytecounts in strings */
628 Charcount total_length;
629
630 for (argnum = 0, total_length = 0; argnum < nargs; argnum++)
631 {
632 #ifdef LOSING_BYTECODE
633 Charcount thislen = length_with_bytecode_hack (args[argnum]);
634 #else
635 Charcount thislen = XINT (Flength (args[argnum]));
636 #endif
637 total_length += thislen;
638 }
639
640 switch (target_type)
641 {
642 case c_cons:
643 if (total_length == 0)
644 /* In append, if all but last arg are nil, return last arg */
645 RETURN_UNGCPRO (last_tail);
646 val = Fmake_list (make_int (total_length), Qnil);
647 break;
648 case c_vector:
649 val = make_vector (total_length, Qnil);
650 break;
651 case c_bit_vector:
652 val = make_bit_vector (total_length, Qzero);
653 break;
654 case c_string:
655 /* We don't make the string yet because we don't know the
656 actual number of bytes. This loop was formerly written
657 to call Fmake_string() here and then call set_string_char()
658 for each char. This seems logical enough but is waaaaaaaay
659 slow -- set_string_char() has to scan the whole string up
660 to the place where the substitution is called for in order
661 to find the place to change, and may have to do some
662 realloc()ing in order to make the char fit properly.
663 O(N^2) yuckage. */
664 val = Qnil;
665 string_result = (Bufbyte *) alloca (total_length * MAX_EMCHAR_LEN);
666 string_result_ptr = string_result;
667 break;
668 default:
669 abort ();
670 }
671 }
672
673
674 if (CONSP (val))
675 tail = val, toindex = -1; /* -1 in toindex is flag we are
676 making a list */
677 else
678 toindex = 0;
679
680 prev = Qnil;
681
682 for (argnum = 0; argnum < nargs; argnum++)
683 {
684 Charcount thisleni = 0;
685 Charcount thisindex = 0;
686 Lisp_Object seq = args[argnum];
687 Bufbyte *string_source_ptr = 0;
688 Bufbyte *string_prev_result_ptr = string_result_ptr;
689
690 if (!CONSP (seq))
691 {
692 #ifdef LOSING_BYTECODE
693 thisleni = length_with_bytecode_hack (seq);
694 #else
695 thisleni = XINT (Flength (seq));
696 #endif
697 }
698 if (STRINGP (seq))
699 string_source_ptr = string_data (XSTRING (seq));
700
701 while (1)
702 {
703 Lisp_Object elt;
704
705 /* We've come to the end of this arg, so exit. */
706 if (NILP (seq))
707 break;
708
709 /* Fetch next element of `seq' arg into `elt' */
710 if (CONSP (seq))
711 {
712 elt = Fcar (seq);
713 seq = Fcdr (seq);
714 }
715 else
716 {
717 if (thisindex >= thisleni)
718 break;
719
720 if (STRINGP (seq))
721 {
722 elt = make_char (charptr_emchar (string_source_ptr));
723 INC_CHARPTR (string_source_ptr);
724 }
725 else if (VECTORP (seq))
726 elt = vector_data (XVECTOR (seq))[thisindex];
727 else if (BIT_VECTORP (seq))
728 elt = make_int (bit_vector_bit (XBIT_VECTOR (seq),
729 thisindex));
730 else
731 elt = Felt (seq, make_int (thisindex));
732 thisindex++;
733 }
734
735 /* Store into result */
736 if (toindex < 0)
737 {
738 /* toindex negative means we are making a list */
739 XCAR (tail) = elt;
740 prev = tail;
741 tail = XCDR (tail);
742 }
743 else if (VECTORP (val))
744 vector_data (XVECTOR (val))[toindex++] = elt;
745 else if (BIT_VECTORP (val))
746 {
747 CHECK_BIT (elt);
748 set_bit_vector_bit (XBIT_VECTOR (val), toindex++, XINT (elt));
749 }
750 else
751 {
752 CHECK_CHAR_COERCE_INT (elt);
753 string_result_ptr += set_charptr_emchar (string_result_ptr,
754 XCHAR (elt));
755 }
756 }
757 if (args_mse)
758 {
759 args_mse[argnum].entry_offset =
760 string_prev_result_ptr - string_result;
761 args_mse[argnum].entry_length =
762 string_result_ptr - string_prev_result_ptr;
763 }
764 }
765
766 /* Now we finally make the string. */
767 if (target_type == c_string)
768 {
769 val = make_string (string_result, string_result_ptr - string_result);
770 for (argnum = 0; argnum < nargs; argnum++)
771 {
772 if (STRINGP (args_mse[argnum].string))
773 copy_string_extents (val, args_mse[argnum].string,
774 args_mse[argnum].entry_offset, 0,
775 args_mse[argnum].entry_length);
776 }
777 }
778
779 if (!NILP (prev))
780 XCDR (prev) = last_tail;
781
782 RETURN_UNGCPRO (val);
783 }
784
785 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0 /*
786 Return a copy of ALIST.
787 This is an alist which represents the same mapping from objects to objects,
788 but does not share the alist structure with ALIST.
789 The objects mapped (cars and cdrs of elements of the alist)
790 are shared, however.
791 Elements of ALIST that are not conses are also shared.
792 */ )
793 (alist)
794 Lisp_Object alist;
795 {
796 Lisp_Object tem;
797
798 CHECK_LIST (alist);
799 if (NILP (alist))
800 return alist;
801 alist = concat (1, &alist, c_cons, 0);
802 for (tem = alist; CONSP (tem); tem = XCDR (tem))
803 {
804 Lisp_Object car;
805 car = XCAR (tem);
806
807 if (CONSP (car))
808 XCAR (tem) = Fcons (XCAR (car), XCDR (car));
809 }
810 return alist;
811 }
812
813 DEFUN ("copy-tree", Fcopy_tree, Scopy_tree, 1, 2, 0 /*
814 Return a copy of a list and substructures.
815 The argument is copied, and any lists contained within it are copied
816 recursively. Circularities and shared substructures are not preserved.
817 Second arg VECP causes vectors to be copied, too. Strings and bit vectors
818 are not copied.
819 */ )
820 (arg, vecp)
821 Lisp_Object arg, vecp;
822 {
823 if (CONSP (arg))
824 {
825 Lisp_Object rest;
826 rest = arg = Fcopy_sequence (arg);
827 while (CONSP (rest))
828 {
829 Lisp_Object elt = XCAR (rest);
830 QUIT;
831 if (CONSP (elt) || VECTORP (elt))
832 XCAR (rest) = Fcopy_tree (elt, vecp);
833 if (VECTORP (XCDR (rest))) /* hack for (a b . [c d]) */
834 XCDR (rest) = Fcopy_tree (XCDR (rest), vecp);
835 rest = XCDR (rest);
836 }
837 }
838 else if (VECTORP (arg) && ! NILP (vecp))
839 {
840 int i = vector_length (XVECTOR (arg));
841 int j;
842 arg = Fcopy_sequence (arg);
843 for (j = 0; j < i; j++)
844 {
845 Lisp_Object elt = vector_data (XVECTOR (arg)) [j];
846 QUIT;
847 if (CONSP (elt) || VECTORP (elt))
848 vector_data (XVECTOR (arg)) [j] = Fcopy_tree (elt, vecp);
849 }
850 }
851 return arg;
852 }
853
854 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0 /*
855 Return a substring of STRING, starting at index FROM and ending before TO.
856 TO may be nil or omitted; then the substring runs to the end of STRING.
857 If FROM or TO is negative, it counts from the end.
858 Relevant parts of the string-extent-data are copied in the new string.
859 */ )
860 (string, from, to)
861 Lisp_Object string;
862 Lisp_Object from, to;
863 {
864 Charcount ccfr, ccto;
865 Bytecount bfr, bto;
866 Lisp_Object val;
867
868 CHECK_STRING (string);
869 /* Historically, FROM could not be omitted. Whatever ... */
870 CHECK_INT (from);
871 get_string_range_char (string, from, to, &ccfr, &ccto,
872 GB_HISTORICAL_STRING_BEHAVIOR);
873 bfr = charcount_to_bytecount (string_data (XSTRING (string)), ccfr);
874 bto = charcount_to_bytecount (string_data (XSTRING (string)), ccto);
875 val = make_string (string_data (XSTRING (string)) + bfr, bto - bfr);
876 /* Copy any applicable extent information into the new string: */
877 copy_string_extents (val, string, 0, bfr, bto - bfr);
878 return (val);
879 }
880
881 DEFUN ("subseq", Fsubseq, Ssubseq, 2, 3, 0 /*
882 Return a subsequence of SEQ, starting at index FROM and ending before TO.
883 TO may be nil or omitted; then the subsequence runs to the end of SEQ.
884 If FROM or TO is negative, it counts from the end.
885 The resulting subsequence is always the same type as the original
886 sequence.
887 If SEQ is a string, relevant parts of the string-extent-data are copied
888 in the new string.
889 */ )
890 (seq, from, to)
891 Lisp_Object seq;
892 Lisp_Object from, to;
893 {
894 int len, f, t;
895
896 if (STRINGP (seq))
897 return Fsubstring (seq, from, to);
898
899 if (CONSP (seq) || NILP (seq))
900 ;
901 else if (VECTORP (seq) || BIT_VECTORP (seq))
902 ;
903 else
904 {
905 check_losing_bytecode ("subseq", seq);
906 seq = wrong_type_argument (Qsequencep, seq);
907 }
908
909 len = XINT (Flength (seq));
910 CHECK_INT (from);
911 f = XINT (from);
912 if (f < 0)
913 f = len + f;
914 if (NILP (to))
915 t = len;
916 else
917 {
918 CHECK_INT (to);
919 t = XINT (to);
920 if (t < 0)
921 t = len + t;
922 }
923
924 if (!(0 <= f && f <= t && t <= len))
925 args_out_of_range_3 (seq, make_int (f), make_int (t));
926
927 if (VECTORP (seq))
928 {
929 Lisp_Object result = make_vector (t - f, Qnil);
930 int i;
931 Lisp_Object *in_elts = vector_data (XVECTOR (seq));
932 Lisp_Object *out_elts = vector_data (XVECTOR (result));
933
934 for (i = f; i < t; i++)
935 out_elts[i - f] = in_elts[i];
936 return result;
937 }
938
939 if (CONSP (seq))
940 {
941 Lisp_Object result = Qnil;
942 int i;
943
944 seq = Fnthcdr (make_int (f), seq);
945
946 for (i = f; i < t; i++)
947 {
948 result = Fcons (Fcar (seq), result);
949 seq = Fcdr (seq);
950 }
951
952 return Fnreverse (result);
953 }
954
955 /* bit vector */
956 {
957 Lisp_Object result = make_bit_vector (t - f, Qzero);
958 int i;
959
960 for (i = f; i < t; i++)
961 set_bit_vector_bit (XBIT_VECTOR (result), i - f,
962 bit_vector_bit (XBIT_VECTOR (seq), i));
963 return result;
964 }
965 }
966
967
968 DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0 /*
969 Take cdr N times on LIST, returns the result.
970 */ )
971 (n, list)
972 Lisp_Object n;
973 Lisp_Object list;
974 {
975 REGISTER int i, num;
976 CHECK_INT (n);
977 num = XINT (n);
978 for (i = 0; i < num && !NILP (list); i++)
979 {
980 QUIT;
981 list = Fcdr (list);
982 }
983 return list;
984 }
985
986 DEFUN ("nth", Fnth, Snth, 2, 2, 0 /*
987 Return the Nth element of LIST.
988 N counts from zero. If LIST is not that long, nil is returned.
989 */ )
990 (n, list)
991 Lisp_Object n, list;
992 {
993 return Fcar (Fnthcdr (n, list));
994 }
995
996 DEFUN ("elt", Felt, Selt, 2, 2, 0 /*
997 Return element of SEQUENCE at index N.
998 */ )
999 (seq, n)
1000 Lisp_Object seq, n;
1001 {
1002 retry:
1003 CHECK_INT_COERCE_CHAR (n); /* yuck! */
1004 if (CONSP (seq) || NILP (seq))
1005 {
1006 Lisp_Object tem = Fnthcdr (n, seq);
1007 /* #### Utterly, completely, fucking disgusting.
1008 * #### The whole point of "elt" is that it operates on
1009 * #### sequences, and does error- (bounds-) checking.
1010 */
1011 if (CONSP (tem))
1012 return (XCAR (tem));
1013 else
1014 #if 1
1015 /* This is The Way It Has Always Been. */
1016 return Qnil;
1017 #else
1018 /* This is The Way Mly Says It Should Be. */
1019 args_out_of_range (seq, n);
1020 #endif
1021 }
1022 else if (STRINGP (seq)
1023 || VECTORP (seq)
1024 || BIT_VECTORP (seq))
1025 return (Faref (seq, n));
1026 #ifdef LOSING_BYTECODE
1027 else if (COMPILED_FUNCTIONP (seq))
1028 {
1029 int idx = XINT (n);
1030 if (idx < 0)
1031 {
1032 lose:
1033 args_out_of_range (seq, n);
1034 }
1035 /* Utter perversity */
1036 {
1037 struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (seq);
1038 switch (idx)
1039 {
1040 case COMPILED_ARGLIST:
1041 return (b->arglist);
1042 case COMPILED_BYTECODE:
1043 return (b->bytecodes);
1044 case COMPILED_CONSTANTS:
1045 return (b->constants);
1046 case COMPILED_STACK_DEPTH:
1047 return (make_int (b->maxdepth));
1048 case COMPILED_DOC_STRING:
1049 return (compiled_function_documentation (b));
1050 case COMPILED_DOMAIN:
1051 return (compiled_function_domain (b));
1052 case COMPILED_INTERACTIVE:
1053 if (b->flags.interactivep)
1054 return (compiled_function_interactive (b));
1055 /* if we return nil, can't tell interactive with no args
1056 from noninteractive. */
1057 goto lose;
1058 default:
1059 goto lose;
1060 }
1061 }
1062 }
1063 #endif /* LOSING_BYTECODE */
1064 else
1065 {
1066 check_losing_bytecode ("elt", seq);
1067 seq = wrong_type_argument (Qsequencep, seq);
1068 goto retry;
1069 }
1070 }
1071
1072 DEFUN ("member", Fmember, Smember, 2, 2, 0 /*
1073 Return non-nil if ELT is an element of LIST. Comparison done with `equal'.
1074 The value is actually the tail of LIST whose car is ELT.
1075 */ )
1076 (elt, list)
1077 Lisp_Object elt;
1078 Lisp_Object list;
1079 {
1080 REGISTER Lisp_Object tail, tem;
1081 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1082 {
1083 tem = Fcar (tail);
1084 if (! NILP (Fequal (elt, tem)))
1085 return tail;
1086 QUIT;
1087 }
1088 return Qnil;
1089 }
1090
1091 DEFUN ("memq", Fmemq, Smemq, 2, 2, 0 /*
1092 Return non-nil if ELT is an element of LIST. Comparison done with `eq'.
1093 The value is actually the tail of LIST whose car is ELT.
1094 */ )
1095 (elt, list)
1096 Lisp_Object elt;
1097 Lisp_Object list;
1098 {
1099 REGISTER Lisp_Object tail, tem;
1100 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1101 {
1102 tem = Fcar (tail);
1103 if (HACKEQ_UNSAFE (elt, tem)) return tail;
1104 QUIT;
1105 }
1106 return Qnil;
1107 }
1108
1109 Lisp_Object
1110 memq_no_quit (Lisp_Object elt, Lisp_Object list)
1111 {
1112 REGISTER Lisp_Object tail, tem;
1113 for (tail = list; CONSP (tail); tail = XCDR (tail))
1114 {
1115 tem = XCAR (tail);
1116 if (HACKEQ_UNSAFE (elt, tem)) return tail;
1117 }
1118 return Qnil;
1119 }
1120
1121 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0 /*
1122 Return non-nil if KEY is `equal' to the car of an element of LIST.
1123 The value is actually the element of LIST whose car equals KEY.
1124 */ )
1125 (key, list)
1126 Lisp_Object key;
1127 Lisp_Object list;
1128 {
1129 /* This function can GC. */
1130 REGISTER Lisp_Object tail, elt, tem;
1131 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1132 {
1133 elt = Fcar (tail);
1134 if (!CONSP (elt)) continue;
1135 tem = Fequal (Fcar (elt), key);
1136 if (!NILP (tem)) return elt;
1137 QUIT;
1138 }
1139 return Qnil;
1140 }
1141
1142 Lisp_Object
1143 assoc_no_quit (Lisp_Object key, Lisp_Object list)
1144 {
1145 int speccount = specpdl_depth ();
1146 specbind (Qinhibit_quit, Qt);
1147 return (unbind_to (speccount, Fassoc (key, list)));
1148 }
1149
1150 DEFUN ("assq", Fassq, Sassq, 2, 2, 0 /*
1151 Return non-nil if KEY is `eq' to the car of an element of LIST.
1152 The value is actually the element of LIST whose car is KEY.
1153 Elements of LIST that are not conses are ignored.
1154 */ )
1155 (key, list)
1156 Lisp_Object key;
1157 Lisp_Object list;
1158 {
1159 REGISTER Lisp_Object tail, elt, tem;
1160 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1161 {
1162 elt = Fcar (tail);
1163 if (!CONSP (elt)) continue;
1164 tem = Fcar (elt);
1165 if (HACKEQ_UNSAFE (key, tem)) return elt;
1166 QUIT;
1167 }
1168 return Qnil;
1169 }
1170
1171 /* Like Fassq but never report an error and do not allow quits.
1172 Use only on lists known never to be circular. */
1173
1174 Lisp_Object
1175 assq_no_quit (Lisp_Object key, Lisp_Object list)
1176 {
1177 /* This cannot GC. */
1178 REGISTER Lisp_Object tail, elt, tem;
1179 for (tail = list; CONSP (tail); tail = XCDR (tail))
1180 {
1181 elt = XCAR (tail);
1182 if (!CONSP (elt)) continue;
1183 tem = XCAR (elt);
1184 if (HACKEQ_UNSAFE (key, tem)) return elt;
1185 }
1186 return Qnil;
1187 }
1188
1189 DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0 /*
1190 Return non-nil if KEY is `equal' to the cdr of an element of LIST.
1191 The value is actually the element of LIST whose cdr equals KEY.
1192 */ )
1193 (key, list)
1194 Lisp_Object key;
1195 Lisp_Object list;
1196 {
1197 REGISTER Lisp_Object tail;
1198 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1199 {
1200 REGISTER Lisp_Object elt, tem;
1201 elt = Fcar (tail);
1202 if (!CONSP (elt)) continue;
1203 tem = Fequal (Fcdr (elt), key);
1204 if (!NILP (tem)) return elt;
1205 QUIT;
1206 }
1207 return Qnil;
1208 }
1209
1210 DEFUN ("rassq", Frassq, Srassq, 2, 2, 0 /*
1211 Return non-nil if KEY is `eq' to the cdr of an element of LIST.
1212 The value is actually the element of LIST whose cdr is KEY.
1213 */ )
1214 (key, list)
1215 Lisp_Object key;
1216 Lisp_Object list;
1217 {
1218 REGISTER Lisp_Object tail, elt, tem;
1219 for (tail = list; !NILP (tail); tail = Fcdr (tail))
1220 {
1221 elt = Fcar (tail);
1222 if (!CONSP (elt)) continue;
1223 tem = Fcdr (elt);
1224 if (HACKEQ_UNSAFE (key, tem)) return elt;
1225 QUIT;
1226 }
1227 return Qnil;
1228 }
1229
1230 Lisp_Object
1231 rassq_no_quit (Lisp_Object key, Lisp_Object list)
1232 {
1233 REGISTER Lisp_Object tail, elt, tem;
1234 for (tail = list; CONSP (tail); tail = XCDR (tail))
1235 {
1236 elt = XCAR (tail);
1237 if (!CONSP (elt)) continue;
1238 tem = XCDR (elt);
1239 if (HACKEQ_UNSAFE (key, tem)) return elt;
1240 }
1241 return Qnil;
1242 }
1243
1244
1245 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0 /*
1246 Delete by side effect any occurrences of ELT as a member of LIST.
1247 The modified LIST is returned. Comparison is done with `equal'.
1248 If the first member of LIST is ELT, there is no way to remove it by side
1249 effect; therefore, write `(setq foo (delete element foo))' to be sure
1250 of changing the value of `foo'.
1251 */ )
1252 (elt, list)
1253 Lisp_Object elt;
1254 Lisp_Object list;
1255 {
1256 REGISTER Lisp_Object tail, prev;
1257
1258 tail = list;
1259 prev = Qnil;
1260 while (!NILP (tail))
1261 {
1262 if (!NILP (Fequal (elt, Fcar (tail))))
1263 {
1264 if (NILP (prev))
1265 list = Fcdr (tail);
1266 else
1267 Fsetcdr (prev, Fcdr (tail));
1268 }
1269 else
1270 prev = tail;
1271 tail = Fcdr (tail);
1272 QUIT;
1273 }
1274 return list;
1275 }
1276
1277 DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0 /*
1278 Delete by side effect any occurrences of ELT as a member of LIST.
1279 The modified LIST is returned. Comparison is done with `eq'.
1280 If the first member of LIST is ELT, there is no way to remove it by side
1281 effect; therefore, write `(setq foo (delq element foo))' to be sure of
1282 changing the value of `foo'.
1283 */ )
1284 (elt, list)
1285 Lisp_Object elt;
1286 Lisp_Object list;
1287 {
1288 REGISTER Lisp_Object tail, prev;
1289 REGISTER Lisp_Object tem;
1290
1291 tail = list;
1292 prev = Qnil;
1293 while (!NILP (tail))
1294 {
1295 tem = Fcar (tail);
1296 if (HACKEQ_UNSAFE (elt, tem))
1297 {
1298 if (NILP (prev))
1299 list = Fcdr (tail);
1300 else
1301 Fsetcdr (prev, Fcdr (tail));
1302 }
1303 else
1304 prev = tail;
1305 tail = Fcdr (tail);
1306 QUIT;
1307 }
1308 return list;
1309 }
1310
1311 /* no quit, no errors; be careful */
1312
1313 Lisp_Object
1314 delq_no_quit (Lisp_Object elt, Lisp_Object list)
1315 {
1316 REGISTER Lisp_Object tail, prev;
1317 REGISTER Lisp_Object tem;
1318
1319 tail = list;
1320 prev = Qnil;
1321 while (CONSP (tail))
1322 {
1323 tem = XCAR (tail);
1324 if (HACKEQ_UNSAFE (elt, tem))
1325 {
1326 if (NILP (prev))
1327 list = XCDR (tail);
1328 else
1329 XCDR (prev) = XCDR (tail);
1330 }
1331 else
1332 prev = tail;
1333 tail = XCDR (tail);
1334 }
1335 return list;
1336 }
1337
1338 /* Be VERY careful with this. This is like delq_no_quit() but
1339 also calls free_cons() on the removed conses. You must be SURE
1340 that no pointers to the freed conses remain around (e.g.
1341 someone else is pointing to part of the list). This function
1342 is useful on internal lists that are used frequently and where
1343 the actual list doesn't escape beyond known code bounds. */
1344
1345 Lisp_Object
1346 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list)
1347 {
1348 REGISTER Lisp_Object tail, prev;
1349 REGISTER Lisp_Object tem;
1350
1351 tail = list;
1352 prev = Qnil;
1353 while (CONSP (tail))
1354 {
1355 Lisp_Object cons_to_free = Qnil;
1356 tem = XCAR (tail);
1357 if (HACKEQ_UNSAFE (elt, tem))
1358 {
1359 if (NILP (prev))
1360 list = XCDR (tail);
1361 else
1362 XCDR (prev) = XCDR (tail);
1363 cons_to_free = tail;
1364 }
1365 else
1366 prev = tail;
1367 tail = XCDR (tail);
1368 if (!NILP (cons_to_free))
1369 free_cons (XCONS (cons_to_free));
1370 }
1371 return list;
1372 }
1373
1374 DEFUN ("remassoc", Fremassoc, Sremassoc, 2, 2, 0 /*
1375 Delete by side effect any elements of LIST whose car is `equal' to KEY.
1376 The modified LIST is returned. If the first member of LIST has a car
1377 that is `equal' to KEY, there is no way to remove it by side effect;
1378 therefore, write `(setq foo (remassoc key foo))' to be sure of changing
1379 the value of `foo'.
1380 */ )
1381 (key, list)
1382 Lisp_Object key;
1383 Lisp_Object list;
1384 {
1385 REGISTER Lisp_Object tail, prev;
1386
1387 tail = list;
1388 prev = Qnil;
1389 while (!NILP (tail))
1390 {
1391 Lisp_Object elt = Fcar (tail);
1392 if (CONSP (elt) && ! NILP (Fequal (key, Fcar (elt))))
1393 {
1394 if (NILP (prev))
1395 list = Fcdr (tail);
1396 else
1397 Fsetcdr (prev, Fcdr (tail));
1398 }
1399 else
1400 prev = tail;
1401 tail = Fcdr (tail);
1402 QUIT;
1403 }
1404 return list;
1405 }
1406
1407 Lisp_Object
1408 remassoc_no_quit (Lisp_Object key, Lisp_Object list)
1409 {
1410 int speccount = specpdl_depth ();
1411 specbind (Qinhibit_quit, Qt);
1412 return (unbind_to (speccount, Fremassoc (key, list)));
1413 }
1414
1415 DEFUN ("remassq", Fremassq, Sremassq, 2, 2, 0 /*
1416 Delete by side effect any elements of LIST whose car is `eq' to KEY.
1417 The modified LIST is returned. If the first member of LIST has a car
1418 that is `eq' to KEY, there is no way to remove it by side effect;
1419 therefore, write `(setq foo (remassq key foo))' to be sure of changing
1420 the value of `foo'.
1421 */ )
1422 (key, list)
1423 Lisp_Object key;
1424 Lisp_Object list;
1425 {
1426 REGISTER Lisp_Object tail, prev;
1427
1428 tail = list;
1429 prev = Qnil;
1430 while (!NILP (tail))
1431 {
1432 Lisp_Object elt = Fcar (tail);
1433 if (CONSP (elt) && HACKEQ_UNSAFE (key, Fcar (elt)))
1434 {
1435 if (NILP (prev))
1436 list = Fcdr (tail);
1437 else
1438 Fsetcdr (prev, Fcdr (tail));
1439 }
1440 else
1441 prev = tail;
1442 tail = Fcdr (tail);
1443 QUIT;
1444 }
1445 return list;
1446 }
1447
1448 /* no quit, no errors; be careful */
1449
1450 Lisp_Object
1451 remassq_no_quit (Lisp_Object key, Lisp_Object list)
1452 {
1453 REGISTER Lisp_Object tail, prev;
1454 REGISTER Lisp_Object tem;
1455
1456 tail = list;
1457 prev = Qnil;
1458 while (CONSP (tail))
1459 {
1460 tem = XCAR (tail);
1461 if (CONSP (tem) && HACKEQ_UNSAFE (key, XCAR (tem)))
1462 {
1463 if (NILP (prev))
1464 list = XCDR (tail);
1465 else
1466 XCDR (prev) = XCDR (tail);
1467 }
1468 else
1469 prev = tail;
1470 tail = XCDR (tail);
1471 }
1472 return list;
1473 }
1474
1475 DEFUN ("remrassoc", Fremrassoc, Sremrassoc, 2, 2, 0 /*
1476 Delete by side effect any elements of LIST whose cdr is `equal' to VALUE.
1477 The modified LIST is returned. If the first member of LIST has a car
1478 that is `equal' to VALUE, there is no way to remove it by side effect;
1479 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing
1480 the value of `foo'.
1481 */ )
1482 (value, list)
1483 Lisp_Object value;
1484 Lisp_Object list;
1485 {
1486 REGISTER Lisp_Object tail, prev;
1487
1488 tail = list;
1489 prev = Qnil;
1490 while (!NILP (tail))
1491 {
1492 Lisp_Object elt = Fcar (tail);
1493 if (CONSP (elt) && ! NILP (Fequal (value, Fcdr (elt))))
1494 {
1495 if (NILP (prev))
1496 list = Fcdr (tail);
1497 else
1498 Fsetcdr (prev, Fcdr (tail));
1499 }
1500 else
1501 prev = tail;
1502 tail = Fcdr (tail);
1503 QUIT;
1504 }
1505 return list;
1506 }
1507
1508 DEFUN ("remrassq", Fremrassq, Sremrassq, 2, 2, 0 /*
1509 Delete by side effect any elements of LIST whose cdr is `eq' to VALUE.
1510 The modified LIST is returned. If the first member of LIST has a car
1511 that is `eq' to VALUE, there is no way to remove it by side effect;
1512 therefore, write `(setq foo (remrassq value foo))' to be sure of changing
1513 the value of `foo'.
1514 */ )
1515 (value, list)
1516 Lisp_Object value;
1517 Lisp_Object list;
1518 {
1519 REGISTER Lisp_Object tail, prev;
1520
1521 tail = list;
1522 prev = Qnil;
1523 while (!NILP (tail))
1524 {
1525 Lisp_Object elt = Fcar (tail);
1526 if (CONSP (elt) && HACKEQ_UNSAFE (value, Fcdr (elt)))
1527 {
1528 if (NILP (prev))
1529 list = Fcdr (tail);
1530 else
1531 Fsetcdr (prev, Fcdr (tail));
1532 }
1533 else
1534 prev = tail;
1535 tail = Fcdr (tail);
1536 QUIT;
1537 }
1538 return list;
1539 }
1540
1541 /* no quit, no errors; be careful */
1542
1543 Lisp_Object
1544 remrassq_no_quit (Lisp_Object value, Lisp_Object list)
1545 {
1546 REGISTER Lisp_Object tail, prev;
1547 REGISTER Lisp_Object tem;
1548
1549 tail = list;
1550 prev = Qnil;
1551 while (CONSP (tail))
1552 {
1553 tem = XCAR (tail);
1554 if (CONSP (tem) && HACKEQ_UNSAFE (value, XCDR (tem)))
1555 {
1556 if (NILP (prev))
1557 list = XCDR (tail);
1558 else
1559 XCDR (prev) = XCDR (tail);
1560 }
1561 else
1562 prev = tail;
1563 tail = XCDR (tail);
1564 }
1565 return list;
1566 }
1567
1568 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0 /*
1569 Reverse LIST by modifying cdr pointers.
1570 Returns the beginning of the reversed list.
1571 */ )
1572 (list)
1573 Lisp_Object list;
1574 {
1575 Lisp_Object prev, tail, next;
1576 struct gcpro gcpro1, gcpro2;
1577
1578 /* We gcpro our args; see `nconc' */
1579 prev = Qnil;
1580 tail = list;
1581 GCPRO2 (prev, tail);
1582 while (!NILP (tail))
1583 {
1584 QUIT;
1585 next = Fcdr (tail);
1586 Fsetcdr (tail, prev);
1587 prev = tail;
1588 tail = next;
1589 }
1590 UNGCPRO;
1591 return prev;
1592 }
1593
1594 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0 /*
1595 Reverse LIST, copying. Returns the beginning of the reversed list.
1596 See also the function `nreverse', which is used more often.
1597 */ )
1598 (list)
1599 Lisp_Object list;
1600 {
1601 Lisp_Object length;
1602 Lisp_Object *vec;
1603 Lisp_Object tail;
1604 REGISTER int i;
1605
1606 length = Flength (list);
1607 vec = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object));
1608 for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail))
1609 vec[i] = Fcar (tail);
1610
1611 return Flist (XINT (length), vec);
1612 }
1613
1614 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
1615 Lisp_Object lisp_arg,
1616 int (*pred_fn) (Lisp_Object, Lisp_Object,
1617 Lisp_Object lisp_arg));
1618
1619 Lisp_Object
1620 list_sort (Lisp_Object list,
1621 Lisp_Object lisp_arg,
1622 int (*pred_fn) (Lisp_Object, Lisp_Object,
1623 Lisp_Object lisp_arg))
1624 {
1625 Lisp_Object front, back;
1626 Lisp_Object len, tem;
1627 struct gcpro gcpro1, gcpro2, gcpro3;
1628 int length;
1629
1630 front = list;
1631 len = Flength (list);
1632 length = XINT (len);
1633 if (length < 2)
1634 return list;
1635
1636 XSETINT (len, (length / 2) - 1);
1637 tem = Fnthcdr (len, list);
1638 back = Fcdr (tem);
1639 Fsetcdr (tem, Qnil);
1640
1641 GCPRO3 (front, back, lisp_arg);
1642 front = list_sort (front, lisp_arg, pred_fn);
1643 back = list_sort (back, lisp_arg, pred_fn);
1644 UNGCPRO;
1645 return list_merge (front, back, lisp_arg, pred_fn);
1646 }
1647
1648
1649 static int
1650 merge_pred_function (Lisp_Object obj1, Lisp_Object obj2,
1651 Lisp_Object pred)
1652 {
1653 Lisp_Object tmp;
1654
1655 /* prevents the GC from happening in call2 */
1656 int speccount = specpdl_depth ();
1657 /* Emacs' GC doesn't actually relocate pointers, so this probably
1658 isn't strictly necessary */
1659 record_unwind_protect (restore_gc_inhibit,
1660 make_int (gc_currently_forbidden));
1661 gc_currently_forbidden = 1;
1662 tmp = call2 (pred, obj1, obj2);
1663 unbind_to (speccount, Qnil);
1664
1665 if (NILP (tmp))
1666 return -1;
1667 else
1668 return 1;
1669 }
1670
1671 DEFUN ("sort", Fsort, Ssort, 2, 2, 0 /*
1672 Sort LIST, stably, comparing elements using PREDICATE.
1673 Returns the sorted list. LIST is modified by side effects.
1674 PREDICATE is called with two elements of LIST, and should return T
1675 if the first element is \"less\" than the second.
1676 */ )
1677 (list, pred)
1678 Lisp_Object list, pred;
1679 {
1680 return list_sort (list, pred, merge_pred_function);
1681 }
1682
1683 Lisp_Object
1684 merge (Lisp_Object org_l1, Lisp_Object org_l2,
1685 Lisp_Object pred)
1686 {
1687 return list_merge (org_l1, org_l2, pred, merge_pred_function);
1688 }
1689
1690
1691 static Lisp_Object
1692 list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
1693 Lisp_Object lisp_arg,
1694 int (*pred_fn) (Lisp_Object, Lisp_Object, Lisp_Object lisp_arg))
1695 {
1696 Lisp_Object value;
1697 Lisp_Object tail;
1698 Lisp_Object tem;
1699 Lisp_Object l1, l2;
1700 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1701
1702 l1 = org_l1;
1703 l2 = org_l2;
1704 tail = Qnil;
1705 value = Qnil;
1706
1707 /* It is sufficient to protect org_l1 and org_l2.
1708 When l1 and l2 are updated, we copy the new values
1709 back into the org_ vars. */
1710
1711 GCPRO4 (org_l1, org_l2, lisp_arg, value);
1712
1713 while (1)
1714 {
1715 if (NILP (l1))
1716 {
1717 UNGCPRO;
1718 if (NILP (tail))
1719 return l2;
1720 Fsetcdr (tail, l2);
1721 return value;
1722 }
1723 if (NILP (l2))
1724 {
1725 UNGCPRO;
1726 if (NILP (tail))
1727 return l1;
1728 Fsetcdr (tail, l1);
1729 return value;
1730 }
1731
1732 if (((*pred_fn) (Fcar (l2), Fcar (l1), lisp_arg)) < 0)
1733 {
1734 tem = l1;
1735 l1 = Fcdr (l1);
1736 org_l1 = l1;
1737 }
1738 else
1739 {
1740 tem = l2;
1741 l2 = Fcdr (l2);
1742 org_l2 = l2;
1743 }
1744 if (NILP (tail))
1745 value = tem;
1746 else
1747 Fsetcdr (tail, tem);
1748 tail = tem;
1749 }
1750 }
1751
1752
1753 /************************************************************************/
1754 /* property-list functions */
1755 /************************************************************************/
1756
1757 /* For properties of text, we need to do order-insensitive comparison of
1758 plists. That is, we need to compare two plists such that they are the
1759 same if they have the same set of keys, and equivalent values.
1760 So (a 1 b 2) would be equal to (b 2 a 1).
1761
1762 NIL_MEANS_NOT_PRESENT is as in `plists-eq' etc.
1763 LAXP means use `equal' for comparisons.
1764 */
1765 int
1766 plists_differ (Lisp_Object a, Lisp_Object b, int nil_means_not_present,
1767 int laxp, int depth)
1768 {
1769 int eqp = (depth == -1); /* -1 as depth means us eq, not equal. */
1770 int la, lb, m, i, fill;
1771 Lisp_Object *keys, *vals;
1772 char *flags;
1773 Lisp_Object rest;
1774
1775 if (NILP (a) && NILP (b))
1776 return 0;
1777
1778 Fcheck_valid_plist (a);
1779 Fcheck_valid_plist (b);
1780
1781 la = XINT (Flength (a));
1782 lb = XINT (Flength (b));
1783 m = (la > lb ? la : lb);
1784 fill = 0;
1785 keys = (Lisp_Object *) alloca (m * sizeof (Lisp_Object));
1786 vals = (Lisp_Object *) alloca (m * sizeof (Lisp_Object));
1787 flags = (char *) alloca (m * sizeof (char));
1788
1789 /* First extract the pairs from A. */
1790 for (rest = a; !NILP (rest); rest = XCDR (XCDR (rest)))
1791 {
1792 Lisp_Object k = XCAR (rest);
1793 Lisp_Object v = XCAR (XCDR (rest));
1794 /* Maybe be Ebolified. */
1795 if (nil_means_not_present && NILP (v)) continue;
1796 keys [fill] = k;
1797 vals [fill] = v;
1798 flags[fill] = 0;
1799 fill++;
1800 }
1801 /* Now iterate over B, and stop if we find something that's not in A,
1802 or that doesn't match. As we match, mark them. */
1803 for (rest = b; !NILP (rest); rest = XCDR (XCDR (rest)))
1804 {
1805 Lisp_Object k = XCAR (rest);
1806 Lisp_Object v = XCAR (XCDR (rest));
1807 /* Maybe be Ebolified. */
1808 if (nil_means_not_present && NILP (v)) continue;
1809 for (i = 0; i < fill; i++)
1810 {
1811 if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth))
1812 {
1813 if ((eqp
1814 /* Ebolified here too, sigh ... */
1815 ? !HACKEQ_UNSAFE (v, vals [i])
1816 : !internal_equal (v, vals [i], depth)))
1817 /* a property in B has a different value than in A */
1818 goto MISMATCH;
1819 flags [i] = 1;
1820 break;
1821 }
1822 }
1823 if (i == fill)
1824 /* there are some properties in B that are not in A */
1825 goto MISMATCH;
1826 }
1827 /* Now check to see that all the properties in A were also in B */
1828 for (i = 0; i < fill; i++)
1829 if (flags [i] == 0)
1830 goto MISMATCH;
1831
1832 /* Ok. */
1833 return 0;
1834
1835 MISMATCH:
1836 return 1;
1837 }
1838
1839 DEFUN ("plists-eq", Fplists_eq, Splists_eq, 2, 3, 0 /*
1840 Return non-nil if property lists A and B are `eq'.
1841 A property list is an alternating list of keywords and values.
1842 This function does order-insensitive comparisons of the property lists:
1843 For example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
1844 Comparison between values is done using `eq'. See also `plists-equal'.
1845 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
1846 a nil value is ignored. This feature is a virus that has infected
1847 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
1848 old Lisps), but should not be used except for backward compatibility.
1849 */ )
1850 (a, b, nil_means_not_present)
1851 Lisp_Object a, b, nil_means_not_present;
1852 {
1853 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, -1)
1854 ? Qnil : Qt);
1855 }
1856
1857 DEFUN ("plists-equal", Fplists_equal, Splists_equal, 2, 3, 0 /*
1858 Return non-nil if property lists A and B are `equal'.
1859 A property list is an alternating list of keywords and values. This
1860 function does order-insensitive comparisons of the property lists: For
1861 example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
1862 Comparison between values is done using `equal'. See also `plists-eq'.
1863 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
1864 a nil value is ignored. This feature is a virus that has infected
1865 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
1866 old Lisps), but should not be used except for backward compatibility.
1867 */ )
1868 (a, b, nil_means_not_present)
1869 Lisp_Object a, b, nil_means_not_present;
1870 {
1871 return (plists_differ (a, b, !NILP (nil_means_not_present), 0, 1)
1872 ? Qnil : Qt);
1873 }
1874
1875
1876 DEFUN ("lax-plists-eq", Flax_plists_eq, Slax_plists_eq, 2, 3, 0 /*
1877 Return non-nil if lax property lists A and B are `eq'.
1878 A property list is an alternating list of keywords and values.
1879 This function does order-insensitive comparisons of the property lists:
1880 For example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
1881 Comparison between values is done using `eq'. See also `plists-equal'.
1882 A lax property list is like a regular one except that comparisons between
1883 keywords is done using `equal' instead of `eq'.
1884 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
1885 a nil value is ignored. This feature is a virus that has infected
1886 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
1887 old Lisps), but should not be used except for backward compatibility.
1888 */ )
1889 (a, b, nil_means_not_present)
1890 Lisp_Object a, b, nil_means_not_present;
1891 {
1892 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, -1)
1893 ? Qnil : Qt);
1894 }
1895
1896 DEFUN ("lax-plists-equal", Flax_plists_equal, Slax_plists_equal, 2, 3, 0 /*
1897 Return non-nil if lax property lists A and B are `equal'.
1898 A property list is an alternating list of keywords and values. This
1899 function does order-insensitive comparisons of the property lists: For
1900 example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
1901 Comparison between values is done using `equal'. See also `plists-eq'.
1902 A lax property list is like a regular one except that comparisons between
1903 keywords is done using `equal' instead of `eq'.
1904 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
1905 a nil value is ignored. This feature is a virus that has infected
1906 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
1907 old Lisps), but should not be used except for backward compatibility.
1908 */ )
1909 (a, b, nil_means_not_present)
1910 Lisp_Object a, b, nil_means_not_present;
1911 {
1912 return (plists_differ (a, b, !NILP (nil_means_not_present), 1, 1)
1913 ? Qnil : Qt);
1914 }
1915
1916 /* Return the value associated with key PROPERTY in property list PLIST.
1917 Return nil if key not found. This function is used for internal
1918 property lists that cannot be directly manipulated by the user.
1919 */
1920
1921 Lisp_Object
1922 internal_plist_get (Lisp_Object plist, Lisp_Object property)
1923 {
1924 Lisp_Object tail = plist;
1925
1926 for (; !NILP (tail); tail = XCDR (XCDR (tail)))
1927 {
1928 struct Lisp_Cons *c = XCONS (tail);
1929 if (EQ (c->car, property))
1930 return XCAR (c->cdr);
1931 }
1932
1933 return Qunbound;
1934 }
1935
1936 /* Set PLIST's value for PROPERTY to VALUE. Analogous to
1937 internal_plist_get(). */
1938
1939 void
1940 internal_plist_put (Lisp_Object *plist, Lisp_Object property,
1941 Lisp_Object value)
1942 {
1943 Lisp_Object tail = *plist;
1944
1945 for (; !NILP (tail); tail = XCDR (XCDR (tail)))
1946 {
1947 struct Lisp_Cons *c = XCONS (tail);
1948 if (EQ (c->car, property))
1949 {
1950 XCAR (c->cdr) = value;
1951 return;
1952 }
1953 }
1954
1955 *plist = Fcons (property, Fcons (value, *plist));
1956 }
1957
1958 int
1959 internal_remprop (Lisp_Object *plist, Lisp_Object property)
1960 {
1961 Lisp_Object tail = *plist;
1962
1963 if (NILP (tail))
1964 return 0;
1965
1966 if (EQ (XCAR (tail), property))
1967 {
1968 *plist = XCDR (XCDR (tail));
1969 return 1;
1970 }
1971
1972 for (tail = XCDR (tail); !NILP (XCDR (tail));
1973 tail = XCDR (XCDR (tail)))
1974 {
1975 struct Lisp_Cons *c = XCONS (tail);
1976 if (EQ (XCAR (c->cdr), property))
1977 {
1978 c->cdr = XCDR (XCDR (c->cdr));
1979 return 1;
1980 }
1981 }
1982
1983 return 0;
1984 }
1985
1986 /* Called on a malformed property list. BADPLACE should be some
1987 place where truncating will form a good list -- i.e. we shouldn't
1988 result in a list with an odd length. */
1989
1990 static Lisp_Object
1991 bad_bad_bunny (Lisp_Object *plist, Lisp_Object *badplace, Error_behavior errb)
1992 {
1993 if (ERRB_EQ (errb, ERROR_ME))
1994 return Fsignal (Qmalformed_property_list, list2 (*plist, *badplace));
1995 else
1996 {
1997 if (ERRB_EQ (errb, ERROR_ME_WARN))
1998 {
1999 warn_when_safe_lispobj
2000 (Qlist, Qwarning,
2001 list2 (build_string
2002 ("Malformed property list -- list has been truncated"),
2003 *plist));
2004 *badplace = Qnil;
2005 }
2006 return Qunbound;
2007 }
2008 }
2009
2010 /* Called on a circular property list. BADPLACE should be some place
2011 where truncating will result in an even-length list, as above.
2012 If doesn't particularly matter where we truncate -- anywhere we
2013 truncate along the entire list will break the circularity, because
2014 it will create a terminus and the list currently doesn't have one.
2015 */
2016
2017 static Lisp_Object
2018 bad_bad_turtle (Lisp_Object *plist, Lisp_Object *badplace, Error_behavior errb)
2019 {
2020 if (ERRB_EQ (errb, ERROR_ME))
2021 /* #### Eek, this will probably result in another error
2022 when PLIST is printed out */
2023 return Fsignal (Qcircular_property_list, list1 (*plist));
2024 else
2025 {
2026 if (ERRB_EQ (errb, ERROR_ME_WARN))
2027 {
2028 warn_when_safe_lispobj
2029 (Qlist, Qwarning,
2030 list2 (build_string
2031 ("Circular property list -- list has been truncated"),
2032 *plist));
2033 *badplace = Qnil;
2034 }
2035 return Qunbound;
2036 }
2037 }
2038
2039 /* Advance the tortoise pointer by two (one iteration of a property-list
2040 loop) and the hare pointer by four and verify that no malformations
2041 or circularities exist. If so, return zero and store a value into
2042 RETVAL that should be returned by the calling function. Otherwise,
2043 return 1. See external_plist_get().
2044 */
2045
2046 static int
2047 advance_plist_pointers (Lisp_Object *plist,
2048 Lisp_Object **tortoise, Lisp_Object **hare,
2049 Error_behavior errb, Lisp_Object *retval)
2050 {
2051 int i;
2052 Lisp_Object *tortsave = *tortoise;
2053
2054 /* Note that our "fixing" may be more brutal than necessary,
2055 but it's the user's own problem, not ours. if they went in and
2056 manually fucked up a plist. */
2057
2058 for (i = 0; i < 2; i++)
2059 {
2060 /* This is a standard iteration of a defensive-loop-checking
2061 loop. We just do it twice because we want to advance past
2062 both the property and its value.
2063
2064 If the pointer indirection is confusing you, remember that
2065 one level of indirection on the hare and tortoise pointers
2066 is only due to pass-by-reference for this function. The other
2067 level is so that the plist can be fixed in place. */
2068
2069 /* When we reach the end of a well-formed plist, **HARE is
2070 nil. In that case, we don't do anything at all except
2071 advance TORTOISE by one. Otherwise, we advance HARE
2072 by two (making sure it's OK to do so), then advance
2073 TORTOISE by one (it will always be OK to do so because
2074 the HARE is always ahead of the TORTOISE and will have
2075 already verified the path), then make sure TORTOISE and
2076 HARE don't contain the same non-nil object -- if the
2077 TORTOISE and the HARE ever meet, then obviously we're
2078 in a circularity, and if we're in a circularity, then
2079 the TORTOISE and the HARE can't cross paths without
2080 meeting, since the HARE only gains one step over the
2081 TORTOISE per iteration. */
2082
2083 if (!NILP (**hare))
2084 {
2085 Lisp_Object *haresave = *hare;
2086 if (!CONSP (**hare))
2087 {
2088 *retval = bad_bad_bunny (plist, haresave, errb);
2089 return 0;
2090 }
2091 *hare = &XCDR (**hare);
2092 /* In a non-plist, we'd check here for a nil value for
2093 **HARE, which is OK (it just means the list has an
2094 odd number of elements). In a plist, it's not OK
2095 for the list to have an odd number of elements. */
2096 if (!CONSP (**hare))
2097 {
2098 *retval = bad_bad_bunny (plist, haresave, errb);
2099 return 0;
2100 }
2101 *hare = &XCDR (**hare);
2102 }
2103
2104 *tortoise = &XCDR (**tortoise);
2105 if (!NILP (**hare) && EQ (**tortoise, **hare))
2106 {
2107 *retval = bad_bad_turtle (plist, tortsave, errb);
2108 return 0;
2109 }
2110 }
2111
2112 return 1;
2113 }
2114
2115 /* Return the value of PROPERTY from PLIST, or Qunbound if
2116 property is not on the list.
2117
2118 PLIST is a Lisp-accessible property list, meaning that it
2119 has to be checked for malformations and circularities.
2120
2121 If ERRB is ERROR_ME, an error will be signalled. Otherwise, the
2122 function will never signal an error; and if ERRB is ERROR_ME_WARN,
2123 on finding a malformation or a circularity, it issues a warning and
2124 attempts to silently fix the problem.
2125
2126 A pointer to PLIST is passed in so that PLIST can be successfully
2127 "fixed" even if the error is at the beginning of the plist. */
2128
2129 Lisp_Object
2130 external_plist_get (Lisp_Object *plist, Lisp_Object property,
2131 int laxp, Error_behavior errb)
2132 {
2133 Lisp_Object *tortoise = plist;
2134 Lisp_Object *hare = plist;
2135
2136 while (!NILP (*tortoise))
2137 {
2138 Lisp_Object *tortsave = tortoise;
2139 Lisp_Object retval;
2140
2141 /* We do the standard tortoise/hare march. We isolate the
2142 grungy stuff to do this in advance_plist_pointers(), though.
2143 To us, all this function does is advance the tortoise
2144 pointer by two and the hare pointer by four and make sure
2145 everything's OK. We first advance the pointers and then
2146 check if a property matched; this ensures that our
2147 check for a matching property is safe. */
2148
2149 if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2150 return retval;
2151
2152 if (!laxp ? EQ (XCAR (*tortsave), property)
2153 : internal_equal (XCAR (*tortsave), property, 0))
2154 return XCAR (XCDR (*tortsave));
2155 }
2156
2157 return Qunbound;
2158 }
2159
2160 /* Set PLIST's value for PROPERTY to VALUE, given a possibly
2161 malformed or circular plist. Analogous to external_plist_get(). */
2162
2163 void
2164 external_plist_put (Lisp_Object *plist, Lisp_Object property,
2165 Lisp_Object value, int laxp, Error_behavior errb)
2166 {
2167 Lisp_Object *tortoise = plist;
2168 Lisp_Object *hare = plist;
2169
2170 while (!NILP (*tortoise))
2171 {
2172 Lisp_Object *tortsave = tortoise;
2173 Lisp_Object retval;
2174
2175 /* See above */
2176 if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2177 return;
2178
2179 if (!laxp ? EQ (XCAR (*tortsave), property)
2180 : internal_equal (XCAR (*tortsave), property, 0))
2181 {
2182 XCAR (XCDR (*tortsave)) = value;
2183 return;
2184 }
2185 }
2186
2187 *plist = Fcons (property, Fcons (value, *plist));
2188 }
2189
2190 int
2191 external_remprop (Lisp_Object *plist, Lisp_Object property,
2192 int laxp, Error_behavior errb)
2193 {
2194 Lisp_Object *tortoise = plist;
2195 Lisp_Object *hare = plist;
2196
2197 while (!NILP (*tortoise))
2198 {
2199 Lisp_Object *tortsave = tortoise;
2200 Lisp_Object retval;
2201
2202 /* See above */
2203 if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2204 return 0;
2205
2206 if (!laxp ? EQ (XCAR (*tortsave), property)
2207 : internal_equal (XCAR (*tortsave), property, 0))
2208 {
2209 /* Now you see why it's so convenient to have that level
2210 of indirection. */
2211 *tortsave = XCDR (XCDR (*tortsave));
2212 return 1;
2213 }
2214 }
2215
2216 return 0;
2217 }
2218
2219 DEFUN ("plist-get", Fplist_get, Splist_get, 2, 3, 0 /*
2220 Extract a value from a property list.
2221 PLIST is a property list, which is a list of the form
2222 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
2223 corresponding to the given PROP, or DEFAULT if PROP is not
2224 one of the properties on the list.
2225 */ )
2226 (plist, prop, defalt) /* Cant spel in C */
2227 Lisp_Object plist, prop, defalt;
2228 {
2229 Lisp_Object val = external_plist_get (&plist, prop, 0, ERROR_ME);
2230 if (UNBOUNDP (val))
2231 return defalt;
2232 return val;
2233 }
2234
2235 DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0 /*
2236 Change value in PLIST of PROP to VAL.
2237 PLIST is a property list, which is a list of the form \(PROP1 VALUE1
2238 PROP2 VALUE2 ...). PROP is usually a symbol and VAL is any object.
2239 If PROP is already a property on the list, its value is set to VAL,
2240 otherwise the new PROP VAL pair is added. The new plist is returned;
2241 use `(setq x (plist-put x prop val))' to be sure to use the new value.
2242 The PLIST is modified by side effects.
2243 */ )
2244 (plist, prop, val)
2245 Lisp_Object plist, prop, val;
2246 {
2247 external_plist_put (&plist, prop, val, 0, ERROR_ME);
2248 return plist;
2249 }
2250
2251 DEFUN ("plist-remprop", Fplist_remprop, Splist_remprop, 2, 2, 0 /*
2252 Remove from PLIST the property PROP and its value.
2253 PLIST is a property list, which is a list of the form \(PROP1 VALUE1
2254 PROP2 VALUE2 ...). PROP is usually a symbol. The new plist is
2255 returned; use `(setq x (plist-remprop x prop val))' to be sure to use
2256 the new value. The PLIST is modified by side effects.
2257 */ )
2258 (plist, prop)
2259 Lisp_Object plist, prop;
2260 {
2261 external_remprop (&plist, prop, 0, ERROR_ME);
2262 return plist;
2263 }
2264
2265 DEFUN ("plist-member", Fplist_member, Splist_member, 2, 2, 0 /*
2266 Return t if PROP has a value specified in PLIST.
2267 */ )
2268 (plist, prop)
2269 Lisp_Object plist, prop;
2270 {
2271 return UNBOUNDP (Fplist_get (plist, prop, Qunbound)) ? Qnil : Qt;
2272 }
2273
2274 DEFUN ("check-valid-plist", Fcheck_valid_plist, Scheck_valid_plist,
2275 1, 1, 0 /*
2276 Given a plist, signal an error if there is anything wrong with it.
2277 This means that it's a malformed or circular plist.
2278 */ )
2279 (plist)
2280 Lisp_Object plist;
2281 {
2282 Lisp_Object *tortoise;
2283 Lisp_Object *hare;
2284
2285 start_over:
2286 tortoise = &plist;
2287 hare = &plist;
2288 while (!NILP (*tortoise))
2289 {
2290 Lisp_Object retval;
2291
2292 /* See above */
2293 if (!advance_plist_pointers (&plist, &tortoise, &hare, ERROR_ME,
2294 &retval))
2295 goto start_over;
2296 }
2297
2298 return Qnil;
2299 }
2300
2301 DEFUN ("valid-plist-p", Fvalid_plist_p, Svalid_plist_p,
2302 1, 1, 0 /*
2303 Given a plist, return non-nil if its format is correct.
2304 If it returns nil, `check-valid-plist' will signal an error when given
2305 the plist; that means it's a malformed or circular plist or has non-symbols
2306 as keywords.
2307 */ )
2308 (plist)
2309 Lisp_Object plist;
2310 {
2311 Lisp_Object *tortoise;
2312 Lisp_Object *hare;
2313
2314 tortoise = &plist;
2315 hare = &plist;
2316 while (!NILP (*tortoise))
2317 {
2318 Lisp_Object retval;
2319
2320 /* See above */
2321 if (!advance_plist_pointers (&plist, &tortoise, &hare, ERROR_ME_NOT,
2322 &retval))
2323 return Qnil;
2324 }
2325
2326 return Qt;
2327 }
2328
2329 DEFUN ("canonicalize-plist", Fcanonicalize_plist, Scanonicalize_plist,
2330 1, 2, 0 /*
2331 Destructively remove any duplicate entries from a plist.
2332 In such cases, the first entry applies.
2333
2334 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2335 a nil value is removed. This feature is a virus that has infected
2336 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
2337 old Lisps), but should not be used except for backward compatibility.
2338
2339 The new plist is returned. If NIL-MEANS-NOT-PRESENT is given, the
2340 return value may not be EQ to the passed-in value, so make sure to
2341 `setq' the value back into where it came from.
2342 */ )
2343 (plist, nil_means_not_present)
2344 Lisp_Object plist, nil_means_not_present;
2345 {
2346 Lisp_Object head = plist;
2347
2348 Fcheck_valid_plist (plist);
2349
2350 while (!NILP (plist))
2351 {
2352 Lisp_Object prop = Fcar (plist);
2353 Lisp_Object next = Fcdr (plist);
2354
2355 CHECK_CONS (next); /* just make doubly sure we catch any errors */
2356 if (!NILP (nil_means_not_present) && NILP (Fcar (next)))
2357 {
2358 if (EQ (head, plist))
2359 head = Fcdr (next);
2360 plist = Fcdr (next);
2361 continue;
2362 }
2363 /* external_remprop returns 1 if it removed any property.
2364 We have to loop till it didn't remove anything, in case
2365 the property occurs many times. */
2366 while (external_remprop (&XCDR (next), prop, 0, ERROR_ME));
2367 plist = Fcdr (next);
2368 }
2369
2370 return head;
2371 }
2372
2373 DEFUN ("lax-plist-get", Flax_plist_get, Slax_plist_get, 2, 3, 0 /*
2374 Extract a value from a lax property list.
2375
2376 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2377 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2378 using `equal' instead of `eq'. This function returns the value
2379 corresponding to the given PROP, or DEFAULT if PROP is not one of the
2380 properties on the list.
2381 */ )
2382 (lax_plist, prop, defalt) /* Cant spel in C */
2383 Lisp_Object lax_plist, prop, defalt;
2384 {
2385 Lisp_Object val = external_plist_get (&lax_plist, prop, 1, ERROR_ME);
2386 if (UNBOUNDP (val))
2387 return defalt;
2388 return val;
2389 }
2390
2391 DEFUN ("lax-plist-put", Flax_plist_put, Slax_plist_put, 3, 3, 0 /*
2392 Change value in LAX-PLIST of PROP to VAL.
2393 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2394 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2395 using `equal' instead of `eq'. PROP is usually a symbol and VAL is
2396 any object. If PROP is already a property on the list, its value is
2397 set to VAL, otherwise the new PROP VAL pair is added. The new plist
2398 is returned; use `(setq x (lax-plist-put x prop val))' to be sure to
2399 use the new value. The LAX-PLIST is modified by side effects.
2400 */ )
2401 (lax_plist, prop, val)
2402 Lisp_Object lax_plist, prop, val;
2403 {
2404 external_plist_put (&lax_plist, prop, val, 1, ERROR_ME);
2405 return lax_plist;
2406 }
2407
2408 DEFUN ("lax-plist-remprop", Flax_plist_remprop, Slax_plist_remprop, 2, 2, 0 /*
2409 Remove from LAX-PLIST the property PROP and its value.
2410 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2411 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2412 using `equal' instead of `eq'. PROP is usually a symbol. The new
2413 plist is returned; use `(setq x (lax-plist-remprop x prop val))' to be
2414 sure to use the new value. The LAX-PLIST is modified by side effects.
2415 */ )
2416 (lax_plist, prop)
2417 Lisp_Object lax_plist, prop;
2418 {
2419 external_remprop (&lax_plist, prop, 1, ERROR_ME);
2420 return lax_plist;
2421 }
2422
2423 DEFUN ("lax-plist-member", Flax_plist_member, Slax_plist_member, 2, 2, 0 /*
2424 Return t if PROP has a value specified in LAX-PLIST.
2425 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2426 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2427 using `equal' instead of `eq'.
2428 */ )
2429 (lax_plist, prop)
2430 Lisp_Object lax_plist, prop;
2431 {
2432 return UNBOUNDP (Flax_plist_get (lax_plist, prop, Qunbound)) ? Qnil : Qt;
2433 }
2434
2435 DEFUN ("canonicalize-lax-plist", Fcanonicalize_lax_plist,
2436 Scanonicalize_lax_plist, 1, 2, 0 /*
2437 Destructively remove any duplicate entries from a lax plist.
2438 In such cases, the first entry applies.
2439
2440 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2441 a nil value is removed. This feature is a virus that has infected
2442 old Lisp implementations (and thus E-Lisp, due to RMS's enamorment with
2443 old Lisps), but should not be used except for backward compatibility.
2444
2445 The new plist is returned. If NIL-MEANS-NOT-PRESENT is given, the
2446 return value may not be EQ to the passed-in value, so make sure to
2447 `setq' the value back into where it came from.
2448 */ )
2449 (lax_plist, nil_means_not_present)
2450 Lisp_Object lax_plist, nil_means_not_present;
2451 {
2452 Lisp_Object head = lax_plist;
2453
2454 Fcheck_valid_plist (lax_plist);
2455
2456 while (!NILP (lax_plist))
2457 {
2458 Lisp_Object prop = Fcar (lax_plist);
2459 Lisp_Object next = Fcdr (lax_plist);
2460
2461 CHECK_CONS (next); /* just make doubly sure we catch any errors */
2462 if (!NILP (nil_means_not_present) && NILP (Fcar (next)))
2463 {
2464 if (EQ (head, lax_plist))
2465 head = Fcdr (next);
2466 lax_plist = Fcdr (next);
2467 continue;
2468 }
2469 /* external_remprop returns 1 if it removed any property.
2470 We have to loop till it didn't remove anything, in case
2471 the property occurs many times. */
2472 while (external_remprop (&XCDR (next), prop, 1, ERROR_ME));
2473 lax_plist = Fcdr (next);
2474 }
2475
2476 return head;
2477 }
2478
2479 /* In C because the frame props stuff uses it */
2480
2481 DEFUN ("destructive-alist-to-plist", Fdestructive_alist_to_plist,
2482 Sdestructive_alist_to_plist, 1, 1, 0 /*
2483 Convert association list ALIST into the equivalent property-list form.
2484 The plist is returned. This converts from
2485
2486 \((a . 1) (b . 2) (c . 3))
2487
2488 into
2489
2490 \(a 1 b 2 c 3)
2491
2492 The original alist is destroyed in the process of constructing the plist.
2493 See also `alist-to-plist'.
2494 */ )
2495 (alist)
2496 Lisp_Object alist;
2497 {
2498 Lisp_Object head = alist;
2499 while (!NILP (alist))
2500 {
2501 /* remember the alist element. */
2502 Lisp_Object el = Fcar (alist);
2503
2504 Fsetcar (alist, Fcar (el));
2505 Fsetcar (el, Fcdr (el));
2506 Fsetcdr (el, Fcdr (alist));
2507 Fsetcdr (alist, el);
2508 alist = Fcdr (Fcdr (alist));
2509 }
2510
2511 return head;
2512 }
2513
2514 /* Symbol plists are directly accessible, so we need to protect against
2515 invalid property list structure */
2516
2517 static Lisp_Object
2518 symbol_getprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object defalt)
2519 {
2520 Lisp_Object val = external_plist_get (&XSYMBOL (sym)->plist, propname,
2521 0, ERROR_ME);
2522 if (UNBOUNDP (val))
2523 return defalt;
2524 return val;
2525 }
2526
2527 static void
2528 symbol_putprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object value)
2529 {
2530 external_plist_put (&XSYMBOL (sym)->plist, propname, value, 0, ERROR_ME);
2531 }
2532
2533 static int
2534 symbol_remprop (Lisp_Object symbol, Lisp_Object propname)
2535 {
2536 return external_remprop (&XSYMBOL (symbol)->plist, propname, 0, ERROR_ME);
2537 }
2538
2539 /* We store the string's extent info as the first element of the string's
2540 property list; and the string's MODIFF as the first or second element
2541 of the string's property list (depending on whether the extent info
2542 is present), but only if the string has been modified. This is ugly
2543 but it reduces the memory allocated for the string in the vast
2544 majority of cases, where the string is never modified and has no
2545 extent info. */
2546
2547
2548 static Lisp_Object *
2549 string_plist_ptr (struct Lisp_String *s)
2550 {
2551 Lisp_Object *ptr = &s->plist;
2552
2553 if (CONSP (*ptr) && EXTENT_INFOP (XCAR (*ptr)))
2554 ptr = &XCDR (*ptr);
2555 if (CONSP (*ptr) && INTP (XCAR (*ptr)))
2556 ptr = &XCDR (*ptr);
2557 return ptr;
2558 }
2559
2560 Lisp_Object
2561 string_getprop (struct Lisp_String *s, Lisp_Object property,
2562 Lisp_Object defalt)
2563 {
2564 Lisp_Object val = external_plist_get (string_plist_ptr (s), property, 0,
2565 ERROR_ME);
2566 if (UNBOUNDP (val))
2567 return defalt;
2568 return val;
2569 }
2570
2571 void
2572 string_putprop (struct Lisp_String *s, Lisp_Object property,
2573 Lisp_Object value)
2574 {
2575 external_plist_put (string_plist_ptr (s), property, value, 0, ERROR_ME);
2576 }
2577
2578 static int
2579 string_remprop (struct Lisp_String *s, Lisp_Object property)
2580 {
2581 return external_remprop (string_plist_ptr (s), property, 0, ERROR_ME);
2582 }
2583
2584 static Lisp_Object
2585 string_plist (struct Lisp_String *s)
2586 {
2587 return *string_plist_ptr (s);
2588 }
2589
2590 DEFUN ("get", Fget, Sget, 2, 3, 0 /*
2591 Return the value of OBJECT's PROPNAME property.
2592 This is the last VALUE stored with `(put OBJECT PROPNAME VALUE)'.
2593 If there is no such property, return optional third arg DEFAULT
2594 (which defaults to `nil'). OBJECT can be a symbol, face, extent,
2595 or string. See also `put', `remprop', and `object-plist'.
2596 */ )
2597 (object, propname, defalt) /* Cant spel in C */
2598 Lisp_Object object, propname, defalt;
2599 {
2600 Lisp_Object val;
2601
2602 /* Various places in emacs call Fget() and expect it not to quit,
2603 so don't quit. */
2604
2605 /* It's easiest to treat symbols specially because they may not
2606 be an lrecord */
2607 if (SYMBOLP (object))
2608 val = symbol_getprop (object, propname, defalt);
2609 else if (STRINGP (object))
2610 val = string_getprop (XSTRING (object), propname, defalt);
2611 else if (LRECORDP (object))
2612 {
2613 CONST struct lrecord_implementation
2614 *imp = XRECORD_LHEADER (object)->implementation;
2615 if (imp->getprop)
2616 {
2617 val = (imp->getprop) (object, propname);
2618 if (UNBOUNDP (val))
2619 val = defalt;
2620 }
2621 else
2622 goto noprops;
2623 }
2624 else
2625 {
2626 noprops:
2627 signal_simple_error ("Object type has no properties", object);
2628 }
2629
2630 return val;
2631 }
2632
2633 DEFUN ("put", Fput, Sput, 3, 3, 0 /*
2634 Store OBJECT's PROPNAME property with value VALUE.
2635 It can be retrieved with `(get OBJECT PROPNAME)'. OBJECT can be a
2636 symbol, face, extent, or string.
2637
2638 For a string, no properties currently have predefined meanings.
2639 For the predefined properties for extents, see `set-extent-property'.
2640 For the predefined properties for faces, see `set-face-property'.
2641
2642 See also `get', `remprop', and `object-plist'.
2643 */ )
2644 (object, propname, value)
2645 Lisp_Object object;
2646 Lisp_Object propname;
2647 Lisp_Object value;
2648 {
2649 CHECK_SYMBOL (propname);
2650 CHECK_IMPURE (object);
2651
2652 if (SYMBOLP (object))
2653 symbol_putprop (object, propname, value);
2654 else if (STRINGP (object))
2655 string_putprop (XSTRING (object), propname, value);
2656 else if (LRECORDP (object))
2657 {
2658 CONST struct lrecord_implementation
2659 *imp = XRECORD_LHEADER (object)->implementation;
2660 if (imp->putprop)
2661 {
2662 if (! (imp->putprop) (object, propname, value))
2663 signal_simple_error ("Can't set property on object", propname);
2664 }
2665 else
2666 goto noprops;
2667 }
2668 else
2669 {
2670 noprops:
2671 signal_simple_error ("Object type has no settable properties", object);
2672 }
2673
2674 return value;
2675 }
2676
2677 void
2678 pure_put (Lisp_Object sym, Lisp_Object prop, Lisp_Object val)
2679 {
2680 Fput (sym, prop, Fpurecopy (val));
2681 }
2682
2683 DEFUN ("remprop", Fremprop, Sremprop, 2, 2, 0 /*
2684 Remove from OBJECT's property list the property PROPNAME and its
2685 value. OBJECT can be a symbol, face, extent, or string. Returns
2686 non-nil if the property list was actually changed (i.e. if PROPNAME
2687 was present in the property list). See also `get', `put', and
2688 `object-plist'.
2689 */ )
2690 (object, propname)
2691 Lisp_Object object, propname;
2692 {
2693 int retval = 0;
2694
2695 CHECK_SYMBOL (propname);
2696 CHECK_IMPURE (object);
2697
2698 if (SYMBOLP (object))
2699 retval = symbol_remprop (object, propname);
2700 else if (STRINGP (object))
2701 retval = string_remprop (XSTRING (object), propname);
2702 else if (LRECORDP (object))
2703 {
2704 CONST struct lrecord_implementation
2705 *imp = XRECORD_LHEADER (object)->implementation;
2706 if (imp->remprop)
2707 {
2708 retval = (imp->remprop) (object, propname);
2709 if (retval == -1)
2710 signal_simple_error ("Can't remove property from object",
2711 propname);
2712 }
2713 else
2714 goto noprops;
2715 }
2716 else
2717 {
2718 noprops:
2719 signal_simple_error ("Object type has no removable properties", object);
2720 }
2721
2722 return retval ? Qt : Qnil;
2723 }
2724
2725 DEFUN ("object-plist", Fobject_plist, Sobject_plist, 1, 1, 0 /*
2726 Return a property list of OBJECT's props.
2727 For a symbol this is equivalent to `symbol-plist'.
2728 Do not modify the property list directly; this may or may not have
2729 the desired effects. (In particular, for a property with a special
2730 interpretation, this will probably have no effect at all.)
2731 */ )
2732 (object)
2733 Lisp_Object object;
2734 {
2735 if (SYMBOLP (object))
2736 return Fsymbol_plist (object);
2737 else if (STRINGP (object))
2738 return string_plist (XSTRING (object));
2739 else if (LRECORDP (object))
2740 {
2741 CONST struct lrecord_implementation
2742 *imp = XRECORD_LHEADER (object)->implementation;
2743 if (imp->plist)
2744 return (imp->plist) (object);
2745 else
2746 signal_simple_error ("Object type has no properties", object);
2747 }
2748 else
2749 signal_simple_error ("Object type has no properties", object);
2750
2751 return Qnil;
2752 }
2753
2754
2755 int
2756 internal_equal (Lisp_Object o1, Lisp_Object o2, int depth)
2757 {
2758 if (depth > 200)
2759 error ("Stack overflow in equal");
2760 do_cdr:
2761 QUIT;
2762 if (HACKEQ_UNSAFE (o1, o2))
2763 return (1);
2764 /* Note that (equal 20 20.0) should be nil */
2765 else if (XTYPE (o1) != XTYPE (o2))
2766 return (0);
2767 else if (CONSP (o1))
2768 {
2769 if (!internal_equal (Fcar (o1), Fcar (o2), depth + 1))
2770 return (0);
2771 o1 = Fcdr (o1);
2772 o2 = Fcdr (o2);
2773 goto do_cdr;
2774 }
2775
2776 #ifndef LRECORD_VECTOR
2777 else if (VECTORP (o1))
2778 {
2779 int indecks;
2780 int len = vector_length (XVECTOR (o1));
2781 if (len != vector_length (XVECTOR (o2)))
2782 return (0);
2783 for (indecks = 0; indecks < len; indecks++)
2784 {
2785 Lisp_Object v1, v2;
2786 v1 = vector_data (XVECTOR (o1)) [indecks];
2787 v2 = vector_data (XVECTOR (o2)) [indecks];
2788 if (!internal_equal (v1, v2, depth + 1))
2789 return (0);
2790 }
2791 return (1);
2792 }
2793 #endif /* !LRECORD_VECTOR */
2794 else if (STRINGP (o1))
2795 {
2796 Bytecount len = string_length (XSTRING (o1));
2797 if (len != string_length (XSTRING (o2)))
2798 return (0);
2799 if (memcmp (string_data (XSTRING (o1)), string_data (XSTRING (o2)), len))
2800 return (0);
2801 return (1);
2802 }
2803 else if (LRECORDP (o1))
2804 {
2805 CONST struct lrecord_implementation
2806 *imp1 = XRECORD_LHEADER (o1)->implementation,
2807 *imp2 = XRECORD_LHEADER (o2)->implementation;
2808 if (imp1 != imp2)
2809 return (0);
2810 else if (imp1->equal == 0)
2811 /* EQ-ness of the objects was noticed above */
2812 return (0);
2813 else
2814 return ((imp1->equal) (o1, o2, depth));
2815 }
2816
2817 return (0);
2818 }
2819
2820 DEFUN ("equal", Fequal, Sequal, 2, 2, 0 /*
2821 T if two Lisp objects have similar structure and contents.
2822 They must have the same data type.
2823 Conses are compared by comparing the cars and the cdrs.
2824 Vectors and strings are compared element by element.
2825 Numbers are compared by value. Symbols must match exactly.
2826 */ )
2827 (o1, o2)
2828 Lisp_Object o1, o2;
2829 {
2830 return ((internal_equal (o1, o2, 0)) ? Qt : Qnil);
2831 }
2832
2833
2834 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0 /*
2835 Store each element of ARRAY with ITEM.
2836 ARRAY is a vector, bit vector, or string.
2837 */ )
2838 (array, item)
2839 Lisp_Object array, item;
2840 {
2841 retry:
2842 if (VECTORP (array))
2843 {
2844 Lisp_Object *p;
2845 int size;
2846 int indecks;
2847 CHECK_IMPURE (array);
2848 size = vector_length (XVECTOR (array));
2849 p = vector_data (XVECTOR (array));
2850 for (indecks = 0; indecks < size; indecks++)
2851 p[indecks] = item;
2852 }
2853 else if (VECTORP (array))
2854 {
2855 struct Lisp_Bit_Vector *v;
2856 int size;
2857 int indecks;
2858
2859 CHECK_BIT (item);
2860 CHECK_IMPURE (array);
2861 v = XBIT_VECTOR (array);
2862 size = bit_vector_length (v);
2863 for (indecks = 0; indecks < size; indecks++)
2864 set_bit_vector_bit (v, indecks, XINT (item));
2865 }
2866 else if (STRINGP (array))
2867 {
2868 Charcount size;
2869 Charcount indecks;
2870 Emchar charval;
2871 CHECK_CHAR_COERCE_INT (item);
2872 CHECK_IMPURE (array);
2873 charval = XCHAR (item);
2874 size = string_char_length (XSTRING (array));
2875 for (indecks = 0; indecks < size; indecks++)
2876 set_string_char (XSTRING (array), indecks, charval);
2877 bump_string_modiff (array);
2878 }
2879 else
2880 {
2881 array = wrong_type_argument (Qarrayp, array);
2882 goto retry;
2883 }
2884 return array;
2885 }
2886
2887 Lisp_Object
2888 nconc2 (Lisp_Object s1, Lisp_Object s2)
2889 {
2890 Lisp_Object args[2];
2891 args[0] = s1;
2892 args[1] = s2;
2893 return Fnconc (2, args);
2894 }
2895
2896 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0 /*
2897 Concatenate any number of lists by altering them.
2898 Only the last argument is not altered, and need not be a list.
2899 */ )
2900 (nargs, args)
2901 int nargs;
2902 Lisp_Object *args;
2903 {
2904 int argnum;
2905 Lisp_Object tail, tem, val;
2906 struct gcpro gcpro1;
2907
2908 /* The modus operandi in Emacs is "caller gc-protects args".
2909 However, nconc (particularly nconc2 ()) is called many times
2910 in Emacs on freshly created stuff (e.g. you see the idiom
2911 nconc2 (Fcopy_sequence (foo), bar) a lot). So we help those
2912 callers out by protecting the args ourselves to save them
2913 a lot of temporary-variable grief. */
2914
2915 GCPRO1 (args[0]);
2916 gcpro1.nvars = nargs;
2917
2918 val = Qnil;
2919
2920 for (argnum = 0; argnum < nargs; argnum++)
2921 {
2922 tem = args[argnum];
2923 if (NILP (tem)) continue;
2924
2925 if (NILP (val))
2926 val = tem;
2927
2928 if (argnum + 1 == nargs) break;
2929
2930 if (!CONSP (tem))
2931 tem = wrong_type_argument (Qlistp, tem);
2932
2933 while (CONSP (tem))
2934 {
2935 tail = tem;
2936 tem = Fcdr (tail);
2937 QUIT;
2938 }
2939
2940 tem = args[argnum + 1];
2941 Fsetcdr (tail, tem);
2942 if (NILP (tem))
2943 args[argnum + 1] = tail;
2944 }
2945
2946 RETURN_UNGCPRO (val);
2947 }
2948
2949
2950 /* This is the guts of all mapping functions.
2951 Apply fn to each element of seq, one by one,
2952 storing the results into elements of vals, a C vector of Lisp_Objects.
2953 leni is the length of vals, which should also be the length of seq.
2954
2955 If VALS is a null pointer, do not accumulate the results. */
2956
2957 static void
2958 mapcar1 (int leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
2959 {
2960 Lisp_Object tail;
2961 Lisp_Object dummy = Qnil;
2962 int i;
2963 struct gcpro gcpro1, gcpro2, gcpro3;
2964 Lisp_Object result;
2965
2966 GCPRO3 (dummy, fn, seq);
2967
2968 if (vals)
2969 {
2970 /* Don't let vals contain any garbage when GC happens. */
2971 for (i = 0; i < leni; i++)
2972 vals[i] = Qnil;
2973 gcpro1.var = vals;
2974 gcpro1.nvars = leni;
2975 }
2976
2977 /* We need not explicitly protect `tail' because it is used only on
2978 lists, and 1) lists are not relocated and 2) the list is marked
2979 via `seq' so will not be freed */
2980
2981 if (VECTORP (seq))
2982 {
2983 for (i = 0; i < leni; i++)
2984 {
2985 dummy = vector_data (XVECTOR (seq))[i];
2986 result = call1 (fn, dummy);
2987 if (vals)
2988 vals[i] = result;
2989 }
2990 }
2991 else if (BIT_VECTORP (seq))
2992 {
2993 struct Lisp_Bit_Vector *v = XBIT_VECTOR (seq);
2994 for (i = 0; i < leni; i++)
2995 {
2996 XSETINT (dummy, bit_vector_bit (v, i));
2997 result = call1 (fn, dummy);
2998 if (vals)
2999 vals[i] = result;
3000 }
3001 }
3002 else if (STRINGP (seq))
3003 {
3004 for (i = 0; i < leni; i++)
3005 {
3006 result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
3007 if (vals)
3008 vals[i] = result;
3009 }
3010 }
3011 else /* Must be a list, since Flength did not get an error */
3012 {
3013 tail = seq;
3014 for (i = 0; i < leni; i++)
3015 {
3016 result = call1 (fn, Fcar (tail));
3017 if (vals)
3018 vals[i] = result;
3019 tail = Fcdr (tail);
3020 }
3021 }
3022
3023 UNGCPRO;
3024 }
3025
3026 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0 /*
3027 Apply FN to each element of SEQ, and concat the results as strings.
3028 In between each pair of results, stick in SEP.
3029 Thus, \" \" as SEP results in spaces between the values returned by FN.
3030 */ )
3031 (fn, seq, sep)
3032 Lisp_Object fn, seq, sep;
3033 {
3034 Lisp_Object len;
3035 int leni;
3036 int nargs;
3037 Lisp_Object *args;
3038 int i;
3039 struct gcpro gcpro1;
3040
3041 len = Flength (seq);
3042 leni = XINT (len);
3043 nargs = leni + leni - 1;
3044 if (nargs < 0) return build_string ("");
3045
3046 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
3047
3048 GCPRO1 (sep);
3049 mapcar1 (leni, args, fn, seq);
3050 UNGCPRO;
3051
3052 for (i = leni - 1; i >= 0; i--)
3053 args[i + i] = args[i];
3054
3055 for (i = 1; i < nargs; i += 2)
3056 args[i] = sep;
3057
3058 return Fconcat (nargs, args);
3059 }
3060
3061 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0 /*
3062 Apply FUNCTION to each element of SEQUENCE, and make a list of the results.
3063 The result is a list just as long as SEQUENCE.
3064 SEQUENCE may be a list, a vector, a bit vector, or a string.
3065 */ )
3066 (fn, seq)
3067 Lisp_Object fn, seq;
3068 {
3069 Lisp_Object len;
3070 int leni;
3071 Lisp_Object *args;
3072
3073 len = Flength (seq);
3074 leni = XINT (len);
3075 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
3076
3077 mapcar1 (leni, args, fn, seq);
3078
3079 return Flist (leni, args);
3080 }
3081
3082 DEFUN ("mapc-internal", Fmapc_internal, Smapc_internal, 2, 2, 0 /*
3083 Apply FUNCTION to each element of SEQUENCE.
3084 SEQUENCE may be a list, a vector, a bit vector, or a string.
3085 This function is like `mapcar' but does not accumulate the results,
3086 which is more efficient if you do not use the results.
3087 */ )
3088 (fn, seq)
3089 Lisp_Object fn, seq;
3090 {
3091 Lisp_Object len;
3092 int leni;
3093
3094 len = Flength (seq);
3095 leni = XINT (len);
3096
3097 mapcar1 (leni, 0, fn, seq);
3098
3099 return Qnil;
3100 }
3101
3102
3103 /* #### this function doesn't belong in this file! */
3104
3105 DEFUN ("load-average", Fload_average, Sload_average, 0, 0, 0 /*
3106 Return list of 1 minute, 5 minute and 15 minute load averages.
3107 Each of the three load averages is multiplied by 100,
3108 then converted to integer.
3109
3110 If the 5-minute or 15-minute load averages are not available, return a
3111 shortened list, containing only those averages which are available.
3112
3113 On most systems, this won't work unless the emacs executable is installed
3114 as setgid kmem (assuming that /dev/kmem is in the group kmem).
3115 */ )
3116 ()
3117 {
3118 double load_ave[10]; /* hey, just in case */
3119 int loads = getloadavg (load_ave, 3);
3120 Lisp_Object ret;
3121
3122 if (loads == -2)
3123 error ("load-average not implemented for this operating system.");
3124 else if (loads < 0)
3125 error ("could not get load-average; check permissions.");
3126
3127 ret = Qnil;
3128 while (loads > 0)
3129 ret = Fcons (make_int ((int) (load_ave[--loads] * 100.0)), ret);
3130
3131 return ret;
3132 }
3133
3134
3135 Lisp_Object Vfeatures;
3136
3137 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0 /*
3138 Return t if FEATURE is present in this Emacs.
3139 Use this to conditionalize execution of lisp code based on the presence or
3140 absence of emacs or environment extensions.
3141 Use `provide' to declare that a feature is available.
3142 This function looks at the value of the variable `features'.
3143 */ )
3144 (feature)
3145 Lisp_Object feature;
3146 {
3147 Lisp_Object tem;
3148 CHECK_SYMBOL (feature);
3149 tem = Fmemq (feature, Vfeatures);
3150 return (NILP (tem)) ? Qnil : Qt;
3151 }
3152
3153 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0 /*
3154 Announce that FEATURE is a feature of the current Emacs.
3155 */ )
3156 (feature)
3157 Lisp_Object feature;
3158 {
3159 Lisp_Object tem;
3160 CHECK_SYMBOL (feature);
3161 if (!NILP (Vautoload_queue))
3162 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
3163 tem = Fmemq (feature, Vfeatures);
3164 if (NILP (tem))
3165 Vfeatures = Fcons (feature, Vfeatures);
3166 LOADHIST_ATTACH (Fcons (Qprovide, feature));
3167 return feature;
3168 }
3169
3170 DEFUN ("require", Frequire, Srequire, 1, 2, 0 /*
3171 If feature FEATURE is not loaded, load it from FILENAME.
3172 If FEATURE is not a member of the list `features', then the feature
3173 is not loaded; so load the file FILENAME.
3174 If FILENAME is omitted, the printname of FEATURE is used as the file name.
3175 */ )
3176 (feature, file_name)
3177 Lisp_Object feature, file_name;
3178 {
3179 Lisp_Object tem;
3180 CHECK_SYMBOL (feature);
3181 tem = Fmemq (feature, Vfeatures);
3182 LOADHIST_ATTACH (Fcons (Qrequire, feature));
3183 if (!NILP (tem))
3184 return (feature);
3185 else
3186 {
3187 int speccount = specpdl_depth ();
3188
3189 /* Value saved here is to be restored into Vautoload_queue */
3190 record_unwind_protect (un_autoload, Vautoload_queue);
3191 Vautoload_queue = Qt;
3192
3193 call4 (Qload, NILP (file_name) ? Fsymbol_name (feature) : file_name,
3194 Qnil, Qt, Qnil);
3195
3196 tem = Fmemq (feature, Vfeatures);
3197 if (NILP (tem))
3198 error ("Required feature %s was not provided",
3199 string_data (XSYMBOL (feature)->name));
3200
3201 /* Once loading finishes, don't undo it. */
3202 Vautoload_queue = Qt;
3203 return (unbind_to (speccount, feature));
3204 }
3205 }
3206
3207
3208 Lisp_Object Qyes_or_no_p;
3209
3210 void
3211 syms_of_fns (void)
3212 {
3213 defsymbol (&Qstring_lessp, "string-lessp");
3214 defsymbol (&Qidentity, "identity");
3215 defsymbol (&Qyes_or_no_p, "yes-or-no-p");
3216
3217 defsubr (&Sidentity);
3218 defsubr (&Srandom);
3219 defsubr (&Slength);
3220 defsubr (&Ssafe_length);
3221 defsubr (&Sstring_equal);
3222 defsubr (&Sstring_lessp);
3223 defsubr (&Sstring_modified_tick);
3224 defsubr (&Sappend);
3225 defsubr (&Sconcat);
3226 defsubr (&Svconcat);
3227 defsubr (&Sbvconcat);
3228 defsubr (&Scopy_sequence);
3229 defsubr (&Scopy_alist);
3230 defsubr (&Scopy_tree);
3231 defsubr (&Ssubstring);
3232 defsubr (&Ssubseq);
3233 defsubr (&Snthcdr);
3234 defsubr (&Snth);
3235 defsubr (&Selt);
3236 defsubr (&Smember);
3237 defsubr (&Smemq);
3238 defsubr (&Sassoc);
3239 defsubr (&Sassq);
3240 defsubr (&Srassoc);
3241 defsubr (&Srassq);
3242 defsubr (&Sdelete);
3243 defsubr (&Sdelq);
3244 defsubr (&Sremassoc);
3245 defsubr (&Sremassq);
3246 defsubr (&Sremrassoc);
3247 defsubr (&Sremrassq);
3248 defsubr (&Snreverse);
3249 defsubr (&Sreverse);
3250 defsubr (&Ssort);
3251 defsubr (&Splists_eq);
3252 defsubr (&Splists_equal);
3253 defsubr (&Slax_plists_eq);
3254 defsubr (&Slax_plists_equal);
3255 defsubr (&Splist_get);
3256 defsubr (&Splist_put);
3257 defsubr (&Splist_remprop);
3258 defsubr (&Splist_member);
3259 defsubr (&Scheck_valid_plist);
3260 defsubr (&Svalid_plist_p);
3261 defsubr (&Scanonicalize_plist);
3262 defsubr (&Slax_plist_get);
3263 defsubr (&Slax_plist_put);
3264 defsubr (&Slax_plist_remprop);
3265 defsubr (&Slax_plist_member);
3266 defsubr (&Scanonicalize_lax_plist);
3267 defsubr (&Sdestructive_alist_to_plist);
3268 defsubr (&Sget);
3269 defsubr (&Sput);
3270 defsubr (&Sremprop);
3271 defsubr (&Sobject_plist);
3272 defsubr (&Sequal);
3273 defsubr (&Sfillarray);
3274 defsubr (&Snconc);
3275 defsubr (&Smapcar);
3276 defsubr (&Smapc_internal);
3277 defsubr (&Smapconcat);
3278 defsubr (&Sload_average);
3279 defsubr (&Sfeaturep);
3280 defsubr (&Srequire);
3281 defsubr (&Sprovide);
3282 }
3283
3284 void
3285 init_provide_once (void)
3286 {
3287 DEFVAR_LISP ("features", &Vfeatures /*
3288 A list of symbols which are the features of the executing emacs.
3289 Used by `featurep' and `require', and altered by `provide'.
3290 */ );
3291 Vfeatures = Qnil;
3292 }