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