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