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