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