]> code.delx.au - gnu-emacs/blob - src/fns.c
*** empty log message ***
[gnu-emacs] / src / fns.c
1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 98, 1999 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 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #include <time.h>
28
29 /* Note on some machines this defines `vector' as a typedef,
30 so make sure we don't use that name in this file. */
31 #undef vector
32 #define vector *****
33
34 #include "lisp.h"
35 #include "commands.h"
36 #include "charset.h"
37
38 #include "buffer.h"
39 #include "keyboard.h"
40 #include "intervals.h"
41 #include "frame.h"
42 #include "window.h"
43 #if defined (HAVE_MENUS) && defined (HAVE_X_WINDOWS)
44 #include "xterm.h"
45 #endif
46
47 #ifndef NULL
48 #define NULL (void *)0
49 #endif
50
51 #ifndef min
52 #define min(a, b) ((a) < (b) ? (a) : (b))
53 #define max(a, b) ((a) > (b) ? (a) : (b))
54 #endif
55
56 /* Nonzero enables use of dialog boxes for questions
57 asked by mouse commands. */
58 int use_dialog_box;
59
60 extern int minibuffer_auto_raise;
61 extern Lisp_Object minibuf_window;
62
63 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
64 Lisp_Object Qyes_or_no_p_history;
65 Lisp_Object Qcursor_in_echo_area;
66 Lisp_Object Qwidget_type;
67
68 extern Lisp_Object Qinput_method_function;
69
70 static int internal_equal ();
71
72 extern long get_random ();
73 extern void seed_random ();
74
75 #ifndef HAVE_UNISTD_H
76 extern long time ();
77 #endif
78 \f
79 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
80 "Return the argument unchanged.")
81 (arg)
82 Lisp_Object arg;
83 {
84 return arg;
85 }
86
87 DEFUN ("random", Frandom, Srandom, 0, 1, 0,
88 "Return a pseudo-random number.\n\
89 All integers representable in Lisp are equally likely.\n\
90 On most systems, this is 28 bits' worth.\n\
91 With positive integer argument N, return random number in interval [0,N).\n\
92 With argument t, set the random number seed from the current time and pid.")
93 (n)
94 Lisp_Object n;
95 {
96 EMACS_INT val;
97 Lisp_Object lispy_val;
98 unsigned long denominator;
99
100 if (EQ (n, Qt))
101 seed_random (getpid () + time (NULL));
102 if (NATNUMP (n) && XFASTINT (n) != 0)
103 {
104 /* Try to take our random number from the higher bits of VAL,
105 not the lower, since (says Gentzel) the low bits of `random'
106 are less random than the higher ones. We do this by using the
107 quotient rather than the remainder. At the high end of the RNG
108 it's possible to get a quotient larger than n; discarding
109 these values eliminates the bias that would otherwise appear
110 when using a large n. */
111 denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n);
112 do
113 val = get_random () / denominator;
114 while (val >= XFASTINT (n));
115 }
116 else
117 val = get_random ();
118 XSETINT (lispy_val, val);
119 return lispy_val;
120 }
121 \f
122 /* Random data-structure functions */
123
124 DEFUN ("length", Flength, Slength, 1, 1, 0,
125 "Return the length of vector, list or string SEQUENCE.\n\
126 A byte-code function object is also allowed.\n\
127 If the string contains multibyte characters, this is not the necessarily\n\
128 the number of bytes in the string; it is the number of characters.\n\
129 To get the number of bytes, use `string-bytes'")
130 (sequence)
131 register Lisp_Object sequence;
132 {
133 register Lisp_Object tail, val;
134 register int i;
135
136 retry:
137 if (STRINGP (sequence))
138 XSETFASTINT (val, XSTRING (sequence)->size);
139 else if (VECTORP (sequence))
140 XSETFASTINT (val, XVECTOR (sequence)->size);
141 else if (CHAR_TABLE_P (sequence))
142 XSETFASTINT (val, MAX_CHAR);
143 else if (BOOL_VECTOR_P (sequence))
144 XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
145 else if (COMPILEDP (sequence))
146 XSETFASTINT (val, XVECTOR (sequence)->size & PSEUDOVECTOR_SIZE_MASK);
147 else if (CONSP (sequence))
148 {
149 i = 0;
150 while (CONSP (sequence))
151 {
152 sequence = XCDR (sequence);
153 ++i;
154
155 if (!CONSP (sequence))
156 break;
157
158 sequence = XCDR (sequence);
159 ++i;
160 QUIT;
161 }
162
163 if (!NILP (sequence))
164 wrong_type_argument (Qlistp, sequence);
165
166 val = make_number (i);
167 }
168 else if (NILP (sequence))
169 XSETFASTINT (val, 0);
170 else
171 {
172 sequence = wrong_type_argument (Qsequencep, sequence);
173 goto retry;
174 }
175 return val;
176 }
177
178 /* This does not check for quits. That is safe
179 since it must terminate. */
180
181 DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
182 "Return the length of a list, but avoid error or infinite loop.\n\
183 This function never gets an error. If LIST is not really a list,\n\
184 it returns 0. If LIST is circular, it returns a finite value\n\
185 which is at least the number of distinct elements.")
186 (list)
187 Lisp_Object list;
188 {
189 Lisp_Object tail, halftail, length;
190 int len = 0;
191
192 /* halftail is used to detect circular lists. */
193 halftail = list;
194 for (tail = list; CONSP (tail); tail = XCDR (tail))
195 {
196 if (EQ (tail, halftail) && len != 0)
197 break;
198 len++;
199 if ((len & 1) == 0)
200 halftail = XCDR (halftail);
201 }
202
203 XSETINT (length, len);
204 return length;
205 }
206
207 DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
208 "Return the number of bytes in STRING.\n\
209 If STRING is a multibyte string, this is greater than the length of STRING.")
210 (string)
211 Lisp_Object string;
212 {
213 CHECK_STRING (string, 1);
214 return make_number (STRING_BYTES (XSTRING (string)));
215 }
216
217 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
218 "Return t if two strings have identical contents.\n\
219 Case is significant, but text properties are ignored.\n\
220 Symbols are also allowed; their print names are used instead.")
221 (s1, s2)
222 register Lisp_Object s1, s2;
223 {
224 if (SYMBOLP (s1))
225 XSETSTRING (s1, XSYMBOL (s1)->name);
226 if (SYMBOLP (s2))
227 XSETSTRING (s2, XSYMBOL (s2)->name);
228 CHECK_STRING (s1, 0);
229 CHECK_STRING (s2, 1);
230
231 if (XSTRING (s1)->size != XSTRING (s2)->size
232 || STRING_BYTES (XSTRING (s1)) != STRING_BYTES (XSTRING (s2))
233 || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, STRING_BYTES (XSTRING (s1))))
234 return Qnil;
235 return Qt;
236 }
237
238 DEFUN ("compare-strings", Fcompare_strings,
239 Scompare_strings, 6, 7, 0,
240 "Compare the contents of two strings, converting to multibyte if needed.\n\
241 In string STR1, skip the first START1 characters and stop at END1.\n\
242 In string STR2, skip the first START2 characters and stop at END2.\n\
243 END1 and END2 default to the full lengths of the respective strings.\n\
244 \n\
245 Case is significant in this comparison if IGNORE-CASE is nil.\n\
246 Unibyte strings are converted to multibyte for comparison.\n\
247 \n\
248 The value is t if the strings (or specified portions) match.\n\
249 If string STR1 is less, the value is a negative number N;\n\
250 - 1 - N is the number of characters that match at the beginning.\n\
251 If string STR1 is greater, the value is a positive number N;\n\
252 N - 1 is the number of characters that match at the beginning.")
253 (str1, start1, end1, str2, start2, end2, ignore_case)
254 Lisp_Object str1, start1, end1, start2, str2, end2, ignore_case;
255 {
256 register int end1_char, end2_char;
257 register int i1, i1_byte, i2, i2_byte;
258
259 CHECK_STRING (str1, 0);
260 CHECK_STRING (str2, 1);
261 if (NILP (start1))
262 start1 = make_number (0);
263 if (NILP (start2))
264 start2 = make_number (0);
265 CHECK_NATNUM (start1, 2);
266 CHECK_NATNUM (start2, 3);
267 if (! NILP (end1))
268 CHECK_NATNUM (end1, 4);
269 if (! NILP (end2))
270 CHECK_NATNUM (end2, 4);
271
272 i1 = XINT (start1);
273 i2 = XINT (start2);
274
275 i1_byte = string_char_to_byte (str1, i1);
276 i2_byte = string_char_to_byte (str2, i2);
277
278 end1_char = XSTRING (str1)->size;
279 if (! NILP (end1) && end1_char > XINT (end1))
280 end1_char = XINT (end1);
281
282 end2_char = XSTRING (str2)->size;
283 if (! NILP (end2) && end2_char > XINT (end2))
284 end2_char = XINT (end2);
285
286 while (i1 < end1_char && i2 < end2_char)
287 {
288 /* When we find a mismatch, we must compare the
289 characters, not just the bytes. */
290 int c1, c2;
291
292 if (STRING_MULTIBYTE (str1))
293 FETCH_STRING_CHAR_ADVANCE (c1, str1, i1, i1_byte);
294 else
295 {
296 c1 = XSTRING (str1)->data[i1++];
297 c1 = unibyte_char_to_multibyte (c1);
298 }
299
300 if (STRING_MULTIBYTE (str2))
301 FETCH_STRING_CHAR_ADVANCE (c2, str2, i2, i2_byte);
302 else
303 {
304 c2 = XSTRING (str2)->data[i2++];
305 c2 = unibyte_char_to_multibyte (c2);
306 }
307
308 if (c1 == c2)
309 continue;
310
311 if (! NILP (ignore_case))
312 {
313 Lisp_Object tem;
314
315 tem = Fupcase (make_number (c1));
316 c1 = XINT (tem);
317 tem = Fupcase (make_number (c2));
318 c2 = XINT (tem);
319 }
320
321 if (c1 == c2)
322 continue;
323
324 /* Note that I1 has already been incremented
325 past the character that we are comparing;
326 hence we don't add or subtract 1 here. */
327 if (c1 < c2)
328 return make_number (- i1);
329 else
330 return make_number (i1);
331 }
332
333 if (i1 < end1_char)
334 return make_number (i1 - XINT (start1) + 1);
335 if (i2 < end2_char)
336 return make_number (- i1 + XINT (start1) - 1);
337
338 return Qt;
339 }
340
341 DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
342 "Return t if first arg string is less than second in lexicographic order.\n\
343 Case is significant.\n\
344 Symbols are also allowed; their print names are used instead.")
345 (s1, s2)
346 register Lisp_Object s1, s2;
347 {
348 register int end;
349 register int i1, i1_byte, i2, i2_byte;
350
351 if (SYMBOLP (s1))
352 XSETSTRING (s1, XSYMBOL (s1)->name);
353 if (SYMBOLP (s2))
354 XSETSTRING (s2, XSYMBOL (s2)->name);
355 CHECK_STRING (s1, 0);
356 CHECK_STRING (s2, 1);
357
358 i1 = i1_byte = i2 = i2_byte = 0;
359
360 end = XSTRING (s1)->size;
361 if (end > XSTRING (s2)->size)
362 end = XSTRING (s2)->size;
363
364 while (i1 < end)
365 {
366 /* When we find a mismatch, we must compare the
367 characters, not just the bytes. */
368 int c1, c2;
369
370 if (STRING_MULTIBYTE (s1))
371 FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte);
372 else
373 c1 = XSTRING (s1)->data[i1++];
374
375 if (STRING_MULTIBYTE (s2))
376 FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte);
377 else
378 c2 = XSTRING (s2)->data[i2++];
379
380 if (c1 != c2)
381 return c1 < c2 ? Qt : Qnil;
382 }
383 return i1 < XSTRING (s2)->size ? Qt : Qnil;
384 }
385 \f
386 static Lisp_Object concat ();
387
388 /* ARGSUSED */
389 Lisp_Object
390 concat2 (s1, s2)
391 Lisp_Object s1, s2;
392 {
393 #ifdef NO_ARG_ARRAY
394 Lisp_Object args[2];
395 args[0] = s1;
396 args[1] = s2;
397 return concat (2, args, Lisp_String, 0);
398 #else
399 return concat (2, &s1, Lisp_String, 0);
400 #endif /* NO_ARG_ARRAY */
401 }
402
403 /* ARGSUSED */
404 Lisp_Object
405 concat3 (s1, s2, s3)
406 Lisp_Object s1, s2, s3;
407 {
408 #ifdef NO_ARG_ARRAY
409 Lisp_Object args[3];
410 args[0] = s1;
411 args[1] = s2;
412 args[2] = s3;
413 return concat (3, args, Lisp_String, 0);
414 #else
415 return concat (3, &s1, Lisp_String, 0);
416 #endif /* NO_ARG_ARRAY */
417 }
418
419 DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
420 "Concatenate all the arguments and make the result a list.\n\
421 The result is a list whose elements are the elements of all the arguments.\n\
422 Each argument may be a list, vector or string.\n\
423 The last argument is not copied, just used as the tail of the new list.")
424 (nargs, args)
425 int nargs;
426 Lisp_Object *args;
427 {
428 return concat (nargs, args, Lisp_Cons, 1);
429 }
430
431 DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
432 "Concatenate all the arguments and make the result a string.\n\
433 The result is a string whose elements are the elements of all the arguments.\n\
434 Each argument may be a string or a list or vector of characters (integers).\n\
435 \n\
436 Do not use individual integers as arguments!\n\
437 The behavior of `concat' in that case will be changed later!\n\
438 If your program passes an integer as an argument to `concat',\n\
439 you should change it right away not to do so.")
440 (nargs, args)
441 int nargs;
442 Lisp_Object *args;
443 {
444 return concat (nargs, args, Lisp_String, 0);
445 }
446
447 DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
448 "Concatenate all the arguments and make the result a vector.\n\
449 The result is a vector whose elements are the elements of all the arguments.\n\
450 Each argument may be a list, vector or string.")
451 (nargs, args)
452 int nargs;
453 Lisp_Object *args;
454 {
455 return concat (nargs, args, Lisp_Vectorlike, 0);
456 }
457
458 /* Retrun a copy of a sub char table ARG. The elements except for a
459 nested sub char table are not copied. */
460 static Lisp_Object
461 copy_sub_char_table (arg)
462 Lisp_Object arg;
463 {
464 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
465 int i;
466
467 /* Copy all the contents. */
468 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
469 SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
470 /* Recursively copy any sub char-tables in the ordinary slots. */
471 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
472 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
473 XCHAR_TABLE (copy)->contents[i]
474 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
475
476 return copy;
477 }
478
479
480 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
481 "Return a copy of a list, vector or string.\n\
482 The elements of a list or vector are not copied; they are shared\n\
483 with the original.")
484 (arg)
485 Lisp_Object arg;
486 {
487 if (NILP (arg)) return arg;
488
489 if (CHAR_TABLE_P (arg))
490 {
491 int i;
492 Lisp_Object copy;
493
494 copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
495 /* Copy all the slots, including the extra ones. */
496 bcopy (XVECTOR (arg)->contents, XVECTOR (copy)->contents,
497 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
498 * sizeof (Lisp_Object)));
499
500 /* Recursively copy any sub char tables in the ordinary slots
501 for multibyte characters. */
502 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
503 i < CHAR_TABLE_ORDINARY_SLOTS; i++)
504 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
505 XCHAR_TABLE (copy)->contents[i]
506 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
507
508 return copy;
509 }
510
511 if (BOOL_VECTOR_P (arg))
512 {
513 Lisp_Object val;
514 int size_in_chars
515 = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
516
517 val = Fmake_bool_vector (Flength (arg), Qnil);
518 bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
519 size_in_chars);
520 return val;
521 }
522
523 if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
524 arg = wrong_type_argument (Qsequencep, arg);
525 return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
526 }
527
528 /* In string STR of length LEN, see if bytes before STR[I] combine
529 with bytes after STR[I] to form a single character. If so, return
530 the number of bytes after STR[I] which combine in this way.
531 Otherwize, return 0. */
532
533 static int
534 count_combining (str, len, i)
535 unsigned char *str;
536 int len, i;
537 {
538 int j = i - 1, bytes;
539
540 if (i == 0 || i == len || CHAR_HEAD_P (str[i]))
541 return 0;
542 while (j >= 0 && !CHAR_HEAD_P (str[j])) j--;
543 if (j < 0 || ! BASE_LEADING_CODE_P (str[j]))
544 return 0;
545 PARSE_MULTIBYTE_SEQ (str + j, len - j, bytes);
546 return (bytes <= i - j ? 0 : bytes - (i - j));
547 }
548
549 /* This structure holds information of an argument of `concat' that is
550 a string and has text properties to be copied. */
551 struct textprop_rec
552 {
553 int argnum; /* refer to ARGS (arguments of `concat') */
554 int from; /* refer to ARGS[argnum] (argument string) */
555 int to; /* refer to VAL (the target string) */
556 };
557
558 static Lisp_Object
559 concat (nargs, args, target_type, last_special)
560 int nargs;
561 Lisp_Object *args;
562 enum Lisp_Type target_type;
563 int last_special;
564 {
565 Lisp_Object val;
566 register Lisp_Object tail;
567 register Lisp_Object this;
568 int toindex;
569 int toindex_byte;
570 register int result_len;
571 register int result_len_byte;
572 register int argnum;
573 Lisp_Object last_tail;
574 Lisp_Object prev;
575 int some_multibyte;
576 /* When we make a multibyte string, we can't copy text properties
577 while concatinating each string because the length of resulting
578 string can't be decided until we finish the whole concatination.
579 So, we record strings that have text properties to be copied
580 here, and copy the text properties after the concatination. */
581 struct textprop_rec *textprops;
582 /* Number of elments in textprops. */
583 int num_textprops = 0;
584
585 /* In append, the last arg isn't treated like the others */
586 if (last_special && nargs > 0)
587 {
588 nargs--;
589 last_tail = args[nargs];
590 }
591 else
592 last_tail = Qnil;
593
594 /* Canonicalize each argument. */
595 for (argnum = 0; argnum < nargs; argnum++)
596 {
597 this = args[argnum];
598 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
599 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
600 {
601 if (INTEGERP (this))
602 args[argnum] = Fnumber_to_string (this);
603 else
604 args[argnum] = wrong_type_argument (Qsequencep, this);
605 }
606 }
607
608 /* Compute total length in chars of arguments in RESULT_LEN.
609 If desired output is a string, also compute length in bytes
610 in RESULT_LEN_BYTE, and determine in SOME_MULTIBYTE
611 whether the result should be a multibyte string. */
612 result_len_byte = 0;
613 result_len = 0;
614 some_multibyte = 0;
615 for (argnum = 0; argnum < nargs; argnum++)
616 {
617 int len;
618 this = args[argnum];
619 len = XFASTINT (Flength (this));
620 if (target_type == Lisp_String)
621 {
622 /* We must count the number of bytes needed in the string
623 as well as the number of characters. */
624 int i;
625 Lisp_Object ch;
626 int this_len_byte;
627
628 if (VECTORP (this))
629 for (i = 0; i < len; i++)
630 {
631 ch = XVECTOR (this)->contents[i];
632 if (! INTEGERP (ch))
633 wrong_type_argument (Qintegerp, ch);
634 this_len_byte = CHAR_BYTES (XINT (ch));
635 result_len_byte += this_len_byte;
636 if (this_len_byte > 1)
637 some_multibyte = 1;
638 }
639 else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
640 wrong_type_argument (Qintegerp, Faref (this, make_number (0)));
641 else if (CONSP (this))
642 for (; CONSP (this); this = XCDR (this))
643 {
644 ch = XCAR (this);
645 if (! INTEGERP (ch))
646 wrong_type_argument (Qintegerp, ch);
647 this_len_byte = CHAR_BYTES (XINT (ch));
648 result_len_byte += this_len_byte;
649 if (this_len_byte > 1)
650 some_multibyte = 1;
651 }
652 else if (STRINGP (this))
653 {
654 if (STRING_MULTIBYTE (this))
655 {
656 some_multibyte = 1;
657 result_len_byte += STRING_BYTES (XSTRING (this));
658 }
659 else
660 result_len_byte += count_size_as_multibyte (XSTRING (this)->data,
661 XSTRING (this)->size);
662 }
663 }
664
665 result_len += len;
666 }
667
668 if (! some_multibyte)
669 result_len_byte = result_len;
670
671 /* Create the output object. */
672 if (target_type == Lisp_Cons)
673 val = Fmake_list (make_number (result_len), Qnil);
674 else if (target_type == Lisp_Vectorlike)
675 val = Fmake_vector (make_number (result_len), Qnil);
676 else if (some_multibyte)
677 val = make_uninit_multibyte_string (result_len, result_len_byte);
678 else
679 val = make_uninit_string (result_len);
680
681 /* In `append', if all but last arg are nil, return last arg. */
682 if (target_type == Lisp_Cons && EQ (val, Qnil))
683 return last_tail;
684
685 /* Copy the contents of the args into the result. */
686 if (CONSP (val))
687 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
688 else
689 toindex = 0, toindex_byte = 0;
690
691 prev = Qnil;
692 if (STRINGP (val))
693 textprops
694 = (struct textprop_rec *) alloca (sizeof (struct textprop_rec) * nargs);
695
696 for (argnum = 0; argnum < nargs; argnum++)
697 {
698 Lisp_Object thislen;
699 int thisleni;
700 register unsigned int thisindex = 0;
701 register unsigned int thisindex_byte = 0;
702
703 this = args[argnum];
704 if (!CONSP (this))
705 thislen = Flength (this), thisleni = XINT (thislen);
706
707 /* Between strings of the same kind, copy fast. */
708 if (STRINGP (this) && STRINGP (val)
709 && STRING_MULTIBYTE (this) == some_multibyte)
710 {
711 int thislen_byte = STRING_BYTES (XSTRING (this));
712 int combined;
713
714 bcopy (XSTRING (this)->data, XSTRING (val)->data + toindex_byte,
715 STRING_BYTES (XSTRING (this)));
716 combined = (some_multibyte && toindex_byte > 0
717 ? count_combining (XSTRING (val)->data,
718 toindex_byte + thislen_byte,
719 toindex_byte)
720 : 0);
721 if (! NULL_INTERVAL_P (XSTRING (this)->intervals))
722 {
723 textprops[num_textprops].argnum = argnum;
724 /* We ignore text properties on characters being combined. */
725 textprops[num_textprops].from = combined;
726 textprops[num_textprops++].to = toindex;
727 }
728 toindex_byte += thislen_byte;
729 toindex += thisleni - combined;
730 XSTRING (val)->size -= combined;
731 }
732 /* Copy a single-byte string to a multibyte string. */
733 else if (STRINGP (this) && STRINGP (val))
734 {
735 if (! NULL_INTERVAL_P (XSTRING (this)->intervals))
736 {
737 textprops[num_textprops].argnum = argnum;
738 textprops[num_textprops].from = 0;
739 textprops[num_textprops++].to = toindex;
740 }
741 toindex_byte += copy_text (XSTRING (this)->data,
742 XSTRING (val)->data + toindex_byte,
743 XSTRING (this)->size, 0, 1);
744 toindex += thisleni;
745 }
746 else
747 /* Copy element by element. */
748 while (1)
749 {
750 register Lisp_Object elt;
751
752 /* Fetch next element of `this' arg into `elt', or break if
753 `this' is exhausted. */
754 if (NILP (this)) break;
755 if (CONSP (this))
756 elt = XCAR (this), this = XCDR (this);
757 else if (thisindex >= thisleni)
758 break;
759 else if (STRINGP (this))
760 {
761 int c;
762 if (STRING_MULTIBYTE (this))
763 {
764 FETCH_STRING_CHAR_ADVANCE (c, this,
765 thisindex,
766 thisindex_byte);
767 XSETFASTINT (elt, c);
768 }
769 else
770 {
771 XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
772 if (some_multibyte
773 && (XINT (elt) >= 0240
774 || (XINT (elt) >= 0200
775 && ! NILP (Vnonascii_translation_table)))
776 && XINT (elt) < 0400)
777 {
778 c = unibyte_char_to_multibyte (XINT (elt));
779 XSETINT (elt, c);
780 }
781 }
782 }
783 else if (BOOL_VECTOR_P (this))
784 {
785 int byte;
786 byte = XBOOL_VECTOR (this)->data[thisindex / BITS_PER_CHAR];
787 if (byte & (1 << (thisindex % BITS_PER_CHAR)))
788 elt = Qt;
789 else
790 elt = Qnil;
791 thisindex++;
792 }
793 else
794 elt = XVECTOR (this)->contents[thisindex++];
795
796 /* Store this element into the result. */
797 if (toindex < 0)
798 {
799 XCAR (tail) = elt;
800 prev = tail;
801 tail = XCDR (tail);
802 }
803 else if (VECTORP (val))
804 XVECTOR (val)->contents[toindex++] = elt;
805 else
806 {
807 CHECK_NUMBER (elt, 0);
808 if (SINGLE_BYTE_CHAR_P (XINT (elt)))
809 {
810 XSTRING (val)->data[toindex_byte++] = XINT (elt);
811 if (some_multibyte
812 && toindex_byte > 0
813 && count_combining (XSTRING (val)->data,
814 toindex_byte, toindex_byte - 1))
815 XSTRING (val)->size--;
816 else
817 toindex++;
818 }
819 else
820 /* If we have any multibyte characters,
821 we already decided to make a multibyte string. */
822 {
823 int c = XINT (elt);
824 /* P exists as a variable
825 to avoid a bug on the Masscomp C compiler. */
826 unsigned char *p = & XSTRING (val)->data[toindex_byte];
827
828 toindex_byte += CHAR_STRING (c, p);
829 toindex++;
830 }
831 }
832 }
833 }
834 if (!NILP (prev))
835 XCDR (prev) = last_tail;
836
837 if (num_textprops > 0)
838 {
839 for (argnum = 0; argnum < num_textprops; argnum++)
840 {
841 this = args[textprops[argnum].argnum];
842 copy_text_properties (make_number (textprops[argnum].from),
843 make_number (XSTRING (this)->size), this,
844 make_number (textprops[argnum].to), val, Qnil);
845 }
846 }
847 return val;
848 }
849 \f
850 static Lisp_Object string_char_byte_cache_string;
851 static int string_char_byte_cache_charpos;
852 static int string_char_byte_cache_bytepos;
853
854 void
855 clear_string_char_byte_cache ()
856 {
857 string_char_byte_cache_string = Qnil;
858 }
859
860 /* Return the character index corresponding to CHAR_INDEX in STRING. */
861
862 int
863 string_char_to_byte (string, char_index)
864 Lisp_Object string;
865 int char_index;
866 {
867 int i, i_byte;
868 int best_below, best_below_byte;
869 int best_above, best_above_byte;
870
871 if (! STRING_MULTIBYTE (string))
872 return char_index;
873
874 best_below = best_below_byte = 0;
875 best_above = XSTRING (string)->size;
876 best_above_byte = STRING_BYTES (XSTRING (string));
877
878 if (EQ (string, string_char_byte_cache_string))
879 {
880 if (string_char_byte_cache_charpos < char_index)
881 {
882 best_below = string_char_byte_cache_charpos;
883 best_below_byte = string_char_byte_cache_bytepos;
884 }
885 else
886 {
887 best_above = string_char_byte_cache_charpos;
888 best_above_byte = string_char_byte_cache_bytepos;
889 }
890 }
891
892 if (char_index - best_below < best_above - char_index)
893 {
894 while (best_below < char_index)
895 {
896 int c;
897 FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
898 }
899 i = best_below;
900 i_byte = best_below_byte;
901 }
902 else
903 {
904 while (best_above > char_index)
905 {
906 unsigned char *pend = XSTRING (string)->data + best_above_byte;
907 unsigned char *pbeg = pend - best_above_byte;
908 unsigned char *p = pend - 1;
909 int bytes;
910
911 while (p > pbeg && !CHAR_HEAD_P (*p)) p--;
912 PARSE_MULTIBYTE_SEQ (p, pend - p, bytes);
913 if (bytes == pend - p)
914 best_above_byte -= bytes;
915 else if (bytes > pend - p)
916 best_above_byte -= (pend - p);
917 else
918 best_above_byte--;
919 best_above--;
920 }
921 i = best_above;
922 i_byte = best_above_byte;
923 }
924
925 string_char_byte_cache_bytepos = i_byte;
926 string_char_byte_cache_charpos = i;
927 string_char_byte_cache_string = string;
928
929 return i_byte;
930 }
931 \f
932 /* Return the character index corresponding to BYTE_INDEX in STRING. */
933
934 int
935 string_byte_to_char (string, byte_index)
936 Lisp_Object string;
937 int byte_index;
938 {
939 int i, i_byte;
940 int best_below, best_below_byte;
941 int best_above, best_above_byte;
942
943 if (! STRING_MULTIBYTE (string))
944 return byte_index;
945
946 best_below = best_below_byte = 0;
947 best_above = XSTRING (string)->size;
948 best_above_byte = STRING_BYTES (XSTRING (string));
949
950 if (EQ (string, string_char_byte_cache_string))
951 {
952 if (string_char_byte_cache_bytepos < byte_index)
953 {
954 best_below = string_char_byte_cache_charpos;
955 best_below_byte = string_char_byte_cache_bytepos;
956 }
957 else
958 {
959 best_above = string_char_byte_cache_charpos;
960 best_above_byte = string_char_byte_cache_bytepos;
961 }
962 }
963
964 if (byte_index - best_below_byte < best_above_byte - byte_index)
965 {
966 while (best_below_byte < byte_index)
967 {
968 int c;
969 FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
970 }
971 i = best_below;
972 i_byte = best_below_byte;
973 }
974 else
975 {
976 while (best_above_byte > byte_index)
977 {
978 unsigned char *pend = XSTRING (string)->data + best_above_byte;
979 unsigned char *pbeg = pend - best_above_byte;
980 unsigned char *p = pend - 1;
981 int bytes;
982
983 while (p > pbeg && !CHAR_HEAD_P (*p)) p--;
984 PARSE_MULTIBYTE_SEQ (p, pend - p, bytes);
985 if (bytes == pend - p)
986 best_above_byte -= bytes;
987 else if (bytes > pend - p)
988 best_above_byte -= (pend - p);
989 else
990 best_above_byte--;
991 best_above--;
992 }
993 i = best_above;
994 i_byte = best_above_byte;
995 }
996
997 string_char_byte_cache_bytepos = i_byte;
998 string_char_byte_cache_charpos = i;
999 string_char_byte_cache_string = string;
1000
1001 return i;
1002 }
1003 \f
1004 /* Convert STRING to a multibyte string.
1005 Single-byte characters 0240 through 0377 are converted
1006 by adding nonascii_insert_offset to each. */
1007
1008 Lisp_Object
1009 string_make_multibyte (string)
1010 Lisp_Object string;
1011 {
1012 unsigned char *buf;
1013 int nbytes;
1014
1015 if (STRING_MULTIBYTE (string))
1016 return string;
1017
1018 nbytes = count_size_as_multibyte (XSTRING (string)->data,
1019 XSTRING (string)->size);
1020 /* If all the chars are ASCII, they won't need any more bytes
1021 once converted. In that case, we can return STRING itself. */
1022 if (nbytes == STRING_BYTES (XSTRING (string)))
1023 return string;
1024
1025 buf = (unsigned char *) alloca (nbytes);
1026 copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
1027 0, 1);
1028
1029 return make_multibyte_string (buf, XSTRING (string)->size, nbytes);
1030 }
1031
1032 /* Convert STRING to a single-byte string. */
1033
1034 Lisp_Object
1035 string_make_unibyte (string)
1036 Lisp_Object string;
1037 {
1038 unsigned char *buf;
1039
1040 if (! STRING_MULTIBYTE (string))
1041 return string;
1042
1043 buf = (unsigned char *) alloca (XSTRING (string)->size);
1044
1045 copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
1046 1, 0);
1047
1048 return make_unibyte_string (buf, XSTRING (string)->size);
1049 }
1050
1051 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
1052 1, 1, 0,
1053 "Return the multibyte equivalent of STRING.\n\
1054 The function `unibyte-char-to-multibyte' is used to convert\n\
1055 each unibyte character to a multibyte character.")
1056 (string)
1057 Lisp_Object string;
1058 {
1059 CHECK_STRING (string, 0);
1060
1061 return string_make_multibyte (string);
1062 }
1063
1064 DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
1065 1, 1, 0,
1066 "Return the unibyte equivalent of STRING.\n\
1067 Multibyte character codes are converted to unibyte\n\
1068 by using just the low 8 bits.")
1069 (string)
1070 Lisp_Object string;
1071 {
1072 CHECK_STRING (string, 0);
1073
1074 return string_make_unibyte (string);
1075 }
1076
1077 DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte,
1078 1, 1, 0,
1079 "Return a unibyte string with the same individual bytes as STRING.\n\
1080 If STRING is unibyte, the result is STRING itself.\n\
1081 Otherwise it is a newly created string, with no text properties.")
1082 (string)
1083 Lisp_Object string;
1084 {
1085 CHECK_STRING (string, 0);
1086
1087 if (STRING_MULTIBYTE (string))
1088 {
1089 string = Fcopy_sequence (string);
1090 XSTRING (string)->size = STRING_BYTES (XSTRING (string));
1091 XSTRING (string)->intervals = NULL_INTERVAL;
1092 SET_STRING_BYTES (XSTRING (string), -1);
1093 }
1094 return string;
1095 }
1096
1097 DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte,
1098 1, 1, 0,
1099 "Return a multibyte string with the same individual bytes as STRING.\n\
1100 If STRING is multibyte, the result is STRING itself.\n\
1101 Otherwise it is a newly created string, with no text properties.")
1102 (string)
1103 Lisp_Object string;
1104 {
1105 CHECK_STRING (string, 0);
1106
1107 if (! STRING_MULTIBYTE (string))
1108 {
1109 int nbytes = STRING_BYTES (XSTRING (string));
1110 int newlen = multibyte_chars_in_text (XSTRING (string)->data, nbytes);
1111
1112 string = Fcopy_sequence (string);
1113 XSTRING (string)->size = newlen;
1114 XSTRING (string)->size_byte = nbytes;
1115 XSTRING (string)->intervals = NULL_INTERVAL;
1116 }
1117 return string;
1118 }
1119 \f
1120 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
1121 "Return a copy of ALIST.\n\
1122 This is an alist which represents the same mapping from objects to objects,\n\
1123 but does not share the alist structure with ALIST.\n\
1124 The objects mapped (cars and cdrs of elements of the alist)\n\
1125 are shared, however.\n\
1126 Elements of ALIST that are not conses are also shared.")
1127 (alist)
1128 Lisp_Object alist;
1129 {
1130 register Lisp_Object tem;
1131
1132 CHECK_LIST (alist, 0);
1133 if (NILP (alist))
1134 return alist;
1135 alist = concat (1, &alist, Lisp_Cons, 0);
1136 for (tem = alist; CONSP (tem); tem = XCDR (tem))
1137 {
1138 register Lisp_Object car;
1139 car = XCAR (tem);
1140
1141 if (CONSP (car))
1142 XCAR (tem) = Fcons (XCAR (car), XCDR (car));
1143 }
1144 return alist;
1145 }
1146
1147 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
1148 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
1149 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
1150 If FROM or TO is negative, it counts from the end.\n\
1151 \n\
1152 This function allows vectors as well as strings.")
1153 (string, from, to)
1154 Lisp_Object string;
1155 register Lisp_Object from, to;
1156 {
1157 Lisp_Object res;
1158 int size;
1159 int size_byte;
1160 int from_char, to_char;
1161 int from_byte, to_byte;
1162
1163 if (! (STRINGP (string) || VECTORP (string)))
1164 wrong_type_argument (Qarrayp, string);
1165
1166 CHECK_NUMBER (from, 1);
1167
1168 if (STRINGP (string))
1169 {
1170 size = XSTRING (string)->size;
1171 size_byte = STRING_BYTES (XSTRING (string));
1172 }
1173 else
1174 size = XVECTOR (string)->size;
1175
1176 if (NILP (to))
1177 {
1178 to_char = size;
1179 to_byte = size_byte;
1180 }
1181 else
1182 {
1183 CHECK_NUMBER (to, 2);
1184
1185 to_char = XINT (to);
1186 if (to_char < 0)
1187 to_char += size;
1188
1189 if (STRINGP (string))
1190 to_byte = string_char_to_byte (string, to_char);
1191 }
1192
1193 from_char = XINT (from);
1194 if (from_char < 0)
1195 from_char += size;
1196 if (STRINGP (string))
1197 from_byte = string_char_to_byte (string, from_char);
1198
1199 if (!(0 <= from_char && from_char <= to_char && to_char <= size))
1200 args_out_of_range_3 (string, make_number (from_char),
1201 make_number (to_char));
1202
1203 if (STRINGP (string))
1204 {
1205 res = make_specified_string (XSTRING (string)->data + from_byte,
1206 to_char - from_char, to_byte - from_byte,
1207 STRING_MULTIBYTE (string));
1208 copy_text_properties (make_number (from_char), make_number (to_char),
1209 string, make_number (0), res, Qnil);
1210 }
1211 else
1212 res = Fvector (to_char - from_char,
1213 XVECTOR (string)->contents + from_char);
1214
1215 return res;
1216 }
1217
1218 /* Extract a substring of STRING, giving start and end positions
1219 both in characters and in bytes. */
1220
1221 Lisp_Object
1222 substring_both (string, from, from_byte, to, to_byte)
1223 Lisp_Object string;
1224 int from, from_byte, to, to_byte;
1225 {
1226 Lisp_Object res;
1227 int size;
1228 int size_byte;
1229
1230 if (! (STRINGP (string) || VECTORP (string)))
1231 wrong_type_argument (Qarrayp, string);
1232
1233 if (STRINGP (string))
1234 {
1235 size = XSTRING (string)->size;
1236 size_byte = STRING_BYTES (XSTRING (string));
1237 }
1238 else
1239 size = XVECTOR (string)->size;
1240
1241 if (!(0 <= from && from <= to && to <= size))
1242 args_out_of_range_3 (string, make_number (from), make_number (to));
1243
1244 if (STRINGP (string))
1245 {
1246 res = make_specified_string (XSTRING (string)->data + from_byte,
1247 to - from, to_byte - from_byte,
1248 STRING_MULTIBYTE (string));
1249 copy_text_properties (make_number (from), make_number (to),
1250 string, make_number (0), res, Qnil);
1251 }
1252 else
1253 res = Fvector (to - from,
1254 XVECTOR (string)->contents + from);
1255
1256 return res;
1257 }
1258 \f
1259 DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
1260 "Take cdr N times on LIST, returns the result.")
1261 (n, list)
1262 Lisp_Object n;
1263 register Lisp_Object list;
1264 {
1265 register int i, num;
1266 CHECK_NUMBER (n, 0);
1267 num = XINT (n);
1268 for (i = 0; i < num && !NILP (list); i++)
1269 {
1270 QUIT;
1271 if (! CONSP (list))
1272 wrong_type_argument (Qlistp, list);
1273 list = XCDR (list);
1274 }
1275 return list;
1276 }
1277
1278 DEFUN ("nth", Fnth, Snth, 2, 2, 0,
1279 "Return the Nth element of LIST.\n\
1280 N counts from zero. If LIST is not that long, nil is returned.")
1281 (n, list)
1282 Lisp_Object n, list;
1283 {
1284 return Fcar (Fnthcdr (n, list));
1285 }
1286
1287 DEFUN ("elt", Felt, Selt, 2, 2, 0,
1288 "Return element of SEQUENCE at index N.")
1289 (sequence, n)
1290 register Lisp_Object sequence, n;
1291 {
1292 CHECK_NUMBER (n, 0);
1293 while (1)
1294 {
1295 if (CONSP (sequence) || NILP (sequence))
1296 return Fcar (Fnthcdr (n, sequence));
1297 else if (STRINGP (sequence) || VECTORP (sequence)
1298 || BOOL_VECTOR_P (sequence) || CHAR_TABLE_P (sequence))
1299 return Faref (sequence, n);
1300 else
1301 sequence = wrong_type_argument (Qsequencep, sequence);
1302 }
1303 }
1304
1305 DEFUN ("member", Fmember, Smember, 2, 2, 0,
1306 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
1307 The value is actually the tail of LIST whose car is ELT.")
1308 (elt, list)
1309 register Lisp_Object elt;
1310 Lisp_Object list;
1311 {
1312 register Lisp_Object tail;
1313 for (tail = list; !NILP (tail); tail = XCDR (tail))
1314 {
1315 register Lisp_Object tem;
1316 if (! CONSP (tail))
1317 wrong_type_argument (Qlistp, list);
1318 tem = XCAR (tail);
1319 if (! NILP (Fequal (elt, tem)))
1320 return tail;
1321 QUIT;
1322 }
1323 return Qnil;
1324 }
1325
1326 DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
1327 "Return non-nil if ELT is an element of LIST.\n\
1328 Comparison done with EQ. The value is actually the tail of LIST\n\
1329 whose car is ELT.")
1330 (elt, list)
1331 Lisp_Object elt, list;
1332 {
1333 while (1)
1334 {
1335 if (!CONSP (list) || EQ (XCAR (list), elt))
1336 break;
1337
1338 list = XCDR (list);
1339 if (!CONSP (list) || EQ (XCAR (list), elt))
1340 break;
1341
1342 list = XCDR (list);
1343 if (!CONSP (list) || EQ (XCAR (list), elt))
1344 break;
1345
1346 list = XCDR (list);
1347 QUIT;
1348 }
1349
1350 if (!CONSP (list) && !NILP (list))
1351 list = wrong_type_argument (Qlistp, list);
1352
1353 return list;
1354 }
1355
1356 DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
1357 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
1358 The value is actually the element of LIST whose car is KEY.\n\
1359 Elements of LIST that are not conses are ignored.")
1360 (key, list)
1361 Lisp_Object key, list;
1362 {
1363 Lisp_Object result;
1364
1365 while (1)
1366 {
1367 if (!CONSP (list)
1368 || (CONSP (XCAR (list))
1369 && EQ (XCAR (XCAR (list)), key)))
1370 break;
1371
1372 list = XCDR (list);
1373 if (!CONSP (list)
1374 || (CONSP (XCAR (list))
1375 && EQ (XCAR (XCAR (list)), key)))
1376 break;
1377
1378 list = XCDR (list);
1379 if (!CONSP (list)
1380 || (CONSP (XCAR (list))
1381 && EQ (XCAR (XCAR (list)), key)))
1382 break;
1383
1384 list = XCDR (list);
1385 QUIT;
1386 }
1387
1388 if (CONSP (list))
1389 result = XCAR (list);
1390 else if (NILP (list))
1391 result = Qnil;
1392 else
1393 result = wrong_type_argument (Qlistp, list);
1394
1395 return result;
1396 }
1397
1398 /* Like Fassq but never report an error and do not allow quits.
1399 Use only on lists known never to be circular. */
1400
1401 Lisp_Object
1402 assq_no_quit (key, list)
1403 Lisp_Object key, list;
1404 {
1405 while (CONSP (list)
1406 && (!CONSP (XCAR (list))
1407 || !EQ (XCAR (XCAR (list)), key)))
1408 list = XCDR (list);
1409
1410 return CONSP (list) ? XCAR (list) : Qnil;
1411 }
1412
1413 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
1414 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
1415 The value is actually the element of LIST whose car equals KEY.")
1416 (key, list)
1417 Lisp_Object key, list;
1418 {
1419 Lisp_Object result, car;
1420
1421 while (1)
1422 {
1423 if (!CONSP (list)
1424 || (CONSP (XCAR (list))
1425 && (car = XCAR (XCAR (list)),
1426 EQ (car, key) || !NILP (Fequal (car, key)))))
1427 break;
1428
1429 list = XCDR (list);
1430 if (!CONSP (list)
1431 || (CONSP (XCAR (list))
1432 && (car = XCAR (XCAR (list)),
1433 EQ (car, key) || !NILP (Fequal (car, key)))))
1434 break;
1435
1436 list = XCDR (list);
1437 if (!CONSP (list)
1438 || (CONSP (XCAR (list))
1439 && (car = XCAR (XCAR (list)),
1440 EQ (car, key) || !NILP (Fequal (car, key)))))
1441 break;
1442
1443 list = XCDR (list);
1444 QUIT;
1445 }
1446
1447 if (CONSP (list))
1448 result = XCAR (list);
1449 else if (NILP (list))
1450 result = Qnil;
1451 else
1452 result = wrong_type_argument (Qlistp, list);
1453
1454 return result;
1455 }
1456
1457 DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
1458 "Return non-nil if KEY is `eq' to the cdr of an element of LIST.\n\
1459 The value is actually the element of LIST whose cdr is KEY.")
1460 (key, list)
1461 register Lisp_Object key;
1462 Lisp_Object list;
1463 {
1464 Lisp_Object result;
1465
1466 while (1)
1467 {
1468 if (!CONSP (list)
1469 || (CONSP (XCAR (list))
1470 && EQ (XCDR (XCAR (list)), key)))
1471 break;
1472
1473 list = XCDR (list);
1474 if (!CONSP (list)
1475 || (CONSP (XCAR (list))
1476 && EQ (XCDR (XCAR (list)), key)))
1477 break;
1478
1479 list = XCDR (list);
1480 if (!CONSP (list)
1481 || (CONSP (XCAR (list))
1482 && EQ (XCDR (XCAR (list)), key)))
1483 break;
1484
1485 list = XCDR (list);
1486 QUIT;
1487 }
1488
1489 if (NILP (list))
1490 result = Qnil;
1491 else if (CONSP (list))
1492 result = XCAR (list);
1493 else
1494 result = wrong_type_argument (Qlistp, list);
1495
1496 return result;
1497 }
1498
1499 DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
1500 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
1501 The value is actually the element of LIST whose cdr equals KEY.")
1502 (key, list)
1503 Lisp_Object key, list;
1504 {
1505 Lisp_Object result, cdr;
1506
1507 while (1)
1508 {
1509 if (!CONSP (list)
1510 || (CONSP (XCAR (list))
1511 && (cdr = XCDR (XCAR (list)),
1512 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1513 break;
1514
1515 list = XCDR (list);
1516 if (!CONSP (list)
1517 || (CONSP (XCAR (list))
1518 && (cdr = XCDR (XCAR (list)),
1519 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1520 break;
1521
1522 list = XCDR (list);
1523 if (!CONSP (list)
1524 || (CONSP (XCAR (list))
1525 && (cdr = XCDR (XCAR (list)),
1526 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1527 break;
1528
1529 list = XCDR (list);
1530 QUIT;
1531 }
1532
1533 if (CONSP (list))
1534 result = XCAR (list);
1535 else if (NILP (list))
1536 result = Qnil;
1537 else
1538 result = wrong_type_argument (Qlistp, list);
1539
1540 return result;
1541 }
1542 \f
1543 DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
1544 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1545 The modified LIST is returned. Comparison is done with `eq'.\n\
1546 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
1547 therefore, write `(setq foo (delq element foo))'\n\
1548 to be sure of changing the value of `foo'.")
1549 (elt, list)
1550 register Lisp_Object elt;
1551 Lisp_Object list;
1552 {
1553 register Lisp_Object tail, prev;
1554 register Lisp_Object tem;
1555
1556 tail = list;
1557 prev = Qnil;
1558 while (!NILP (tail))
1559 {
1560 if (! CONSP (tail))
1561 wrong_type_argument (Qlistp, list);
1562 tem = XCAR (tail);
1563 if (EQ (elt, tem))
1564 {
1565 if (NILP (prev))
1566 list = XCDR (tail);
1567 else
1568 Fsetcdr (prev, XCDR (tail));
1569 }
1570 else
1571 prev = tail;
1572 tail = XCDR (tail);
1573 QUIT;
1574 }
1575 return list;
1576 }
1577
1578 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
1579 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1580 The modified LIST is returned. Comparison is done with `equal'.\n\
1581 If the first member of LIST is ELT, deleting it is not a side effect;\n\
1582 it is simply using a different list.\n\
1583 Therefore, write `(setq foo (delete element foo))'\n\
1584 to be sure of changing the value of `foo'.")
1585 (elt, list)
1586 register Lisp_Object elt;
1587 Lisp_Object list;
1588 {
1589 register Lisp_Object tail, prev;
1590 register Lisp_Object tem;
1591
1592 tail = list;
1593 prev = Qnil;
1594 while (!NILP (tail))
1595 {
1596 if (! CONSP (tail))
1597 wrong_type_argument (Qlistp, list);
1598 tem = XCAR (tail);
1599 if (! NILP (Fequal (elt, tem)))
1600 {
1601 if (NILP (prev))
1602 list = XCDR (tail);
1603 else
1604 Fsetcdr (prev, XCDR (tail));
1605 }
1606 else
1607 prev = tail;
1608 tail = XCDR (tail);
1609 QUIT;
1610 }
1611 return list;
1612 }
1613
1614 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
1615 "Reverse LIST by modifying cdr pointers.\n\
1616 Returns the beginning of the reversed list.")
1617 (list)
1618 Lisp_Object list;
1619 {
1620 register Lisp_Object prev, tail, next;
1621
1622 if (NILP (list)) return list;
1623 prev = Qnil;
1624 tail = list;
1625 while (!NILP (tail))
1626 {
1627 QUIT;
1628 if (! CONSP (tail))
1629 wrong_type_argument (Qlistp, list);
1630 next = XCDR (tail);
1631 Fsetcdr (tail, prev);
1632 prev = tail;
1633 tail = next;
1634 }
1635 return prev;
1636 }
1637
1638 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
1639 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
1640 See also the function `nreverse', which is used more often.")
1641 (list)
1642 Lisp_Object list;
1643 {
1644 Lisp_Object new;
1645
1646 for (new = Qnil; CONSP (list); list = XCDR (list))
1647 new = Fcons (XCAR (list), new);
1648 if (!NILP (list))
1649 wrong_type_argument (Qconsp, list);
1650 return new;
1651 }
1652 \f
1653 Lisp_Object merge ();
1654
1655 DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
1656 "Sort LIST, stably, comparing elements using PREDICATE.\n\
1657 Returns the sorted list. LIST is modified by side effects.\n\
1658 PREDICATE is called with two elements of LIST, and should return T\n\
1659 if the first element is \"less\" than the second.")
1660 (list, predicate)
1661 Lisp_Object list, predicate;
1662 {
1663 Lisp_Object front, back;
1664 register Lisp_Object len, tem;
1665 struct gcpro gcpro1, gcpro2;
1666 register int length;
1667
1668 front = list;
1669 len = Flength (list);
1670 length = XINT (len);
1671 if (length < 2)
1672 return list;
1673
1674 XSETINT (len, (length / 2) - 1);
1675 tem = Fnthcdr (len, list);
1676 back = Fcdr (tem);
1677 Fsetcdr (tem, Qnil);
1678
1679 GCPRO2 (front, back);
1680 front = Fsort (front, predicate);
1681 back = Fsort (back, predicate);
1682 UNGCPRO;
1683 return merge (front, back, predicate);
1684 }
1685
1686 Lisp_Object
1687 merge (org_l1, org_l2, pred)
1688 Lisp_Object org_l1, org_l2;
1689 Lisp_Object pred;
1690 {
1691 Lisp_Object value;
1692 register Lisp_Object tail;
1693 Lisp_Object tem;
1694 register Lisp_Object l1, l2;
1695 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1696
1697 l1 = org_l1;
1698 l2 = org_l2;
1699 tail = Qnil;
1700 value = Qnil;
1701
1702 /* It is sufficient to protect org_l1 and org_l2.
1703 When l1 and l2 are updated, we copy the new values
1704 back into the org_ vars. */
1705 GCPRO4 (org_l1, org_l2, pred, value);
1706
1707 while (1)
1708 {
1709 if (NILP (l1))
1710 {
1711 UNGCPRO;
1712 if (NILP (tail))
1713 return l2;
1714 Fsetcdr (tail, l2);
1715 return value;
1716 }
1717 if (NILP (l2))
1718 {
1719 UNGCPRO;
1720 if (NILP (tail))
1721 return l1;
1722 Fsetcdr (tail, l1);
1723 return value;
1724 }
1725 tem = call2 (pred, Fcar (l2), Fcar (l1));
1726 if (NILP (tem))
1727 {
1728 tem = l1;
1729 l1 = Fcdr (l1);
1730 org_l1 = l1;
1731 }
1732 else
1733 {
1734 tem = l2;
1735 l2 = Fcdr (l2);
1736 org_l2 = l2;
1737 }
1738 if (NILP (tail))
1739 value = tem;
1740 else
1741 Fsetcdr (tail, tem);
1742 tail = tem;
1743 }
1744 }
1745 \f
1746
1747 DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
1748 "Extract a value from a property list.\n\
1749 PLIST is a property list, which is a list of the form\n\
1750 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
1751 corresponding to the given PROP, or nil if PROP is not\n\
1752 one of the properties on the list.")
1753 (plist, prop)
1754 Lisp_Object plist;
1755 register Lisp_Object prop;
1756 {
1757 register Lisp_Object tail;
1758 for (tail = plist; !NILP (tail); tail = Fcdr (XCDR (tail)))
1759 {
1760 register Lisp_Object tem;
1761 tem = Fcar (tail);
1762 if (EQ (prop, tem))
1763 return Fcar (XCDR (tail));
1764 }
1765 return Qnil;
1766 }
1767
1768 DEFUN ("get", Fget, Sget, 2, 2, 0,
1769 "Return the value of SYMBOL's PROPNAME property.\n\
1770 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
1771 (symbol, propname)
1772 Lisp_Object symbol, propname;
1773 {
1774 CHECK_SYMBOL (symbol, 0);
1775 return Fplist_get (XSYMBOL (symbol)->plist, propname);
1776 }
1777
1778 DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
1779 "Change value in PLIST of PROP to VAL.\n\
1780 PLIST is a property list, which is a list of the form\n\
1781 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
1782 If PROP is already a property on the list, its value is set to VAL,\n\
1783 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
1784 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
1785 The PLIST is modified by side effects.")
1786 (plist, prop, val)
1787 Lisp_Object plist;
1788 register Lisp_Object prop;
1789 Lisp_Object val;
1790 {
1791 register Lisp_Object tail, prev;
1792 Lisp_Object newcell;
1793 prev = Qnil;
1794 for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
1795 tail = XCDR (XCDR (tail)))
1796 {
1797 if (EQ (prop, XCAR (tail)))
1798 {
1799 Fsetcar (XCDR (tail), val);
1800 return plist;
1801 }
1802 prev = tail;
1803 }
1804 newcell = Fcons (prop, Fcons (val, Qnil));
1805 if (NILP (prev))
1806 return newcell;
1807 else
1808 Fsetcdr (XCDR (prev), newcell);
1809 return plist;
1810 }
1811
1812 DEFUN ("put", Fput, Sput, 3, 3, 0,
1813 "Store SYMBOL's PROPNAME property with value VALUE.\n\
1814 It can be retrieved with `(get SYMBOL PROPNAME)'.")
1815 (symbol, propname, value)
1816 Lisp_Object symbol, propname, value;
1817 {
1818 CHECK_SYMBOL (symbol, 0);
1819 XSYMBOL (symbol)->plist
1820 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1821 return value;
1822 }
1823
1824 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
1825 "Return t if two Lisp objects have similar structure and contents.\n\
1826 They must have the same data type.\n\
1827 Conses are compared by comparing the cars and the cdrs.\n\
1828 Vectors and strings are compared element by element.\n\
1829 Numbers are compared by value, but integers cannot equal floats.\n\
1830 (Use `=' if you want integers and floats to be able to be equal.)\n\
1831 Symbols must match exactly.")
1832 (o1, o2)
1833 register Lisp_Object o1, o2;
1834 {
1835 return internal_equal (o1, o2, 0) ? Qt : Qnil;
1836 }
1837
1838 static int
1839 internal_equal (o1, o2, depth)
1840 register Lisp_Object o1, o2;
1841 int depth;
1842 {
1843 if (depth > 200)
1844 error ("Stack overflow in equal");
1845
1846 tail_recurse:
1847 QUIT;
1848 if (EQ (o1, o2))
1849 return 1;
1850 if (XTYPE (o1) != XTYPE (o2))
1851 return 0;
1852
1853 switch (XTYPE (o1))
1854 {
1855 case Lisp_Float:
1856 return (extract_float (o1) == extract_float (o2));
1857
1858 case Lisp_Cons:
1859 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1))
1860 return 0;
1861 o1 = XCDR (o1);
1862 o2 = XCDR (o2);
1863 goto tail_recurse;
1864
1865 case Lisp_Misc:
1866 if (XMISCTYPE (o1) != XMISCTYPE (o2))
1867 return 0;
1868 if (OVERLAYP (o1))
1869 {
1870 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
1871 depth + 1)
1872 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
1873 depth + 1))
1874 return 0;
1875 o1 = XOVERLAY (o1)->plist;
1876 o2 = XOVERLAY (o2)->plist;
1877 goto tail_recurse;
1878 }
1879 if (MARKERP (o1))
1880 {
1881 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
1882 && (XMARKER (o1)->buffer == 0
1883 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
1884 }
1885 break;
1886
1887 case Lisp_Vectorlike:
1888 {
1889 register int i, size;
1890 size = XVECTOR (o1)->size;
1891 /* Pseudovectors have the type encoded in the size field, so this test
1892 actually checks that the objects have the same type as well as the
1893 same size. */
1894 if (XVECTOR (o2)->size != size)
1895 return 0;
1896 /* Boolvectors are compared much like strings. */
1897 if (BOOL_VECTOR_P (o1))
1898 {
1899 int size_in_chars
1900 = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1901
1902 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
1903 return 0;
1904 if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
1905 size_in_chars))
1906 return 0;
1907 return 1;
1908 }
1909 if (WINDOW_CONFIGURATIONP (o1))
1910 return compare_window_configurations (o1, o2, 0);
1911
1912 /* Aside from them, only true vectors, char-tables, and compiled
1913 functions are sensible to compare, so eliminate the others now. */
1914 if (size & PSEUDOVECTOR_FLAG)
1915 {
1916 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
1917 return 0;
1918 size &= PSEUDOVECTOR_SIZE_MASK;
1919 }
1920 for (i = 0; i < size; i++)
1921 {
1922 Lisp_Object v1, v2;
1923 v1 = XVECTOR (o1)->contents [i];
1924 v2 = XVECTOR (o2)->contents [i];
1925 if (!internal_equal (v1, v2, depth + 1))
1926 return 0;
1927 }
1928 return 1;
1929 }
1930 break;
1931
1932 case Lisp_String:
1933 if (XSTRING (o1)->size != XSTRING (o2)->size)
1934 return 0;
1935 if (STRING_BYTES (XSTRING (o1)) != STRING_BYTES (XSTRING (o2)))
1936 return 0;
1937 if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
1938 STRING_BYTES (XSTRING (o1))))
1939 return 0;
1940 return 1;
1941 }
1942 return 0;
1943 }
1944 \f
1945 extern Lisp_Object Fmake_char_internal ();
1946
1947 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
1948 "Store each element of ARRAY with ITEM.\n\
1949 ARRAY is a vector, string, char-table, or bool-vector.")
1950 (array, item)
1951 Lisp_Object array, item;
1952 {
1953 register int size, index, charval;
1954 retry:
1955 if (VECTORP (array))
1956 {
1957 register Lisp_Object *p = XVECTOR (array)->contents;
1958 size = XVECTOR (array)->size;
1959 for (index = 0; index < size; index++)
1960 p[index] = item;
1961 }
1962 else if (CHAR_TABLE_P (array))
1963 {
1964 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
1965 size = CHAR_TABLE_ORDINARY_SLOTS;
1966 for (index = 0; index < size; index++)
1967 p[index] = item;
1968 XCHAR_TABLE (array)->defalt = Qnil;
1969 }
1970 else if (STRINGP (array))
1971 {
1972 register unsigned char *p = XSTRING (array)->data;
1973 CHECK_NUMBER (item, 1);
1974 charval = XINT (item);
1975 size = XSTRING (array)->size;
1976 if (STRING_MULTIBYTE (array))
1977 {
1978 unsigned char str[MAX_MULTIBYTE_LENGTH];
1979 int len = CHAR_STRING (charval, str);
1980 int size_byte = STRING_BYTES (XSTRING (array));
1981 unsigned char *p1 = p, *endp = p + size_byte;
1982 int i;
1983
1984 if (size != size_byte)
1985 while (p1 < endp)
1986 {
1987 int this_len = MULTIBYTE_FORM_LENGTH (p1, endp - p1);
1988 if (len != this_len)
1989 error ("Attempt to change byte length of a string");
1990 p1 += this_len;
1991 }
1992 for (i = 0; i < size_byte; i++)
1993 *p++ = str[i % len];
1994 }
1995 else
1996 for (index = 0; index < size; index++)
1997 p[index] = charval;
1998 }
1999 else if (BOOL_VECTOR_P (array))
2000 {
2001 register unsigned char *p = XBOOL_VECTOR (array)->data;
2002 int size_in_chars
2003 = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
2004
2005 charval = (! NILP (item) ? -1 : 0);
2006 for (index = 0; index < size_in_chars; index++)
2007 p[index] = charval;
2008 }
2009 else
2010 {
2011 array = wrong_type_argument (Qarrayp, array);
2012 goto retry;
2013 }
2014 return array;
2015 }
2016 \f
2017 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
2018 1, 1, 0,
2019 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
2020 (char_table)
2021 Lisp_Object char_table;
2022 {
2023 CHECK_CHAR_TABLE (char_table, 0);
2024
2025 return XCHAR_TABLE (char_table)->purpose;
2026 }
2027
2028 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
2029 1, 1, 0,
2030 "Return the parent char-table of CHAR-TABLE.\n\
2031 The value is either nil or another char-table.\n\
2032 If CHAR-TABLE holds nil for a given character,\n\
2033 then the actual applicable value is inherited from the parent char-table\n\
2034 \(or from its parents, if necessary).")
2035 (char_table)
2036 Lisp_Object char_table;
2037 {
2038 CHECK_CHAR_TABLE (char_table, 0);
2039
2040 return XCHAR_TABLE (char_table)->parent;
2041 }
2042
2043 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
2044 2, 2, 0,
2045 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
2046 PARENT must be either nil or another char-table.")
2047 (char_table, parent)
2048 Lisp_Object char_table, parent;
2049 {
2050 Lisp_Object temp;
2051
2052 CHECK_CHAR_TABLE (char_table, 0);
2053
2054 if (!NILP (parent))
2055 {
2056 CHECK_CHAR_TABLE (parent, 0);
2057
2058 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
2059 if (EQ (temp, char_table))
2060 error ("Attempt to make a chartable be its own parent");
2061 }
2062
2063 XCHAR_TABLE (char_table)->parent = parent;
2064
2065 return parent;
2066 }
2067
2068 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
2069 2, 2, 0,
2070 "Return the value of CHAR-TABLE's extra-slot number N.")
2071 (char_table, n)
2072 Lisp_Object char_table, n;
2073 {
2074 CHECK_CHAR_TABLE (char_table, 1);
2075 CHECK_NUMBER (n, 2);
2076 if (XINT (n) < 0
2077 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
2078 args_out_of_range (char_table, n);
2079
2080 return XCHAR_TABLE (char_table)->extras[XINT (n)];
2081 }
2082
2083 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
2084 Sset_char_table_extra_slot,
2085 3, 3, 0,
2086 "Set CHAR-TABLE's extra-slot number N to VALUE.")
2087 (char_table, n, value)
2088 Lisp_Object char_table, n, value;
2089 {
2090 CHECK_CHAR_TABLE (char_table, 1);
2091 CHECK_NUMBER (n, 2);
2092 if (XINT (n) < 0
2093 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
2094 args_out_of_range (char_table, n);
2095
2096 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
2097 }
2098 \f
2099 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
2100 2, 2, 0,
2101 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
2102 RANGE should be nil (for the default value)\n\
2103 a vector which identifies a character set or a row of a character set,\n\
2104 a character set name, or a character code.")
2105 (char_table, range)
2106 Lisp_Object char_table, range;
2107 {
2108 CHECK_CHAR_TABLE (char_table, 0);
2109
2110 if (EQ (range, Qnil))
2111 return XCHAR_TABLE (char_table)->defalt;
2112 else if (INTEGERP (range))
2113 return Faref (char_table, range);
2114 else if (SYMBOLP (range))
2115 {
2116 Lisp_Object charset_info;
2117
2118 charset_info = Fget (range, Qcharset);
2119 CHECK_VECTOR (charset_info, 0);
2120
2121 return Faref (char_table,
2122 make_number (XINT (XVECTOR (charset_info)->contents[0])
2123 + 128));
2124 }
2125 else if (VECTORP (range))
2126 {
2127 if (XVECTOR (range)->size == 1)
2128 return Faref (char_table,
2129 make_number (XINT (XVECTOR (range)->contents[0]) + 128));
2130 else
2131 {
2132 int size = XVECTOR (range)->size;
2133 Lisp_Object *val = XVECTOR (range)->contents;
2134 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
2135 size <= 1 ? Qnil : val[1],
2136 size <= 2 ? Qnil : val[2]);
2137 return Faref (char_table, ch);
2138 }
2139 }
2140 else
2141 error ("Invalid RANGE argument to `char-table-range'");
2142 }
2143
2144 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
2145 3, 3, 0,
2146 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
2147 RANGE should be t (for all characters), nil (for the default value)\n\
2148 a vector which identifies a character set or a row of a character set,\n\
2149 a coding system, or a character code.")
2150 (char_table, range, value)
2151 Lisp_Object char_table, range, value;
2152 {
2153 int i;
2154
2155 CHECK_CHAR_TABLE (char_table, 0);
2156
2157 if (EQ (range, Qt))
2158 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
2159 XCHAR_TABLE (char_table)->contents[i] = value;
2160 else if (EQ (range, Qnil))
2161 XCHAR_TABLE (char_table)->defalt = value;
2162 else if (SYMBOLP (range))
2163 {
2164 Lisp_Object charset_info;
2165
2166 charset_info = Fget (range, Qcharset);
2167 CHECK_VECTOR (charset_info, 0);
2168
2169 return Faset (char_table,
2170 make_number (XINT (XVECTOR (charset_info)->contents[0])
2171 + 128),
2172 value);
2173 }
2174 else if (INTEGERP (range))
2175 Faset (char_table, range, value);
2176 else if (VECTORP (range))
2177 {
2178 if (XVECTOR (range)->size == 1)
2179 return Faset (char_table,
2180 make_number (XINT (XVECTOR (range)->contents[0]) + 128),
2181 value);
2182 else
2183 {
2184 int size = XVECTOR (range)->size;
2185 Lisp_Object *val = XVECTOR (range)->contents;
2186 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
2187 size <= 1 ? Qnil : val[1],
2188 size <= 2 ? Qnil : val[2]);
2189 return Faset (char_table, ch, value);
2190 }
2191 }
2192 else
2193 error ("Invalid RANGE argument to `set-char-table-range'");
2194
2195 return value;
2196 }
2197
2198 DEFUN ("set-char-table-default", Fset_char_table_default,
2199 Sset_char_table_default, 3, 3, 0,
2200 "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
2201 The generic character specifies the group of characters.\n\
2202 See also the documentation of make-char.")
2203 (char_table, ch, value)
2204 Lisp_Object char_table, ch, value;
2205 {
2206 int c, charset, code1, code2;
2207 Lisp_Object temp;
2208
2209 CHECK_CHAR_TABLE (char_table, 0);
2210 CHECK_NUMBER (ch, 1);
2211
2212 c = XINT (ch);
2213 SPLIT_CHAR (c, charset, code1, code2);
2214
2215 /* Since we may want to set the default value for a character set
2216 not yet defined, we check only if the character set is in the
2217 valid range or not, instead of it is already defined or not. */
2218 if (! CHARSET_VALID_P (charset))
2219 invalid_character (c);
2220
2221 if (charset == CHARSET_ASCII)
2222 return (XCHAR_TABLE (char_table)->defalt = value);
2223
2224 /* Even if C is not a generic char, we had better behave as if a
2225 generic char is specified. */
2226 if (CHARSET_DIMENSION (charset) == 1)
2227 code1 = 0;
2228 temp = XCHAR_TABLE (char_table)->contents[charset + 128];
2229 if (!code1)
2230 {
2231 if (SUB_CHAR_TABLE_P (temp))
2232 XCHAR_TABLE (temp)->defalt = value;
2233 else
2234 XCHAR_TABLE (char_table)->contents[charset + 128] = value;
2235 return value;
2236 }
2237 char_table = temp;
2238 if (! SUB_CHAR_TABLE_P (char_table))
2239 char_table = (XCHAR_TABLE (char_table)->contents[charset + 128]
2240 = make_sub_char_table (temp));
2241 temp = XCHAR_TABLE (char_table)->contents[code1];
2242 if (SUB_CHAR_TABLE_P (temp))
2243 XCHAR_TABLE (temp)->defalt = value;
2244 else
2245 XCHAR_TABLE (char_table)->contents[code1] = value;
2246 return value;
2247 }
2248
2249 /* Look up the element in TABLE at index CH,
2250 and return it as an integer.
2251 If the element is nil, return CH itself.
2252 (Actually we do that for any non-integer.) */
2253
2254 int
2255 char_table_translate (table, ch)
2256 Lisp_Object table;
2257 int ch;
2258 {
2259 Lisp_Object value;
2260 value = Faref (table, make_number (ch));
2261 if (! INTEGERP (value))
2262 return ch;
2263 return XINT (value);
2264 }
2265
2266 static void
2267 optimize_sub_char_table (table, chars)
2268 Lisp_Object *table;
2269 int chars;
2270 {
2271 Lisp_Object elt;
2272 int from, to;
2273
2274 if (chars == 94)
2275 from = 33, to = 127;
2276 else
2277 from = 32, to = 128;
2278
2279 if (!SUB_CHAR_TABLE_P (*table))
2280 return;
2281 elt = XCHAR_TABLE (*table)->contents[from++];
2282 for (; from < to; from++)
2283 if (NILP (Fequal (elt, XCHAR_TABLE (*table)->contents[from])))
2284 return;
2285 *table = elt;
2286 }
2287
2288 DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
2289 1, 1, 0,
2290 "Optimize char table TABLE.")
2291 (table)
2292 Lisp_Object table;
2293 {
2294 Lisp_Object elt;
2295 int dim;
2296 int i, j;
2297
2298 CHECK_CHAR_TABLE (table, 0);
2299
2300 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
2301 {
2302 elt = XCHAR_TABLE (table)->contents[i];
2303 if (!SUB_CHAR_TABLE_P (elt))
2304 continue;
2305 dim = CHARSET_DIMENSION (i);
2306 if (dim == 2)
2307 for (j = 32; j < SUB_CHAR_TABLE_ORDINARY_SLOTS; j++)
2308 optimize_sub_char_table (XCHAR_TABLE (elt)->contents + j, dim);
2309 optimize_sub_char_table (XCHAR_TABLE (table)->contents + i, dim);
2310 }
2311 return Qnil;
2312 }
2313
2314 \f
2315 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
2316 character or group of characters that share a value.
2317 DEPTH is the current depth in the originally specified
2318 chartable, and INDICES contains the vector indices
2319 for the levels our callers have descended.
2320
2321 ARG is passed to C_FUNCTION when that is called. */
2322
2323 void
2324 map_char_table (c_function, function, subtable, arg, depth, indices)
2325 void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
2326 Lisp_Object function, subtable, arg, *indices;
2327 int depth;
2328 {
2329 int i, to;
2330
2331 if (depth == 0)
2332 {
2333 /* At first, handle ASCII and 8-bit European characters. */
2334 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
2335 {
2336 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
2337 if (c_function)
2338 (*c_function) (arg, make_number (i), elt);
2339 else
2340 call2 (function, make_number (i), elt);
2341 }
2342 #if 0 /* If the char table has entries for higher characters,
2343 we should report them. */
2344 if (NILP (current_buffer->enable_multibyte_characters))
2345 return;
2346 #endif
2347 to = CHAR_TABLE_ORDINARY_SLOTS;
2348 }
2349 else
2350 {
2351 i = 32;
2352 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
2353 }
2354
2355 for (; i < to; i++)
2356 {
2357 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
2358
2359 XSETFASTINT (indices[depth], i);
2360
2361 if (SUB_CHAR_TABLE_P (elt))
2362 {
2363 if (depth >= 3)
2364 error ("Too deep char table");
2365 map_char_table (c_function, function, elt, arg, depth + 1, indices);
2366 }
2367 else
2368 {
2369 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
2370
2371 if (CHARSET_DEFINED_P (charset))
2372 {
2373 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
2374 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
2375 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
2376 if (c_function)
2377 (*c_function) (arg, make_number (c), elt);
2378 else
2379 call2 (function, make_number (c), elt);
2380 }
2381 }
2382 }
2383 }
2384
2385 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
2386 2, 2, 0,
2387 "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
2388 FUNCTION is called with two arguments--a key and a value.\n\
2389 The key is always a possible IDX argument to `aref'.")
2390 (function, char_table)
2391 Lisp_Object function, char_table;
2392 {
2393 /* The depth of char table is at most 3. */
2394 Lisp_Object indices[3];
2395
2396 CHECK_CHAR_TABLE (char_table, 1);
2397
2398 map_char_table (NULL, function, char_table, char_table, 0, indices);
2399 return Qnil;
2400 }
2401 \f
2402 /* ARGSUSED */
2403 Lisp_Object
2404 nconc2 (s1, s2)
2405 Lisp_Object s1, s2;
2406 {
2407 #ifdef NO_ARG_ARRAY
2408 Lisp_Object args[2];
2409 args[0] = s1;
2410 args[1] = s2;
2411 return Fnconc (2, args);
2412 #else
2413 return Fnconc (2, &s1);
2414 #endif /* NO_ARG_ARRAY */
2415 }
2416
2417 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
2418 "Concatenate any number of lists by altering them.\n\
2419 Only the last argument is not altered, and need not be a list.")
2420 (nargs, args)
2421 int nargs;
2422 Lisp_Object *args;
2423 {
2424 register int argnum;
2425 register Lisp_Object tail, tem, val;
2426
2427 val = Qnil;
2428
2429 for (argnum = 0; argnum < nargs; argnum++)
2430 {
2431 tem = args[argnum];
2432 if (NILP (tem)) continue;
2433
2434 if (NILP (val))
2435 val = tem;
2436
2437 if (argnum + 1 == nargs) break;
2438
2439 if (!CONSP (tem))
2440 tem = wrong_type_argument (Qlistp, tem);
2441
2442 while (CONSP (tem))
2443 {
2444 tail = tem;
2445 tem = Fcdr (tail);
2446 QUIT;
2447 }
2448
2449 tem = args[argnum + 1];
2450 Fsetcdr (tail, tem);
2451 if (NILP (tem))
2452 args[argnum + 1] = tail;
2453 }
2454
2455 return val;
2456 }
2457 \f
2458 /* This is the guts of all mapping functions.
2459 Apply FN to each element of SEQ, one by one,
2460 storing the results into elements of VALS, a C vector of Lisp_Objects.
2461 LENI is the length of VALS, which should also be the length of SEQ. */
2462
2463 static void
2464 mapcar1 (leni, vals, fn, seq)
2465 int leni;
2466 Lisp_Object *vals;
2467 Lisp_Object fn, seq;
2468 {
2469 register Lisp_Object tail;
2470 Lisp_Object dummy;
2471 register int i;
2472 struct gcpro gcpro1, gcpro2, gcpro3;
2473
2474 /* Don't let vals contain any garbage when GC happens. */
2475 for (i = 0; i < leni; i++)
2476 vals[i] = Qnil;
2477
2478 GCPRO3 (dummy, fn, seq);
2479 gcpro1.var = vals;
2480 gcpro1.nvars = leni;
2481 /* We need not explicitly protect `tail' because it is used only on lists, and
2482 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
2483
2484 if (VECTORP (seq))
2485 {
2486 for (i = 0; i < leni; i++)
2487 {
2488 dummy = XVECTOR (seq)->contents[i];
2489 vals[i] = call1 (fn, dummy);
2490 }
2491 }
2492 else if (BOOL_VECTOR_P (seq))
2493 {
2494 for (i = 0; i < leni; i++)
2495 {
2496 int byte;
2497 byte = XBOOL_VECTOR (seq)->data[i / BITS_PER_CHAR];
2498 if (byte & (1 << (i % BITS_PER_CHAR)))
2499 dummy = Qt;
2500 else
2501 dummy = Qnil;
2502
2503 vals[i] = call1 (fn, dummy);
2504 }
2505 }
2506 else if (STRINGP (seq) && ! STRING_MULTIBYTE (seq))
2507 {
2508 /* Single-byte string. */
2509 for (i = 0; i < leni; i++)
2510 {
2511 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
2512 vals[i] = call1 (fn, dummy);
2513 }
2514 }
2515 else if (STRINGP (seq))
2516 {
2517 /* Multi-byte string. */
2518 int i_byte;
2519
2520 for (i = 0, i_byte = 0; i < leni;)
2521 {
2522 int c;
2523 int i_before = i;
2524
2525 FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte);
2526 XSETFASTINT (dummy, c);
2527 vals[i_before] = call1 (fn, dummy);
2528 }
2529 }
2530 else /* Must be a list, since Flength did not get an error */
2531 {
2532 tail = seq;
2533 for (i = 0; i < leni; i++)
2534 {
2535 vals[i] = call1 (fn, Fcar (tail));
2536 tail = XCDR (tail);
2537 }
2538 }
2539
2540 UNGCPRO;
2541 }
2542
2543 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
2544 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
2545 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
2546 SEPARATOR results in spaces between the values returned by FUNCTION.\n\
2547 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2548 (function, sequence, separator)
2549 Lisp_Object function, sequence, separator;
2550 {
2551 Lisp_Object len;
2552 register int leni;
2553 int nargs;
2554 register Lisp_Object *args;
2555 register int i;
2556 struct gcpro gcpro1;
2557
2558 len = Flength (sequence);
2559 leni = XINT (len);
2560 nargs = leni + leni - 1;
2561 if (nargs < 0) return build_string ("");
2562
2563 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
2564
2565 GCPRO1 (separator);
2566 mapcar1 (leni, args, function, sequence);
2567 UNGCPRO;
2568
2569 for (i = leni - 1; i >= 0; i--)
2570 args[i + i] = args[i];
2571
2572 for (i = 1; i < nargs; i += 2)
2573 args[i] = separator;
2574
2575 return Fconcat (nargs, args);
2576 }
2577
2578 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
2579 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
2580 The result is a list just as long as SEQUENCE.\n\
2581 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2582 (function, sequence)
2583 Lisp_Object function, sequence;
2584 {
2585 register Lisp_Object len;
2586 register int leni;
2587 register Lisp_Object *args;
2588
2589 len = Flength (sequence);
2590 leni = XFASTINT (len);
2591 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
2592
2593 mapcar1 (leni, args, function, sequence);
2594
2595 return Flist (leni, args);
2596 }
2597 \f
2598 /* Anything that calls this function must protect from GC! */
2599
2600 DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
2601 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
2602 Takes one argument, which is the string to display to ask the question.\n\
2603 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
2604 No confirmation of the answer is requested; a single character is enough.\n\
2605 Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses\n\
2606 the bindings in `query-replace-map'; see the documentation of that variable\n\
2607 for more information. In this case, the useful bindings are `act', `skip',\n\
2608 `recenter', and `quit'.\)\n\
2609 \n\
2610 Under a windowing system a dialog box will be used if `last-nonmenu-event'\n\
2611 is nil.")
2612 (prompt)
2613 Lisp_Object prompt;
2614 {
2615 register Lisp_Object obj, key, def, map;
2616 register int answer;
2617 Lisp_Object xprompt;
2618 Lisp_Object args[2];
2619 struct gcpro gcpro1, gcpro2;
2620 int count = specpdl_ptr - specpdl;
2621
2622 specbind (Qcursor_in_echo_area, Qt);
2623
2624 map = Fsymbol_value (intern ("query-replace-map"));
2625
2626 CHECK_STRING (prompt, 0);
2627 xprompt = prompt;
2628 GCPRO2 (prompt, xprompt);
2629
2630 #ifdef HAVE_X_WINDOWS
2631 if (display_busy_cursor_p)
2632 cancel_busy_cursor ();
2633 #endif
2634
2635 while (1)
2636 {
2637
2638 #ifdef HAVE_MENUS
2639 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2640 && use_dialog_box
2641 && have_menus_p ())
2642 {
2643 Lisp_Object pane, menu;
2644 redisplay_preserve_echo_area ();
2645 pane = Fcons (Fcons (build_string ("Yes"), Qt),
2646 Fcons (Fcons (build_string ("No"), Qnil),
2647 Qnil));
2648 menu = Fcons (prompt, pane);
2649 obj = Fx_popup_dialog (Qt, menu);
2650 answer = !NILP (obj);
2651 break;
2652 }
2653 #endif /* HAVE_MENUS */
2654 cursor_in_echo_area = 1;
2655 choose_minibuf_frame ();
2656 message_with_string ("%s(y or n) ", xprompt, 0);
2657
2658 if (minibuffer_auto_raise)
2659 {
2660 Lisp_Object mini_frame;
2661
2662 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
2663
2664 Fraise_frame (mini_frame);
2665 }
2666
2667 obj = read_filtered_event (1, 0, 0, 0);
2668 cursor_in_echo_area = 0;
2669 /* If we need to quit, quit with cursor_in_echo_area = 0. */
2670 QUIT;
2671
2672 key = Fmake_vector (make_number (1), obj);
2673 def = Flookup_key (map, key, Qt);
2674
2675 if (EQ (def, intern ("skip")))
2676 {
2677 answer = 0;
2678 break;
2679 }
2680 else if (EQ (def, intern ("act")))
2681 {
2682 answer = 1;
2683 break;
2684 }
2685 else if (EQ (def, intern ("recenter")))
2686 {
2687 Frecenter (Qnil);
2688 xprompt = prompt;
2689 continue;
2690 }
2691 else if (EQ (def, intern ("quit")))
2692 Vquit_flag = Qt;
2693 /* We want to exit this command for exit-prefix,
2694 and this is the only way to do it. */
2695 else if (EQ (def, intern ("exit-prefix")))
2696 Vquit_flag = Qt;
2697
2698 QUIT;
2699
2700 /* If we don't clear this, then the next call to read_char will
2701 return quit_char again, and we'll enter an infinite loop. */
2702 Vquit_flag = Qnil;
2703
2704 Fding (Qnil);
2705 Fdiscard_input ();
2706 if (EQ (xprompt, prompt))
2707 {
2708 args[0] = build_string ("Please answer y or n. ");
2709 args[1] = prompt;
2710 xprompt = Fconcat (2, args);
2711 }
2712 }
2713 UNGCPRO;
2714
2715 if (! noninteractive)
2716 {
2717 cursor_in_echo_area = -1;
2718 message_with_string (answer ? "%s(y or n) y" : "%s(y or n) n",
2719 xprompt, 0);
2720 }
2721
2722 unbind_to (count, Qnil);
2723 return answer ? Qt : Qnil;
2724 }
2725 \f
2726 /* This is how C code calls `yes-or-no-p' and allows the user
2727 to redefined it.
2728
2729 Anything that calls this function must protect from GC! */
2730
2731 Lisp_Object
2732 do_yes_or_no_p (prompt)
2733 Lisp_Object prompt;
2734 {
2735 return call1 (intern ("yes-or-no-p"), prompt);
2736 }
2737
2738 /* Anything that calls this function must protect from GC! */
2739
2740 DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
2741 "Ask user a yes-or-no question. Return t if answer is yes.\n\
2742 Takes one argument, which is the string to display to ask the question.\n\
2743 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
2744 The user must confirm the answer with RET,\n\
2745 and can edit it until it has been confirmed.\n\
2746 \n\
2747 Under a windowing system a dialog box will be used if `last-nonmenu-event'\n\
2748 is nil.")
2749 (prompt)
2750 Lisp_Object prompt;
2751 {
2752 register Lisp_Object ans;
2753 Lisp_Object args[2];
2754 struct gcpro gcpro1;
2755
2756 CHECK_STRING (prompt, 0);
2757
2758 #ifdef HAVE_MENUS
2759 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2760 && use_dialog_box
2761 && have_menus_p ())
2762 {
2763 Lisp_Object pane, menu, obj;
2764 redisplay_preserve_echo_area ();
2765 pane = Fcons (Fcons (build_string ("Yes"), Qt),
2766 Fcons (Fcons (build_string ("No"), Qnil),
2767 Qnil));
2768 GCPRO1 (pane);
2769 menu = Fcons (prompt, pane);
2770 obj = Fx_popup_dialog (Qt, menu);
2771 UNGCPRO;
2772 return obj;
2773 }
2774 #endif /* HAVE_MENUS */
2775
2776 args[0] = prompt;
2777 args[1] = build_string ("(yes or no) ");
2778 prompt = Fconcat (2, args);
2779
2780 GCPRO1 (prompt);
2781
2782 while (1)
2783 {
2784 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
2785 Qyes_or_no_p_history, Qnil,
2786 Qnil));
2787 if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
2788 {
2789 UNGCPRO;
2790 return Qt;
2791 }
2792 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
2793 {
2794 UNGCPRO;
2795 return Qnil;
2796 }
2797
2798 Fding (Qnil);
2799 Fdiscard_input ();
2800 message ("Please answer yes or no.");
2801 Fsleep_for (make_number (2), Qnil);
2802 }
2803 }
2804 \f
2805 DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
2806 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
2807 Each of the three load averages is multiplied by 100,\n\
2808 then converted to integer.\n\
2809 When USE-FLOATS is non-nil, floats will be used instead of integers.\n\
2810 These floats are not multiplied by 100.\n\n\
2811 If the 5-minute or 15-minute load averages are not available, return a\n\
2812 shortened list, containing only those averages which are available.")
2813 (use_floats)
2814 Lisp_Object use_floats;
2815 {
2816 double load_ave[3];
2817 int loads = getloadavg (load_ave, 3);
2818 Lisp_Object ret = Qnil;
2819
2820 if (loads < 0)
2821 error ("load-average not implemented for this operating system");
2822
2823 while (loads-- > 0)
2824 {
2825 Lisp_Object load = (NILP (use_floats) ?
2826 make_number ((int) (100.0 * load_ave[loads]))
2827 : make_float (load_ave[loads]));
2828 ret = Fcons (load, ret);
2829 }
2830
2831 return ret;
2832 }
2833 \f
2834 Lisp_Object Vfeatures;
2835
2836 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
2837 "Returns t if FEATURE is present in this Emacs.\n\
2838 Use this to conditionalize execution of lisp code based on the presence or\n\
2839 absence of emacs or environment extensions.\n\
2840 Use `provide' to declare that a feature is available.\n\
2841 This function looks at the value of the variable `features'.")
2842 (feature)
2843 Lisp_Object feature;
2844 {
2845 register Lisp_Object tem;
2846 CHECK_SYMBOL (feature, 0);
2847 tem = Fmemq (feature, Vfeatures);
2848 return (NILP (tem)) ? Qnil : Qt;
2849 }
2850
2851 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
2852 "Announce that FEATURE is a feature of the current Emacs.")
2853 (feature)
2854 Lisp_Object feature;
2855 {
2856 register Lisp_Object tem;
2857 CHECK_SYMBOL (feature, 0);
2858 if (!NILP (Vautoload_queue))
2859 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
2860 tem = Fmemq (feature, Vfeatures);
2861 if (NILP (tem))
2862 Vfeatures = Fcons (feature, Vfeatures);
2863 LOADHIST_ATTACH (Fcons (Qprovide, feature));
2864 return feature;
2865 }
2866
2867 DEFUN ("require", Frequire, Srequire, 1, 3, 0,
2868 "If feature FEATURE is not loaded, load it from FILENAME.\n\
2869 If FEATURE is not a member of the list `features', then the feature\n\
2870 is not loaded; so load the file FILENAME.\n\
2871 If FILENAME is omitted, the printname of FEATURE is used as the file name,\n\
2872 but in this case `load' insists on adding the suffix `.el' or `.elc'.\n\
2873 If the optional third argument NOERROR is non-nil,\n\
2874 then return nil if the file is not found.\n\
2875 Normally the return value is FEATURE.")
2876 (feature, file_name, noerror)
2877 Lisp_Object feature, file_name, noerror;
2878 {
2879 register Lisp_Object tem;
2880 CHECK_SYMBOL (feature, 0);
2881 tem = Fmemq (feature, Vfeatures);
2882 LOADHIST_ATTACH (Fcons (Qrequire, feature));
2883 if (NILP (tem))
2884 {
2885 int count = specpdl_ptr - specpdl;
2886
2887 /* Value saved here is to be restored into Vautoload_queue */
2888 record_unwind_protect (un_autoload, Vautoload_queue);
2889 Vautoload_queue = Qt;
2890
2891 tem = Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
2892 noerror, Qt, Qnil, (NILP (file_name) ? Qt : Qnil));
2893 /* If load failed entirely, return nil. */
2894 if (NILP (tem))
2895 return unbind_to (count, Qnil);
2896
2897 tem = Fmemq (feature, Vfeatures);
2898 if (NILP (tem))
2899 error ("Required feature %s was not provided",
2900 XSYMBOL (feature)->name->data);
2901
2902 /* Once loading finishes, don't undo it. */
2903 Vautoload_queue = Qt;
2904 feature = unbind_to (count, feature);
2905 }
2906 return feature;
2907 }
2908 \f
2909 /* Primitives for work of the "widget" library.
2910 In an ideal world, this section would not have been necessary.
2911 However, lisp function calls being as slow as they are, it turns
2912 out that some functions in the widget library (wid-edit.el) are the
2913 bottleneck of Widget operation. Here is their translation to C,
2914 for the sole reason of efficiency. */
2915
2916 DEFUN ("widget-plist-member", Fwidget_plist_member, Swidget_plist_member, 2, 2, 0,
2917 "Return non-nil if PLIST has the property PROP.\n\
2918 PLIST is a property list, which is a list of the form\n\
2919 \(PROP1 VALUE1 PROP2 VALUE2 ...\). PROP is a symbol.\n\
2920 Unlike `plist-get', this allows you to distinguish between a missing\n\
2921 property and a property with the value nil.\n\
2922 The value is actually the tail of PLIST whose car is PROP.")
2923 (plist, prop)
2924 Lisp_Object plist, prop;
2925 {
2926 while (CONSP (plist) && !EQ (XCAR (plist), prop))
2927 {
2928 QUIT;
2929 plist = XCDR (plist);
2930 plist = CDR (plist);
2931 }
2932 return plist;
2933 }
2934
2935 DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
2936 "In WIDGET, set PROPERTY to VALUE.\n\
2937 The value can later be retrieved with `widget-get'.")
2938 (widget, property, value)
2939 Lisp_Object widget, property, value;
2940 {
2941 CHECK_CONS (widget, 1);
2942 XCDR (widget) = Fplist_put (XCDR (widget), property, value);
2943 return value;
2944 }
2945
2946 DEFUN ("widget-get", Fwidget_get, Swidget_get, 2, 2, 0,
2947 "In WIDGET, get the value of PROPERTY.\n\
2948 The value could either be specified when the widget was created, or\n\
2949 later with `widget-put'.")
2950 (widget, property)
2951 Lisp_Object widget, property;
2952 {
2953 Lisp_Object tmp;
2954
2955 while (1)
2956 {
2957 if (NILP (widget))
2958 return Qnil;
2959 CHECK_CONS (widget, 1);
2960 tmp = Fwidget_plist_member (XCDR (widget), property);
2961 if (CONSP (tmp))
2962 {
2963 tmp = XCDR (tmp);
2964 return CAR (tmp);
2965 }
2966 tmp = XCAR (widget);
2967 if (NILP (tmp))
2968 return Qnil;
2969 widget = Fget (tmp, Qwidget_type);
2970 }
2971 }
2972
2973 DEFUN ("widget-apply", Fwidget_apply, Swidget_apply, 2, MANY, 0,
2974 "Apply the value of WIDGET's PROPERTY to the widget itself.\n\
2975 ARGS are passed as extra arguments to the function.")
2976 (nargs, args)
2977 int nargs;
2978 Lisp_Object *args;
2979 {
2980 /* This function can GC. */
2981 Lisp_Object newargs[3];
2982 struct gcpro gcpro1, gcpro2;
2983 Lisp_Object result;
2984
2985 newargs[0] = Fwidget_get (args[0], args[1]);
2986 newargs[1] = args[0];
2987 newargs[2] = Flist (nargs - 2, args + 2);
2988 GCPRO2 (newargs[0], newargs[2]);
2989 result = Fapply (3, newargs);
2990 UNGCPRO;
2991 return result;
2992 }
2993 \f
2994 /* base64 encode/decode functions.
2995 Based on code from GNU recode. */
2996
2997 #define MIME_LINE_LENGTH 76
2998
2999 #define IS_ASCII(Character) \
3000 ((Character) < 128)
3001 #define IS_BASE64(Character) \
3002 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
3003 #define IS_BASE64_IGNORABLE(Character) \
3004 ((Character) == ' ' || (Character) == '\t' || (Character) == '\n' \
3005 || (Character) == '\f' || (Character) == '\r')
3006
3007 /* Used by base64_decode_1 to retrieve a non-base64-ignorable
3008 character or return retval if there are no characters left to
3009 process. */
3010 #define READ_QUADRUPLET_BYTE(retval) \
3011 do \
3012 { \
3013 if (i == length) \
3014 return (retval); \
3015 c = from[i++]; \
3016 } \
3017 while (IS_BASE64_IGNORABLE (c))
3018
3019 /* Don't use alloca for regions larger than this, lest we overflow
3020 their stack. */
3021 #define MAX_ALLOCA 16*1024
3022
3023 /* Table of characters coding the 64 values. */
3024 static char base64_value_to_char[64] =
3025 {
3026 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
3027 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
3028 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
3029 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
3030 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
3031 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
3032 '8', '9', '+', '/' /* 60-63 */
3033 };
3034
3035 /* Table of base64 values for first 128 characters. */
3036 static short base64_char_to_value[128] =
3037 {
3038 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
3039 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */
3040 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */
3041 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
3042 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
3043 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
3044 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
3045 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
3046 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
3047 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
3048 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
3049 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
3050 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
3051 };
3052
3053 /* The following diagram shows the logical steps by which three octets
3054 get transformed into four base64 characters.
3055
3056 .--------. .--------. .--------.
3057 |aaaaaabb| |bbbbcccc| |ccdddddd|
3058 `--------' `--------' `--------'
3059 6 2 4 4 2 6
3060 .--------+--------+--------+--------.
3061 |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
3062 `--------+--------+--------+--------'
3063
3064 .--------+--------+--------+--------.
3065 |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
3066 `--------+--------+--------+--------'
3067
3068 The octets are divided into 6 bit chunks, which are then encoded into
3069 base64 characters. */
3070
3071
3072 static int base64_encode_1 P_ ((const char *, char *, int, int));
3073 static int base64_decode_1 P_ ((const char *, char *, int));
3074
3075 DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region,
3076 2, 3, "r",
3077 "Base64-encode the region between BEG and END.\n\
3078 Return the length of the encoded text.\n\
3079 Optional third argument NO-LINE-BREAK means do not break long lines\n\
3080 into shorter lines.")
3081 (beg, end, no_line_break)
3082 Lisp_Object beg, end, no_line_break;
3083 {
3084 char *encoded;
3085 int allength, length;
3086 int ibeg, iend, encoded_length;
3087 int old_pos = PT;
3088
3089 validate_region (&beg, &end);
3090
3091 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
3092 iend = CHAR_TO_BYTE (XFASTINT (end));
3093 move_gap_both (XFASTINT (beg), ibeg);
3094
3095 /* We need to allocate enough room for encoding the text.
3096 We need 33 1/3% more space, plus a newline every 76
3097 characters, and then we round up. */
3098 length = iend - ibeg;
3099 allength = length + length/3 + 1;
3100 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3101
3102 if (allength <= MAX_ALLOCA)
3103 encoded = (char *) alloca (allength);
3104 else
3105 encoded = (char *) xmalloc (allength);
3106 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
3107 NILP (no_line_break));
3108 if (encoded_length > allength)
3109 abort ();
3110
3111 /* Now we have encoded the region, so we insert the new contents
3112 and delete the old. (Insert first in order to preserve markers.) */
3113 SET_PT_BOTH (XFASTINT (beg), ibeg);
3114 insert (encoded, encoded_length);
3115 if (allength > MAX_ALLOCA)
3116 xfree (encoded);
3117 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
3118
3119 /* If point was outside of the region, restore it exactly; else just
3120 move to the beginning of the region. */
3121 if (old_pos >= XFASTINT (end))
3122 old_pos += encoded_length - (XFASTINT (end) - XFASTINT (beg));
3123 else if (old_pos > XFASTINT (beg))
3124 old_pos = XFASTINT (beg);
3125 SET_PT (old_pos);
3126
3127 /* We return the length of the encoded text. */
3128 return make_number (encoded_length);
3129 }
3130
3131 DEFUN ("base64-encode-string", Fbase64_encode_string, Sbase64_encode_string,
3132 1, 2, 0,
3133 "Base64-encode STRING and return the result.\n\
3134 Optional second argument NO-LINE-BREAK means do not break long lines\n\
3135 into shorter lines.")
3136 (string, no_line_break)
3137 Lisp_Object string, no_line_break;
3138 {
3139 int allength, length, encoded_length;
3140 char *encoded;
3141 Lisp_Object encoded_string;
3142
3143 CHECK_STRING (string, 1);
3144
3145 /* We need to allocate enough room for encoding the text.
3146 We need 33 1/3% more space, plus a newline every 76
3147 characters, and then we round up. */
3148 length = STRING_BYTES (XSTRING (string));
3149 allength = length + length/3 + 1;
3150 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3151
3152 /* We need to allocate enough room for decoding the text. */
3153 if (allength <= MAX_ALLOCA)
3154 encoded = (char *) alloca (allength);
3155 else
3156 encoded = (char *) xmalloc (allength);
3157
3158 encoded_length = base64_encode_1 (XSTRING (string)->data,
3159 encoded, length, NILP (no_line_break));
3160 if (encoded_length > allength)
3161 abort ();
3162
3163 encoded_string = make_unibyte_string (encoded, encoded_length);
3164 if (allength > MAX_ALLOCA)
3165 xfree (encoded);
3166
3167 return encoded_string;
3168 }
3169
3170 static int
3171 base64_encode_1 (from, to, length, line_break)
3172 const char *from;
3173 char *to;
3174 int length;
3175 int line_break;
3176 {
3177 int counter = 0, i = 0;
3178 char *e = to;
3179 unsigned char c;
3180 unsigned int value;
3181
3182 while (i < length)
3183 {
3184 c = from[i++];
3185
3186 /* Wrap line every 76 characters. */
3187
3188 if (line_break)
3189 {
3190 if (counter < MIME_LINE_LENGTH / 4)
3191 counter++;
3192 else
3193 {
3194 *e++ = '\n';
3195 counter = 1;
3196 }
3197 }
3198
3199 /* Process first byte of a triplet. */
3200
3201 *e++ = base64_value_to_char[0x3f & c >> 2];
3202 value = (0x03 & c) << 4;
3203
3204 /* Process second byte of a triplet. */
3205
3206 if (i == length)
3207 {
3208 *e++ = base64_value_to_char[value];
3209 *e++ = '=';
3210 *e++ = '=';
3211 break;
3212 }
3213
3214 c = from[i++];
3215
3216 *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
3217 value = (0x0f & c) << 2;
3218
3219 /* Process third byte of a triplet. */
3220
3221 if (i == length)
3222 {
3223 *e++ = base64_value_to_char[value];
3224 *e++ = '=';
3225 break;
3226 }
3227
3228 c = from[i++];
3229
3230 *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
3231 *e++ = base64_value_to_char[0x3f & c];
3232 }
3233
3234 return e - to;
3235 }
3236
3237
3238 DEFUN ("base64-decode-region", Fbase64_decode_region, Sbase64_decode_region,
3239 2, 2, "r",
3240 "Base64-decode the region between BEG and END.\n\
3241 Return the length of the decoded text.\n\
3242 If the region can't be decoded, signal an error and don't modify the buffer.")
3243 (beg, end)
3244 Lisp_Object beg, end;
3245 {
3246 int ibeg, iend, length;
3247 char *decoded;
3248 int old_pos = PT;
3249 int decoded_length;
3250 int inserted_chars;
3251
3252 validate_region (&beg, &end);
3253
3254 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
3255 iend = CHAR_TO_BYTE (XFASTINT (end));
3256
3257 length = iend - ibeg;
3258 /* We need to allocate enough room for decoding the text. */
3259 if (length <= MAX_ALLOCA)
3260 decoded = (char *) alloca (length);
3261 else
3262 decoded = (char *) xmalloc (length);
3263
3264 move_gap_both (XFASTINT (beg), ibeg);
3265 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length);
3266 if (decoded_length > length)
3267 abort ();
3268
3269 if (decoded_length < 0)
3270 {
3271 /* The decoding wasn't possible. */
3272 if (length > MAX_ALLOCA)
3273 xfree (decoded);
3274 error ("Base64 decoding failed");
3275 }
3276
3277 /* Now we have decoded the region, so we insert the new contents
3278 and delete the old. (Insert first in order to preserve markers.) */
3279 /* We insert two spaces, then insert the decoded text in between
3280 them, at last, delete those extra two spaces. This is to avoid
3281 byte combining while inserting. */
3282 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
3283 insert_1_both (" ", 2, 2, 0, 1, 0);
3284 TEMP_SET_PT_BOTH (XFASTINT (beg) + 1, ibeg + 1);
3285 insert (decoded, decoded_length);
3286 inserted_chars = PT - (XFASTINT (beg) + 1);
3287 if (length > MAX_ALLOCA)
3288 xfree (decoded);
3289 /* At first delete the original text. This never causes byte
3290 combining. */
3291 del_range_both (PT + 1, PT_BYTE + 1, XFASTINT (end) + inserted_chars + 2,
3292 iend + decoded_length + 2, 1);
3293 /* Next delete the extra spaces. This will cause byte combining
3294 error. */
3295 del_range_both (PT, PT_BYTE, PT + 1, PT_BYTE + 1, 0);
3296 del_range_both (XFASTINT (beg), ibeg, XFASTINT (beg) + 1, ibeg + 1, 0);
3297 inserted_chars = PT - XFASTINT (beg);
3298
3299 /* If point was outside of the region, restore it exactly; else just
3300 move to the beginning of the region. */
3301 if (old_pos >= XFASTINT (end))
3302 old_pos += inserted_chars - (XFASTINT (end) - XFASTINT (beg));
3303 else if (old_pos > XFASTINT (beg))
3304 old_pos = XFASTINT (beg);
3305 SET_PT (old_pos > ZV ? ZV : old_pos);
3306
3307 return make_number (inserted_chars);
3308 }
3309
3310 DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3311 1, 1, 0,
3312 "Base64-decode STRING and return the result.")
3313 (string)
3314 Lisp_Object string;
3315 {
3316 char *decoded;
3317 int length, decoded_length;
3318 Lisp_Object decoded_string;
3319
3320 CHECK_STRING (string, 1);
3321
3322 length = STRING_BYTES (XSTRING (string));
3323 /* We need to allocate enough room for decoding the text. */
3324 if (length <= MAX_ALLOCA)
3325 decoded = (char *) alloca (length);
3326 else
3327 decoded = (char *) xmalloc (length);
3328
3329 decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length);
3330 if (decoded_length > length)
3331 abort ();
3332 else if (decoded_length >= 0)
3333 decoded_string = make_string (decoded, decoded_length);
3334 else
3335 decoded_string = Qnil;
3336
3337 if (length > MAX_ALLOCA)
3338 xfree (decoded);
3339 if (!STRINGP (decoded_string))
3340 error ("Base64 decoding failed");
3341
3342 return decoded_string;
3343 }
3344
3345 static int
3346 base64_decode_1 (from, to, length)
3347 const char *from;
3348 char *to;
3349 int length;
3350 {
3351 int i = 0;
3352 char *e = to;
3353 unsigned char c;
3354 unsigned long value;
3355
3356 while (1)
3357 {
3358 /* Process first byte of a quadruplet. */
3359
3360 READ_QUADRUPLET_BYTE (e-to);
3361
3362 if (!IS_BASE64 (c))
3363 return -1;
3364 value = base64_char_to_value[c] << 18;
3365
3366 /* Process second byte of a quadruplet. */
3367
3368 READ_QUADRUPLET_BYTE (-1);
3369
3370 if (!IS_BASE64 (c))
3371 return -1;
3372 value |= base64_char_to_value[c] << 12;
3373
3374 *e++ = (unsigned char) (value >> 16);
3375
3376 /* Process third byte of a quadruplet. */
3377
3378 READ_QUADRUPLET_BYTE (-1);
3379
3380 if (c == '=')
3381 {
3382 READ_QUADRUPLET_BYTE (-1);
3383
3384 if (c != '=')
3385 return -1;
3386 continue;
3387 }
3388
3389 if (!IS_BASE64 (c))
3390 return -1;
3391 value |= base64_char_to_value[c] << 6;
3392
3393 *e++ = (unsigned char) (0xff & value >> 8);
3394
3395 /* Process fourth byte of a quadruplet. */
3396
3397 READ_QUADRUPLET_BYTE (-1);
3398
3399 if (c == '=')
3400 continue;
3401
3402 if (!IS_BASE64 (c))
3403 return -1;
3404 value |= base64_char_to_value[c];
3405
3406 *e++ = (unsigned char) (0xff & value);
3407 }
3408 }
3409
3410
3411 \f
3412 /***********************************************************************
3413 ***** *****
3414 ***** Hash Tables *****
3415 ***** *****
3416 ***********************************************************************/
3417
3418 /* Implemented by gerd@gnu.org. This hash table implementation was
3419 inspired by CMUCL hash tables. */
3420
3421 /* Ideas:
3422
3423 1. For small tables, association lists are probably faster than
3424 hash tables because they have lower overhead.
3425
3426 For uses of hash tables where the O(1) behavior of table
3427 operations is not a requirement, it might therefore be a good idea
3428 not to hash. Instead, we could just do a linear search in the
3429 key_and_value vector of the hash table. This could be done
3430 if a `:linear-search t' argument is given to make-hash-table. */
3431
3432
3433 /* Return the contents of vector V at index IDX. */
3434
3435 #define AREF(V, IDX) XVECTOR (V)->contents[IDX]
3436
3437 /* Value is the key part of entry IDX in hash table H. */
3438
3439 #define HASH_KEY(H, IDX) AREF ((H)->key_and_value, 2 * (IDX))
3440
3441 /* Value is the value part of entry IDX in hash table H. */
3442
3443 #define HASH_VALUE(H, IDX) AREF ((H)->key_and_value, 2 * (IDX) + 1)
3444
3445 /* Value is the index of the next entry following the one at IDX
3446 in hash table H. */
3447
3448 #define HASH_NEXT(H, IDX) AREF ((H)->next, (IDX))
3449
3450 /* Value is the hash code computed for entry IDX in hash table H. */
3451
3452 #define HASH_HASH(H, IDX) AREF ((H)->hash, (IDX))
3453
3454 /* Value is the index of the element in hash table H that is the
3455 start of the collision list at index IDX in the index vector of H. */
3456
3457 #define HASH_INDEX(H, IDX) AREF ((H)->index, (IDX))
3458
3459 /* Value is the size of hash table H. */
3460
3461 #define HASH_TABLE_SIZE(H) XVECTOR ((H)->next)->size
3462
3463 /* The list of all weak hash tables. Don't staticpro this one. */
3464
3465 Lisp_Object Vweak_hash_tables;
3466
3467 /* Various symbols. */
3468
3469 Lisp_Object Qhash_table_p, Qeq, Qeql, Qequal, Qkey, Qvalue;
3470 Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
3471 Lisp_Object Qhash_table_test;
3472
3473 /* Function prototypes. */
3474
3475 static struct Lisp_Hash_Table *check_hash_table P_ ((Lisp_Object));
3476 static int next_almost_prime P_ ((int));
3477 static int get_key_arg P_ ((Lisp_Object, int, Lisp_Object *, char *));
3478 static void maybe_resize_hash_table P_ ((struct Lisp_Hash_Table *));
3479 static int cmpfn_eql P_ ((struct Lisp_Hash_Table *, Lisp_Object, unsigned,
3480 Lisp_Object, unsigned));
3481 static int cmpfn_equal P_ ((struct Lisp_Hash_Table *, Lisp_Object, unsigned,
3482 Lisp_Object, unsigned));
3483 static int cmpfn_user_defined P_ ((struct Lisp_Hash_Table *, Lisp_Object,
3484 unsigned, Lisp_Object, unsigned));
3485 static unsigned hashfn_eq P_ ((struct Lisp_Hash_Table *, Lisp_Object));
3486 static unsigned hashfn_eql P_ ((struct Lisp_Hash_Table *, Lisp_Object));
3487 static unsigned hashfn_equal P_ ((struct Lisp_Hash_Table *, Lisp_Object));
3488 static unsigned hashfn_user_defined P_ ((struct Lisp_Hash_Table *,
3489 Lisp_Object));
3490 static unsigned sxhash_string P_ ((unsigned char *, int));
3491 static unsigned sxhash_list P_ ((Lisp_Object, int));
3492 static unsigned sxhash_vector P_ ((Lisp_Object, int));
3493 static unsigned sxhash_bool_vector P_ ((Lisp_Object));
3494 static int sweep_weak_table P_ ((struct Lisp_Hash_Table *, int));
3495
3496
3497 \f
3498 /***********************************************************************
3499 Utilities
3500 ***********************************************************************/
3501
3502 /* If OBJ is a Lisp hash table, return a pointer to its struct
3503 Lisp_Hash_Table. Otherwise, signal an error. */
3504
3505 static struct Lisp_Hash_Table *
3506 check_hash_table (obj)
3507 Lisp_Object obj;
3508 {
3509 CHECK_HASH_TABLE (obj, 0);
3510 return XHASH_TABLE (obj);
3511 }
3512
3513
3514 /* Value is the next integer I >= N, N >= 0 which is "almost" a prime
3515 number. */
3516
3517 static int
3518 next_almost_prime (n)
3519 int n;
3520 {
3521 if (n % 2 == 0)
3522 n += 1;
3523 if (n % 3 == 0)
3524 n += 2;
3525 if (n % 7 == 0)
3526 n += 4;
3527 return n;
3528 }
3529
3530
3531 /* Find KEY in ARGS which has size NARGS. Don't consider indices for
3532 which USED[I] is non-zero. If found at index I in ARGS, set
3533 USED[I] and USED[I + 1] to 1, and return I + 1. Otherwise return
3534 -1. This function is used to extract a keyword/argument pair from
3535 a DEFUN parameter list. */
3536
3537 static int
3538 get_key_arg (key, nargs, args, used)
3539 Lisp_Object key;
3540 int nargs;
3541 Lisp_Object *args;
3542 char *used;
3543 {
3544 int i;
3545
3546 for (i = 0; i < nargs - 1; ++i)
3547 if (!used[i] && EQ (args[i], key))
3548 break;
3549
3550 if (i >= nargs - 1)
3551 i = -1;
3552 else
3553 {
3554 used[i++] = 1;
3555 used[i] = 1;
3556 }
3557
3558 return i;
3559 }
3560
3561
3562 /* Return a Lisp vector which has the same contents as VEC but has
3563 size NEW_SIZE, NEW_SIZE >= VEC->size. Entries in the resulting
3564 vector that are not copied from VEC are set to INIT. */
3565
3566 Lisp_Object
3567 larger_vector (vec, new_size, init)
3568 Lisp_Object vec;
3569 int new_size;
3570 Lisp_Object init;
3571 {
3572 struct Lisp_Vector *v;
3573 int i, old_size;
3574
3575 xassert (VECTORP (vec));
3576 old_size = XVECTOR (vec)->size;
3577 xassert (new_size >= old_size);
3578
3579 v = allocate_vectorlike (new_size);
3580 v->size = new_size;
3581 bcopy (XVECTOR (vec)->contents, v->contents,
3582 old_size * sizeof *v->contents);
3583 for (i = old_size; i < new_size; ++i)
3584 v->contents[i] = init;
3585 XSETVECTOR (vec, v);
3586 return vec;
3587 }
3588
3589
3590 /***********************************************************************
3591 Low-level Functions
3592 ***********************************************************************/
3593
3594 /* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3595 HASH2 in hash table H using `eql'. Value is non-zero if KEY1 and
3596 KEY2 are the same. */
3597
3598 static int
3599 cmpfn_eql (h, key1, hash1, key2, hash2)
3600 struct Lisp_Hash_Table *h;
3601 Lisp_Object key1, key2;
3602 unsigned hash1, hash2;
3603 {
3604 return (FLOATP (key1)
3605 && FLOATP (key2)
3606 && XFLOAT_DATA (key1) == XFLOAT_DATA (key2));
3607 }
3608
3609
3610 /* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3611 HASH2 in hash table H using `equal'. Value is non-zero if KEY1 and
3612 KEY2 are the same. */
3613
3614 static int
3615 cmpfn_equal (h, key1, hash1, key2, hash2)
3616 struct Lisp_Hash_Table *h;
3617 Lisp_Object key1, key2;
3618 unsigned hash1, hash2;
3619 {
3620 return hash1 == hash2 && !NILP (Fequal (key1, key2));
3621 }
3622
3623
3624 /* Compare KEY1 which has hash code HASH1, and KEY2 with hash code
3625 HASH2 in hash table H using H->user_cmp_function. Value is non-zero
3626 if KEY1 and KEY2 are the same. */
3627
3628 static int
3629 cmpfn_user_defined (h, key1, hash1, key2, hash2)
3630 struct Lisp_Hash_Table *h;
3631 Lisp_Object key1, key2;
3632 unsigned hash1, hash2;
3633 {
3634 if (hash1 == hash2)
3635 {
3636 Lisp_Object args[3];
3637
3638 args[0] = h->user_cmp_function;
3639 args[1] = key1;
3640 args[2] = key2;
3641 return !NILP (Ffuncall (3, args));
3642 }
3643 else
3644 return 0;
3645 }
3646
3647
3648 /* Value is a hash code for KEY for use in hash table H which uses
3649 `eq' to compare keys. The hash code returned is guaranteed to fit
3650 in a Lisp integer. */
3651
3652 static unsigned
3653 hashfn_eq (h, key)
3654 struct Lisp_Hash_Table *h;
3655 Lisp_Object key;
3656 {
3657 /* Lisp strings can change their address. Don't try to compute a
3658 hash code for a string from its address. */
3659 if (STRINGP (key))
3660 return sxhash_string (XSTRING (key)->data, XSTRING (key)->size);
3661 else
3662 return XUINT (key) ^ XGCTYPE (key);
3663 }
3664
3665
3666 /* Value is a hash code for KEY for use in hash table H which uses
3667 `eql' to compare keys. The hash code returned is guaranteed to fit
3668 in a Lisp integer. */
3669
3670 static unsigned
3671 hashfn_eql (h, key)
3672 struct Lisp_Hash_Table *h;
3673 Lisp_Object key;
3674 {
3675 /* Lisp strings can change their address. Don't try to compute a
3676 hash code for a string from its address. */
3677 if (STRINGP (key))
3678 return sxhash_string (XSTRING (key)->data, XSTRING (key)->size);
3679 else if (FLOATP (key))
3680 return sxhash (key, 0);
3681 else
3682 return XUINT (key) ^ XGCTYPE (key);
3683 }
3684
3685
3686 /* Value is a hash code for KEY for use in hash table H which uses
3687 `equal' to compare keys. The hash code returned is guaranteed to fit
3688 in a Lisp integer. */
3689
3690 static unsigned
3691 hashfn_equal (h, key)
3692 struct Lisp_Hash_Table *h;
3693 Lisp_Object key;
3694 {
3695 return sxhash (key, 0);
3696 }
3697
3698
3699 /* Value is a hash code for KEY for use in hash table H which uses as
3700 user-defined function to compare keys. The hash code returned is
3701 guaranteed to fit in a Lisp integer. */
3702
3703 static unsigned
3704 hashfn_user_defined (h, key)
3705 struct Lisp_Hash_Table *h;
3706 Lisp_Object key;
3707 {
3708 Lisp_Object args[2], hash;
3709
3710 args[0] = h->user_hash_function;
3711 args[1] = key;
3712 hash = Ffuncall (2, args);
3713 if (!INTEGERP (hash))
3714 Fsignal (Qerror,
3715 list2 (build_string ("Illegal hash code returned from \
3716 user-supplied hash function"),
3717 hash));
3718 return XUINT (hash);
3719 }
3720
3721
3722 /* Create and initialize a new hash table.
3723
3724 TEST specifies the test the hash table will use to compare keys.
3725 It must be either one of the predefined tests `eq', `eql' or
3726 `equal' or a symbol denoting a user-defined test named TEST with
3727 test and hash functions USER_TEST and USER_HASH.
3728
3729 Give the table initial capacity SIZE, SIZE > 0, an integer.
3730
3731 If REHASH_SIZE is an integer, it must be > 0, and this hash table's
3732 new size when it becomes full is computed by adding REHASH_SIZE to
3733 its old size. If REHASH_SIZE is a float, it must be > 1.0, and the
3734 table's new size is computed by multiplying its old size with
3735 REHASH_SIZE.
3736
3737 REHASH_THRESHOLD must be a float <= 1.0, and > 0. The table will
3738 be resized when the ratio of (number of entries in the table) /
3739 (table size) is >= REHASH_THRESHOLD.
3740
3741 WEAK specifies the weakness of the table. If non-nil, it must be
3742 one of the symbols `key', `value' or t. */
3743
3744 Lisp_Object
3745 make_hash_table (test, size, rehash_size, rehash_threshold, weak,
3746 user_test, user_hash)
3747 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
3748 Lisp_Object user_test, user_hash;
3749 {
3750 struct Lisp_Hash_Table *h;
3751 struct Lisp_Vector *v;
3752 Lisp_Object table;
3753 int index_size, i, len, sz;
3754
3755 /* Preconditions. */
3756 xassert (SYMBOLP (test));
3757 xassert (INTEGERP (size) && XINT (size) > 0);
3758 xassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
3759 || (FLOATP (rehash_size) && XFLOATINT (rehash_size) > 1.0));
3760 xassert (FLOATP (rehash_threshold)
3761 && XFLOATINT (rehash_threshold) > 0
3762 && XFLOATINT (rehash_threshold) <= 1.0);
3763
3764 /* Allocate a vector, and initialize it. */
3765 len = VECSIZE (struct Lisp_Hash_Table);
3766 v = allocate_vectorlike (len);
3767 v->size = len;
3768 for (i = 0; i < len; ++i)
3769 v->contents[i] = Qnil;
3770
3771 /* Initialize hash table slots. */
3772 sz = XFASTINT (size);
3773 h = (struct Lisp_Hash_Table *) v;
3774
3775 h->test = test;
3776 if (EQ (test, Qeql))
3777 {
3778 h->cmpfn = cmpfn_eql;
3779 h->hashfn = hashfn_eql;
3780 }
3781 else if (EQ (test, Qeq))
3782 {
3783 h->cmpfn = NULL;
3784 h->hashfn = hashfn_eq;
3785 }
3786 else if (EQ (test, Qequal))
3787 {
3788 h->cmpfn = cmpfn_equal;
3789 h->hashfn = hashfn_equal;
3790 }
3791 else
3792 {
3793 h->user_cmp_function = user_test;
3794 h->user_hash_function = user_hash;
3795 h->cmpfn = cmpfn_user_defined;
3796 h->hashfn = hashfn_user_defined;
3797 }
3798
3799 h->weak = weak;
3800 h->rehash_threshold = rehash_threshold;
3801 h->rehash_size = rehash_size;
3802 h->count = make_number (0);
3803 h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
3804 h->hash = Fmake_vector (size, Qnil);
3805 h->next = Fmake_vector (size, Qnil);
3806 index_size = next_almost_prime (sz / XFLOATINT (rehash_threshold));
3807 h->index = Fmake_vector (make_number (index_size), Qnil);
3808
3809 /* Set up the free list. */
3810 for (i = 0; i < sz - 1; ++i)
3811 HASH_NEXT (h, i) = make_number (i + 1);
3812 h->next_free = make_number (0);
3813
3814 XSET_HASH_TABLE (table, h);
3815 xassert (HASH_TABLE_P (table));
3816 xassert (XHASH_TABLE (table) == h);
3817
3818 /* Maybe add this hash table to the list of all weak hash tables. */
3819 if (NILP (h->weak))
3820 h->next_weak = Qnil;
3821 else
3822 {
3823 h->next_weak = Vweak_hash_tables;
3824 Vweak_hash_tables = table;
3825 }
3826
3827 return table;
3828 }
3829
3830
3831 /* Return a copy of hash table H1. Keys and values are not copied,
3832 only the table itself is. */
3833
3834 Lisp_Object
3835 copy_hash_table (h1)
3836 struct Lisp_Hash_Table *h1;
3837 {
3838 Lisp_Object table;
3839 struct Lisp_Hash_Table *h2;
3840 struct Lisp_Vector *v, *next;
3841 int len;
3842
3843 len = VECSIZE (struct Lisp_Hash_Table);
3844 v = allocate_vectorlike (len);
3845 h2 = (struct Lisp_Hash_Table *) v;
3846 next = h2->vec_next;
3847 bcopy (h1, h2, sizeof *h2);
3848 h2->vec_next = next;
3849 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
3850 h2->hash = Fcopy_sequence (h1->hash);
3851 h2->next = Fcopy_sequence (h1->next);
3852 h2->index = Fcopy_sequence (h1->index);
3853 XSET_HASH_TABLE (table, h2);
3854
3855 /* Maybe add this hash table to the list of all weak hash tables. */
3856 if (!NILP (h2->weak))
3857 {
3858 h2->next_weak = Vweak_hash_tables;
3859 Vweak_hash_tables = table;
3860 }
3861
3862 return table;
3863 }
3864
3865
3866 /* Resize hash table H if it's too full. If H cannot be resized
3867 because it's already too large, throw an error. */
3868
3869 static INLINE void
3870 maybe_resize_hash_table (h)
3871 struct Lisp_Hash_Table *h;
3872 {
3873 if (NILP (h->next_free))
3874 {
3875 int old_size = HASH_TABLE_SIZE (h);
3876 int i, new_size, index_size;
3877
3878 if (INTEGERP (h->rehash_size))
3879 new_size = old_size + XFASTINT (h->rehash_size);
3880 else
3881 new_size = old_size * XFLOATINT (h->rehash_size);
3882 new_size = max (old_size + 1, new_size);
3883 index_size = next_almost_prime (new_size
3884 / XFLOATINT (h->rehash_threshold));
3885 if (max (index_size, 2 * new_size) & ~VALMASK)
3886 error ("Hash table too large to resize");
3887
3888 h->key_and_value = larger_vector (h->key_and_value, 2 * new_size, Qnil);
3889 h->next = larger_vector (h->next, new_size, Qnil);
3890 h->hash = larger_vector (h->hash, new_size, Qnil);
3891 h->index = Fmake_vector (make_number (index_size), Qnil);
3892
3893 /* Update the free list. Do it so that new entries are added at
3894 the end of the free list. This makes some operations like
3895 maphash faster. */
3896 for (i = old_size; i < new_size - 1; ++i)
3897 HASH_NEXT (h, i) = make_number (i + 1);
3898
3899 if (!NILP (h->next_free))
3900 {
3901 Lisp_Object last, next;
3902
3903 last = h->next_free;
3904 while (next = HASH_NEXT (h, XFASTINT (last)),
3905 !NILP (next))
3906 last = next;
3907
3908 HASH_NEXT (h, XFASTINT (last)) = make_number (old_size);
3909 }
3910 else
3911 XSETFASTINT (h->next_free, old_size);
3912
3913 /* Rehash. */
3914 for (i = 0; i < old_size; ++i)
3915 if (!NILP (HASH_HASH (h, i)))
3916 {
3917 unsigned hash_code = XUINT (HASH_HASH (h, i));
3918 int start_of_bucket = hash_code % XVECTOR (h->index)->size;
3919 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3920 HASH_INDEX (h, start_of_bucket) = make_number (i);
3921 }
3922 }
3923 }
3924
3925
3926 /* Lookup KEY in hash table H. If HASH is non-null, return in *HASH
3927 the hash code of KEY. Value is the index of the entry in H
3928 matching KEY, or -1 if not found. */
3929
3930 int
3931 hash_lookup (h, key, hash)
3932 struct Lisp_Hash_Table *h;
3933 Lisp_Object key;
3934 unsigned *hash;
3935 {
3936 unsigned hash_code;
3937 int start_of_bucket;
3938 Lisp_Object idx;
3939
3940 hash_code = h->hashfn (h, key);
3941 if (hash)
3942 *hash = hash_code;
3943
3944 start_of_bucket = hash_code % XVECTOR (h->index)->size;
3945 idx = HASH_INDEX (h, start_of_bucket);
3946
3947 while (!NILP (idx))
3948 {
3949 int i = XFASTINT (idx);
3950 if (EQ (key, HASH_KEY (h, i))
3951 || (h->cmpfn
3952 && h->cmpfn (h, key, hash_code,
3953 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
3954 break;
3955 idx = HASH_NEXT (h, i);
3956 }
3957
3958 return NILP (idx) ? -1 : XFASTINT (idx);
3959 }
3960
3961
3962 /* Put an entry into hash table H that associates KEY with VALUE.
3963 HASH is a previously computed hash code of KEY.
3964 Value is the index of the entry in H matching KEY. */
3965
3966 int
3967 hash_put (h, key, value, hash)
3968 struct Lisp_Hash_Table *h;
3969 Lisp_Object key, value;
3970 unsigned hash;
3971 {
3972 int start_of_bucket, i;
3973
3974 xassert ((hash & ~VALMASK) == 0);
3975
3976 /* Increment count after resizing because resizing may fail. */
3977 maybe_resize_hash_table (h);
3978 h->count = make_number (XFASTINT (h->count) + 1);
3979
3980 /* Store key/value in the key_and_value vector. */
3981 i = XFASTINT (h->next_free);
3982 h->next_free = HASH_NEXT (h, i);
3983 HASH_KEY (h, i) = key;
3984 HASH_VALUE (h, i) = value;
3985
3986 /* Remember its hash code. */
3987 HASH_HASH (h, i) = make_number (hash);
3988
3989 /* Add new entry to its collision chain. */
3990 start_of_bucket = hash % XVECTOR (h->index)->size;
3991 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3992 HASH_INDEX (h, start_of_bucket) = make_number (i);
3993 return i;
3994 }
3995
3996
3997 /* Remove the entry matching KEY from hash table H, if there is one. */
3998
3999 void
4000 hash_remove (h, key)
4001 struct Lisp_Hash_Table *h;
4002 Lisp_Object key;
4003 {
4004 unsigned hash_code;
4005 int start_of_bucket;
4006 Lisp_Object idx, prev;
4007
4008 hash_code = h->hashfn (h, key);
4009 start_of_bucket = hash_code % XVECTOR (h->index)->size;
4010 idx = HASH_INDEX (h, start_of_bucket);
4011 prev = Qnil;
4012
4013 while (!NILP (idx))
4014 {
4015 int i = XFASTINT (idx);
4016
4017 if (EQ (key, HASH_KEY (h, i))
4018 || (h->cmpfn
4019 && h->cmpfn (h, key, hash_code,
4020 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
4021 {
4022 /* Take entry out of collision chain. */
4023 if (NILP (prev))
4024 HASH_INDEX (h, start_of_bucket) = HASH_NEXT (h, i);
4025 else
4026 HASH_NEXT (h, XFASTINT (prev)) = HASH_NEXT (h, i);
4027
4028 /* Clear slots in key_and_value and add the slots to
4029 the free list. */
4030 HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil;
4031 HASH_NEXT (h, i) = h->next_free;
4032 h->next_free = make_number (i);
4033 h->count = make_number (XFASTINT (h->count) - 1);
4034 xassert (XINT (h->count) >= 0);
4035 break;
4036 }
4037 else
4038 {
4039 prev = idx;
4040 idx = HASH_NEXT (h, i);
4041 }
4042 }
4043 }
4044
4045
4046 /* Clear hash table H. */
4047
4048 void
4049 hash_clear (h)
4050 struct Lisp_Hash_Table *h;
4051 {
4052 if (XFASTINT (h->count) > 0)
4053 {
4054 int i, size = HASH_TABLE_SIZE (h);
4055
4056 for (i = 0; i < size; ++i)
4057 {
4058 HASH_NEXT (h, i) = i < size - 1 ? make_number (i + 1) : Qnil;
4059 HASH_KEY (h, i) = Qnil;
4060 HASH_VALUE (h, i) = Qnil;
4061 HASH_HASH (h, i) = Qnil;
4062 }
4063
4064 for (i = 0; i < XVECTOR (h->index)->size; ++i)
4065 XVECTOR (h->index)->contents[i] = Qnil;
4066
4067 h->next_free = make_number (0);
4068 h->count = make_number (0);
4069 }
4070 }
4071
4072
4073 \f
4074 /************************************************************************
4075 Weak Hash Tables
4076 ************************************************************************/
4077
4078 /* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove
4079 entries from the table that don't survive the current GC.
4080 REMOVE_ENTRIES_P zero means mark entries that are in use. Value is
4081 non-zero if anything was marked. */
4082
4083 static int
4084 sweep_weak_table (h, remove_entries_p)
4085 struct Lisp_Hash_Table *h;
4086 int remove_entries_p;
4087 {
4088 int bucket, n, marked;
4089
4090 n = XVECTOR (h->index)->size & ~ARRAY_MARK_FLAG;
4091 marked = 0;
4092
4093 for (bucket = 0; bucket < n; ++bucket)
4094 {
4095 Lisp_Object idx, prev;
4096
4097 /* Follow collision chain, removing entries that
4098 don't survive this garbage collection. */
4099 idx = HASH_INDEX (h, bucket);
4100 prev = Qnil;
4101 while (!GC_NILP (idx))
4102 {
4103 int remove_p;
4104 int i = XFASTINT (idx);
4105 Lisp_Object next;
4106
4107 if (EQ (h->weak, Qkey))
4108 remove_p = !survives_gc_p (HASH_KEY (h, i));
4109 else if (EQ (h->weak, Qvalue))
4110 remove_p = !survives_gc_p (HASH_VALUE (h, i));
4111 else if (EQ (h->weak, Qt))
4112 remove_p = (!survives_gc_p (HASH_KEY (h, i))
4113 || !survives_gc_p (HASH_VALUE (h, i)));
4114 else
4115 abort ();
4116
4117 next = HASH_NEXT (h, i);
4118
4119 if (remove_entries_p)
4120 {
4121 if (remove_p)
4122 {
4123 /* Take out of collision chain. */
4124 if (GC_NILP (prev))
4125 HASH_INDEX (h, i) = next;
4126 else
4127 HASH_NEXT (h, XFASTINT (prev)) = next;
4128
4129 /* Add to free list. */
4130 HASH_NEXT (h, i) = h->next_free;
4131 h->next_free = idx;
4132
4133 /* Clear key, value, and hash. */
4134 HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil;
4135 HASH_HASH (h, i) = Qnil;
4136
4137 h->count = make_number (XFASTINT (h->count) - 1);
4138 }
4139 }
4140 else
4141 {
4142 if (!remove_p)
4143 {
4144 /* Make sure key and value survive. */
4145 mark_object (&HASH_KEY (h, i));
4146 mark_object (&HASH_VALUE (h, i));
4147 marked = 1;
4148 }
4149 }
4150
4151 idx = next;
4152 }
4153 }
4154
4155 return marked;
4156 }
4157
4158 /* Remove elements from weak hash tables that don't survive the
4159 current garbage collection. Remove weak tables that don't survive
4160 from Vweak_hash_tables. Called from gc_sweep. */
4161
4162 void
4163 sweep_weak_hash_tables ()
4164 {
4165 Lisp_Object table;
4166 struct Lisp_Hash_Table *h, *prev;
4167 int marked;
4168
4169 /* Mark all keys and values that are in use. Keep on marking until
4170 there is no more change. This is necessary for cases like
4171 value-weak table A containing an entry X -> Y, where Y is used in a
4172 key-weak table B, Z -> Y. If B comes after A in the list of weak
4173 tables, X -> Y might be removed from A, although when looking at B
4174 one finds that it shouldn't. */
4175 do
4176 {
4177 marked = 0;
4178 for (table = Vweak_hash_tables; !GC_NILP (table); table = h->next_weak)
4179 {
4180 h = XHASH_TABLE (table);
4181 if (h->size & ARRAY_MARK_FLAG)
4182 marked |= sweep_weak_table (h, 0);
4183 }
4184 }
4185 while (marked);
4186
4187 /* Remove tables and entries that aren't used. */
4188 prev = NULL;
4189 for (table = Vweak_hash_tables; !GC_NILP (table); table = h->next_weak)
4190 {
4191 prev = h;
4192 h = XHASH_TABLE (table);
4193
4194 if (h->size & ARRAY_MARK_FLAG)
4195 {
4196 if (XFASTINT (h->count) > 0)
4197 sweep_weak_table (h, 1);
4198 }
4199 else
4200 {
4201 /* Table is not marked, and will thus be freed.
4202 Take it out of the list of weak hash tables. */
4203 if (prev)
4204 prev->next_weak = h->next_weak;
4205 else
4206 Vweak_hash_tables = h->next_weak;
4207 }
4208 }
4209 }
4210
4211
4212 \f
4213 /***********************************************************************
4214 Hash Code Computation
4215 ***********************************************************************/
4216
4217 /* Maximum depth up to which to dive into Lisp structures. */
4218
4219 #define SXHASH_MAX_DEPTH 3
4220
4221 /* Maximum length up to which to take list and vector elements into
4222 account. */
4223
4224 #define SXHASH_MAX_LEN 7
4225
4226 /* Combine two integers X and Y for hashing. */
4227
4228 #define SXHASH_COMBINE(X, Y) \
4229 ((((unsigned)(X) << 4) + (((unsigned)(X) >> 24) & 0x0fffffff)) \
4230 + (unsigned)(Y))
4231
4232
4233 /* Return a hash for string PTR which has length LEN. */
4234
4235 static unsigned
4236 sxhash_string (ptr, len)
4237 unsigned char *ptr;
4238 int len;
4239 {
4240 unsigned char *p = ptr;
4241 unsigned char *end = p + len;
4242 unsigned char c;
4243 unsigned hash = 0;
4244
4245 while (p != end)
4246 {
4247 c = *p++;
4248 if (c >= 0140)
4249 c -= 40;
4250 hash = ((hash << 3) + (hash >> 28) + c);
4251 }
4252
4253 return hash & 07777777777;
4254 }
4255
4256
4257 /* Return a hash for list LIST. DEPTH is the current depth in the
4258 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
4259
4260 static unsigned
4261 sxhash_list (list, depth)
4262 Lisp_Object list;
4263 int depth;
4264 {
4265 unsigned hash = 0;
4266 int i;
4267
4268 if (depth < SXHASH_MAX_DEPTH)
4269 for (i = 0;
4270 CONSP (list) && i < SXHASH_MAX_LEN;
4271 list = XCDR (list), ++i)
4272 {
4273 unsigned hash2 = sxhash (XCAR (list), depth + 1);
4274 hash = SXHASH_COMBINE (hash, hash2);
4275 }
4276
4277 return hash;
4278 }
4279
4280
4281 /* Return a hash for vector VECTOR. DEPTH is the current depth in
4282 the Lisp structure. */
4283
4284 static unsigned
4285 sxhash_vector (vec, depth)
4286 Lisp_Object vec;
4287 int depth;
4288 {
4289 unsigned hash = XVECTOR (vec)->size;
4290 int i, n;
4291
4292 n = min (SXHASH_MAX_LEN, XVECTOR (vec)->size);
4293 for (i = 0; i < n; ++i)
4294 {
4295 unsigned hash2 = sxhash (XVECTOR (vec)->contents[i], depth + 1);
4296 hash = SXHASH_COMBINE (hash, hash2);
4297 }
4298
4299 return hash;
4300 }
4301
4302
4303 /* Return a hash for bool-vector VECTOR. */
4304
4305 static unsigned
4306 sxhash_bool_vector (vec)
4307 Lisp_Object vec;
4308 {
4309 unsigned hash = XBOOL_VECTOR (vec)->size;
4310 int i, n;
4311
4312 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->vector_size);
4313 for (i = 0; i < n; ++i)
4314 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
4315
4316 return hash;
4317 }
4318
4319
4320 /* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
4321 structure. Value is an unsigned integer clipped to VALMASK. */
4322
4323 unsigned
4324 sxhash (obj, depth)
4325 Lisp_Object obj;
4326 int depth;
4327 {
4328 unsigned hash;
4329
4330 if (depth > SXHASH_MAX_DEPTH)
4331 return 0;
4332
4333 switch (XTYPE (obj))
4334 {
4335 case Lisp_Int:
4336 hash = XUINT (obj);
4337 break;
4338
4339 case Lisp_Symbol:
4340 hash = sxhash_string (XSYMBOL (obj)->name->data,
4341 XSYMBOL (obj)->name->size);
4342 break;
4343
4344 case Lisp_Misc:
4345 hash = XUINT (obj);
4346 break;
4347
4348 case Lisp_String:
4349 hash = sxhash_string (XSTRING (obj)->data, XSTRING (obj)->size);
4350 break;
4351
4352 /* This can be everything from a vector to an overlay. */
4353 case Lisp_Vectorlike:
4354 if (VECTORP (obj))
4355 /* According to the CL HyperSpec, two arrays are equal only if
4356 they are `eq', except for strings and bit-vectors. In
4357 Emacs, this works differently. We have to compare element
4358 by element. */
4359 hash = sxhash_vector (obj, depth);
4360 else if (BOOL_VECTOR_P (obj))
4361 hash = sxhash_bool_vector (obj);
4362 else
4363 /* Others are `equal' if they are `eq', so let's take their
4364 address as hash. */
4365 hash = XUINT (obj);
4366 break;
4367
4368 case Lisp_Cons:
4369 hash = sxhash_list (obj, depth);
4370 break;
4371
4372 case Lisp_Float:
4373 {
4374 unsigned char *p = (unsigned char *) &XFLOAT_DATA (obj);
4375 unsigned char *e = p + sizeof XFLOAT_DATA (obj);
4376 for (hash = 0; p < e; ++p)
4377 hash = SXHASH_COMBINE (hash, *p);
4378 break;
4379 }
4380
4381 default:
4382 abort ();
4383 }
4384
4385 return hash & VALMASK;
4386 }
4387
4388
4389 \f
4390 /***********************************************************************
4391 Lisp Interface
4392 ***********************************************************************/
4393
4394
4395 DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
4396 "Compute a hash code for OBJ and return it as integer.")
4397 (obj)
4398 Lisp_Object obj;
4399 {
4400 unsigned hash = sxhash (obj, 0);;
4401 return make_number (hash);
4402 }
4403
4404
4405 DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
4406 "Create and return a new hash table.\n\
4407 Arguments are specified as keyword/argument pairs. The following\n\
4408 arguments are defined:\n\
4409 \n\
4410 :TEST TEST -- TEST must be a symbol that specifies how to compare keys.\n\
4411 Default is `eql'. Predefined are the tests `eq', `eql', and `equal'.\n\
4412 User-supplied test and hash functions can be specified via\n\
4413 `define-hash-table-test'.\n\
4414 \n\
4415 :SIZE SIZE -- A hint as to how many elements will be put in the table.\n\
4416 Default is 65.\n\
4417 \n\
4418 :REHASH-SIZE REHASH-SIZE - Indicates how to expand the table when\n\
4419 it fills up. If REHASH-SIZE is an integer, add that many space.\n\
4420 If it is a float, it must be > 1.0, and the new size is computed by\n\
4421 multiplying the old size with that factor. Default is 1.5.\n\
4422 \n\
4423 :REHASH-THRESHOLD THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.\n\
4424 Resize the hash table when ratio of the number of entries in the table.\n\
4425 Default is 0.8.\n\
4426 \n\
4427 :WEAKNESS WEAK -- WEAK must be one of nil, t, `key', or `value'.\n\
4428 If WEAK is not nil, the table returned is a weak table. Key/value\n\
4429 pairs are removed from a weak hash table when their key, value or both\n\
4430 (WEAK t) are otherwise unreferenced. Default is nil.")
4431 (nargs, args)
4432 int nargs;
4433 Lisp_Object *args;
4434 {
4435 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4436 Lisp_Object user_test, user_hash;
4437 char *used;
4438 int i;
4439
4440 /* The vector `used' is used to keep track of arguments that
4441 have been consumed. */
4442 used = (char *) alloca (nargs * sizeof *used);
4443 bzero (used, nargs * sizeof *used);
4444
4445 /* See if there's a `:test TEST' among the arguments. */
4446 i = get_key_arg (QCtest, nargs, args, used);
4447 test = i < 0 ? Qeql : args[i];
4448 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal))
4449 {
4450 /* See if it is a user-defined test. */
4451 Lisp_Object prop;
4452
4453 prop = Fget (test, Qhash_table_test);
4454 if (!CONSP (prop) || XFASTINT (Flength (prop)) < 2)
4455 Fsignal (Qerror, list2 (build_string ("Illegal hash table test"),
4456 test));
4457 user_test = Fnth (make_number (0), prop);
4458 user_hash = Fnth (make_number (1), prop);
4459 }
4460 else
4461 user_test = user_hash = Qnil;
4462
4463 /* See if there's a `:size SIZE' argument. */
4464 i = get_key_arg (QCsize, nargs, args, used);
4465 size = i < 0 ? make_number (DEFAULT_HASH_SIZE) : args[i];
4466 if (!INTEGERP (size) || XINT (size) <= 0)
4467 Fsignal (Qerror,
4468 list2 (build_string ("Illegal hash table size"),
4469 size));
4470
4471 /* Look for `:rehash-size SIZE'. */
4472 i = get_key_arg (QCrehash_size, nargs, args, used);
4473 rehash_size = i < 0 ? make_float (DEFAULT_REHASH_SIZE) : args[i];
4474 if (!NUMBERP (rehash_size)
4475 || (INTEGERP (rehash_size) && XINT (rehash_size) <= 0)
4476 || XFLOATINT (rehash_size) <= 1.0)
4477 Fsignal (Qerror,
4478 list2 (build_string ("Illegal hash table rehash size"),
4479 rehash_size));
4480
4481 /* Look for `:rehash-threshold THRESHOLD'. */
4482 i = get_key_arg (QCrehash_threshold, nargs, args, used);
4483 rehash_threshold = i < 0 ? make_float (DEFAULT_REHASH_THRESHOLD) : args[i];
4484 if (!FLOATP (rehash_threshold)
4485 || XFLOATINT (rehash_threshold) <= 0.0
4486 || XFLOATINT (rehash_threshold) > 1.0)
4487 Fsignal (Qerror,
4488 list2 (build_string ("Illegal hash table rehash threshold"),
4489 rehash_threshold));
4490
4491 /* Look for `:weakness WEAK'. */
4492 i = get_key_arg (QCweakness, nargs, args, used);
4493 weak = i < 0 ? Qnil : args[i];
4494 if (!NILP (weak)
4495 && !EQ (weak, Qt)
4496 && !EQ (weak, Qkey)
4497 && !EQ (weak, Qvalue))
4498 Fsignal (Qerror, list2 (build_string ("Illegal hash table weakness"),
4499 weak));
4500
4501 /* Now, all args should have been used up, or there's a problem. */
4502 for (i = 0; i < nargs; ++i)
4503 if (!used[i])
4504 Fsignal (Qerror,
4505 list2 (build_string ("Invalid argument list"), args[i]));
4506
4507 return make_hash_table (test, size, rehash_size, rehash_threshold, weak,
4508 user_test, user_hash);
4509 }
4510
4511
4512 DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
4513 "Return a copy of hash table TABLE.")
4514 (table)
4515 Lisp_Object table;
4516 {
4517 return copy_hash_table (check_hash_table (table));
4518 }
4519
4520
4521 DEFUN ("makehash", Fmakehash, Smakehash, 0, 1, 0,
4522 "Create a new hash table.\n\
4523 Optional first argument TEST specifies how to compare keys in\n\
4524 the table. Predefined tests are `eq', `eql', and `equal'. Default\n\
4525 is `eql'. New tests can be defined with `define-hash-table-test'.")
4526 (test)
4527 Lisp_Object test;
4528 {
4529 Lisp_Object args[2];
4530 args[0] = QCtest;
4531 args[1] = test;
4532 return Fmake_hash_table (2, args);
4533 }
4534
4535
4536 DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
4537 "Return the number of elements in TABLE.")
4538 (table)
4539 Lisp_Object table;
4540 {
4541 return check_hash_table (table)->count;
4542 }
4543
4544
4545 DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
4546 Shash_table_rehash_size, 1, 1, 0,
4547 "Return the current rehash size of TABLE.")
4548 (table)
4549 Lisp_Object table;
4550 {
4551 return check_hash_table (table)->rehash_size;
4552 }
4553
4554
4555 DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold,
4556 Shash_table_rehash_threshold, 1, 1, 0,
4557 "Return the current rehash threshold of TABLE.")
4558 (table)
4559 Lisp_Object table;
4560 {
4561 return check_hash_table (table)->rehash_threshold;
4562 }
4563
4564
4565 DEFUN ("hash-table-size", Fhash_table_size, Shash_table_size, 1, 1, 0,
4566 "Return the size of TABLE.\n\
4567 The size can be used as an argument to `make-hash-table' to create\n\
4568 a hash table than can hold as many elements of TABLE holds\n\
4569 without need for resizing.")
4570 (table)
4571 Lisp_Object table;
4572 {
4573 struct Lisp_Hash_Table *h = check_hash_table (table);
4574 return make_number (HASH_TABLE_SIZE (h));
4575 }
4576
4577
4578 DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
4579 "Return the test TABLE uses.")
4580 (table)
4581 Lisp_Object table;
4582 {
4583 return check_hash_table (table)->test;
4584 }
4585
4586
4587 DEFUN ("hash-table-weakness", Fhash_table_weakness, Shash_table_weakness,
4588 1, 1, 0,
4589 "Return the weakness of TABLE.")
4590 (table)
4591 Lisp_Object table;
4592 {
4593 return check_hash_table (table)->weak;
4594 }
4595
4596
4597 DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
4598 "Return t if OBJ is a Lisp hash table object.")
4599 (obj)
4600 Lisp_Object obj;
4601 {
4602 return HASH_TABLE_P (obj) ? Qt : Qnil;
4603 }
4604
4605
4606 DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
4607 "Clear hash table TABLE.")
4608 (table)
4609 Lisp_Object table;
4610 {
4611 hash_clear (check_hash_table (table));
4612 return Qnil;
4613 }
4614
4615
4616 DEFUN ("gethash", Fgethash, Sgethash, 2, 3, 0,
4617 "Look up KEY in TABLE and return its associated value.\n\
4618 If KEY is not found, return DFLT which defaults to nil.")
4619 (key, table, dflt)
4620 Lisp_Object key, table, dflt;
4621 {
4622 struct Lisp_Hash_Table *h = check_hash_table (table);
4623 int i = hash_lookup (h, key, NULL);
4624 return i >= 0 ? HASH_VALUE (h, i) : dflt;
4625 }
4626
4627
4628 DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
4629 "Associate KEY with VALUE is hash table TABLE.\n\
4630 If KEY is already present in table, replace its current value with\n\
4631 VALUE.")
4632 (key, value, table)
4633 Lisp_Object key, value, table;
4634 {
4635 struct Lisp_Hash_Table *h = check_hash_table (table);
4636 int i;
4637 unsigned hash;
4638
4639 i = hash_lookup (h, key, &hash);
4640 if (i >= 0)
4641 HASH_VALUE (h, i) = value;
4642 else
4643 hash_put (h, key, value, hash);
4644
4645 return Qnil;
4646 }
4647
4648
4649 DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
4650 "Remove KEY from TABLE.")
4651 (key, table)
4652 Lisp_Object key, table;
4653 {
4654 struct Lisp_Hash_Table *h = check_hash_table (table);
4655 hash_remove (h, key);
4656 return Qnil;
4657 }
4658
4659
4660 DEFUN ("maphash", Fmaphash, Smaphash, 2, 2, 0,
4661 "Call FUNCTION for all entries in hash table TABLE.\n\
4662 FUNCTION is called with 2 arguments KEY and VALUE.")
4663 (function, table)
4664 Lisp_Object function, table;
4665 {
4666 struct Lisp_Hash_Table *h = check_hash_table (table);
4667 Lisp_Object args[3];
4668 int i;
4669
4670 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
4671 if (!NILP (HASH_HASH (h, i)))
4672 {
4673 args[0] = function;
4674 args[1] = HASH_KEY (h, i);
4675 args[2] = HASH_VALUE (h, i);
4676 Ffuncall (3, args);
4677 }
4678
4679 return Qnil;
4680 }
4681
4682
4683 DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
4684 Sdefine_hash_table_test, 3, 3, 0,
4685 "Define a new hash table test with name NAME, a symbol.\n\
4686 In hash tables create with NAME specified as test, use TEST to compare\n\
4687 keys, and HASH for computing hash codes of keys.\n\
4688 \n\
4689 TEST must be a function taking two arguments and returning non-nil\n\
4690 if both arguments are the same. HASH must be a function taking\n\
4691 one argument and return an integer that is the hash code of the\n\
4692 argument. Hash code computation should use the whole value range of\n\
4693 integers, including negative integers.")
4694 (name, test, hash)
4695 Lisp_Object name, test, hash;
4696 {
4697 return Fput (name, Qhash_table_test, list2 (test, hash));
4698 }
4699
4700
4701
4702 \f
4703 void
4704 syms_of_fns ()
4705 {
4706 /* Hash table stuff. */
4707 Qhash_table_p = intern ("hash-table-p");
4708 staticpro (&Qhash_table_p);
4709 Qeq = intern ("eq");
4710 staticpro (&Qeq);
4711 Qeql = intern ("eql");
4712 staticpro (&Qeql);
4713 Qequal = intern ("equal");
4714 staticpro (&Qequal);
4715 QCtest = intern (":test");
4716 staticpro (&QCtest);
4717 QCsize = intern (":size");
4718 staticpro (&QCsize);
4719 QCrehash_size = intern (":rehash-size");
4720 staticpro (&QCrehash_size);
4721 QCrehash_threshold = intern (":rehash-threshold");
4722 staticpro (&QCrehash_threshold);
4723 QCweakness = intern (":weakness");
4724 staticpro (&QCweakness);
4725 Qkey = intern ("key");
4726 staticpro (&Qkey);
4727 Qvalue = intern ("value");
4728 staticpro (&Qvalue);
4729 Qhash_table_test = intern ("hash-table-test");
4730 staticpro (&Qhash_table_test);
4731
4732 defsubr (&Ssxhash);
4733 defsubr (&Smake_hash_table);
4734 defsubr (&Scopy_hash_table);
4735 defsubr (&Smakehash);
4736 defsubr (&Shash_table_count);
4737 defsubr (&Shash_table_rehash_size);
4738 defsubr (&Shash_table_rehash_threshold);
4739 defsubr (&Shash_table_size);
4740 defsubr (&Shash_table_test);
4741 defsubr (&Shash_table_weakness);
4742 defsubr (&Shash_table_p);
4743 defsubr (&Sclrhash);
4744 defsubr (&Sgethash);
4745 defsubr (&Sputhash);
4746 defsubr (&Sremhash);
4747 defsubr (&Smaphash);
4748 defsubr (&Sdefine_hash_table_test);
4749
4750 Qstring_lessp = intern ("string-lessp");
4751 staticpro (&Qstring_lessp);
4752 Qprovide = intern ("provide");
4753 staticpro (&Qprovide);
4754 Qrequire = intern ("require");
4755 staticpro (&Qrequire);
4756 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
4757 staticpro (&Qyes_or_no_p_history);
4758 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
4759 staticpro (&Qcursor_in_echo_area);
4760 Qwidget_type = intern ("widget-type");
4761 staticpro (&Qwidget_type);
4762
4763 staticpro (&string_char_byte_cache_string);
4764 string_char_byte_cache_string = Qnil;
4765
4766 Fset (Qyes_or_no_p_history, Qnil);
4767
4768 DEFVAR_LISP ("features", &Vfeatures,
4769 "A list of symbols which are the features of the executing emacs.\n\
4770 Used by `featurep' and `require', and altered by `provide'.");
4771 Vfeatures = Qnil;
4772
4773 DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
4774 "*Non-nil means mouse commands use dialog boxes to ask questions.\n\
4775 This applies to y-or-n and yes-or-no questions asked by commands\n\
4776 invoked by mouse clicks and mouse menu items.");
4777 use_dialog_box = 1;
4778
4779 defsubr (&Sidentity);
4780 defsubr (&Srandom);
4781 defsubr (&Slength);
4782 defsubr (&Ssafe_length);
4783 defsubr (&Sstring_bytes);
4784 defsubr (&Sstring_equal);
4785 defsubr (&Scompare_strings);
4786 defsubr (&Sstring_lessp);
4787 defsubr (&Sappend);
4788 defsubr (&Sconcat);
4789 defsubr (&Svconcat);
4790 defsubr (&Scopy_sequence);
4791 defsubr (&Sstring_make_multibyte);
4792 defsubr (&Sstring_make_unibyte);
4793 defsubr (&Sstring_as_multibyte);
4794 defsubr (&Sstring_as_unibyte);
4795 defsubr (&Scopy_alist);
4796 defsubr (&Ssubstring);
4797 defsubr (&Snthcdr);
4798 defsubr (&Snth);
4799 defsubr (&Selt);
4800 defsubr (&Smember);
4801 defsubr (&Smemq);
4802 defsubr (&Sassq);
4803 defsubr (&Sassoc);
4804 defsubr (&Srassq);
4805 defsubr (&Srassoc);
4806 defsubr (&Sdelq);
4807 defsubr (&Sdelete);
4808 defsubr (&Snreverse);
4809 defsubr (&Sreverse);
4810 defsubr (&Ssort);
4811 defsubr (&Splist_get);
4812 defsubr (&Sget);
4813 defsubr (&Splist_put);
4814 defsubr (&Sput);
4815 defsubr (&Sequal);
4816 defsubr (&Sfillarray);
4817 defsubr (&Schar_table_subtype);
4818 defsubr (&Schar_table_parent);
4819 defsubr (&Sset_char_table_parent);
4820 defsubr (&Schar_table_extra_slot);
4821 defsubr (&Sset_char_table_extra_slot);
4822 defsubr (&Schar_table_range);
4823 defsubr (&Sset_char_table_range);
4824 defsubr (&Sset_char_table_default);
4825 defsubr (&Soptimize_char_table);
4826 defsubr (&Smap_char_table);
4827 defsubr (&Snconc);
4828 defsubr (&Smapcar);
4829 defsubr (&Smapconcat);
4830 defsubr (&Sy_or_n_p);
4831 defsubr (&Syes_or_no_p);
4832 defsubr (&Sload_average);
4833 defsubr (&Sfeaturep);
4834 defsubr (&Srequire);
4835 defsubr (&Sprovide);
4836 defsubr (&Swidget_plist_member);
4837 defsubr (&Swidget_put);
4838 defsubr (&Swidget_get);
4839 defsubr (&Swidget_apply);
4840 defsubr (&Sbase64_encode_region);
4841 defsubr (&Sbase64_decode_region);
4842 defsubr (&Sbase64_encode_string);
4843 defsubr (&Sbase64_decode_string);
4844 }
4845
4846
4847 void
4848 init_fns ()
4849 {
4850 Vweak_hash_tables = Qnil;
4851 }