XEmacs 21.2.4
[chise/xemacs-chise.git.1] / src / fns.c
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 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #include <errno.h>
43
44 #include "buffer.h"
45 #include "bytecode.h"
46 #include "commands.h"
47 #include "device.h"
48 #include "events.h"
49 #include "extents.h"
50 #include "frame.h"
51 #include "systime.h"
52 #include "insdel.h"
53 #include "lstream.h"
54 #include "opaque.h"
55
56 /* NOTE: This symbol is also used in lread.c */
57 #define FEATUREP_SYNTAX
58
59 Lisp_Object Qstring_lessp;
60 Lisp_Object Qidentity;
61
62 static int internal_old_equal (Lisp_Object, Lisp_Object, int);
63
64 static Lisp_Object
65 mark_bit_vector (Lisp_Object obj, void (*markobj) (Lisp_Object))
66 {
67   return Qnil;
68 }
69
70 static void
71 print_bit_vector (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
72 {
73   int i;
74   struct Lisp_Bit_Vector *v = XBIT_VECTOR (obj);
75   int len = bit_vector_length (v);
76   int last = len;
77
78   if (INTP (Vprint_length))
79     last = min (len, XINT (Vprint_length));
80   write_c_string ("#*", printcharfun);
81   for (i = 0; i < last; i++)
82     {
83       if (bit_vector_bit (v, i))
84         write_c_string ("1", printcharfun);
85       else
86         write_c_string ("0", printcharfun);
87     }
88
89   if (last != len)
90     write_c_string ("...", printcharfun);
91 }
92
93 static int
94 bit_vector_equal (Lisp_Object o1, Lisp_Object o2, int depth)
95 {
96   struct Lisp_Bit_Vector *v1 = XBIT_VECTOR (o1);
97   struct Lisp_Bit_Vector *v2 = XBIT_VECTOR (o2);
98
99   return ((bit_vector_length (v1) == bit_vector_length (v2)) &&
100           !memcmp (v1->bits, v2->bits,
101                    BIT_VECTOR_LONG_STORAGE (bit_vector_length (v1)) *
102                    sizeof (long)));
103 }
104
105 static unsigned long
106 bit_vector_hash (Lisp_Object obj, int depth)
107 {
108   struct Lisp_Bit_Vector *v = XBIT_VECTOR (obj);
109   return HASH2 (bit_vector_length (v),
110                 memory_hash (v->bits,
111                              BIT_VECTOR_LONG_STORAGE (bit_vector_length (v)) *
112                              sizeof (long)));
113 }
114
115 DEFINE_BASIC_LRECORD_IMPLEMENTATION ("bit-vector", bit_vector,
116                                      mark_bit_vector, print_bit_vector, 0,
117                                      bit_vector_equal, bit_vector_hash,
118                                      struct Lisp_Bit_Vector);
119 \f
120 DEFUN ("identity", Fidentity, 1, 1, 0, /*
121 Return the argument unchanged.
122 */
123        (arg))
124 {
125   return arg;
126 }
127
128 extern long get_random (void);
129 extern void seed_random (long arg);
130
131 DEFUN ("random", Frandom, 0, 1, 0, /*
132 Return a pseudo-random number.
133 All integers representable in Lisp are equally likely.
134   On most systems, this is 28 bits' worth.
135 With positive integer argument N, return random number in interval [0,N).
136 With argument t, set the random number seed from the current time and pid.
137 */
138        (limit))
139 {
140   EMACS_INT val;
141   unsigned long denominator;
142
143   if (EQ (limit, Qt))
144     seed_random (getpid () + time (NULL));
145   if (NATNUMP (limit) && !ZEROP (limit))
146     {
147       /* Try to take our random number from the higher bits of VAL,
148          not the lower, since (says Gentzel) the low bits of `random'
149          are less random than the higher ones.  We do this by using the
150          quotient rather than the remainder.  At the high end of the RNG
151          it's possible to get a quotient larger than limit; discarding
152          these values eliminates the bias that would otherwise appear
153          when using a large limit.  */
154       denominator = ((unsigned long)1 << VALBITS) / XINT (limit);
155       do
156         val = get_random () / denominator;
157       while (val >= XINT (limit));
158     }
159   else
160     val = get_random ();
161
162   return make_int (val);
163 }
164 \f
165 /* Random data-structure functions */
166
167 #ifdef LOSING_BYTECODE
168
169 /* #### Delete this shit */
170
171 /* Charcount is a misnomer here as we might be dealing with the
172    length of a vector or list, but emphasizes that we're not dealing
173    with Bytecounts in strings */
174 static Charcount
175 length_with_bytecode_hack (Lisp_Object seq)
176 {
177   if (!COMPILED_FUNCTIONP (seq))
178     return XINT (Flength (seq));
179   else
180     {
181       struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (seq);
182
183       return (b->flags.interactivep ? COMPILED_INTERACTIVE :
184               b->flags.domainp      ? COMPILED_DOMAIN :
185               COMPILED_DOC_STRING)
186         + 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 20.3, `%s' no longer works with compiled-function objects",
199        function);
200 }
201
202 DEFUN ("length", Flength, 1, 1, 0, /*
203 Return the length of vector, bit vector, list or string SEQUENCE.
204 */
205        (sequence))
206 {
207  retry:
208   if (STRINGP (sequence))
209     return make_int (XSTRING_CHAR_LENGTH (sequence));
210   else if (CONSP (sequence))
211     {
212       Lisp_Object tail;
213       int i = 0;
214
215       EXTERNAL_LIST_LOOP (tail, sequence)
216         {
217           QUIT;
218           i++;
219         }
220
221       return make_int (i);
222     }
223   else if (VECTORP (sequence))
224     return make_int (XVECTOR_LENGTH (sequence));
225   else if (NILP (sequence))
226     return Qzero;
227   else if (BIT_VECTORP (sequence))
228     return make_int (bit_vector_length (XBIT_VECTOR (sequence)));
229   else
230     {
231       check_losing_bytecode ("length", sequence);
232       sequence = wrong_type_argument (Qsequencep, sequence);
233       goto retry;
234     }
235 }
236
237 /* This does not check for quits.  That is safe
238    since it must terminate.  */
239
240 DEFUN ("safe-length", Fsafe_length, 1, 1, 0, /*
241 Return the length of a list, but avoid error or infinite loop.
242 This function never gets an error.  If LIST is not really a list,
243 it returns 0.  If LIST is circular, it returns a finite value
244 which is at least the number of distinct elements.
245 */
246        (list))
247 {
248   Lisp_Object halftail = list; /* Used to detect circular lists. */
249   Lisp_Object tail;
250   int len = 0;
251
252   for (tail = list; CONSP (tail); tail = XCDR (tail))
253     {
254       if (EQ (tail, halftail) && len != 0)
255         break;
256       len++;
257       if ((len & 1) == 0)
258         halftail = XCDR (halftail);
259     }
260
261   return make_int (len);
262 }
263
264 /*** string functions. ***/
265
266 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /*
267 Return t if two strings have identical contents.
268 Case is significant.  Text properties are ignored.
269 \(Under XEmacs, `equal' also ignores text properties and extents in
270 strings, but this is not the case under FSF Emacs 19.  In FSF Emacs 20
271 `equal' is the same as in XEmacs, in that respect.)
272 Symbols are also allowed; their print names are used instead.
273 */
274        (s1, s2))
275 {
276   Bytecount len;
277   struct Lisp_String *p1, *p2;
278
279   if (SYMBOLP (s1))
280     p1 = XSYMBOL (s1)->name;
281   else
282     {
283       CHECK_STRING (s1);
284       p1 = XSTRING (s1);
285     }
286
287   if (SYMBOLP (s2))
288     p2 = XSYMBOL (s2)->name;
289   else
290     {
291       CHECK_STRING (s2);
292       p2 = XSTRING (s2);
293     }
294
295   return (((len = string_length (p1)) == string_length (p2)) &&
296           !memcmp (string_data (p1), string_data (p2), len)) ? Qt : Qnil;
297 }
298
299
300 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /*
301 Return t if first arg string is less than second in lexicographic order.
302 If I18N2 support (but not Mule support) was compiled in, ordering is
303 determined by the locale. (Case is significant for the default C locale.)
304 In all other cases, comparison is simply done on a character-by-
305 character basis using the numeric value of a character. (Note that
306 this may not produce particularly meaningful results under Mule if
307 characters from different charsets are being compared.)
308
309 Symbols are also allowed; their print names are used instead.
310
311 The reason that the I18N2 locale-specific collation is not used under
312 Mule is that the locale model of internationalization does not handle
313 multiple charsets and thus has no hope of working properly under Mule.
314 What we really should do is create a collation table over all built-in
315 charsets.  This is extremely difficult to do from scratch, however.
316
317 Unicode is a good first step towards solving this problem.  In fact,
318 it is quite likely that a collation table exists (or will exist) for
319 Unicode.  When Unicode support is added to XEmacs/Mule, this problem
320 may be solved.
321 */
322        (s1, s2))
323 {
324   struct Lisp_String *p1, *p2;
325   Charcount end, len2;
326   int i;
327
328   if (SYMBOLP (s1))
329     p1 = XSYMBOL (s1)->name;
330   else
331     {
332       CHECK_STRING (s1);
333       p1 = XSTRING (s1);
334     }
335
336   if (SYMBOLP (s2))
337     p2 = XSYMBOL (s2)->name;
338   else
339     {
340       CHECK_STRING (s2);
341       p2 = XSTRING (s2);
342     }
343
344   end  = string_char_length (p1);
345   len2 = string_char_length (p2);
346   if (end > len2)
347     end = len2;
348
349 #if defined (I18N2) && !defined (MULE)
350   /* There is no hope of this working under Mule.  Even if we converted
351      the data into an external format so that strcoll() processed it
352      properly, it would still not work because strcoll() does not
353      handle multiple locales.  This is the fundamental flaw in the
354      locale model. */
355   Bytecount bcend = charcount_to_bytecount (string_data (p1), end);
356   /* Compare strings using collation order of locale. */
357   /* Need to be tricky to handle embedded nulls. */
358
359   for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1)
360     {
361       int val = strcoll ((char *) string_data (p1) + i,
362                          (char *) string_data (p2) + i);
363       if (val < 0)
364         return Qt;
365       if (val > 0)
366         return Qnil;
367     }
368 #else /* not I18N2, or MULE */
369   /* #### It is not really necessary to do this: We could compare
370      byte-by-byte and still get a reasonable comparison, since this
371      would compare characters with a charset in the same way.
372      With a little rearrangement of the leading bytes, we could
373      make most inter-charset comparisons work out the same, too;
374      even if some don't, this is not a big deal because inter-charset
375      comparisons aren't really well-defined anyway. */
376   for (i = 0; i < end; i++)
377     {
378       if (string_char (p1, i) != string_char (p2, i))
379         return string_char (p1, i) < string_char (p2, i) ? Qt : Qnil;
380     }
381 #endif /* not I18N2, or MULE */
382   /* Can't do i < len2 because then comparison between "foo" and "foo^@"
383      won't work right in I18N2 case */
384   return end < len2 ? Qt : Qnil;
385 }
386
387 DEFUN ("string-modified-tick", Fstring_modified_tick, 1, 1, 0, /*
388 Return STRING's tick counter, incremented for each change to the string.
389 Each string has a tick counter which is incremented each time the contents
390 of the string are changed (e.g. with `aset').  It wraps around occasionally.
391 */
392        (string))
393 {
394   struct Lisp_String *s;
395
396   CHECK_STRING (string);
397   s = XSTRING (string);
398   if (CONSP (s->plist) && INTP (XCAR (s->plist)))
399     return XCAR (s->plist);
400   else
401     return Qzero;
402 }
403
404 void
405 bump_string_modiff (Lisp_Object str)
406 {
407   struct Lisp_String *s = XSTRING (str);
408   Lisp_Object *ptr = &s->plist;
409
410 #ifdef I18N3
411   /* #### remove the `string-translatable' property from the string,
412      if there is one. */
413 #endif
414   /* skip over extent info if it's there */
415   if (CONSP (*ptr) && EXTENT_INFOP (XCAR (*ptr)))
416     ptr = &XCDR (*ptr);
417   if (CONSP (*ptr) && INTP (XCAR (*ptr)))
418     XSETINT (XCAR (*ptr), 1+XINT (XCAR (*ptr)));
419   else
420     *ptr = Fcons (make_int (1), *ptr);
421 }
422
423 \f
424 enum  concat_target_type { c_cons, c_string, c_vector, c_bit_vector };
425 static Lisp_Object concat (int nargs, Lisp_Object *args,
426                            enum concat_target_type target_type,
427                            int last_special);
428
429 Lisp_Object
430 concat2 (Lisp_Object s1, Lisp_Object s2)
431 {
432   Lisp_Object args[2];
433   args[0] = s1;
434   args[1] = s2;
435   return concat (2, args, c_string, 0);
436 }
437
438 Lisp_Object
439 concat3 (Lisp_Object s1, Lisp_Object s2, Lisp_Object s3)
440 {
441   Lisp_Object args[3];
442   args[0] = s1;
443   args[1] = s2;
444   args[2] = s3;
445   return concat (3, args, c_string, 0);
446 }
447
448 Lisp_Object
449 vconcat2 (Lisp_Object s1, Lisp_Object s2)
450 {
451   Lisp_Object args[2];
452   args[0] = s1;
453   args[1] = s2;
454   return concat (2, args, c_vector, 0);
455 }
456
457 Lisp_Object
458 vconcat3 (Lisp_Object s1, Lisp_Object s2, Lisp_Object s3)
459 {
460   Lisp_Object args[3];
461   args[0] = s1;
462   args[1] = s2;
463   args[2] = s3;
464   return concat (3, args, c_vector, 0);
465 }
466
467 DEFUN ("append", Fappend, 0, MANY, 0, /*
468 Concatenate all the arguments and make the result a list.
469 The result is a list whose elements are the elements of all the arguments.
470 Each argument may be a list, vector, bit vector, or string.
471 The last argument is not copied, just used as the tail of the new list.
472 Also see: `nconc'.
473 */
474        (int nargs, Lisp_Object *args))
475 {
476   return concat (nargs, args, c_cons, 1);
477 }
478
479 DEFUN ("concat", Fconcat, 0, MANY, 0, /*
480 Concatenate all the arguments and make the result a string.
481 The result is a string whose elements are the elements of all the arguments.
482 Each argument may be a string or a list or vector of characters.
483
484 As of XEmacs 21.0, this function does NOT accept individual integers
485 as arguments.  Old code that relies on, for example, (concat "foo" 50)
486 returning "foo50" will fail.  To fix such code, either apply
487 `int-to-string' to the integer argument, or use `format'.
488 */
489        (int nargs, Lisp_Object *args))
490 {
491   return concat (nargs, args, c_string, 0);
492 }
493
494 DEFUN ("vconcat", Fvconcat, 0, MANY, 0, /*
495 Concatenate all the arguments and make the result a vector.
496 The result is a vector whose elements are the elements of all the arguments.
497 Each argument may be a list, vector, bit vector, or string.
498 */
499        (int nargs, Lisp_Object *args))
500 {
501   return concat (nargs, args, c_vector, 0);
502 }
503
504 DEFUN ("bvconcat", Fbvconcat, 0, MANY, 0, /*
505 Concatenate all the arguments and make the result a bit vector.
506 The result is a bit vector whose elements are the elements of all the
507 arguments.  Each argument may be a list, vector, bit vector, or string.
508 */
509        (int nargs, Lisp_Object *args))
510 {
511   return concat (nargs, args, c_bit_vector, 0);
512 }
513
514 DEFUN ("copy-sequence", Fcopy_sequence, 1, 1, 0, /*
515 Return a copy of a list, vector, bit vector or string.
516 The elements of a list or vector are not copied; they are shared
517 with the original.
518 */
519        (arg))
520 {
521  again:
522   if (NILP (arg)) return arg;
523   /* We handle conses separately because concat() is big and hairy and
524      doesn't handle (copy-sequence '(a b . c)) and it's easier to redo this
525      than to fix concat() without worrying about breaking other things.
526    */
527   if (CONSP (arg))
528     {
529       Lisp_Object head = Fcons (XCAR (arg), XCDR (arg));
530       Lisp_Object tail = head;
531
532       for (arg = XCDR (arg); CONSP (arg); arg = XCDR (arg))
533         {
534           XCDR (tail) = Fcons (XCAR (arg), XCDR (arg));
535           tail = XCDR (tail);
536           QUIT;
537         }
538       return head;
539     }
540   if (STRINGP     (arg)) return concat (1, &arg, c_string,     0);
541   if (VECTORP     (arg)) return concat (1, &arg, c_vector,     0);
542   if (BIT_VECTORP (arg)) return concat (1, &arg, c_bit_vector, 0);
543
544   check_losing_bytecode ("copy-sequence", arg);
545   arg = wrong_type_argument (Qsequencep, arg);
546   goto again;
547 }
548
549 struct merge_string_extents_struct
550 {
551   Lisp_Object string;
552   Bytecount entry_offset;
553   Bytecount entry_length;
554 };
555
556 static Lisp_Object
557 concat (int nargs, Lisp_Object *args,
558         enum concat_target_type target_type,
559         int last_special)
560 {
561   Lisp_Object val;
562   Lisp_Object tail = Qnil;
563   int toindex;
564   int argnum;
565   Lisp_Object last_tail;
566   Lisp_Object prev;
567   struct merge_string_extents_struct *args_mse = 0;
568   Bufbyte *string_result = 0;
569   Bufbyte *string_result_ptr = 0;
570   struct gcpro gcpro1;
571
572   /* The modus operandi in Emacs is "caller gc-protects args".
573      However, concat is called many times in Emacs on freshly
574      created stuff.  So we help those callers out by protecting
575      the args ourselves to save them a lot of temporary-variable
576      grief. */
577
578   GCPRO1 (args[0]);
579   gcpro1.nvars = nargs;
580
581 #ifdef I18N3
582   /* #### if the result is a string and any of the strings have a string
583      for the `string-translatable' property, then concat should also
584      concat the args but use the `string-translatable' strings, and store
585      the result in the returned string's `string-translatable' property. */
586 #endif
587   if (target_type == c_string)
588     args_mse = alloca_array (struct merge_string_extents_struct, nargs);
589
590   /* In append, the last arg isn't treated like the others */
591   if (last_special && nargs > 0)
592     {
593       nargs--;
594       last_tail = args[nargs];
595     }
596   else
597     last_tail = Qnil;
598
599   /* Check and coerce the arguments. */
600   for (argnum = 0; argnum < nargs; argnum++)
601     {
602       Lisp_Object seq = args[argnum];
603       if (LISTP (seq))
604         ;
605       else if (VECTORP (seq) || STRINGP (seq) || BIT_VECTORP (seq))
606         ;
607 #ifdef LOSING_BYTECODE
608       else if (COMPILED_FUNCTIONP (seq))
609         /* Urk!  We allow this, for "compatibility"... */
610         ;
611 #endif
612 #if 0                           /* removed for XEmacs 21 */
613       else if (INTP (seq))
614         /* This is too revolting to think about but maintains
615            compatibility with FSF (and lots and lots of old code). */
616         args[argnum] = Fnumber_to_string (seq);
617 #endif
618       else
619         {
620           check_losing_bytecode ("concat", seq);
621           args[argnum] = wrong_type_argument (Qsequencep, seq);
622         }
623
624       if (args_mse)
625         {
626           if (STRINGP (seq))
627             args_mse[argnum].string = seq;
628           else
629             args_mse[argnum].string = Qnil;
630         }
631     }
632
633   {
634     /* Charcount is a misnomer here as we might be dealing with the
635        length of a vector or list, but emphasizes that we're not dealing
636        with Bytecounts in strings */
637     Charcount total_length;
638
639     for (argnum = 0, total_length = 0; argnum < nargs; argnum++)
640       {
641 #ifdef LOSING_BYTECODE
642         Charcount thislen = length_with_bytecode_hack (args[argnum]);
643 #else
644         Charcount thislen = XINT (Flength (args[argnum]));
645 #endif
646         total_length += thislen;
647       }
648
649     switch (target_type)
650       {
651       case c_cons:
652         if (total_length == 0)
653           /* In append, if all but last arg are nil, return last arg */
654           RETURN_UNGCPRO (last_tail);
655         val = Fmake_list (make_int (total_length), Qnil);
656         break;
657       case c_vector:
658         val = make_vector (total_length, Qnil);
659         break;
660       case c_bit_vector:
661         val = make_bit_vector (total_length, Qzero);
662         break;
663       case c_string:
664         /* We don't make the string yet because we don't know the
665            actual number of bytes.  This loop was formerly written
666            to call Fmake_string() here and then call set_string_char()
667            for each char.  This seems logical enough but is waaaaaaaay
668            slow -- set_string_char() has to scan the whole string up
669            to the place where the substitution is called for in order
670            to find the place to change, and may have to do some
671            realloc()ing in order to make the char fit properly.
672            O(N^2) yuckage. */
673         val = Qnil;
674         string_result = (Bufbyte *) alloca (total_length * MAX_EMCHAR_LEN);
675         string_result_ptr = string_result;
676         break;
677       default:
678         abort ();
679       }
680   }
681
682
683   if (CONSP (val))
684     tail = val, toindex = -1;   /* -1 in toindex is flag we are
685                                     making a list */
686   else
687     toindex = 0;
688
689   prev = Qnil;
690
691   for (argnum = 0; argnum < nargs; argnum++)
692     {
693       Charcount thisleni = 0;
694       Charcount thisindex = 0;
695       Lisp_Object seq = args[argnum];
696       Bufbyte *string_source_ptr = 0;
697       Bufbyte *string_prev_result_ptr = string_result_ptr;
698
699       if (!CONSP (seq))
700         {
701 #ifdef LOSING_BYTECODE
702           thisleni = length_with_bytecode_hack (seq);
703 #else
704           thisleni = XINT (Flength (seq));
705 #endif
706         }
707       if (STRINGP (seq))
708         string_source_ptr = XSTRING_DATA (seq);
709
710       while (1)
711         {
712           Lisp_Object elt;
713
714           /* We've come to the end of this arg, so exit. */
715           if (NILP (seq))
716             break;
717
718           /* Fetch next element of `seq' arg into `elt' */
719           if (CONSP (seq))
720             {
721               elt = XCAR (seq);
722               seq = XCDR (seq);
723             }
724           else
725             {
726               if (thisindex >= thisleni)
727                 break;
728
729               if (STRINGP (seq))
730                 {
731                   elt = make_char (charptr_emchar (string_source_ptr));
732                   INC_CHARPTR (string_source_ptr);
733                 }
734               else if (VECTORP (seq))
735                 elt = XVECTOR_DATA (seq)[thisindex];
736               else if (BIT_VECTORP (seq))
737                 elt = make_int (bit_vector_bit (XBIT_VECTOR (seq),
738                                                 thisindex));
739               else
740                 elt = Felt (seq, make_int (thisindex));
741               thisindex++;
742             }
743
744           /* Store into result */
745           if (toindex < 0)
746             {
747               /* toindex negative means we are making a list */
748               XCAR (tail) = elt;
749               prev = tail;
750               tail = XCDR (tail);
751             }
752           else if (VECTORP (val))
753             XVECTOR_DATA (val)[toindex++] = elt;
754           else if (BIT_VECTORP (val))
755             {
756               CHECK_BIT (elt);
757               set_bit_vector_bit (XBIT_VECTOR (val), toindex++, XINT (elt));
758             }
759           else
760             {
761               CHECK_CHAR_COERCE_INT (elt);
762               string_result_ptr += set_charptr_emchar (string_result_ptr,
763                                                        XCHAR (elt));
764             }
765         }
766       if (args_mse)
767         {
768           args_mse[argnum].entry_offset =
769             string_prev_result_ptr - string_result;
770           args_mse[argnum].entry_length =
771             string_result_ptr - string_prev_result_ptr;
772         }
773     }
774
775   /* Now we finally make the string. */
776   if (target_type == c_string)
777     {
778       val = make_string (string_result, string_result_ptr - string_result);
779       for (argnum = 0; argnum < nargs; argnum++)
780         {
781           if (STRINGP (args_mse[argnum].string))
782             copy_string_extents (val, args_mse[argnum].string,
783                                  args_mse[argnum].entry_offset, 0,
784                                  args_mse[argnum].entry_length);
785         }
786     }
787
788   if (!NILP (prev))
789     XCDR (prev) = last_tail;
790
791   RETURN_UNGCPRO (val);
792 }
793 \f
794 DEFUN ("copy-alist", Fcopy_alist, 1, 1, 0, /*
795 Return a copy of ALIST.
796 This is an alist which represents the same mapping from objects to objects,
797 but does not share the alist structure with ALIST.
798 The objects mapped (cars and cdrs of elements of the alist)
799 are shared, however.
800 Elements of ALIST that are not conses are also shared.
801 */
802        (alist))
803 {
804   Lisp_Object tail;
805
806   if (NILP (alist))
807     return alist;
808   CHECK_CONS (alist);
809
810   alist = concat (1, &alist, c_cons, 0);
811   for (tail = alist; CONSP (tail); tail = XCDR (tail))
812     {
813       Lisp_Object car = XCAR (tail);
814
815       if (CONSP (car))
816         XCAR (tail) = Fcons (XCAR (car), XCDR (car));
817     }
818   return alist;
819 }
820
821 DEFUN ("copy-tree", Fcopy_tree, 1, 2, 0, /*
822 Return a copy of a list and substructures.
823 The argument is copied, and any lists contained within it are copied
824 recursively.  Circularities and shared substructures are not preserved.
825 Second arg VECP causes vectors to be copied, too.  Strings and bit vectors
826 are not copied.
827 */
828        (arg, vecp))
829 {
830   if (CONSP (arg))
831     {
832       Lisp_Object rest;
833       rest = arg = Fcopy_sequence (arg);
834       while (CONSP (rest))
835         {
836           Lisp_Object elt = XCAR (rest);
837           QUIT;
838           if (CONSP (elt) || VECTORP (elt))
839             XCAR (rest) = Fcopy_tree (elt, vecp);
840           if (VECTORP (XCDR (rest))) /* hack for (a b . [c d]) */
841             XCDR (rest) = Fcopy_tree (XCDR (rest), vecp);
842           rest = XCDR (rest);
843         }
844     }
845   else if (VECTORP (arg) && ! NILP (vecp))
846     {
847       int i = XVECTOR_LENGTH (arg);
848       int j;
849       arg = Fcopy_sequence (arg);
850       for (j = 0; j < i; j++)
851         {
852           Lisp_Object elt = XVECTOR_DATA (arg) [j];
853           QUIT;
854           if (CONSP (elt) || VECTORP (elt))
855             XVECTOR_DATA (arg) [j] = Fcopy_tree (elt, vecp);
856         }
857     }
858   return arg;
859 }
860
861 DEFUN ("substring", Fsubstring, 2, 3, 0, /*
862 Return a substring of STRING, starting at index FROM and ending before TO.
863 TO may be nil or omitted; then the substring runs to the end of STRING.
864 If FROM or TO is negative, it counts from the end.
865 Relevant parts of the string-extent-data are copied in the new string.
866 */
867        (string, from, to))
868 {
869   Charcount ccfr, ccto;
870   Bytecount bfr, bto;
871   Lisp_Object val;
872
873   CHECK_STRING (string);
874   /* Historically, FROM could not be omitted.  Whatever ... */
875   CHECK_INT (from);
876   get_string_range_char (string, from, to, &ccfr, &ccto,
877                          GB_HISTORICAL_STRING_BEHAVIOR);
878   bfr = charcount_to_bytecount (XSTRING_DATA (string), ccfr);
879   bto = charcount_to_bytecount (XSTRING_DATA (string), ccto);
880   val = make_string (XSTRING_DATA (string) + bfr, bto - bfr);
881   /* Copy any applicable extent information into the new string: */
882   copy_string_extents (val, string, 0, bfr, bto - bfr);
883   return val;
884 }
885
886 DEFUN ("subseq", Fsubseq, 2, 3, 0, /*
887 Return a subsequence of SEQ, starting at index FROM and ending before TO.
888 TO may be nil or omitted; then the subsequence runs to the end of SEQ.
889 If FROM or TO is negative, it counts from the end.
890 The resulting subsequence is always the same type as the original
891  sequence.
892 If SEQ is a string, relevant parts of the string-extent-data are copied
893  to the new string.
894 */
895        (seq, from, to))
896 {
897   int len, f, t;
898
899   if (STRINGP (seq))
900     return Fsubstring (seq, from, to);
901
902   if (!LISTP (seq) && !VECTORP (seq) && !BIT_VECTORP (seq))
903     {
904       check_losing_bytecode ("subseq", seq);
905       seq = wrong_type_argument (Qsequencep, seq);
906     }
907
908   len = XINT (Flength (seq));
909
910   CHECK_INT (from);
911   f = XINT (from);
912   if (f < 0)
913     f = len + f;
914
915   if (NILP (to))
916     t = len;
917   else
918     {
919       CHECK_INT (to);
920       t = XINT (to);
921       if (t < 0)
922         t = len + t;
923     }
924
925   if (!(0 <= f && f <= t && t <= len))
926     args_out_of_range_3 (seq, make_int (f), make_int (t));
927
928   if (VECTORP (seq))
929     {
930       Lisp_Object result = make_vector (t - f, Qnil);
931       int i;
932       Lisp_Object *in_elts  = XVECTOR_DATA (seq);
933       Lisp_Object *out_elts = XVECTOR_DATA (result);
934
935       for (i = f; i < t; i++)
936         out_elts[i - f] = in_elts[i];
937       return result;
938     }
939
940   if (LISTP (seq))
941     {
942       Lisp_Object result = Qnil;
943       int i;
944
945       seq = Fnthcdr (make_int (f), seq);
946
947       for (i = f; i < t; i++)
948         {
949           result = Fcons (Fcar (seq), result);
950           seq = Fcdr (seq);
951         }
952
953       return Fnreverse (result);
954     }
955
956   /* bit vector */
957   {
958     Lisp_Object result = make_bit_vector (t - f, Qzero);
959     int i;
960
961     for (i = f; i < t; i++)
962       set_bit_vector_bit (XBIT_VECTOR (result), i - f,
963                           bit_vector_bit (XBIT_VECTOR (seq), i));
964     return result;
965   }
966 }
967
968 \f
969 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /*
970 Take cdr N times on LIST, and return the result.
971 */
972        (n, list))
973 {
974   REGISTER int i;
975   REGISTER Lisp_Object tail = list;
976   CHECK_NATNUM (n);
977   for (i = XINT (n); i; i--)
978     {
979       if (CONSP (tail))
980         tail = XCDR (tail);
981       else if (NILP (tail))
982         return Qnil;
983       else
984         {
985           tail = wrong_type_argument (Qlistp, tail);
986           i++;
987         }
988     }
989   return tail;
990 }
991
992 DEFUN ("nth", Fnth, 2, 2, 0, /*
993 Return the Nth element of LIST.
994 N counts from zero.  If LIST is not that long, nil is returned.
995 */
996        (n, list))
997 {
998   return Fcar (Fnthcdr (n, list));
999 }
1000
1001 DEFUN ("elt", Felt, 2, 2, 0, /*
1002 Return element of SEQUENCE at index N.
1003 */
1004        (sequence, n))
1005 {
1006  retry:
1007   CHECK_INT_COERCE_CHAR (n); /* yuck! */
1008   if (LISTP (sequence))
1009     {
1010       Lisp_Object tem = Fnthcdr (n, sequence);
1011       /* #### Utterly, completely, fucking disgusting.
1012        * #### The whole point of "elt" is that it operates on
1013        * #### sequences, and does error- (bounds-) checking.
1014        */
1015       if (CONSP (tem))
1016         return XCAR (tem);
1017       else
1018 #if 1
1019         /* This is The Way It Has Always Been. */
1020         return Qnil;
1021 #else
1022         /* This is The Way Mly and Cltl2 say It Should Be. */
1023         args_out_of_range (sequence, n);
1024 #endif
1025     }
1026   else if (STRINGP (sequence)
1027            || VECTORP (sequence)
1028            || BIT_VECTORP (sequence))
1029     return Faref (sequence, n);
1030 #ifdef LOSING_BYTECODE
1031   else if (COMPILED_FUNCTIONP (sequence))
1032     {
1033       int idx = XINT (n);
1034       if (idx < 0)
1035         {
1036         lose:
1037           args_out_of_range (sequence, n);
1038         }
1039       /* Utter perversity */
1040       {
1041         struct Lisp_Compiled_Function *b = XCOMPILED_FUNCTION (sequence);
1042         switch (idx)
1043           {
1044           case COMPILED_ARGLIST:
1045             return b->arglist;
1046           case COMPILED_BYTECODE:
1047             return b->bytecodes;
1048           case COMPILED_CONSTANTS:
1049             return b->constants;
1050           case COMPILED_STACK_DEPTH:
1051             return make_int (b->maxdepth);
1052           case COMPILED_DOC_STRING:
1053             return compiled_function_documentation (b);
1054           case COMPILED_DOMAIN:
1055             return compiled_function_domain (b);
1056           case COMPILED_INTERACTIVE:
1057             if (b->flags.interactivep)
1058               return compiled_function_interactive (b);
1059             /* if we return nil, can't tell interactive with no args
1060                from noninteractive. */
1061             goto lose;
1062           default:
1063             goto lose;
1064           }
1065       }
1066     }
1067 #endif /* LOSING_BYTECODE */
1068   else
1069     {
1070       check_losing_bytecode ("elt", sequence);
1071       sequence = wrong_type_argument (Qsequencep, sequence);
1072       goto retry;
1073     }
1074 }
1075
1076 DEFUN ("member", Fmember, 2, 2, 0, /*
1077 Return non-nil if ELT is an element of LIST.  Comparison done with `equal'.
1078 The value is actually the tail of LIST whose car is ELT.
1079 */
1080        (elt, list))
1081 {
1082   REGISTER Lisp_Object tail;
1083   LIST_LOOP (tail, list)
1084     {
1085       CONCHECK_CONS (tail);
1086       if (internal_equal (elt, XCAR (tail), 0))
1087         return tail;
1088       QUIT;
1089     }
1090   return Qnil;
1091 }
1092
1093 DEFUN ("old-member", Fold_member, 2, 2, 0, /*
1094 Return non-nil if ELT is an element of LIST.  Comparison done with `old-equal'.
1095 The value is actually the tail of LIST whose car is ELT.
1096 This function is provided only for byte-code compatibility with v19.
1097 Do not use it.
1098 */
1099        (elt, list))
1100 {
1101   REGISTER Lisp_Object tail;
1102   LIST_LOOP (tail, list)
1103     {
1104       CONCHECK_CONS (tail);
1105       if (internal_old_equal (elt, XCAR (tail), 0))
1106         return tail;
1107       QUIT;
1108     }
1109   return Qnil;
1110 }
1111
1112 DEFUN ("memq", Fmemq, 2, 2, 0, /*
1113 Return non-nil if ELT is an element of LIST.  Comparison done with `eq'.
1114 The value is actually the tail of LIST whose car is ELT.
1115 */
1116        (elt, list))
1117 {
1118   REGISTER Lisp_Object tail;
1119   LIST_LOOP (tail, list)
1120     {
1121       REGISTER Lisp_Object tem;
1122       CONCHECK_CONS (tail);
1123       if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1124         return tail;
1125       QUIT;
1126     }
1127   return Qnil;
1128 }
1129
1130 DEFUN ("old-memq", Fold_memq, 2, 2, 0, /*
1131 Return non-nil if ELT is an element of LIST.  Comparison done with `old-eq'.
1132 The value is actually the tail of LIST whose car is ELT.
1133 This function is provided only for byte-code compatibility with v19.
1134 Do not use it.
1135 */
1136        (elt, list))
1137 {
1138   REGISTER Lisp_Object tail;
1139   LIST_LOOP (tail, list)
1140     {
1141       REGISTER Lisp_Object tem;
1142       CONCHECK_CONS (tail);
1143       if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem))
1144         return tail;
1145       QUIT;
1146     }
1147   return Qnil;
1148 }
1149
1150 Lisp_Object
1151 memq_no_quit (Lisp_Object elt, Lisp_Object list)
1152 {
1153   REGISTER Lisp_Object tail;
1154   for (tail = list; CONSP (tail); tail = XCDR (tail))
1155     {
1156       REGISTER Lisp_Object tem;
1157       if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1158         return tail;
1159     }
1160   return Qnil;
1161 }
1162
1163 DEFUN ("assoc", Fassoc, 2, 2, 0, /*
1164 Return non-nil if KEY is `equal' to the car of an element of LIST.
1165 The value is actually the element of LIST whose car equals KEY.
1166 */
1167        (key, list))
1168 {
1169   /* This function can GC. */
1170   REGISTER Lisp_Object tail;
1171   LIST_LOOP (tail, list)
1172     {
1173       REGISTER Lisp_Object elt;
1174       CONCHECK_CONS (tail);
1175       elt = XCAR (tail);
1176       if (CONSP (elt) && internal_equal (XCAR (elt), key, 0))
1177         return elt;
1178       QUIT;
1179     }
1180   return Qnil;
1181 }
1182
1183 DEFUN ("old-assoc", Fold_assoc, 2, 2, 0, /*
1184 Return non-nil if KEY is `old-equal' to the car of an element of LIST.
1185 The value is actually the element of LIST whose car equals KEY.
1186 */
1187        (key, list))
1188 {
1189   /* This function can GC. */
1190   REGISTER Lisp_Object tail;
1191   LIST_LOOP (tail, list)
1192     {
1193       REGISTER Lisp_Object elt;
1194       CONCHECK_CONS (tail);
1195       elt = XCAR (tail);
1196       if (CONSP (elt) && internal_old_equal (XCAR (elt), key, 0))
1197         return elt;
1198       QUIT;
1199     }
1200   return Qnil;
1201 }
1202
1203 Lisp_Object
1204 assoc_no_quit (Lisp_Object key, Lisp_Object list)
1205 {
1206   int speccount = specpdl_depth ();
1207   specbind (Qinhibit_quit, Qt);
1208   return unbind_to (speccount, Fassoc (key, list));
1209 }
1210
1211 DEFUN ("assq", Fassq, 2, 2, 0, /*
1212 Return non-nil if KEY is `eq' to the car of an element of LIST.
1213 The value is actually the element of LIST whose car is KEY.
1214 Elements of LIST that are not conses are ignored.
1215 */
1216        (key, list))
1217 {
1218   REGISTER Lisp_Object tail;
1219   LIST_LOOP (tail, list)
1220     {
1221       REGISTER Lisp_Object elt, tem;
1222       CONCHECK_CONS (tail);
1223       elt = XCAR (tail);
1224       if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1225         return elt;
1226       QUIT;
1227     }
1228   return Qnil;
1229 }
1230
1231 DEFUN ("old-assq", Fold_assq, 2, 2, 0, /*
1232 Return non-nil if KEY is `old-eq' to the car of an element of LIST.
1233 The value is actually the element of LIST whose car is KEY.
1234 Elements of LIST that are not conses are ignored.
1235 This function is provided only for byte-code compatibility with v19.
1236 Do not use it.
1237 */
1238        (key, list))
1239 {
1240   REGISTER Lisp_Object tail;
1241   LIST_LOOP (tail, list)
1242     {
1243       REGISTER Lisp_Object elt, tem;
1244       CONCHECK_CONS (tail);
1245       elt = XCAR (tail);
1246       if (CONSP (elt) && (tem = XCAR (elt), HACKEQ_UNSAFE (key, tem)))
1247         return elt;
1248       QUIT;
1249     }
1250   return Qnil;
1251 }
1252
1253 /* Like Fassq but never report an error and do not allow quits.
1254    Use only on lists known never to be circular.  */
1255
1256 Lisp_Object
1257 assq_no_quit (Lisp_Object key, Lisp_Object list)
1258 {
1259   /* This cannot GC. */
1260   REGISTER Lisp_Object tail;
1261   for (tail = list; CONSP (tail); tail = XCDR (tail))
1262     {
1263       REGISTER Lisp_Object tem, elt;
1264       elt = XCAR (tail);
1265       if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1266           return elt;
1267     }
1268   return Qnil;
1269 }
1270
1271 DEFUN ("rassoc", Frassoc, 2, 2, 0, /*
1272 Return non-nil if KEY is `equal' to the cdr of an element of LIST.
1273 The value is actually the element of LIST whose cdr equals KEY.
1274 */
1275        (key, list))
1276 {
1277   REGISTER Lisp_Object tail;
1278   LIST_LOOP (tail, list)
1279     {
1280       REGISTER Lisp_Object elt;
1281       CONCHECK_CONS (tail);
1282       elt = XCAR (tail);
1283       if (CONSP (elt) && internal_equal (XCDR (elt), key, 0))
1284         return elt;
1285       QUIT;
1286     }
1287   return Qnil;
1288 }
1289
1290 DEFUN ("old-rassoc", Fold_rassoc, 2, 2, 0, /*
1291 Return non-nil if KEY is `old-equal' to the cdr of an element of LIST.
1292 The value is actually the element of LIST whose cdr equals KEY.
1293 */
1294        (key, list))
1295 {
1296   REGISTER Lisp_Object tail;
1297   LIST_LOOP (tail, list)
1298     {
1299       REGISTER Lisp_Object elt;
1300       CONCHECK_CONS (tail);
1301       elt = XCAR (tail);
1302       if (CONSP (elt) && internal_old_equal (XCDR (elt), key, 0))
1303         return elt;
1304       QUIT;
1305     }
1306   return Qnil;
1307 }
1308
1309 DEFUN ("rassq", Frassq, 2, 2, 0, /*
1310 Return non-nil if KEY is `eq' to the cdr of an element of LIST.
1311 The value is actually the element of LIST whose cdr is KEY.
1312 */
1313        (key, list))
1314 {
1315   REGISTER Lisp_Object tail;
1316   LIST_LOOP (tail, list)
1317     {
1318       REGISTER Lisp_Object elt, tem;
1319       CONCHECK_CONS (tail);
1320       elt = XCAR (tail);
1321       if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1322         return elt;
1323       QUIT;
1324     }
1325   return Qnil;
1326 }
1327
1328 DEFUN ("old-rassq", Fold_rassq, 2, 2, 0, /*
1329 Return non-nil if KEY is `old-eq' to the cdr of an element of LIST.
1330 The value is actually the element of LIST whose cdr is KEY.
1331 */
1332        (key, list))
1333 {
1334   REGISTER Lisp_Object tail;
1335   LIST_LOOP (tail, list)
1336     {
1337       REGISTER Lisp_Object elt, tem;
1338       CONCHECK_CONS (tail);
1339       elt = XCAR (tail);
1340       if (CONSP (elt) && (tem = XCDR (elt), HACKEQ_UNSAFE (key, tem)))
1341         return elt;
1342       QUIT;
1343     }
1344   return Qnil;
1345 }
1346
1347 Lisp_Object
1348 rassq_no_quit (Lisp_Object key, Lisp_Object list)
1349 {
1350   REGISTER Lisp_Object tail;
1351   for (tail = list; CONSP (tail); tail = XCDR (tail))
1352     {
1353       REGISTER Lisp_Object elt, tem;
1354       elt = XCAR (tail);
1355       if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1356         return elt;
1357     }
1358   return Qnil;
1359 }
1360
1361 \f
1362 DEFUN ("delete", Fdelete, 2, 2, 0, /*
1363 Delete by side effect any occurrences of ELT as a member of LIST.
1364 The modified LIST is returned.  Comparison is done with `equal'.
1365 If the first member of LIST is ELT, there is no way to remove it by side
1366 effect; therefore, write `(setq foo (delete element foo))' to be sure
1367 of changing the value of `foo'.
1368 Also see: `remove'.
1369 */
1370        (elt, list))
1371 {
1372   REGISTER Lisp_Object tail = list;
1373   REGISTER Lisp_Object prev = Qnil;
1374
1375   while (!NILP (tail))
1376     {
1377       CONCHECK_CONS (tail);
1378       if (internal_equal (elt, XCAR (tail), 0))
1379         {
1380           if (NILP (prev))
1381             list = XCDR (tail);
1382           else
1383             XCDR (prev) = XCDR (tail);
1384         }
1385       else
1386         prev = tail;
1387       tail = XCDR (tail);
1388       QUIT;
1389     }
1390   return list;
1391 }
1392
1393 DEFUN ("old-delete", Fold_delete, 2, 2, 0, /*
1394 Delete by side effect any occurrences of ELT as a member of LIST.
1395 The modified LIST is returned.  Comparison is done with `old-equal'.
1396 If the first member of LIST is ELT, there is no way to remove it by side
1397 effect; therefore, write `(setq foo (old-delete element foo))' to be sure
1398 of changing the value of `foo'.
1399 */
1400        (elt, list))
1401 {
1402   REGISTER Lisp_Object tail = list;
1403   REGISTER Lisp_Object prev = Qnil;
1404
1405   while (!NILP (tail))
1406     {
1407       CONCHECK_CONS (tail);
1408       if (internal_old_equal (elt, XCAR (tail), 0))
1409         {
1410           if (NILP (prev))
1411             list = XCDR (tail);
1412           else
1413             XCDR (prev) = XCDR (tail);
1414         }
1415       else
1416         prev = tail;
1417       tail = XCDR (tail);
1418       QUIT;
1419     }
1420   return list;
1421 }
1422
1423 DEFUN ("delq", Fdelq, 2, 2, 0, /*
1424 Delete by side effect any occurrences of ELT as a member of LIST.
1425 The modified LIST is returned.  Comparison is done with `eq'.
1426 If the first member of LIST is ELT, there is no way to remove it by side
1427 effect; therefore, write `(setq foo (delq element foo))' to be sure of
1428 changing the value of `foo'.
1429 */
1430        (elt, list))
1431 {
1432   REGISTER Lisp_Object tail = list;
1433   REGISTER Lisp_Object prev = Qnil;
1434
1435   while (!NILP (tail))
1436     {
1437       REGISTER Lisp_Object tem;
1438       CONCHECK_CONS (tail);
1439       if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1440         {
1441           if (NILP (prev))
1442             list = XCDR (tail);
1443           else
1444             XCDR (prev) = XCDR (tail);
1445         }
1446       else
1447         prev = tail;
1448       tail = XCDR (tail);
1449       QUIT;
1450     }
1451   return list;
1452 }
1453
1454 DEFUN ("old-delq", Fold_delq, 2, 2, 0, /*
1455 Delete by side effect any occurrences of ELT as a member of LIST.
1456 The modified LIST is returned.  Comparison is done with `old-eq'.
1457 If the first member of LIST is ELT, there is no way to remove it by side
1458 effect; therefore, write `(setq foo (old-delq element foo))' to be sure of
1459 changing the value of `foo'.
1460 */
1461        (elt, list))
1462 {
1463   REGISTER Lisp_Object tail = list;
1464   REGISTER Lisp_Object prev = Qnil;
1465
1466   while (!NILP (tail))
1467     {
1468       REGISTER Lisp_Object tem;
1469       CONCHECK_CONS (tail);
1470       if (tem = XCAR (tail), HACKEQ_UNSAFE (elt, tem))
1471         {
1472           if (NILP (prev))
1473             list = XCDR (tail);
1474           else
1475             XCDR (prev) = XCDR (tail);
1476         }
1477       else
1478         prev = tail;
1479       tail = XCDR (tail);
1480       QUIT;
1481     }
1482   return list;
1483 }
1484
1485 /* no quit, no errors; be careful */
1486
1487 Lisp_Object
1488 delq_no_quit (Lisp_Object elt, Lisp_Object list)
1489 {
1490   REGISTER Lisp_Object tail = list;
1491   REGISTER Lisp_Object prev = Qnil;
1492
1493   while (CONSP (tail))
1494     {
1495       REGISTER Lisp_Object tem;
1496       if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1497         {
1498           if (NILP (prev))
1499             list = XCDR (tail);
1500           else
1501             XCDR (prev) = XCDR (tail);
1502         }
1503       else
1504         prev = tail;
1505       tail = XCDR (tail);
1506     }
1507   return list;
1508 }
1509
1510 /* Be VERY careful with this.  This is like delq_no_quit() but
1511    also calls free_cons() on the removed conses.  You must be SURE
1512    that no pointers to the freed conses remain around (e.g.
1513    someone else is pointing to part of the list).  This function
1514    is useful on internal lists that are used frequently and where
1515    the actual list doesn't escape beyond known code bounds. */
1516
1517 Lisp_Object
1518 delq_no_quit_and_free_cons (Lisp_Object elt, Lisp_Object list)
1519 {
1520   REGISTER Lisp_Object tail = list;
1521   REGISTER Lisp_Object prev = Qnil;
1522   struct Lisp_Cons *cons_to_free = NULL;
1523
1524   while (CONSP (tail))
1525     {
1526       REGISTER Lisp_Object tem;
1527       if (tem = XCAR (tail), EQ_WITH_EBOLA_NOTICE (elt, tem))
1528         {
1529           if (NILP (prev))
1530             list = XCDR (tail);
1531           else
1532             XCDR (prev) = XCDR (tail);
1533           cons_to_free = XCONS (tail);
1534         }
1535       else
1536         prev = tail;
1537       tail = XCDR (tail);
1538       if (cons_to_free)
1539         {
1540           free_cons (cons_to_free);
1541           cons_to_free = NULL;
1542         }
1543     }
1544   return list;
1545 }
1546
1547 DEFUN ("remassoc", Fremassoc, 2, 2, 0, /*
1548 Delete by side effect any elements of LIST whose car is `equal' to KEY.
1549 The modified LIST is returned.  If the first member of LIST has a car
1550 that is `equal' to KEY, there is no way to remove it by side effect;
1551 therefore, write `(setq foo (remassoc key foo))' to be sure of changing
1552 the value of `foo'.
1553 */
1554        (key, list))
1555 {
1556   REGISTER Lisp_Object tail = list;
1557   REGISTER Lisp_Object prev = Qnil;
1558
1559   while (!NILP (tail))
1560     {
1561       REGISTER Lisp_Object elt;
1562       CONCHECK_CONS (tail);
1563       elt = XCAR (tail);
1564       if (CONSP (elt) && internal_equal (key, XCAR (elt), 0))
1565         {
1566           if (NILP (prev))
1567             list = XCDR (tail);
1568           else
1569             XCDR (prev) = XCDR (tail);
1570         }
1571       else
1572         prev = tail;
1573       tail = XCDR (tail);
1574       QUIT;
1575     }
1576   return list;
1577 }
1578
1579 Lisp_Object
1580 remassoc_no_quit (Lisp_Object key, Lisp_Object list)
1581 {
1582   int speccount = specpdl_depth ();
1583   specbind (Qinhibit_quit, Qt);
1584   return unbind_to (speccount, Fremassoc (key, list));
1585 }
1586
1587 DEFUN ("remassq", Fremassq, 2, 2, 0, /*
1588 Delete by side effect any elements of LIST whose car is `eq' to KEY.
1589 The modified LIST is returned.  If the first member of LIST has a car
1590 that is `eq' to KEY, there is no way to remove it by side effect;
1591 therefore, write `(setq foo (remassq key foo))' to be sure of changing
1592 the value of `foo'.
1593 */
1594        (key, list))
1595 {
1596   REGISTER Lisp_Object tail = list;
1597   REGISTER Lisp_Object prev = Qnil;
1598
1599   while (!NILP (tail))
1600     {
1601       REGISTER Lisp_Object elt, tem;
1602       CONCHECK_CONS (tail);
1603       elt = XCAR (tail);
1604       if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1605         {
1606           if (NILP (prev))
1607             list = XCDR (tail);
1608           else
1609             XCDR (prev) = XCDR (tail);
1610         }
1611       else
1612         prev = tail;
1613       tail = XCDR (tail);
1614       QUIT;
1615     }
1616   return list;
1617 }
1618
1619 /* no quit, no errors; be careful */
1620
1621 Lisp_Object
1622 remassq_no_quit (Lisp_Object key, Lisp_Object list)
1623 {
1624   REGISTER Lisp_Object tail = list;
1625   REGISTER Lisp_Object prev = Qnil;
1626
1627   while (CONSP (tail))
1628     {
1629       REGISTER Lisp_Object elt, tem;
1630       elt = XCAR (tail);
1631       if (CONSP (elt) && (tem = XCAR (elt), EQ_WITH_EBOLA_NOTICE (key, tem)))
1632         {
1633           if (NILP (prev))
1634             list = XCDR (tail);
1635           else
1636             XCDR (prev) = XCDR (tail);
1637         }
1638       else
1639         prev = tail;
1640       tail = XCDR (tail);
1641     }
1642   return list;
1643 }
1644
1645 DEFUN ("remrassoc", Fremrassoc, 2, 2, 0, /*
1646 Delete by side effect any elements of LIST whose cdr is `equal' to VALUE.
1647 The modified LIST is returned.  If the first member of LIST has a car
1648 that is `equal' to VALUE, there is no way to remove it by side effect;
1649 therefore, write `(setq foo (remrassoc value foo))' to be sure of changing
1650 the value of `foo'.
1651 */
1652        (value, list))
1653 {
1654   REGISTER Lisp_Object tail = list;
1655   REGISTER Lisp_Object prev = Qnil;
1656
1657   while (!NILP (tail))
1658     {
1659       REGISTER Lisp_Object elt;
1660       CONCHECK_CONS (tail);
1661       elt = XCAR (tail);
1662       if (CONSP (elt) && internal_equal (value, XCDR (elt), 0))
1663         {
1664           if (NILP (prev))
1665             list = XCDR (tail);
1666           else
1667             XCDR (prev) = XCDR (tail);
1668         }
1669       else
1670         prev = tail;
1671       tail = XCDR (tail);
1672       QUIT;
1673     }
1674   return list;
1675 }
1676
1677 DEFUN ("remrassq", Fremrassq, 2, 2, 0, /*
1678 Delete by side effect any elements of LIST whose cdr is `eq' to VALUE.
1679 The modified LIST is returned.  If the first member of LIST has a car
1680 that is `eq' to VALUE, there is no way to remove it by side effect;
1681 therefore, write `(setq foo (remrassq value foo))' to be sure of changing
1682 the value of `foo'.
1683 */
1684        (value, list))
1685 {
1686   REGISTER Lisp_Object tail = list;
1687   REGISTER Lisp_Object prev = Qnil;
1688
1689   while (!NILP (tail))
1690     {
1691       REGISTER Lisp_Object elt, tem;
1692       CONCHECK_CONS (tail);
1693       elt = XCAR (tail);
1694       if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
1695         {
1696           if (NILP (prev))
1697             list = XCDR (tail);
1698           else
1699             XCDR (prev) = XCDR (tail);
1700         }
1701       else
1702         prev = tail;
1703       tail = XCDR (tail);
1704       QUIT;
1705     }
1706   return list;
1707 }
1708
1709 /* no quit, no errors; be careful */
1710
1711 Lisp_Object
1712 remrassq_no_quit (Lisp_Object value, Lisp_Object list)
1713 {
1714   REGISTER Lisp_Object tail = list;
1715   REGISTER Lisp_Object prev = Qnil;
1716
1717   while (CONSP (tail))
1718     {
1719       REGISTER Lisp_Object elt, tem;
1720       elt = XCAR (tail);
1721       if (CONSP (elt) && (tem = XCDR (elt), EQ_WITH_EBOLA_NOTICE (value, tem)))
1722         {
1723           if (NILP (prev))
1724             list = XCDR (tail);
1725           else
1726             XCDR (prev) = XCDR (tail);
1727         }
1728       else
1729         prev = tail;
1730       tail = XCDR (tail);
1731     }
1732   return list;
1733 }
1734
1735 DEFUN ("nreverse", Fnreverse, 1, 1, 0, /*
1736 Reverse LIST by destructively modifying cdr pointers.
1737 Return the beginning of the reversed list.
1738 Also see: `reverse'.
1739 */
1740        (list))
1741 {
1742   struct gcpro gcpro1, gcpro2;
1743   REGISTER Lisp_Object prev = Qnil;
1744   REGISTER Lisp_Object tail = list;
1745
1746   /* We gcpro our args; see `nconc' */
1747   GCPRO2 (prev, tail);
1748   while (!NILP (tail))
1749     {
1750       REGISTER Lisp_Object next;
1751       QUIT;
1752       CONCHECK_CONS (tail);
1753       next = XCDR (tail);
1754       XCDR (tail) = prev;
1755       prev = tail;
1756       tail = next;
1757     }
1758   UNGCPRO;
1759   return prev;
1760 }
1761
1762 DEFUN ("reverse", Freverse, 1, 1, 0, /*
1763 Reverse LIST, copying.  Return the beginning of the reversed list.
1764 See also the function `nreverse', which is used more often.
1765 */
1766        (list))
1767 {
1768   REGISTER Lisp_Object tail;
1769   Lisp_Object new = Qnil;
1770
1771   for (tail = list; CONSP (tail); tail = XCDR (tail))
1772     {
1773       new = Fcons (XCAR (tail), new);
1774       QUIT;
1775     }
1776   if (!NILP (tail))
1777     dead_wrong_type_argument (Qlistp, tail);
1778   return new;
1779 }
1780 \f
1781 static Lisp_Object list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
1782                                Lisp_Object lisp_arg,
1783                                int (*pred_fn) (Lisp_Object, Lisp_Object,
1784                                                Lisp_Object lisp_arg));
1785
1786 Lisp_Object
1787 list_sort (Lisp_Object list,
1788            Lisp_Object lisp_arg,
1789            int (*pred_fn) (Lisp_Object, Lisp_Object,
1790                            Lisp_Object lisp_arg))
1791 {
1792   struct gcpro gcpro1, gcpro2, gcpro3;
1793   Lisp_Object back, tem;
1794   Lisp_Object front = list;
1795   Lisp_Object len = Flength (list);
1796   int length = XINT (len);
1797
1798   if (length < 2)
1799     return list;
1800
1801   XSETINT (len, (length / 2) - 1);
1802   tem = Fnthcdr (len, list);
1803   back = Fcdr (tem);
1804   Fsetcdr (tem, Qnil);
1805
1806   GCPRO3 (front, back, lisp_arg);
1807   front = list_sort (front, lisp_arg, pred_fn);
1808   back = list_sort (back, lisp_arg, pred_fn);
1809   UNGCPRO;
1810   return list_merge (front, back, lisp_arg, pred_fn);
1811 }
1812
1813 \f
1814 static int
1815 merge_pred_function (Lisp_Object obj1, Lisp_Object obj2,
1816                      Lisp_Object pred)
1817 {
1818   Lisp_Object tmp;
1819
1820   /* prevents the GC from happening in call2 */
1821   int speccount = specpdl_depth ();
1822 /* Emacs' GC doesn't actually relocate pointers, so this probably
1823    isn't strictly necessary */
1824   record_unwind_protect (restore_gc_inhibit,
1825                          make_int (gc_currently_forbidden));
1826   gc_currently_forbidden = 1;
1827   tmp = call2 (pred, obj1, obj2);
1828   unbind_to (speccount, Qnil);
1829
1830   if (NILP (tmp))
1831     return -1;
1832   else
1833     return 1;
1834 }
1835
1836 DEFUN ("sort", Fsort, 2, 2, 0, /*
1837 Sort LIST, stably, comparing elements using PREDICATE.
1838 Returns the sorted list.  LIST is modified by side effects.
1839 PREDICATE is called with two elements of LIST, and should return T
1840 if the first element is "less" than the second.
1841 */
1842        (list, pred))
1843 {
1844   return list_sort (list, pred, merge_pred_function);
1845 }
1846
1847 Lisp_Object
1848 merge (Lisp_Object org_l1, Lisp_Object org_l2,
1849        Lisp_Object pred)
1850 {
1851   return list_merge (org_l1, org_l2, pred, merge_pred_function);
1852 }
1853
1854
1855 static Lisp_Object
1856 list_merge (Lisp_Object org_l1, Lisp_Object org_l2,
1857             Lisp_Object lisp_arg,
1858             int (*pred_fn) (Lisp_Object, Lisp_Object, Lisp_Object lisp_arg))
1859 {
1860   Lisp_Object value;
1861   Lisp_Object tail;
1862   Lisp_Object tem;
1863   Lisp_Object l1, l2;
1864   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1865
1866   l1 = org_l1;
1867   l2 = org_l2;
1868   tail = Qnil;
1869   value = Qnil;
1870
1871   /* It is sufficient to protect org_l1 and org_l2.
1872      When l1 and l2 are updated, we copy the new values
1873      back into the org_ vars.  */
1874
1875   GCPRO4 (org_l1, org_l2, lisp_arg, value);
1876
1877   while (1)
1878     {
1879       if (NILP (l1))
1880         {
1881           UNGCPRO;
1882           if (NILP (tail))
1883             return l2;
1884           Fsetcdr (tail, l2);
1885           return value;
1886         }
1887       if (NILP (l2))
1888         {
1889           UNGCPRO;
1890           if (NILP (tail))
1891             return l1;
1892           Fsetcdr (tail, l1);
1893           return value;
1894         }
1895
1896       if (((*pred_fn) (Fcar (l2), Fcar (l1), lisp_arg)) < 0)
1897         {
1898           tem = l1;
1899           l1 = Fcdr (l1);
1900           org_l1 = l1;
1901         }
1902       else
1903         {
1904           tem = l2;
1905           l2 = Fcdr (l2);
1906           org_l2 = l2;
1907         }
1908       if (NILP (tail))
1909         value = tem;
1910       else
1911         Fsetcdr (tail, tem);
1912       tail = tem;
1913     }
1914 }
1915
1916 \f
1917 /************************************************************************/
1918 /*                      property-list functions                         */
1919 /************************************************************************/
1920
1921 /* For properties of text, we need to do order-insensitive comparison of
1922    plists.  That is, we need to compare two plists such that they are the
1923    same if they have the same set of keys, and equivalent values.
1924    So (a 1 b 2) would be equal to (b 2 a 1).
1925
1926    NIL_MEANS_NOT_PRESENT is as in `plists-eq' etc.
1927    LAXP means use `equal' for comparisons.
1928  */
1929 int
1930 plists_differ (Lisp_Object a, Lisp_Object b, int nil_means_not_present,
1931                int laxp, int depth)
1932 {
1933   int eqp = (depth == -1);      /* -1 as depth means us eq, not equal. */
1934   int la, lb, m, i, fill;
1935   Lisp_Object *keys, *vals;
1936   char *flags;
1937   Lisp_Object rest;
1938
1939   if (NILP (a) && NILP (b))
1940     return 0;
1941
1942   Fcheck_valid_plist (a);
1943   Fcheck_valid_plist (b);
1944
1945   la = XINT (Flength (a));
1946   lb = XINT (Flength (b));
1947   m = (la > lb ? la : lb);
1948   fill = 0;
1949   keys  = alloca_array (Lisp_Object, m);
1950   vals  = alloca_array (Lisp_Object, m);
1951   flags = alloca_array (char, m);
1952
1953   /* First extract the pairs from A. */
1954   for (rest = a; !NILP (rest); rest = XCDR (XCDR (rest)))
1955     {
1956       Lisp_Object k = XCAR (rest);
1957       Lisp_Object v = XCAR (XCDR (rest));
1958       /* Maybe be Ebolified. */
1959       if (nil_means_not_present && NILP (v)) continue;
1960       keys [fill] = k;
1961       vals [fill] = v;
1962       flags[fill] = 0;
1963       fill++;
1964     }
1965   /* Now iterate over B, and stop if we find something that's not in A,
1966      or that doesn't match.  As we match, mark them. */
1967   for (rest = b; !NILP (rest); rest = XCDR (XCDR (rest)))
1968     {
1969       Lisp_Object k = XCAR (rest);
1970       Lisp_Object v = XCAR (XCDR (rest));
1971       /* Maybe be Ebolified. */
1972       if (nil_means_not_present && NILP (v)) continue;
1973       for (i = 0; i < fill; i++)
1974         {
1975           if (!laxp ? EQ (k, keys [i]) : internal_equal (k, keys [i], depth))
1976             {
1977               if ((eqp
1978                    /* We narrowly escaped being Ebolified here. */
1979                    ? !EQ_WITH_EBOLA_NOTICE (v, vals [i])
1980                    : !internal_equal (v, vals [i], depth)))
1981                 /* a property in B has a different value than in A */
1982                 goto MISMATCH;
1983               flags [i] = 1;
1984               break;
1985             }
1986         }
1987       if (i == fill)
1988         /* there are some properties in B that are not in A */
1989         goto MISMATCH;
1990     }
1991   /* Now check to see that all the properties in A were also in B */
1992   for (i = 0; i < fill; i++)
1993     if (flags [i] == 0)
1994       goto MISMATCH;
1995
1996   /* Ok. */
1997   return 0;
1998
1999  MISMATCH:
2000   return 1;
2001 }
2002
2003 DEFUN ("plists-eq", Fplists_eq, 2, 3, 0, /*
2004 Return non-nil if property lists A and B are `eq'.
2005 A property list is an alternating list of keywords and values.
2006  This function does order-insensitive comparisons of the property lists:
2007  For example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
2008  Comparison between values is done using `eq'.  See also `plists-equal'.
2009 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2010  a nil value is ignored.  This feature is a virus that has infected
2011  old Lisp implementations, but should not be used except for backward
2012  compatibility.
2013 */
2014        (a, b, nil_means_not_present))
2015 {
2016   return (plists_differ (a, b, !NILP (nil_means_not_present), 0, -1)
2017           ? Qnil : Qt);
2018 }
2019
2020 DEFUN ("plists-equal", Fplists_equal, 2, 3, 0, /*
2021 Return non-nil if property lists A and B are `equal'.
2022 A property list is an alternating list of keywords and values.  This
2023  function does order-insensitive comparisons of the property lists: For
2024  example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
2025  Comparison between values is done using `equal'.  See also `plists-eq'.
2026 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2027  a nil value is ignored.  This feature is a virus that has infected
2028  old Lisp implementations, but should not be used except for backward
2029  compatibility.
2030 */
2031        (a, b, nil_means_not_present))
2032 {
2033   return (plists_differ (a, b, !NILP (nil_means_not_present), 0, 1)
2034           ? Qnil : Qt);
2035 }
2036
2037
2038 DEFUN ("lax-plists-eq", Flax_plists_eq, 2, 3, 0, /*
2039 Return non-nil if lax property lists A and B are `eq'.
2040 A property list is an alternating list of keywords and values.
2041  This function does order-insensitive comparisons of the property lists:
2042  For example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
2043  Comparison between values is done using `eq'.  See also `plists-equal'.
2044 A lax property list is like a regular one except that comparisons between
2045  keywords is done using `equal' instead of `eq'.
2046 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2047  a nil value is ignored.  This feature is a virus that has infected
2048  old Lisp implementations, but should not be used except for backward
2049  compatibility.
2050 */
2051        (a, b, nil_means_not_present))
2052 {
2053   return (plists_differ (a, b, !NILP (nil_means_not_present), 1, -1)
2054           ? Qnil : Qt);
2055 }
2056
2057 DEFUN ("lax-plists-equal", Flax_plists_equal, 2, 3, 0, /*
2058 Return non-nil if lax property lists A and B are `equal'.
2059 A property list is an alternating list of keywords and values.  This
2060  function does order-insensitive comparisons of the property lists: For
2061  example, the property lists '(a 1 b 2) and '(b 2 a 1) are equal.
2062  Comparison between values is done using `equal'.  See also `plists-eq'.
2063 A lax property list is like a regular one except that comparisons between
2064  keywords is done using `equal' instead of `eq'.
2065 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2066  a nil value is ignored.  This feature is a virus that has infected
2067  old Lisp implementations, but should not be used except for backward
2068  compatibility.
2069 */
2070        (a, b, nil_means_not_present))
2071 {
2072   return (plists_differ (a, b, !NILP (nil_means_not_present), 1, 1)
2073           ? Qnil : Qt);
2074 }
2075
2076 /* Return the value associated with key PROPERTY in property list PLIST.
2077    Return nil if key not found.  This function is used for internal
2078    property lists that cannot be directly manipulated by the user.
2079    */
2080
2081 Lisp_Object
2082 internal_plist_get (Lisp_Object plist, Lisp_Object property)
2083 {
2084   Lisp_Object tail = plist;
2085
2086   for (; !NILP (tail); tail = XCDR (XCDR (tail)))
2087     {
2088       struct Lisp_Cons *c = XCONS (tail);
2089       if (EQ (c->car, property))
2090         return XCAR (c->cdr);
2091     }
2092
2093   return Qunbound;
2094 }
2095
2096 /* Set PLIST's value for PROPERTY to VALUE.  Analogous to
2097    internal_plist_get(). */
2098
2099 void
2100 internal_plist_put (Lisp_Object *plist, Lisp_Object property,
2101                     Lisp_Object value)
2102 {
2103   Lisp_Object tail;
2104
2105   for (tail = *plist; !NILP (tail); tail = XCDR (XCDR (tail)))
2106     {
2107       if (EQ (XCAR (tail), property))
2108         {
2109           XCAR (XCDR (tail)) = value;
2110           return;
2111         }
2112     }
2113
2114   *plist = Fcons (property, Fcons (value, *plist));
2115 }
2116
2117 int
2118 internal_remprop (Lisp_Object *plist, Lisp_Object property)
2119 {
2120   Lisp_Object tail = *plist;
2121
2122   if (NILP (tail))
2123     return 0;
2124
2125   if (EQ (XCAR (tail), property))
2126     {
2127       *plist = XCDR (XCDR (tail));
2128       return 1;
2129     }
2130
2131   for (tail = XCDR (tail); !NILP (XCDR (tail));
2132        tail = XCDR (XCDR (tail)))
2133     {
2134       struct Lisp_Cons *c = XCONS (tail);
2135       if (EQ (XCAR (c->cdr), property))
2136         {
2137           c->cdr = XCDR (XCDR (c->cdr));
2138           return 1;
2139         }
2140     }
2141
2142   return 0;
2143 }
2144
2145 /* Called on a malformed property list.  BADPLACE should be some
2146    place where truncating will form a good list -- i.e. we shouldn't
2147    result in a list with an odd length. */
2148
2149 static Lisp_Object
2150 bad_bad_bunny (Lisp_Object *plist, Lisp_Object *badplace, Error_behavior errb)
2151 {
2152   if (ERRB_EQ (errb, ERROR_ME))
2153     return Fsignal (Qmalformed_property_list, list2 (*plist, *badplace));
2154   else
2155     {
2156       if (ERRB_EQ (errb, ERROR_ME_WARN))
2157         {
2158           warn_when_safe_lispobj
2159             (Qlist, Qwarning,
2160              list2 (build_string
2161                     ("Malformed property list -- list has been truncated"),
2162                     *plist));
2163           *badplace = Qnil;
2164         }
2165       return Qunbound;
2166     }
2167 }
2168
2169 /* Called on a circular property list.  BADPLACE should be some place
2170    where truncating will result in an even-length list, as above.
2171    If doesn't particularly matter where we truncate -- anywhere we
2172    truncate along the entire list will break the circularity, because
2173    it will create a terminus and the list currently doesn't have one.
2174 */
2175
2176 static Lisp_Object
2177 bad_bad_turtle (Lisp_Object *plist, Lisp_Object *badplace, Error_behavior errb)
2178 {
2179   if (ERRB_EQ (errb, ERROR_ME))
2180     /* #### Eek, this will probably result in another error
2181        when PLIST is printed out */
2182     return Fsignal (Qcircular_property_list, list1 (*plist));
2183   else
2184     {
2185       if (ERRB_EQ (errb, ERROR_ME_WARN))
2186         {
2187           warn_when_safe_lispobj
2188             (Qlist, Qwarning,
2189              list2 (build_string
2190                     ("Circular property list -- list has been truncated"),
2191                     *plist));
2192           *badplace = Qnil;
2193         }
2194       return Qunbound;
2195     }
2196 }
2197
2198 /* Advance the tortoise pointer by two (one iteration of a property-list
2199    loop) and the hare pointer by four and verify that no malformations
2200    or circularities exist.  If so, return zero and store a value into
2201    RETVAL that should be returned by the calling function.  Otherwise,
2202    return 1.  See external_plist_get().
2203  */
2204
2205 static int
2206 advance_plist_pointers (Lisp_Object *plist,
2207                         Lisp_Object **tortoise, Lisp_Object **hare,
2208                         Error_behavior errb, Lisp_Object *retval)
2209 {
2210   int i;
2211   Lisp_Object *tortsave = *tortoise;
2212
2213   /* Note that our "fixing" may be more brutal than necessary,
2214      but it's the user's own problem, not ours. if they went in and
2215      manually fucked up a plist. */
2216
2217   for (i = 0; i < 2; i++)
2218     {
2219       /* This is a standard iteration of a defensive-loop-checking
2220          loop.  We just do it twice because we want to advance past
2221          both the property and its value.
2222
2223          If the pointer indirection is confusing you, remember that
2224          one level of indirection on the hare and tortoise pointers
2225          is only due to pass-by-reference for this function.  The other
2226          level is so that the plist can be fixed in place. */
2227
2228       /* When we reach the end of a well-formed plist, **HARE is
2229          nil.  In that case, we don't do anything at all except
2230          advance TORTOISE by one.  Otherwise, we advance HARE
2231          by two (making sure it's OK to do so), then advance
2232          TORTOISE by one (it will always be OK to do so because
2233          the HARE is always ahead of the TORTOISE and will have
2234          already verified the path), then make sure TORTOISE and
2235          HARE don't contain the same non-nil object -- if the
2236          TORTOISE and the HARE ever meet, then obviously we're
2237          in a circularity, and if we're in a circularity, then
2238          the TORTOISE and the HARE can't cross paths without
2239          meeting, since the HARE only gains one step over the
2240          TORTOISE per iteration. */
2241
2242       if (!NILP (**hare))
2243         {
2244           Lisp_Object *haresave = *hare;
2245           if (!CONSP (**hare))
2246             {
2247               *retval = bad_bad_bunny (plist, haresave, errb);
2248               return 0;
2249             }
2250           *hare = &XCDR (**hare);
2251           /* In a non-plist, we'd check here for a nil value for
2252              **HARE, which is OK (it just means the list has an
2253              odd number of elements).  In a plist, it's not OK
2254              for the list to have an odd number of elements. */
2255           if (!CONSP (**hare))
2256             {
2257               *retval = bad_bad_bunny (plist, haresave, errb);
2258               return 0;
2259             }
2260           *hare = &XCDR (**hare);
2261         }
2262
2263       *tortoise = &XCDR (**tortoise);
2264       if (!NILP (**hare) && EQ (**tortoise, **hare))
2265         {
2266           *retval = bad_bad_turtle (plist, tortsave, errb);
2267           return 0;
2268         }
2269     }
2270
2271   return 1;
2272 }
2273
2274 /* Return the value of PROPERTY from PLIST, or Qunbound if
2275    property is not on the list.
2276
2277    PLIST is a Lisp-accessible property list, meaning that it
2278    has to be checked for malformations and circularities.
2279
2280    If ERRB is ERROR_ME, an error will be signalled.  Otherwise, the
2281    function will never signal an error; and if ERRB is ERROR_ME_WARN,
2282    on finding a malformation or a circularity, it issues a warning and
2283    attempts to silently fix the problem.
2284
2285    A pointer to PLIST is passed in so that PLIST can be successfully
2286    "fixed" even if the error is at the beginning of the plist. */
2287
2288 Lisp_Object
2289 external_plist_get (Lisp_Object *plist, Lisp_Object property,
2290                     int laxp, Error_behavior errb)
2291 {
2292   Lisp_Object *tortoise = plist;
2293   Lisp_Object *hare = plist;
2294
2295   while (!NILP (*tortoise))
2296     {
2297       Lisp_Object *tortsave = tortoise;
2298       Lisp_Object retval;
2299
2300       /* We do the standard tortoise/hare march.  We isolate the
2301          grungy stuff to do this in advance_plist_pointers(), though.
2302          To us, all this function does is advance the tortoise
2303          pointer by two and the hare pointer by four and make sure
2304          everything's OK.  We first advance the pointers and then
2305          check if a property matched; this ensures that our
2306          check for a matching property is safe. */
2307
2308       if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2309         return retval;
2310
2311       if (!laxp ? EQ (XCAR (*tortsave), property)
2312           : internal_equal (XCAR (*tortsave), property, 0))
2313         return XCAR (XCDR (*tortsave));
2314     }
2315
2316   return Qunbound;
2317 }
2318
2319 /* Set PLIST's value for PROPERTY to VALUE, given a possibly
2320    malformed or circular plist.  Analogous to external_plist_get(). */
2321
2322 void
2323 external_plist_put (Lisp_Object *plist, Lisp_Object property,
2324                     Lisp_Object value, int laxp, Error_behavior errb)
2325 {
2326   Lisp_Object *tortoise = plist;
2327   Lisp_Object *hare = plist;
2328
2329   while (!NILP (*tortoise))
2330     {
2331       Lisp_Object *tortsave = tortoise;
2332       Lisp_Object retval;
2333
2334       /* See above */
2335       if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2336         return;
2337
2338       if (!laxp ? EQ (XCAR (*tortsave), property)
2339           : internal_equal (XCAR (*tortsave), property, 0))
2340         {
2341           XCAR (XCDR (*tortsave)) = value;
2342           return;
2343         }
2344     }
2345
2346   *plist = Fcons (property, Fcons (value, *plist));
2347 }
2348
2349 int
2350 external_remprop (Lisp_Object *plist, Lisp_Object property,
2351                   int laxp, Error_behavior errb)
2352 {
2353   Lisp_Object *tortoise = plist;
2354   Lisp_Object *hare = plist;
2355
2356   while (!NILP (*tortoise))
2357     {
2358       Lisp_Object *tortsave = tortoise;
2359       Lisp_Object retval;
2360
2361       /* See above */
2362       if (!advance_plist_pointers (plist, &tortoise, &hare, errb, &retval))
2363         return 0;
2364
2365       if (!laxp ? EQ (XCAR (*tortsave), property)
2366           : internal_equal (XCAR (*tortsave), property, 0))
2367         {
2368           /* Now you see why it's so convenient to have that level
2369              of indirection. */
2370           *tortsave = XCDR (XCDR (*tortsave));
2371           return 1;
2372         }
2373     }
2374
2375   return 0;
2376 }
2377
2378 DEFUN ("plist-get", Fplist_get, 2, 3, 0, /*
2379 Extract a value from a property list.
2380 PLIST is a property list, which is a list of the form
2381 \(PROP1 VALUE1 PROP2 VALUE2...).  This function returns the value
2382 corresponding to the given PROP, or DEFAULT if PROP is not
2383 one of the properties on the list.
2384 */
2385        (plist, prop, default_))
2386 {
2387   Lisp_Object val = external_plist_get (&plist, prop, 0, ERROR_ME);
2388   if (UNBOUNDP (val))
2389     return default_;
2390   return val;
2391 }
2392
2393 DEFUN ("plist-put", Fplist_put, 3, 3, 0, /*
2394 Change value in PLIST of PROP to VAL.
2395 PLIST is a property list, which is a list of the form \(PROP1 VALUE1
2396 PROP2 VALUE2 ...).  PROP is usually a symbol and VAL is any object.
2397 If PROP is already a property on the list, its value is set to VAL,
2398 otherwise the new PROP VAL pair is added.  The new plist is returned;
2399 use `(setq x (plist-put x prop val))' to be sure to use the new value.
2400 The PLIST is modified by side effects.
2401 */
2402        (plist, prop, val))
2403 {
2404   external_plist_put (&plist, prop, val, 0, ERROR_ME);
2405   return plist;
2406 }
2407
2408 DEFUN ("plist-remprop", Fplist_remprop, 2, 2, 0, /*
2409 Remove from PLIST the property PROP and its value.
2410 PLIST is a property list, which is a list of the form \(PROP1 VALUE1
2411 PROP2 VALUE2 ...).  PROP is usually a symbol.  The new plist is
2412 returned; use `(setq x (plist-remprop x prop val))' to be sure to use
2413 the new value.  The PLIST is modified by side effects.
2414 */
2415        (plist, prop))
2416 {
2417   external_remprop (&plist, prop, 0, ERROR_ME);
2418   return plist;
2419 }
2420
2421 DEFUN ("plist-member", Fplist_member, 2, 2, 0, /*
2422 Return t if PROP has a value specified in PLIST.
2423 */
2424        (plist, prop))
2425 {
2426   return UNBOUNDP (Fplist_get (plist, prop, Qunbound)) ? Qnil : Qt;
2427 }
2428
2429 DEFUN ("check-valid-plist", Fcheck_valid_plist, 1, 1, 0, /*
2430 Given a plist, signal an error if there is anything wrong with it.
2431 This means that it's a malformed or circular plist.
2432 */
2433        (plist))
2434 {
2435   Lisp_Object *tortoise;
2436   Lisp_Object *hare;
2437
2438  start_over:
2439   tortoise = &plist;
2440   hare = &plist;
2441   while (!NILP (*tortoise))
2442     {
2443       Lisp_Object retval;
2444
2445       /* See above */
2446       if (!advance_plist_pointers (&plist, &tortoise, &hare, ERROR_ME,
2447                                    &retval))
2448         goto start_over;
2449     }
2450
2451   return Qnil;
2452 }
2453
2454 DEFUN ("valid-plist-p", Fvalid_plist_p, 1, 1, 0, /*
2455 Given a plist, return non-nil if its format is correct.
2456 If it returns nil, `check-valid-plist' will signal an error when given
2457 the plist; that means it's a malformed or circular plist or has non-symbols
2458 as keywords.
2459 */
2460        (plist))
2461 {
2462   Lisp_Object *tortoise;
2463   Lisp_Object *hare;
2464
2465   tortoise = &plist;
2466   hare = &plist;
2467   while (!NILP (*tortoise))
2468     {
2469       Lisp_Object retval;
2470
2471       /* See above */
2472       if (!advance_plist_pointers (&plist, &tortoise, &hare, ERROR_ME_NOT,
2473                                    &retval))
2474         return Qnil;
2475     }
2476
2477   return Qt;
2478 }
2479
2480 DEFUN ("canonicalize-plist", Fcanonicalize_plist, 1, 2, 0, /*
2481 Destructively remove any duplicate entries from a plist.
2482 In such cases, the first entry applies.
2483
2484 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2485  a nil value is removed.  This feature is a virus that has infected
2486  old Lisp implementations, but should not be used except for backward
2487  compatibility.
2488
2489 The new plist is returned.  If NIL-MEANS-NOT-PRESENT is given, the
2490  return value may not be EQ to the passed-in value, so make sure to
2491  `setq' the value back into where it came from.
2492 */
2493        (plist, nil_means_not_present))
2494 {
2495   Lisp_Object head = plist;
2496
2497   Fcheck_valid_plist (plist);
2498
2499   while (!NILP (plist))
2500     {
2501       Lisp_Object prop = Fcar (plist);
2502       Lisp_Object next = Fcdr (plist);
2503
2504       CHECK_CONS (next); /* just make doubly sure we catch any errors */
2505       if (!NILP (nil_means_not_present) && NILP (Fcar (next)))
2506         {
2507           if (EQ (head, plist))
2508             head = Fcdr (next);
2509           plist = Fcdr (next);
2510           continue;
2511         }
2512       /* external_remprop returns 1 if it removed any property.
2513          We have to loop till it didn't remove anything, in case
2514          the property occurs many times. */
2515       while (external_remprop (&XCDR (next), prop, 0, ERROR_ME));
2516       plist = Fcdr (next);
2517     }
2518
2519   return head;
2520 }
2521
2522 DEFUN ("lax-plist-get", Flax_plist_get, 2, 3, 0, /*
2523 Extract a value from a lax property list.
2524
2525 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2526 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2527 using `equal' instead of `eq'.  This function returns the value
2528 corresponding to the given PROP, or DEFAULT if PROP is not one of the
2529 properties on the list.
2530 */
2531        (lax_plist, prop, default_))
2532 {
2533   Lisp_Object val = external_plist_get (&lax_plist, prop, 1, ERROR_ME);
2534   if (UNBOUNDP (val))
2535     return default_;
2536   return val;
2537 }
2538
2539 DEFUN ("lax-plist-put", Flax_plist_put, 3, 3, 0, /*
2540 Change value in LAX-PLIST of PROP to VAL.
2541 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2542 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2543 using `equal' instead of `eq'.  PROP is usually a symbol and VAL is
2544 any object.  If PROP is already a property on the list, its value is
2545 set to VAL, otherwise the new PROP VAL pair is added.  The new plist
2546 is returned; use `(setq x (lax-plist-put x prop val))' to be sure to
2547 use the new value.  The LAX-PLIST is modified by side effects.
2548 */
2549        (lax_plist, prop, val))
2550 {
2551   external_plist_put (&lax_plist, prop, val, 1, ERROR_ME);
2552   return lax_plist;
2553 }
2554
2555 DEFUN ("lax-plist-remprop", Flax_plist_remprop, 2, 2, 0, /*
2556 Remove from LAX-PLIST the property PROP and its value.
2557 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2558 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2559 using `equal' instead of `eq'.  PROP is usually a symbol.  The new
2560 plist is returned; use `(setq x (lax-plist-remprop x prop val))' to be
2561 sure to use the new value.  The LAX-PLIST is modified by side effects.
2562 */
2563        (lax_plist, prop))
2564 {
2565   external_remprop (&lax_plist, prop, 1, ERROR_ME);
2566   return lax_plist;
2567 }
2568
2569 DEFUN ("lax-plist-member", Flax_plist_member, 2, 2, 0, /*
2570 Return t if PROP has a value specified in LAX-PLIST.
2571 LAX-PLIST is a lax property list, which is a list of the form \(PROP1
2572 VALUE1 PROP2 VALUE2...), where comparions between properties is done
2573 using `equal' instead of `eq'.
2574 */
2575        (lax_plist, prop))
2576 {
2577   return UNBOUNDP (Flax_plist_get (lax_plist, prop, Qunbound)) ? Qnil : Qt;
2578 }
2579
2580 DEFUN ("canonicalize-lax-plist", Fcanonicalize_lax_plist, 1, 2, 0, /*
2581 Destructively remove any duplicate entries from a lax plist.
2582 In such cases, the first entry applies.
2583
2584 If optional arg NIL-MEANS-NOT-PRESENT is non-nil, then a property with
2585  a nil value is removed.  This feature is a virus that has infected
2586  old Lisp implementations, but should not be used except for backward
2587  compatibility.
2588
2589 The new plist is returned.  If NIL-MEANS-NOT-PRESENT is given, the
2590  return value may not be EQ to the passed-in value, so make sure to
2591  `setq' the value back into where it came from.
2592 */
2593        (lax_plist, nil_means_not_present))
2594 {
2595   Lisp_Object head = lax_plist;
2596
2597   Fcheck_valid_plist (lax_plist);
2598
2599   while (!NILP (lax_plist))
2600     {
2601       Lisp_Object prop = Fcar (lax_plist);
2602       Lisp_Object next = Fcdr (lax_plist);
2603
2604       CHECK_CONS (next); /* just make doubly sure we catch any errors */
2605       if (!NILP (nil_means_not_present) && NILP (Fcar (next)))
2606         {
2607           if (EQ (head, lax_plist))
2608             head = Fcdr (next);
2609           lax_plist = Fcdr (next);
2610           continue;
2611         }
2612       /* external_remprop returns 1 if it removed any property.
2613          We have to loop till it didn't remove anything, in case
2614          the property occurs many times. */
2615       while (external_remprop (&XCDR (next), prop, 1, ERROR_ME));
2616       lax_plist = Fcdr (next);
2617     }
2618
2619   return head;
2620 }
2621
2622 /* In C because the frame props stuff uses it */
2623
2624 DEFUN ("destructive-alist-to-plist", Fdestructive_alist_to_plist, 1, 1, 0, /*
2625 Convert association list ALIST into the equivalent property-list form.
2626 The plist is returned.  This converts from
2627
2628 \((a . 1) (b . 2) (c . 3))
2629
2630 into
2631
2632 \(a 1 b 2 c 3)
2633
2634 The original alist is destroyed in the process of constructing the plist.
2635 See also `alist-to-plist'.
2636 */
2637        (alist))
2638 {
2639   Lisp_Object head = alist;
2640   while (!NILP (alist))
2641     {
2642       /* remember the alist element. */
2643       Lisp_Object el = Fcar (alist);
2644
2645       Fsetcar (alist, Fcar (el));
2646       Fsetcar (el, Fcdr (el));
2647       Fsetcdr (el, Fcdr (alist));
2648       Fsetcdr (alist, el);
2649       alist = Fcdr (Fcdr (alist));
2650     }
2651
2652   return head;
2653 }
2654
2655 /* Symbol plists are directly accessible, so we need to protect against
2656    invalid property list structure */
2657
2658 static Lisp_Object
2659 symbol_getprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object default_)
2660 {
2661   Lisp_Object val = external_plist_get (&XSYMBOL (sym)->plist, propname,
2662                                         0, ERROR_ME);
2663   return UNBOUNDP (val) ? default_ : val;
2664 }
2665
2666 static void
2667 symbol_putprop (Lisp_Object sym, Lisp_Object propname, Lisp_Object value)
2668 {
2669   external_plist_put (&XSYMBOL (sym)->plist, propname, value, 0, ERROR_ME);
2670 }
2671
2672 static int
2673 symbol_remprop (Lisp_Object symbol, Lisp_Object propname)
2674 {
2675   return external_remprop (&XSYMBOL (symbol)->plist, propname, 0, ERROR_ME);
2676 }
2677
2678 /* We store the string's extent info as the first element of the string's
2679    property list; and the string's MODIFF as the first or second element
2680    of the string's property list (depending on whether the extent info
2681    is present), but only if the string has been modified.  This is ugly
2682    but it reduces the memory allocated for the string in the vast
2683    majority of cases, where the string is never modified and has no
2684    extent info. */
2685
2686
2687 static Lisp_Object *
2688 string_plist_ptr (struct Lisp_String *s)
2689 {
2690   Lisp_Object *ptr = &s->plist;
2691
2692   if (CONSP (*ptr) && EXTENT_INFOP (XCAR (*ptr)))
2693     ptr = &XCDR (*ptr);
2694   if (CONSP (*ptr) && INTP (XCAR (*ptr)))
2695     ptr = &XCDR (*ptr);
2696   return ptr;
2697 }
2698
2699 static Lisp_Object
2700 string_getprop (struct Lisp_String *s, Lisp_Object property,
2701                 Lisp_Object default_)
2702 {
2703   Lisp_Object val = external_plist_get (string_plist_ptr (s), property, 0,
2704                                         ERROR_ME);
2705   return UNBOUNDP (val) ? default_ : val;
2706 }
2707
2708 static void
2709 string_putprop (struct Lisp_String *s, Lisp_Object property,
2710                 Lisp_Object value)
2711 {
2712   external_plist_put (string_plist_ptr (s), property, value, 0, ERROR_ME);
2713 }
2714
2715 static int
2716 string_remprop (struct Lisp_String *s, Lisp_Object property)
2717 {
2718   return external_remprop (string_plist_ptr (s), property, 0, ERROR_ME);
2719 }
2720
2721 static Lisp_Object
2722 string_plist (struct Lisp_String *s)
2723 {
2724   return *string_plist_ptr (s);
2725 }
2726
2727 DEFUN ("get", Fget, 2, 3, 0, /*
2728 Return the value of OBJECT's PROPNAME property.
2729 This is the last VALUE stored with `(put OBJECT PROPNAME VALUE)'.
2730 If there is no such property, return optional third arg DEFAULT
2731 \(which defaults to `nil').  OBJECT can be a symbol, face, extent,
2732 or string.  See also `put', `remprop', and `object-plist'.
2733 */
2734        (object, propname, default_))
2735 {
2736   Lisp_Object val;
2737
2738   /* Various places in emacs call Fget() and expect it not to quit,
2739      so don't quit. */
2740
2741   /* It's easiest to treat symbols specially because they may not
2742      be an lrecord */
2743   if (SYMBOLP (object))
2744     val = symbol_getprop (object, propname, default_);
2745   else if (STRINGP (object))
2746     val = string_getprop (XSTRING (object), propname, default_);
2747   else if (LRECORDP (object))
2748     {
2749       CONST struct lrecord_implementation
2750         *imp = XRECORD_LHEADER_IMPLEMENTATION (object);
2751       if (imp->getprop)
2752         {
2753           val = (imp->getprop) (object, propname);
2754           if (UNBOUNDP (val))
2755             val = default_;
2756         }
2757       else
2758         goto noprops;
2759     }
2760   else
2761     {
2762     noprops:
2763       signal_simple_error ("Object type has no properties", object);
2764     }
2765
2766   return val;
2767 }
2768
2769 DEFUN ("put", Fput, 3, 3, 0, /*
2770 Store OBJECT's PROPNAME property with value VALUE.
2771 It can be retrieved with `(get OBJECT PROPNAME)'.  OBJECT can be a
2772 symbol, face, extent, or string.
2773
2774 For a string, no properties currently have predefined meanings.
2775 For the predefined properties for extents, see `set-extent-property'.
2776 For the predefined properties for faces, see `set-face-property'.
2777
2778 See also `get', `remprop', and `object-plist'.
2779 */
2780        (object, propname, value))
2781 {
2782   CHECK_SYMBOL (propname);
2783   CHECK_IMPURE (object);
2784
2785   if (SYMBOLP (object))
2786     symbol_putprop (object, propname, value);
2787   else if (STRINGP (object))
2788     string_putprop (XSTRING (object), propname, value);
2789   else if (LRECORDP (object))
2790     {
2791       CONST struct lrecord_implementation
2792         *imp = XRECORD_LHEADER_IMPLEMENTATION (object);
2793       if (imp->putprop)
2794         {
2795           if (! (imp->putprop) (object, propname, value))
2796             signal_simple_error ("Can't set property on object", propname);
2797         }
2798       else
2799         goto noprops;
2800     }
2801   else
2802     {
2803     noprops:
2804       signal_simple_error ("Object type has no settable properties", object);
2805     }
2806
2807   return value;
2808 }
2809
2810 void
2811 pure_put (Lisp_Object sym, Lisp_Object prop, Lisp_Object val)
2812 {
2813   Fput (sym, prop, Fpurecopy (val));
2814 }
2815
2816 DEFUN ("remprop", Fremprop, 2, 2, 0, /*
2817 Remove from OBJECT's property list the property PROPNAME and its
2818 value.  OBJECT can be a symbol, face, extent, or string.  Returns
2819 non-nil if the property list was actually changed (i.e. if PROPNAME
2820 was present in the property list).  See also `get', `put', and
2821 `object-plist'.
2822 */
2823        (object, propname))
2824 {
2825   int retval = 0;
2826
2827   CHECK_SYMBOL (propname);
2828   CHECK_IMPURE (object);
2829
2830   if (SYMBOLP (object))
2831     retval = symbol_remprop (object, propname);
2832   else if (STRINGP (object))
2833     retval = string_remprop (XSTRING (object), propname);
2834   else if (LRECORDP (object))
2835     {
2836       CONST struct lrecord_implementation
2837         *imp = XRECORD_LHEADER_IMPLEMENTATION (object);
2838       if (imp->remprop)
2839         {
2840           retval = (imp->remprop) (object, propname);
2841           if (retval == -1)
2842             signal_simple_error ("Can't remove property from object",
2843                                  propname);
2844         }
2845       else
2846         goto noprops;
2847     }
2848   else
2849     {
2850     noprops:
2851       signal_simple_error ("Object type has no removable properties", object);
2852     }
2853
2854   return retval ? Qt : Qnil;
2855 }
2856
2857 DEFUN ("object-plist", Fobject_plist, 1, 1, 0, /*
2858 Return a property list of OBJECT's props.
2859 For a symbol this is equivalent to `symbol-plist'.
2860 Do not modify the property list directly; this may or may not have
2861 the desired effects. (In particular, for a property with a special
2862 interpretation, this will probably have no effect at all.)
2863 */
2864        (object))
2865 {
2866   if (SYMBOLP (object))
2867     return Fsymbol_plist (object);
2868   else if (STRINGP (object))
2869     return string_plist (XSTRING (object));
2870   else if (LRECORDP (object))
2871     {
2872       CONST struct lrecord_implementation
2873         *imp = XRECORD_LHEADER_IMPLEMENTATION (object);
2874       if (imp->plist)
2875         return (imp->plist) (object);
2876       else
2877         signal_simple_error ("Object type has no properties", object);
2878     }
2879   else
2880     signal_simple_error ("Object type has no properties", object);
2881
2882   return Qnil;
2883 }
2884
2885 \f
2886 int
2887 internal_equal (Lisp_Object o1, Lisp_Object o2, int depth)
2888 {
2889   if (depth > 200)
2890     error ("Stack overflow in equal");
2891 #ifndef LRECORD_CONS
2892  do_cdr:
2893 #endif
2894   QUIT;
2895   if (EQ_WITH_EBOLA_NOTICE (o1, o2))
2896     return 1;
2897   /* Note that (equal 20 20.0) should be nil */
2898   else if (XTYPE (o1) != XTYPE (o2))
2899     return 0;
2900 #ifndef LRECORD_CONS
2901   else if (CONSP (o1))
2902     {
2903       if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1))
2904         return 0;
2905       o1 = XCDR (o1);
2906       o2 = XCDR (o2);
2907       goto do_cdr;
2908     }
2909 #endif
2910 #ifndef LRECORD_VECTOR
2911   else if (VECTORP (o1))
2912     {
2913       Lisp_Object *v1 = XVECTOR_DATA (o1);
2914       Lisp_Object *v2 = XVECTOR_DATA (o2);
2915       int len = XVECTOR_LENGTH (o1);
2916       if (len != XVECTOR_LENGTH (o2))
2917         return 0;
2918       while (len--)
2919         if (!internal_equal (*v1++, *v2++, depth + 1))
2920           return 0;
2921       return 1;
2922     }
2923 #endif
2924 #ifndef LRECORD_STRING
2925   else if (STRINGP (o1))
2926     {
2927       Bytecount len;
2928       return (((len = XSTRING_LENGTH (o1)) == XSTRING_LENGTH (o2)) &&
2929               !memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len));
2930     }
2931 #endif
2932   else if (LRECORDP (o1))
2933     {
2934       CONST struct lrecord_implementation
2935         *imp1 = XRECORD_LHEADER_IMPLEMENTATION (o1),
2936         *imp2 = XRECORD_LHEADER_IMPLEMENTATION (o2);
2937       if (imp1 != imp2)
2938         return 0;
2939       else if (imp1->equal == 0)
2940         /* EQ-ness of the objects was noticed above */
2941         return 0;
2942       else
2943         return (imp1->equal) (o1, o2, depth);
2944     }
2945
2946   return 0;
2947 }
2948
2949 /* Note that we may be calling sub-objects that will use
2950    internal_equal() (instead of internal_old_equal()).  Oh well.
2951    We will get an Ebola note if there's any possibility of confusion,
2952    but that seems unlikely. */
2953
2954 static int
2955 internal_old_equal (Lisp_Object o1, Lisp_Object o2, int depth)
2956 {
2957   if (depth > 200)
2958     error ("Stack overflow in equal");
2959 #ifndef LRECORD_CONS
2960  do_cdr:
2961 #endif
2962   QUIT;
2963   if (HACKEQ_UNSAFE (o1, o2))
2964     return 1;
2965   /* Note that (equal 20 20.0) should be nil */
2966   else if (XTYPE (o1) != XTYPE (o2))
2967     return 0;
2968 #ifndef LRECORD_CONS
2969   else if (CONSP (o1))
2970     {
2971       if (!internal_old_equal (XCAR (o1), XCAR (o2), depth + 1))
2972         return 0;
2973       o1 = XCDR (o1);
2974       o2 = XCDR (o2);
2975       goto do_cdr;
2976     }
2977 #endif
2978 #ifndef LRECORD_VECTOR
2979   else if (VECTORP (o1))
2980     {
2981       int indice;
2982       int len = XVECTOR_LENGTH (o1);
2983       if (len != XVECTOR_LENGTH (o2))
2984         return 0;
2985       for (indice = 0; indice < len; indice++)
2986         {
2987           if (!internal_old_equal (XVECTOR_DATA (o1) [indice],
2988                                    XVECTOR_DATA (o2) [indice],
2989                                    depth + 1))
2990             return 0;
2991         }
2992       return 1;
2993     }
2994 #endif
2995 #ifndef LRECORD_STRING
2996   else if (STRINGP (o1))
2997     {
2998       Bytecount len = XSTRING_LENGTH (o1);
2999       if (len != XSTRING_LENGTH (o2))
3000         return 0;
3001       if (memcmp (XSTRING_DATA (o1), XSTRING_DATA (o2), len))
3002         return 0;
3003       return 1;
3004     }
3005 #endif
3006   else if (LRECORDP (o1))
3007     {
3008       CONST struct lrecord_implementation
3009         *imp1 = XRECORD_LHEADER_IMPLEMENTATION (o1),
3010         *imp2 = XRECORD_LHEADER_IMPLEMENTATION (o2);
3011       if (imp1 != imp2)
3012         return 0;
3013       else if (imp1->equal == 0)
3014         /* EQ-ness of the objects was noticed above */
3015         return 0;
3016       else
3017         return (imp1->equal) (o1, o2, depth);
3018     }
3019
3020   return 0;
3021 }
3022
3023 DEFUN ("equal", Fequal, 2, 2, 0, /*
3024 Return t if two Lisp objects have similar structure and contents.
3025 They must have the same data type.
3026 Conses are compared by comparing the cars and the cdrs.
3027 Vectors and strings are compared element by element.
3028 Numbers are compared by value.  Symbols must match exactly.
3029 */
3030        (o1, o2))
3031 {
3032   return internal_equal (o1, o2, 0) ? Qt : Qnil;
3033 }
3034
3035 DEFUN ("old-equal", Fold_equal, 2, 2, 0, /*
3036 Return t if two Lisp objects have similar structure and contents.
3037 They must have the same data type.
3038 \(Note, however, that an exception is made for characters and integers;
3039 this is known as the "char-int confoundance disease." See `eq' and
3040 `old-eq'.)
3041 This function is provided only for byte-code compatibility with v19.
3042 Do not use it.
3043 */
3044        (o1, o2))
3045 {
3046   return internal_old_equal (o1, o2, 0) ? Qt : Qnil;
3047 }
3048
3049 \f
3050 DEFUN ("fillarray", Ffillarray, 2, 2, 0, /*
3051 Store each element of ARRAY with ITEM.
3052 ARRAY is a vector, bit vector, or string.
3053 */
3054        (array, item))
3055 {
3056  retry:
3057   if (STRINGP (array))
3058     {
3059       Emchar charval;
3060       struct Lisp_String *s = XSTRING (array);
3061       Charcount len = string_char_length (s);
3062       Charcount i;
3063       CHECK_CHAR_COERCE_INT (item);
3064       CHECK_IMPURE (array);
3065       charval = XCHAR (item);
3066       for (i = 0; i < len; i++)
3067         set_string_char (s, i, charval);
3068       bump_string_modiff (array);
3069     }
3070   else if (VECTORP (array))
3071     {
3072       Lisp_Object *p = XVECTOR_DATA (array);
3073       int len = XVECTOR_LENGTH (array);
3074       CHECK_IMPURE (array);
3075       while (len--)
3076         *p++ = item;
3077     }
3078   else if (BIT_VECTORP (array))
3079     {
3080       struct Lisp_Bit_Vector *v = XBIT_VECTOR (array);
3081       int len = bit_vector_length (v);
3082       int bit;
3083       CHECK_BIT (item);
3084       CHECK_IMPURE (array);
3085       bit = XINT (item);
3086       while (len--)
3087         set_bit_vector_bit (v, len, bit);
3088     }
3089   else
3090     {
3091       array = wrong_type_argument (Qarrayp, array);
3092       goto retry;
3093     }
3094   return array;
3095 }
3096
3097 Lisp_Object
3098 nconc2 (Lisp_Object s1, Lisp_Object s2)
3099 {
3100   Lisp_Object args[2];
3101   args[0] = s1;
3102   args[1] = s2;
3103   return Fnconc (2, args);
3104 }
3105
3106 DEFUN ("nconc", Fnconc, 0, MANY, 0, /*
3107 Concatenate any number of lists by altering them.
3108 Only the last argument is not altered, and need not be a list.
3109 Also see: `append'.
3110 If the first argument is nil, there is no way to modify it by side
3111 effect; therefore, write `(setq foo (nconc foo list))' to be sure of
3112 changing the value of `foo'.
3113 */
3114        (int nargs, Lisp_Object *args))
3115 {
3116   int argnum = 0;
3117   struct gcpro gcpro1;
3118
3119   /* The modus operandi in Emacs is "caller gc-protects args".
3120      However, nconc (particularly nconc2 ()) is called many times
3121      in Emacs on freshly created stuff (e.g. you see the idiom
3122      nconc2 (Fcopy_sequence (foo), bar) a lot).  So we help those
3123      callers out by protecting the args ourselves to save them
3124      a lot of temporary-variable grief. */
3125
3126   GCPRO1 (args[0]);
3127   gcpro1.nvars = nargs;
3128
3129   while (argnum < nargs)
3130     {
3131       Lisp_Object val = args[argnum];
3132       if (CONSP (val))
3133         {
3134           /* Found the first cons, which will be our return value.  */
3135           Lisp_Object last = val;
3136
3137           for (argnum++; argnum < nargs; argnum++)
3138             {
3139               Lisp_Object next = args[argnum];
3140             redo:
3141               if (CONSP (next) || argnum == nargs -1)
3142                 {
3143                   /* (setcdr (last val) next) */
3144                   while (CONSP (XCDR (last)))
3145                     {
3146                       last = XCDR (last);
3147                       QUIT;
3148                     }
3149                   XCDR (last) = next;
3150                 }
3151               else if (NILP (next))
3152                 {
3153                   continue;
3154                 }
3155               else
3156                 {
3157                   next = wrong_type_argument (next, Qlistp);
3158                   goto redo;
3159                 }
3160             }
3161           RETURN_UNGCPRO (val);
3162         }
3163       else if (NILP (val))
3164         argnum++;
3165       else if (argnum == nargs - 1) /* last arg? */
3166         RETURN_UNGCPRO (val);
3167       else
3168         args[argnum] = wrong_type_argument (val, Qlistp);
3169     }
3170   RETURN_UNGCPRO (Qnil);  /* No non-nil args provided. */
3171 }
3172
3173 \f
3174 /* This is the guts of all mapping functions.
3175  Apply fn to each element of seq, one by one,
3176  storing the results into elements of vals, a C vector of Lisp_Objects.
3177  leni is the length of vals, which should also be the length of seq.
3178
3179  If VALS is a null pointer, do not accumulate the results. */
3180
3181 static void
3182 mapcar1 (int leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
3183 {
3184   Lisp_Object tail;
3185   Lisp_Object dummy = Qnil;
3186   int i;
3187   struct gcpro gcpro1, gcpro2, gcpro3;
3188   Lisp_Object result;
3189
3190   GCPRO3 (dummy, fn, seq);
3191
3192   if (vals)
3193     {
3194       /* Don't let vals contain any garbage when GC happens.  */
3195       for (i = 0; i < leni; i++)
3196         vals[i] = Qnil;
3197       gcpro1.var = vals;
3198       gcpro1.nvars = leni;
3199     }
3200
3201   /* We need not explicitly protect `tail' because it is used only on
3202     lists, and 1) lists are not relocated and 2) the list is marked
3203     via `seq' so will not be freed */
3204
3205   if (VECTORP (seq))
3206     {
3207       for (i = 0; i < leni; i++)
3208         {
3209           dummy = XVECTOR_DATA (seq)[i];
3210           result = call1 (fn, dummy);
3211           if (vals)
3212             vals[i] = result;
3213         }
3214     }
3215   else if (BIT_VECTORP (seq))
3216     {
3217       struct Lisp_Bit_Vector *v = XBIT_VECTOR (seq);
3218       for (i = 0; i < leni; i++)
3219         {
3220           XSETINT (dummy, bit_vector_bit (v, i));
3221           result = call1 (fn, dummy);
3222           if (vals)
3223             vals[i] = result;
3224         }
3225     }
3226   else if (STRINGP (seq))
3227     {
3228       for (i = 0; i < leni; i++)
3229         {
3230           result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
3231           if (vals)
3232             vals[i] = result;
3233         }
3234     }
3235   else   /* Must be a list, since Flength did not get an error */
3236     {
3237       tail = seq;
3238       for (i = 0; i < leni; i++)
3239         {
3240           result = call1 (fn, Fcar (tail));
3241           if (vals)
3242             vals[i] = result;
3243           tail = Fcdr (tail);
3244         }
3245     }
3246
3247   UNGCPRO;
3248 }
3249
3250 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /*
3251 Apply FN to each element of SEQ, and concat the results as strings.
3252 In between each pair of results, stick in SEP.
3253 Thus, " " as SEP results in spaces between the values returned by FN.
3254 */
3255        (fn, seq, sep))
3256 {
3257   int len = XINT (Flength (seq));
3258   Lisp_Object *args;
3259   int i;
3260   struct gcpro gcpro1;
3261   int nargs = len + len - 1;
3262
3263   if (nargs < 0) return build_string ("");
3264
3265   args = alloca_array (Lisp_Object, nargs);
3266
3267   GCPRO1 (sep);
3268   mapcar1 (len, args, fn, seq);
3269   UNGCPRO;
3270
3271   for (i = len - 1; i >= 0; i--)
3272     args[i + i] = args[i];
3273
3274   for (i = 1; i < nargs; i += 2)
3275     args[i] = sep;
3276
3277   return Fconcat (nargs, args);
3278 }
3279
3280 DEFUN ("mapcar", Fmapcar, 2, 2, 0, /*
3281 Apply FUNCTION to each element of SEQUENCE, and make a list of the results.
3282 The result is a list just as long as SEQUENCE.
3283 SEQUENCE may be a list, a vector, a bit vector, or a string.
3284 */
3285        (fn, seq))
3286 {
3287   int len = XINT (Flength (seq));
3288   Lisp_Object *args = alloca_array (Lisp_Object, len);
3289
3290   mapcar1 (len, args, fn, seq);
3291
3292   return Flist (len, args);
3293 }
3294
3295 DEFUN ("mapvector", Fmapvector, 2, 2, 0, /*
3296 Apply FUNCTION to each element of SEQUENCE, making a vector of the results.
3297 The result is a vector of the same length as SEQUENCE.
3298 SEQUENCE may be a list, a vector or a string.
3299 */
3300        (fn, seq))
3301 {
3302   int len = XINT (Flength (seq));
3303   /* Ideally, this should call make_vector_internal, because we don't
3304      need initialization.  */
3305   Lisp_Object result = make_vector (len, Qnil);
3306   struct gcpro gcpro1;
3307
3308   GCPRO1 (result);
3309   mapcar1 (len, XVECTOR_DATA (result), fn, seq);
3310   UNGCPRO;
3311
3312   return result;
3313 }
3314
3315 DEFUN ("mapc", Fmapc, 2, 2, 0, /*
3316 Apply FUNCTION to each element of SEQUENCE.
3317 SEQUENCE may be a list, a vector, a bit vector, or a string.
3318 This function is like `mapcar' but does not accumulate the results,
3319 which is more efficient if you do not use the results.
3320 */
3321        (fn, seq))
3322 {
3323   mapcar1 (XINT (Flength (seq)), 0, fn, seq);
3324
3325   return seq;
3326 }
3327
3328 \f
3329 /* #### this function doesn't belong in this file! */
3330
3331 DEFUN ("load-average", Fload_average, 0, 1, 0, /*
3332 Return list of 1 minute, 5 minute and 15 minute load averages.
3333 Each of the three load averages is multiplied by 100,
3334 then converted to integer.
3335
3336 When USE-FLOATS is non-nil, floats will be used instead of integers.
3337 These floats are not multiplied by 100.
3338
3339 If the 5-minute or 15-minute load averages are not available, return a
3340 shortened list, containing only those averages which are available.
3341
3342 On some systems, this won't work due to permissions on /dev/kmem,
3343 in which case you can't use this.
3344 */
3345        (use_floats))
3346 {
3347   double load_ave[3];
3348   int loads = getloadavg (load_ave, countof (load_ave));
3349   Lisp_Object ret = Qnil;
3350
3351   if (loads == -2)
3352     error ("load-average not implemented for this operating system");
3353   else if (loads < 0)
3354     signal_simple_error ("Could not get load-average",
3355                          lisp_strerror (errno));
3356
3357   while (loads-- > 0)
3358     {
3359       Lisp_Object load = (NILP (use_floats) ?
3360                           make_int ((int) (100.0 * load_ave[loads]))
3361                           : make_float (load_ave[loads]));
3362       ret = Fcons (load, ret);
3363     }
3364   return ret;
3365 }
3366
3367 \f
3368 Lisp_Object Vfeatures;
3369
3370 DEFUN ("featurep", Ffeaturep, 1, 1, 0, /*
3371 Return non-nil if feature FEXP is present in this Emacs.
3372 Use this to conditionalize execution of lisp code based on the
3373  presence or absence of emacs or environment extensions.
3374 FEXP can be a symbol, a number, or a list.
3375 If it is a symbol, that symbol is looked up in the `features' variable,
3376  and non-nil will be returned if found.
3377 If it is a number, the function will return non-nil if this Emacs
3378  has an equal or greater version number than FEXP.
3379 If it is a list whose car is the symbol `and', it will return
3380  non-nil if all the features in its cdr are non-nil.
3381 If it is a list whose car is the symbol `or', it will return non-nil
3382  if any of the features in its cdr are non-nil.
3383 If it is a list whose car is the symbol `not', it will return
3384  non-nil if the feature is not present.
3385
3386 Examples:
3387
3388   (featurep 'xemacs)
3389     => ; Non-nil on XEmacs.
3390
3391   (featurep '(and xemacs gnus))
3392     => ; Non-nil on XEmacs with Gnus loaded.
3393
3394   (featurep '(or tty-frames (and emacs 19.30)))
3395     => ; Non-nil if this Emacs supports TTY frames.
3396
3397   (featurep '(or (and xemacs 19.15) (and emacs 19.34)))
3398     => ; Non-nil on XEmacs 19.15 and later, or FSF Emacs 19.34 and later.
3399
3400 NOTE: The advanced arguments of this function (anything other than a
3401 symbol) are not yet supported by FSF Emacs.  If you feel they are useful
3402 for supporting multiple Emacs variants, lobby Richard Stallman at
3403 <bug-gnu-emacs@prep.ai.mit.edu>.
3404 */
3405        (fexp))
3406 {
3407 #ifndef FEATUREP_SYNTAX
3408   CHECK_SYMBOL (fexp);
3409   return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt;
3410 #else  /* FEATUREP_SYNTAX */
3411   static double featurep_emacs_version;
3412
3413   /* Brute force translation from Erik Naggum's lisp function. */
3414   if (SYMBOLP (fexp))
3415     {
3416       /* Original definition */
3417       return NILP (Fmemq (fexp, Vfeatures)) ? Qnil : Qt;
3418     }
3419   else if (INTP (fexp) || FLOATP (fexp))
3420     {
3421       double d = extract_float (fexp);
3422
3423       if (featurep_emacs_version == 0.0)
3424         {
3425           featurep_emacs_version = XINT (Vemacs_major_version) +
3426             (XINT (Vemacs_minor_version) / 100.0);
3427         }
3428       return featurep_emacs_version >= d ? Qt : Qnil;
3429     }
3430   else if (CONSP (fexp))
3431     {
3432       Lisp_Object tem = XCAR (fexp);
3433       if (EQ (tem, Qnot))
3434         {
3435           Lisp_Object negate;
3436
3437           tem = XCDR (fexp);
3438           negate = Fcar (tem);
3439           if (!NILP (tem))
3440             return NILP (call1 (Qfeaturep, negate)) ? Qt : Qnil;
3441           else
3442             return Fsignal (Qinvalid_read_syntax, list1 (tem));
3443         }
3444       else if (EQ (tem, Qand))
3445         {
3446           tem = XCDR (fexp);
3447           /* Use Fcar/Fcdr for error-checking. */
3448           while (!NILP (tem) && !NILP (call1 (Qfeaturep, Fcar (tem))))
3449             {
3450               tem = Fcdr (tem);
3451             }
3452           return NILP (tem) ? Qt : Qnil;
3453         }
3454       else if (EQ (tem, Qor))
3455         {
3456           tem = XCDR (fexp);
3457           /* Use Fcar/Fcdr for error-checking. */
3458           while (!NILP (tem) && NILP (call1 (Qfeaturep, Fcar (tem))))
3459             {
3460               tem = Fcdr (tem);
3461             }
3462           return NILP (tem) ? Qnil : Qt;
3463         }
3464       else
3465         {
3466           return Fsignal (Qinvalid_read_syntax, list1 (XCDR (fexp)));
3467         }
3468     }
3469   else
3470     {
3471       return Fsignal (Qinvalid_read_syntax, list1 (fexp));
3472     }
3473 }
3474 #endif /* FEATUREP_SYNTAX */
3475
3476 DEFUN ("provide", Fprovide, 1, 1, 0, /*
3477 Announce that FEATURE is a feature of the current Emacs.
3478 This function updates the value of the variable `features'.
3479 */
3480        (feature))
3481 {
3482   Lisp_Object tem;
3483   CHECK_SYMBOL (feature);
3484   if (!NILP (Vautoload_queue))
3485     Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
3486   tem = Fmemq (feature, Vfeatures);
3487   if (NILP (tem))
3488     Vfeatures = Fcons (feature, Vfeatures);
3489   LOADHIST_ATTACH (Fcons (Qprovide, feature));
3490   return feature;
3491 }
3492
3493 DEFUN ("require", Frequire, 1, 2, 0, /*
3494 If feature FEATURE is not loaded, load it from FILENAME.
3495 If FEATURE is not a member of the list `features', then the feature
3496 is not loaded; so load the file FILENAME.
3497 If FILENAME is omitted, the printname of FEATURE is used as the file name.
3498 */
3499        (feature, file_name))
3500 {
3501   Lisp_Object tem;
3502   CHECK_SYMBOL (feature);
3503   tem = Fmemq (feature, Vfeatures);
3504   LOADHIST_ATTACH (Fcons (Qrequire, feature));
3505   if (!NILP (tem))
3506     return feature;
3507   else
3508     {
3509       int speccount = specpdl_depth ();
3510
3511       /* Value saved here is to be restored into Vautoload_queue */
3512       record_unwind_protect (un_autoload, Vautoload_queue);
3513       Vautoload_queue = Qt;
3514
3515       call4 (Qload, NILP (file_name) ? Fsymbol_name (feature) : file_name,
3516              Qnil, Qt, Qnil);
3517
3518       tem = Fmemq (feature, Vfeatures);
3519       if (NILP (tem))
3520         error ("Required feature %s was not provided",
3521                string_data (XSYMBOL (feature)->name));
3522
3523       /* Once loading finishes, don't undo it.  */
3524       Vautoload_queue = Qt;
3525       return unbind_to (speccount, feature);
3526     }
3527 }
3528 \f
3529 /* base64 encode/decode functions.
3530    Based on code from GNU recode. */
3531
3532 #define MIME_LINE_LENGTH 76
3533
3534 #define IS_ASCII(Character) \
3535   ((Character) < 128)
3536 #define IS_BASE64(Character) \
3537   (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
3538
3539 /* Table of characters coding the 64 values.  */
3540 static char base64_value_to_char[64] =
3541 {
3542   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',     /*  0- 9 */
3543   'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',     /* 10-19 */
3544   'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',     /* 20-29 */
3545   'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',     /* 30-39 */
3546   'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',     /* 40-49 */
3547   'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',     /* 50-59 */
3548   '8', '9', '+', '/'                                    /* 60-63 */
3549 };
3550
3551 /* Table of base64 values for first 128 characters.  */
3552 static short base64_char_to_value[128] =
3553 {
3554   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,      /*   0-  9 */
3555   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,      /*  10- 19 */
3556   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,      /*  20- 29 */
3557   -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,      /*  30- 39 */
3558   -1,  -1,  -1,  62,  -1,  -1,  -1,  63,  52,  53,      /*  40- 49 */
3559   54,  55,  56,  57,  58,  59,  60,  61,  -1,  -1,      /*  50- 59 */
3560   -1,  -1,  -1,  -1,  -1,  0,   1,   2,   3,   4,       /*  60- 69 */
3561   5,   6,   7,   8,   9,   10,  11,  12,  13,  14,      /*  70- 79 */
3562   15,  16,  17,  18,  19,  20,  21,  22,  23,  24,      /*  80- 89 */
3563   25,  -1,  -1,  -1,  -1,  -1,  -1,  26,  27,  28,      /*  90- 99 */
3564   29,  30,  31,  32,  33,  34,  35,  36,  37,  38,      /* 100-109 */
3565   39,  40,  41,  42,  43,  44,  45,  46,  47,  48,      /* 110-119 */
3566   49,  50,  51,  -1,  -1,  -1,  -1,  -1                 /* 120-127 */
3567 };
3568
3569 /* The following diagram shows the logical steps by which three octets
3570    get transformed into four base64 characters.
3571
3572                  .--------.  .--------.  .--------.
3573                  |aaaaaabb|  |bbbbcccc|  |ccdddddd|
3574                  `--------'  `--------'  `--------'
3575                     6   2      4   4       2   6
3576                .--------+--------+--------+--------.
3577                |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
3578                `--------+--------+--------+--------'
3579
3580                .--------+--------+--------+--------.
3581                |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
3582                `--------+--------+--------+--------'
3583
3584    The octets are divided into 6 bit chunks, which are then encoded into
3585    base64 characters.  */
3586
3587 #define ADVANCE_INPUT(c, stream)                                \
3588  (ec = Lstream_get_emchar (stream),                             \
3589   ec == -1 ? 0 :                                                \
3590   ((ec > 255) ?                                                 \
3591    (error ("Non-ascii character detected in base64 input"), 0)  \
3592    : (c = (Bufbyte)ec, 1)))
3593
3594 static Bytind
3595 base64_encode_1 (Lstream *istream, Bufbyte *to, int line_break)
3596 {
3597   EMACS_INT counter = 0;
3598   Bufbyte *e = to;
3599   Emchar ec;
3600   unsigned int value;
3601
3602   while (1)
3603     {
3604       Bufbyte c;
3605       if (!ADVANCE_INPUT (c, istream))
3606         break;
3607
3608       /* Wrap line every 76 characters.  */
3609       if (line_break)
3610         {
3611           if (counter < MIME_LINE_LENGTH / 4)
3612             counter++;
3613           else
3614             {
3615               *e++ = '\n';
3616               counter = 1;
3617             }
3618         }
3619
3620       /* Process first byte of a triplet.  */
3621       *e++ = base64_value_to_char[0x3f & c >> 2];
3622       value = (0x03 & c) << 4;
3623
3624       /* Process second byte of a triplet.  */
3625       if (!ADVANCE_INPUT (c, istream))
3626         {
3627           *e++ = base64_value_to_char[value];
3628           *e++ = '=';
3629           *e++ = '=';
3630           break;
3631         }
3632
3633       *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
3634       value = (0x0f & c) << 2;
3635
3636       /* Process third byte of a triplet.  */
3637       if (!ADVANCE_INPUT (c, istream))
3638         {
3639           *e++ = base64_value_to_char[value];
3640           *e++ = '=';
3641           break;
3642         }
3643
3644       *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
3645       *e++ = base64_value_to_char[0x3f & c];
3646     }
3647
3648   /* Complete last partial line.  */
3649   if (line_break)
3650     if (counter > 0)
3651       *e++ = '\n';
3652
3653   return e - to;
3654 }
3655 #undef ADVANCE_INPUT
3656
3657 #define ADVANCE_INPUT(c, stream)                \
3658  (ec = Lstream_get_emchar (stream),             \
3659   ec == -1 ? 0 : (c = (Bufbyte)ec, 1))
3660
3661 #define INPUT_EOF_P(stream)                             \
3662  (ADVANCE_INPUT (c2, stream)                            \
3663   ? (Lstream_unget_emchar (stream, (Emchar)c2), 0)      \
3664   : 1)
3665
3666 #define STORE_BYTE(pos, val) do {                                       \
3667   pos += set_charptr_emchar (pos, (Emchar)((unsigned char)(val)));      \
3668   ++*ccptr;                                                             \
3669 } while (0)
3670
3671 static Bytind
3672 base64_decode_1 (Lstream *istream, Bufbyte *to, Charcount *ccptr)
3673 {
3674   EMACS_INT counter = 0;
3675   Emchar ec;
3676   Bufbyte *e = to;
3677   unsigned long value;
3678
3679   *ccptr = 0;
3680   while (1)
3681     {
3682       Bufbyte c, c2;
3683
3684       if (!ADVANCE_INPUT (c, istream))
3685         break;
3686
3687       /* Accept wrapping lines, reversibly if at each 76 characters.  */
3688       if (c == '\n')
3689         {
3690           if (!ADVANCE_INPUT (c, istream))
3691             break;
3692           if (INPUT_EOF_P (istream))
3693             break;
3694           /* FSF Emacs has this check, apparently inherited from
3695              recode.  However, I see no reason to be this picky about
3696              line length -- why reject base64 with say 72-byte lines?
3697              (yes, there are programs that generate them.)  */
3698           /*if (counter != MIME_LINE_LENGTH / 4) return -1;*/
3699           counter = 1;
3700         }
3701       else
3702         counter++;
3703
3704       /* Process first byte of a quadruplet.  */
3705       if (!IS_BASE64 (c))
3706         return -1;
3707       value = base64_char_to_value[c] << 18;
3708
3709       /* Process second byte of a quadruplet.  */
3710       if (!ADVANCE_INPUT (c, istream))
3711         return -1;
3712
3713       if (!IS_BASE64 (c))
3714         return -1;
3715       value |= base64_char_to_value[c] << 12;
3716
3717       STORE_BYTE (e, value >> 16);
3718
3719       /* Process third byte of a quadruplet.  */
3720       if (!ADVANCE_INPUT (c, istream))
3721         return -1;
3722
3723       if (c == '=')
3724         {
3725           if (!ADVANCE_INPUT (c, istream))
3726             return -1;
3727           if (c != '=')
3728             return -1;
3729           continue;
3730         }
3731
3732       if (!IS_BASE64 (c))
3733         return -1;
3734       value |= base64_char_to_value[c] << 6;
3735
3736       STORE_BYTE (e, 0xff & value >> 8);
3737
3738       /* Process fourth byte of a quadruplet.  */
3739       if (!ADVANCE_INPUT (c, istream))
3740         return -1;
3741
3742       if (c == '=')
3743         continue;
3744
3745       if (!IS_BASE64 (c))
3746         return -1;
3747       value |= base64_char_to_value[c];
3748
3749       STORE_BYTE (e, 0xff & value);
3750     }
3751
3752   return e - to;
3753 }
3754 #undef ADVANCE_INPUT
3755 #undef INPUT_EOF_P
3756
3757 static Lisp_Object
3758 free_malloced_ptr (Lisp_Object unwind_obj)
3759 {
3760   void *ptr = (void *)get_opaque_ptr (unwind_obj);
3761   xfree (ptr);
3762   free_opaque_ptr (unwind_obj);
3763   return Qnil;
3764 }
3765
3766 /* Don't use alloca for regions larger than this, lest we overflow
3767    the stack.  */
3768 #define MAX_ALLOCA 65536
3769
3770 /* We need to setup proper unwinding, because there is a number of
3771    ways these functions can blow up, and we don't want to have memory
3772    leaks in those cases.  */
3773 #define XMALLOC_OR_ALLOCA(ptr, len, type) do {                  \
3774   if ((len) > MAX_ALLOCA)                                       \
3775     {                                                           \
3776       ptr = (type *)xmalloc ((len) * sizeof (type));            \
3777       speccount = specpdl_depth ();                             \
3778       record_unwind_protect (free_malloced_ptr,                 \
3779                              make_opaque_ptr ((void *)ptr));    \
3780     }                                                           \
3781   else                                                          \
3782     ptr = alloca_array (type, len);                             \
3783 } while (0)
3784
3785 #define XMALLOC_UNBIND(ptr, len) do {           \
3786   if ((len) > MAX_ALLOCA)                       \
3787     unbind_to (speccount, Qnil);                \
3788 } while (0)
3789
3790 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /*
3791 Base64-encode the region between BEG and END.
3792 Return the length of the encoded text.
3793 Optional third argument NO-LINE-BREAK means do not break long lines
3794 into shorter lines.
3795 */
3796        (beg, end, no_line_break))
3797 {
3798   Bufbyte *encoded;
3799   Bytind encoded_length;
3800   Charcount allength, length;
3801   struct buffer *buf = current_buffer;
3802   Bufpos begv, zv, old_pt = BUF_PT (buf);
3803   Lisp_Object input;
3804   int speccount;
3805
3806   get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
3807
3808   /* We need to allocate enough room for encoding the text.
3809      We need 33 1/3% more space, plus a newline every 76
3810      characters, and then we round up. */
3811   length = zv - begv;
3812   allength = length + length/3 + 1;
3813   allength += allength / MIME_LINE_LENGTH + 1 + 6;
3814
3815   input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
3816   /* We needn't multiply allength with MAX_EMCHAR_LEN because all the
3817      base64 characters will be single-byte.  */
3818   XMALLOC_OR_ALLOCA (encoded, allength, Bufbyte);
3819   encoded_length = base64_encode_1 (XLSTREAM (input), encoded,
3820                                     NILP (no_line_break));
3821   if (encoded_length > allength)
3822     abort ();
3823   Lstream_delete (XLSTREAM (input));
3824
3825   /* Now we have encoded the region, so we insert the new contents
3826      and delete the old.  (Insert first in order to preserve markers.)  */
3827   buffer_insert_raw_string_1 (buf, begv, encoded, encoded_length, 0);
3828   XMALLOC_UNBIND (encoded, allength);
3829   buffer_delete_range (buf, begv + encoded_length, zv + encoded_length, 0);
3830
3831   /* Simulate FSF Emacs: if point was in the region, place it at the
3832      beginning.  */
3833   if (old_pt >= begv && old_pt < zv)
3834     BUF_SET_PT (buf, begv);
3835
3836   /* We return the length of the encoded text. */
3837   return make_int (encoded_length);
3838 }
3839
3840 DEFUN ("base64-encode-string", Fbase64_encode_string, 1, 1, 0, /*
3841 Base64 encode STRING and return the result.
3842 */
3843        (string))
3844 {
3845   Charcount allength, length;
3846   Bytind encoded_length;
3847   Bufbyte *encoded;
3848   Lisp_Object input, result;
3849   int speccount;
3850
3851   CHECK_STRING (string);
3852
3853   length = XSTRING_CHAR_LENGTH (string);
3854   allength = length + length/3 + 1 + 6;
3855
3856   input = make_lisp_string_input_stream (string, 0, -1);
3857   XMALLOC_OR_ALLOCA (encoded, allength, Bufbyte);
3858   encoded_length = base64_encode_1 (XLSTREAM (input), encoded, 0);
3859   if (encoded_length > allength)
3860     abort ();
3861   Lstream_delete (XLSTREAM (input));
3862   result = make_string (encoded, encoded_length);
3863   XMALLOC_UNBIND (encoded, allength);
3864   return result;
3865 }
3866
3867 DEFUN ("base64-decode-region", Fbase64_decode_region, 2, 2, "r", /*
3868 Base64-decode the region between BEG and END.
3869 Return the length of the decoded text.
3870 If the region can't be decoded, return nil and don't modify the buffer.
3871 */
3872        (beg, end))
3873 {
3874   struct buffer *buf = current_buffer;
3875   Bufpos begv, zv, old_pt = BUF_PT (buf);
3876   Bufbyte *decoded;
3877   Bytind decoded_length;
3878   Charcount length, cc_decoded_length;
3879   Lisp_Object input;
3880   int speccount;
3881
3882   get_buffer_range_char (buf, beg, end, &begv, &zv, 0);
3883   length = zv - begv;
3884
3885   input = make_lisp_buffer_input_stream (buf, begv, zv, 0);
3886   /* We need to allocate enough room for decoding the text. */
3887   XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte);
3888   decoded_length = base64_decode_1 (XLSTREAM (input), decoded, &cc_decoded_length);
3889   if (decoded_length > length * MAX_EMCHAR_LEN)
3890     abort ();
3891   Lstream_delete (XLSTREAM (input));
3892
3893   if (decoded_length < 0)
3894     {
3895       /* The decoding wasn't possible. */
3896       XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
3897       return Qnil;
3898     }
3899
3900   /* Now we have decoded the region, so we insert the new contents
3901      and delete the old.  (Insert first in order to preserve markers.)  */
3902   BUF_SET_PT (buf, begv);
3903   buffer_insert_raw_string_1 (buf, begv, decoded, decoded_length, 0);
3904   XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
3905   buffer_delete_range (buf, begv + cc_decoded_length,
3906                        zv + cc_decoded_length, 0);
3907
3908   /* Simulate FSF Emacs: if point was in the region, place it at the
3909      beginning.  */
3910   if (old_pt >= begv && old_pt < zv)
3911     BUF_SET_PT (buf, begv);
3912
3913   return make_int (cc_decoded_length);
3914 }
3915
3916 DEFUN ("base64-decode-string", Fbase64_decode_string, 1, 1, 0, /*
3917 Base64-decode STRING and return the result.
3918 */
3919        (string))
3920 {
3921   Bufbyte *decoded;
3922   Bytind decoded_length;
3923   Charcount length, cc_decoded_length;
3924   Lisp_Object input, result;
3925   int speccount;
3926
3927   CHECK_STRING (string);
3928
3929   length = XSTRING_CHAR_LENGTH (string);
3930   /* We need to allocate enough room for decoding the text. */
3931   XMALLOC_OR_ALLOCA (decoded, length * MAX_EMCHAR_LEN, Bufbyte);
3932
3933   input = make_lisp_string_input_stream (string, 0, -1);
3934   decoded_length = base64_decode_1 (XLSTREAM (input), decoded,
3935                                     &cc_decoded_length);
3936   if (decoded_length > length * MAX_EMCHAR_LEN)
3937     abort ();
3938   Lstream_delete (XLSTREAM (input));
3939
3940   if (decoded_length < 0)
3941     {
3942       return Qnil;
3943       XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
3944     }
3945
3946   result = make_string (decoded, decoded_length);
3947   XMALLOC_UNBIND (decoded, length * MAX_EMCHAR_LEN);
3948   return result;
3949 }
3950 \f
3951 Lisp_Object Qyes_or_no_p;
3952
3953 void
3954 syms_of_fns (void)
3955 {
3956   defsymbol (&Qstring_lessp, "string-lessp");
3957   defsymbol (&Qidentity, "identity");
3958   defsymbol (&Qyes_or_no_p, "yes-or-no-p");
3959
3960   DEFSUBR (Fidentity);
3961   DEFSUBR (Frandom);
3962   DEFSUBR (Flength);
3963   DEFSUBR (Fsafe_length);
3964   DEFSUBR (Fstring_equal);
3965   DEFSUBR (Fstring_lessp);
3966   DEFSUBR (Fstring_modified_tick);
3967   DEFSUBR (Fappend);
3968   DEFSUBR (Fconcat);
3969   DEFSUBR (Fvconcat);
3970   DEFSUBR (Fbvconcat);
3971   DEFSUBR (Fcopy_sequence);
3972   DEFSUBR (Fcopy_alist);
3973   DEFSUBR (Fcopy_tree);
3974   DEFSUBR (Fsubstring);
3975   DEFSUBR (Fsubseq);
3976   DEFSUBR (Fnthcdr);
3977   DEFSUBR (Fnth);
3978   DEFSUBR (Felt);
3979   DEFSUBR (Fmember);
3980   DEFSUBR (Fold_member);
3981   DEFSUBR (Fmemq);
3982   DEFSUBR (Fold_memq);
3983   DEFSUBR (Fassoc);
3984   DEFSUBR (Fold_assoc);
3985   DEFSUBR (Fassq);
3986   DEFSUBR (Fold_assq);
3987   DEFSUBR (Frassoc);
3988   DEFSUBR (Fold_rassoc);
3989   DEFSUBR (Frassq);
3990   DEFSUBR (Fold_rassq);
3991   DEFSUBR (Fdelete);
3992   DEFSUBR (Fold_delete);
3993   DEFSUBR (Fdelq);
3994   DEFSUBR (Fold_delq);
3995   DEFSUBR (Fremassoc);
3996   DEFSUBR (Fremassq);
3997   DEFSUBR (Fremrassoc);
3998   DEFSUBR (Fremrassq);
3999   DEFSUBR (Fnreverse);
4000   DEFSUBR (Freverse);
4001   DEFSUBR (Fsort);
4002   DEFSUBR (Fplists_eq);
4003   DEFSUBR (Fplists_equal);
4004   DEFSUBR (Flax_plists_eq);
4005   DEFSUBR (Flax_plists_equal);
4006   DEFSUBR (Fplist_get);
4007   DEFSUBR (Fplist_put);
4008   DEFSUBR (Fplist_remprop);
4009   DEFSUBR (Fplist_member);
4010   DEFSUBR (Fcheck_valid_plist);
4011   DEFSUBR (Fvalid_plist_p);
4012   DEFSUBR (Fcanonicalize_plist);
4013   DEFSUBR (Flax_plist_get);
4014   DEFSUBR (Flax_plist_put);
4015   DEFSUBR (Flax_plist_remprop);
4016   DEFSUBR (Flax_plist_member);
4017   DEFSUBR (Fcanonicalize_lax_plist);
4018   DEFSUBR (Fdestructive_alist_to_plist);
4019   DEFSUBR (Fget);
4020   DEFSUBR (Fput);
4021   DEFSUBR (Fremprop);
4022   DEFSUBR (Fobject_plist);
4023   DEFSUBR (Fequal);
4024   DEFSUBR (Fold_equal);
4025   DEFSUBR (Ffillarray);
4026   DEFSUBR (Fnconc);
4027   DEFSUBR (Fmapcar);
4028   DEFSUBR (Fmapvector);
4029   DEFSUBR (Fmapc);
4030   DEFSUBR (Fmapconcat);
4031   DEFSUBR (Fload_average);
4032   DEFSUBR (Ffeaturep);
4033   DEFSUBR (Frequire);
4034   DEFSUBR (Fprovide);
4035   DEFSUBR (Fbase64_encode_region);
4036   DEFSUBR (Fbase64_encode_string);
4037   DEFSUBR (Fbase64_decode_region);
4038   DEFSUBR (Fbase64_decode_string);
4039 }
4040
4041 void
4042 init_provide_once (void)
4043 {
4044   DEFVAR_LISP ("features", &Vfeatures /*
4045 A list of symbols which are the features of the executing emacs.
4046 Used by `featurep' and `require', and altered by `provide'.
4047 */ );
4048   Vfeatures = Qnil;
4049 }