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