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