(map_char_table): Use XSETFASTINT.
[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 return 1;
1163 }
1164 return 0;
1165 }
1166 \f
1167 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
1168 "Store each element of ARRAY with ITEM.\n\
1169 ARRAY is a vector, string, char-table, or bool-vector.")
1170 (array, item)
1171 Lisp_Object array, item;
1172 {
1173 register int size, index, charval;
1174 retry:
1175 if (VECTORP (array))
1176 {
1177 register Lisp_Object *p = XVECTOR (array)->contents;
1178 size = XVECTOR (array)->size;
1179 for (index = 0; index < size; index++)
1180 p[index] = item;
1181 }
1182 else if (CHAR_TABLE_P (array))
1183 {
1184 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
1185 size = CHAR_TABLE_ORDINARY_SLOTS;
1186 for (index = 0; index < size; index++)
1187 p[index] = item;
1188 XCHAR_TABLE (array)->defalt = Qnil;
1189 }
1190 else if (STRINGP (array))
1191 {
1192 register unsigned char *p = XSTRING (array)->data;
1193 CHECK_NUMBER (item, 1);
1194 charval = XINT (item);
1195 size = XSTRING (array)->size;
1196 for (index = 0; index < size; index++)
1197 p[index] = charval;
1198 }
1199 else if (BOOL_VECTOR_P (array))
1200 {
1201 register unsigned char *p = XBOOL_VECTOR (array)->data;
1202 int size_in_chars
1203 = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1204
1205 charval = (! NILP (item) ? -1 : 0);
1206 for (index = 0; index < size_in_chars; index++)
1207 p[index] = charval;
1208 }
1209 else
1210 {
1211 array = wrong_type_argument (Qarrayp, array);
1212 goto retry;
1213 }
1214 return array;
1215 }
1216
1217 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
1218 1, 1, 0,
1219 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1220 (char_table)
1221 Lisp_Object char_table;
1222 {
1223 CHECK_CHAR_TABLE (char_table, 0);
1224
1225 return XCHAR_TABLE (char_table)->purpose;
1226 }
1227
1228 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
1229 1, 1, 0,
1230 "Return the parent char-table of CHAR-TABLE.\n\
1231 The value is either nil or another char-table.\n\
1232 If CHAR-TABLE holds nil for a given character,\n\
1233 then the actual applicable value is inherited from the parent char-table\n\
1234 \(or from its parents, if necessary).")
1235 (char_table)
1236 Lisp_Object char_table;
1237 {
1238 CHECK_CHAR_TABLE (char_table, 0);
1239
1240 return XCHAR_TABLE (char_table)->parent;
1241 }
1242
1243 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
1244 2, 2, 0,
1245 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1246 PARENT must be either nil or another char-table.")
1247 (char_table, parent)
1248 Lisp_Object char_table, parent;
1249 {
1250 Lisp_Object temp;
1251
1252 CHECK_CHAR_TABLE (char_table, 0);
1253
1254 if (!NILP (parent))
1255 {
1256 CHECK_CHAR_TABLE (parent, 0);
1257
1258 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
1259 if (EQ (temp, char_table))
1260 error ("Attempt to make a chartable be its own parent");
1261 }
1262
1263 XCHAR_TABLE (char_table)->parent = parent;
1264
1265 return parent;
1266 }
1267
1268 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
1269 2, 2, 0,
1270 "Return the value of CHAR-TABLE's extra-slot number N.")
1271 (char_table, n)
1272 Lisp_Object char_table, n;
1273 {
1274 CHECK_CHAR_TABLE (char_table, 1);
1275 CHECK_NUMBER (n, 2);
1276 if (XINT (n) < 0
1277 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1278 args_out_of_range (char_table, n);
1279
1280 return XCHAR_TABLE (char_table)->extras[XINT (n)];
1281 }
1282
1283 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
1284 Sset_char_table_extra_slot,
1285 3, 3, 0,
1286 "Set CHAR-TABLE's extra-slot number N to VALUE.")
1287 (char_table, n, value)
1288 Lisp_Object char_table, n, value;
1289 {
1290 CHECK_CHAR_TABLE (char_table, 1);
1291 CHECK_NUMBER (n, 2);
1292 if (XINT (n) < 0
1293 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1294 args_out_of_range (char_table, n);
1295
1296 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
1297 }
1298
1299 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
1300 2, 2, 0,
1301 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
1302 RANGE should be t (for all characters), nil (for the default value)\n\
1303 a vector which identifies a character set or a row of a character set,\n\
1304 or a character code.")
1305 (char_table, range)
1306 Lisp_Object char_table, range;
1307 {
1308 int i;
1309
1310 CHECK_CHAR_TABLE (char_table, 0);
1311
1312 if (EQ (range, Qnil))
1313 return XCHAR_TABLE (char_table)->defalt;
1314 else if (INTEGERP (range))
1315 return Faref (char_table, range);
1316 else if (VECTORP (range))
1317 {
1318 if (XVECTOR (range)->size == 1)
1319 return Faref (char_table, XVECTOR (range)->contents[0]);
1320 else
1321 {
1322 int size = XVECTOR (range)->size;
1323 Lisp_Object *val = XVECTOR (range)->contents;
1324 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1325 size <= 1 ? Qnil : val[1],
1326 size <= 2 ? Qnil : val[2]);
1327 return Faref (char_table, ch);
1328 }
1329 }
1330 else
1331 error ("Invalid RANGE argument to `char-table-range'");
1332 }
1333
1334 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
1335 3, 3, 0,
1336 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
1337 RANGE should be t (for all characters), nil (for the default value)\n\
1338 a vector which identifies a character set or a row of a character set,\n\
1339 or a character code.")
1340 (char_table, range, value)
1341 Lisp_Object char_table, range, value;
1342 {
1343 int i;
1344
1345 CHECK_CHAR_TABLE (char_table, 0);
1346
1347 if (EQ (range, Qt))
1348 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1349 XCHAR_TABLE (char_table)->contents[i] = value;
1350 else if (EQ (range, Qnil))
1351 XCHAR_TABLE (char_table)->defalt = value;
1352 else if (INTEGERP (range))
1353 Faset (char_table, range, value);
1354 else if (VECTORP (range))
1355 {
1356 if (XVECTOR (range)->size == 1)
1357 return Faset (char_table, XVECTOR (range)->contents[0], value);
1358 else
1359 {
1360 int size = XVECTOR (range)->size;
1361 Lisp_Object *val = XVECTOR (range)->contents;
1362 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1363 size <= 1 ? Qnil : val[1],
1364 size <= 2 ? Qnil : val[2]);
1365 return Faset (char_table, ch, value);
1366 }
1367 }
1368 else
1369 error ("Invalid RANGE argument to `set-char-table-range'");
1370
1371 return value;
1372 }
1373
1374 DEFUN ("set-char-table-default", Fset_char_table_default,
1375 Sset_char_table_default, 3, 3, 0,
1376 "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
1377 The generic character specifies the group of characters.\n\
1378 See also the documentation of make-char.")
1379 (char_table, ch, value)
1380 Lisp_Object char_table, ch, value;
1381 {
1382 int c, i, charset, code1, code2;
1383 Lisp_Object temp;
1384
1385 CHECK_CHAR_TABLE (char_table, 0);
1386 CHECK_NUMBER (ch, 1);
1387
1388 c = XINT (ch);
1389 SPLIT_NON_ASCII_CHAR (c, charset, code1, code2);
1390 if (! CHARSET_DEFINED_P (charset))
1391 error ("Invalid character: %d", c);
1392
1393 if (charset == CHARSET_ASCII)
1394 return (XCHAR_TABLE (char_table)->defalt = value);
1395
1396 /* Even if C is not a generic char, we had better behave as if a
1397 generic char is specified. */
1398 if (CHARSET_DIMENSION (charset) == 1)
1399 code1 = 0;
1400 temp = XCHAR_TABLE (char_table)->contents[charset + 128];
1401 if (!code1)
1402 {
1403 if (SUB_CHAR_TABLE_P (temp))
1404 XCHAR_TABLE (temp)->defalt = value;
1405 else
1406 XCHAR_TABLE (char_table)->contents[charset + 128] = value;
1407 return value;
1408 }
1409 char_table = temp;
1410 if (! SUB_CHAR_TABLE_P (char_table))
1411 char_table = (XCHAR_TABLE (char_table)->contents[charset + 128]
1412 = make_sub_char_table (temp));
1413 temp = XCHAR_TABLE (char_table)->contents[code1];
1414 if (SUB_CHAR_TABLE_P (temp))
1415 XCHAR_TABLE (temp)->defalt = value;
1416 else
1417 XCHAR_TABLE (char_table)->contents[code1] = value;
1418 return value;
1419 }
1420
1421 \f
1422 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
1423 character or group of characters that share a value.
1424 DEPTH is the current depth in the originally specified
1425 chartable, and INDICES contains the vector indices
1426 for the levels our callers have descended.
1427
1428 ARG is passed to C_FUNCTION when that is called. */
1429
1430 void
1431 map_char_table (c_function, function, subtable, arg, depth, indices)
1432 Lisp_Object (*c_function) (), function, subtable, arg, *indices;
1433 int depth;
1434 {
1435 int i, to;
1436
1437 if (depth == 0)
1438 {
1439 /* At first, handle ASCII and 8-bit European characters. */
1440 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
1441 {
1442 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
1443 if (c_function)
1444 (*c_function) (arg, make_number (i), elt);
1445 else
1446 call2 (function, make_number (i), elt);
1447 }
1448 to = CHAR_TABLE_ORDINARY_SLOTS;
1449 }
1450 else
1451 {
1452 i = 0;
1453 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
1454 }
1455
1456 for (; i < to; i++)
1457 {
1458 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
1459
1460 XSETFASTINT (indices[depth], i);
1461
1462 if (SUB_CHAR_TABLE_P (elt))
1463 {
1464 if (depth >= 3)
1465 error ("Too deep char table");
1466 map_char_table (c_function, function, elt, arg, depth + 1, indices);
1467 }
1468 else
1469 {
1470 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
1471
1472 if (CHARSET_DEFINED_P (charset))
1473 {
1474 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
1475 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
1476 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
1477 if (c_function)
1478 (*c_function) (arg, make_number (c), elt);
1479 else
1480 call2 (function, make_number (c), elt);
1481 }
1482 }
1483 }
1484 }
1485
1486 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
1487 2, 2, 0,
1488 "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
1489 FUNCTION is called with two arguments--a key and a value.\n\
1490 The key is always a possible IDX argument to `aref'.")
1491 (function, char_table)
1492 Lisp_Object function, char_table;
1493 {
1494 /* The depth of char table is at most 3. */
1495 Lisp_Object indices[3];
1496
1497 CHECK_CHAR_TABLE (char_table, 1);
1498
1499 map_char_table (NULL, function, char_table, char_table, 0, indices);
1500 return Qnil;
1501 }
1502 \f
1503 /* ARGSUSED */
1504 Lisp_Object
1505 nconc2 (s1, s2)
1506 Lisp_Object s1, s2;
1507 {
1508 #ifdef NO_ARG_ARRAY
1509 Lisp_Object args[2];
1510 args[0] = s1;
1511 args[1] = s2;
1512 return Fnconc (2, args);
1513 #else
1514 return Fnconc (2, &s1);
1515 #endif /* NO_ARG_ARRAY */
1516 }
1517
1518 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
1519 "Concatenate any number of lists by altering them.\n\
1520 Only the last argument is not altered, and need not be a list.")
1521 (nargs, args)
1522 int nargs;
1523 Lisp_Object *args;
1524 {
1525 register int argnum;
1526 register Lisp_Object tail, tem, val;
1527
1528 val = Qnil;
1529
1530 for (argnum = 0; argnum < nargs; argnum++)
1531 {
1532 tem = args[argnum];
1533 if (NILP (tem)) continue;
1534
1535 if (NILP (val))
1536 val = tem;
1537
1538 if (argnum + 1 == nargs) break;
1539
1540 if (!CONSP (tem))
1541 tem = wrong_type_argument (Qlistp, tem);
1542
1543 while (CONSP (tem))
1544 {
1545 tail = tem;
1546 tem = Fcdr (tail);
1547 QUIT;
1548 }
1549
1550 tem = args[argnum + 1];
1551 Fsetcdr (tail, tem);
1552 if (NILP (tem))
1553 args[argnum + 1] = tail;
1554 }
1555
1556 return val;
1557 }
1558 \f
1559 /* This is the guts of all mapping functions.
1560 Apply fn to each element of seq, one by one,
1561 storing the results into elements of vals, a C vector of Lisp_Objects.
1562 leni is the length of vals, which should also be the length of seq. */
1563
1564 static void
1565 mapcar1 (leni, vals, fn, seq)
1566 int leni;
1567 Lisp_Object *vals;
1568 Lisp_Object fn, seq;
1569 {
1570 register Lisp_Object tail;
1571 Lisp_Object dummy;
1572 register int i;
1573 struct gcpro gcpro1, gcpro2, gcpro3;
1574
1575 /* Don't let vals contain any garbage when GC happens. */
1576 for (i = 0; i < leni; i++)
1577 vals[i] = Qnil;
1578
1579 GCPRO3 (dummy, fn, seq);
1580 gcpro1.var = vals;
1581 gcpro1.nvars = leni;
1582 /* We need not explicitly protect `tail' because it is used only on lists, and
1583 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
1584
1585 if (VECTORP (seq))
1586 {
1587 for (i = 0; i < leni; i++)
1588 {
1589 dummy = XVECTOR (seq)->contents[i];
1590 vals[i] = call1 (fn, dummy);
1591 }
1592 }
1593 else if (STRINGP (seq))
1594 {
1595 for (i = 0; i < leni; i++)
1596 {
1597 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
1598 vals[i] = call1 (fn, dummy);
1599 }
1600 }
1601 else /* Must be a list, since Flength did not get an error */
1602 {
1603 tail = seq;
1604 for (i = 0; i < leni; i++)
1605 {
1606 vals[i] = call1 (fn, Fcar (tail));
1607 tail = Fcdr (tail);
1608 }
1609 }
1610
1611 UNGCPRO;
1612 }
1613
1614 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
1615 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
1616 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
1617 SEPARATOR results in spaces between the values returned by FUNCTION.")
1618 (function, sequence, separator)
1619 Lisp_Object function, sequence, separator;
1620 {
1621 Lisp_Object len;
1622 register int leni;
1623 int nargs;
1624 register Lisp_Object *args;
1625 register int i;
1626 struct gcpro gcpro1;
1627
1628 len = Flength (sequence);
1629 leni = XINT (len);
1630 nargs = leni + leni - 1;
1631 if (nargs < 0) return build_string ("");
1632
1633 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
1634
1635 GCPRO1 (separator);
1636 mapcar1 (leni, args, function, sequence);
1637 UNGCPRO;
1638
1639 for (i = leni - 1; i >= 0; i--)
1640 args[i + i] = args[i];
1641
1642 for (i = 1; i < nargs; i += 2)
1643 args[i] = separator;
1644
1645 return Fconcat (nargs, args);
1646 }
1647
1648 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
1649 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
1650 The result is a list just as long as SEQUENCE.\n\
1651 SEQUENCE may be a list, a vector or a string.")
1652 (function, sequence)
1653 Lisp_Object function, sequence;
1654 {
1655 register Lisp_Object len;
1656 register int leni;
1657 register Lisp_Object *args;
1658
1659 len = Flength (sequence);
1660 leni = XFASTINT (len);
1661 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
1662
1663 mapcar1 (leni, args, function, sequence);
1664
1665 return Flist (leni, args);
1666 }
1667 \f
1668 /* Anything that calls this function must protect from GC! */
1669
1670 DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
1671 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
1672 Takes one argument, which is the string to display to ask the question.\n\
1673 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
1674 No confirmation of the answer is requested; a single character is enough.\n\
1675 Also accepts Space to mean yes, or Delete to mean no.")
1676 (prompt)
1677 Lisp_Object prompt;
1678 {
1679 register Lisp_Object obj, key, def, answer_string, map;
1680 register int answer;
1681 Lisp_Object xprompt;
1682 Lisp_Object args[2];
1683 struct gcpro gcpro1, gcpro2;
1684 int count = specpdl_ptr - specpdl;
1685
1686 specbind (Qcursor_in_echo_area, Qt);
1687
1688 map = Fsymbol_value (intern ("query-replace-map"));
1689
1690 CHECK_STRING (prompt, 0);
1691 xprompt = prompt;
1692 GCPRO2 (prompt, xprompt);
1693
1694 while (1)
1695 {
1696
1697
1698 #ifdef HAVE_MENUS
1699 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1700 && have_menus_p ())
1701 {
1702 Lisp_Object pane, menu;
1703 redisplay_preserve_echo_area ();
1704 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1705 Fcons (Fcons (build_string ("No"), Qnil),
1706 Qnil));
1707 menu = Fcons (prompt, pane);
1708 obj = Fx_popup_dialog (Qt, menu);
1709 answer = !NILP (obj);
1710 break;
1711 }
1712 #endif /* HAVE_MENUS */
1713 cursor_in_echo_area = 1;
1714 choose_minibuf_frame ();
1715 message_nolog ("%s(y or n) ", XSTRING (xprompt)->data);
1716
1717 if (minibuffer_auto_raise)
1718 {
1719 Lisp_Object mini_frame;
1720
1721 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
1722
1723 Fraise_frame (mini_frame);
1724 }
1725
1726 obj = read_filtered_event (1, 0, 0);
1727 cursor_in_echo_area = 0;
1728 /* If we need to quit, quit with cursor_in_echo_area = 0. */
1729 QUIT;
1730
1731 key = Fmake_vector (make_number (1), obj);
1732 def = Flookup_key (map, key, Qt);
1733 answer_string = Fsingle_key_description (obj);
1734
1735 if (EQ (def, intern ("skip")))
1736 {
1737 answer = 0;
1738 break;
1739 }
1740 else if (EQ (def, intern ("act")))
1741 {
1742 answer = 1;
1743 break;
1744 }
1745 else if (EQ (def, intern ("recenter")))
1746 {
1747 Frecenter (Qnil);
1748 xprompt = prompt;
1749 continue;
1750 }
1751 else if (EQ (def, intern ("quit")))
1752 Vquit_flag = Qt;
1753 /* We want to exit this command for exit-prefix,
1754 and this is the only way to do it. */
1755 else if (EQ (def, intern ("exit-prefix")))
1756 Vquit_flag = Qt;
1757
1758 QUIT;
1759
1760 /* If we don't clear this, then the next call to read_char will
1761 return quit_char again, and we'll enter an infinite loop. */
1762 Vquit_flag = Qnil;
1763
1764 Fding (Qnil);
1765 Fdiscard_input ();
1766 if (EQ (xprompt, prompt))
1767 {
1768 args[0] = build_string ("Please answer y or n. ");
1769 args[1] = prompt;
1770 xprompt = Fconcat (2, args);
1771 }
1772 }
1773 UNGCPRO;
1774
1775 if (! noninteractive)
1776 {
1777 cursor_in_echo_area = -1;
1778 message_nolog ("%s(y or n) %c",
1779 XSTRING (xprompt)->data, answer ? 'y' : 'n');
1780 }
1781
1782 unbind_to (count, Qnil);
1783 return answer ? Qt : Qnil;
1784 }
1785 \f
1786 /* This is how C code calls `yes-or-no-p' and allows the user
1787 to redefined it.
1788
1789 Anything that calls this function must protect from GC! */
1790
1791 Lisp_Object
1792 do_yes_or_no_p (prompt)
1793 Lisp_Object prompt;
1794 {
1795 return call1 (intern ("yes-or-no-p"), prompt);
1796 }
1797
1798 /* Anything that calls this function must protect from GC! */
1799
1800 DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
1801 "Ask user a yes-or-no question. Return t if answer is yes.\n\
1802 Takes one argument, which is the string to display to ask the question.\n\
1803 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
1804 The user must confirm the answer with RET,\n\
1805 and can edit it until it has been confirmed.")
1806 (prompt)
1807 Lisp_Object prompt;
1808 {
1809 register Lisp_Object ans;
1810 Lisp_Object args[2];
1811 struct gcpro gcpro1;
1812 Lisp_Object menu;
1813
1814 CHECK_STRING (prompt, 0);
1815
1816 #ifdef HAVE_MENUS
1817 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
1818 && have_menus_p ())
1819 {
1820 Lisp_Object pane, menu, obj;
1821 redisplay_preserve_echo_area ();
1822 pane = Fcons (Fcons (build_string ("Yes"), Qt),
1823 Fcons (Fcons (build_string ("No"), Qnil),
1824 Qnil));
1825 GCPRO1 (pane);
1826 menu = Fcons (prompt, pane);
1827 obj = Fx_popup_dialog (Qt, menu);
1828 UNGCPRO;
1829 return obj;
1830 }
1831 #endif /* HAVE_MENUS */
1832
1833 args[0] = prompt;
1834 args[1] = build_string ("(yes or no) ");
1835 prompt = Fconcat (2, args);
1836
1837 GCPRO1 (prompt);
1838
1839 while (1)
1840 {
1841 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
1842 Qyes_or_no_p_history, Qnil));
1843 if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
1844 {
1845 UNGCPRO;
1846 return Qt;
1847 }
1848 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
1849 {
1850 UNGCPRO;
1851 return Qnil;
1852 }
1853
1854 Fding (Qnil);
1855 Fdiscard_input ();
1856 message ("Please answer yes or no.");
1857 Fsleep_for (make_number (2), Qnil);
1858 }
1859 }
1860 \f
1861 DEFUN ("load-average", Fload_average, Sload_average, 0, 0, 0,
1862 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
1863 Each of the three load averages is multiplied by 100,\n\
1864 then converted to integer.\n\
1865 If the 5-minute or 15-minute load averages are not available, return a\n\
1866 shortened list, containing only those averages which are available.")
1867 ()
1868 {
1869 double load_ave[3];
1870 int loads = getloadavg (load_ave, 3);
1871 Lisp_Object ret;
1872
1873 if (loads < 0)
1874 error ("load-average not implemented for this operating system");
1875
1876 ret = Qnil;
1877 while (loads > 0)
1878 ret = Fcons (make_number ((int) (load_ave[--loads] * 100.0)), ret);
1879
1880 return ret;
1881 }
1882 \f
1883 Lisp_Object Vfeatures;
1884
1885 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
1886 "Returns t if FEATURE is present in this Emacs.\n\
1887 Use this to conditionalize execution of lisp code based on the presence or\n\
1888 absence of emacs or environment extensions.\n\
1889 Use `provide' to declare that a feature is available.\n\
1890 This function looks at the value of the variable `features'.")
1891 (feature)
1892 Lisp_Object feature;
1893 {
1894 register Lisp_Object tem;
1895 CHECK_SYMBOL (feature, 0);
1896 tem = Fmemq (feature, Vfeatures);
1897 return (NILP (tem)) ? Qnil : Qt;
1898 }
1899
1900 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
1901 "Announce that FEATURE is a feature of the current Emacs.")
1902 (feature)
1903 Lisp_Object feature;
1904 {
1905 register Lisp_Object tem;
1906 CHECK_SYMBOL (feature, 0);
1907 if (!NILP (Vautoload_queue))
1908 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
1909 tem = Fmemq (feature, Vfeatures);
1910 if (NILP (tem))
1911 Vfeatures = Fcons (feature, Vfeatures);
1912 LOADHIST_ATTACH (Fcons (Qprovide, feature));
1913 return feature;
1914 }
1915
1916 DEFUN ("require", Frequire, Srequire, 1, 2, 0,
1917 "If feature FEATURE is not loaded, load it from FILENAME.\n\
1918 If FEATURE is not a member of the list `features', then the feature\n\
1919 is not loaded; so load the file FILENAME.\n\
1920 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
1921 (feature, file_name)
1922 Lisp_Object feature, file_name;
1923 {
1924 register Lisp_Object tem;
1925 CHECK_SYMBOL (feature, 0);
1926 tem = Fmemq (feature, Vfeatures);
1927 LOADHIST_ATTACH (Fcons (Qrequire, feature));
1928 if (NILP (tem))
1929 {
1930 int count = specpdl_ptr - specpdl;
1931
1932 /* Value saved here is to be restored into Vautoload_queue */
1933 record_unwind_protect (un_autoload, Vautoload_queue);
1934 Vautoload_queue = Qt;
1935
1936 Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
1937 Qnil, Qt, Qnil);
1938
1939 tem = Fmemq (feature, Vfeatures);
1940 if (NILP (tem))
1941 error ("Required feature %s was not provided",
1942 XSYMBOL (feature)->name->data );
1943
1944 /* Once loading finishes, don't undo it. */
1945 Vautoload_queue = Qt;
1946 feature = unbind_to (count, feature);
1947 }
1948 return feature;
1949 }
1950 \f
1951 syms_of_fns ()
1952 {
1953 Qstring_lessp = intern ("string-lessp");
1954 staticpro (&Qstring_lessp);
1955 Qprovide = intern ("provide");
1956 staticpro (&Qprovide);
1957 Qrequire = intern ("require");
1958 staticpro (&Qrequire);
1959 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
1960 staticpro (&Qyes_or_no_p_history);
1961 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
1962 staticpro (&Qcursor_in_echo_area);
1963
1964 Fset (Qyes_or_no_p_history, Qnil);
1965
1966 DEFVAR_LISP ("features", &Vfeatures,
1967 "A list of symbols which are the features of the executing emacs.\n\
1968 Used by `featurep' and `require', and altered by `provide'.");
1969 Vfeatures = Qnil;
1970
1971 defsubr (&Sidentity);
1972 defsubr (&Srandom);
1973 defsubr (&Slength);
1974 defsubr (&Ssafe_length);
1975 defsubr (&Sstring_equal);
1976 defsubr (&Sstring_lessp);
1977 defsubr (&Sappend);
1978 defsubr (&Sconcat);
1979 defsubr (&Svconcat);
1980 defsubr (&Scopy_sequence);
1981 defsubr (&Scopy_alist);
1982 defsubr (&Ssubstring);
1983 defsubr (&Snthcdr);
1984 defsubr (&Snth);
1985 defsubr (&Selt);
1986 defsubr (&Smember);
1987 defsubr (&Smemq);
1988 defsubr (&Sassq);
1989 defsubr (&Sassoc);
1990 defsubr (&Srassq);
1991 defsubr (&Srassoc);
1992 defsubr (&Sdelq);
1993 defsubr (&Sdelete);
1994 defsubr (&Snreverse);
1995 defsubr (&Sreverse);
1996 defsubr (&Ssort);
1997 defsubr (&Splist_get);
1998 defsubr (&Sget);
1999 defsubr (&Splist_put);
2000 defsubr (&Sput);
2001 defsubr (&Sequal);
2002 defsubr (&Sfillarray);
2003 defsubr (&Schar_table_subtype);
2004 defsubr (&Schar_table_parent);
2005 defsubr (&Sset_char_table_parent);
2006 defsubr (&Schar_table_extra_slot);
2007 defsubr (&Sset_char_table_extra_slot);
2008 defsubr (&Schar_table_range);
2009 defsubr (&Sset_char_table_range);
2010 defsubr (&Sset_char_table_default);
2011 defsubr (&Smap_char_table);
2012 defsubr (&Snconc);
2013 defsubr (&Smapcar);
2014 defsubr (&Smapconcat);
2015 defsubr (&Sy_or_n_p);
2016 defsubr (&Syes_or_no_p);
2017 defsubr (&Sload_average);
2018 defsubr (&Sfeaturep);
2019 defsubr (&Srequire);
2020 defsubr (&Sprovide);
2021 }