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