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