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