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