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