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