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