Use defcustom for user variables.
[emacs.git] / src / fns.c
blob2631210a6429a662310afbc5fdcf673b709040de
1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include <config.h>
24 /* Note on some machines this defines `vector' as a typedef,
25 so make sure we don't use that name in this file. */
26 #undef vector
27 #define vector *****
29 #include "lisp.h"
30 #include "commands.h"
31 #include "charset.h"
33 #include "buffer.h"
34 #include "keyboard.h"
35 #include "intervals.h"
36 #include "frame.h"
37 #include "window.h"
39 #ifndef NULL
40 #define NULL (void *)0
41 #endif
43 extern Lisp_Object Flookup_key ();
45 extern int minibuffer_auto_raise;
46 extern Lisp_Object minibuf_window;
48 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
49 Lisp_Object Qyes_or_no_p_history;
50 Lisp_Object Qcursor_in_echo_area;
52 static int internal_equal ();
54 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
55 "Return the argument unchanged.")
56 (arg)
57 Lisp_Object arg;
59 return arg;
62 extern long get_random ();
63 extern void seed_random ();
64 extern long time ();
66 DEFUN ("random", Frandom, Srandom, 0, 1, 0,
67 "Return a pseudo-random number.\n\
68 All integers representable in Lisp are equally likely.\n\
69 On most systems, this is 28 bits' worth.\n\
70 With positive integer argument N, return random number in interval [0,N).\n\
71 With argument t, set the random number seed from the current time and pid.")
72 (n)
73 Lisp_Object n;
75 EMACS_INT val;
76 Lisp_Object lispy_val;
77 unsigned long denominator;
79 if (EQ (n, Qt))
80 seed_random (getpid () + time (NULL));
81 if (NATNUMP (n) && XFASTINT (n) != 0)
83 /* Try to take our random number from the higher bits of VAL,
84 not the lower, since (says Gentzel) the low bits of `random'
85 are less random than the higher ones. We do this by using the
86 quotient rather than the remainder. At the high end of the RNG
87 it's possible to get a quotient larger than n; discarding
88 these values eliminates the bias that would otherwise appear
89 when using a large n. */
90 denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n);
92 val = get_random () / denominator;
93 while (val >= XFASTINT (n));
95 else
96 val = get_random ();
97 XSETINT (lispy_val, val);
98 return lispy_val;
101 /* Random data-structure functions */
103 DEFUN ("length", Flength, Slength, 1, 1, 0,
104 "Return the length of vector, list or string SEQUENCE.\n\
105 A byte-code function object is also allowed.")
106 (sequence)
107 register Lisp_Object sequence;
109 register Lisp_Object tail, val;
110 register int i;
112 retry:
113 if (STRINGP (sequence))
114 XSETFASTINT (val, XSTRING (sequence)->size);
115 else if (VECTORP (sequence))
116 XSETFASTINT (val, XVECTOR (sequence)->size);
117 else if (CHAR_TABLE_P (sequence))
118 XSETFASTINT (val, CHAR_TABLE_ORDINARY_SLOTS);
119 else if (BOOL_VECTOR_P (sequence))
120 XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
121 else if (COMPILEDP (sequence))
122 XSETFASTINT (val, XVECTOR (sequence)->size & PSEUDOVECTOR_SIZE_MASK);
123 else if (CONSP (sequence))
125 for (i = 0, tail = sequence; !NILP (tail); i++)
127 QUIT;
128 tail = Fcdr (tail);
131 XSETFASTINT (val, i);
133 else if (NILP (sequence))
134 XSETFASTINT (val, 0);
135 else
137 sequence = wrong_type_argument (Qsequencep, sequence);
138 goto retry;
140 return val;
143 /* This does not check for quits. That is safe
144 since it must terminate. */
146 DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
147 "Return the length of a list, but avoid error or infinite loop.\n\
148 This function never gets an error. If LIST is not really a list,\n\
149 it returns 0. If LIST is circular, it returns a finite value\n\
150 which is at least the number of distinct elements.")
151 (list)
152 Lisp_Object list;
154 Lisp_Object tail, halftail, length;
155 int len = 0;
157 /* halftail is used to detect circular lists. */
158 halftail = list;
159 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
161 if (EQ (tail, halftail) && len != 0)
162 break;
163 len++;
164 if ((len & 1) == 0)
165 halftail = XCONS (halftail)->cdr;
168 XSETINT (length, len);
169 return length;
172 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
173 "T if two strings have identical contents.\n\
174 Case is significant, but text properties are ignored.\n\
175 Symbols are also allowed; their print names are used instead.")
176 (s1, s2)
177 register Lisp_Object s1, s2;
179 if (SYMBOLP (s1))
180 XSETSTRING (s1, XSYMBOL (s1)->name);
181 if (SYMBOLP (s2))
182 XSETSTRING (s2, XSYMBOL (s2)->name);
183 CHECK_STRING (s1, 0);
184 CHECK_STRING (s2, 1);
186 if (XSTRING (s1)->size != XSTRING (s2)->size ||
187 bcmp (XSTRING (s1)->data, XSTRING (s2)->data, XSTRING (s1)->size))
188 return Qnil;
189 return Qt;
192 DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
193 "T if first arg string is less than second in lexicographic order.\n\
194 Case is significant.\n\
195 Symbols are also allowed; their print names are used instead.")
196 (s1, s2)
197 register Lisp_Object s1, s2;
199 register int i;
200 register unsigned char *p1, *p2;
201 register int end;
203 if (SYMBOLP (s1))
204 XSETSTRING (s1, XSYMBOL (s1)->name);
205 if (SYMBOLP (s2))
206 XSETSTRING (s2, XSYMBOL (s2)->name);
207 CHECK_STRING (s1, 0);
208 CHECK_STRING (s2, 1);
210 p1 = XSTRING (s1)->data;
211 p2 = XSTRING (s2)->data;
212 end = XSTRING (s1)->size;
213 if (end > XSTRING (s2)->size)
214 end = XSTRING (s2)->size;
216 for (i = 0; i < end; i++)
218 if (p1[i] != p2[i])
219 return p1[i] < p2[i] ? Qt : Qnil;
221 return i < XSTRING (s2)->size ? Qt : Qnil;
224 static Lisp_Object concat ();
226 /* ARGSUSED */
227 Lisp_Object
228 concat2 (s1, s2)
229 Lisp_Object s1, s2;
231 #ifdef NO_ARG_ARRAY
232 Lisp_Object args[2];
233 args[0] = s1;
234 args[1] = s2;
235 return concat (2, args, Lisp_String, 0);
236 #else
237 return concat (2, &s1, Lisp_String, 0);
238 #endif /* NO_ARG_ARRAY */
241 /* ARGSUSED */
242 Lisp_Object
243 concat3 (s1, s2, s3)
244 Lisp_Object s1, s2, s3;
246 #ifdef NO_ARG_ARRAY
247 Lisp_Object args[3];
248 args[0] = s1;
249 args[1] = s2;
250 args[2] = s3;
251 return concat (3, args, Lisp_String, 0);
252 #else
253 return concat (3, &s1, Lisp_String, 0);
254 #endif /* NO_ARG_ARRAY */
257 DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
258 "Concatenate all the arguments and make the result a list.\n\
259 The result is a list whose elements are the elements of all the arguments.\n\
260 Each argument may be a list, vector or string.\n\
261 The last argument is not copied, just used as the tail of the new list.")
262 (nargs, args)
263 int nargs;
264 Lisp_Object *args;
266 return concat (nargs, args, Lisp_Cons, 1);
269 DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
270 "Concatenate all the arguments and make the result a string.\n\
271 The result is a string whose elements are the elements of all the arguments.\n\
272 Each argument may be a string or a list or vector of characters (integers).\n\
274 Do not use individual integers as arguments!\n\
275 The behavior of `concat' in that case will be changed later!\n\
276 If your program passes an integer as an argument to `concat',\n\
277 you should change it right away not to do so.")
278 (nargs, args)
279 int nargs;
280 Lisp_Object *args;
282 return concat (nargs, args, Lisp_String, 0);
285 DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
286 "Concatenate all the arguments and make the result a vector.\n\
287 The result is a vector whose elements are the elements of all the arguments.\n\
288 Each argument may be a list, vector or string.")
289 (nargs, args)
290 int nargs;
291 Lisp_Object *args;
293 return concat (nargs, args, Lisp_Vectorlike, 0);
296 /* Retrun a copy of a sub char table ARG. The elements except for a
297 nested sub char table are not copied. */
298 static Lisp_Object
299 copy_sub_char_table (arg)
301 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
302 int i;
304 /* Copy all the contents. */
305 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
306 SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
307 /* Recursively copy any sub char-tables in the ordinary slots. */
308 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
309 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
310 XCHAR_TABLE (copy)->contents[i]
311 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
313 return copy;
317 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
318 "Return a copy of a list, vector or string.\n\
319 The elements of a list or vector are not copied; they are shared\n\
320 with the original.")
321 (arg)
322 Lisp_Object arg;
324 if (NILP (arg)) return arg;
326 if (CHAR_TABLE_P (arg))
328 int i;
329 Lisp_Object copy;
331 copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
332 /* Copy all the slots, including the extra ones. */
333 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
334 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
335 * sizeof (Lisp_Object)));
337 /* Recursively copy any sub char tables in the ordinary slots
338 for multibyte characters. */
339 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
340 i < CHAR_TABLE_ORDINARY_SLOTS; i++)
341 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
342 XCHAR_TABLE (copy)->contents[i]
343 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
345 return copy;
348 if (BOOL_VECTOR_P (arg))
350 Lisp_Object val;
351 int size_in_chars
352 = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
354 val = Fmake_bool_vector (Flength (arg), Qnil);
355 bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
356 size_in_chars);
357 return val;
360 if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
361 arg = wrong_type_argument (Qsequencep, arg);
362 return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
365 static Lisp_Object
366 concat (nargs, args, target_type, last_special)
367 int nargs;
368 Lisp_Object *args;
369 enum Lisp_Type target_type;
370 int last_special;
372 Lisp_Object val;
373 Lisp_Object len;
374 register Lisp_Object tail;
375 register Lisp_Object this;
376 int toindex;
377 register int leni;
378 register int argnum;
379 Lisp_Object last_tail;
380 Lisp_Object prev;
382 /* In append, the last arg isn't treated like the others */
383 if (last_special && nargs > 0)
385 nargs--;
386 last_tail = args[nargs];
388 else
389 last_tail = Qnil;
391 for (argnum = 0; argnum < nargs; argnum++)
393 this = args[argnum];
394 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
395 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
397 if (INTEGERP (this))
398 args[argnum] = Fnumber_to_string (this);
399 else
400 args[argnum] = wrong_type_argument (Qsequencep, this);
404 for (argnum = 0, leni = 0; argnum < nargs; argnum++)
406 this = args[argnum];
407 len = Flength (this);
408 leni += XFASTINT (len);
411 XSETFASTINT (len, leni);
413 if (target_type == Lisp_Cons)
414 val = Fmake_list (len, Qnil);
415 else if (target_type == Lisp_Vectorlike)
416 val = Fmake_vector (len, Qnil);
417 else
418 val = Fmake_string (len, len);
420 /* In append, if all but last arg are nil, return last arg */
421 if (target_type == Lisp_Cons && EQ (val, Qnil))
422 return last_tail;
424 if (CONSP (val))
425 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
426 else
427 toindex = 0;
429 prev = Qnil;
431 for (argnum = 0; argnum < nargs; argnum++)
433 Lisp_Object thislen;
434 int thisleni;
435 register unsigned int thisindex = 0;
437 this = args[argnum];
438 if (!CONSP (this))
439 thislen = Flength (this), thisleni = XINT (thislen);
441 if (STRINGP (this) && STRINGP (val)
442 && ! NULL_INTERVAL_P (XSTRING (this)->intervals))
444 copy_text_properties (make_number (0), thislen, this,
445 make_number (toindex), val, Qnil);
448 while (1)
450 register Lisp_Object elt;
452 /* Fetch next element of `this' arg into `elt', or break if
453 `this' is exhausted. */
454 if (NILP (this)) break;
455 if (CONSP (this))
456 elt = Fcar (this), this = Fcdr (this);
457 else
459 if (thisindex >= thisleni) break;
460 if (STRINGP (this))
461 XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
462 else if (BOOL_VECTOR_P (this))
464 int size_in_chars
465 = ((XBOOL_VECTOR (this)->size + BITS_PER_CHAR - 1)
466 / BITS_PER_CHAR);
467 int byte;
468 byte = XBOOL_VECTOR (val)->data[thisindex / BITS_PER_CHAR];
469 if (byte & (1 << (thisindex % BITS_PER_CHAR)))
470 elt = Qt;
471 else
472 elt = Qnil;
474 else
475 elt = XVECTOR (this)->contents[thisindex++];
478 /* Store into result */
479 if (toindex < 0)
481 XCONS (tail)->car = elt;
482 prev = tail;
483 tail = XCONS (tail)->cdr;
485 else if (VECTORP (val))
486 XVECTOR (val)->contents[toindex++] = elt;
487 else
489 while (!INTEGERP (elt))
490 elt = wrong_type_argument (Qintegerp, elt);
492 #ifdef MASSC_REGISTER_BUG
493 /* Even removing all "register"s doesn't disable this bug!
494 Nothing simpler than this seems to work. */
495 unsigned char *p = & XSTRING (val)->data[toindex++];
496 *p = XINT (elt);
497 #else
498 XSTRING (val)->data[toindex++] = XINT (elt);
499 #endif
504 if (!NILP (prev))
505 XCONS (prev)->cdr = last_tail;
507 return val;
510 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
511 "Return a copy of ALIST.\n\
512 This is an alist which represents the same mapping from objects to objects,\n\
513 but does not share the alist structure with ALIST.\n\
514 The objects mapped (cars and cdrs of elements of the alist)\n\
515 are shared, however.\n\
516 Elements of ALIST that are not conses are also shared.")
517 (alist)
518 Lisp_Object alist;
520 register Lisp_Object tem;
522 CHECK_LIST (alist, 0);
523 if (NILP (alist))
524 return alist;
525 alist = concat (1, &alist, Lisp_Cons, 0);
526 for (tem = alist; CONSP (tem); tem = XCONS (tem)->cdr)
528 register Lisp_Object car;
529 car = XCONS (tem)->car;
531 if (CONSP (car))
532 XCONS (tem)->car = Fcons (XCONS (car)->car, XCONS (car)->cdr);
534 return alist;
537 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
538 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
539 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
540 If FROM or TO is negative, it counts from the end.\n\
542 This function allows vectors as well as strings.")
543 (string, from, to)
544 Lisp_Object string;
545 register Lisp_Object from, to;
547 Lisp_Object res;
548 int size;
550 if (! (STRINGP (string) || VECTORP (string)))
551 wrong_type_argument (Qarrayp, string);
553 CHECK_NUMBER (from, 1);
555 if (STRINGP (string))
556 size = XSTRING (string)->size;
557 else
558 size = XVECTOR (string)->size;
560 if (NILP (to))
561 to = size;
562 else
563 CHECK_NUMBER (to, 2);
565 if (XINT (from) < 0)
566 XSETINT (from, XINT (from) + size);
567 if (XINT (to) < 0)
568 XSETINT (to, XINT (to) + size);
569 if (!(0 <= XINT (from) && XINT (from) <= XINT (to)
570 && XINT (to) <= size))
571 args_out_of_range_3 (string, from, to);
573 if (STRINGP (string))
575 res = make_string (XSTRING (string)->data + XINT (from),
576 XINT (to) - XINT (from));
577 copy_text_properties (from, to, string, make_number (0), res, Qnil);
579 else
580 res = Fvector (XINT (to) - XINT (from),
581 XVECTOR (string)->contents + XINT (from));
583 return res;
586 DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
587 "Take cdr N times on LIST, returns the result.")
588 (n, list)
589 Lisp_Object n;
590 register Lisp_Object list;
592 register int i, num;
593 CHECK_NUMBER (n, 0);
594 num = XINT (n);
595 for (i = 0; i < num && !NILP (list); i++)
597 QUIT;
598 list = Fcdr (list);
600 return list;
603 DEFUN ("nth", Fnth, Snth, 2, 2, 0,
604 "Return the Nth element of LIST.\n\
605 N counts from zero. If LIST is not that long, nil is returned.")
606 (n, list)
607 Lisp_Object n, list;
609 return Fcar (Fnthcdr (n, list));
612 DEFUN ("elt", Felt, Selt, 2, 2, 0,
613 "Return element of SEQUENCE at index N.")
614 (sequence, n)
615 register Lisp_Object sequence, n;
617 CHECK_NUMBER (n, 0);
618 while (1)
620 if (CONSP (sequence) || NILP (sequence))
621 return Fcar (Fnthcdr (n, sequence));
622 else if (STRINGP (sequence) || VECTORP (sequence)
623 || BOOL_VECTOR_P (sequence) || CHAR_TABLE_P (sequence))
624 return Faref (sequence, n);
625 else
626 sequence = wrong_type_argument (Qsequencep, sequence);
630 DEFUN ("member", Fmember, Smember, 2, 2, 0,
631 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
632 The value is actually the tail of LIST whose car is ELT.")
633 (elt, list)
634 register Lisp_Object elt;
635 Lisp_Object list;
637 register Lisp_Object tail;
638 for (tail = list; !NILP (tail); tail = Fcdr (tail))
640 register Lisp_Object tem;
641 tem = Fcar (tail);
642 if (! NILP (Fequal (elt, tem)))
643 return tail;
644 QUIT;
646 return Qnil;
649 DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
650 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
651 The value is actually the tail of LIST whose car is ELT.")
652 (elt, list)
653 register Lisp_Object elt;
654 Lisp_Object list;
656 register Lisp_Object tail;
657 for (tail = list; !NILP (tail); tail = Fcdr (tail))
659 register Lisp_Object tem;
660 tem = Fcar (tail);
661 if (EQ (elt, tem)) return tail;
662 QUIT;
664 return Qnil;
667 DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
668 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
669 The value is actually the element of LIST whose car is KEY.\n\
670 Elements of LIST that are not conses are ignored.")
671 (key, list)
672 register Lisp_Object key;
673 Lisp_Object list;
675 register Lisp_Object tail;
676 for (tail = list; !NILP (tail); tail = Fcdr (tail))
678 register Lisp_Object elt, tem;
679 elt = Fcar (tail);
680 if (!CONSP (elt)) continue;
681 tem = Fcar (elt);
682 if (EQ (key, tem)) return elt;
683 QUIT;
685 return Qnil;
688 /* Like Fassq but never report an error and do not allow quits.
689 Use only on lists known never to be circular. */
691 Lisp_Object
692 assq_no_quit (key, list)
693 register Lisp_Object key;
694 Lisp_Object list;
696 register Lisp_Object tail;
697 for (tail = list; CONSP (tail); tail = Fcdr (tail))
699 register Lisp_Object elt, tem;
700 elt = Fcar (tail);
701 if (!CONSP (elt)) continue;
702 tem = Fcar (elt);
703 if (EQ (key, tem)) return elt;
705 return Qnil;
708 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
709 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
710 The value is actually the element of LIST whose car equals KEY.")
711 (key, list)
712 register Lisp_Object key;
713 Lisp_Object list;
715 register Lisp_Object tail;
716 for (tail = list; !NILP (tail); tail = Fcdr (tail))
718 register Lisp_Object elt, tem;
719 elt = Fcar (tail);
720 if (!CONSP (elt)) continue;
721 tem = Fequal (Fcar (elt), key);
722 if (!NILP (tem)) return elt;
723 QUIT;
725 return Qnil;
728 DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
729 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
730 The value is actually the element of LIST whose cdr is ELT.")
731 (key, list)
732 register Lisp_Object key;
733 Lisp_Object list;
735 register Lisp_Object tail;
736 for (tail = list; !NILP (tail); tail = Fcdr (tail))
738 register Lisp_Object elt, tem;
739 elt = Fcar (tail);
740 if (!CONSP (elt)) continue;
741 tem = Fcdr (elt);
742 if (EQ (key, tem)) return elt;
743 QUIT;
745 return Qnil;
748 DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
749 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
750 The value is actually the element of LIST whose cdr equals KEY.")
751 (key, list)
752 register Lisp_Object key;
753 Lisp_Object list;
755 register Lisp_Object tail;
756 for (tail = list; !NILP (tail); tail = Fcdr (tail))
758 register Lisp_Object elt, tem;
759 elt = Fcar (tail);
760 if (!CONSP (elt)) continue;
761 tem = Fequal (Fcdr (elt), key);
762 if (!NILP (tem)) return elt;
763 QUIT;
765 return Qnil;
768 DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
769 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
770 The modified LIST is returned. Comparison is done with `eq'.\n\
771 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
772 therefore, write `(setq foo (delq element foo))'\n\
773 to be sure of changing the value of `foo'.")
774 (elt, list)
775 register Lisp_Object elt;
776 Lisp_Object list;
778 register Lisp_Object tail, prev;
779 register Lisp_Object tem;
781 tail = list;
782 prev = Qnil;
783 while (!NILP (tail))
785 tem = Fcar (tail);
786 if (EQ (elt, tem))
788 if (NILP (prev))
789 list = Fcdr (tail);
790 else
791 Fsetcdr (prev, Fcdr (tail));
793 else
794 prev = tail;
795 tail = Fcdr (tail);
796 QUIT;
798 return list;
801 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
802 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
803 The modified LIST is returned. Comparison is done with `equal'.\n\
804 If the first member of LIST is ELT, deleting it is not a side effect;\n\
805 it is simply using a different list.\n\
806 Therefore, write `(setq foo (delete element foo))'\n\
807 to be sure of changing the value of `foo'.")
808 (elt, list)
809 register Lisp_Object elt;
810 Lisp_Object list;
812 register Lisp_Object tail, prev;
813 register Lisp_Object tem;
815 tail = list;
816 prev = Qnil;
817 while (!NILP (tail))
819 tem = Fcar (tail);
820 if (! NILP (Fequal (elt, tem)))
822 if (NILP (prev))
823 list = Fcdr (tail);
824 else
825 Fsetcdr (prev, Fcdr (tail));
827 else
828 prev = tail;
829 tail = Fcdr (tail);
830 QUIT;
832 return list;
835 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
836 "Reverse LIST by modifying cdr pointers.\n\
837 Returns the beginning of the reversed list.")
838 (list)
839 Lisp_Object list;
841 register Lisp_Object prev, tail, next;
843 if (NILP (list)) return list;
844 prev = Qnil;
845 tail = list;
846 while (!NILP (tail))
848 QUIT;
849 next = Fcdr (tail);
850 Fsetcdr (tail, prev);
851 prev = tail;
852 tail = next;
854 return prev;
857 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
858 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
859 See also the function `nreverse', which is used more often.")
860 (list)
861 Lisp_Object list;
863 Lisp_Object length;
864 register Lisp_Object *vec;
865 register Lisp_Object tail;
866 register int i;
868 length = Flength (list);
869 vec = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object));
870 for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail))
871 vec[i] = Fcar (tail);
873 return Flist (XINT (length), vec);
876 Lisp_Object merge ();
878 DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
879 "Sort LIST, stably, comparing elements using PREDICATE.\n\
880 Returns the sorted list. LIST is modified by side effects.\n\
881 PREDICATE is called with two elements of LIST, and should return T\n\
882 if the first element is \"less\" than the second.")
883 (list, predicate)
884 Lisp_Object list, predicate;
886 Lisp_Object front, back;
887 register Lisp_Object len, tem;
888 struct gcpro gcpro1, gcpro2;
889 register int length;
891 front = list;
892 len = Flength (list);
893 length = XINT (len);
894 if (length < 2)
895 return list;
897 XSETINT (len, (length / 2) - 1);
898 tem = Fnthcdr (len, list);
899 back = Fcdr (tem);
900 Fsetcdr (tem, Qnil);
902 GCPRO2 (front, back);
903 front = Fsort (front, predicate);
904 back = Fsort (back, predicate);
905 UNGCPRO;
906 return merge (front, back, predicate);
909 Lisp_Object
910 merge (org_l1, org_l2, pred)
911 Lisp_Object org_l1, org_l2;
912 Lisp_Object pred;
914 Lisp_Object value;
915 register Lisp_Object tail;
916 Lisp_Object tem;
917 register Lisp_Object l1, l2;
918 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
920 l1 = org_l1;
921 l2 = org_l2;
922 tail = Qnil;
923 value = Qnil;
925 /* It is sufficient to protect org_l1 and org_l2.
926 When l1 and l2 are updated, we copy the new values
927 back into the org_ vars. */
928 GCPRO4 (org_l1, org_l2, pred, value);
930 while (1)
932 if (NILP (l1))
934 UNGCPRO;
935 if (NILP (tail))
936 return l2;
937 Fsetcdr (tail, l2);
938 return value;
940 if (NILP (l2))
942 UNGCPRO;
943 if (NILP (tail))
944 return l1;
945 Fsetcdr (tail, l1);
946 return value;
948 tem = call2 (pred, Fcar (l2), Fcar (l1));
949 if (NILP (tem))
951 tem = l1;
952 l1 = Fcdr (l1);
953 org_l1 = l1;
955 else
957 tem = l2;
958 l2 = Fcdr (l2);
959 org_l2 = l2;
961 if (NILP (tail))
962 value = tem;
963 else
964 Fsetcdr (tail, tem);
965 tail = tem;
970 DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
971 "Extract a value from a property list.\n\
972 PLIST is a property list, which is a list of the form\n\
973 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
974 corresponding to the given PROP, or nil if PROP is not\n\
975 one of the properties on the list.")
976 (plist, prop)
977 Lisp_Object plist;
978 register Lisp_Object prop;
980 register Lisp_Object tail;
981 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
983 register Lisp_Object tem;
984 tem = Fcar (tail);
985 if (EQ (prop, tem))
986 return Fcar (Fcdr (tail));
988 return Qnil;
991 DEFUN ("get", Fget, Sget, 2, 2, 0,
992 "Return the value of SYMBOL's PROPNAME property.\n\
993 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
994 (symbol, propname)
995 Lisp_Object symbol, propname;
997 CHECK_SYMBOL (symbol, 0);
998 return Fplist_get (XSYMBOL (symbol)->plist, propname);
1001 DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
1002 "Change value in PLIST of PROP to VAL.\n\
1003 PLIST is a property list, which is a list of the form\n\
1004 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
1005 If PROP is already a property on the list, its value is set to VAL,\n\
1006 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
1007 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
1008 The PLIST is modified by side effects.")
1009 (plist, prop, val)
1010 Lisp_Object plist;
1011 register Lisp_Object prop;
1012 Lisp_Object val;
1014 register Lisp_Object tail, prev;
1015 Lisp_Object newcell;
1016 prev = Qnil;
1017 for (tail = plist; CONSP (tail) && CONSP (XCONS (tail)->cdr);
1018 tail = XCONS (XCONS (tail)->cdr)->cdr)
1020 if (EQ (prop, XCONS (tail)->car))
1022 Fsetcar (XCONS (tail)->cdr, val);
1023 return plist;
1025 prev = tail;
1027 newcell = Fcons (prop, Fcons (val, Qnil));
1028 if (NILP (prev))
1029 return newcell;
1030 else
1031 Fsetcdr (XCONS (prev)->cdr, newcell);
1032 return plist;
1035 DEFUN ("put", Fput, Sput, 3, 3, 0,
1036 "Store SYMBOL's PROPNAME property with value VALUE.\n\
1037 It can be retrieved with `(get SYMBOL PROPNAME)'.")
1038 (symbol, propname, value)
1039 Lisp_Object symbol, propname, value;
1041 CHECK_SYMBOL (symbol, 0);
1042 XSYMBOL (symbol)->plist
1043 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1044 return value;
1047 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
1048 "T if two Lisp objects have similar structure and contents.\n\
1049 They must have the same data type.\n\
1050 Conses are compared by comparing the cars and the cdrs.\n\
1051 Vectors and strings are compared element by element.\n\
1052 Numbers are compared by value, but integers cannot equal floats.\n\
1053 (Use `=' if you want integers and floats to be able to be equal.)\n\
1054 Symbols must match exactly.")
1055 (o1, o2)
1056 register Lisp_Object o1, o2;
1058 return internal_equal (o1, o2, 0) ? Qt : Qnil;
1061 static int
1062 internal_equal (o1, o2, depth)
1063 register Lisp_Object o1, o2;
1064 int depth;
1066 if (depth > 200)
1067 error ("Stack overflow in equal");
1069 tail_recurse:
1070 QUIT;
1071 if (EQ (o1, o2))
1072 return 1;
1073 if (XTYPE (o1) != XTYPE (o2))
1074 return 0;
1076 switch (XTYPE (o1))
1078 #ifdef LISP_FLOAT_TYPE
1079 case Lisp_Float:
1080 return (extract_float (o1) == extract_float (o2));
1081 #endif
1083 case Lisp_Cons:
1084 if (!internal_equal (XCONS (o1)->car, XCONS (o2)->car, depth + 1))
1085 return 0;
1086 o1 = XCONS (o1)->cdr;
1087 o2 = XCONS (o2)->cdr;
1088 goto tail_recurse;
1090 case Lisp_Misc:
1091 if (XMISCTYPE (o1) != XMISCTYPE (o2))
1092 return 0;
1093 if (OVERLAYP (o1))
1095 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o1),
1096 depth + 1)
1097 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o1),
1098 depth + 1))
1099 return 0;
1100 o1 = XOVERLAY (o1)->plist;
1101 o2 = XOVERLAY (o2)->plist;
1102 goto tail_recurse;
1104 if (MARKERP (o1))
1106 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
1107 && (XMARKER (o1)->buffer == 0
1108 || XMARKER (o1)->bufpos == XMARKER (o2)->bufpos));
1110 break;
1112 case Lisp_Vectorlike:
1114 register int i, size;
1115 size = XVECTOR (o1)->size;
1116 /* Pseudovectors have the type encoded in the size field, so this test
1117 actually checks that the objects have the same type as well as the
1118 same size. */
1119 if (XVECTOR (o2)->size != size)
1120 return 0;
1121 /* Boolvectors are compared much like strings. */
1122 if (BOOL_VECTOR_P (o1))
1124 int size_in_chars
1125 = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1127 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
1128 return 0;
1129 if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
1130 size_in_chars))
1131 return 0;
1132 return 1;
1135 /* Aside from them, only true vectors, char-tables, and compiled
1136 functions are sensible to compare, so eliminate the others now. */
1137 if (size & PSEUDOVECTOR_FLAG)
1139 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
1140 return 0;
1141 size &= PSEUDOVECTOR_SIZE_MASK;
1143 for (i = 0; i < size; i++)
1145 Lisp_Object v1, v2;
1146 v1 = XVECTOR (o1)->contents [i];
1147 v2 = XVECTOR (o2)->contents [i];
1148 if (!internal_equal (v1, v2, depth + 1))
1149 return 0;
1151 return 1;
1153 break;
1155 case Lisp_String:
1156 if (XSTRING (o1)->size != XSTRING (o2)->size)
1157 return 0;
1158 if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
1159 XSTRING (o1)->size))
1160 return 0;
1161 #ifdef USE_TEXT_PROPERTIES
1162 /* If the strings have intervals, verify they match;
1163 if not, they are unequal. */
1164 if ((XSTRING (o1)->intervals != 0 || XSTRING (o2)->intervals != 0)
1165 && ! compare_string_intervals (o1, o2))
1166 return 0;
1167 #endif
1168 return 1;
1170 return 0;
1173 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
1174 "Store each element of ARRAY with ITEM.\n\
1175 ARRAY is a vector, string, char-table, or bool-vector.")
1176 (array, item)
1177 Lisp_Object array, item;
1179 register int size, index, charval;
1180 retry:
1181 if (VECTORP (array))
1183 register Lisp_Object *p = XVECTOR (array)->contents;
1184 size = XVECTOR (array)->size;
1185 for (index = 0; index < size; index++)
1186 p[index] = item;
1188 else if (CHAR_TABLE_P (array))
1190 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
1191 size = CHAR_TABLE_ORDINARY_SLOTS;
1192 for (index = 0; index < size; index++)
1193 p[index] = item;
1194 XCHAR_TABLE (array)->defalt = Qnil;
1196 else if (STRINGP (array))
1198 register unsigned char *p = XSTRING (array)->data;
1199 CHECK_NUMBER (item, 1);
1200 charval = XINT (item);
1201 size = XSTRING (array)->size;
1202 for (index = 0; index < size; index++)
1203 p[index] = charval;
1205 else if (BOOL_VECTOR_P (array))
1207 register unsigned char *p = XBOOL_VECTOR (array)->data;
1208 int size_in_chars
1209 = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1211 charval = (! NILP (item) ? -1 : 0);
1212 for (index = 0; index < size_in_chars; index++)
1213 p[index] = charval;
1215 else
1217 array = wrong_type_argument (Qarrayp, array);
1218 goto retry;
1220 return array;
1223 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
1224 1, 1, 0,
1225 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1226 (char_table)
1227 Lisp_Object char_table;
1229 CHECK_CHAR_TABLE (char_table, 0);
1231 return XCHAR_TABLE (char_table)->purpose;
1234 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
1235 1, 1, 0,
1236 "Return the parent char-table of CHAR-TABLE.\n\
1237 The value is either nil or another char-table.\n\
1238 If CHAR-TABLE holds nil for a given character,\n\
1239 then the actual applicable value is inherited from the parent char-table\n\
1240 \(or from its parents, if necessary).")
1241 (char_table)
1242 Lisp_Object char_table;
1244 CHECK_CHAR_TABLE (char_table, 0);
1246 return XCHAR_TABLE (char_table)->parent;
1249 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
1250 2, 2, 0,
1251 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1252 PARENT must be either nil or another char-table.")
1253 (char_table, parent)
1254 Lisp_Object char_table, parent;
1256 Lisp_Object temp;
1258 CHECK_CHAR_TABLE (char_table, 0);
1260 if (!NILP (parent))
1262 CHECK_CHAR_TABLE (parent, 0);
1264 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
1265 if (EQ (temp, char_table))
1266 error ("Attempt to make a chartable be its own parent");
1269 XCHAR_TABLE (char_table)->parent = parent;
1271 return parent;
1274 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
1275 2, 2, 0,
1276 "Return the value of CHAR-TABLE's extra-slot number N.")
1277 (char_table, n)
1278 Lisp_Object char_table, n;
1280 CHECK_CHAR_TABLE (char_table, 1);
1281 CHECK_NUMBER (n, 2);
1282 if (XINT (n) < 0
1283 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1284 args_out_of_range (char_table, n);
1286 return XCHAR_TABLE (char_table)->extras[XINT (n)];
1289 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
1290 Sset_char_table_extra_slot,
1291 3, 3, 0,
1292 "Set CHAR-TABLE's extra-slot number N to VALUE.")
1293 (char_table, n, value)
1294 Lisp_Object char_table, n, value;
1296 CHECK_CHAR_TABLE (char_table, 1);
1297 CHECK_NUMBER (n, 2);
1298 if (XINT (n) < 0
1299 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1300 args_out_of_range (char_table, n);
1302 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
1305 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
1306 2, 2, 0,
1307 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
1308 RANGE should be t (for all characters), nil (for the default value)\n\
1309 a vector which identifies a character set or a row of a character set,\n\
1310 or a character code.")
1311 (char_table, range)
1312 Lisp_Object char_table, range;
1314 int i;
1316 CHECK_CHAR_TABLE (char_table, 0);
1318 if (EQ (range, Qnil))
1319 return XCHAR_TABLE (char_table)->defalt;
1320 else if (INTEGERP (range))
1321 return Faref (char_table, range);
1322 else if (VECTORP (range))
1324 int size = XVECTOR (range)->size;
1325 Lisp_Object *val = XVECTOR (range)->contents;
1326 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1327 size <= 1 ? Qnil : val[1],
1328 size <= 2 ? Qnil : val[2]);
1329 return Faref (char_table, ch);
1331 else
1332 error ("Invalid RANGE argument to `char-table-range'");
1335 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
1336 3, 3, 0,
1337 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
1338 RANGE should be t (for all characters), nil (for the default value)\n\
1339 a vector which identifies a character set or a row of a character set,\n\
1340 or a character code.")
1341 (char_table, range, value)
1342 Lisp_Object char_table, range, value;
1344 int i;
1346 CHECK_CHAR_TABLE (char_table, 0);
1348 if (EQ (range, Qt))
1349 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1350 XCHAR_TABLE (char_table)->contents[i] = value;
1351 else if (EQ (range, Qnil))
1352 XCHAR_TABLE (char_table)->defalt = value;
1353 else if (INTEGERP (range))
1354 Faset (char_table, range, value);
1355 else if (VECTORP (range))
1357 int size = XVECTOR (range)->size;
1358 Lisp_Object *val = XVECTOR (range)->contents;
1359 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1360 size <= 1 ? Qnil : val[1],
1361 size <= 2 ? Qnil : val[2]);
1362 return Faset (char_table, ch, value);
1364 else
1365 error ("Invalid RANGE argument to `set-char-table-range'");
1367 return value;
1370 /* Map C_FUNCTION or FUNCTION over CHARTABLE, calling it for each
1371 character or group of characters that share a value.
1372 DEPTH is the current depth in the originally specified
1373 chartable, and INDICES contains the vector indices
1374 for the levels our callers have descended. */
1376 void
1377 map_char_table (c_function, function, chartable, depth, indices)
1378 Lisp_Object (*c_function) (), function, chartable, *indices;
1379 int depth;
1381 int i, to;
1383 if (depth == 0)
1385 /* At first, handle ASCII and 8-bit European characters. */
1386 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
1388 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1389 if (c_function)
1390 (*c_function) (i, elt);
1391 else
1392 call2 (function, make_number (i), elt);
1394 to = CHAR_TABLE_ORDINARY_SLOTS;
1396 else
1398 i = 32;
1399 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1402 for (i; i < to; i++)
1404 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1406 indices[depth] = i;
1408 if (SUB_CHAR_TABLE_P (elt))
1410 if (depth >= 3)
1411 error ("Too deep char table");
1412 map_char_table (c_function, function, elt, depth + 1, indices);
1414 else
1416 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
1418 if (CHARSET_DEFINED_P (charset))
1420 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
1421 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
1422 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
1423 if (c_function)
1424 (*c_function) (c, elt);
1425 else
1426 call2 (function, make_number (c), elt);
1432 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
1433 2, 2, 0,
1434 "Call FUNCTION for each range of like characters in CHAR-TABLE.\n\
1435 FUNCTION is called with two arguments--a key and a value.\n\
1436 The key is always a possible RANGE argument to `set-char-table-range'.")
1437 (function, char_table)
1438 Lisp_Object function, char_table;
1440 Lisp_Object keyvec;
1441 /* The depth of char table is at most 3. */
1442 Lisp_Object *indices = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
1444 map_char_table (NULL, function, char_table, 0, indices);
1445 return Qnil;
1448 /* ARGSUSED */
1449 Lisp_Object
1450 nconc2 (s1, s2)
1451 Lisp_Object s1, s2;
1453 #ifdef NO_ARG_ARRAY
1454 Lisp_Object args[2];
1455 args[0] = s1;
1456 args[1] = s2;
1457 return Fnconc (2, args);
1458 #else
1459 return Fnconc (2, &s1);
1460 #endif /* NO_ARG_ARRAY */
1463 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
1464 "Concatenate any number of lists by altering them.\n\
1465 Only the last argument is not altered, and need not be a list.")
1466 (nargs, args)
1467 int nargs;
1468 Lisp_Object *args;
1470 register int argnum;
1471 register Lisp_Object tail, tem, val;
1473 val = Qnil;
1475 for (argnum = 0; argnum < nargs; argnum++)
1477 tem = args[argnum];
1478 if (NILP (tem)) continue;
1480 if (NILP (val))
1481 val = tem;
1483 if (argnum + 1 == nargs) break;
1485 if (!CONSP (tem))
1486 tem = wrong_type_argument (Qlistp, tem);
1488 while (CONSP (tem))
1490 tail = tem;
1491 tem = Fcdr (tail);
1492 QUIT;
1495 tem = args[argnum + 1];
1496 Fsetcdr (tail, tem);
1497 if (NILP (tem))
1498 args[argnum + 1] = tail;
1501 return val;
1504 /* This is the guts of all mapping functions.
1505 Apply fn to each element of seq, one by one,
1506 storing the results into elements of vals, a C vector of Lisp_Objects.
1507 leni is the length of vals, which should also be the length of seq. */
1509 static void
1510 mapcar1 (leni, vals, fn, seq)
1511 int leni;
1512 Lisp_Object *vals;
1513 Lisp_Object fn, seq;
1515 register Lisp_Object tail;
1516 Lisp_Object dummy;
1517 register int i;
1518 struct gcpro gcpro1, gcpro2, gcpro3;
1520 /* Don't let vals contain any garbage when GC happens. */
1521 for (i = 0; i < leni; i++)
1522 vals[i] = Qnil;
1524 GCPRO3 (dummy, fn, seq);
1525 gcpro1.var = vals;
1526 gcpro1.nvars = leni;
1527 /* We need not explicitly protect `tail' because it is used only on lists, and
1528 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
1530 if (VECTORP (seq))
1532 for (i = 0; i < leni; i++)
1534 dummy = XVECTOR (seq)->contents[i];
1535 vals[i] = call1 (fn, dummy);
1538 else if (STRINGP (seq))
1540 for (i = 0; i < leni; i++)
1542 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
1543 vals[i] = call1 (fn, dummy);
1546 else /* Must be a list, since Flength did not get an error */
1548 tail = seq;
1549 for (i = 0; i < leni; i++)
1551 vals[i] = call1 (fn, Fcar (tail));
1552 tail = Fcdr (tail);
1556 UNGCPRO;
1559 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
1560 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
1561 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
1562 SEPARATOR results in spaces between the values returned by FUNCTION.")
1563 (function, sequence, separator)
1564 Lisp_Object function, sequence, separator;
1566 Lisp_Object len;
1567 register int leni;
1568 int nargs;
1569 register Lisp_Object *args;
1570 register int i;
1571 struct gcpro gcpro1;
1573 len = Flength (sequence);
1574 leni = XINT (len);
1575 nargs = leni + leni - 1;
1576 if (nargs < 0) return build_string ("");
1578 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
1580 GCPRO1 (separator);
1581 mapcar1 (leni, args, function, sequence);
1582 UNGCPRO;
1584 for (i = leni - 1; i >= 0; i--)
1585 args[i + i] = args[i];
1587 for (i = 1; i < nargs; i += 2)
1588 args[i] = separator;
1590 return Fconcat (nargs, args);
1593 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
1594 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
1595 The result is a list just as long as SEQUENCE.\n\
1596 SEQUENCE may be a list, a vector or a string.")
1597 (function, sequence)
1598 Lisp_Object function, sequence;
1600 register Lisp_Object len;
1601 register int leni;
1602 register Lisp_Object *args;
1604 len = Flength (sequence);
1605 leni = XFASTINT (len);
1606 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
1608 mapcar1 (leni, args, function, sequence);
1610 return Flist (leni, args);
1613 /* Anything that calls this function must protect from GC! */
1615 DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
1616 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
1617 Takes one argument, which is the string to display to ask the question.\n\
1618 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
1619 No confirmation of the answer is requested; a single character is enough.\n\
1620 Also accepts Space to mean yes, or Delete to mean no.")
1621 (prompt)
1622 Lisp_Object prompt;
1624 register Lisp_Object obj, key, def, answer_string, map;
1625 register int answer;
1626 Lisp_Object xprompt;
1627 Lisp_Object args[2];
1628 struct gcpro gcpro1, gcpro2;
1629 int count = specpdl_ptr - specpdl;
1631 specbind (Qcursor_in_echo_area, Qt);
1633 map = Fsymbol_value (intern ("query-replace-map"));
1635 CHECK_STRING (prompt, 0);
1636 xprompt = prompt;
1637 GCPRO2 (prompt, xprompt);
1639 while (1)
1643 #ifdef HAVE_MENUS
1644 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1645 && have_menus_p ())
1647 Lisp_Object pane, menu;
1648 redisplay_preserve_echo_area ();
1649 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1650 Fcons (Fcons (build_string ("No"), Qnil),
1651 Qnil));
1652 menu = Fcons (prompt, pane);
1653 obj = Fx_popup_dialog (Qt, menu);
1654 answer = !NILP (obj);
1655 break;
1657 #endif /* HAVE_MENUS */
1658 cursor_in_echo_area = 1;
1659 choose_minibuf_frame ();
1660 message_nolog ("%s(y or n) ", XSTRING (xprompt)->data);
1662 if (minibuffer_auto_raise)
1664 Lisp_Object mini_frame;
1666 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
1668 Fraise_frame (mini_frame);
1671 obj = read_filtered_event (1, 0, 0);
1672 cursor_in_echo_area = 0;
1673 /* If we need to quit, quit with cursor_in_echo_area = 0. */
1674 QUIT;
1676 key = Fmake_vector (make_number (1), obj);
1677 def = Flookup_key (map, key, Qt);
1678 answer_string = Fsingle_key_description (obj);
1680 if (EQ (def, intern ("skip")))
1682 answer = 0;
1683 break;
1685 else if (EQ (def, intern ("act")))
1687 answer = 1;
1688 break;
1690 else if (EQ (def, intern ("recenter")))
1692 Frecenter (Qnil);
1693 xprompt = prompt;
1694 continue;
1696 else if (EQ (def, intern ("quit")))
1697 Vquit_flag = Qt;
1698 /* We want to exit this command for exit-prefix,
1699 and this is the only way to do it. */
1700 else if (EQ (def, intern ("exit-prefix")))
1701 Vquit_flag = Qt;
1703 QUIT;
1705 /* If we don't clear this, then the next call to read_char will
1706 return quit_char again, and we'll enter an infinite loop. */
1707 Vquit_flag = Qnil;
1709 Fding (Qnil);
1710 Fdiscard_input ();
1711 if (EQ (xprompt, prompt))
1713 args[0] = build_string ("Please answer y or n. ");
1714 args[1] = prompt;
1715 xprompt = Fconcat (2, args);
1718 UNGCPRO;
1720 if (! noninteractive)
1722 cursor_in_echo_area = -1;
1723 message_nolog ("%s(y or n) %c",
1724 XSTRING (xprompt)->data, answer ? 'y' : 'n');
1727 unbind_to (count, Qnil);
1728 return answer ? Qt : Qnil;
1731 /* This is how C code calls `yes-or-no-p' and allows the user
1732 to redefined it.
1734 Anything that calls this function must protect from GC! */
1736 Lisp_Object
1737 do_yes_or_no_p (prompt)
1738 Lisp_Object prompt;
1740 return call1 (intern ("yes-or-no-p"), prompt);
1743 /* Anything that calls this function must protect from GC! */
1745 DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
1746 "Ask user a yes-or-no question. Return t if answer is yes.\n\
1747 Takes one argument, which is the string to display to ask the question.\n\
1748 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
1749 The user must confirm the answer with RET,\n\
1750 and can edit it until it has been confirmed.")
1751 (prompt)
1752 Lisp_Object prompt;
1754 register Lisp_Object ans;
1755 Lisp_Object args[2];
1756 struct gcpro gcpro1;
1757 Lisp_Object menu;
1759 CHECK_STRING (prompt, 0);
1761 #ifdef HAVE_MENUS
1762 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1763 && have_menus_p ())
1765 Lisp_Object pane, menu, obj;
1766 redisplay_preserve_echo_area ();
1767 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1768 Fcons (Fcons (build_string ("No"), Qnil),
1769 Qnil));
1770 GCPRO1 (pane);
1771 menu = Fcons (prompt, pane);
1772 obj = Fx_popup_dialog (Qt, menu);
1773 UNGCPRO;
1774 return obj;
1776 #endif /* HAVE_MENUS */
1778 args[0] = prompt;
1779 args[1] = build_string ("(yes or no) ");
1780 prompt = Fconcat (2, args);
1782 GCPRO1 (prompt);
1784 while (1)
1786 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
1787 Qyes_or_no_p_history));
1788 if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
1790 UNGCPRO;
1791 return Qt;
1793 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
1795 UNGCPRO;
1796 return Qnil;
1799 Fding (Qnil);
1800 Fdiscard_input ();
1801 message ("Please answer yes or no.");
1802 Fsleep_for (make_number (2), Qnil);
1806 DEFUN ("load-average", Fload_average, Sload_average, 0, 0, 0,
1807 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
1808 Each of the three load averages is multiplied by 100,\n\
1809 then converted to integer.\n\
1810 If the 5-minute or 15-minute load averages are not available, return a\n\
1811 shortened list, containing only those averages which are available.")
1814 double load_ave[3];
1815 int loads = getloadavg (load_ave, 3);
1816 Lisp_Object ret;
1818 if (loads < 0)
1819 error ("load-average not implemented for this operating system");
1821 ret = Qnil;
1822 while (loads > 0)
1823 ret = Fcons (make_number ((int) (load_ave[--loads] * 100.0)), ret);
1825 return ret;
1828 Lisp_Object Vfeatures;
1830 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
1831 "Returns t if FEATURE is present in this Emacs.\n\
1832 Use this to conditionalize execution of lisp code based on the presence or\n\
1833 absence of emacs or environment extensions.\n\
1834 Use `provide' to declare that a feature is available.\n\
1835 This function looks at the value of the variable `features'.")
1836 (feature)
1837 Lisp_Object feature;
1839 register Lisp_Object tem;
1840 CHECK_SYMBOL (feature, 0);
1841 tem = Fmemq (feature, Vfeatures);
1842 return (NILP (tem)) ? Qnil : Qt;
1845 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
1846 "Announce that FEATURE is a feature of the current Emacs.")
1847 (feature)
1848 Lisp_Object feature;
1850 register Lisp_Object tem;
1851 CHECK_SYMBOL (feature, 0);
1852 if (!NILP (Vautoload_queue))
1853 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
1854 tem = Fmemq (feature, Vfeatures);
1855 if (NILP (tem))
1856 Vfeatures = Fcons (feature, Vfeatures);
1857 LOADHIST_ATTACH (Fcons (Qprovide, feature));
1858 return feature;
1861 DEFUN ("require", Frequire, Srequire, 1, 2, 0,
1862 "If feature FEATURE is not loaded, load it from FILENAME.\n\
1863 If FEATURE is not a member of the list `features', then the feature\n\
1864 is not loaded; so load the file FILENAME.\n\
1865 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
1866 (feature, file_name)
1867 Lisp_Object feature, file_name;
1869 register Lisp_Object tem;
1870 CHECK_SYMBOL (feature, 0);
1871 tem = Fmemq (feature, Vfeatures);
1872 LOADHIST_ATTACH (Fcons (Qrequire, feature));
1873 if (NILP (tem))
1875 int count = specpdl_ptr - specpdl;
1877 /* Value saved here is to be restored into Vautoload_queue */
1878 record_unwind_protect (un_autoload, Vautoload_queue);
1879 Vautoload_queue = Qt;
1881 Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
1882 Qnil, Qt, Qnil);
1884 tem = Fmemq (feature, Vfeatures);
1885 if (NILP (tem))
1886 error ("Required feature %s was not provided",
1887 XSYMBOL (feature)->name->data );
1889 /* Once loading finishes, don't undo it. */
1890 Vautoload_queue = Qt;
1891 feature = unbind_to (count, feature);
1893 return feature;
1896 syms_of_fns ()
1898 Qstring_lessp = intern ("string-lessp");
1899 staticpro (&Qstring_lessp);
1900 Qprovide = intern ("provide");
1901 staticpro (&Qprovide);
1902 Qrequire = intern ("require");
1903 staticpro (&Qrequire);
1904 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
1905 staticpro (&Qyes_or_no_p_history);
1906 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
1907 staticpro (&Qcursor_in_echo_area);
1909 Fset (Qyes_or_no_p_history, Qnil);
1911 DEFVAR_LISP ("features", &Vfeatures,
1912 "A list of symbols which are the features of the executing emacs.\n\
1913 Used by `featurep' and `require', and altered by `provide'.");
1914 Vfeatures = Qnil;
1916 defsubr (&Sidentity);
1917 defsubr (&Srandom);
1918 defsubr (&Slength);
1919 defsubr (&Ssafe_length);
1920 defsubr (&Sstring_equal);
1921 defsubr (&Sstring_lessp);
1922 defsubr (&Sappend);
1923 defsubr (&Sconcat);
1924 defsubr (&Svconcat);
1925 defsubr (&Scopy_sequence);
1926 defsubr (&Scopy_alist);
1927 defsubr (&Ssubstring);
1928 defsubr (&Snthcdr);
1929 defsubr (&Snth);
1930 defsubr (&Selt);
1931 defsubr (&Smember);
1932 defsubr (&Smemq);
1933 defsubr (&Sassq);
1934 defsubr (&Sassoc);
1935 defsubr (&Srassq);
1936 defsubr (&Srassoc);
1937 defsubr (&Sdelq);
1938 defsubr (&Sdelete);
1939 defsubr (&Snreverse);
1940 defsubr (&Sreverse);
1941 defsubr (&Ssort);
1942 defsubr (&Splist_get);
1943 defsubr (&Sget);
1944 defsubr (&Splist_put);
1945 defsubr (&Sput);
1946 defsubr (&Sequal);
1947 defsubr (&Sfillarray);
1948 defsubr (&Schar_table_subtype);
1949 defsubr (&Schar_table_parent);
1950 defsubr (&Sset_char_table_parent);
1951 defsubr (&Schar_table_extra_slot);
1952 defsubr (&Sset_char_table_extra_slot);
1953 defsubr (&Schar_table_range);
1954 defsubr (&Sset_char_table_range);
1955 defsubr (&Smap_char_table);
1956 defsubr (&Snconc);
1957 defsubr (&Smapcar);
1958 defsubr (&Smapconcat);
1959 defsubr (&Sy_or_n_p);
1960 defsubr (&Syes_or_no_p);
1961 defsubr (&Sload_average);
1962 defsubr (&Sfeaturep);
1963 defsubr (&Srequire);
1964 defsubr (&Sprovide);