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