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