(copy_sub_char_table): Declare the argument ARG as
[bpt/emacs.git] / 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 Lisp_Object arg;
301 {
302 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
303 int i;
304
305 /* Copy all the contents. */
306 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
307 SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
308 /* Recursively copy any sub char-tables in the ordinary slots. */
309 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
310 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
311 XCHAR_TABLE (copy)->contents[i]
312 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
313
314 return copy;
315 }
316
317
318 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
319 "Return a copy of a list, vector or string.\n\
320 The elements of a list or vector are not copied; they are shared\n\
321 with the original.")
322 (arg)
323 Lisp_Object arg;
324 {
325 if (NILP (arg)) return arg;
326
327 if (CHAR_TABLE_P (arg))
328 {
329 int i;
330 Lisp_Object copy;
331
332 copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
333 /* Copy all the slots, including the extra ones. */
334 bcopy (XVECTOR (arg)->contents, XVECTOR (copy)->contents,
335 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
336 * sizeof (Lisp_Object)));
337
338 /* Recursively copy any sub char tables in the ordinary slots
339 for multibyte characters. */
340 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
341 i < CHAR_TABLE_ORDINARY_SLOTS; i++)
342 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
343 XCHAR_TABLE (copy)->contents[i]
344 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
345
346 return copy;
347 }
348
349 if (BOOL_VECTOR_P (arg))
350 {
351 Lisp_Object val;
352 int size_in_chars
353 = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
354
355 val = Fmake_bool_vector (Flength (arg), Qnil);
356 bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
357 size_in_chars);
358 return val;
359 }
360
361 if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
362 arg = wrong_type_argument (Qsequencep, arg);
363 return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
364 }
365
366 static Lisp_Object
367 concat (nargs, args, target_type, last_special)
368 int nargs;
369 Lisp_Object *args;
370 enum Lisp_Type target_type;
371 int last_special;
372 {
373 Lisp_Object val;
374 Lisp_Object len;
375 register Lisp_Object tail;
376 register Lisp_Object this;
377 int toindex;
378 register int leni;
379 register int argnum;
380 Lisp_Object last_tail;
381 Lisp_Object prev;
382
383 /* In append, the last arg isn't treated like the others */
384 if (last_special && nargs > 0)
385 {
386 nargs--;
387 last_tail = args[nargs];
388 }
389 else
390 last_tail = Qnil;
391
392 for (argnum = 0; argnum < nargs; argnum++)
393 {
394 this = args[argnum];
395 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
396 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
397 {
398 if (INTEGERP (this))
399 args[argnum] = Fnumber_to_string (this);
400 else
401 args[argnum] = wrong_type_argument (Qsequencep, this);
402 }
403 }
404
405 for (argnum = 0, leni = 0; argnum < nargs; argnum++)
406 {
407 this = args[argnum];
408 len = Flength (this);
409 leni += XFASTINT (len);
410 }
411
412 XSETFASTINT (len, leni);
413
414 if (target_type == Lisp_Cons)
415 val = Fmake_list (len, Qnil);
416 else if (target_type == Lisp_Vectorlike)
417 val = Fmake_vector (len, Qnil);
418 else
419 val = Fmake_string (len, len);
420
421 /* In append, if all but last arg are nil, return last arg */
422 if (target_type == Lisp_Cons && EQ (val, Qnil))
423 return last_tail;
424
425 if (CONSP (val))
426 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
427 else
428 toindex = 0;
429
430 prev = Qnil;
431
432 for (argnum = 0; argnum < nargs; argnum++)
433 {
434 Lisp_Object thislen;
435 int thisleni;
436 register unsigned int thisindex = 0;
437
438 this = args[argnum];
439 if (!CONSP (this))
440 thislen = Flength (this), thisleni = XINT (thislen);
441
442 if (STRINGP (this) && STRINGP (val)
443 && ! NULL_INTERVAL_P (XSTRING (this)->intervals))
444 {
445 copy_text_properties (make_number (0), thislen, this,
446 make_number (toindex), val, Qnil);
447 }
448
449 while (1)
450 {
451 register Lisp_Object elt;
452
453 /* Fetch next element of `this' arg into `elt', or break if
454 `this' is exhausted. */
455 if (NILP (this)) break;
456 if (CONSP (this))
457 elt = Fcar (this), this = Fcdr (this);
458 else
459 {
460 if (thisindex >= thisleni) break;
461 if (STRINGP (this))
462 XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
463 else if (BOOL_VECTOR_P (this))
464 {
465 int size_in_chars
466 = ((XBOOL_VECTOR (this)->size + BITS_PER_CHAR - 1)
467 / BITS_PER_CHAR);
468 int byte;
469 byte = XBOOL_VECTOR (val)->data[thisindex / BITS_PER_CHAR];
470 if (byte & (1 << (thisindex % BITS_PER_CHAR)))
471 elt = Qt;
472 else
473 elt = Qnil;
474 }
475 else
476 elt = XVECTOR (this)->contents[thisindex++];
477 }
478
479 /* Store into result */
480 if (toindex < 0)
481 {
482 XCONS (tail)->car = elt;
483 prev = tail;
484 tail = XCONS (tail)->cdr;
485 }
486 else if (VECTORP (val))
487 XVECTOR (val)->contents[toindex++] = elt;
488 else
489 {
490 while (!INTEGERP (elt))
491 elt = wrong_type_argument (Qintegerp, elt);
492 {
493 #ifdef MASSC_REGISTER_BUG
494 /* Even removing all "register"s doesn't disable this bug!
495 Nothing simpler than this seems to work. */
496 unsigned char *p = & XSTRING (val)->data[toindex++];
497 *p = XINT (elt);
498 #else
499 XSTRING (val)->data[toindex++] = XINT (elt);
500 #endif
501 }
502 }
503 }
504 }
505 if (!NILP (prev))
506 XCONS (prev)->cdr = last_tail;
507
508 return val;
509 }
510 \f
511 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
512 "Return a copy of ALIST.\n\
513 This is an alist which represents the same mapping from objects to objects,\n\
514 but does not share the alist structure with ALIST.\n\
515 The objects mapped (cars and cdrs of elements of the alist)\n\
516 are shared, however.\n\
517 Elements of ALIST that are not conses are also shared.")
518 (alist)
519 Lisp_Object alist;
520 {
521 register Lisp_Object tem;
522
523 CHECK_LIST (alist, 0);
524 if (NILP (alist))
525 return alist;
526 alist = concat (1, &alist, Lisp_Cons, 0);
527 for (tem = alist; CONSP (tem); tem = XCONS (tem)->cdr)
528 {
529 register Lisp_Object car;
530 car = XCONS (tem)->car;
531
532 if (CONSP (car))
533 XCONS (tem)->car = Fcons (XCONS (car)->car, XCONS (car)->cdr);
534 }
535 return alist;
536 }
537
538 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
539 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
540 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
541 If FROM or TO is negative, it counts from the end.\n\
542 \n\
543 This function allows vectors as well as strings.")
544 (string, from, to)
545 Lisp_Object string;
546 register Lisp_Object from, to;
547 {
548 Lisp_Object res;
549 int size;
550
551 if (! (STRINGP (string) || VECTORP (string)))
552 wrong_type_argument (Qarrayp, string);
553
554 CHECK_NUMBER (from, 1);
555
556 if (STRINGP (string))
557 size = XSTRING (string)->size;
558 else
559 size = XVECTOR (string)->size;
560
561 if (NILP (to))
562 to = size;
563 else
564 CHECK_NUMBER (to, 2);
565
566 if (XINT (from) < 0)
567 XSETINT (from, XINT (from) + size);
568 if (XINT (to) < 0)
569 XSETINT (to, XINT (to) + size);
570 if (!(0 <= XINT (from) && XINT (from) <= XINT (to)
571 && XINT (to) <= size))
572 args_out_of_range_3 (string, from, to);
573
574 if (STRINGP (string))
575 {
576 res = make_string (XSTRING (string)->data + XINT (from),
577 XINT (to) - XINT (from));
578 copy_text_properties (from, to, string, make_number (0), res, Qnil);
579 }
580 else
581 res = Fvector (XINT (to) - XINT (from),
582 XVECTOR (string)->contents + XINT (from));
583
584 return res;
585 }
586 \f
587 DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
588 "Take cdr N times on LIST, returns the result.")
589 (n, list)
590 Lisp_Object n;
591 register Lisp_Object list;
592 {
593 register int i, num;
594 CHECK_NUMBER (n, 0);
595 num = XINT (n);
596 for (i = 0; i < num && !NILP (list); i++)
597 {
598 QUIT;
599 list = Fcdr (list);
600 }
601 return list;
602 }
603
604 DEFUN ("nth", Fnth, Snth, 2, 2, 0,
605 "Return the Nth element of LIST.\n\
606 N counts from zero. If LIST is not that long, nil is returned.")
607 (n, list)
608 Lisp_Object n, list;
609 {
610 return Fcar (Fnthcdr (n, list));
611 }
612
613 DEFUN ("elt", Felt, Selt, 2, 2, 0,
614 "Return element of SEQUENCE at index N.")
615 (sequence, n)
616 register Lisp_Object sequence, n;
617 {
618 CHECK_NUMBER (n, 0);
619 while (1)
620 {
621 if (CONSP (sequence) || NILP (sequence))
622 return Fcar (Fnthcdr (n, sequence));
623 else if (STRINGP (sequence) || VECTORP (sequence)
624 || BOOL_VECTOR_P (sequence) || CHAR_TABLE_P (sequence))
625 return Faref (sequence, n);
626 else
627 sequence = wrong_type_argument (Qsequencep, sequence);
628 }
629 }
630
631 DEFUN ("member", Fmember, Smember, 2, 2, 0,
632 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
633 The value is actually the tail of LIST whose car is ELT.")
634 (elt, list)
635 register Lisp_Object elt;
636 Lisp_Object list;
637 {
638 register Lisp_Object tail;
639 for (tail = list; !NILP (tail); tail = Fcdr (tail))
640 {
641 register Lisp_Object tem;
642 tem = Fcar (tail);
643 if (! NILP (Fequal (elt, tem)))
644 return tail;
645 QUIT;
646 }
647 return Qnil;
648 }
649
650 DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
651 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
652 The value is actually the tail of LIST whose car is ELT.")
653 (elt, list)
654 register Lisp_Object elt;
655 Lisp_Object list;
656 {
657 register Lisp_Object tail;
658 for (tail = list; !NILP (tail); tail = Fcdr (tail))
659 {
660 register Lisp_Object tem;
661 tem = Fcar (tail);
662 if (EQ (elt, tem)) return tail;
663 QUIT;
664 }
665 return Qnil;
666 }
667
668 DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
669 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
670 The value is actually the element of LIST whose car is KEY.\n\
671 Elements of LIST that are not conses are ignored.")
672 (key, list)
673 register Lisp_Object key;
674 Lisp_Object list;
675 {
676 register Lisp_Object tail;
677 for (tail = list; !NILP (tail); tail = Fcdr (tail))
678 {
679 register Lisp_Object elt, tem;
680 elt = Fcar (tail);
681 if (!CONSP (elt)) continue;
682 tem = Fcar (elt);
683 if (EQ (key, tem)) return elt;
684 QUIT;
685 }
686 return Qnil;
687 }
688
689 /* Like Fassq but never report an error and do not allow quits.
690 Use only on lists known never to be circular. */
691
692 Lisp_Object
693 assq_no_quit (key, list)
694 register Lisp_Object key;
695 Lisp_Object list;
696 {
697 register Lisp_Object tail;
698 for (tail = list; CONSP (tail); tail = Fcdr (tail))
699 {
700 register Lisp_Object elt, tem;
701 elt = Fcar (tail);
702 if (!CONSP (elt)) continue;
703 tem = Fcar (elt);
704 if (EQ (key, tem)) return elt;
705 }
706 return Qnil;
707 }
708
709 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
710 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
711 The value is actually the element of LIST whose car equals KEY.")
712 (key, list)
713 register Lisp_Object key;
714 Lisp_Object list;
715 {
716 register Lisp_Object tail;
717 for (tail = list; !NILP (tail); tail = Fcdr (tail))
718 {
719 register Lisp_Object elt, tem;
720 elt = Fcar (tail);
721 if (!CONSP (elt)) continue;
722 tem = Fequal (Fcar (elt), key);
723 if (!NILP (tem)) return elt;
724 QUIT;
725 }
726 return Qnil;
727 }
728
729 DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
730 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
731 The value is actually the element of LIST whose cdr is ELT.")
732 (key, list)
733 register Lisp_Object key;
734 Lisp_Object list;
735 {
736 register Lisp_Object tail;
737 for (tail = list; !NILP (tail); tail = Fcdr (tail))
738 {
739 register Lisp_Object elt, tem;
740 elt = Fcar (tail);
741 if (!CONSP (elt)) continue;
742 tem = Fcdr (elt);
743 if (EQ (key, tem)) return elt;
744 QUIT;
745 }
746 return Qnil;
747 }
748
749 DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
750 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
751 The value is actually the element of LIST whose cdr equals KEY.")
752 (key, list)
753 register Lisp_Object key;
754 Lisp_Object list;
755 {
756 register Lisp_Object tail;
757 for (tail = list; !NILP (tail); tail = Fcdr (tail))
758 {
759 register Lisp_Object elt, tem;
760 elt = Fcar (tail);
761 if (!CONSP (elt)) continue;
762 tem = Fequal (Fcdr (elt), key);
763 if (!NILP (tem)) return elt;
764 QUIT;
765 }
766 return Qnil;
767 }
768 \f
769 DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
770 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
771 The modified LIST is returned. Comparison is done with `eq'.\n\
772 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
773 therefore, write `(setq foo (delq element foo))'\n\
774 to be sure of changing the value of `foo'.")
775 (elt, list)
776 register Lisp_Object elt;
777 Lisp_Object list;
778 {
779 register Lisp_Object tail, prev;
780 register Lisp_Object tem;
781
782 tail = list;
783 prev = Qnil;
784 while (!NILP (tail))
785 {
786 tem = Fcar (tail);
787 if (EQ (elt, tem))
788 {
789 if (NILP (prev))
790 list = Fcdr (tail);
791 else
792 Fsetcdr (prev, Fcdr (tail));
793 }
794 else
795 prev = tail;
796 tail = Fcdr (tail);
797 QUIT;
798 }
799 return list;
800 }
801
802 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
803 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
804 The modified LIST is returned. Comparison is done with `equal'.\n\
805 If the first member of LIST is ELT, deleting it is not a side effect;\n\
806 it is simply using a different list.\n\
807 Therefore, write `(setq foo (delete element foo))'\n\
808 to be sure of changing the value of `foo'.")
809 (elt, list)
810 register Lisp_Object elt;
811 Lisp_Object list;
812 {
813 register Lisp_Object tail, prev;
814 register Lisp_Object tem;
815
816 tail = list;
817 prev = Qnil;
818 while (!NILP (tail))
819 {
820 tem = Fcar (tail);
821 if (! NILP (Fequal (elt, tem)))
822 {
823 if (NILP (prev))
824 list = Fcdr (tail);
825 else
826 Fsetcdr (prev, Fcdr (tail));
827 }
828 else
829 prev = tail;
830 tail = Fcdr (tail);
831 QUIT;
832 }
833 return list;
834 }
835
836 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
837 "Reverse LIST by modifying cdr pointers.\n\
838 Returns the beginning of the reversed list.")
839 (list)
840 Lisp_Object list;
841 {
842 register Lisp_Object prev, tail, next;
843
844 if (NILP (list)) return list;
845 prev = Qnil;
846 tail = list;
847 while (!NILP (tail))
848 {
849 QUIT;
850 next = Fcdr (tail);
851 Fsetcdr (tail, prev);
852 prev = tail;
853 tail = next;
854 }
855 return prev;
856 }
857
858 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
859 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
860 See also the function `nreverse', which is used more often.")
861 (list)
862 Lisp_Object list;
863 {
864 Lisp_Object length;
865 register Lisp_Object *vec;
866 register Lisp_Object tail;
867 register int i;
868
869 length = Flength (list);
870 vec = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object));
871 for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail))
872 vec[i] = Fcar (tail);
873
874 return Flist (XINT (length), vec);
875 }
876 \f
877 Lisp_Object merge ();
878
879 DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
880 "Sort LIST, stably, comparing elements using PREDICATE.\n\
881 Returns the sorted list. LIST is modified by side effects.\n\
882 PREDICATE is called with two elements of LIST, and should return T\n\
883 if the first element is \"less\" than the second.")
884 (list, predicate)
885 Lisp_Object list, predicate;
886 {
887 Lisp_Object front, back;
888 register Lisp_Object len, tem;
889 struct gcpro gcpro1, gcpro2;
890 register int length;
891
892 front = list;
893 len = Flength (list);
894 length = XINT (len);
895 if (length < 2)
896 return list;
897
898 XSETINT (len, (length / 2) - 1);
899 tem = Fnthcdr (len, list);
900 back = Fcdr (tem);
901 Fsetcdr (tem, Qnil);
902
903 GCPRO2 (front, back);
904 front = Fsort (front, predicate);
905 back = Fsort (back, predicate);
906 UNGCPRO;
907 return merge (front, back, predicate);
908 }
909
910 Lisp_Object
911 merge (org_l1, org_l2, pred)
912 Lisp_Object org_l1, org_l2;
913 Lisp_Object pred;
914 {
915 Lisp_Object value;
916 register Lisp_Object tail;
917 Lisp_Object tem;
918 register Lisp_Object l1, l2;
919 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
920
921 l1 = org_l1;
922 l2 = org_l2;
923 tail = Qnil;
924 value = Qnil;
925
926 /* It is sufficient to protect org_l1 and org_l2.
927 When l1 and l2 are updated, we copy the new values
928 back into the org_ vars. */
929 GCPRO4 (org_l1, org_l2, pred, value);
930
931 while (1)
932 {
933 if (NILP (l1))
934 {
935 UNGCPRO;
936 if (NILP (tail))
937 return l2;
938 Fsetcdr (tail, l2);
939 return value;
940 }
941 if (NILP (l2))
942 {
943 UNGCPRO;
944 if (NILP (tail))
945 return l1;
946 Fsetcdr (tail, l1);
947 return value;
948 }
949 tem = call2 (pred, Fcar (l2), Fcar (l1));
950 if (NILP (tem))
951 {
952 tem = l1;
953 l1 = Fcdr (l1);
954 org_l1 = l1;
955 }
956 else
957 {
958 tem = l2;
959 l2 = Fcdr (l2);
960 org_l2 = l2;
961 }
962 if (NILP (tail))
963 value = tem;
964 else
965 Fsetcdr (tail, tem);
966 tail = tem;
967 }
968 }
969 \f
970
971 DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
972 "Extract a value from a property list.\n\
973 PLIST is a property list, which is a list of the form\n\
974 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
975 corresponding to the given PROP, or nil if PROP is not\n\
976 one of the properties on the list.")
977 (plist, prop)
978 Lisp_Object plist;
979 register Lisp_Object prop;
980 {
981 register Lisp_Object tail;
982 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
983 {
984 register Lisp_Object tem;
985 tem = Fcar (tail);
986 if (EQ (prop, tem))
987 return Fcar (Fcdr (tail));
988 }
989 return Qnil;
990 }
991
992 DEFUN ("get", Fget, Sget, 2, 2, 0,
993 "Return the value of SYMBOL's PROPNAME property.\n\
994 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
995 (symbol, propname)
996 Lisp_Object symbol, propname;
997 {
998 CHECK_SYMBOL (symbol, 0);
999 return Fplist_get (XSYMBOL (symbol)->plist, propname);
1000 }
1001
1002 DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
1003 "Change value in PLIST of PROP to VAL.\n\
1004 PLIST is a property list, which is a list of the form\n\
1005 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
1006 If PROP is already a property on the list, its value is set to VAL,\n\
1007 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
1008 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
1009 The PLIST is modified by side effects.")
1010 (plist, prop, val)
1011 Lisp_Object plist;
1012 register Lisp_Object prop;
1013 Lisp_Object val;
1014 {
1015 register Lisp_Object tail, prev;
1016 Lisp_Object newcell;
1017 prev = Qnil;
1018 for (tail = plist; CONSP (tail) && CONSP (XCONS (tail)->cdr);
1019 tail = XCONS (XCONS (tail)->cdr)->cdr)
1020 {
1021 if (EQ (prop, XCONS (tail)->car))
1022 {
1023 Fsetcar (XCONS (tail)->cdr, val);
1024 return plist;
1025 }
1026 prev = tail;
1027 }
1028 newcell = Fcons (prop, Fcons (val, Qnil));
1029 if (NILP (prev))
1030 return newcell;
1031 else
1032 Fsetcdr (XCONS (prev)->cdr, newcell);
1033 return plist;
1034 }
1035
1036 DEFUN ("put", Fput, Sput, 3, 3, 0,
1037 "Store SYMBOL's PROPNAME property with value VALUE.\n\
1038 It can be retrieved with `(get SYMBOL PROPNAME)'.")
1039 (symbol, propname, value)
1040 Lisp_Object symbol, propname, value;
1041 {
1042 CHECK_SYMBOL (symbol, 0);
1043 XSYMBOL (symbol)->plist
1044 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1045 return value;
1046 }
1047
1048 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
1049 "T if two Lisp objects have similar structure and contents.\n\
1050 They must have the same data type.\n\
1051 Conses are compared by comparing the cars and the cdrs.\n\
1052 Vectors and strings are compared element by element.\n\
1053 Numbers are compared by value, but integers cannot equal floats.\n\
1054 (Use `=' if you want integers and floats to be able to be equal.)\n\
1055 Symbols must match exactly.")
1056 (o1, o2)
1057 register Lisp_Object o1, o2;
1058 {
1059 return internal_equal (o1, o2, 0) ? Qt : Qnil;
1060 }
1061
1062 static int
1063 internal_equal (o1, o2, depth)
1064 register Lisp_Object o1, o2;
1065 int depth;
1066 {
1067 if (depth > 200)
1068 error ("Stack overflow in equal");
1069
1070 tail_recurse:
1071 QUIT;
1072 if (EQ (o1, o2))
1073 return 1;
1074 if (XTYPE (o1) != XTYPE (o2))
1075 return 0;
1076
1077 switch (XTYPE (o1))
1078 {
1079 #ifdef LISP_FLOAT_TYPE
1080 case Lisp_Float:
1081 return (extract_float (o1) == extract_float (o2));
1082 #endif
1083
1084 case Lisp_Cons:
1085 if (!internal_equal (XCONS (o1)->car, XCONS (o2)->car, depth + 1))
1086 return 0;
1087 o1 = XCONS (o1)->cdr;
1088 o2 = XCONS (o2)->cdr;
1089 goto tail_recurse;
1090
1091 case Lisp_Misc:
1092 if (XMISCTYPE (o1) != XMISCTYPE (o2))
1093 return 0;
1094 if (OVERLAYP (o1))
1095 {
1096 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o1),
1097 depth + 1)
1098 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o1),
1099 depth + 1))
1100 return 0;
1101 o1 = XOVERLAY (o1)->plist;
1102 o2 = XOVERLAY (o2)->plist;
1103 goto tail_recurse;
1104 }
1105 if (MARKERP (o1))
1106 {
1107 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
1108 && (XMARKER (o1)->buffer == 0
1109 || XMARKER (o1)->bufpos == XMARKER (o2)->bufpos));
1110 }
1111 break;
1112
1113 case Lisp_Vectorlike:
1114 {
1115 register int i, size;
1116 size = XVECTOR (o1)->size;
1117 /* Pseudovectors have the type encoded in the size field, so this test
1118 actually checks that the objects have the same type as well as the
1119 same size. */
1120 if (XVECTOR (o2)->size != size)
1121 return 0;
1122 /* Boolvectors are compared much like strings. */
1123 if (BOOL_VECTOR_P (o1))
1124 {
1125 int size_in_chars
1126 = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1127
1128 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
1129 return 0;
1130 if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
1131 size_in_chars))
1132 return 0;
1133 return 1;
1134 }
1135
1136 /* Aside from them, only true vectors, char-tables, and compiled
1137 functions are sensible to compare, so eliminate the others now. */
1138 if (size & PSEUDOVECTOR_FLAG)
1139 {
1140 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
1141 return 0;
1142 size &= PSEUDOVECTOR_SIZE_MASK;
1143 }
1144 for (i = 0; i < size; i++)
1145 {
1146 Lisp_Object v1, v2;
1147 v1 = XVECTOR (o1)->contents [i];
1148 v2 = XVECTOR (o2)->contents [i];
1149 if (!internal_equal (v1, v2, depth + 1))
1150 return 0;
1151 }
1152 return 1;
1153 }
1154 break;
1155
1156 case Lisp_String:
1157 if (XSTRING (o1)->size != XSTRING (o2)->size)
1158 return 0;
1159 if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
1160 XSTRING (o1)->size))
1161 return 0;
1162 #ifdef USE_TEXT_PROPERTIES
1163 /* If the strings have intervals, verify they match;
1164 if not, they are unequal. */
1165 if ((XSTRING (o1)->intervals != 0 || XSTRING (o2)->intervals != 0)
1166 && ! compare_string_intervals (o1, o2))
1167 return 0;
1168 #endif
1169 return 1;
1170 }
1171 return 0;
1172 }
1173 \f
1174 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
1175 "Store each element of ARRAY with ITEM.\n\
1176 ARRAY is a vector, string, char-table, or bool-vector.")
1177 (array, item)
1178 Lisp_Object array, item;
1179 {
1180 register int size, index, charval;
1181 retry:
1182 if (VECTORP (array))
1183 {
1184 register Lisp_Object *p = XVECTOR (array)->contents;
1185 size = XVECTOR (array)->size;
1186 for (index = 0; index < size; index++)
1187 p[index] = item;
1188 }
1189 else if (CHAR_TABLE_P (array))
1190 {
1191 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
1192 size = CHAR_TABLE_ORDINARY_SLOTS;
1193 for (index = 0; index < size; index++)
1194 p[index] = item;
1195 XCHAR_TABLE (array)->defalt = Qnil;
1196 }
1197 else if (STRINGP (array))
1198 {
1199 register unsigned char *p = XSTRING (array)->data;
1200 CHECK_NUMBER (item, 1);
1201 charval = XINT (item);
1202 size = XSTRING (array)->size;
1203 for (index = 0; index < size; index++)
1204 p[index] = charval;
1205 }
1206 else if (BOOL_VECTOR_P (array))
1207 {
1208 register unsigned char *p = XBOOL_VECTOR (array)->data;
1209 int size_in_chars
1210 = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1211
1212 charval = (! NILP (item) ? -1 : 0);
1213 for (index = 0; index < size_in_chars; index++)
1214 p[index] = charval;
1215 }
1216 else
1217 {
1218 array = wrong_type_argument (Qarrayp, array);
1219 goto retry;
1220 }
1221 return array;
1222 }
1223
1224 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
1225 1, 1, 0,
1226 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1227 (char_table)
1228 Lisp_Object char_table;
1229 {
1230 CHECK_CHAR_TABLE (char_table, 0);
1231
1232 return XCHAR_TABLE (char_table)->purpose;
1233 }
1234
1235 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
1236 1, 1, 0,
1237 "Return the parent char-table of CHAR-TABLE.\n\
1238 The value is either nil or another char-table.\n\
1239 If CHAR-TABLE holds nil for a given character,\n\
1240 then the actual applicable value is inherited from the parent char-table\n\
1241 \(or from its parents, if necessary).")
1242 (char_table)
1243 Lisp_Object char_table;
1244 {
1245 CHECK_CHAR_TABLE (char_table, 0);
1246
1247 return XCHAR_TABLE (char_table)->parent;
1248 }
1249
1250 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
1251 2, 2, 0,
1252 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1253 PARENT must be either nil or another char-table.")
1254 (char_table, parent)
1255 Lisp_Object char_table, parent;
1256 {
1257 Lisp_Object temp;
1258
1259 CHECK_CHAR_TABLE (char_table, 0);
1260
1261 if (!NILP (parent))
1262 {
1263 CHECK_CHAR_TABLE (parent, 0);
1264
1265 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
1266 if (EQ (temp, char_table))
1267 error ("Attempt to make a chartable be its own parent");
1268 }
1269
1270 XCHAR_TABLE (char_table)->parent = parent;
1271
1272 return parent;
1273 }
1274
1275 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
1276 2, 2, 0,
1277 "Return the value of CHAR-TABLE's extra-slot number N.")
1278 (char_table, n)
1279 Lisp_Object char_table, n;
1280 {
1281 CHECK_CHAR_TABLE (char_table, 1);
1282 CHECK_NUMBER (n, 2);
1283 if (XINT (n) < 0
1284 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1285 args_out_of_range (char_table, n);
1286
1287 return XCHAR_TABLE (char_table)->extras[XINT (n)];
1288 }
1289
1290 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
1291 Sset_char_table_extra_slot,
1292 3, 3, 0,
1293 "Set CHAR-TABLE's extra-slot number N to VALUE.")
1294 (char_table, n, value)
1295 Lisp_Object char_table, n, value;
1296 {
1297 CHECK_CHAR_TABLE (char_table, 1);
1298 CHECK_NUMBER (n, 2);
1299 if (XINT (n) < 0
1300 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1301 args_out_of_range (char_table, n);
1302
1303 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
1304 }
1305
1306 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
1307 2, 2, 0,
1308 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
1309 RANGE should be t (for all characters), nil (for the default value)\n\
1310 a vector which identifies a character set or a row of a character set,\n\
1311 or a character code.")
1312 (char_table, range)
1313 Lisp_Object char_table, range;
1314 {
1315 int i;
1316
1317 CHECK_CHAR_TABLE (char_table, 0);
1318
1319 if (EQ (range, Qnil))
1320 return XCHAR_TABLE (char_table)->defalt;
1321 else if (INTEGERP (range))
1322 return Faref (char_table, range);
1323 else if (VECTORP (range))
1324 {
1325 int size = XVECTOR (range)->size;
1326 Lisp_Object *val = XVECTOR (range)->contents;
1327 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1328 size <= 1 ? Qnil : val[1],
1329 size <= 2 ? Qnil : val[2]);
1330 return Faref (char_table, ch);
1331 }
1332 else
1333 error ("Invalid RANGE argument to `char-table-range'");
1334 }
1335
1336 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
1337 3, 3, 0,
1338 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
1339 RANGE should be t (for all characters), nil (for the default value)\n\
1340 a vector which identifies a character set or a row of a character set,\n\
1341 or a character code.")
1342 (char_table, range, value)
1343 Lisp_Object char_table, range, value;
1344 {
1345 int i;
1346
1347 CHECK_CHAR_TABLE (char_table, 0);
1348
1349 if (EQ (range, Qt))
1350 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1351 XCHAR_TABLE (char_table)->contents[i] = value;
1352 else if (EQ (range, Qnil))
1353 XCHAR_TABLE (char_table)->defalt = value;
1354 else if (INTEGERP (range))
1355 Faset (char_table, range, value);
1356 else if (VECTORP (range))
1357 {
1358 int size = XVECTOR (range)->size;
1359 Lisp_Object *val = XVECTOR (range)->contents;
1360 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1361 size <= 1 ? Qnil : val[1],
1362 size <= 2 ? Qnil : val[2]);
1363 return Faset (char_table, ch, value);
1364 }
1365 else
1366 error ("Invalid RANGE argument to `set-char-table-range'");
1367
1368 return value;
1369 }
1370
1371 DEFUN ("set-char-table-default", Fset_char_table_default,
1372 Sset_char_table_default, 3, 3, 0,
1373 "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
1374 The generic character specifies the group of characters.\n\
1375 See also the documentation of make-char.")
1376 (char_table, ch, value)
1377 Lisp_Object char_table, ch, value;
1378 {
1379 int c, i, charset, code1, code2;
1380 Lisp_Object temp;
1381
1382 CHECK_CHAR_TABLE (char_table, 0);
1383 CHECK_NUMBER (ch, 1);
1384
1385 c = XINT (ch);
1386 SPLIT_NON_ASCII_CHAR (c, charset, code1, code2);
1387 if (! CHARSET_DEFINED_P (charset))
1388 error ("Invalid character: %d", c);
1389
1390 if (charset == CHARSET_ASCII)
1391 return (XCHAR_TABLE (char_table)->defalt = value);
1392
1393 /* Even if C is not a generic char, we had better behave as if a
1394 generic char is specified. */
1395 if (CHARSET_DIMENSION (charset) == 1)
1396 code1 = 0;
1397 temp = XCHAR_TABLE (char_table)->contents[charset + 128];
1398 if (!code1)
1399 {
1400 if (SUB_CHAR_TABLE_P (temp))
1401 XCHAR_TABLE (temp)->defalt = value;
1402 else
1403 XCHAR_TABLE (char_table)->contents[charset + 128] = value;
1404 return value;
1405 }
1406 char_table = temp;
1407 if (! SUB_CHAR_TABLE_P (char_table))
1408 char_table = (XCHAR_TABLE (char_table)->contents[charset + 128]
1409 = make_sub_char_table (temp));
1410 temp = XCHAR_TABLE (char_table)->contents[code1];
1411 if (SUB_CHAR_TABLE_P (temp))
1412 XCHAR_TABLE (temp)->defalt = value;
1413 else
1414 XCHAR_TABLE (char_table)->contents[code1] = value;
1415 return value;
1416 }
1417
1418 \f
1419 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
1420 character or group of characters that share a value.
1421 DEPTH is the current depth in the originally specified
1422 chartable, and INDICES contains the vector indices
1423 for the levels our callers have descended.
1424
1425 ARG is passed to C_FUNCTION when that is called. */
1426
1427 void
1428 map_char_table (c_function, function, subtable, arg, depth, indices)
1429 Lisp_Object (*c_function) (), function, subtable, arg, *indices;
1430 int depth;
1431 {
1432 int i, to;
1433
1434 if (depth == 0)
1435 {
1436 /* At first, handle ASCII and 8-bit European characters. */
1437 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
1438 {
1439 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
1440 if (c_function)
1441 (*c_function) (arg, make_number (i), elt);
1442 else
1443 call2 (function, make_number (i), elt);
1444 }
1445 to = CHAR_TABLE_ORDINARY_SLOTS;
1446 }
1447 else
1448 {
1449 i = 32;
1450 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1451 }
1452
1453 for (i; i < to; i++)
1454 {
1455 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
1456
1457 indices[depth] = i;
1458
1459 if (SUB_CHAR_TABLE_P (elt))
1460 {
1461 if (depth >= 3)
1462 error ("Too deep char table");
1463 map_char_table (c_function, function, elt, arg,
1464 depth + 1, indices);
1465 }
1466 else
1467 {
1468 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
1469
1470 if (CHARSET_DEFINED_P (charset))
1471 {
1472 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
1473 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
1474 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
1475 if (c_function)
1476 (*c_function) (arg, make_number (c), elt);
1477 else
1478 call2 (function, make_number (c), elt);
1479 }
1480 }
1481 }
1482 }
1483
1484 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
1485 2, 2, 0,
1486 "Call FUNCTION for each range of like characters in CHAR-TABLE.\n\
1487 FUNCTION is called with two arguments--a key and a value.\n\
1488 The key is always a possible RANGE argument to `set-char-table-range'.")
1489 (function, char_table)
1490 Lisp_Object function, char_table;
1491 {
1492 Lisp_Object keyvec;
1493 /* The depth of char table is at most 3. */
1494 Lisp_Object *indices = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
1495
1496 map_char_table (NULL, function, char_table, char_table, 0, indices);
1497 return Qnil;
1498 }
1499 \f
1500 /* ARGSUSED */
1501 Lisp_Object
1502 nconc2 (s1, s2)
1503 Lisp_Object s1, s2;
1504 {
1505 #ifdef NO_ARG_ARRAY
1506 Lisp_Object args[2];
1507 args[0] = s1;
1508 args[1] = s2;
1509 return Fnconc (2, args);
1510 #else
1511 return Fnconc (2, &s1);
1512 #endif /* NO_ARG_ARRAY */
1513 }
1514
1515 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
1516 "Concatenate any number of lists by altering them.\n\
1517 Only the last argument is not altered, and need not be a list.")
1518 (nargs, args)
1519 int nargs;
1520 Lisp_Object *args;
1521 {
1522 register int argnum;
1523 register Lisp_Object tail, tem, val;
1524
1525 val = Qnil;
1526
1527 for (argnum = 0; argnum < nargs; argnum++)
1528 {
1529 tem = args[argnum];
1530 if (NILP (tem)) continue;
1531
1532 if (NILP (val))
1533 val = tem;
1534
1535 if (argnum + 1 == nargs) break;
1536
1537 if (!CONSP (tem))
1538 tem = wrong_type_argument (Qlistp, tem);
1539
1540 while (CONSP (tem))
1541 {
1542 tail = tem;
1543 tem = Fcdr (tail);
1544 QUIT;
1545 }
1546
1547 tem = args[argnum + 1];
1548 Fsetcdr (tail, tem);
1549 if (NILP (tem))
1550 args[argnum + 1] = tail;
1551 }
1552
1553 return val;
1554 }
1555 \f
1556 /* This is the guts of all mapping functions.
1557 Apply fn to each element of seq, one by one,
1558 storing the results into elements of vals, a C vector of Lisp_Objects.
1559 leni is the length of vals, which should also be the length of seq. */
1560
1561 static void
1562 mapcar1 (leni, vals, fn, seq)
1563 int leni;
1564 Lisp_Object *vals;
1565 Lisp_Object fn, seq;
1566 {
1567 register Lisp_Object tail;
1568 Lisp_Object dummy;
1569 register int i;
1570 struct gcpro gcpro1, gcpro2, gcpro3;
1571
1572 /* Don't let vals contain any garbage when GC happens. */
1573 for (i = 0; i < leni; i++)
1574 vals[i] = Qnil;
1575
1576 GCPRO3 (dummy, fn, seq);
1577 gcpro1.var = vals;
1578 gcpro1.nvars = leni;
1579 /* We need not explicitly protect `tail' because it is used only on lists, and
1580 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
1581
1582 if (VECTORP (seq))
1583 {
1584 for (i = 0; i < leni; i++)
1585 {
1586 dummy = XVECTOR (seq)->contents[i];
1587 vals[i] = call1 (fn, dummy);
1588 }
1589 }
1590 else if (STRINGP (seq))
1591 {
1592 for (i = 0; i < leni; i++)
1593 {
1594 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
1595 vals[i] = call1 (fn, dummy);
1596 }
1597 }
1598 else /* Must be a list, since Flength did not get an error */
1599 {
1600 tail = seq;
1601 for (i = 0; i < leni; i++)
1602 {
1603 vals[i] = call1 (fn, Fcar (tail));
1604 tail = Fcdr (tail);
1605 }
1606 }
1607
1608 UNGCPRO;
1609 }
1610
1611 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
1612 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
1613 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
1614 SEPARATOR results in spaces between the values returned by FUNCTION.")
1615 (function, sequence, separator)
1616 Lisp_Object function, sequence, separator;
1617 {
1618 Lisp_Object len;
1619 register int leni;
1620 int nargs;
1621 register Lisp_Object *args;
1622 register int i;
1623 struct gcpro gcpro1;
1624
1625 len = Flength (sequence);
1626 leni = XINT (len);
1627 nargs = leni + leni - 1;
1628 if (nargs < 0) return build_string ("");
1629
1630 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
1631
1632 GCPRO1 (separator);
1633 mapcar1 (leni, args, function, sequence);
1634 UNGCPRO;
1635
1636 for (i = leni - 1; i >= 0; i--)
1637 args[i + i] = args[i];
1638
1639 for (i = 1; i < nargs; i += 2)
1640 args[i] = separator;
1641
1642 return Fconcat (nargs, args);
1643 }
1644
1645 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
1646 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
1647 The result is a list just as long as SEQUENCE.\n\
1648 SEQUENCE may be a list, a vector or a string.")
1649 (function, sequence)
1650 Lisp_Object function, sequence;
1651 {
1652 register Lisp_Object len;
1653 register int leni;
1654 register Lisp_Object *args;
1655
1656 len = Flength (sequence);
1657 leni = XFASTINT (len);
1658 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
1659
1660 mapcar1 (leni, args, function, sequence);
1661
1662 return Flist (leni, args);
1663 }
1664 \f
1665 /* Anything that calls this function must protect from GC! */
1666
1667 DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
1668 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
1669 Takes one argument, which is the string to display to ask the question.\n\
1670 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
1671 No confirmation of the answer is requested; a single character is enough.\n\
1672 Also accepts Space to mean yes, or Delete to mean no.")
1673 (prompt)
1674 Lisp_Object prompt;
1675 {
1676 register Lisp_Object obj, key, def, answer_string, map;
1677 register int answer;
1678 Lisp_Object xprompt;
1679 Lisp_Object args[2];
1680 struct gcpro gcpro1, gcpro2;
1681 int count = specpdl_ptr - specpdl;
1682
1683 specbind (Qcursor_in_echo_area, Qt);
1684
1685 map = Fsymbol_value (intern ("query-replace-map"));
1686
1687 CHECK_STRING (prompt, 0);
1688 xprompt = prompt;
1689 GCPRO2 (prompt, xprompt);
1690
1691 while (1)
1692 {
1693
1694
1695 #ifdef HAVE_MENUS
1696 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1697 && have_menus_p ())
1698 {
1699 Lisp_Object pane, menu;
1700 redisplay_preserve_echo_area ();
1701 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1702 Fcons (Fcons (build_string ("No"), Qnil),
1703 Qnil));
1704 menu = Fcons (prompt, pane);
1705 obj = Fx_popup_dialog (Qt, menu);
1706 answer = !NILP (obj);
1707 break;
1708 }
1709 #endif /* HAVE_MENUS */
1710 cursor_in_echo_area = 1;
1711 choose_minibuf_frame ();
1712 message_nolog ("%s(y or n) ", XSTRING (xprompt)->data);
1713
1714 if (minibuffer_auto_raise)
1715 {
1716 Lisp_Object mini_frame;
1717
1718 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
1719
1720 Fraise_frame (mini_frame);
1721 }
1722
1723 obj = read_filtered_event (1, 0, 0);
1724 cursor_in_echo_area = 0;
1725 /* If we need to quit, quit with cursor_in_echo_area = 0. */
1726 QUIT;
1727
1728 key = Fmake_vector (make_number (1), obj);
1729 def = Flookup_key (map, key, Qt);
1730 answer_string = Fsingle_key_description (obj);
1731
1732 if (EQ (def, intern ("skip")))
1733 {
1734 answer = 0;
1735 break;
1736 }
1737 else if (EQ (def, intern ("act")))
1738 {
1739 answer = 1;
1740 break;
1741 }
1742 else if (EQ (def, intern ("recenter")))
1743 {
1744 Frecenter (Qnil);
1745 xprompt = prompt;
1746 continue;
1747 }
1748 else if (EQ (def, intern ("quit")))
1749 Vquit_flag = Qt;
1750 /* We want to exit this command for exit-prefix,
1751 and this is the only way to do it. */
1752 else if (EQ (def, intern ("exit-prefix")))
1753 Vquit_flag = Qt;
1754
1755 QUIT;
1756
1757 /* If we don't clear this, then the next call to read_char will
1758 return quit_char again, and we'll enter an infinite loop. */
1759 Vquit_flag = Qnil;
1760
1761 Fding (Qnil);
1762 Fdiscard_input ();
1763 if (EQ (xprompt, prompt))
1764 {
1765 args[0] = build_string ("Please answer y or n. ");
1766 args[1] = prompt;
1767 xprompt = Fconcat (2, args);
1768 }
1769 }
1770 UNGCPRO;
1771
1772 if (! noninteractive)
1773 {
1774 cursor_in_echo_area = -1;
1775 message_nolog ("%s(y or n) %c",
1776 XSTRING (xprompt)->data, answer ? 'y' : 'n');
1777 }
1778
1779 unbind_to (count, Qnil);
1780 return answer ? Qt : Qnil;
1781 }
1782 \f
1783 /* This is how C code calls `yes-or-no-p' and allows the user
1784 to redefined it.
1785
1786 Anything that calls this function must protect from GC! */
1787
1788 Lisp_Object
1789 do_yes_or_no_p (prompt)
1790 Lisp_Object prompt;
1791 {
1792 return call1 (intern ("yes-or-no-p"), prompt);
1793 }
1794
1795 /* Anything that calls this function must protect from GC! */
1796
1797 DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
1798 "Ask user a yes-or-no question. Return t if answer is yes.\n\
1799 Takes one argument, which is the string to display to ask the question.\n\
1800 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
1801 The user must confirm the answer with RET,\n\
1802 and can edit it until it has been confirmed.")
1803 (prompt)
1804 Lisp_Object prompt;
1805 {
1806 register Lisp_Object ans;
1807 Lisp_Object args[2];
1808 struct gcpro gcpro1;
1809 Lisp_Object menu;
1810
1811 CHECK_STRING (prompt, 0);
1812
1813 #ifdef HAVE_MENUS
1814 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1815 && have_menus_p ())
1816 {
1817 Lisp_Object pane, menu, obj;
1818 redisplay_preserve_echo_area ();
1819 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1820 Fcons (Fcons (build_string ("No"), Qnil),
1821 Qnil));
1822 GCPRO1 (pane);
1823 menu = Fcons (prompt, pane);
1824 obj = Fx_popup_dialog (Qt, menu);
1825 UNGCPRO;
1826 return obj;
1827 }
1828 #endif /* HAVE_MENUS */
1829
1830 args[0] = prompt;
1831 args[1] = build_string ("(yes or no) ");
1832 prompt = Fconcat (2, args);
1833
1834 GCPRO1 (prompt);
1835
1836 while (1)
1837 {
1838 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
1839 Qyes_or_no_p_history, Qnil));
1840 if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
1841 {
1842 UNGCPRO;
1843 return Qt;
1844 }
1845 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
1846 {
1847 UNGCPRO;
1848 return Qnil;
1849 }
1850
1851 Fding (Qnil);
1852 Fdiscard_input ();
1853 message ("Please answer yes or no.");
1854 Fsleep_for (make_number (2), Qnil);
1855 }
1856 }
1857 \f
1858 DEFUN ("load-average", Fload_average, Sload_average, 0, 0, 0,
1859 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
1860 Each of the three load averages is multiplied by 100,\n\
1861 then converted to integer.\n\
1862 If the 5-minute or 15-minute load averages are not available, return a\n\
1863 shortened list, containing only those averages which are available.")
1864 ()
1865 {
1866 double load_ave[3];
1867 int loads = getloadavg (load_ave, 3);
1868 Lisp_Object ret;
1869
1870 if (loads < 0)
1871 error ("load-average not implemented for this operating system");
1872
1873 ret = Qnil;
1874 while (loads > 0)
1875 ret = Fcons (make_number ((int) (load_ave[--loads] * 100.0)), ret);
1876
1877 return ret;
1878 }
1879 \f
1880 Lisp_Object Vfeatures;
1881
1882 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
1883 "Returns t if FEATURE is present in this Emacs.\n\
1884 Use this to conditionalize execution of lisp code based on the presence or\n\
1885 absence of emacs or environment extensions.\n\
1886 Use `provide' to declare that a feature is available.\n\
1887 This function looks at the value of the variable `features'.")
1888 (feature)
1889 Lisp_Object feature;
1890 {
1891 register Lisp_Object tem;
1892 CHECK_SYMBOL (feature, 0);
1893 tem = Fmemq (feature, Vfeatures);
1894 return (NILP (tem)) ? Qnil : Qt;
1895 }
1896
1897 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
1898 "Announce that FEATURE is a feature of the current Emacs.")
1899 (feature)
1900 Lisp_Object feature;
1901 {
1902 register Lisp_Object tem;
1903 CHECK_SYMBOL (feature, 0);
1904 if (!NILP (Vautoload_queue))
1905 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
1906 tem = Fmemq (feature, Vfeatures);
1907 if (NILP (tem))
1908 Vfeatures = Fcons (feature, Vfeatures);
1909 LOADHIST_ATTACH (Fcons (Qprovide, feature));
1910 return feature;
1911 }
1912
1913 DEFUN ("require", Frequire, Srequire, 1, 2, 0,
1914 "If feature FEATURE is not loaded, load it from FILENAME.\n\
1915 If FEATURE is not a member of the list `features', then the feature\n\
1916 is not loaded; so load the file FILENAME.\n\
1917 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
1918 (feature, file_name)
1919 Lisp_Object feature, file_name;
1920 {
1921 register Lisp_Object tem;
1922 CHECK_SYMBOL (feature, 0);
1923 tem = Fmemq (feature, Vfeatures);
1924 LOADHIST_ATTACH (Fcons (Qrequire, feature));
1925 if (NILP (tem))
1926 {
1927 int count = specpdl_ptr - specpdl;
1928
1929 /* Value saved here is to be restored into Vautoload_queue */
1930 record_unwind_protect (un_autoload, Vautoload_queue);
1931 Vautoload_queue = Qt;
1932
1933 Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
1934 Qnil, Qt, Qnil);
1935
1936 tem = Fmemq (feature, Vfeatures);
1937 if (NILP (tem))
1938 error ("Required feature %s was not provided",
1939 XSYMBOL (feature)->name->data );
1940
1941 /* Once loading finishes, don't undo it. */
1942 Vautoload_queue = Qt;
1943 feature = unbind_to (count, feature);
1944 }
1945 return feature;
1946 }
1947 \f
1948 syms_of_fns ()
1949 {
1950 Qstring_lessp = intern ("string-lessp");
1951 staticpro (&Qstring_lessp);
1952 Qprovide = intern ("provide");
1953 staticpro (&Qprovide);
1954 Qrequire = intern ("require");
1955 staticpro (&Qrequire);
1956 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
1957 staticpro (&Qyes_or_no_p_history);
1958 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
1959 staticpro (&Qcursor_in_echo_area);
1960
1961 Fset (Qyes_or_no_p_history, Qnil);
1962
1963 DEFVAR_LISP ("features", &Vfeatures,
1964 "A list of symbols which are the features of the executing emacs.\n\
1965 Used by `featurep' and `require', and altered by `provide'.");
1966 Vfeatures = Qnil;
1967
1968 defsubr (&Sidentity);
1969 defsubr (&Srandom);
1970 defsubr (&Slength);
1971 defsubr (&Ssafe_length);
1972 defsubr (&Sstring_equal);
1973 defsubr (&Sstring_lessp);
1974 defsubr (&Sappend);
1975 defsubr (&Sconcat);
1976 defsubr (&Svconcat);
1977 defsubr (&Scopy_sequence);
1978 defsubr (&Scopy_alist);
1979 defsubr (&Ssubstring);
1980 defsubr (&Snthcdr);
1981 defsubr (&Snth);
1982 defsubr (&Selt);
1983 defsubr (&Smember);
1984 defsubr (&Smemq);
1985 defsubr (&Sassq);
1986 defsubr (&Sassoc);
1987 defsubr (&Srassq);
1988 defsubr (&Srassoc);
1989 defsubr (&Sdelq);
1990 defsubr (&Sdelete);
1991 defsubr (&Snreverse);
1992 defsubr (&Sreverse);
1993 defsubr (&Ssort);
1994 defsubr (&Splist_get);
1995 defsubr (&Sget);
1996 defsubr (&Splist_put);
1997 defsubr (&Sput);
1998 defsubr (&Sequal);
1999 defsubr (&Sfillarray);
2000 defsubr (&Schar_table_subtype);
2001 defsubr (&Schar_table_parent);
2002 defsubr (&Sset_char_table_parent);
2003 defsubr (&Schar_table_extra_slot);
2004 defsubr (&Sset_char_table_extra_slot);
2005 defsubr (&Schar_table_range);
2006 defsubr (&Sset_char_table_range);
2007 defsubr (&Sset_char_table_default);
2008 defsubr (&Smap_char_table);
2009 defsubr (&Snconc);
2010 defsubr (&Smapcar);
2011 defsubr (&Smapconcat);
2012 defsubr (&Sy_or_n_p);
2013 defsubr (&Syes_or_no_p);
2014 defsubr (&Sload_average);
2015 defsubr (&Sfeaturep);
2016 defsubr (&Srequire);
2017 defsubr (&Sprovide);
2018 }