]> code.delx.au - gnu-emacs/blob - src/fns.c
(enum syntaxcode): New members Scomment_fence, Sstring_fence.
[gnu-emacs] / src / fns.c
1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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.
10
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.
15
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. */
20
21
22 #include <config.h>
23
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 *****
28
29 #include "lisp.h"
30 #include "commands.h"
31 #include "charset.h"
32
33 #include "buffer.h"
34 #include "keyboard.h"
35 #include "intervals.h"
36 #include "frame.h"
37 #include "window.h"
38
39 #ifndef NULL
40 #define NULL (void *)0
41 #endif
42
43 extern Lisp_Object Flookup_key ();
44
45 extern int minibuffer_auto_raise;
46 extern Lisp_Object minibuf_window;
47
48 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
49 Lisp_Object Qyes_or_no_p_history;
50 Lisp_Object Qcursor_in_echo_area;
51
52 static int internal_equal ();
53 \f
54 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
55 "Return the argument unchanged.")
56 (arg)
57 Lisp_Object arg;
58 {
59 return arg;
60 }
61
62 extern long get_random ();
63 extern void seed_random ();
64 extern long time ();
65
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;
74 {
75 EMACS_INT val;
76 Lisp_Object lispy_val;
77 unsigned long denominator;
78
79 if (EQ (n, Qt))
80 seed_random (getpid () + time (NULL));
81 if (NATNUMP (n) && XFASTINT (n) != 0)
82 {
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);
91 do
92 val = get_random () / denominator;
93 while (val >= XFASTINT (n));
94 }
95 else
96 val = get_random ();
97 XSETINT (lispy_val, val);
98 return lispy_val;
99 }
100 \f
101 /* Random data-structure functions */
102
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;
108 {
109 register Lisp_Object tail, val;
110 register int i;
111
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))
124 {
125 for (i = 0, tail = sequence; !NILP (tail); i++)
126 {
127 QUIT;
128 tail = Fcdr (tail);
129 }
130
131 XSETFASTINT (val, i);
132 }
133 else if (NILP (sequence))
134 XSETFASTINT (val, 0);
135 else
136 {
137 sequence = wrong_type_argument (Qsequencep, sequence);
138 goto retry;
139 }
140 return val;
141 }
142
143 /* This does not check for quits. That is safe
144 since it must terminate. */
145
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;
153 {
154 Lisp_Object tail, halftail, length;
155 int len = 0;
156
157 /* halftail is used to detect circular lists. */
158 halftail = list;
159 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
160 {
161 if (EQ (tail, halftail) && len != 0)
162 break;
163 len++;
164 if ((len & 1) == 0)
165 halftail = XCONS (halftail)->cdr;
166 }
167
168 XSETINT (length, len);
169 return length;
170 }
171
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;
178 {
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);
185
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;
190 }
191
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;
198 {
199 register int i;
200 register unsigned char *p1, *p2;
201 register int end;
202
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);
209
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;
215
216 for (i = 0; i < end; i++)
217 {
218 if (p1[i] != p2[i])
219 return p1[i] < p2[i] ? Qt : Qnil;
220 }
221 return i < XSTRING (s2)->size ? Qt : Qnil;
222 }
223 \f
224 static Lisp_Object concat ();
225
226 /* ARGSUSED */
227 Lisp_Object
228 concat2 (s1, s2)
229 Lisp_Object s1, s2;
230 {
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 */
239 }
240
241 /* ARGSUSED */
242 Lisp_Object
243 concat3 (s1, s2, s3)
244 Lisp_Object s1, s2, s3;
245 {
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 */
255 }
256
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;
265 {
266 return concat (nargs, args, Lisp_Cons, 1);
267 }
268
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\
273 \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;
281 {
282 return concat (nargs, args, Lisp_String, 0);
283 }
284
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;
292 {
293 return concat (nargs, args, Lisp_Vectorlike, 0);
294 }
295
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)
300 {
301 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
302 int i;
303
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]);
312
313 return copy;
314 }
315
316
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;
323 {
324 if (NILP (arg)) return arg;
325
326 if (CHAR_TABLE_P (arg))
327 {
328 int i;
329 Lisp_Object copy;
330
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)));
336
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]);
344
345 return copy;
346 }
347
348 if (BOOL_VECTOR_P (arg))
349 {
350 Lisp_Object val;
351 int size_in_chars
352 = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
353
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;
358 }
359
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);
363 }
364
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;
371 {
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;
381
382 /* In append, the last arg isn't treated like the others */
383 if (last_special && nargs > 0)
384 {
385 nargs--;
386 last_tail = args[nargs];
387 }
388 else
389 last_tail = Qnil;
390
391 for (argnum = 0; argnum < nargs; argnum++)
392 {
393 this = args[argnum];
394 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
395 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
396 {
397 if (INTEGERP (this))
398 args[argnum] = Fnumber_to_string (this);
399 else
400 args[argnum] = wrong_type_argument (Qsequencep, this);
401 }
402 }
403
404 for (argnum = 0, leni = 0; argnum < nargs; argnum++)
405 {
406 this = args[argnum];
407 len = Flength (this);
408 leni += XFASTINT (len);
409 }
410
411 XSETFASTINT (len, leni);
412
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);
419
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;
423
424 if (CONSP (val))
425 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
426 else
427 toindex = 0;
428
429 prev = Qnil;
430
431 for (argnum = 0; argnum < nargs; argnum++)
432 {
433 Lisp_Object thislen;
434 int thisleni;
435 register unsigned int thisindex = 0;
436
437 this = args[argnum];
438 if (!CONSP (this))
439 thislen = Flength (this), thisleni = XINT (thislen);
440
441 if (STRINGP (this) && STRINGP (val)
442 && ! NULL_INTERVAL_P (XSTRING (this)->intervals))
443 {
444 copy_text_properties (make_number (0), thislen, this,
445 make_number (toindex), val, Qnil);
446 }
447
448 while (1)
449 {
450 register Lisp_Object elt;
451
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
458 {
459 if (thisindex >= thisleni) break;
460 if (STRINGP (this))
461 XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
462 else if (BOOL_VECTOR_P (this))
463 {
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;
473 }
474 else
475 elt = XVECTOR (this)->contents[thisindex++];
476 }
477
478 /* Store into result */
479 if (toindex < 0)
480 {
481 XCONS (tail)->car = elt;
482 prev = tail;
483 tail = XCONS (tail)->cdr;
484 }
485 else if (VECTORP (val))
486 XVECTOR (val)->contents[toindex++] = elt;
487 else
488 {
489 while (!INTEGERP (elt))
490 elt = wrong_type_argument (Qintegerp, elt);
491 {
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
500 }
501 }
502 }
503 }
504 if (!NILP (prev))
505 XCONS (prev)->cdr = last_tail;
506
507 return val;
508 }
509 \f
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;
519 {
520 register Lisp_Object tem;
521
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)
527 {
528 register Lisp_Object car;
529 car = XCONS (tem)->car;
530
531 if (CONSP (car))
532 XCONS (tem)->car = Fcons (XCONS (car)->car, XCONS (car)->cdr);
533 }
534 return alist;
535 }
536
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\
541 \n\
542 This function allows vectors as well as strings.")
543 (string, from, to)
544 Lisp_Object string;
545 register Lisp_Object from, to;
546 {
547 Lisp_Object res;
548 int size;
549
550 if (! (STRINGP (string) || VECTORP (string)))
551 wrong_type_argument (Qarrayp, string);
552
553 CHECK_NUMBER (from, 1);
554
555 if (STRINGP (string))
556 size = XSTRING (string)->size;
557 else
558 size = XVECTOR (string)->size;
559
560 if (NILP (to))
561 to = size;
562 else
563 CHECK_NUMBER (to, 2);
564
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);
572
573 if (STRINGP (string))
574 {
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);
578 }
579 else
580 res = Fvector (XINT (to) - XINT (from),
581 XVECTOR (string)->contents + XINT (from));
582
583 return res;
584 }
585 \f
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;
591 {
592 register int i, num;
593 CHECK_NUMBER (n, 0);
594 num = XINT (n);
595 for (i = 0; i < num && !NILP (list); i++)
596 {
597 QUIT;
598 list = Fcdr (list);
599 }
600 return list;
601 }
602
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;
608 {
609 return Fcar (Fnthcdr (n, list));
610 }
611
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;
616 {
617 CHECK_NUMBER (n, 0);
618 while (1)
619 {
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);
627 }
628 }
629
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;
636 {
637 register Lisp_Object tail;
638 for (tail = list; !NILP (tail); tail = Fcdr (tail))
639 {
640 register Lisp_Object tem;
641 tem = Fcar (tail);
642 if (! NILP (Fequal (elt, tem)))
643 return tail;
644 QUIT;
645 }
646 return Qnil;
647 }
648
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;
655 {
656 register Lisp_Object tail;
657 for (tail = list; !NILP (tail); tail = Fcdr (tail))
658 {
659 register Lisp_Object tem;
660 tem = Fcar (tail);
661 if (EQ (elt, tem)) return tail;
662 QUIT;
663 }
664 return Qnil;
665 }
666
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;
674 {
675 register Lisp_Object tail;
676 for (tail = list; !NILP (tail); tail = Fcdr (tail))
677 {
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;
684 }
685 return Qnil;
686 }
687
688 /* Like Fassq but never report an error and do not allow quits.
689 Use only on lists known never to be circular. */
690
691 Lisp_Object
692 assq_no_quit (key, list)
693 register Lisp_Object key;
694 Lisp_Object list;
695 {
696 register Lisp_Object tail;
697 for (tail = list; CONSP (tail); tail = Fcdr (tail))
698 {
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;
704 }
705 return Qnil;
706 }
707
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;
714 {
715 register Lisp_Object tail;
716 for (tail = list; !NILP (tail); tail = Fcdr (tail))
717 {
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;
724 }
725 return Qnil;
726 }
727
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;
734 {
735 register Lisp_Object tail;
736 for (tail = list; !NILP (tail); tail = Fcdr (tail))
737 {
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;
744 }
745 return Qnil;
746 }
747
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;
754 {
755 register Lisp_Object tail;
756 for (tail = list; !NILP (tail); tail = Fcdr (tail))
757 {
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;
764 }
765 return Qnil;
766 }
767 \f
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;
777 {
778 register Lisp_Object tail, prev;
779 register Lisp_Object tem;
780
781 tail = list;
782 prev = Qnil;
783 while (!NILP (tail))
784 {
785 tem = Fcar (tail);
786 if (EQ (elt, tem))
787 {
788 if (NILP (prev))
789 list = Fcdr (tail);
790 else
791 Fsetcdr (prev, Fcdr (tail));
792 }
793 else
794 prev = tail;
795 tail = Fcdr (tail);
796 QUIT;
797 }
798 return list;
799 }
800
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;
811 {
812 register Lisp_Object tail, prev;
813 register Lisp_Object tem;
814
815 tail = list;
816 prev = Qnil;
817 while (!NILP (tail))
818 {
819 tem = Fcar (tail);
820 if (! NILP (Fequal (elt, tem)))
821 {
822 if (NILP (prev))
823 list = Fcdr (tail);
824 else
825 Fsetcdr (prev, Fcdr (tail));
826 }
827 else
828 prev = tail;
829 tail = Fcdr (tail);
830 QUIT;
831 }
832 return list;
833 }
834
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;
840 {
841 register Lisp_Object prev, tail, next;
842
843 if (NILP (list)) return list;
844 prev = Qnil;
845 tail = list;
846 while (!NILP (tail))
847 {
848 QUIT;
849 next = Fcdr (tail);
850 Fsetcdr (tail, prev);
851 prev = tail;
852 tail = next;
853 }
854 return prev;
855 }
856
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;
862 {
863 Lisp_Object length;
864 register Lisp_Object *vec;
865 register Lisp_Object tail;
866 register int i;
867
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);
872
873 return Flist (XINT (length), vec);
874 }
875 \f
876 Lisp_Object merge ();
877
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;
885 {
886 Lisp_Object front, back;
887 register Lisp_Object len, tem;
888 struct gcpro gcpro1, gcpro2;
889 register int length;
890
891 front = list;
892 len = Flength (list);
893 length = XINT (len);
894 if (length < 2)
895 return list;
896
897 XSETINT (len, (length / 2) - 1);
898 tem = Fnthcdr (len, list);
899 back = Fcdr (tem);
900 Fsetcdr (tem, Qnil);
901
902 GCPRO2 (front, back);
903 front = Fsort (front, predicate);
904 back = Fsort (back, predicate);
905 UNGCPRO;
906 return merge (front, back, predicate);
907 }
908
909 Lisp_Object
910 merge (org_l1, org_l2, pred)
911 Lisp_Object org_l1, org_l2;
912 Lisp_Object pred;
913 {
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;
919
920 l1 = org_l1;
921 l2 = org_l2;
922 tail = Qnil;
923 value = Qnil;
924
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);
929
930 while (1)
931 {
932 if (NILP (l1))
933 {
934 UNGCPRO;
935 if (NILP (tail))
936 return l2;
937 Fsetcdr (tail, l2);
938 return value;
939 }
940 if (NILP (l2))
941 {
942 UNGCPRO;
943 if (NILP (tail))
944 return l1;
945 Fsetcdr (tail, l1);
946 return value;
947 }
948 tem = call2 (pred, Fcar (l2), Fcar (l1));
949 if (NILP (tem))
950 {
951 tem = l1;
952 l1 = Fcdr (l1);
953 org_l1 = l1;
954 }
955 else
956 {
957 tem = l2;
958 l2 = Fcdr (l2);
959 org_l2 = l2;
960 }
961 if (NILP (tail))
962 value = tem;
963 else
964 Fsetcdr (tail, tem);
965 tail = tem;
966 }
967 }
968 \f
969
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;
979 {
980 register Lisp_Object tail;
981 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
982 {
983 register Lisp_Object tem;
984 tem = Fcar (tail);
985 if (EQ (prop, tem))
986 return Fcar (Fcdr (tail));
987 }
988 return Qnil;
989 }
990
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;
996 {
997 CHECK_SYMBOL (symbol, 0);
998 return Fplist_get (XSYMBOL (symbol)->plist, propname);
999 }
1000
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;
1013 {
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)
1019 {
1020 if (EQ (prop, XCONS (tail)->car))
1021 {
1022 Fsetcar (XCONS (tail)->cdr, val);
1023 return plist;
1024 }
1025 prev = tail;
1026 }
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;
1033 }
1034
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;
1040 {
1041 CHECK_SYMBOL (symbol, 0);
1042 XSYMBOL (symbol)->plist
1043 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1044 return value;
1045 }
1046
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;
1057 {
1058 return internal_equal (o1, o2, 0) ? Qt : Qnil;
1059 }
1060
1061 static int
1062 internal_equal (o1, o2, depth)
1063 register Lisp_Object o1, o2;
1064 int depth;
1065 {
1066 if (depth > 200)
1067 error ("Stack overflow in equal");
1068
1069 tail_recurse:
1070 QUIT;
1071 if (EQ (o1, o2))
1072 return 1;
1073 if (XTYPE (o1) != XTYPE (o2))
1074 return 0;
1075
1076 switch (XTYPE (o1))
1077 {
1078 #ifdef LISP_FLOAT_TYPE
1079 case Lisp_Float:
1080 return (extract_float (o1) == extract_float (o2));
1081 #endif
1082
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;
1089
1090 case Lisp_Misc:
1091 if (XMISCTYPE (o1) != XMISCTYPE (o2))
1092 return 0;
1093 if (OVERLAYP (o1))
1094 {
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;
1103 }
1104 if (MARKERP (o1))
1105 {
1106 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
1107 && (XMARKER (o1)->buffer == 0
1108 || XMARKER (o1)->bufpos == XMARKER (o2)->bufpos));
1109 }
1110 break;
1111
1112 case Lisp_Vectorlike:
1113 {
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))
1123 {
1124 int size_in_chars
1125 = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1126
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;
1133 }
1134
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)
1138 {
1139 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
1140 return 0;
1141 size &= PSEUDOVECTOR_SIZE_MASK;
1142 }
1143 for (i = 0; i < size; i++)
1144 {
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;
1150 }
1151 return 1;
1152 }
1153 break;
1154
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;
1169 }
1170 return 0;
1171 }
1172 \f
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;
1178 {
1179 register int size, index, charval;
1180 retry:
1181 if (VECTORP (array))
1182 {
1183 register Lisp_Object *p = XVECTOR (array)->contents;
1184 size = XVECTOR (array)->size;
1185 for (index = 0; index < size; index++)
1186 p[index] = item;
1187 }
1188 else if (CHAR_TABLE_P (array))
1189 {
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;
1195 }
1196 else if (STRINGP (array))
1197 {
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;
1204 }
1205 else if (BOOL_VECTOR_P (array))
1206 {
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;
1210
1211 charval = (! NILP (item) ? -1 : 0);
1212 for (index = 0; index < size_in_chars; index++)
1213 p[index] = charval;
1214 }
1215 else
1216 {
1217 array = wrong_type_argument (Qarrayp, array);
1218 goto retry;
1219 }
1220 return array;
1221 }
1222
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;
1228 {
1229 CHECK_CHAR_TABLE (char_table, 0);
1230
1231 return XCHAR_TABLE (char_table)->purpose;
1232 }
1233
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;
1243 {
1244 CHECK_CHAR_TABLE (char_table, 0);
1245
1246 return XCHAR_TABLE (char_table)->parent;
1247 }
1248
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;
1255 {
1256 Lisp_Object temp;
1257
1258 CHECK_CHAR_TABLE (char_table, 0);
1259
1260 if (!NILP (parent))
1261 {
1262 CHECK_CHAR_TABLE (parent, 0);
1263
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");
1267 }
1268
1269 XCHAR_TABLE (char_table)->parent = parent;
1270
1271 return parent;
1272 }
1273
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;
1279 {
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);
1285
1286 return XCHAR_TABLE (char_table)->extras[XINT (n)];
1287 }
1288
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;
1295 {
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);
1301
1302 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
1303 }
1304
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;
1313 {
1314 int i;
1315
1316 CHECK_CHAR_TABLE (char_table, 0);
1317
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))
1323 {
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);
1330 }
1331 else
1332 error ("Invalid RANGE argument to `char-table-range'");
1333 }
1334
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;
1343 {
1344 int i;
1345
1346 CHECK_CHAR_TABLE (char_table, 0);
1347
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))
1356 {
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);
1363 }
1364 else
1365 error ("Invalid RANGE argument to `set-char-table-range'");
1366
1367 return value;
1368 }
1369 \f
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. */
1375
1376 void
1377 map_char_table (c_function, function, chartable, depth, indices)
1378 Lisp_Object (*c_function) (), function, chartable, *indices;
1379 int depth;
1380 {
1381 int i, to;
1382
1383 if (depth == 0)
1384 {
1385 /* At first, handle ASCII and 8-bit European characters. */
1386 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
1387 {
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);
1393 }
1394 to = CHAR_TABLE_ORDINARY_SLOTS;
1395 }
1396 else
1397 {
1398 i = 32;
1399 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1400 }
1401
1402 for (i; i < to; i++)
1403 {
1404 Lisp_Object elt = XCHAR_TABLE (chartable)->contents[i];
1405
1406 indices[depth] = i;
1407
1408 if (SUB_CHAR_TABLE_P (elt))
1409 {
1410 if (depth >= 3)
1411 error ("Too deep char table");
1412 map_char_table (c_function, function, elt, depth + 1, indices);
1413 }
1414 else
1415 {
1416 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
1417
1418 if (CHARSET_DEFINED_P (charset))
1419 {
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);
1427 }
1428 }
1429 }
1430 }
1431
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;
1439 {
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));
1443
1444 map_char_table (NULL, function, char_table, 0, indices);
1445 return Qnil;
1446 }
1447 \f
1448 /* ARGSUSED */
1449 Lisp_Object
1450 nconc2 (s1, s2)
1451 Lisp_Object s1, s2;
1452 {
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 */
1461 }
1462
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;
1469 {
1470 register int argnum;
1471 register Lisp_Object tail, tem, val;
1472
1473 val = Qnil;
1474
1475 for (argnum = 0; argnum < nargs; argnum++)
1476 {
1477 tem = args[argnum];
1478 if (NILP (tem)) continue;
1479
1480 if (NILP (val))
1481 val = tem;
1482
1483 if (argnum + 1 == nargs) break;
1484
1485 if (!CONSP (tem))
1486 tem = wrong_type_argument (Qlistp, tem);
1487
1488 while (CONSP (tem))
1489 {
1490 tail = tem;
1491 tem = Fcdr (tail);
1492 QUIT;
1493 }
1494
1495 tem = args[argnum + 1];
1496 Fsetcdr (tail, tem);
1497 if (NILP (tem))
1498 args[argnum + 1] = tail;
1499 }
1500
1501 return val;
1502 }
1503 \f
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. */
1508
1509 static void
1510 mapcar1 (leni, vals, fn, seq)
1511 int leni;
1512 Lisp_Object *vals;
1513 Lisp_Object fn, seq;
1514 {
1515 register Lisp_Object tail;
1516 Lisp_Object dummy;
1517 register int i;
1518 struct gcpro gcpro1, gcpro2, gcpro3;
1519
1520 /* Don't let vals contain any garbage when GC happens. */
1521 for (i = 0; i < leni; i++)
1522 vals[i] = Qnil;
1523
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 */
1529
1530 if (VECTORP (seq))
1531 {
1532 for (i = 0; i < leni; i++)
1533 {
1534 dummy = XVECTOR (seq)->contents[i];
1535 vals[i] = call1 (fn, dummy);
1536 }
1537 }
1538 else if (STRINGP (seq))
1539 {
1540 for (i = 0; i < leni; i++)
1541 {
1542 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
1543 vals[i] = call1 (fn, dummy);
1544 }
1545 }
1546 else /* Must be a list, since Flength did not get an error */
1547 {
1548 tail = seq;
1549 for (i = 0; i < leni; i++)
1550 {
1551 vals[i] = call1 (fn, Fcar (tail));
1552 tail = Fcdr (tail);
1553 }
1554 }
1555
1556 UNGCPRO;
1557 }
1558
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;
1565 {
1566 Lisp_Object len;
1567 register int leni;
1568 int nargs;
1569 register Lisp_Object *args;
1570 register int i;
1571 struct gcpro gcpro1;
1572
1573 len = Flength (sequence);
1574 leni = XINT (len);
1575 nargs = leni + leni - 1;
1576 if (nargs < 0) return build_string ("");
1577
1578 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
1579
1580 GCPRO1 (separator);
1581 mapcar1 (leni, args, function, sequence);
1582 UNGCPRO;
1583
1584 for (i = leni - 1; i >= 0; i--)
1585 args[i + i] = args[i];
1586
1587 for (i = 1; i < nargs; i += 2)
1588 args[i] = separator;
1589
1590 return Fconcat (nargs, args);
1591 }
1592
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;
1599 {
1600 register Lisp_Object len;
1601 register int leni;
1602 register Lisp_Object *args;
1603
1604 len = Flength (sequence);
1605 leni = XFASTINT (len);
1606 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
1607
1608 mapcar1 (leni, args, function, sequence);
1609
1610 return Flist (leni, args);
1611 }
1612 \f
1613 /* Anything that calls this function must protect from GC! */
1614
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;
1623 {
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;
1630
1631 specbind (Qcursor_in_echo_area, Qt);
1632
1633 map = Fsymbol_value (intern ("query-replace-map"));
1634
1635 CHECK_STRING (prompt, 0);
1636 xprompt = prompt;
1637 GCPRO2 (prompt, xprompt);
1638
1639 while (1)
1640 {
1641
1642
1643 #ifdef HAVE_MENUS
1644 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1645 && have_menus_p ())
1646 {
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;
1656 }
1657 #endif /* HAVE_MENUS */
1658 cursor_in_echo_area = 1;
1659 choose_minibuf_frame ();
1660 message_nolog ("%s(y or n) ", XSTRING (xprompt)->data);
1661
1662 if (minibuffer_auto_raise)
1663 {
1664 Lisp_Object mini_frame;
1665
1666 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
1667
1668 Fraise_frame (mini_frame);
1669 }
1670
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;
1675
1676 key = Fmake_vector (make_number (1), obj);
1677 def = Flookup_key (map, key, Qt);
1678 answer_string = Fsingle_key_description (obj);
1679
1680 if (EQ (def, intern ("skip")))
1681 {
1682 answer = 0;
1683 break;
1684 }
1685 else if (EQ (def, intern ("act")))
1686 {
1687 answer = 1;
1688 break;
1689 }
1690 else if (EQ (def, intern ("recenter")))
1691 {
1692 Frecenter (Qnil);
1693 xprompt = prompt;
1694 continue;
1695 }
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;
1702
1703 QUIT;
1704
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;
1708
1709 Fding (Qnil);
1710 Fdiscard_input ();
1711 if (EQ (xprompt, prompt))
1712 {
1713 args[0] = build_string ("Please answer y or n. ");
1714 args[1] = prompt;
1715 xprompt = Fconcat (2, args);
1716 }
1717 }
1718 UNGCPRO;
1719
1720 if (! noninteractive)
1721 {
1722 cursor_in_echo_area = -1;
1723 message_nolog ("%s(y or n) %c",
1724 XSTRING (xprompt)->data, answer ? 'y' : 'n');
1725 }
1726
1727 unbind_to (count, Qnil);
1728 return answer ? Qt : Qnil;
1729 }
1730 \f
1731 /* This is how C code calls `yes-or-no-p' and allows the user
1732 to redefined it.
1733
1734 Anything that calls this function must protect from GC! */
1735
1736 Lisp_Object
1737 do_yes_or_no_p (prompt)
1738 Lisp_Object prompt;
1739 {
1740 return call1 (intern ("yes-or-no-p"), prompt);
1741 }
1742
1743 /* Anything that calls this function must protect from GC! */
1744
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;
1753 {
1754 register Lisp_Object ans;
1755 Lisp_Object args[2];
1756 struct gcpro gcpro1;
1757 Lisp_Object menu;
1758
1759 CHECK_STRING (prompt, 0);
1760
1761 #ifdef HAVE_MENUS
1762 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1763 && have_menus_p ())
1764 {
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;
1775 }
1776 #endif /* HAVE_MENUS */
1777
1778 args[0] = prompt;
1779 args[1] = build_string ("(yes or no) ");
1780 prompt = Fconcat (2, args);
1781
1782 GCPRO1 (prompt);
1783
1784 while (1)
1785 {
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"))
1789 {
1790 UNGCPRO;
1791 return Qt;
1792 }
1793 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
1794 {
1795 UNGCPRO;
1796 return Qnil;
1797 }
1798
1799 Fding (Qnil);
1800 Fdiscard_input ();
1801 message ("Please answer yes or no.");
1802 Fsleep_for (make_number (2), Qnil);
1803 }
1804 }
1805 \f
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.")
1812 ()
1813 {
1814 double load_ave[3];
1815 int loads = getloadavg (load_ave, 3);
1816 Lisp_Object ret;
1817
1818 if (loads < 0)
1819 error ("load-average not implemented for this operating system");
1820
1821 ret = Qnil;
1822 while (loads > 0)
1823 ret = Fcons (make_number ((int) (load_ave[--loads] * 100.0)), ret);
1824
1825 return ret;
1826 }
1827 \f
1828 Lisp_Object Vfeatures;
1829
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;
1838 {
1839 register Lisp_Object tem;
1840 CHECK_SYMBOL (feature, 0);
1841 tem = Fmemq (feature, Vfeatures);
1842 return (NILP (tem)) ? Qnil : Qt;
1843 }
1844
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;
1849 {
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;
1859 }
1860
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;
1868 {
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))
1874 {
1875 int count = specpdl_ptr - specpdl;
1876
1877 /* Value saved here is to be restored into Vautoload_queue */
1878 record_unwind_protect (un_autoload, Vautoload_queue);
1879 Vautoload_queue = Qt;
1880
1881 Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
1882 Qnil, Qt, Qnil);
1883
1884 tem = Fmemq (feature, Vfeatures);
1885 if (NILP (tem))
1886 error ("Required feature %s was not provided",
1887 XSYMBOL (feature)->name->data );
1888
1889 /* Once loading finishes, don't undo it. */
1890 Vautoload_queue = Qt;
1891 feature = unbind_to (count, feature);
1892 }
1893 return feature;
1894 }
1895 \f
1896 syms_of_fns ()
1897 {
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);
1908
1909 Fset (Qyes_or_no_p_history, Qnil);
1910
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;
1915
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);
1965 }