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