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