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