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