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