* lisp/term/xterm.el (xterm--version-handler): Adapt to xterm-280's output.
[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,
8cd86d04
LI
2428 doc: /* Ask user a yes-or-no question.
2429Return t if answer is yes, and nil if the answer is no.
9aea757b
CY
2430PROMPT is the string to display to ask the question. It should end in
2431a space; `yes-or-no-p' adds \"(yes or no) \" to it.
3d91e302
CY
2432
2433The user must confirm the answer with RET, and can edit it until it
2434has been confirmed.
47cebab1 2435
9f8551de
EZ
2436If dialog boxes are supported, a dialog box will be used
2437if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */)
5842a27b 2438 (Lisp_Object prompt)
7b863bd5
JB
2439{
2440 register Lisp_Object ans;
2441 Lisp_Object args[2];
2442 struct gcpro gcpro1;
2443
b7826503 2444 CHECK_STRING (prompt);
7b863bd5 2445
7452b7bd 2446 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
9f8551de 2447 && use_dialog_box)
1db4cfb2
RS
2448 {
2449 Lisp_Object pane, menu, obj;
3007ebfb 2450 redisplay_preserve_echo_area (4);
6c6f1994
PE
2451 pane = list2 (Fcons (build_string ("Yes"), Qt),
2452 Fcons (build_string ("No"), Qnil));
1db4cfb2 2453 GCPRO1 (pane);
ec26e1b9 2454 menu = Fcons (prompt, pane);
f0a31d70 2455 obj = Fx_popup_dialog (Qt, menu, Qnil);
1db4cfb2
RS
2456 UNGCPRO;
2457 return obj;
2458 }
2459
7b863bd5
JB
2460 args[0] = prompt;
2461 args[1] = build_string ("(yes or no) ");
2462 prompt = Fconcat (2, args);
2463
2464 GCPRO1 (prompt);
1db4cfb2 2465
7b863bd5
JB
2466 while (1)
2467 {
0ce830bc 2468 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
b24014d4 2469 Qyes_or_no_p_history, Qnil,
ba139299 2470 Qnil));
42a5b22f 2471 if (SCHARS (ans) == 3 && !strcmp (SSDATA (ans), "yes"))
7b863bd5
JB
2472 {
2473 UNGCPRO;
2474 return Qt;
2475 }
42a5b22f 2476 if (SCHARS (ans) == 2 && !strcmp (SSDATA (ans), "no"))
7b863bd5
JB
2477 {
2478 UNGCPRO;
2479 return Qnil;
2480 }
2481
2482 Fding (Qnil);
2483 Fdiscard_input ();
2f73da9c 2484 message1 ("Please answer yes or no.");
99dc4745 2485 Fsleep_for (make_number (2), Qnil);
7b863bd5 2486 }
7b863bd5
JB
2487}
2488\f
f4b50f66 2489DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
e9d8ddc9 2490 doc: /* Return list of 1 minute, 5 minute and 15 minute load averages.
91f78c99 2491
47cebab1
GM
2492Each of the three load averages is multiplied by 100, then converted
2493to integer.
2494
2495When USE-FLOATS is non-nil, floats will be used instead of integers.
2496These floats are not multiplied by 100.
2497
2498If the 5-minute or 15-minute load averages are not available, return a
30b1b0cf
DL
2499shortened list, containing only those averages which are available.
2500
2501An error is thrown if the load average can't be obtained. In some
2502cases making it work would require Emacs being installed setuid or
2503setgid so that it can read kernel information, and that usually isn't
2504advisable. */)
5842a27b 2505 (Lisp_Object use_floats)
7b863bd5 2506{
daa37602
JB
2507 double load_ave[3];
2508 int loads = getloadavg (load_ave, 3);
f4b50f66 2509 Lisp_Object ret = Qnil;
7b863bd5 2510
daa37602
JB
2511 if (loads < 0)
2512 error ("load-average not implemented for this operating system");
2513
f4b50f66
RS
2514 while (loads-- > 0)
2515 {
566684ea
PE
2516 Lisp_Object load = (NILP (use_floats)
2517 ? make_number (100.0 * load_ave[loads])
f4b50f66
RS
2518 : make_float (load_ave[loads]));
2519 ret = Fcons (load, ret);
2520 }
daa37602
JB
2521
2522 return ret;
2523}
7b863bd5 2524\f
955cbe7b 2525static Lisp_Object Qsubfeatures;
7b863bd5 2526
65550192 2527DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
b756c005 2528 doc: /* Return t if FEATURE is present in this Emacs.
91f78c99 2529
47cebab1 2530Use this to conditionalize execution of lisp code based on the
4774b68e 2531presence or absence of Emacs or environment extensions.
47cebab1
GM
2532Use `provide' to declare that a feature is available. This function
2533looks at the value of the variable `features'. The optional argument
e9d8ddc9 2534SUBFEATURE can be used to check a specific subfeature of FEATURE. */)
5842a27b 2535 (Lisp_Object feature, Lisp_Object subfeature)
7b863bd5
JB
2536{
2537 register Lisp_Object tem;
b7826503 2538 CHECK_SYMBOL (feature);
7b863bd5 2539 tem = Fmemq (feature, Vfeatures);
65550192 2540 if (!NILP (tem) && !NILP (subfeature))
37ebddef 2541 tem = Fmember (subfeature, Fget (feature, Qsubfeatures));
265a9e55 2542 return (NILP (tem)) ? Qnil : Qt;
7b863bd5
JB
2543}
2544
de0503df
SM
2545static Lisp_Object Qfuncall;
2546
a7ca3326 2547DEFUN ("provide", Fprovide, Sprovide, 1, 2, 0,
e9d8ddc9 2548 doc: /* Announce that FEATURE is a feature of the current Emacs.
47cebab1 2549The optional argument SUBFEATURES should be a list of symbols listing
e9d8ddc9 2550particular subfeatures supported in this version of FEATURE. */)
5842a27b 2551 (Lisp_Object feature, Lisp_Object subfeatures)
7b863bd5
JB
2552{
2553 register Lisp_Object tem;
b7826503 2554 CHECK_SYMBOL (feature);
37ebddef 2555 CHECK_LIST (subfeatures);
265a9e55 2556 if (!NILP (Vautoload_queue))
989e66e1
RS
2557 Vautoload_queue = Fcons (Fcons (make_number (0), Vfeatures),
2558 Vautoload_queue);
7b863bd5 2559 tem = Fmemq (feature, Vfeatures);
265a9e55 2560 if (NILP (tem))
7b863bd5 2561 Vfeatures = Fcons (feature, Vfeatures);
65550192
SM
2562 if (!NILP (subfeatures))
2563 Fput (feature, Qsubfeatures, subfeatures);
68732608 2564 LOADHIST_ATTACH (Fcons (Qprovide, feature));
65550192
SM
2565
2566 /* Run any load-hooks for this file. */
2567 tem = Fassq (feature, Vafter_load_alist);
cf42cb72 2568 if (CONSP (tem))
de0503df 2569 Fmapc (Qfuncall, XCDR (tem));
65550192 2570
7b863bd5
JB
2571 return feature;
2572}
1f79789d
RS
2573\f
2574/* `require' and its subroutines. */
2575
2576/* List of features currently being require'd, innermost first. */
2577
2a80c887 2578static Lisp_Object require_nesting_list;
1f79789d 2579
27e498e6 2580static void
971de7fb 2581require_unwind (Lisp_Object old_value)
1f79789d 2582{
27e498e6 2583 require_nesting_list = old_value;
1f79789d 2584}
7b863bd5 2585
53d5acf5 2586DEFUN ("require", Frequire, Srequire, 1, 3, 0,
e9d8ddc9 2587 doc: /* If feature FEATURE is not loaded, load it from FILENAME.
47cebab1
GM
2588If FEATURE is not a member of the list `features', then the feature
2589is not loaded; so load the file FILENAME.
2590If FILENAME is omitted, the printname of FEATURE is used as the file name,
6b61353c
KH
2591and `load' will try to load this name appended with the suffix `.elc' or
2592`.el', in that order. The name without appended suffix will not be used.
90186c68 2593See `get-load-suffixes' for the complete list of suffixes.
47cebab1
GM
2594If the optional third argument NOERROR is non-nil,
2595then return nil if the file is not found instead of signaling an error.
2596Normally the return value is FEATURE.
e9d8ddc9 2597The normal messages at start and end of loading FILENAME are suppressed. */)
5842a27b 2598 (Lisp_Object feature, Lisp_Object filename, Lisp_Object noerror)
7b863bd5 2599{
f75d7a91 2600 Lisp_Object tem;
1f79789d 2601 struct gcpro gcpro1, gcpro2;
f75d7a91 2602 bool from_file = load_in_progress;
1f79789d 2603
b7826503 2604 CHECK_SYMBOL (feature);
1f79789d 2605
5ba8f83d 2606 /* Record the presence of `require' in this file
9d5c2e7e
RS
2607 even if the feature specified is already loaded.
2608 But not more than once in any file,
06100606
RS
2609 and not when we aren't loading or reading from a file. */
2610 if (!from_file)
2611 for (tem = Vcurrent_load_list; CONSP (tem); tem = XCDR (tem))
2612 if (NILP (XCDR (tem)) && STRINGP (XCAR (tem)))
2613 from_file = 1;
2614
2615 if (from_file)
9d5c2e7e
RS
2616 {
2617 tem = Fcons (Qrequire, feature);
2618 if (NILP (Fmember (tem, Vcurrent_load_list)))
2619 LOADHIST_ATTACH (tem);
2620 }
7b863bd5 2621 tem = Fmemq (feature, Vfeatures);
91f78c99 2622
265a9e55 2623 if (NILP (tem))
7b863bd5 2624 {
d311d28c 2625 ptrdiff_t count = SPECPDL_INDEX ();
1f79789d 2626 int nesting = 0;
bcb31b2a 2627
aea6173f
RS
2628 /* This is to make sure that loadup.el gives a clear picture
2629 of what files are preloaded and when. */
bcb31b2a
RS
2630 if (! NILP (Vpurify_flag))
2631 error ("(require %s) while preparing to dump",
d5db4077 2632 SDATA (SYMBOL_NAME (feature)));
91f78c99 2633
1f79789d
RS
2634 /* A certain amount of recursive `require' is legitimate,
2635 but if we require the same feature recursively 3 times,
2636 signal an error. */
2637 tem = require_nesting_list;
2638 while (! NILP (tem))
2639 {
2640 if (! NILP (Fequal (feature, XCAR (tem))))
2641 nesting++;
2642 tem = XCDR (tem);
2643 }
f707342d 2644 if (nesting > 3)
1f79789d 2645 error ("Recursive `require' for feature `%s'",
d5db4077 2646 SDATA (SYMBOL_NAME (feature)));
1f79789d
RS
2647
2648 /* Update the list for any nested `require's that occur. */
2649 record_unwind_protect (require_unwind, require_nesting_list);
2650 require_nesting_list = Fcons (feature, require_nesting_list);
7b863bd5
JB
2651
2652 /* Value saved here is to be restored into Vautoload_queue */
2653 record_unwind_protect (un_autoload, Vautoload_queue);
2654 Vautoload_queue = Qt;
2655
1f79789d
RS
2656 /* Load the file. */
2657 GCPRO2 (feature, filename);
81a81c0f
GM
2658 tem = Fload (NILP (filename) ? Fsymbol_name (feature) : filename,
2659 noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil));
1f79789d
RS
2660 UNGCPRO;
2661
53d5acf5
RS
2662 /* If load failed entirely, return nil. */
2663 if (NILP (tem))
41857307 2664 return unbind_to (count, Qnil);
7b863bd5
JB
2665
2666 tem = Fmemq (feature, Vfeatures);
265a9e55 2667 if (NILP (tem))
1f79789d 2668 error ("Required feature `%s' was not provided",
d5db4077 2669 SDATA (SYMBOL_NAME (feature)));
7b863bd5
JB
2670
2671 /* Once loading finishes, don't undo it. */
2672 Vautoload_queue = Qt;
2673 feature = unbind_to (count, feature);
2674 }
1f79789d 2675
7b863bd5
JB
2676 return feature;
2677}
2678\f
b4f334f7
KH
2679/* Primitives for work of the "widget" library.
2680 In an ideal world, this section would not have been necessary.
2681 However, lisp function calls being as slow as they are, it turns
2682 out that some functions in the widget library (wid-edit.el) are the
2683 bottleneck of Widget operation. Here is their translation to C,
2684 for the sole reason of efficiency. */
2685
a7ca3326 2686DEFUN ("plist-member", Fplist_member, Splist_member, 2, 2, 0,
e9d8ddc9 2687 doc: /* Return non-nil if PLIST has the property PROP.
47cebab1
GM
2688PLIST is a property list, which is a list of the form
2689\(PROP1 VALUE1 PROP2 VALUE2 ...\). PROP is a symbol.
2690Unlike `plist-get', this allows you to distinguish between a missing
2691property and a property with the value nil.
e9d8ddc9 2692The value is actually the tail of PLIST whose car is PROP. */)
5842a27b 2693 (Lisp_Object plist, Lisp_Object prop)
b4f334f7
KH
2694{
2695 while (CONSP (plist) && !EQ (XCAR (plist), prop))
2696 {
2697 QUIT;
2698 plist = XCDR (plist);
2699 plist = CDR (plist);
2700 }
2701 return plist;
2702}
2703
2704DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
e9d8ddc9
MB
2705 doc: /* In WIDGET, set PROPERTY to VALUE.
2706The value can later be retrieved with `widget-get'. */)
5842a27b 2707 (Lisp_Object widget, Lisp_Object property, Lisp_Object value)
b4f334f7 2708{
b7826503 2709 CHECK_CONS (widget);
f3fbd155 2710 XSETCDR (widget, Fplist_put (XCDR (widget), property, value));
f7993597 2711 return value;
b4f334f7
KH
2712}
2713
2714DEFUN ("widget-get", Fwidget_get, Swidget_get, 2, 2, 0,
e9d8ddc9 2715 doc: /* In WIDGET, get the value of PROPERTY.
47cebab1 2716The value could either be specified when the widget was created, or
e9d8ddc9 2717later with `widget-put'. */)
5842a27b 2718 (Lisp_Object widget, Lisp_Object property)
b4f334f7
KH
2719{
2720 Lisp_Object tmp;
2721
2722 while (1)
2723 {
2724 if (NILP (widget))
2725 return Qnil;
b7826503 2726 CHECK_CONS (widget);
a5254817 2727 tmp = Fplist_member (XCDR (widget), property);
b4f334f7
KH
2728 if (CONSP (tmp))
2729 {
2730 tmp = XCDR (tmp);
2731 return CAR (tmp);
2732 }
2733 tmp = XCAR (widget);
2734 if (NILP (tmp))
2735 return Qnil;
2736 widget = Fget (tmp, Qwidget_type);
2737 }
2738}
2739
2740DEFUN ("widget-apply", Fwidget_apply, Swidget_apply, 2, MANY, 0,
e9d8ddc9 2741 doc: /* Apply the value of WIDGET's PROPERTY to the widget itself.
4bf8e2a3
MB
2742ARGS are passed as extra arguments to the function.
2743usage: (widget-apply WIDGET PROPERTY &rest ARGS) */)
f66c7cf8 2744 (ptrdiff_t nargs, Lisp_Object *args)
b4f334f7 2745{
b09cca6a 2746 /* This function can GC. */
b4f334f7
KH
2747 Lisp_Object newargs[3];
2748 struct gcpro gcpro1, gcpro2;
2749 Lisp_Object result;
2750
2751 newargs[0] = Fwidget_get (args[0], args[1]);
2752 newargs[1] = args[0];
2753 newargs[2] = Flist (nargs - 2, args + 2);
2754 GCPRO2 (newargs[0], newargs[2]);
2755 result = Fapply (3, newargs);
2756 UNGCPRO;
2757 return result;
2758}
dec002ca
DL
2759
2760#ifdef HAVE_LANGINFO_CODESET
2761#include <langinfo.h>
2762#endif
2763
d68beb2f
RS
2764DEFUN ("locale-info", Flocale_info, Slocale_info, 1, 1, 0,
2765 doc: /* Access locale data ITEM for the current C locale, if available.
2766ITEM should be one of the following:
30b1b0cf 2767
98aeeaa1 2768`codeset', returning the character set as a string (locale item CODESET);
30b1b0cf 2769
98aeeaa1 2770`days', returning a 7-element vector of day names (locale items DAY_n);
30b1b0cf 2771
98aeeaa1 2772`months', returning a 12-element vector of month names (locale items MON_n);
30b1b0cf 2773
d68beb2f 2774`paper', returning a list (WIDTH HEIGHT) for the default paper size,
66699ad3 2775 both measured in millimeters (locale items PAPER_WIDTH, PAPER_HEIGHT).
dec002ca
DL
2776
2777If the system can't provide such information through a call to
d68beb2f 2778`nl_langinfo', or if ITEM isn't from the list above, return nil.
dec002ca 2779
98aeeaa1
DL
2780See also Info node `(libc)Locales'.
2781
dec002ca 2782The data read from the system are decoded using `locale-coding-system'. */)
5842a27b 2783 (Lisp_Object item)
dec002ca
DL
2784{
2785 char *str = NULL;
2786#ifdef HAVE_LANGINFO_CODESET
2787 Lisp_Object val;
2788 if (EQ (item, Qcodeset))
2789 {
2790 str = nl_langinfo (CODESET);
2791 return build_string (str);
2792 }
2793#ifdef DAY_1
2794 else if (EQ (item, Qdays)) /* e.g. for calendar-day-name-array */
2795 {
2796 Lisp_Object v = Fmake_vector (make_number (7), Qnil);
77bf07e1 2797 const int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
dec002ca 2798 int i;
77bf07e1
AS
2799 struct gcpro gcpro1;
2800 GCPRO1 (v);
dec002ca
DL
2801 synchronize_system_time_locale ();
2802 for (i = 0; i < 7; i++)
2803 {
2804 str = nl_langinfo (days[i]);
d7ea76b4 2805 val = build_unibyte_string (str);
dec002ca
DL
2806 /* Fixme: Is this coding system necessarily right, even if
2807 it is consistent with CODESET? If not, what to do? */
9a9d91d9
DA
2808 ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system,
2809 0));
dec002ca 2810 }
77bf07e1 2811 UNGCPRO;
dec002ca
DL
2812 return v;
2813 }
2814#endif /* DAY_1 */
2815#ifdef MON_1
2816 else if (EQ (item, Qmonths)) /* e.g. for calendar-month-name-array */
2817 {
77bf07e1
AS
2818 Lisp_Object v = Fmake_vector (make_number (12), Qnil);
2819 const int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7,
2820 MON_8, MON_9, MON_10, MON_11, MON_12};
dec002ca 2821 int i;
77bf07e1
AS
2822 struct gcpro gcpro1;
2823 GCPRO1 (v);
dec002ca
DL
2824 synchronize_system_time_locale ();
2825 for (i = 0; i < 12; i++)
2826 {
2827 str = nl_langinfo (months[i]);
d7ea76b4 2828 val = build_unibyte_string (str);
9a9d91d9
DA
2829 ASET (v, i, code_convert_string_norecord (val, Vlocale_coding_system,
2830 0));
dec002ca 2831 }
77bf07e1
AS
2832 UNGCPRO;
2833 return v;
dec002ca
DL
2834 }
2835#endif /* MON_1 */
2836/* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1,
2837 but is in the locale files. This could be used by ps-print. */
2838#ifdef PAPER_WIDTH
2839 else if (EQ (item, Qpaper))
3de717bd 2840 return list2i (nl_langinfo (PAPER_WIDTH), nl_langinfo (PAPER_HEIGHT));
dec002ca
DL
2841#endif /* PAPER_WIDTH */
2842#endif /* HAVE_LANGINFO_CODESET*/
30b1b0cf 2843 return Qnil;
dec002ca 2844}
b4f334f7 2845\f
a90e80bf 2846/* base64 encode/decode functions (RFC 2045).
24c129e4
KH
2847 Based on code from GNU recode. */
2848
2849#define MIME_LINE_LENGTH 76
2850
2851#define IS_ASCII(Character) \
2852 ((Character) < 128)
2853#define IS_BASE64(Character) \
2854 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
9a092df0
PF
2855#define IS_BASE64_IGNORABLE(Character) \
2856 ((Character) == ' ' || (Character) == '\t' || (Character) == '\n' \
2857 || (Character) == '\f' || (Character) == '\r')
2858
2859/* Used by base64_decode_1 to retrieve a non-base64-ignorable
2860 character or return retval if there are no characters left to
2861 process. */
caff31d4
KH
2862#define READ_QUADRUPLET_BYTE(retval) \
2863 do \
2864 { \
2865 if (i == length) \
2866 { \
2867 if (nchars_return) \
2868 *nchars_return = nchars; \
2869 return (retval); \
2870 } \
2871 c = from[i++]; \
2872 } \
9a092df0 2873 while (IS_BASE64_IGNORABLE (c))
24c129e4
KH
2874
2875/* Table of characters coding the 64 values. */
91433552 2876static const char base64_value_to_char[64] =
24c129e4
KH
2877{
2878 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
2879 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
2880 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
2881 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
2882 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
2883 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
2884 '8', '9', '+', '/' /* 60-63 */
2885};
2886
2887/* Table of base64 values for first 128 characters. */
91433552 2888static const short base64_char_to_value[128] =
24c129e4
KH
2889{
2890 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
2891 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */
2892 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */
2893 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
2894 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
2895 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
2896 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
2897 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
2898 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
2899 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
2900 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
2901 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
2902 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
2903};
2904
2905/* The following diagram shows the logical steps by which three octets
2906 get transformed into four base64 characters.
2907
2908 .--------. .--------. .--------.
2909 |aaaaaabb| |bbbbcccc| |ccdddddd|
2910 `--------' `--------' `--------'
2911 6 2 4 4 2 6
2912 .--------+--------+--------+--------.
2913 |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
2914 `--------+--------+--------+--------'
2915
2916 .--------+--------+--------+--------.
2917 |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
2918 `--------+--------+--------+--------'
2919
2920 The octets are divided into 6 bit chunks, which are then encoded into
2921 base64 characters. */
2922
2923
f75d7a91
PE
2924static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, bool, bool);
2925static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, bool,
d311d28c 2926 ptrdiff_t *);
24c129e4
KH
2927
2928DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region,
2929 2, 3, "r",
e9d8ddc9 2930 doc: /* Base64-encode the region between BEG and END.
47cebab1
GM
2931Return the length of the encoded text.
2932Optional third argument NO-LINE-BREAK means do not break long lines
e9d8ddc9 2933into shorter lines. */)
5842a27b 2934 (Lisp_Object beg, Lisp_Object end, Lisp_Object no_line_break)
24c129e4
KH
2935{
2936 char *encoded;
d311d28c
PE
2937 ptrdiff_t allength, length;
2938 ptrdiff_t ibeg, iend, encoded_length;
2939 ptrdiff_t old_pos = PT;
799c08ac 2940 USE_SAFE_ALLOCA;
24c129e4
KH
2941
2942 validate_region (&beg, &end);
2943
2944 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
2945 iend = CHAR_TO_BYTE (XFASTINT (end));
2946 move_gap_both (XFASTINT (beg), ibeg);
2947
2948 /* We need to allocate enough room for encoding the text.
2949 We need 33 1/3% more space, plus a newline every 76
2950 characters, and then we round up. */
2951 length = iend - ibeg;
2952 allength = length + length/3 + 1;
2953 allength += allength / MIME_LINE_LENGTH + 1 + 6;
2954
98c6f1e3 2955 encoded = SAFE_ALLOCA (allength);
f1e59824
PE
2956 encoded_length = base64_encode_1 ((char *) BYTE_POS_ADDR (ibeg),
2957 encoded, length, NILP (no_line_break),
4b4deea2 2958 !NILP (BVAR (current_buffer, enable_multibyte_characters)));
24c129e4 2959 if (encoded_length > allength)
1088b922 2960 emacs_abort ();
24c129e4 2961
2efdd1b9
KH
2962 if (encoded_length < 0)
2963 {
2964 /* The encoding wasn't possible. */
233f3db6 2965 SAFE_FREE ();
a90e80bf 2966 error ("Multibyte character in data for base64 encoding");
2efdd1b9
KH
2967 }
2968
24c129e4
KH
2969 /* Now we have encoded the region, so we insert the new contents
2970 and delete the old. (Insert first in order to preserve markers.) */
8b835738 2971 SET_PT_BOTH (XFASTINT (beg), ibeg);
24c129e4 2972 insert (encoded, encoded_length);
233f3db6 2973 SAFE_FREE ();
24c129e4
KH
2974 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
2975
2976 /* If point was outside of the region, restore it exactly; else just
2977 move to the beginning of the region. */
2978 if (old_pos >= XFASTINT (end))
2979 old_pos += encoded_length - (XFASTINT (end) - XFASTINT (beg));
8b835738
AS
2980 else if (old_pos > XFASTINT (beg))
2981 old_pos = XFASTINT (beg);
24c129e4
KH
2982 SET_PT (old_pos);
2983
2984 /* We return the length of the encoded text. */
2985 return make_number (encoded_length);
2986}
2987
2988DEFUN ("base64-encode-string", Fbase64_encode_string, Sbase64_encode_string,
c22554ac 2989 1, 2, 0,
e9d8ddc9 2990 doc: /* Base64-encode STRING and return the result.
47cebab1 2991Optional second argument NO-LINE-BREAK means do not break long lines
e9d8ddc9 2992into shorter lines. */)
5842a27b 2993 (Lisp_Object string, Lisp_Object no_line_break)
24c129e4 2994{
d311d28c 2995 ptrdiff_t allength, length, encoded_length;
24c129e4 2996 char *encoded;
4b2e75e6 2997 Lisp_Object encoded_string;
799c08ac 2998 USE_SAFE_ALLOCA;
24c129e4 2999
b7826503 3000 CHECK_STRING (string);
24c129e4 3001
7f8a0840
KH
3002 /* We need to allocate enough room for encoding the text.
3003 We need 33 1/3% more space, plus a newline every 76
3004 characters, and then we round up. */
d5db4077 3005 length = SBYTES (string);
7f8a0840
KH
3006 allength = length + length/3 + 1;
3007 allength += allength / MIME_LINE_LENGTH + 1 + 6;
24c129e4
KH
3008
3009 /* We need to allocate enough room for decoding the text. */
98c6f1e3 3010 encoded = SAFE_ALLOCA (allength);
24c129e4 3011
42a5b22f 3012 encoded_length = base64_encode_1 (SSDATA (string),
2efdd1b9
KH
3013 encoded, length, NILP (no_line_break),
3014 STRING_MULTIBYTE (string));
24c129e4 3015 if (encoded_length > allength)
1088b922 3016 emacs_abort ();
24c129e4 3017
2efdd1b9
KH
3018 if (encoded_length < 0)
3019 {
3020 /* The encoding wasn't possible. */
233f3db6 3021 SAFE_FREE ();
a90e80bf 3022 error ("Multibyte character in data for base64 encoding");
2efdd1b9
KH
3023 }
3024
4b2e75e6 3025 encoded_string = make_unibyte_string (encoded, encoded_length);
233f3db6 3026 SAFE_FREE ();
4b2e75e6
EZ
3027
3028 return encoded_string;
24c129e4
KH
3029}
3030
d311d28c
PE
3031static ptrdiff_t
3032base64_encode_1 (const char *from, char *to, ptrdiff_t length,
f75d7a91 3033 bool line_break, bool multibyte)
24c129e4 3034{
e6d4aefa 3035 int counter = 0;
d311d28c 3036 ptrdiff_t i = 0;
24c129e4 3037 char *e = to;
844eb643 3038 int c;
24c129e4 3039 unsigned int value;
2efdd1b9 3040 int bytes;
24c129e4
KH
3041
3042 while (i < length)
3043 {
2efdd1b9
KH
3044 if (multibyte)
3045 {
f1e59824 3046 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes);
680d4b87
KH
3047 if (CHAR_BYTE8_P (c))
3048 c = CHAR_TO_BYTE8 (c);
3049 else if (c >= 256)
2efdd1b9 3050 return -1;
caff31d4 3051 i += bytes;
2efdd1b9
KH
3052 }
3053 else
3054 c = from[i++];
24c129e4
KH
3055
3056 /* Wrap line every 76 characters. */
3057
3058 if (line_break)
3059 {
3060 if (counter < MIME_LINE_LENGTH / 4)
3061 counter++;
3062 else
3063 {
3064 *e++ = '\n';
3065 counter = 1;
3066 }
3067 }
3068
3069 /* Process first byte of a triplet. */
3070
3071 *e++ = base64_value_to_char[0x3f & c >> 2];
3072 value = (0x03 & c) << 4;
3073
3074 /* Process second byte of a triplet. */
3075
3076 if (i == length)
3077 {
3078 *e++ = base64_value_to_char[value];
3079 *e++ = '=';
3080 *e++ = '=';
3081 break;
3082 }
3083
2efdd1b9
KH
3084 if (multibyte)
3085 {
f1e59824 3086 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes);
680d4b87
KH
3087 if (CHAR_BYTE8_P (c))
3088 c = CHAR_TO_BYTE8 (c);
3089 else if (c >= 256)
9b40fbe6 3090 return -1;
caff31d4 3091 i += bytes;
2efdd1b9
KH
3092 }
3093 else
3094 c = from[i++];
24c129e4
KH
3095
3096 *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
3097 value = (0x0f & c) << 2;
3098
3099 /* Process third byte of a triplet. */
3100
3101 if (i == length)
3102 {
3103 *e++ = base64_value_to_char[value];
3104 *e++ = '=';
3105 break;
3106 }
3107
2efdd1b9
KH
3108 if (multibyte)
3109 {
f1e59824 3110 c = STRING_CHAR_AND_LENGTH ((unsigned char *) from + i, bytes);
680d4b87
KH
3111 if (CHAR_BYTE8_P (c))
3112 c = CHAR_TO_BYTE8 (c);
3113 else if (c >= 256)
844eb643 3114 return -1;
caff31d4 3115 i += bytes;
2efdd1b9
KH
3116 }
3117 else
3118 c = from[i++];
24c129e4
KH
3119
3120 *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
3121 *e++ = base64_value_to_char[0x3f & c];
3122 }
3123
24c129e4
KH
3124 return e - to;
3125}
3126
3127
3128DEFUN ("base64-decode-region", Fbase64_decode_region, Sbase64_decode_region,
47cebab1 3129 2, 2, "r",
e9d8ddc9 3130 doc: /* Base64-decode the region between BEG and END.
47cebab1 3131Return the length of the decoded text.
e9d8ddc9 3132If the region can't be decoded, signal an error and don't modify the buffer. */)
5842a27b 3133 (Lisp_Object beg, Lisp_Object end)
24c129e4 3134{
d311d28c 3135 ptrdiff_t ibeg, iend, length, allength;
24c129e4 3136 char *decoded;
d311d28c
PE
3137 ptrdiff_t old_pos = PT;
3138 ptrdiff_t decoded_length;
3139 ptrdiff_t inserted_chars;
f75d7a91 3140 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
799c08ac 3141 USE_SAFE_ALLOCA;
24c129e4
KH
3142
3143 validate_region (&beg, &end);
3144
3145 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
3146 iend = CHAR_TO_BYTE (XFASTINT (end));
3147
3148 length = iend - ibeg;
caff31d4
KH
3149
3150 /* We need to allocate enough room for decoding the text. If we are
3151 working on a multibyte buffer, each decoded code may occupy at
3152 most two bytes. */
3153 allength = multibyte ? length * 2 : length;
98c6f1e3 3154 decoded = SAFE_ALLOCA (allength);
24c129e4
KH
3155
3156 move_gap_both (XFASTINT (beg), ibeg);
f1e59824
PE
3157 decoded_length = base64_decode_1 ((char *) BYTE_POS_ADDR (ibeg),
3158 decoded, length,
caff31d4
KH
3159 multibyte, &inserted_chars);
3160 if (decoded_length > allength)
1088b922 3161 emacs_abort ();
24c129e4
KH
3162
3163 if (decoded_length < 0)
8c217645
KH
3164 {
3165 /* The decoding wasn't possible. */
233f3db6 3166 SAFE_FREE ();
a90e80bf 3167 error ("Invalid base64 data");
8c217645 3168 }
24c129e4
KH
3169
3170 /* Now we have decoded the region, so we insert the new contents
3171 and delete the old. (Insert first in order to preserve markers.) */
59f953a2 3172 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
2efdd1b9 3173 insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0);
233f3db6 3174 SAFE_FREE ();
799c08ac 3175
2efdd1b9
KH
3176 /* Delete the original text. */
3177 del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars,
3178 iend + decoded_length, 1);
24c129e4
KH
3179
3180 /* If point was outside of the region, restore it exactly; else just
3181 move to the beginning of the region. */
3182 if (old_pos >= XFASTINT (end))
9b703a38
KH
3183 old_pos += inserted_chars - (XFASTINT (end) - XFASTINT (beg));
3184 else if (old_pos > XFASTINT (beg))
3185 old_pos = XFASTINT (beg);
e52ad9c9 3186 SET_PT (old_pos > ZV ? ZV : old_pos);
24c129e4 3187
9b703a38 3188 return make_number (inserted_chars);
24c129e4
KH
3189}
3190
3191DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3192 1, 1, 0,
e9d8ddc9 3193 doc: /* Base64-decode STRING and return the result. */)
5842a27b 3194 (Lisp_Object string)
24c129e4
KH
3195{
3196 char *decoded;
d311d28c 3197 ptrdiff_t length, decoded_length;
4b2e75e6 3198 Lisp_Object decoded_string;
799c08ac 3199 USE_SAFE_ALLOCA;
24c129e4 3200
b7826503 3201 CHECK_STRING (string);
24c129e4 3202
d5db4077 3203 length = SBYTES (string);
24c129e4 3204 /* We need to allocate enough room for decoding the text. */
98c6f1e3 3205 decoded = SAFE_ALLOCA (length);
24c129e4 3206
8ec118cd 3207 /* The decoded result should be unibyte. */
42a5b22f 3208 decoded_length = base64_decode_1 (SSDATA (string), decoded, length,
8ec118cd 3209 0, NULL);
24c129e4 3210 if (decoded_length > length)
1088b922 3211 emacs_abort ();
3d6c79c5 3212 else if (decoded_length >= 0)
2efdd1b9 3213 decoded_string = make_unibyte_string (decoded, decoded_length);
3d6c79c5
GM
3214 else
3215 decoded_string = Qnil;
24c129e4 3216
233f3db6 3217 SAFE_FREE ();
3d6c79c5 3218 if (!STRINGP (decoded_string))
a90e80bf 3219 error ("Invalid base64 data");
4b2e75e6
EZ
3220
3221 return decoded_string;
24c129e4
KH
3222}
3223
53964682 3224/* Base64-decode the data at FROM of LENGTH bytes into TO. If
f75d7a91 3225 MULTIBYTE, the decoded result should be in multibyte
9858f6c3 3226 form. If NCHARS_RETURN is not NULL, store the number of produced
caff31d4
KH
3227 characters in *NCHARS_RETURN. */
3228
d311d28c
PE
3229static ptrdiff_t
3230base64_decode_1 (const char *from, char *to, ptrdiff_t length,
f75d7a91 3231 bool multibyte, ptrdiff_t *nchars_return)
24c129e4 3232{
d311d28c 3233 ptrdiff_t i = 0; /* Used inside READ_QUADRUPLET_BYTE */
24c129e4
KH
3234 char *e = to;
3235 unsigned char c;
3236 unsigned long value;
d311d28c 3237 ptrdiff_t nchars = 0;
24c129e4 3238
9a092df0 3239 while (1)
24c129e4 3240 {
9a092df0 3241 /* Process first byte of a quadruplet. */
24c129e4 3242
9a092df0 3243 READ_QUADRUPLET_BYTE (e-to);
24c129e4
KH
3244
3245 if (!IS_BASE64 (c))
3246 return -1;
3247 value = base64_char_to_value[c] << 18;
3248
3249 /* Process second byte of a quadruplet. */
3250
9a092df0 3251 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
3252
3253 if (!IS_BASE64 (c))
3254 return -1;
3255 value |= base64_char_to_value[c] << 12;
3256
caff31d4 3257 c = (unsigned char) (value >> 16);
5a38b8c5
KH
3258 if (multibyte && c >= 128)
3259 e += BYTE8_STRING (c, e);
caff31d4
KH
3260 else
3261 *e++ = c;
3262 nchars++;
24c129e4
KH
3263
3264 /* Process third byte of a quadruplet. */
59f953a2 3265
9a092df0 3266 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
3267
3268 if (c == '=')
3269 {
9a092df0 3270 READ_QUADRUPLET_BYTE (-1);
59f953a2 3271
24c129e4
KH
3272 if (c != '=')
3273 return -1;
3274 continue;
3275 }
3276
3277 if (!IS_BASE64 (c))
3278 return -1;
3279 value |= base64_char_to_value[c] << 6;
3280
caff31d4 3281 c = (unsigned char) (0xff & value >> 8);
5a38b8c5
KH
3282 if (multibyte && c >= 128)
3283 e += BYTE8_STRING (c, e);
caff31d4
KH
3284 else
3285 *e++ = c;
3286 nchars++;
24c129e4
KH
3287
3288 /* Process fourth byte of a quadruplet. */
3289
9a092df0 3290 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
3291
3292 if (c == '=')
3293 continue;
3294
3295 if (!IS_BASE64 (c))
3296 return -1;
3297 value |= base64_char_to_value[c];
3298
caff31d4 3299 c = (unsigned char) (0xff & value);
5a38b8c5
KH
3300 if (multibyte && c >= 128)
3301 e += BYTE8_STRING (c, e);
caff31d4
KH
3302 else
3303 *e++ = c;
3304 nchars++;
24c129e4 3305 }
24c129e4 3306}
d80c6c11
GM
3307
3308
3309\f
3310/***********************************************************************
3311 ***** *****
3312 ***** Hash Tables *****
3313 ***** *****
3314 ***********************************************************************/
3315
3316/* Implemented by gerd@gnu.org. This hash table implementation was
3317 inspired by CMUCL hash tables. */
3318
3319/* Ideas:
3320
3321 1. For small tables, association lists are probably faster than
3322 hash tables because they have lower overhead.
3323
3324 For uses of hash tables where the O(1) behavior of table
3325 operations is not a requirement, it might therefore be a good idea
3326 not to hash. Instead, we could just do a linear search in the
3327 key_and_value vector of the hash table. This could be done
3328 if a `:linear-search t' argument is given to make-hash-table. */
3329
3330
d80c6c11
GM
3331/* The list of all weak hash tables. Don't staticpro this one. */
3332
dfcf3579 3333static struct Lisp_Hash_Table *weak_hash_tables;
d80c6c11
GM
3334
3335/* Various symbols. */
3336
84575e67
PE
3337static Lisp_Object Qhash_table_p;
3338static Lisp_Object Qkey, Qvalue, Qeql;
53371430 3339Lisp_Object Qeq, Qequal;
ee0403b3 3340Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
955cbe7b 3341static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
d80c6c11 3342
d80c6c11
GM
3343\f
3344/***********************************************************************
3345 Utilities
3346 ***********************************************************************/
3347
84575e67
PE
3348static void
3349CHECK_HASH_TABLE (Lisp_Object x)
3350{
3351 CHECK_TYPE (HASH_TABLE_P (x), Qhash_table_p, x);
3352}
3353
3354static void
3355set_hash_key_and_value (struct Lisp_Hash_Table *h, Lisp_Object key_and_value)
3356{
3357 h->key_and_value = key_and_value;
3358}
3359static void
3360set_hash_next (struct Lisp_Hash_Table *h, Lisp_Object next)
3361{
3362 h->next = next;
3363}
3364static void
3365set_hash_next_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3366{
3367 gc_aset (h->next, idx, val);
3368}
3369static void
3370set_hash_hash (struct Lisp_Hash_Table *h, Lisp_Object hash)
3371{
3372 h->hash = hash;
3373}
3374static void
3375set_hash_hash_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3376{
3377 gc_aset (h->hash, idx, val);
3378}
3379static void
3380set_hash_index (struct Lisp_Hash_Table *h, Lisp_Object index)
3381{
3382 h->index = index;
3383}
3384static void
3385set_hash_index_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
3386{
3387 gc_aset (h->index, idx, val);
3388}
3389
d80c6c11
GM
3390/* If OBJ is a Lisp hash table, return a pointer to its struct
3391 Lisp_Hash_Table. Otherwise, signal an error. */
3392
3393static struct Lisp_Hash_Table *
971de7fb 3394check_hash_table (Lisp_Object obj)
d80c6c11 3395{
b7826503 3396 CHECK_HASH_TABLE (obj);
d80c6c11
GM
3397 return XHASH_TABLE (obj);
3398}
3399
3400
3401/* Value is the next integer I >= N, N >= 0 which is "almost" a prime
ca9ce8f2
PE
3402 number. A number is "almost" a prime number if it is not divisible
3403 by any integer in the range 2 .. (NEXT_ALMOST_PRIME_LIMIT - 1). */
d80c6c11 3404
0de4bb68
PE
3405EMACS_INT
3406next_almost_prime (EMACS_INT n)
d80c6c11 3407{
ca9ce8f2 3408 verify (NEXT_ALMOST_PRIME_LIMIT == 11);
86fe5cfe
PE
3409 for (n |= 1; ; n += 2)
3410 if (n % 3 != 0 && n % 5 != 0 && n % 7 != 0)
3411 return n;
d80c6c11
GM
3412}
3413
3414
3415/* Find KEY in ARGS which has size NARGS. Don't consider indices for
3416 which USED[I] is non-zero. If found at index I in ARGS, set
3417 USED[I] and USED[I + 1] to 1, and return I + 1. Otherwise return
c5101a77 3418 0. This function is used to extract a keyword/argument pair from
d80c6c11
GM
3419 a DEFUN parameter list. */
3420
f66c7cf8
PE
3421static ptrdiff_t
3422get_key_arg (Lisp_Object key, ptrdiff_t nargs, Lisp_Object *args, char *used)
d80c6c11 3423{
f66c7cf8 3424 ptrdiff_t i;
59f953a2 3425
c5101a77
PE
3426 for (i = 1; i < nargs; i++)
3427 if (!used[i - 1] && EQ (args[i - 1], key))
3428 {
3429 used[i - 1] = 1;
3430 used[i] = 1;
3431 return i;
3432 }
59f953a2 3433
c5101a77 3434 return 0;
d80c6c11
GM
3435}
3436
3437
3438/* Return a Lisp vector which has the same contents as VEC but has
d311d28c
PE
3439 at least INCR_MIN more entries, where INCR_MIN is positive.
3440 If NITEMS_MAX is not -1, do not grow the vector to be any larger
3441 than NITEMS_MAX. Entries in the resulting
3442 vector that are not copied from VEC are set to nil. */
d80c6c11 3443
fa7dad5b 3444Lisp_Object
8c172e82 3445larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
d80c6c11
GM
3446{
3447 struct Lisp_Vector *v;
d311d28c 3448 ptrdiff_t i, incr, incr_max, old_size, new_size;
91f2d272 3449 ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents;
8c172e82
PE
3450 ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
3451 ? nitems_max : C_language_max);
a54e2c05
DA
3452 eassert (VECTORP (vec));
3453 eassert (0 < incr_min && -1 <= nitems_max);
7edbb0da 3454 old_size = ASIZE (vec);
d311d28c
PE
3455 incr_max = n_max - old_size;
3456 incr = max (incr_min, min (old_size >> 1, incr_max));
3457 if (incr_max < incr)
3458 memory_full (SIZE_MAX);
3459 new_size = old_size + incr;
b3660ef6 3460 v = allocate_vector (new_size);
91f2d272 3461 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
d80c6c11 3462 for (i = old_size; i < new_size; ++i)
91f2d272 3463 v->contents[i] = Qnil;
d80c6c11
GM
3464 XSETVECTOR (vec, v);
3465 return vec;
3466}
3467
3468
3469/***********************************************************************
3470 Low-level Functions
3471 ***********************************************************************/
3472
53371430
PE
3473static struct hash_table_test hashtest_eq;
3474struct hash_table_test hashtest_eql, hashtest_equal;
b7432bb2 3475
d80c6c11 3476/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
f75d7a91 3477 HASH2 in hash table H using `eql'. Value is true if KEY1 and
d80c6c11
GM
3478 KEY2 are the same. */
3479
f75d7a91 3480static bool
b7432bb2
SM
3481cmpfn_eql (struct hash_table_test *ht,
3482 Lisp_Object key1,
3483 Lisp_Object key2)
d80c6c11 3484{
2e5da676
GM
3485 return (FLOATP (key1)
3486 && FLOATP (key2)
e84b1dea 3487 && XFLOAT_DATA (key1) == XFLOAT_DATA (key2));
d80c6c11
GM
3488}
3489
3490
3491/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
f75d7a91 3492 HASH2 in hash table H using `equal'. Value is true if KEY1 and
d80c6c11
GM
3493 KEY2 are the same. */
3494
f75d7a91 3495static bool
b7432bb2
SM
3496cmpfn_equal (struct hash_table_test *ht,
3497 Lisp_Object key1,
3498 Lisp_Object key2)
d80c6c11 3499{
b7432bb2 3500 return !NILP (Fequal (key1, key2));
d80c6c11
GM
3501}
3502
59f953a2 3503
d80c6c11 3504/* Compare KEY1 which has hash code HASH1, and KEY2 with hash code
f75d7a91 3505 HASH2 in hash table H using H->user_cmp_function. Value is true
d80c6c11
GM
3506 if KEY1 and KEY2 are the same. */
3507
f75d7a91 3508static bool
b7432bb2
SM
3509cmpfn_user_defined (struct hash_table_test *ht,
3510 Lisp_Object key1,
3511 Lisp_Object key2)
d80c6c11 3512{
b7432bb2 3513 Lisp_Object args[3];
59f953a2 3514
b7432bb2
SM
3515 args[0] = ht->user_cmp_function;
3516 args[1] = key1;
3517 args[2] = key2;
3518 return !NILP (Ffuncall (3, args));
d80c6c11
GM
3519}
3520
3521
3522/* Value is a hash code for KEY for use in hash table H which uses
3523 `eq' to compare keys. The hash code returned is guaranteed to fit
3524 in a Lisp integer. */
3525
0de4bb68 3526static EMACS_UINT
b7432bb2 3527hashfn_eq (struct hash_table_test *ht, Lisp_Object key)
d80c6c11 3528{
61ddb1b9 3529 EMACS_UINT hash = XHASH (key) ^ XTYPE (key);
cf681889 3530 return hash;
d80c6c11
GM
3531}
3532
d80c6c11
GM
3533/* Value is a hash code for KEY for use in hash table H which uses
3534 `eql' to compare keys. The hash code returned is guaranteed to fit
3535 in a Lisp integer. */
3536
0de4bb68 3537static EMACS_UINT
b7432bb2 3538hashfn_eql (struct hash_table_test *ht, Lisp_Object key)
d80c6c11 3539{
0de4bb68 3540 EMACS_UINT hash;
cf681889
GM
3541 if (FLOATP (key))
3542 hash = sxhash (key, 0);
d80c6c11 3543 else
61ddb1b9 3544 hash = XHASH (key) ^ XTYPE (key);
cf681889 3545 return hash;
d80c6c11
GM
3546}
3547
d80c6c11
GM
3548/* Value is a hash code for KEY for use in hash table H which uses
3549 `equal' to compare keys. The hash code returned is guaranteed to fit
3550 in a Lisp integer. */
3551
0de4bb68 3552static EMACS_UINT
b7432bb2 3553hashfn_equal (struct hash_table_test *ht, Lisp_Object key)
d80c6c11 3554{
0de4bb68 3555 EMACS_UINT hash = sxhash (key, 0);
cf681889 3556 return hash;
d80c6c11
GM
3557}
3558
d80c6c11
GM
3559/* Value is a hash code for KEY for use in hash table H which uses as
3560 user-defined function to compare keys. The hash code returned is
3561 guaranteed to fit in a Lisp integer. */
3562
0de4bb68 3563static EMACS_UINT
b7432bb2 3564hashfn_user_defined (struct hash_table_test *ht, Lisp_Object key)
d80c6c11
GM
3565{
3566 Lisp_Object args[2], hash;
59f953a2 3567
b7432bb2 3568 args[0] = ht->user_hash_function;
d80c6c11
GM
3569 args[1] = key;
3570 hash = Ffuncall (2, args);
79804536 3571 return hashfn_eq (ht, hash);
d80c6c11
GM
3572}
3573
d311d28c
PE
3574/* An upper bound on the size of a hash table index. It must fit in
3575 ptrdiff_t and be a valid Emacs fixnum. */
3576#define INDEX_SIZE_BOUND \
663e2b3f 3577 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX / word_size))
d80c6c11
GM
3578
3579/* Create and initialize a new hash table.
3580
3581 TEST specifies the test the hash table will use to compare keys.
3582 It must be either one of the predefined tests `eq', `eql' or
3583 `equal' or a symbol denoting a user-defined test named TEST with
3584 test and hash functions USER_TEST and USER_HASH.
59f953a2 3585
1fd4c450 3586 Give the table initial capacity SIZE, SIZE >= 0, an integer.
d80c6c11
GM
3587
3588 If REHASH_SIZE is an integer, it must be > 0, and this hash table's
3589 new size when it becomes full is computed by adding REHASH_SIZE to
3590 its old size. If REHASH_SIZE is a float, it must be > 1.0, and the
3591 table's new size is computed by multiplying its old size with
3592 REHASH_SIZE.
3593
3594 REHASH_THRESHOLD must be a float <= 1.0, and > 0. The table will
3595 be resized when the ratio of (number of entries in the table) /
3596 (table size) is >= REHASH_THRESHOLD.
3597
3598 WEAK specifies the weakness of the table. If non-nil, it must be
ec504e6f 3599 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */
d80c6c11
GM
3600
3601Lisp_Object
b7432bb2
SM
3602make_hash_table (struct hash_table_test test,
3603 Lisp_Object size, Lisp_Object rehash_size,
3604 Lisp_Object rehash_threshold, Lisp_Object weak)
d80c6c11
GM
3605{
3606 struct Lisp_Hash_Table *h;
d80c6c11 3607 Lisp_Object table;
d311d28c
PE
3608 EMACS_INT index_size, sz;
3609 ptrdiff_t i;
0de4bb68 3610 double index_float;
d80c6c11
GM
3611
3612 /* Preconditions. */
b7432bb2 3613 eassert (SYMBOLP (test.name));
a54e2c05
DA
3614 eassert (INTEGERP (size) && XINT (size) >= 0);
3615 eassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
0de4bb68 3616 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
a54e2c05 3617 eassert (FLOATP (rehash_threshold)
0de4bb68
PE
3618 && 0 < XFLOAT_DATA (rehash_threshold)
3619 && XFLOAT_DATA (rehash_threshold) <= 1.0);
d80c6c11 3620
1fd4c450
GM
3621 if (XFASTINT (size) == 0)
3622 size = make_number (1);
3623
0de4bb68
PE
3624 sz = XFASTINT (size);
3625 index_float = sz / XFLOAT_DATA (rehash_threshold);
d311d28c 3626 index_size = (index_float < INDEX_SIZE_BOUND + 1
0de4bb68 3627 ? next_almost_prime (index_float)
d311d28c
PE
3628 : INDEX_SIZE_BOUND + 1);
3629 if (INDEX_SIZE_BOUND < max (index_size, 2 * sz))
0de4bb68
PE
3630 error ("Hash table too large");
3631
b3660ef6
GM
3632 /* Allocate a table and initialize it. */
3633 h = allocate_hash_table ();
d80c6c11
GM
3634
3635 /* Initialize hash table slots. */
d80c6c11 3636 h->test = test;
d80c6c11
GM
3637 h->weak = weak;
3638 h->rehash_threshold = rehash_threshold;
3639 h->rehash_size = rehash_size;
878f97ff 3640 h->count = 0;
d80c6c11
GM
3641 h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
3642 h->hash = Fmake_vector (size, Qnil);
3643 h->next = Fmake_vector (size, Qnil);
d80c6c11
GM
3644 h->index = Fmake_vector (make_number (index_size), Qnil);
3645
3646 /* Set up the free list. */
3647 for (i = 0; i < sz - 1; ++i)
e83064be 3648 set_hash_next_slot (h, i, make_number (i + 1));
d80c6c11
GM
3649 h->next_free = make_number (0);
3650
3651 XSET_HASH_TABLE (table, h);
a54e2c05
DA
3652 eassert (HASH_TABLE_P (table));
3653 eassert (XHASH_TABLE (table) == h);
d80c6c11
GM
3654
3655 /* Maybe add this hash table to the list of all weak hash tables. */
3656 if (NILP (h->weak))
6c661ec9 3657 h->next_weak = NULL;
d80c6c11
GM
3658 else
3659 {
6c661ec9
SM
3660 h->next_weak = weak_hash_tables;
3661 weak_hash_tables = h;
d80c6c11
GM
3662 }
3663
3664 return table;
3665}
3666
3667
f899c503
GM
3668/* Return a copy of hash table H1. Keys and values are not copied,
3669 only the table itself is. */
3670
2f7c71a1 3671static Lisp_Object
971de7fb 3672copy_hash_table (struct Lisp_Hash_Table *h1)
f899c503
GM
3673{
3674 Lisp_Object table;
3675 struct Lisp_Hash_Table *h2;
59f953a2 3676
b3660ef6 3677 h2 = allocate_hash_table ();
ae1d87e2 3678 *h2 = *h1;
f899c503
GM
3679 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
3680 h2->hash = Fcopy_sequence (h1->hash);
3681 h2->next = Fcopy_sequence (h1->next);
3682 h2->index = Fcopy_sequence (h1->index);
3683 XSET_HASH_TABLE (table, h2);
3684
3685 /* Maybe add this hash table to the list of all weak hash tables. */
3686 if (!NILP (h2->weak))
3687 {
6c661ec9
SM
3688 h2->next_weak = weak_hash_tables;
3689 weak_hash_tables = h2;
f899c503
GM
3690 }
3691
3692 return table;
3693}
3694
3695
d80c6c11
GM
3696/* Resize hash table H if it's too full. If H cannot be resized
3697 because it's already too large, throw an error. */
3698
b0ab8123 3699static void
971de7fb 3700maybe_resize_hash_table (struct Lisp_Hash_Table *h)
d80c6c11
GM
3701{
3702 if (NILP (h->next_free))
3703 {
d311d28c
PE
3704 ptrdiff_t old_size = HASH_TABLE_SIZE (h);
3705 EMACS_INT new_size, index_size, nsize;
3706 ptrdiff_t i;
0de4bb68 3707 double index_float;
59f953a2 3708
d80c6c11
GM
3709 if (INTEGERP (h->rehash_size))
3710 new_size = old_size + XFASTINT (h->rehash_size);
3711 else
0de4bb68
PE
3712 {
3713 double float_new_size = old_size * XFLOAT_DATA (h->rehash_size);
d311d28c 3714 if (float_new_size < INDEX_SIZE_BOUND + 1)
0de4bb68
PE
3715 {
3716 new_size = float_new_size;
3717 if (new_size <= old_size)
3718 new_size = old_size + 1;
3719 }
3720 else
d311d28c 3721 new_size = INDEX_SIZE_BOUND + 1;
0de4bb68
PE
3722 }
3723 index_float = new_size / XFLOAT_DATA (h->rehash_threshold);
d311d28c 3724 index_size = (index_float < INDEX_SIZE_BOUND + 1
0de4bb68 3725 ? next_almost_prime (index_float)
d311d28c 3726 : INDEX_SIZE_BOUND + 1);
9bd1cd35 3727 nsize = max (index_size, 2 * new_size);
d311d28c 3728 if (INDEX_SIZE_BOUND < nsize)
d80c6c11
GM
3729 error ("Hash table too large to resize");
3730
1ec4b7b2
SM
3731#ifdef ENABLE_CHECKING
3732 if (HASH_TABLE_P (Vpurify_flag)
3733 && XHASH_TABLE (Vpurify_flag) == h)
3734 {
3735 Lisp_Object args[2];
3736 args[0] = build_string ("Growing hash table to: %d");
3737 args[1] = make_number (new_size);
3738 Fmessage (2, args);
3739 }
3740#endif
3741
e83064be
DA
3742 set_hash_key_and_value (h, larger_vector (h->key_and_value,
3743 2 * (new_size - old_size), -1));
3744 set_hash_next (h, larger_vector (h->next, new_size - old_size, -1));
3745 set_hash_hash (h, larger_vector (h->hash, new_size - old_size, -1));
3746 set_hash_index (h, Fmake_vector (make_number (index_size), Qnil));
d80c6c11
GM
3747
3748 /* Update the free list. Do it so that new entries are added at
3749 the end of the free list. This makes some operations like
3750 maphash faster. */
3751 for (i = old_size; i < new_size - 1; ++i)
e83064be 3752 set_hash_next_slot (h, i, make_number (i + 1));
59f953a2 3753
d80c6c11
GM
3754 if (!NILP (h->next_free))
3755 {
3756 Lisp_Object last, next;
59f953a2 3757
d80c6c11
GM
3758 last = h->next_free;
3759 while (next = HASH_NEXT (h, XFASTINT (last)),
3760 !NILP (next))
3761 last = next;
59f953a2 3762
e83064be 3763 set_hash_next_slot (h, XFASTINT (last), make_number (old_size));
d80c6c11
GM
3764 }
3765 else
3766 XSETFASTINT (h->next_free, old_size);
3767
3768 /* Rehash. */
3769 for (i = 0; i < old_size; ++i)
3770 if (!NILP (HASH_HASH (h, i)))
3771 {
0de4bb68 3772 EMACS_UINT hash_code = XUINT (HASH_HASH (h, i));
d311d28c 3773 ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
e83064be
DA
3774 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
3775 set_hash_index_slot (h, start_of_bucket, make_number (i));
d80c6c11 3776 }
59f953a2 3777 }
d80c6c11
GM
3778}
3779
3780
3781/* Lookup KEY in hash table H. If HASH is non-null, return in *HASH
3782 the hash code of KEY. Value is the index of the entry in H
3783 matching KEY, or -1 if not found. */
3784
d3411f89 3785ptrdiff_t
0de4bb68 3786hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
d80c6c11 3787{
0de4bb68 3788 EMACS_UINT hash_code;
d3411f89 3789 ptrdiff_t start_of_bucket;
d80c6c11
GM
3790 Lisp_Object idx;
3791
b7432bb2
SM
3792 hash_code = h->test.hashfn (&h->test, key);
3793 eassert ((hash_code & ~INTMASK) == 0);
d80c6c11
GM
3794 if (hash)
3795 *hash = hash_code;
59f953a2 3796
7edbb0da 3797 start_of_bucket = hash_code % ASIZE (h->index);
d80c6c11
GM
3798 idx = HASH_INDEX (h, start_of_bucket);
3799
f5c75033 3800 /* We need not gcpro idx since it's either an integer or nil. */
d80c6c11
GM
3801 while (!NILP (idx))
3802 {
d311d28c 3803 ptrdiff_t i = XFASTINT (idx);
2e5da676 3804 if (EQ (key, HASH_KEY (h, i))
b7432bb2
SM
3805 || (h->test.cmpfn
3806 && hash_code == XUINT (HASH_HASH (h, i))
3807 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
d80c6c11
GM
3808 break;
3809 idx = HASH_NEXT (h, i);
3810 }
3811
3812 return NILP (idx) ? -1 : XFASTINT (idx);
3813}
3814
3815
3816/* Put an entry into hash table H that associates KEY with VALUE.
64a5094a
KH
3817 HASH is a previously computed hash code of KEY.
3818 Value is the index of the entry in H matching KEY. */
d80c6c11 3819
d3411f89 3820ptrdiff_t
0de4bb68
PE
3821hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
3822 EMACS_UINT hash)
d80c6c11 3823{
d3411f89 3824 ptrdiff_t start_of_bucket, i;
d80c6c11 3825
a54e2c05 3826 eassert ((hash & ~INTMASK) == 0);
d80c6c11
GM
3827
3828 /* Increment count after resizing because resizing may fail. */
3829 maybe_resize_hash_table (h);
878f97ff 3830 h->count++;
59f953a2 3831
d80c6c11
GM
3832 /* Store key/value in the key_and_value vector. */
3833 i = XFASTINT (h->next_free);
3834 h->next_free = HASH_NEXT (h, i);
e83064be
DA
3835 set_hash_key_slot (h, i, key);
3836 set_hash_value_slot (h, i, value);
d80c6c11
GM
3837
3838 /* Remember its hash code. */
e83064be 3839 set_hash_hash_slot (h, i, make_number (hash));
d80c6c11
GM
3840
3841 /* Add new entry to its collision chain. */
7edbb0da 3842 start_of_bucket = hash % ASIZE (h->index);
e83064be
DA
3843 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
3844 set_hash_index_slot (h, start_of_bucket, make_number (i));
64a5094a 3845 return i;
d80c6c11
GM
3846}
3847
3848
3849/* Remove the entry matching KEY from hash table H, if there is one. */
3850
2749d28e 3851static void
971de7fb 3852hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
d80c6c11 3853{
0de4bb68 3854 EMACS_UINT hash_code;
d311d28c 3855 ptrdiff_t start_of_bucket;
d80c6c11
GM
3856 Lisp_Object idx, prev;
3857
b7432bb2
SM
3858 hash_code = h->test.hashfn (&h->test, key);
3859 eassert ((hash_code & ~INTMASK) == 0);
7edbb0da 3860 start_of_bucket = hash_code % ASIZE (h->index);
d80c6c11
GM
3861 idx = HASH_INDEX (h, start_of_bucket);
3862 prev = Qnil;
3863
f5c75033 3864 /* We need not gcpro idx, prev since they're either integers or nil. */
d80c6c11
GM
3865 while (!NILP (idx))
3866 {
d311d28c 3867 ptrdiff_t i = XFASTINT (idx);
d80c6c11 3868
2e5da676 3869 if (EQ (key, HASH_KEY (h, i))
b7432bb2
SM
3870 || (h->test.cmpfn
3871 && hash_code == XUINT (HASH_HASH (h, i))
3872 && h->test.cmpfn (&h->test, key, HASH_KEY (h, i))))
d80c6c11
GM
3873 {
3874 /* Take entry out of collision chain. */
3875 if (NILP (prev))
e83064be 3876 set_hash_index_slot (h, start_of_bucket, HASH_NEXT (h, i));
d80c6c11 3877 else
e83064be 3878 set_hash_next_slot (h, XFASTINT (prev), HASH_NEXT (h, i));
d80c6c11
GM
3879
3880 /* Clear slots in key_and_value and add the slots to
3881 the free list. */
e83064be
DA
3882 set_hash_key_slot (h, i, Qnil);
3883 set_hash_value_slot (h, i, Qnil);
3884 set_hash_hash_slot (h, i, Qnil);
3885 set_hash_next_slot (h, i, h->next_free);
d80c6c11 3886 h->next_free = make_number (i);
878f97ff 3887 h->count--;
a54e2c05 3888 eassert (h->count >= 0);
d80c6c11
GM
3889 break;
3890 }
3891 else
3892 {
3893 prev = idx;
3894 idx = HASH_NEXT (h, i);
3895 }
3896 }
3897}
3898
3899
3900/* Clear hash table H. */
3901
2f7c71a1 3902static void
971de7fb 3903hash_clear (struct Lisp_Hash_Table *h)
d80c6c11 3904{
878f97ff 3905 if (h->count > 0)
d80c6c11 3906 {
d311d28c 3907 ptrdiff_t i, size = HASH_TABLE_SIZE (h);
d80c6c11
GM
3908
3909 for (i = 0; i < size; ++i)
3910 {
e83064be
DA
3911 set_hash_next_slot (h, i, i < size - 1 ? make_number (i + 1) : Qnil);
3912 set_hash_key_slot (h, i, Qnil);
3913 set_hash_value_slot (h, i, Qnil);
3914 set_hash_hash_slot (h, i, Qnil);
d80c6c11
GM
3915 }
3916
7edbb0da 3917 for (i = 0; i < ASIZE (h->index); ++i)
68b587a6 3918 ASET (h->index, i, Qnil);
d80c6c11
GM
3919
3920 h->next_free = make_number (0);
878f97ff 3921 h->count = 0;
d80c6c11
GM
3922 }
3923}
3924
3925
3926\f
3927/************************************************************************
3928 Weak Hash Tables
3929 ************************************************************************/
3930
f75d7a91 3931/* Sweep weak hash table H. REMOVE_ENTRIES_P means remove
a0b581cc 3932 entries from the table that don't survive the current GC.
f75d7a91
PE
3933 !REMOVE_ENTRIES_P means mark entries that are in use. Value is
3934 true if anything was marked. */
a0b581cc 3935
f75d7a91
PE
3936static bool
3937sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
a0b581cc 3938{
d311d28c 3939 ptrdiff_t bucket, n;
f75d7a91 3940 bool marked;
59f953a2 3941
7edbb0da 3942 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG;
a0b581cc 3943 marked = 0;
59f953a2 3944
a0b581cc
GM
3945 for (bucket = 0; bucket < n; ++bucket)
3946 {
1e546714 3947 Lisp_Object idx, next, prev;
a0b581cc
GM
3948
3949 /* Follow collision chain, removing entries that
3950 don't survive this garbage collection. */
a0b581cc 3951 prev = Qnil;
8e50cc2d 3952 for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next)
a0b581cc 3953 {
d311d28c 3954 ptrdiff_t i = XFASTINT (idx);
fce31d69
PE
3955 bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
3956 bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
f75d7a91 3957 bool remove_p;
59f953a2 3958
a0b581cc 3959 if (EQ (h->weak, Qkey))
aee625fa 3960 remove_p = !key_known_to_survive_p;
a0b581cc 3961 else if (EQ (h->weak, Qvalue))
aee625fa 3962 remove_p = !value_known_to_survive_p;
ec504e6f 3963 else if (EQ (h->weak, Qkey_or_value))
728c5d9d 3964 remove_p = !(key_known_to_survive_p || value_known_to_survive_p);
ec504e6f 3965 else if (EQ (h->weak, Qkey_and_value))
728c5d9d 3966 remove_p = !(key_known_to_survive_p && value_known_to_survive_p);
a0b581cc 3967 else
1088b922 3968 emacs_abort ();
59f953a2 3969
a0b581cc
GM
3970 next = HASH_NEXT (h, i);
3971
3972 if (remove_entries_p)
3973 {
3974 if (remove_p)
3975 {
3976 /* Take out of collision chain. */
8e50cc2d 3977 if (NILP (prev))
e83064be 3978 set_hash_index_slot (h, bucket, next);
a0b581cc 3979 else
e83064be 3980 set_hash_next_slot (h, XFASTINT (prev), next);
59f953a2 3981
a0b581cc 3982 /* Add to free list. */
e83064be 3983 set_hash_next_slot (h, i, h->next_free);
a0b581cc 3984 h->next_free = idx;
59f953a2 3985
a0b581cc 3986 /* Clear key, value, and hash. */
e83064be
DA
3987 set_hash_key_slot (h, i, Qnil);
3988 set_hash_value_slot (h, i, Qnil);
3989 set_hash_hash_slot (h, i, Qnil);
59f953a2 3990
878f97ff 3991 h->count--;
a0b581cc 3992 }
d278cde0
KS
3993 else
3994 {
3995 prev = idx;
3996 }
a0b581cc
GM
3997 }
3998 else
3999 {
4000 if (!remove_p)
4001 {
4002 /* Make sure key and value survive. */
aee625fa
GM
4003 if (!key_known_to_survive_p)
4004 {
9568e3d8 4005 mark_object (HASH_KEY (h, i));
aee625fa
GM
4006 marked = 1;
4007 }
4008
4009 if (!value_known_to_survive_p)
4010 {
9568e3d8 4011 mark_object (HASH_VALUE (h, i));
aee625fa
GM
4012 marked = 1;
4013 }
a0b581cc
GM
4014 }
4015 }
a0b581cc
GM
4016 }
4017 }
4018
4019 return marked;
4020}
4021
d80c6c11
GM
4022/* Remove elements from weak hash tables that don't survive the
4023 current garbage collection. Remove weak tables that don't survive
4024 from Vweak_hash_tables. Called from gc_sweep. */
4025
4026void
971de7fb 4027sweep_weak_hash_tables (void)
d80c6c11 4028{
6c661ec9 4029 struct Lisp_Hash_Table *h, *used, *next;
f75d7a91 4030 bool marked;
a0b581cc
GM
4031
4032 /* Mark all keys and values that are in use. Keep on marking until
4033 there is no more change. This is necessary for cases like
4034 value-weak table A containing an entry X -> Y, where Y is used in a
4035 key-weak table B, Z -> Y. If B comes after A in the list of weak
4036 tables, X -> Y might be removed from A, although when looking at B
4037 one finds that it shouldn't. */
4038 do
4039 {
4040 marked = 0;
6c661ec9 4041 for (h = weak_hash_tables; h; h = h->next_weak)
a0b581cc 4042 {
eab3844f 4043 if (h->header.size & ARRAY_MARK_FLAG)
a0b581cc
GM
4044 marked |= sweep_weak_table (h, 0);
4045 }
4046 }
4047 while (marked);
d80c6c11 4048
a0b581cc 4049 /* Remove tables and entries that aren't used. */
6c661ec9 4050 for (h = weak_hash_tables, used = NULL; h; h = next)
d80c6c11 4051 {
ac0e96ee 4052 next = h->next_weak;
91f78c99 4053
eab3844f 4054 if (h->header.size & ARRAY_MARK_FLAG)
d80c6c11 4055 {
ac0e96ee 4056 /* TABLE is marked as used. Sweep its contents. */
878f97ff 4057 if (h->count > 0)
a0b581cc 4058 sweep_weak_table (h, 1);
ac0e96ee
GM
4059
4060 /* Add table to the list of used weak hash tables. */
4061 h->next_weak = used;
6c661ec9 4062 used = h;
d80c6c11
GM
4063 }
4064 }
ac0e96ee 4065
6c661ec9 4066 weak_hash_tables = used;
d80c6c11
GM
4067}
4068
4069
4070\f
4071/***********************************************************************
4072 Hash Code Computation
4073 ***********************************************************************/
4074
4075/* Maximum depth up to which to dive into Lisp structures. */
4076
4077#define SXHASH_MAX_DEPTH 3
4078
4079/* Maximum length up to which to take list and vector elements into
4080 account. */
4081
4082#define SXHASH_MAX_LEN 7
4083
3cc5a532
PE
4084/* Return a hash for string PTR which has length LEN. The hash value
4085 can be any EMACS_UINT value. */
d80c6c11 4086
3cc5a532
PE
4087EMACS_UINT
4088hash_string (char const *ptr, ptrdiff_t len)
d80c6c11 4089{
3cc5a532
PE
4090 char const *p = ptr;
4091 char const *end = p + len;
d80c6c11 4092 unsigned char c;
0de4bb68 4093 EMACS_UINT hash = 0;
d80c6c11
GM
4094
4095 while (p != end)
4096 {
4097 c = *p++;
04a2d0d3 4098 hash = sxhash_combine (hash, c);
d80c6c11 4099 }
59f953a2 4100
3cc5a532
PE
4101 return hash;
4102}
4103
4104/* Return a hash for string PTR which has length LEN. The hash
4105 code returned is guaranteed to fit in a Lisp integer. */
4106
4107static EMACS_UINT
4108sxhash_string (char const *ptr, ptrdiff_t len)
4109{
4110 EMACS_UINT hash = hash_string (ptr, len);
0de4bb68 4111 return SXHASH_REDUCE (hash);
d80c6c11
GM
4112}
4113
0de4bb68
PE
4114/* Return a hash for the floating point value VAL. */
4115
eff1c190 4116static EMACS_UINT
0de4bb68
PE
4117sxhash_float (double val)
4118{
4119 EMACS_UINT hash = 0;
4120 enum {
4121 WORDS_PER_DOUBLE = (sizeof val / sizeof hash
4122 + (sizeof val % sizeof hash != 0))
4123 };
4124 union {
4125 double val;
4126 EMACS_UINT word[WORDS_PER_DOUBLE];
4127 } u;
4128 int i;
4129 u.val = val;
4130 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4131 for (i = 0; i < WORDS_PER_DOUBLE; i++)
04a2d0d3 4132 hash = sxhash_combine (hash, u.word[i]);
0de4bb68
PE
4133 return SXHASH_REDUCE (hash);
4134}
d80c6c11
GM
4135
4136/* Return a hash for list LIST. DEPTH is the current depth in the
4137 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
4138
0de4bb68 4139static EMACS_UINT
971de7fb 4140sxhash_list (Lisp_Object list, int depth)
d80c6c11 4141{
0de4bb68 4142 EMACS_UINT hash = 0;
d80c6c11 4143 int i;
59f953a2 4144
d80c6c11
GM
4145 if (depth < SXHASH_MAX_DEPTH)
4146 for (i = 0;
4147 CONSP (list) && i < SXHASH_MAX_LEN;
4148 list = XCDR (list), ++i)
4149 {
0de4bb68 4150 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
04a2d0d3 4151 hash = sxhash_combine (hash, hash2);
d80c6c11
GM
4152 }
4153
ea284f33
KS
4154 if (!NILP (list))
4155 {
0de4bb68 4156 EMACS_UINT hash2 = sxhash (list, depth + 1);
04a2d0d3 4157 hash = sxhash_combine (hash, hash2);
ea284f33
KS
4158 }
4159
0de4bb68 4160 return SXHASH_REDUCE (hash);
d80c6c11
GM
4161}
4162
4163
4164/* Return a hash for vector VECTOR. DEPTH is the current depth in
4165 the Lisp structure. */
4166
0de4bb68 4167static EMACS_UINT
971de7fb 4168sxhash_vector (Lisp_Object vec, int depth)
d80c6c11 4169{
0de4bb68 4170 EMACS_UINT hash = ASIZE (vec);
d80c6c11
GM
4171 int i, n;
4172
7edbb0da 4173 n = min (SXHASH_MAX_LEN, ASIZE (vec));
d80c6c11
GM
4174 for (i = 0; i < n; ++i)
4175 {
0de4bb68 4176 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
04a2d0d3 4177 hash = sxhash_combine (hash, hash2);
d80c6c11
GM
4178 }
4179
0de4bb68 4180 return SXHASH_REDUCE (hash);
d80c6c11
GM
4181}
4182
d80c6c11
GM
4183/* Return a hash for bool-vector VECTOR. */
4184
0de4bb68 4185static EMACS_UINT
971de7fb 4186sxhash_bool_vector (Lisp_Object vec)
d80c6c11 4187{
1c0a7493
PE
4188 EMACS_INT size = bool_vector_size (vec);
4189 EMACS_UINT hash = size;
d80c6c11
GM
4190 int i, n;
4191
df5b4930 4192 n = min (SXHASH_MAX_LEN, bool_vector_words (size));
d80c6c11 4193 for (i = 0; i < n; ++i)
df5b4930 4194 hash = sxhash_combine (hash, bool_vector_data (vec)[i]);
d80c6c11 4195
0de4bb68 4196 return SXHASH_REDUCE (hash);
d80c6c11
GM
4197}
4198
4199
4200/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
6b61353c 4201 structure. Value is an unsigned integer clipped to INTMASK. */
d80c6c11 4202
0de4bb68 4203EMACS_UINT
971de7fb 4204sxhash (Lisp_Object obj, int depth)
d80c6c11 4205{
0de4bb68 4206 EMACS_UINT hash;
d80c6c11
GM
4207
4208 if (depth > SXHASH_MAX_DEPTH)
4209 return 0;
59f953a2 4210
d80c6c11
GM
4211 switch (XTYPE (obj))
4212 {
2de9f71c 4213 case_Lisp_Int:
d80c6c11
GM
4214 hash = XUINT (obj);
4215 break;
4216
d80c6c11 4217 case Lisp_Misc:
61ddb1b9 4218 hash = XHASH (obj);
d80c6c11
GM
4219 break;
4220
32bfb2d5
EZ
4221 case Lisp_Symbol:
4222 obj = SYMBOL_NAME (obj);
4223 /* Fall through. */
4224
d80c6c11 4225 case Lisp_String:
3cc5a532 4226 hash = sxhash_string (SSDATA (obj), SBYTES (obj));
d80c6c11
GM
4227 break;
4228
4229 /* This can be everything from a vector to an overlay. */
4230 case Lisp_Vectorlike:
4231 if (VECTORP (obj))
4232 /* According to the CL HyperSpec, two arrays are equal only if
4233 they are `eq', except for strings and bit-vectors. In
4234 Emacs, this works differently. We have to compare element
4235 by element. */
4236 hash = sxhash_vector (obj, depth);
4237 else if (BOOL_VECTOR_P (obj))
4238 hash = sxhash_bool_vector (obj);
4239 else
4240 /* Others are `equal' if they are `eq', so let's take their
4241 address as hash. */
61ddb1b9 4242 hash = XHASH (obj);
d80c6c11
GM
4243 break;
4244
4245 case Lisp_Cons:
4246 hash = sxhash_list (obj, depth);
4247 break;
4248
4249 case Lisp_Float:
0de4bb68
PE
4250 hash = sxhash_float (XFLOAT_DATA (obj));
4251 break;
d80c6c11
GM
4252
4253 default:
1088b922 4254 emacs_abort ();
d80c6c11
GM
4255 }
4256
0de4bb68 4257 return hash;
d80c6c11
GM
4258}
4259
4260
4261\f
4262/***********************************************************************
4263 Lisp Interface
4264 ***********************************************************************/
4265
4266
4267DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
e9d8ddc9 4268 doc: /* Compute a hash code for OBJ and return it as integer. */)
5842a27b 4269 (Lisp_Object obj)
d80c6c11 4270{
0de4bb68 4271 EMACS_UINT hash = sxhash (obj, 0);
d80c6c11
GM
4272 return make_number (hash);
4273}
4274
4275
a7ca3326 4276DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
e9d8ddc9 4277 doc: /* Create and return a new hash table.
91f78c99 4278
47cebab1
GM
4279Arguments are specified as keyword/argument pairs. The following
4280arguments are defined:
4281
4282:test TEST -- TEST must be a symbol that specifies how to compare
4283keys. Default is `eql'. Predefined are the tests `eq', `eql', and
4284`equal'. User-supplied test and hash functions can be specified via
4285`define-hash-table-test'.
4286
4287:size SIZE -- A hint as to how many elements will be put in the table.
4288Default is 65.
4289
4290:rehash-size REHASH-SIZE - Indicates how to expand the table when it
79d6f59e
CY
4291fills up. If REHASH-SIZE is an integer, increase the size by that
4292amount. If it is a float, it must be > 1.0, and the new size is the
4293old size multiplied by that factor. Default is 1.5.
47cebab1
GM
4294
4295:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
b756c005 4296Resize the hash table when the ratio (number of entries / table size)
e1025755 4297is greater than or equal to THRESHOLD. Default is 0.8.
47cebab1
GM
4298
4299:weakness WEAK -- WEAK must be one of nil, t, `key', `value',
4300`key-or-value', or `key-and-value'. If WEAK is not nil, the table
4301returned is a weak table. Key/value pairs are removed from a weak
4302hash table when there are no non-weak references pointing to their
4303key, value, one of key or value, or both key and value, depending on
4304WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK
4bf8e2a3
MB
4305is nil.
4306
4307usage: (make-hash-table &rest KEYWORD-ARGS) */)
f66c7cf8 4308 (ptrdiff_t nargs, Lisp_Object *args)
d80c6c11
GM
4309{
4310 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
b7432bb2 4311 struct hash_table_test testdesc;
d80c6c11 4312 char *used;
f66c7cf8 4313 ptrdiff_t i;
d80c6c11
GM
4314
4315 /* The vector `used' is used to keep track of arguments that
4316 have been consumed. */
38182d90 4317 used = alloca (nargs * sizeof *used);
72af86bd 4318 memset (used, 0, nargs * sizeof *used);
d80c6c11
GM
4319
4320 /* See if there's a `:test TEST' among the arguments. */
4321 i = get_key_arg (QCtest, nargs, args, used);
c5101a77 4322 test = i ? args[i] : Qeql;
b7432bb2
SM
4323 if (EQ (test, Qeq))
4324 testdesc = hashtest_eq;
4325 else if (EQ (test, Qeql))
4326 testdesc = hashtest_eql;
4327 else if (EQ (test, Qequal))
4328 testdesc = hashtest_equal;
4329 else
d80c6c11
GM
4330 {
4331 /* See if it is a user-defined test. */
4332 Lisp_Object prop;
59f953a2 4333
d80c6c11 4334 prop = Fget (test, Qhash_table_test);
c1dd95fc 4335 if (!CONSP (prop) || !CONSP (XCDR (prop)))
692ae65c 4336 signal_error ("Invalid hash table test", test);
b7432bb2
SM
4337 testdesc.name = test;
4338 testdesc.user_cmp_function = XCAR (prop);
4339 testdesc.user_hash_function = XCAR (XCDR (prop));
4340 testdesc.hashfn = hashfn_user_defined;
4341 testdesc.cmpfn = cmpfn_user_defined;
d80c6c11 4342 }
d80c6c11
GM
4343
4344 /* See if there's a `:size SIZE' argument. */
4345 i = get_key_arg (QCsize, nargs, args, used);
c5101a77 4346 size = i ? args[i] : Qnil;
cf42cb72
SM
4347 if (NILP (size))
4348 size = make_number (DEFAULT_HASH_SIZE);
4349 else if (!INTEGERP (size) || XINT (size) < 0)
692ae65c 4350 signal_error ("Invalid hash table size", size);
d80c6c11
GM
4351
4352 /* Look for `:rehash-size SIZE'. */
4353 i = get_key_arg (QCrehash_size, nargs, args, used);
c5101a77 4354 rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE);
0de4bb68
PE
4355 if (! ((INTEGERP (rehash_size) && 0 < XINT (rehash_size))
4356 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))))
692ae65c 4357 signal_error ("Invalid hash table rehash size", rehash_size);
59f953a2 4358
d80c6c11
GM
4359 /* Look for `:rehash-threshold THRESHOLD'. */
4360 i = get_key_arg (QCrehash_threshold, nargs, args, used);
c5101a77 4361 rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD);
0de4bb68
PE
4362 if (! (FLOATP (rehash_threshold)
4363 && 0 < XFLOAT_DATA (rehash_threshold)
4364 && XFLOAT_DATA (rehash_threshold) <= 1))
692ae65c 4365 signal_error ("Invalid hash table rehash threshold", rehash_threshold);
59f953a2 4366
ee0403b3
GM
4367 /* Look for `:weakness WEAK'. */
4368 i = get_key_arg (QCweakness, nargs, args, used);
c5101a77 4369 weak = i ? args[i] : Qnil;
ec504e6f
GM
4370 if (EQ (weak, Qt))
4371 weak = Qkey_and_value;
d80c6c11 4372 if (!NILP (weak)
f899c503 4373 && !EQ (weak, Qkey)
ec504e6f
GM
4374 && !EQ (weak, Qvalue)
4375 && !EQ (weak, Qkey_or_value)
4376 && !EQ (weak, Qkey_and_value))
692ae65c 4377 signal_error ("Invalid hash table weakness", weak);
59f953a2 4378
d80c6c11
GM
4379 /* Now, all args should have been used up, or there's a problem. */
4380 for (i = 0; i < nargs; ++i)
4381 if (!used[i])
692ae65c 4382 signal_error ("Invalid argument list", args[i]);
d80c6c11 4383
b7432bb2 4384 return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
d80c6c11
GM
4385}
4386
4387
f899c503 4388DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
e9d8ddc9 4389 doc: /* Return a copy of hash table TABLE. */)
5842a27b 4390 (Lisp_Object table)
f899c503
GM
4391{
4392 return copy_hash_table (check_hash_table (table));
4393}
4394
4395
d80c6c11 4396DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
e9d8ddc9 4397 doc: /* Return the number of elements in TABLE. */)
5842a27b 4398 (Lisp_Object table)
d80c6c11 4399{
878f97ff 4400 return make_number (check_hash_table (table)->count);
d80c6c11
GM
4401}
4402
59f953a2 4403
d80c6c11
GM
4404DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
4405 Shash_table_rehash_size, 1, 1, 0,
e9d8ddc9 4406 doc: /* Return the current rehash size of TABLE. */)
5842a27b 4407 (Lisp_Object table)
d80c6c11
GM
4408{
4409 return check_hash_table (table)->rehash_size;
4410}
59f953a2 4411
d80c6c11
GM
4412
4413DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold,
4414 Shash_table_rehash_threshold, 1, 1, 0,
e9d8ddc9 4415 doc: /* Return the current rehash threshold of TABLE. */)
5842a27b 4416 (Lisp_Object table)
d80c6c11
GM
4417{
4418 return check_hash_table (table)->rehash_threshold;
4419}
59f953a2 4420
d80c6c11
GM
4421
4422DEFUN ("hash-table-size", Fhash_table_size, Shash_table_size, 1, 1, 0,
e9d8ddc9 4423 doc: /* Return the size of TABLE.
47cebab1 4424The size can be used as an argument to `make-hash-table' to create
b756c005 4425a hash table than can hold as many elements as TABLE holds
e9d8ddc9 4426without need for resizing. */)
5842a27b 4427 (Lisp_Object table)
d80c6c11
GM
4428{
4429 struct Lisp_Hash_Table *h = check_hash_table (table);
4430 return make_number (HASH_TABLE_SIZE (h));
4431}
59f953a2 4432
d80c6c11
GM
4433
4434DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
e9d8ddc9 4435 doc: /* Return the test TABLE uses. */)
5842a27b 4436 (Lisp_Object table)
d80c6c11 4437{
b7432bb2 4438 return check_hash_table (table)->test.name;
d80c6c11
GM
4439}
4440
59f953a2 4441
e84b1dea
GM
4442DEFUN ("hash-table-weakness", Fhash_table_weakness, Shash_table_weakness,
4443 1, 1, 0,
e9d8ddc9 4444 doc: /* Return the weakness of TABLE. */)
5842a27b 4445 (Lisp_Object table)
d80c6c11
GM
4446{
4447 return check_hash_table (table)->weak;
4448}
4449
59f953a2 4450
d80c6c11 4451DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
e9d8ddc9 4452 doc: /* Return t if OBJ is a Lisp hash table object. */)
5842a27b 4453 (Lisp_Object obj)
d80c6c11
GM
4454{
4455 return HASH_TABLE_P (obj) ? Qt : Qnil;
4456}
4457
4458
4459DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
ccd8f7fe 4460 doc: /* Clear hash table TABLE and return it. */)
5842a27b 4461 (Lisp_Object table)
d80c6c11
GM
4462{
4463 hash_clear (check_hash_table (table));
ccd8f7fe
TTN
4464 /* Be compatible with XEmacs. */
4465 return table;
d80c6c11
GM
4466}
4467
4468
a7ca3326 4469DEFUN ("gethash", Fgethash, Sgethash, 2, 3, 0,
e9d8ddc9
MB
4470 doc: /* Look up KEY in TABLE and return its associated value.
4471If KEY is not found, return DFLT which defaults to nil. */)
5842a27b 4472 (Lisp_Object key, Lisp_Object table, Lisp_Object dflt)
d80c6c11
GM
4473{
4474 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4475 ptrdiff_t i = hash_lookup (h, key, NULL);
d80c6c11
GM
4476 return i >= 0 ? HASH_VALUE (h, i) : dflt;
4477}
4478
4479
a7ca3326 4480DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
e9d8ddc9 4481 doc: /* Associate KEY with VALUE in hash table TABLE.
47cebab1 4482If KEY is already present in table, replace its current value with
a54e3482 4483VALUE. In any case, return VALUE. */)
5842a27b 4484 (Lisp_Object key, Lisp_Object value, Lisp_Object table)
d80c6c11
GM
4485{
4486 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4487 ptrdiff_t i;
0de4bb68 4488 EMACS_UINT hash;
d80c6c11
GM
4489
4490 i = hash_lookup (h, key, &hash);
4491 if (i >= 0)
e83064be 4492 set_hash_value_slot (h, i, value);
d80c6c11
GM
4493 else
4494 hash_put (h, key, value, hash);
59f953a2 4495
d9c4f922 4496 return value;
d80c6c11
GM
4497}
4498
4499
a7ca3326 4500DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
e9d8ddc9 4501 doc: /* Remove KEY from TABLE. */)
5842a27b 4502 (Lisp_Object key, Lisp_Object table)
d80c6c11
GM
4503{
4504 struct Lisp_Hash_Table *h = check_hash_table (table);
5a2d7ab6 4505 hash_remove_from_table (h, key);
d80c6c11
GM
4506 return Qnil;
4507}
4508
4509
4510DEFUN ("maphash", Fmaphash, Smaphash, 2, 2, 0,
e9d8ddc9 4511 doc: /* Call FUNCTION for all entries in hash table TABLE.
a3a8a7da
LI
4512FUNCTION is called with two arguments, KEY and VALUE.
4513`maphash' always returns nil. */)
5842a27b 4514 (Lisp_Object function, Lisp_Object table)
d80c6c11
GM
4515{
4516 struct Lisp_Hash_Table *h = check_hash_table (table);
4517 Lisp_Object args[3];
d311d28c 4518 ptrdiff_t i;
d80c6c11
GM
4519
4520 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
4521 if (!NILP (HASH_HASH (h, i)))
4522 {
4523 args[0] = function;
4524 args[1] = HASH_KEY (h, i);
4525 args[2] = HASH_VALUE (h, i);
4526 Ffuncall (3, args);
4527 }
59f953a2 4528
d80c6c11
GM
4529 return Qnil;
4530}
4531
4532
4533DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
4534 Sdefine_hash_table_test, 3, 3, 0,
e9d8ddc9 4535 doc: /* Define a new hash table test with name NAME, a symbol.
91f78c99 4536
47cebab1
GM
4537In hash tables created with NAME specified as test, use TEST to
4538compare keys, and HASH for computing hash codes of keys.
4539
4540TEST must be a function taking two arguments and returning non-nil if
4541both arguments are the same. HASH must be a function taking one
79804536
SM
4542argument and returning an object that is the hash code of the argument.
4543It should be the case that if (eq (funcall HASH x1) (funcall HASH x2))
4544returns nil, then (funcall TEST x1 x2) also returns nil. */)
5842a27b 4545 (Lisp_Object name, Lisp_Object test, Lisp_Object hash)
d80c6c11
GM
4546{
4547 return Fput (name, Qhash_table_test, list2 (test, hash));
4548}
4549
a3b210c4 4550
57916a7a 4551\f
5c302da4 4552/************************************************************************
7f3f739f 4553 MD5, SHA-1, and SHA-2
5c302da4
GM
4554 ************************************************************************/
4555
57916a7a 4556#include "md5.h"
e1b90ef6 4557#include "sha1.h"
7f3f739f
LL
4558#include "sha256.h"
4559#include "sha512.h"
57916a7a 4560
7f3f739f 4561/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
47cebab1 4562
f1b54466 4563static Lisp_Object
7f3f739f 4564secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary)
57916a7a 4565{
57916a7a 4566 int i;
d311d28c 4567 ptrdiff_t size;
e6d4aefa 4568 EMACS_INT start_char = 0, end_char = 0;
d311d28c 4569 ptrdiff_t start_byte, end_byte;
e6d4aefa 4570 register EMACS_INT b, e;
57916a7a 4571 register struct buffer *bp;
e6d4aefa 4572 EMACS_INT temp;
7f3f739f
LL
4573 int digest_size;
4574 void *(*hash_func) (const char *, size_t, void *);
4575 Lisp_Object digest;
4576
4577 CHECK_SYMBOL (algorithm);
57916a7a 4578
5c302da4 4579 if (STRINGP (object))
57916a7a
GM
4580 {
4581 if (NILP (coding_system))
4582 {
5c302da4 4583 /* Decide the coding-system to encode the data with. */
57916a7a 4584
5c302da4
GM
4585 if (STRING_MULTIBYTE (object))
4586 /* use default, we can't guess correct value */
38583a69 4587 coding_system = preferred_coding_system ();
91f78c99 4588 else
5c302da4 4589 coding_system = Qraw_text;
57916a7a 4590 }
91f78c99 4591
5c302da4 4592 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4593 {
5c302da4 4594 /* Invalid coding system. */
91f78c99 4595
5c302da4
GM
4596 if (!NILP (noerror))
4597 coding_system = Qraw_text;
4598 else
692ae65c 4599 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4600 }
4601
5c302da4 4602 if (STRING_MULTIBYTE (object))
38583a69 4603 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
5c302da4 4604
d5db4077 4605 size = SCHARS (object);
57916a7a
GM
4606
4607 if (!NILP (start))
4608 {
b7826503 4609 CHECK_NUMBER (start);
57916a7a
GM
4610
4611 start_char = XINT (start);
4612
4613 if (start_char < 0)
4614 start_char += size;
57916a7a
GM
4615 }
4616
4617 if (NILP (end))
d311d28c 4618 end_char = size;
57916a7a
GM
4619 else
4620 {
b7826503 4621 CHECK_NUMBER (end);
91f78c99 4622
57916a7a
GM
4623 end_char = XINT (end);
4624
4625 if (end_char < 0)
4626 end_char += size;
57916a7a 4627 }
91f78c99 4628
57916a7a
GM
4629 if (!(0 <= start_char && start_char <= end_char && end_char <= size))
4630 args_out_of_range_3 (object, make_number (start_char),
4631 make_number (end_char));
d311d28c
PE
4632
4633 start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char);
4634 end_byte =
4635 NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char);
57916a7a
GM
4636 }
4637 else
4638 {
6b61353c
KH
4639 struct buffer *prev = current_buffer;
4640
66322887 4641 record_unwind_current_buffer ();
6b61353c 4642
b7826503 4643 CHECK_BUFFER (object);
57916a7a
GM
4644
4645 bp = XBUFFER (object);
a3d794a1 4646 set_buffer_internal (bp);
91f78c99 4647
57916a7a 4648 if (NILP (start))
6b61353c 4649 b = BEGV;
57916a7a
GM
4650 else
4651 {
b7826503 4652 CHECK_NUMBER_COERCE_MARKER (start);
57916a7a
GM
4653 b = XINT (start);
4654 }
4655
4656 if (NILP (end))
6b61353c 4657 e = ZV;
57916a7a
GM
4658 else
4659 {
b7826503 4660 CHECK_NUMBER_COERCE_MARKER (end);
57916a7a
GM
4661 e = XINT (end);
4662 }
91f78c99 4663
57916a7a
GM
4664 if (b > e)
4665 temp = b, b = e, e = temp;
91f78c99 4666
6b61353c 4667 if (!(BEGV <= b && e <= ZV))
57916a7a 4668 args_out_of_range (start, end);
91f78c99 4669
57916a7a
GM
4670 if (NILP (coding_system))
4671 {
91f78c99 4672 /* Decide the coding-system to encode the data with.
5c302da4
GM
4673 See fileio.c:Fwrite-region */
4674
4675 if (!NILP (Vcoding_system_for_write))
4676 coding_system = Vcoding_system_for_write;
4677 else
4678 {
f75d7a91 4679 bool force_raw_text = 0;
5c302da4 4680
4b4deea2 4681 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4682 if (NILP (coding_system)
4683 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4684 {
4685 coding_system = Qnil;
4b4deea2 4686 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
5c302da4
GM
4687 force_raw_text = 1;
4688 }
4689
5e617bc2 4690 if (NILP (coding_system) && !NILP (Fbuffer_file_name (object)))
5c302da4
GM
4691 {
4692 /* Check file-coding-system-alist. */
4693 Lisp_Object args[4], val;
91f78c99 4694
5c302da4 4695 args[0] = Qwrite_region; args[1] = start; args[2] = end;
5e617bc2 4696 args[3] = Fbuffer_file_name (object);
5c302da4
GM
4697 val = Ffind_operation_coding_system (4, args);
4698 if (CONSP (val) && !NILP (XCDR (val)))
4699 coding_system = XCDR (val);
4700 }
4701
4702 if (NILP (coding_system)
4b4deea2 4703 && !NILP (BVAR (XBUFFER (object), buffer_file_coding_system)))
5c302da4
GM
4704 {
4705 /* If we still have not decided a coding system, use the
4706 default value of buffer-file-coding-system. */
4b4deea2 4707 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4708 }
4709
4710 if (!force_raw_text
4711 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4712 /* Confirm that VAL can surely encode the current region. */
1e59646d 4713 coding_system = call4 (Vselect_safe_coding_system_function,
70da6a76 4714 make_number (b), make_number (e),
1e59646d 4715 coding_system, Qnil);
5c302da4
GM
4716
4717 if (force_raw_text)
4718 coding_system = Qraw_text;
4719 }
4720
4721 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4722 {
5c302da4
GM
4723 /* Invalid coding system. */
4724
4725 if (!NILP (noerror))
4726 coding_system = Qraw_text;
4727 else
692ae65c 4728 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4729 }
4730 }
4731
4732 object = make_buffer_string (b, e, 0);
a3d794a1 4733 set_buffer_internal (prev);
6b61353c
KH
4734 /* Discard the unwind protect for recovering the current
4735 buffer. */
4736 specpdl_ptr--;
57916a7a
GM
4737
4738 if (STRING_MULTIBYTE (object))
8f924df7 4739 object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
d311d28c
PE
4740 start_byte = 0;
4741 end_byte = SBYTES (object);
57916a7a
GM
4742 }
4743
7f3f739f 4744 if (EQ (algorithm, Qmd5))
e1b90ef6 4745 {
7f3f739f
LL
4746 digest_size = MD5_DIGEST_SIZE;
4747 hash_func = md5_buffer;
4748 }
4749 else if (EQ (algorithm, Qsha1))
4750 {
4751 digest_size = SHA1_DIGEST_SIZE;
4752 hash_func = sha1_buffer;
4753 }
4754 else if (EQ (algorithm, Qsha224))
4755 {
4756 digest_size = SHA224_DIGEST_SIZE;
4757 hash_func = sha224_buffer;
4758 }
4759 else if (EQ (algorithm, Qsha256))
4760 {
4761 digest_size = SHA256_DIGEST_SIZE;
4762 hash_func = sha256_buffer;
4763 }
4764 else if (EQ (algorithm, Qsha384))
4765 {
4766 digest_size = SHA384_DIGEST_SIZE;
4767 hash_func = sha384_buffer;
4768 }
4769 else if (EQ (algorithm, Qsha512))
4770 {
4771 digest_size = SHA512_DIGEST_SIZE;
4772 hash_func = sha512_buffer;
4773 }
4774 else
4775 error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm)));
57916a7a 4776
7f3f739f
LL
4777 /* allocate 2 x digest_size so that it can be re-used to hold the
4778 hexified value */
4779 digest = make_uninit_string (digest_size * 2);
57916a7a 4780
7f3f739f 4781 hash_func (SSDATA (object) + start_byte,
d311d28c 4782 end_byte - start_byte,
7f3f739f 4783 SSDATA (digest));
e1b90ef6 4784
7f3f739f
LL
4785 if (NILP (binary))
4786 {
4787 unsigned char *p = SDATA (digest);
4788 for (i = digest_size - 1; i >= 0; i--)
4789 {
4790 static char const hexdigit[16] = "0123456789abcdef";
4791 int p_i = p[i];
4792 p[2 * i] = hexdigit[p_i >> 4];
4793 p[2 * i + 1] = hexdigit[p_i & 0xf];
4794 }
4795 return digest;
4796 }
4797 else
a9041e6c 4798 return make_unibyte_string (SSDATA (digest), digest_size);
e1b90ef6
LL
4799}
4800
4801DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
4802 doc: /* Return MD5 message digest of OBJECT, a buffer or string.
4803
4804A message digest is a cryptographic checksum of a document, and the
4805algorithm to calculate it is defined in RFC 1321.
4806
4807The two optional arguments START and END are character positions
4808specifying for which part of OBJECT the message digest should be
4809computed. If nil or omitted, the digest is computed for the whole
4810OBJECT.
4811
4812The MD5 message digest is computed from the result of encoding the
4813text in a coding system, not directly from the internal Emacs form of
4814the text. The optional fourth argument CODING-SYSTEM specifies which
4815coding system to encode the text with. It should be the same coding
4816system that you used or will use when actually writing the text into a
4817file.
4818
4819If CODING-SYSTEM is nil or omitted, the default depends on OBJECT. If
4820OBJECT is a buffer, the default for CODING-SYSTEM is whatever coding
4821system would be chosen by default for writing this text into a file.
4822
4823If OBJECT is a string, the most preferred coding system (see the
4824command `prefer-coding-system') is used.
4825
4826If NOERROR is non-nil, silently assume the `raw-text' coding if the
4827guesswork fails. Normally, an error is signaled in such case. */)
4828 (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror)
4829{
7f3f739f 4830 return secure_hash (Qmd5, object, start, end, coding_system, noerror, Qnil);
e1b90ef6
LL
4831}
4832
7f3f739f 4833DEFUN ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0,
49241268
GM
4834 doc: /* Return the secure hash of OBJECT, a buffer or string.
4835ALGORITHM is a symbol specifying the hash to use:
4836md5, sha1, sha224, sha256, sha384 or sha512.
4837
4838The two optional arguments START and END are positions specifying for
4839which part of OBJECT to compute the hash. If nil or omitted, uses the
4840whole OBJECT.
4841
4842If BINARY is non-nil, returns a string in binary form. */)
7f3f739f 4843 (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
e1b90ef6 4844{
7f3f739f 4845 return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary);
57916a7a 4846}
24c129e4 4847\f
dfcf069d 4848void
971de7fb 4849syms_of_fns (void)
7b863bd5 4850{
7f3f739f
LL
4851 DEFSYM (Qmd5, "md5");
4852 DEFSYM (Qsha1, "sha1");
4853 DEFSYM (Qsha224, "sha224");
4854 DEFSYM (Qsha256, "sha256");
4855 DEFSYM (Qsha384, "sha384");
4856 DEFSYM (Qsha512, "sha512");
4857
d80c6c11 4858 /* Hash table stuff. */
cd3520a4
JB
4859 DEFSYM (Qhash_table_p, "hash-table-p");
4860 DEFSYM (Qeq, "eq");
4861 DEFSYM (Qeql, "eql");
4862 DEFSYM (Qequal, "equal");
4863 DEFSYM (QCtest, ":test");
4864 DEFSYM (QCsize, ":size");
4865 DEFSYM (QCrehash_size, ":rehash-size");
4866 DEFSYM (QCrehash_threshold, ":rehash-threshold");
4867 DEFSYM (QCweakness, ":weakness");
4868 DEFSYM (Qkey, "key");
4869 DEFSYM (Qvalue, "value");
4870 DEFSYM (Qhash_table_test, "hash-table-test");
4871 DEFSYM (Qkey_or_value, "key-or-value");
4872 DEFSYM (Qkey_and_value, "key-and-value");
d80c6c11
GM
4873
4874 defsubr (&Ssxhash);
4875 defsubr (&Smake_hash_table);
f899c503 4876 defsubr (&Scopy_hash_table);
d80c6c11
GM
4877 defsubr (&Shash_table_count);
4878 defsubr (&Shash_table_rehash_size);
4879 defsubr (&Shash_table_rehash_threshold);
4880 defsubr (&Shash_table_size);
4881 defsubr (&Shash_table_test);
e84b1dea 4882 defsubr (&Shash_table_weakness);
d80c6c11
GM
4883 defsubr (&Shash_table_p);
4884 defsubr (&Sclrhash);
4885 defsubr (&Sgethash);
4886 defsubr (&Sputhash);
4887 defsubr (&Sremhash);
4888 defsubr (&Smaphash);
4889 defsubr (&Sdefine_hash_table_test);
59f953a2 4890
cd3520a4
JB
4891 DEFSYM (Qstring_lessp, "string-lessp");
4892 DEFSYM (Qprovide, "provide");
4893 DEFSYM (Qrequire, "require");
4894 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history");
4895 DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area");
4896 DEFSYM (Qwidget_type, "widget-type");
7b863bd5 4897
09ab3c3b
KH
4898 staticpro (&string_char_byte_cache_string);
4899 string_char_byte_cache_string = Qnil;
4900
1f79789d
RS
4901 require_nesting_list = Qnil;
4902 staticpro (&require_nesting_list);
4903
52a9879b
RS
4904 Fset (Qyes_or_no_p_history, Qnil);
4905
29208e82 4906 DEFVAR_LISP ("features", Vfeatures,
4774b68e 4907 doc: /* A list of symbols which are the features of the executing Emacs.
47cebab1 4908Used by `featurep' and `require', and altered by `provide'. */);
6c6f1994 4909 Vfeatures = list1 (intern_c_string ("emacs"));
cd3520a4 4910 DEFSYM (Qsubfeatures, "subfeatures");
de0503df 4911 DEFSYM (Qfuncall, "funcall");
7b863bd5 4912
dec002ca 4913#ifdef HAVE_LANGINFO_CODESET
cd3520a4
JB
4914 DEFSYM (Qcodeset, "codeset");
4915 DEFSYM (Qdays, "days");
4916 DEFSYM (Qmonths, "months");
4917 DEFSYM (Qpaper, "paper");
dec002ca
DL
4918#endif /* HAVE_LANGINFO_CODESET */
4919
29208e82 4920 DEFVAR_BOOL ("use-dialog-box", use_dialog_box,
fb7ada5f 4921 doc: /* Non-nil means mouse commands use dialog boxes to ask questions.
436fa78b 4922This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands
7e861e0d
CY
4923invoked by mouse clicks and mouse menu items.
4924
4925On some platforms, file selection dialogs are also enabled if this is
4926non-nil. */);
bdd8d692
RS
4927 use_dialog_box = 1;
4928
29208e82 4929 DEFVAR_BOOL ("use-file-dialog", use_file_dialog,
fb7ada5f 4930 doc: /* Non-nil means mouse commands use a file dialog to ask for files.
1f1d0797 4931This applies to commands from menus and tool bar buttons even when
2fd0161b
CY
4932they are initiated from the keyboard. If `use-dialog-box' is nil,
4933that disables the use of a file dialog, regardless of the value of
4934this variable. */);
6b61353c
KH
4935 use_file_dialog = 1;
4936
7b863bd5
JB
4937 defsubr (&Sidentity);
4938 defsubr (&Srandom);
4939 defsubr (&Slength);
5a30fab8 4940 defsubr (&Ssafe_length);
026f59ce 4941 defsubr (&Sstring_bytes);
7b863bd5 4942 defsubr (&Sstring_equal);
0e1e9f8d 4943 defsubr (&Scompare_strings);
7b863bd5
JB
4944 defsubr (&Sstring_lessp);
4945 defsubr (&Sappend);
4946 defsubr (&Sconcat);
4947 defsubr (&Svconcat);
4948 defsubr (&Scopy_sequence);
09ab3c3b
KH
4949 defsubr (&Sstring_make_multibyte);
4950 defsubr (&Sstring_make_unibyte);
6d475204
RS
4951 defsubr (&Sstring_as_multibyte);
4952 defsubr (&Sstring_as_unibyte);
2df18cdb 4953 defsubr (&Sstring_to_multibyte);
b4480f16 4954 defsubr (&Sstring_to_unibyte);
7b863bd5
JB
4955 defsubr (&Scopy_alist);
4956 defsubr (&Ssubstring);
aebf4d42 4957 defsubr (&Ssubstring_no_properties);
7b863bd5
JB
4958 defsubr (&Snthcdr);
4959 defsubr (&Snth);
4960 defsubr (&Selt);
4961 defsubr (&Smember);
4962 defsubr (&Smemq);
008ef0ef 4963 defsubr (&Smemql);
7b863bd5
JB
4964 defsubr (&Sassq);
4965 defsubr (&Sassoc);
4966 defsubr (&Srassq);
0fb5a19c 4967 defsubr (&Srassoc);
7b863bd5 4968 defsubr (&Sdelq);
ca8dd546 4969 defsubr (&Sdelete);
7b863bd5
JB
4970 defsubr (&Snreverse);
4971 defsubr (&Sreverse);
4972 defsubr (&Ssort);
be9d483d 4973 defsubr (&Splist_get);
7b863bd5 4974 defsubr (&Sget);
be9d483d 4975 defsubr (&Splist_put);
7b863bd5 4976 defsubr (&Sput);
aebf4d42
RS
4977 defsubr (&Slax_plist_get);
4978 defsubr (&Slax_plist_put);
95f8c3b9 4979 defsubr (&Seql);
7b863bd5 4980 defsubr (&Sequal);
6b61353c 4981 defsubr (&Sequal_including_properties);
7b863bd5 4982 defsubr (&Sfillarray);
85cad579 4983 defsubr (&Sclear_string);
7b863bd5
JB
4984 defsubr (&Snconc);
4985 defsubr (&Smapcar);
5c6740c9 4986 defsubr (&Smapc);
7b863bd5 4987 defsubr (&Smapconcat);
7b863bd5
JB
4988 defsubr (&Syes_or_no_p);
4989 defsubr (&Sload_average);
4990 defsubr (&Sfeaturep);
4991 defsubr (&Srequire);
4992 defsubr (&Sprovide);
a5254817 4993 defsubr (&Splist_member);
b4f334f7
KH
4994 defsubr (&Swidget_put);
4995 defsubr (&Swidget_get);
4996 defsubr (&Swidget_apply);
24c129e4
KH
4997 defsubr (&Sbase64_encode_region);
4998 defsubr (&Sbase64_decode_region);
4999 defsubr (&Sbase64_encode_string);
5000 defsubr (&Sbase64_decode_string);
57916a7a 5001 defsubr (&Smd5);
7f3f739f 5002 defsubr (&Ssecure_hash);
d68beb2f 5003 defsubr (&Slocale_info);
b7432bb2 5004
29abe551
PE
5005 hashtest_eq.name = Qeq;
5006 hashtest_eq.user_hash_function = Qnil;
5007 hashtest_eq.user_cmp_function = Qnil;
5008 hashtest_eq.cmpfn = 0;
5009 hashtest_eq.hashfn = hashfn_eq;
5010
5011 hashtest_eql.name = Qeql;
5012 hashtest_eql.user_hash_function = Qnil;
5013 hashtest_eql.user_cmp_function = Qnil;
5014 hashtest_eql.cmpfn = cmpfn_eql;
5015 hashtest_eql.hashfn = hashfn_eql;
5016
5017 hashtest_equal.name = Qequal;
5018 hashtest_equal.user_hash_function = Qnil;
5019 hashtest_equal.user_cmp_function = Qnil;
5020 hashtest_equal.cmpfn = cmpfn_equal;
5021 hashtest_equal.hashfn = hashfn_equal;
7b863bd5 5022}