* simple.el (completion-list-mode-finish): Don't use toggle-read-only.
[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
PE
80 {
81 EMACS_TIME t;
82 EMACS_GET_TIME (t);
d35af63c 83 seed_random (getpid () ^ EMACS_SECS (t) ^ EMACS_NSECS (t));
d8ed26bd
PE
84 }
85
13d62fad 86 if (NATNUMP (limit) && XFASTINT (limit) != 0)
7b863bd5 87 {
4cab5074
KH
88 /* Try to take our random number from the higher bits of VAL,
89 not the lower, since (says Gentzel) the low bits of `random'
90 are less random than the higher ones. We do this by using the
91 quotient rather than the remainder. At the high end of the RNG
88fe8140 92 it's possible to get a quotient larger than n; discarding
4cab5074 93 these values eliminates the bias that would otherwise appear
88fe8140 94 when using a large n. */
d8ed26bd 95 EMACS_INT denominator = (INTMASK + 1) / XFASTINT (limit);
4cab5074 96 do
99175c23 97 val = get_random () / denominator;
13d62fad 98 while (val >= XFASTINT (limit));
7b863bd5 99 }
78217ef1 100 else
99175c23 101 val = get_random ();
e2d6972a
KH
102 XSETINT (lispy_val, val);
103 return lispy_val;
7b863bd5
JB
104}
105\f
e6966cd6
PE
106/* Heuristic on how many iterations of a tight loop can be safely done
107 before it's time to do a QUIT. This must be a power of 2. */
108enum { QUIT_COUNT_HEURISTIC = 1 << 16 };
109
7b863bd5
JB
110/* Random data-structure functions */
111
a7ca3326 112DEFUN ("length", Flength, Slength, 1, 1, 0,
e9d8ddc9 113 doc: /* Return the length of vector, list or string SEQUENCE.
47cebab1 114A byte-code function object is also allowed.
f5965ada 115If the string contains multibyte characters, this is not necessarily
47cebab1 116the number of bytes in the string; it is the number of characters.
adf2c803 117To get the number of bytes, use `string-bytes'. */)
5842a27b 118 (register Lisp_Object sequence)
7b863bd5 119{
504f24f1 120 register Lisp_Object val;
7b863bd5 121
88fe8140 122 if (STRINGP (sequence))
d5db4077 123 XSETFASTINT (val, SCHARS (sequence));
88fe8140 124 else if (VECTORP (sequence))
7edbb0da 125 XSETFASTINT (val, ASIZE (sequence));
88fe8140 126 else if (CHAR_TABLE_P (sequence))
64a5094a 127 XSETFASTINT (val, MAX_CHAR);
88fe8140
EN
128 else if (BOOL_VECTOR_P (sequence))
129 XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
876c194c
SM
130 else if (COMPILEDP (sequence))
131 XSETFASTINT (val, ASIZE (sequence) & PSEUDOVECTOR_SIZE_MASK);
88fe8140 132 else if (CONSP (sequence))
7b863bd5 133 {
00c604f2
PE
134 EMACS_INT i = 0;
135
136 do
7b863bd5 137 {
7843e09c 138 ++i;
e6966cd6 139 if ((i & (QUIT_COUNT_HEURISTIC - 1)) == 0)
00c604f2
PE
140 {
141 if (MOST_POSITIVE_FIXNUM < i)
142 error ("List too long");
143 QUIT;
144 }
7843e09c 145 sequence = XCDR (sequence);
7b863bd5 146 }
00c604f2 147 while (CONSP (sequence));
7b863bd5 148
89662fc3 149 CHECK_LIST_END (sequence, sequence);
f2be3671
GM
150
151 val = make_number (i);
7b863bd5 152 }
88fe8140 153 else if (NILP (sequence))
a2ad3e19 154 XSETFASTINT (val, 0);
7b863bd5 155 else
692ae65c 156 wrong_type_argument (Qsequencep, sequence);
89662fc3 157
a2ad3e19 158 return val;
7b863bd5
JB
159}
160
12ae7fc6 161/* This does not check for quits. That is safe since it must terminate. */
5a30fab8
RS
162
163DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
e9d8ddc9 164 doc: /* Return the length of a list, but avoid error or infinite loop.
47cebab1
GM
165This function never gets an error. If LIST is not really a list,
166it returns 0. If LIST is circular, it returns a finite value
adf2c803 167which is at least the number of distinct elements. */)
5842a27b 168 (Lisp_Object list)
5a30fab8 169{
e6966cd6
PE
170 Lisp_Object tail, halftail;
171 double hilen = 0;
172 uintmax_t lolen = 1;
173
174 if (! CONSP (list))
ff2bc410 175 return make_number (0);
5a30fab8
RS
176
177 /* halftail is used to detect circular lists. */
e6966cd6 178 for (tail = halftail = list; ; )
5a30fab8 179 {
e6966cd6
PE
180 tail = XCDR (tail);
181 if (! CONSP (tail))
cb3d1a0a 182 break;
e6966cd6
PE
183 if (EQ (tail, halftail))
184 break;
185 lolen++;
186 if ((lolen & 1) == 0)
187 {
188 halftail = XCDR (halftail);
189 if ((lolen & (QUIT_COUNT_HEURISTIC - 1)) == 0)
190 {
191 QUIT;
192 if (lolen == 0)
193 hilen += UINTMAX_MAX + 1.0;
194 }
195 }
5a30fab8
RS
196 }
197
e6966cd6
PE
198 /* If the length does not fit into a fixnum, return a float.
199 On all known practical machines this returns an upper bound on
200 the true length. */
201 return hilen ? make_float (hilen + lolen) : make_fixnum_or_float (lolen);
5a30fab8
RS
202}
203
91f78c99 204DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
e9d8ddc9 205 doc: /* Return the number of bytes in STRING.
eeb7eaa8 206If STRING is multibyte, this may be greater than the length of STRING. */)
5842a27b 207 (Lisp_Object string)
026f59ce 208{
b7826503 209 CHECK_STRING (string);
d5db4077 210 return make_number (SBYTES (string));
026f59ce
RS
211}
212
a7ca3326 213DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
e9d8ddc9 214 doc: /* Return t if two strings have identical contents.
47cebab1 215Case is significant, but text properties are ignored.
adf2c803 216Symbols are also allowed; their print names are used instead. */)
5842a27b 217 (register Lisp_Object s1, Lisp_Object s2)
7b863bd5 218{
7650760e 219 if (SYMBOLP (s1))
c06583e1 220 s1 = SYMBOL_NAME (s1);
7650760e 221 if (SYMBOLP (s2))
c06583e1 222 s2 = SYMBOL_NAME (s2);
b7826503
PJ
223 CHECK_STRING (s1);
224 CHECK_STRING (s2);
7b863bd5 225
d5db4077
KR
226 if (SCHARS (s1) != SCHARS (s2)
227 || SBYTES (s1) != SBYTES (s2)
72af86bd 228 || memcmp (SDATA (s1), SDATA (s2), SBYTES (s1)))
7b863bd5
JB
229 return Qnil;
230 return Qt;
231}
232
a7ca3326 233DEFUN ("compare-strings", Fcompare_strings, Scompare_strings, 6, 7, 0,
b756c005 234 doc: /* Compare the contents of two strings, converting to multibyte if needed.
47cebab1
GM
235In string STR1, skip the first START1 characters and stop at END1.
236In string STR2, skip the first START2 characters and stop at END2.
237END1 and END2 default to the full lengths of the respective strings.
238
239Case is significant in this comparison if IGNORE-CASE is nil.
240Unibyte strings are converted to multibyte for comparison.
241
242The value is t if the strings (or specified portions) match.
243If string STR1 is less, the value is a negative number N;
244 - 1 - N is the number of characters that match at the beginning.
245If string STR1 is greater, the value is a positive number N;
adf2c803 246 N - 1 is the number of characters that match at the beginning. */)
5842a27b 247 (Lisp_Object str1, Lisp_Object start1, Lisp_Object end1, Lisp_Object str2, Lisp_Object start2, Lisp_Object end2, Lisp_Object ignore_case)
0e1e9f8d 248{
d311d28c
PE
249 register ptrdiff_t end1_char, end2_char;
250 register ptrdiff_t i1, i1_byte, i2, i2_byte;
0e1e9f8d 251
b7826503
PJ
252 CHECK_STRING (str1);
253 CHECK_STRING (str2);
0e1e9f8d
RS
254 if (NILP (start1))
255 start1 = make_number (0);
256 if (NILP (start2))
257 start2 = make_number (0);
b7826503
PJ
258 CHECK_NATNUM (start1);
259 CHECK_NATNUM (start2);
0e1e9f8d 260 if (! NILP (end1))
b7826503 261 CHECK_NATNUM (end1);
0e1e9f8d 262 if (! NILP (end2))
b7826503 263 CHECK_NATNUM (end2);
0e1e9f8d 264
d5db4077 265 end1_char = SCHARS (str1);
0e1e9f8d
RS
266 if (! NILP (end1) && end1_char > XINT (end1))
267 end1_char = XINT (end1);
d311d28c
PE
268 if (end1_char < XINT (start1))
269 args_out_of_range (str1, start1);
0e1e9f8d 270
d5db4077 271 end2_char = SCHARS (str2);
0e1e9f8d
RS
272 if (! NILP (end2) && end2_char > XINT (end2))
273 end2_char = XINT (end2);
d311d28c
PE
274 if (end2_char < XINT (start2))
275 args_out_of_range (str2, start2);
276
277 i1 = XINT (start1);
278 i2 = XINT (start2);
279
280 i1_byte = string_char_to_byte (str1, i1);
281 i2_byte = string_char_to_byte (str2, i2);
0e1e9f8d
RS
282
283 while (i1 < end1_char && i2 < end2_char)
284 {
285 /* When we find a mismatch, we must compare the
286 characters, not just the bytes. */
287 int c1, c2;
288
289 if (STRING_MULTIBYTE (str1))
2efdd1b9 290 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c1, str1, i1, i1_byte);
0e1e9f8d
RS
291 else
292 {
d5db4077 293 c1 = SREF (str1, i1++);
4c0354d7 294 MAKE_CHAR_MULTIBYTE (c1);
0e1e9f8d
RS
295 }
296
297 if (STRING_MULTIBYTE (str2))
2efdd1b9 298 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c2, str2, i2, i2_byte);
0e1e9f8d
RS
299 else
300 {
d5db4077 301 c2 = SREF (str2, i2++);
4c0354d7 302 MAKE_CHAR_MULTIBYTE (c2);
0e1e9f8d
RS
303 }
304
305 if (c1 == c2)
306 continue;
307
308 if (! NILP (ignore_case))
309 {
310 Lisp_Object tem;
311
312 tem = Fupcase (make_number (c1));
313 c1 = XINT (tem);
314 tem = Fupcase (make_number (c2));
315 c2 = XINT (tem);
316 }
317
318 if (c1 == c2)
319 continue;
320
321 /* Note that I1 has already been incremented
322 past the character that we are comparing;
323 hence we don't add or subtract 1 here. */
324 if (c1 < c2)
60f8d735 325 return make_number (- i1 + XINT (start1));
0e1e9f8d 326 else
60f8d735 327 return make_number (i1 - XINT (start1));
0e1e9f8d
RS
328 }
329
330 if (i1 < end1_char)
331 return make_number (i1 - XINT (start1) + 1);
332 if (i2 < end2_char)
333 return make_number (- i1 + XINT (start1) - 1);
334
335 return Qt;
336}
337
a7ca3326 338DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
e9d8ddc9 339 doc: /* Return t if first arg string is less than second in lexicographic order.
47cebab1 340Case is significant.
adf2c803 341Symbols are also allowed; their print names are used instead. */)
5842a27b 342 (register Lisp_Object s1, Lisp_Object s2)
7b863bd5 343{
d311d28c
PE
344 register ptrdiff_t end;
345 register ptrdiff_t i1, i1_byte, i2, i2_byte;
7b863bd5 346
7650760e 347 if (SYMBOLP (s1))
c06583e1 348 s1 = SYMBOL_NAME (s1);
7650760e 349 if (SYMBOLP (s2))
c06583e1 350 s2 = SYMBOL_NAME (s2);
b7826503
PJ
351 CHECK_STRING (s1);
352 CHECK_STRING (s2);
7b863bd5 353
09ab3c3b
KH
354 i1 = i1_byte = i2 = i2_byte = 0;
355
d5db4077
KR
356 end = SCHARS (s1);
357 if (end > SCHARS (s2))
358 end = SCHARS (s2);
7b863bd5 359
09ab3c3b 360 while (i1 < end)
7b863bd5 361 {
09ab3c3b
KH
362 /* When we find a mismatch, we must compare the
363 characters, not just the bytes. */
364 int c1, c2;
365
2efdd1b9
KH
366 FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte);
367 FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte);
09ab3c3b
KH
368
369 if (c1 != c2)
370 return c1 < c2 ? Qt : Qnil;
7b863bd5 371 }
d5db4077 372 return i1 < SCHARS (s2) ? Qt : Qnil;
7b863bd5
JB
373}
374\f
f66c7cf8 375static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args,
a64df650 376 enum Lisp_Type target_type, int last_special);
7b863bd5
JB
377
378/* ARGSUSED */
379Lisp_Object
971de7fb 380concat2 (Lisp_Object s1, Lisp_Object s2)
7b863bd5 381{
7b863bd5
JB
382 Lisp_Object args[2];
383 args[0] = s1;
384 args[1] = s2;
385 return concat (2, args, Lisp_String, 0);
7b863bd5
JB
386}
387
d4af3687
RS
388/* ARGSUSED */
389Lisp_Object
971de7fb 390concat3 (Lisp_Object s1, Lisp_Object s2, Lisp_Object s3)
d4af3687 391{
d4af3687
RS
392 Lisp_Object args[3];
393 args[0] = s1;
394 args[1] = s2;
395 args[2] = s3;
396 return concat (3, args, Lisp_String, 0);
d4af3687
RS
397}
398
a7ca3326 399DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
e9d8ddc9 400 doc: /* Concatenate all the arguments and make the result a list.
47cebab1
GM
401The result is a list whose elements are the elements of all the arguments.
402Each argument may be a list, vector or string.
4bf8e2a3
MB
403The last argument is not copied, just used as the tail of the new list.
404usage: (append &rest SEQUENCES) */)
f66c7cf8 405 (ptrdiff_t nargs, Lisp_Object *args)
7b863bd5
JB
406{
407 return concat (nargs, args, Lisp_Cons, 1);
408}
409
a7ca3326 410DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
e9d8ddc9 411 doc: /* Concatenate all the arguments and make the result a string.
47cebab1 412The result is a string whose elements are the elements of all the arguments.
4bf8e2a3
MB
413Each argument may be a string or a list or vector of characters (integers).
414usage: (concat &rest SEQUENCES) */)
f66c7cf8 415 (ptrdiff_t nargs, Lisp_Object *args)
7b863bd5
JB
416{
417 return concat (nargs, args, Lisp_String, 0);
418}
419
a7ca3326 420DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
e9d8ddc9 421 doc: /* Concatenate all the arguments and make the result a vector.
47cebab1 422The result is a vector whose elements are the elements of all the arguments.
4bf8e2a3
MB
423Each argument may be a list, vector or string.
424usage: (vconcat &rest SEQUENCES) */)
f66c7cf8 425 (ptrdiff_t nargs, Lisp_Object *args)
7b863bd5 426{
3e7383eb 427 return concat (nargs, args, Lisp_Vectorlike, 0);
7b863bd5
JB
428}
429
3720677d 430
a7ca3326 431DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
7652ade0 432 doc: /* Return a copy of a list, vector, string or char-table.
47cebab1 433The elements of a list or vector are not copied; they are shared
adf2c803 434with the original. */)
5842a27b 435 (Lisp_Object arg)
7b863bd5 436{
265a9e55 437 if (NILP (arg)) return arg;
e03f7933
RS
438
439 if (CHAR_TABLE_P (arg))
440 {
38583a69 441 return copy_char_table (arg);
e03f7933
RS
442 }
443
444 if (BOOL_VECTOR_P (arg))
445 {
446 Lisp_Object val;
de41a810 447 ptrdiff_t size_in_chars
db85986c
AS
448 = ((XBOOL_VECTOR (arg)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
449 / BOOL_VECTOR_BITS_PER_CHAR);
e03f7933
RS
450
451 val = Fmake_bool_vector (Flength (arg), Qnil);
72af86bd
AS
452 memcpy (XBOOL_VECTOR (val)->data, XBOOL_VECTOR (arg)->data,
453 size_in_chars);
e03f7933
RS
454 return val;
455 }
456
7650760e 457 if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
89662fc3
KS
458 wrong_type_argument (Qsequencep, arg);
459
7b863bd5
JB
460 return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
461}
462
2d6115c8
KH
463/* This structure holds information of an argument of `concat' that is
464 a string and has text properties to be copied. */
87f0532f 465struct textprop_rec
2d6115c8 466{
f66c7cf8 467 ptrdiff_t argnum; /* refer to ARGS (arguments of `concat') */
d311d28c
PE
468 ptrdiff_t from; /* refer to ARGS[argnum] (argument string) */
469 ptrdiff_t to; /* refer to VAL (the target string) */
2d6115c8
KH
470};
471
7b863bd5 472static Lisp_Object
f66c7cf8 473concat (ptrdiff_t nargs, Lisp_Object *args,
c5101a77 474 enum Lisp_Type target_type, int last_special)
7b863bd5
JB
475{
476 Lisp_Object val;
7b863bd5
JB
477 register Lisp_Object tail;
478 register Lisp_Object this;
d311d28c
PE
479 ptrdiff_t toindex;
480 ptrdiff_t toindex_byte = 0;
e6d4aefa
EZ
481 register EMACS_INT result_len;
482 register EMACS_INT result_len_byte;
f66c7cf8 483 ptrdiff_t argnum;
7b863bd5
JB
484 Lisp_Object last_tail;
485 Lisp_Object prev;
ea35ce3d 486 int some_multibyte;
2d6115c8 487 /* When we make a multibyte string, we can't copy text properties
66699ad3
PE
488 while concatenating each string because the length of resulting
489 string can't be decided until we finish the whole concatenation.
2d6115c8 490 So, we record strings that have text properties to be copied
66699ad3 491 here, and copy the text properties after the concatenation. */
093386ca 492 struct textprop_rec *textprops = NULL;
78edd3b7 493 /* Number of elements in textprops. */
f66c7cf8 494 ptrdiff_t num_textprops = 0;
2ec7f67a 495 USE_SAFE_ALLOCA;
7b863bd5 496
093386ca
GM
497 tail = Qnil;
498
7b863bd5
JB
499 /* In append, the last arg isn't treated like the others */
500 if (last_special && nargs > 0)
501 {
502 nargs--;
503 last_tail = args[nargs];
504 }
505 else
506 last_tail = Qnil;
507
89662fc3 508 /* Check each argument. */
7b863bd5
JB
509 for (argnum = 0; argnum < nargs; argnum++)
510 {
511 this = args[argnum];
7650760e 512 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
876c194c 513 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
89662fc3 514 wrong_type_argument (Qsequencep, this);
7b863bd5
JB
515 }
516
ea35ce3d
RS
517 /* Compute total length in chars of arguments in RESULT_LEN.
518 If desired output is a string, also compute length in bytes
519 in RESULT_LEN_BYTE, and determine in SOME_MULTIBYTE
520 whether the result should be a multibyte string. */
521 result_len_byte = 0;
522 result_len = 0;
523 some_multibyte = 0;
524 for (argnum = 0; argnum < nargs; argnum++)
7b863bd5 525 {
e6d4aefa 526 EMACS_INT len;
7b863bd5 527 this = args[argnum];
ea35ce3d
RS
528 len = XFASTINT (Flength (this));
529 if (target_type == Lisp_String)
5b6dddaa 530 {
09ab3c3b
KH
531 /* We must count the number of bytes needed in the string
532 as well as the number of characters. */
d311d28c 533 ptrdiff_t i;
5b6dddaa 534 Lisp_Object ch;
c1f134b5 535 int c;
d311d28c 536 ptrdiff_t this_len_byte;
5b6dddaa 537
876c194c 538 if (VECTORP (this) || COMPILEDP (this))
ea35ce3d 539 for (i = 0; i < len; i++)
dec58e65 540 {
7edbb0da 541 ch = AREF (this, i);
63db3c1b 542 CHECK_CHARACTER (ch);
c1f134b5
PE
543 c = XFASTINT (ch);
544 this_len_byte = CHAR_BYTES (c);
d311d28c
PE
545 if (STRING_BYTES_BOUND - result_len_byte < this_len_byte)
546 string_overflow ();
ea35ce3d 547 result_len_byte += this_len_byte;
c1f134b5 548 if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c))
ea35ce3d 549 some_multibyte = 1;
dec58e65 550 }
6d475204
RS
551 else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
552 wrong_type_argument (Qintegerp, Faref (this, make_number (0)));
ea35ce3d 553 else if (CONSP (this))
70949dac 554 for (; CONSP (this); this = XCDR (this))
dec58e65 555 {
70949dac 556 ch = XCAR (this);
63db3c1b 557 CHECK_CHARACTER (ch);
c1f134b5
PE
558 c = XFASTINT (ch);
559 this_len_byte = CHAR_BYTES (c);
d311d28c
PE
560 if (STRING_BYTES_BOUND - result_len_byte < this_len_byte)
561 string_overflow ();
ea35ce3d 562 result_len_byte += this_len_byte;
c1f134b5 563 if (! ASCII_CHAR_P (c) && ! CHAR_BYTE8_P (c))
ea35ce3d 564 some_multibyte = 1;
dec58e65 565 }
470730a8 566 else if (STRINGP (this))
ea35ce3d 567 {
06f57aa7 568 if (STRING_MULTIBYTE (this))
09ab3c3b
KH
569 {
570 some_multibyte = 1;
d311d28c 571 this_len_byte = SBYTES (this);
09ab3c3b
KH
572 }
573 else
d311d28c
PE
574 this_len_byte = count_size_as_multibyte (SDATA (this),
575 SCHARS (this));
576 if (STRING_BYTES_BOUND - result_len_byte < this_len_byte)
577 string_overflow ();
578 result_len_byte += this_len_byte;
ea35ce3d 579 }
5b6dddaa 580 }
ea35ce3d
RS
581
582 result_len += len;
d311d28c
PE
583 if (MOST_POSITIVE_FIXNUM < result_len)
584 memory_full (SIZE_MAX);
7b863bd5
JB
585 }
586
09ab3c3b
KH
587 if (! some_multibyte)
588 result_len_byte = result_len;
7b863bd5 589
ea35ce3d 590 /* Create the output object. */
7b863bd5 591 if (target_type == Lisp_Cons)
ea35ce3d 592 val = Fmake_list (make_number (result_len), Qnil);
3e7383eb 593 else if (target_type == Lisp_Vectorlike)
ea35ce3d 594 val = Fmake_vector (make_number (result_len), Qnil);
b10b2daa 595 else if (some_multibyte)
ea35ce3d 596 val = make_uninit_multibyte_string (result_len, result_len_byte);
b10b2daa
RS
597 else
598 val = make_uninit_string (result_len);
7b863bd5 599
09ab3c3b
KH
600 /* In `append', if all but last arg are nil, return last arg. */
601 if (target_type == Lisp_Cons && EQ (val, Qnil))
602 return last_tail;
7b863bd5 603
ea35ce3d 604 /* Copy the contents of the args into the result. */
7b863bd5 605 if (CONSP (val))
2d6115c8 606 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
7b863bd5 607 else
ea35ce3d 608 toindex = 0, toindex_byte = 0;
7b863bd5
JB
609
610 prev = Qnil;
2d6115c8 611 if (STRINGP (val))
0065d054 612 SAFE_NALLOCA (textprops, 1, nargs);
7b863bd5
JB
613
614 for (argnum = 0; argnum < nargs; argnum++)
615 {
616 Lisp_Object thislen;
d311d28c
PE
617 ptrdiff_t thisleni = 0;
618 register ptrdiff_t thisindex = 0;
619 register ptrdiff_t thisindex_byte = 0;
7b863bd5
JB
620
621 this = args[argnum];
622 if (!CONSP (this))
623 thislen = Flength (this), thisleni = XINT (thislen);
624
ea35ce3d
RS
625 /* Between strings of the same kind, copy fast. */
626 if (STRINGP (this) && STRINGP (val)
627 && STRING_MULTIBYTE (this) == some_multibyte)
7b863bd5 628 {
d311d28c 629 ptrdiff_t thislen_byte = SBYTES (this);
2d6115c8 630
72af86bd 631 memcpy (SDATA (val) + toindex_byte, SDATA (this), SBYTES (this));
d5db4077 632 if (! NULL_INTERVAL_P (STRING_INTERVALS (this)))
2d6115c8 633 {
87f0532f 634 textprops[num_textprops].argnum = argnum;
38583a69 635 textprops[num_textprops].from = 0;
87f0532f 636 textprops[num_textprops++].to = toindex;
2d6115c8 637 }
ea35ce3d 638 toindex_byte += thislen_byte;
38583a69 639 toindex += thisleni;
ea35ce3d 640 }
09ab3c3b
KH
641 /* Copy a single-byte string to a multibyte string. */
642 else if (STRINGP (this) && STRINGP (val))
643 {
d5db4077 644 if (! NULL_INTERVAL_P (STRING_INTERVALS (this)))
2d6115c8 645 {
87f0532f
KH
646 textprops[num_textprops].argnum = argnum;
647 textprops[num_textprops].from = 0;
648 textprops[num_textprops++].to = toindex;
2d6115c8 649 }
d5db4077
KR
650 toindex_byte += copy_text (SDATA (this),
651 SDATA (val) + toindex_byte,
652 SCHARS (this), 0, 1);
09ab3c3b
KH
653 toindex += thisleni;
654 }
ea35ce3d
RS
655 else
656 /* Copy element by element. */
657 while (1)
658 {
659 register Lisp_Object elt;
660
661 /* Fetch next element of `this' arg into `elt', or break if
662 `this' is exhausted. */
663 if (NILP (this)) break;
664 if (CONSP (this))
70949dac 665 elt = XCAR (this), this = XCDR (this);
6a7df83b
RS
666 else if (thisindex >= thisleni)
667 break;
668 else if (STRINGP (this))
ea35ce3d 669 {
2cef5737 670 int c;
6a7df83b 671 if (STRING_MULTIBYTE (this))
c1f134b5
PE
672 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, this,
673 thisindex,
674 thisindex_byte);
6a7df83b 675 else
ea35ce3d 676 {
c1f134b5
PE
677 c = SREF (this, thisindex); thisindex++;
678 if (some_multibyte && !ASCII_CHAR_P (c))
679 c = BYTE8_TO_CHAR (c);
ea35ce3d 680 }
c1f134b5 681 XSETFASTINT (elt, c);
6a7df83b
RS
682 }
683 else if (BOOL_VECTOR_P (this))
684 {
685 int byte;
db85986c
AS
686 byte = XBOOL_VECTOR (this)->data[thisindex / BOOL_VECTOR_BITS_PER_CHAR];
687 if (byte & (1 << (thisindex % BOOL_VECTOR_BITS_PER_CHAR)))
6a7df83b 688 elt = Qt;
ea35ce3d 689 else
6a7df83b
RS
690 elt = Qnil;
691 thisindex++;
ea35ce3d 692 }
6a7df83b 693 else
68b587a6
SM
694 {
695 elt = AREF (this, thisindex);
696 thisindex++;
697 }
7b863bd5 698
ea35ce3d
RS
699 /* Store this element into the result. */
700 if (toindex < 0)
7b863bd5 701 {
f3fbd155 702 XSETCAR (tail, elt);
ea35ce3d 703 prev = tail;
70949dac 704 tail = XCDR (tail);
7b863bd5 705 }
ea35ce3d 706 else if (VECTORP (val))
68b587a6
SM
707 {
708 ASET (val, toindex, elt);
709 toindex++;
710 }
ea35ce3d
RS
711 else
712 {
13bdea59
PE
713 int c;
714 CHECK_CHARACTER (elt);
715 c = XFASTINT (elt);
38583a69 716 if (some_multibyte)
13bdea59 717 toindex_byte += CHAR_STRING (c, SDATA (val) + toindex_byte);
ea35ce3d 718 else
13bdea59 719 SSET (val, toindex_byte++, c);
38583a69 720 toindex++;
ea35ce3d
RS
721 }
722 }
7b863bd5 723 }
265a9e55 724 if (!NILP (prev))
f3fbd155 725 XSETCDR (prev, last_tail);
7b863bd5 726
87f0532f 727 if (num_textprops > 0)
2d6115c8 728 {
33f37824 729 Lisp_Object props;
d311d28c 730 ptrdiff_t last_to_end = -1;
33f37824 731
87f0532f 732 for (argnum = 0; argnum < num_textprops; argnum++)
2d6115c8 733 {
87f0532f 734 this = args[textprops[argnum].argnum];
33f37824
KH
735 props = text_property_list (this,
736 make_number (0),
d5db4077 737 make_number (SCHARS (this)),
33f37824 738 Qnil);
66699ad3 739 /* If successive arguments have properties, be sure that the
33f37824 740 value of `composition' property be the copy. */
3bd00f3b 741 if (last_to_end == textprops[argnum].to)
33f37824
KH
742 make_composition_value_copy (props);
743 add_text_properties_from_list (val, props,
744 make_number (textprops[argnum].to));
d5db4077 745 last_to_end = textprops[argnum].to + SCHARS (this);
2d6115c8
KH
746 }
747 }
2ec7f67a
KS
748
749 SAFE_FREE ();
b4f334f7 750 return val;
7b863bd5
JB
751}
752\f
09ab3c3b 753static Lisp_Object string_char_byte_cache_string;
d311d28c
PE
754static ptrdiff_t string_char_byte_cache_charpos;
755static ptrdiff_t string_char_byte_cache_bytepos;
09ab3c3b 756
57247650 757void
971de7fb 758clear_string_char_byte_cache (void)
57247650
KH
759{
760 string_char_byte_cache_string = Qnil;
761}
762
13818c30 763/* Return the byte index corresponding to CHAR_INDEX in STRING. */
ea35ce3d 764
d311d28c
PE
765ptrdiff_t
766string_char_to_byte (Lisp_Object string, ptrdiff_t char_index)
ea35ce3d 767{
d311d28c
PE
768 ptrdiff_t i_byte;
769 ptrdiff_t best_below, best_below_byte;
770 ptrdiff_t best_above, best_above_byte;
ea35ce3d 771
09ab3c3b 772 best_below = best_below_byte = 0;
d5db4077
KR
773 best_above = SCHARS (string);
774 best_above_byte = SBYTES (string);
95ac7579
KH
775 if (best_above == best_above_byte)
776 return char_index;
09ab3c3b
KH
777
778 if (EQ (string, string_char_byte_cache_string))
779 {
780 if (string_char_byte_cache_charpos < char_index)
781 {
782 best_below = string_char_byte_cache_charpos;
783 best_below_byte = string_char_byte_cache_bytepos;
784 }
785 else
786 {
787 best_above = string_char_byte_cache_charpos;
788 best_above_byte = string_char_byte_cache_bytepos;
789 }
790 }
791
792 if (char_index - best_below < best_above - char_index)
793 {
8f924df7 794 unsigned char *p = SDATA (string) + best_below_byte;
38583a69 795
09ab3c3b
KH
796 while (best_below < char_index)
797 {
38583a69
KH
798 p += BYTES_BY_CHAR_HEAD (*p);
799 best_below++;
09ab3c3b 800 }
8f924df7 801 i_byte = p - SDATA (string);
09ab3c3b
KH
802 }
803 else
ea35ce3d 804 {
8f924df7 805 unsigned char *p = SDATA (string) + best_above_byte;
38583a69 806
09ab3c3b
KH
807 while (best_above > char_index)
808 {
38583a69
KH
809 p--;
810 while (!CHAR_HEAD_P (*p)) p--;
09ab3c3b
KH
811 best_above--;
812 }
8f924df7 813 i_byte = p - SDATA (string);
ea35ce3d
RS
814 }
815
09ab3c3b 816 string_char_byte_cache_bytepos = i_byte;
38583a69 817 string_char_byte_cache_charpos = char_index;
09ab3c3b
KH
818 string_char_byte_cache_string = string;
819
ea35ce3d
RS
820 return i_byte;
821}
09ab3c3b 822\f
ea35ce3d
RS
823/* Return the character index corresponding to BYTE_INDEX in STRING. */
824
d311d28c
PE
825ptrdiff_t
826string_byte_to_char (Lisp_Object string, ptrdiff_t byte_index)
ea35ce3d 827{
d311d28c
PE
828 ptrdiff_t i, i_byte;
829 ptrdiff_t best_below, best_below_byte;
830 ptrdiff_t best_above, best_above_byte;
ea35ce3d 831
09ab3c3b 832 best_below = best_below_byte = 0;
d5db4077
KR
833 best_above = SCHARS (string);
834 best_above_byte = SBYTES (string);
95ac7579
KH
835 if (best_above == best_above_byte)
836 return byte_index;
09ab3c3b
KH
837
838 if (EQ (string, string_char_byte_cache_string))
839 {
840 if (string_char_byte_cache_bytepos < byte_index)
841 {
842 best_below = string_char_byte_cache_charpos;
843 best_below_byte = string_char_byte_cache_bytepos;
844 }
845 else
846 {
847 best_above = string_char_byte_cache_charpos;
848 best_above_byte = string_char_byte_cache_bytepos;
849 }
850 }
851
852 if (byte_index - best_below_byte < best_above_byte - byte_index)
853 {
8f924df7
KH
854 unsigned char *p = SDATA (string) + best_below_byte;
855 unsigned char *pend = SDATA (string) + byte_index;
38583a69
KH
856
857 while (p < pend)
09ab3c3b 858 {
38583a69
KH
859 p += BYTES_BY_CHAR_HEAD (*p);
860 best_below++;
09ab3c3b
KH
861 }
862 i = best_below;
8f924df7 863 i_byte = p - SDATA (string);
09ab3c3b
KH
864 }
865 else
ea35ce3d 866 {
8f924df7
KH
867 unsigned char *p = SDATA (string) + best_above_byte;
868 unsigned char *pbeg = SDATA (string) + byte_index;
38583a69
KH
869
870 while (p > pbeg)
09ab3c3b 871 {
38583a69
KH
872 p--;
873 while (!CHAR_HEAD_P (*p)) p--;
09ab3c3b
KH
874 best_above--;
875 }
876 i = best_above;
8f924df7 877 i_byte = p - SDATA (string);
ea35ce3d
RS
878 }
879
09ab3c3b
KH
880 string_char_byte_cache_bytepos = i_byte;
881 string_char_byte_cache_charpos = i;
882 string_char_byte_cache_string = string;
883
ea35ce3d
RS
884 return i;
885}
09ab3c3b 886\f
9d6d303b 887/* Convert STRING to a multibyte string. */
ea35ce3d 888
2f7c71a1 889static Lisp_Object
971de7fb 890string_make_multibyte (Lisp_Object string)
ea35ce3d
RS
891{
892 unsigned char *buf;
d311d28c 893 ptrdiff_t nbytes;
e76ca790
MB
894 Lisp_Object ret;
895 USE_SAFE_ALLOCA;
ea35ce3d
RS
896
897 if (STRING_MULTIBYTE (string))
898 return string;
899
d5db4077
KR
900 nbytes = count_size_as_multibyte (SDATA (string),
901 SCHARS (string));
6d475204
RS
902 /* If all the chars are ASCII, they won't need any more bytes
903 once converted. In that case, we can return STRING itself. */
d5db4077 904 if (nbytes == SBYTES (string))
6d475204
RS
905 return string;
906
799c08ac 907 SAFE_ALLOCA (buf, unsigned char *, nbytes);
d5db4077 908 copy_text (SDATA (string), buf, SBYTES (string),
ea35ce3d
RS
909 0, 1);
910
f1e59824 911 ret = make_multibyte_string ((char *) buf, SCHARS (string), nbytes);
233f3db6 912 SAFE_FREE ();
799c08ac
KS
913
914 return ret;
ea35ce3d
RS
915}
916
2df18cdb 917
8f924df7
KH
918/* Convert STRING (if unibyte) to a multibyte string without changing
919 the number of characters. Characters 0200 trough 0237 are
920 converted to eight-bit characters. */
2df18cdb
KH
921
922Lisp_Object
971de7fb 923string_to_multibyte (Lisp_Object string)
2df18cdb
KH
924{
925 unsigned char *buf;
d311d28c 926 ptrdiff_t nbytes;
799c08ac
KS
927 Lisp_Object ret;
928 USE_SAFE_ALLOCA;
2df18cdb
KH
929
930 if (STRING_MULTIBYTE (string))
931 return string;
932
de883a70 933 nbytes = count_size_as_multibyte (SDATA (string), SBYTES (string));
8f924df7
KH
934 /* If all the chars are ASCII, they won't need any more bytes once
935 converted. */
2df18cdb 936 if (nbytes == SBYTES (string))
42a5b22f 937 return make_multibyte_string (SSDATA (string), nbytes, nbytes);
2df18cdb 938
799c08ac 939 SAFE_ALLOCA (buf, unsigned char *, nbytes);
72af86bd 940 memcpy (buf, SDATA (string), SBYTES (string));
2df18cdb
KH
941 str_to_multibyte (buf, nbytes, SBYTES (string));
942
f1e59824 943 ret = make_multibyte_string ((char *) buf, SCHARS (string), nbytes);
233f3db6 944 SAFE_FREE ();
799c08ac
KS
945
946 return ret;
2df18cdb
KH
947}
948
949
ea35ce3d
RS
950/* Convert STRING to a single-byte string. */
951
952Lisp_Object
971de7fb 953string_make_unibyte (Lisp_Object string)
ea35ce3d 954{
d311d28c 955 ptrdiff_t nchars;
ea35ce3d 956 unsigned char *buf;
a6cb6b78 957 Lisp_Object ret;
799c08ac 958 USE_SAFE_ALLOCA;
ea35ce3d
RS
959
960 if (! STRING_MULTIBYTE (string))
961 return string;
962
799c08ac 963 nchars = SCHARS (string);
ea35ce3d 964
799c08ac 965 SAFE_ALLOCA (buf, unsigned char *, nchars);
d5db4077 966 copy_text (SDATA (string), buf, SBYTES (string),
ea35ce3d
RS
967 1, 0);
968
f1e59824 969 ret = make_unibyte_string ((char *) buf, nchars);
233f3db6 970 SAFE_FREE ();
a6cb6b78
JD
971
972 return ret;
ea35ce3d 973}
09ab3c3b 974
a7ca3326 975DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
09ab3c3b 976 1, 1, 0,
e9d8ddc9 977 doc: /* Return the multibyte equivalent of STRING.
6b61353c
KH
978If STRING is unibyte and contains non-ASCII characters, the function
979`unibyte-char-to-multibyte' is used to convert each unibyte character
980to a multibyte character. In this case, the returned string is a
981newly created string with no text properties. If STRING is multibyte
982or entirely ASCII, it is returned unchanged. In particular, when
983STRING is unibyte and entirely ASCII, the returned string is unibyte.
984\(When the characters are all ASCII, Emacs primitives will treat the
985string the same way whether it is unibyte or multibyte.) */)
5842a27b 986 (Lisp_Object string)
09ab3c3b 987{
b7826503 988 CHECK_STRING (string);
aabd38ec 989
09ab3c3b
KH
990 return string_make_multibyte (string);
991}
992
a7ca3326 993DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
09ab3c3b 994 1, 1, 0,
e9d8ddc9 995 doc: /* Return the unibyte equivalent of STRING.
f8f2fbf9
EZ
996Multibyte character codes are converted to unibyte according to
997`nonascii-translation-table' or, if that is nil, `nonascii-insert-offset'.
998If the lookup in the translation table fails, this function takes just
adf2c803 999the low 8 bits of each character. */)
5842a27b 1000 (Lisp_Object string)
09ab3c3b 1001{
b7826503 1002 CHECK_STRING (string);
aabd38ec 1003
09ab3c3b
KH
1004 return string_make_unibyte (string);
1005}
6d475204 1006
a7ca3326 1007DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte,
6d475204 1008 1, 1, 0,
e9d8ddc9 1009 doc: /* Return a unibyte string with the same individual bytes as STRING.
47cebab1
GM
1010If STRING is unibyte, the result is STRING itself.
1011Otherwise it is a newly created string, with no text properties.
1012If STRING is multibyte and contains a character of charset
6b61353c 1013`eight-bit', it is converted to the corresponding single byte. */)
5842a27b 1014 (Lisp_Object string)
6d475204 1015{
b7826503 1016 CHECK_STRING (string);
aabd38ec 1017
6d475204
RS
1018 if (STRING_MULTIBYTE (string))
1019 {
d311d28c 1020 ptrdiff_t bytes = SBYTES (string);
2efdd1b9
KH
1021 unsigned char *str = (unsigned char *) xmalloc (bytes);
1022
72af86bd 1023 memcpy (str, SDATA (string), bytes);
2efdd1b9 1024 bytes = str_as_unibyte (str, bytes);
f1e59824 1025 string = make_unibyte_string ((char *) str, bytes);
2efdd1b9 1026 xfree (str);
6d475204
RS
1027 }
1028 return string;
1029}
1030
a7ca3326 1031DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte,
6d475204 1032 1, 1, 0,
e9d8ddc9 1033 doc: /* Return a multibyte string with the same individual bytes as STRING.
47cebab1
GM
1034If STRING is multibyte, the result is STRING itself.
1035Otherwise it is a newly created string, with no text properties.
2d5cc537 1036
47cebab1 1037If STRING is unibyte and contains an individual 8-bit byte (i.e. not
2d5cc537
DL
1038part of a correct utf-8 sequence), it is converted to the corresponding
1039multibyte character of charset `eight-bit'.
3100d59f
KH
1040See also `string-to-multibyte'.
1041
1042Beware, this often doesn't really do what you think it does.
1043It is similar to (decode-coding-string STRING 'utf-8-emacs).
1044If you're not sure, whether to use `string-as-multibyte' or
1045`string-to-multibyte', use `string-to-multibyte'. */)
5842a27b 1046 (Lisp_Object string)
6d475204 1047{
b7826503 1048 CHECK_STRING (string);
aabd38ec 1049
6d475204
RS
1050 if (! STRING_MULTIBYTE (string))
1051 {
2efdd1b9 1052 Lisp_Object new_string;
d311d28c 1053 ptrdiff_t nchars, nbytes;
2efdd1b9 1054
d5db4077
KR
1055 parse_str_as_multibyte (SDATA (string),
1056 SBYTES (string),
2efdd1b9
KH
1057 &nchars, &nbytes);
1058 new_string = make_uninit_multibyte_string (nchars, nbytes);
72af86bd 1059 memcpy (SDATA (new_string), SDATA (string), SBYTES (string));
d5db4077
KR
1060 if (nbytes != SBYTES (string))
1061 str_as_multibyte (SDATA (new_string), nbytes,
1062 SBYTES (string), NULL);
2efdd1b9 1063 string = new_string;
7a2e5600 1064 STRING_SET_INTERVALS (string, NULL_INTERVAL);
6d475204
RS
1065 }
1066 return string;
1067}
2df18cdb 1068
a7ca3326 1069DEFUN ("string-to-multibyte", Fstring_to_multibyte, Sstring_to_multibyte,
2df18cdb
KH
1070 1, 1, 0,
1071 doc: /* Return a multibyte string with the same individual chars as STRING.
9c7a329a 1072If STRING is multibyte, the result is STRING itself.
2df18cdb 1073Otherwise it is a newly created string, with no text properties.
88dad6e7
KH
1074
1075If STRING is unibyte and contains an 8-bit byte, it is converted to
2d5cc537
DL
1076the corresponding multibyte character of charset `eight-bit'.
1077
1078This differs from `string-as-multibyte' by converting each byte of a correct
1079utf-8 sequence to an eight-bit character, not just bytes that don't form a
1080correct sequence. */)
5842a27b 1081 (Lisp_Object string)
2df18cdb
KH
1082{
1083 CHECK_STRING (string);
1084
1085 return string_to_multibyte (string);
1086}
1087
b4480f16 1088DEFUN ("string-to-unibyte", Fstring_to_unibyte, Sstring_to_unibyte,
6e8b42de 1089 1, 1, 0,
b4480f16
KH
1090 doc: /* Return a unibyte string with the same individual chars as STRING.
1091If STRING is unibyte, the result is STRING itself.
1092Otherwise it is a newly created string, with no text properties,
1093where each `eight-bit' character is converted to the corresponding byte.
1094If STRING contains a non-ASCII, non-`eight-bit' character,
6e8b42de 1095an error is signaled. */)
5842a27b 1096 (Lisp_Object string)
b4480f16
KH
1097{
1098 CHECK_STRING (string);
1099
1100 if (STRING_MULTIBYTE (string))
1101 {
d311d28c 1102 ptrdiff_t chars = SCHARS (string);
b4480f16 1103 unsigned char *str = (unsigned char *) xmalloc (chars);
d311d28c 1104 ptrdiff_t converted = str_to_unibyte (SDATA (string), str, chars, 0);
6e8b42de 1105
b4480f16 1106 if (converted < chars)
7c85f529 1107 error ("Can't convert the %"pD"dth character to unibyte", converted);
f1e59824 1108 string = make_unibyte_string ((char *) str, chars);
b4480f16
KH
1109 xfree (str);
1110 }
1111 return string;
1112}
1113
ea35ce3d 1114\f
a7ca3326 1115DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
e9d8ddc9 1116 doc: /* Return a copy of ALIST.
47cebab1
GM
1117This is an alist which represents the same mapping from objects to objects,
1118but does not share the alist structure with ALIST.
1119The objects mapped (cars and cdrs of elements of the alist)
1120are shared, however.
e9d8ddc9 1121Elements of ALIST that are not conses are also shared. */)
5842a27b 1122 (Lisp_Object alist)
7b863bd5
JB
1123{
1124 register Lisp_Object tem;
1125
b7826503 1126 CHECK_LIST (alist);
265a9e55 1127 if (NILP (alist))
7b863bd5
JB
1128 return alist;
1129 alist = concat (1, &alist, Lisp_Cons, 0);
70949dac 1130 for (tem = alist; CONSP (tem); tem = XCDR (tem))
7b863bd5
JB
1131 {
1132 register Lisp_Object car;
70949dac 1133 car = XCAR (tem);
7b863bd5
JB
1134
1135 if (CONSP (car))
f3fbd155 1136 XSETCAR (tem, Fcons (XCAR (car), XCDR (car)));
7b863bd5
JB
1137 }
1138 return alist;
1139}
1140
a7ca3326 1141DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
753169bd
CY
1142 doc: /* Return a new string whose contents are a substring of STRING.
1143The returned string consists of the characters between index FROM
1144\(inclusive) and index TO (exclusive) of STRING. FROM and TO are
1145zero-indexed: 0 means the first character of STRING. Negative values
1146are counted from the end of STRING. If TO is nil, the substring runs
1147to the end of STRING.
1148
1149The STRING argument may also be a vector. In that case, the return
1150value is a new vector that contains the elements between index FROM
1151\(inclusive) and index TO (exclusive) of that vector argument. */)
5842a27b 1152 (Lisp_Object string, register Lisp_Object from, Lisp_Object to)
7b863bd5 1153{
ac811a55 1154 Lisp_Object res;
d311d28c 1155 ptrdiff_t size;
e6d4aefa 1156 EMACS_INT from_char, to_char;
21fbc8e5 1157
89662fc3 1158 CHECK_VECTOR_OR_STRING (string);
b7826503 1159 CHECK_NUMBER (from);
21fbc8e5
RS
1160
1161 if (STRINGP (string))
d311d28c 1162 size = SCHARS (string);
21fbc8e5 1163 else
7edbb0da 1164 size = ASIZE (string);
21fbc8e5 1165
265a9e55 1166 if (NILP (to))
d311d28c 1167 to_char = size;
7b863bd5 1168 else
ea35ce3d 1169 {
b7826503 1170 CHECK_NUMBER (to);
ea35ce3d
RS
1171
1172 to_char = XINT (to);
1173 if (to_char < 0)
1174 to_char += size;
ea35ce3d
RS
1175 }
1176
1177 from_char = XINT (from);
1178 if (from_char < 0)
1179 from_char += size;
ea35ce3d
RS
1180 if (!(0 <= from_char && from_char <= to_char && to_char <= size))
1181 args_out_of_range_3 (string, make_number (from_char),
1182 make_number (to_char));
8c172e82 1183
21fbc8e5
RS
1184 if (STRINGP (string))
1185 {
d311d28c
PE
1186 ptrdiff_t to_byte =
1187 (NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char));
1188 ptrdiff_t from_byte = string_char_to_byte (string, from_char);
42a5b22f 1189 res = make_specified_string (SSDATA (string) + from_byte,
b10b2daa
RS
1190 to_char - from_char, to_byte - from_byte,
1191 STRING_MULTIBYTE (string));
21ab867f
AS
1192 copy_text_properties (make_number (from_char), make_number (to_char),
1193 string, make_number (0), res, Qnil);
ea35ce3d
RS
1194 }
1195 else
7edbb0da 1196 res = Fvector (to_char - from_char, &AREF (string, from_char));
ea35ce3d
RS
1197
1198 return res;
1199}
1200
aebf4d42
RS
1201
1202DEFUN ("substring-no-properties", Fsubstring_no_properties, Ssubstring_no_properties, 1, 3, 0,
1203 doc: /* Return a substring of STRING, without text properties.
b756c005 1204It starts at index FROM and ends before TO.
aebf4d42
RS
1205TO may be nil or omitted; then the substring runs to the end of STRING.
1206If FROM is nil or omitted, the substring starts at the beginning of STRING.
1207If FROM or TO is negative, it counts from the end.
1208
1209With one argument, just copy STRING without its properties. */)
5842a27b 1210 (Lisp_Object string, register Lisp_Object from, Lisp_Object to)
aebf4d42 1211{
d311d28c 1212 ptrdiff_t size;
e6d4aefa 1213 EMACS_INT from_char, to_char;
d311d28c 1214 ptrdiff_t from_byte, to_byte;
aebf4d42
RS
1215
1216 CHECK_STRING (string);
1217
d5db4077 1218 size = SCHARS (string);
aebf4d42
RS
1219
1220 if (NILP (from))
d311d28c 1221 from_char = 0;
aebf4d42
RS
1222 else
1223 {
1224 CHECK_NUMBER (from);
1225 from_char = XINT (from);
1226 if (from_char < 0)
1227 from_char += size;
aebf4d42
RS
1228 }
1229
1230 if (NILP (to))
d311d28c 1231 to_char = size;
aebf4d42
RS
1232 else
1233 {
1234 CHECK_NUMBER (to);
aebf4d42
RS
1235 to_char = XINT (to);
1236 if (to_char < 0)
1237 to_char += size;
aebf4d42
RS
1238 }
1239
1240 if (!(0 <= from_char && from_char <= to_char && to_char <= size))
1241 args_out_of_range_3 (string, make_number (from_char),
1242 make_number (to_char));
1243
d311d28c
PE
1244 from_byte = NILP (from) ? 0 : string_char_to_byte (string, from_char);
1245 to_byte =
1246 NILP (to) ? SBYTES (string) : string_char_to_byte (string, to_char);
42a5b22f 1247 return make_specified_string (SSDATA (string) + from_byte,
aebf4d42
RS
1248 to_char - from_char, to_byte - from_byte,
1249 STRING_MULTIBYTE (string));
1250}
1251
ea35ce3d
RS
1252/* Extract a substring of STRING, giving start and end positions
1253 both in characters and in bytes. */
1254
1255Lisp_Object
d311d28c
PE
1256substring_both (Lisp_Object string, ptrdiff_t from, ptrdiff_t from_byte,
1257 ptrdiff_t to, ptrdiff_t to_byte)
ea35ce3d
RS
1258{
1259 Lisp_Object res;
d311d28c 1260 ptrdiff_t size;
ea35ce3d 1261
89662fc3 1262 CHECK_VECTOR_OR_STRING (string);
ea35ce3d 1263
0bc0b309 1264 size = STRINGP (string) ? SCHARS (string) : ASIZE (string);
ea35ce3d
RS
1265
1266 if (!(0 <= from && from <= to && to <= size))
1267 args_out_of_range_3 (string, make_number (from), make_number (to));
1268
1269 if (STRINGP (string))
1270 {
42a5b22f 1271 res = make_specified_string (SSDATA (string) + from_byte,
b10b2daa
RS
1272 to - from, to_byte - from_byte,
1273 STRING_MULTIBYTE (string));
21ab867f
AS
1274 copy_text_properties (make_number (from), make_number (to),
1275 string, make_number (0), res, Qnil);
21fbc8e5
RS
1276 }
1277 else
5ee699a7 1278 res = Fvector (to - from, &AREF (string, from));
b4f334f7 1279
ac811a55 1280 return res;
7b863bd5
JB
1281}
1282\f
a7ca3326 1283DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
b756c005 1284 doc: /* Take cdr N times on LIST, return the result. */)
5842a27b 1285 (Lisp_Object n, Lisp_Object list)
7b863bd5 1286{
6346d301 1287 EMACS_INT i, num;
b7826503 1288 CHECK_NUMBER (n);
7b863bd5 1289 num = XINT (n);
265a9e55 1290 for (i = 0; i < num && !NILP (list); i++)
7b863bd5
JB
1291 {
1292 QUIT;
89662fc3 1293 CHECK_LIST_CONS (list, list);
71a8e74b 1294 list = XCDR (list);
7b863bd5
JB
1295 }
1296 return list;
1297}
1298
a7ca3326 1299DEFUN ("nth", Fnth, Snth, 2, 2, 0,
e9d8ddc9
MB
1300 doc: /* Return the Nth element of LIST.
1301N counts from zero. If LIST is not that long, nil is returned. */)
5842a27b 1302 (Lisp_Object n, Lisp_Object list)
7b863bd5
JB
1303{
1304 return Fcar (Fnthcdr (n, list));
1305}
1306
a7ca3326 1307DEFUN ("elt", Felt, Selt, 2, 2, 0,
e9d8ddc9 1308 doc: /* Return element of SEQUENCE at index N. */)
5842a27b 1309 (register Lisp_Object sequence, Lisp_Object n)
7b863bd5 1310{
b7826503 1311 CHECK_NUMBER (n);
89662fc3
KS
1312 if (CONSP (sequence) || NILP (sequence))
1313 return Fcar (Fnthcdr (n, sequence));
1314
1315 /* Faref signals a "not array" error, so check here. */
876c194c 1316 CHECK_ARRAY (sequence, Qsequencep);
89662fc3 1317 return Faref (sequence, n);
7b863bd5
JB
1318}
1319
a7ca3326 1320DEFUN ("member", Fmember, Smember, 2, 2, 0,
b756c005 1321 doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `equal'.
e9d8ddc9 1322The value is actually the tail of LIST whose car is ELT. */)
5842a27b 1323 (register Lisp_Object elt, Lisp_Object list)
7b863bd5
JB
1324{
1325 register Lisp_Object tail;
9beb8baa 1326 for (tail = list; CONSP (tail); tail = XCDR (tail))
7b863bd5
JB
1327 {
1328 register Lisp_Object tem;
89662fc3 1329 CHECK_LIST_CONS (tail, list);
71a8e74b 1330 tem = XCAR (tail);
265a9e55 1331 if (! NILP (Fequal (elt, tem)))
7b863bd5
JB
1332 return tail;
1333 QUIT;
1334 }
1335 return Qnil;
1336}
1337
a7ca3326 1338DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
b756c005 1339 doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eq'.
008ef0ef 1340The value is actually the tail of LIST whose car is ELT. */)
5842a27b 1341 (register Lisp_Object elt, Lisp_Object list)
7b863bd5 1342{
f2be3671 1343 while (1)
7b863bd5 1344 {
f2be3671
GM
1345 if (!CONSP (list) || EQ (XCAR (list), elt))
1346 break;
59f953a2 1347
f2be3671
GM
1348 list = XCDR (list);
1349 if (!CONSP (list) || EQ (XCAR (list), elt))
1350 break;
1351
1352 list = XCDR (list);
1353 if (!CONSP (list) || EQ (XCAR (list), elt))
1354 break;
1355
1356 list = XCDR (list);
7b863bd5
JB
1357 QUIT;
1358 }
f2be3671 1359
89662fc3 1360 CHECK_LIST (list);
f2be3671 1361 return list;
7b863bd5
JB
1362}
1363
008ef0ef 1364DEFUN ("memql", Fmemql, Smemql, 2, 2, 0,
b756c005 1365 doc: /* Return non-nil if ELT is an element of LIST. Comparison done with `eql'.
008ef0ef 1366The value is actually the tail of LIST whose car is ELT. */)
5842a27b 1367 (register Lisp_Object elt, Lisp_Object list)
008ef0ef
KS
1368{
1369 register Lisp_Object tail;
1370
1371 if (!FLOATP (elt))
1372 return Fmemq (elt, list);
1373
9beb8baa 1374 for (tail = list; CONSP (tail); tail = XCDR (tail))
008ef0ef
KS
1375 {
1376 register Lisp_Object tem;
1377 CHECK_LIST_CONS (tail, list);
1378 tem = XCAR (tail);
1379 if (FLOATP (tem) && internal_equal (elt, tem, 0, 0))
1380 return tail;
1381 QUIT;
1382 }
1383 return Qnil;
1384}
1385
a7ca3326 1386DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
e9d8ddc9 1387 doc: /* Return non-nil if KEY is `eq' to the car of an element of LIST.
6b61353c 1388The value is actually the first element of LIST whose car is KEY.
e9d8ddc9 1389Elements of LIST that are not conses are ignored. */)
5842a27b 1390 (Lisp_Object key, Lisp_Object list)
7b863bd5 1391{
f2be3671 1392 while (1)
7b863bd5 1393 {
f2be3671
GM
1394 if (!CONSP (list)
1395 || (CONSP (XCAR (list))
1396 && EQ (XCAR (XCAR (list)), key)))
1397 break;
59f953a2 1398
f2be3671
GM
1399 list = XCDR (list);
1400 if (!CONSP (list)
1401 || (CONSP (XCAR (list))
1402 && EQ (XCAR (XCAR (list)), key)))
1403 break;
59f953a2 1404
f2be3671
GM
1405 list = XCDR (list);
1406 if (!CONSP (list)
1407 || (CONSP (XCAR (list))
1408 && EQ (XCAR (XCAR (list)), key)))
1409 break;
59f953a2 1410
f2be3671 1411 list = XCDR (list);
7b863bd5
JB
1412 QUIT;
1413 }
f2be3671 1414
89662fc3 1415 return CAR (list);
7b863bd5
JB
1416}
1417
1418/* Like Fassq but never report an error and do not allow quits.
1419 Use only on lists known never to be circular. */
1420
1421Lisp_Object
971de7fb 1422assq_no_quit (Lisp_Object key, Lisp_Object list)
7b863bd5 1423{
f2be3671
GM
1424 while (CONSP (list)
1425 && (!CONSP (XCAR (list))
1426 || !EQ (XCAR (XCAR (list)), key)))
1427 list = XCDR (list);
1428
89662fc3 1429 return CAR_SAFE (list);
7b863bd5
JB
1430}
1431
a7ca3326 1432DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
e9d8ddc9 1433 doc: /* Return non-nil if KEY is `equal' to the car of an element of LIST.
6b61353c 1434The value is actually the first element of LIST whose car equals KEY. */)
5842a27b 1435 (Lisp_Object key, Lisp_Object list)
7b863bd5 1436{
89662fc3 1437 Lisp_Object car;
f2be3671
GM
1438
1439 while (1)
7b863bd5 1440 {
f2be3671
GM
1441 if (!CONSP (list)
1442 || (CONSP (XCAR (list))
1443 && (car = XCAR (XCAR (list)),
1444 EQ (car, key) || !NILP (Fequal (car, key)))))
1445 break;
59f953a2 1446
f2be3671
GM
1447 list = XCDR (list);
1448 if (!CONSP (list)
1449 || (CONSP (XCAR (list))
1450 && (car = XCAR (XCAR (list)),
1451 EQ (car, key) || !NILP (Fequal (car, key)))))
1452 break;
59f953a2 1453
f2be3671
GM
1454 list = XCDR (list);
1455 if (!CONSP (list)
1456 || (CONSP (XCAR (list))
1457 && (car = XCAR (XCAR (list)),
1458 EQ (car, key) || !NILP (Fequal (car, key)))))
1459 break;
59f953a2 1460
f2be3671 1461 list = XCDR (list);
7b863bd5
JB
1462 QUIT;
1463 }
f2be3671 1464
89662fc3 1465 return CAR (list);
7b863bd5
JB
1466}
1467
86840809
KH
1468/* Like Fassoc but never report an error and do not allow quits.
1469 Use only on lists known never to be circular. */
1470
1471Lisp_Object
971de7fb 1472assoc_no_quit (Lisp_Object key, Lisp_Object list)
86840809
KH
1473{
1474 while (CONSP (list)
1475 && (!CONSP (XCAR (list))
1476 || (!EQ (XCAR (XCAR (list)), key)
1477 && NILP (Fequal (XCAR (XCAR (list)), key)))))
1478 list = XCDR (list);
1479
1480 return CONSP (list) ? XCAR (list) : Qnil;
1481}
1482
a7ca3326 1483DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
e9d8ddc9 1484 doc: /* Return non-nil if KEY is `eq' to the cdr of an element of LIST.
6b61353c 1485The value is actually the first element of LIST whose cdr is KEY. */)
5842a27b 1486 (register Lisp_Object key, Lisp_Object list)
7b863bd5 1487{
f2be3671 1488 while (1)
7b863bd5 1489 {
f2be3671
GM
1490 if (!CONSP (list)
1491 || (CONSP (XCAR (list))
1492 && EQ (XCDR (XCAR (list)), key)))
1493 break;
59f953a2 1494
f2be3671
GM
1495 list = XCDR (list);
1496 if (!CONSP (list)
1497 || (CONSP (XCAR (list))
1498 && EQ (XCDR (XCAR (list)), key)))
1499 break;
59f953a2 1500
f2be3671
GM
1501 list = XCDR (list);
1502 if (!CONSP (list)
1503 || (CONSP (XCAR (list))
1504 && EQ (XCDR (XCAR (list)), key)))
1505 break;
59f953a2 1506
f2be3671 1507 list = XCDR (list);
7b863bd5
JB
1508 QUIT;
1509 }
f2be3671 1510
89662fc3 1511 return CAR (list);
7b863bd5 1512}
0fb5a19c 1513
a7ca3326 1514DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
e9d8ddc9 1515 doc: /* Return non-nil if KEY is `equal' to the cdr of an element of LIST.
6b61353c 1516The value is actually the first element of LIST whose cdr equals KEY. */)
5842a27b 1517 (Lisp_Object key, Lisp_Object list)
0fb5a19c 1518{
89662fc3 1519 Lisp_Object cdr;
f2be3671
GM
1520
1521 while (1)
0fb5a19c 1522 {
f2be3671
GM
1523 if (!CONSP (list)
1524 || (CONSP (XCAR (list))
1525 && (cdr = XCDR (XCAR (list)),
1526 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1527 break;
59f953a2 1528
f2be3671
GM
1529 list = XCDR (list);
1530 if (!CONSP (list)
1531 || (CONSP (XCAR (list))
1532 && (cdr = XCDR (XCAR (list)),
1533 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1534 break;
59f953a2 1535
f2be3671
GM
1536 list = XCDR (list);
1537 if (!CONSP (list)
1538 || (CONSP (XCAR (list))
1539 && (cdr = XCDR (XCAR (list)),
1540 EQ (cdr, key) || !NILP (Fequal (cdr, key)))))
1541 break;
59f953a2 1542
f2be3671 1543 list = XCDR (list);
0fb5a19c
RS
1544 QUIT;
1545 }
f2be3671 1546
89662fc3 1547 return CAR (list);
0fb5a19c 1548}
7b863bd5 1549\f
a7ca3326 1550DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
e9d8ddc9 1551 doc: /* Delete by side effect any occurrences of ELT as a member of LIST.
47cebab1
GM
1552The modified LIST is returned. Comparison is done with `eq'.
1553If the first member of LIST is ELT, there is no way to remove it by side effect;
1554therefore, write `(setq foo (delq element foo))'
e9d8ddc9 1555to be sure of changing the value of `foo'. */)
5842a27b 1556 (register Lisp_Object elt, Lisp_Object list)
7b863bd5
JB
1557{
1558 register Lisp_Object tail, prev;
1559 register Lisp_Object tem;
1560
1561 tail = list;
1562 prev = Qnil;
265a9e55 1563 while (!NILP (tail))
7b863bd5 1564 {
89662fc3 1565 CHECK_LIST_CONS (tail, list);
71a8e74b 1566 tem = XCAR (tail);
7b863bd5
JB
1567 if (EQ (elt, tem))
1568 {
265a9e55 1569 if (NILP (prev))
70949dac 1570 list = XCDR (tail);
7b863bd5 1571 else
70949dac 1572 Fsetcdr (prev, XCDR (tail));
7b863bd5
JB
1573 }
1574 else
1575 prev = tail;
70949dac 1576 tail = XCDR (tail);
7b863bd5
JB
1577 QUIT;
1578 }
1579 return list;
1580}
1581
a7ca3326 1582DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
e9d8ddc9 1583 doc: /* Delete by side effect any occurrences of ELT as a member of SEQ.
47cebab1
GM
1584SEQ must be a list, a vector, or a string.
1585The modified SEQ is returned. Comparison is done with `equal'.
1586If SEQ is not a list, or the first member of SEQ is ELT, deleting it
1587is not a side effect; it is simply using a different sequence.
1588Therefore, write `(setq foo (delete element foo))'
e9d8ddc9 1589to be sure of changing the value of `foo'. */)
5842a27b 1590 (Lisp_Object elt, Lisp_Object seq)
1e134a5f 1591{
e517f19d
GM
1592 if (VECTORP (seq))
1593 {
d311d28c 1594 ptrdiff_t i, n;
1e134a5f 1595
e517f19d
GM
1596 for (i = n = 0; i < ASIZE (seq); ++i)
1597 if (NILP (Fequal (AREF (seq, i), elt)))
1598 ++n;
1599
1600 if (n != ASIZE (seq))
1601 {
b3660ef6 1602 struct Lisp_Vector *p = allocate_vector (n);
59f953a2 1603
e517f19d
GM
1604 for (i = n = 0; i < ASIZE (seq); ++i)
1605 if (NILP (Fequal (AREF (seq, i), elt)))
1606 p->contents[n++] = AREF (seq, i);
1607
e517f19d
GM
1608 XSETVECTOR (seq, p);
1609 }
1610 }
1611 else if (STRINGP (seq))
1e134a5f 1612 {
d311d28c 1613 ptrdiff_t i, ibyte, nchars, nbytes, cbytes;
e517f19d
GM
1614 int c;
1615
1616 for (i = nchars = nbytes = ibyte = 0;
d5db4077 1617 i < SCHARS (seq);
e517f19d 1618 ++i, ibyte += cbytes)
1e134a5f 1619 {
e517f19d
GM
1620 if (STRING_MULTIBYTE (seq))
1621 {
62a6e103 1622 c = STRING_CHAR (SDATA (seq) + ibyte);
e517f19d
GM
1623 cbytes = CHAR_BYTES (c);
1624 }
1e134a5f 1625 else
e517f19d 1626 {
d5db4077 1627 c = SREF (seq, i);
e517f19d
GM
1628 cbytes = 1;
1629 }
59f953a2 1630
e517f19d
GM
1631 if (!INTEGERP (elt) || c != XINT (elt))
1632 {
1633 ++nchars;
1634 nbytes += cbytes;
1635 }
1636 }
1637
d5db4077 1638 if (nchars != SCHARS (seq))
e517f19d
GM
1639 {
1640 Lisp_Object tem;
1641
1642 tem = make_uninit_multibyte_string (nchars, nbytes);
1643 if (!STRING_MULTIBYTE (seq))
d5db4077 1644 STRING_SET_UNIBYTE (tem);
59f953a2 1645
e517f19d 1646 for (i = nchars = nbytes = ibyte = 0;
d5db4077 1647 i < SCHARS (seq);
e517f19d
GM
1648 ++i, ibyte += cbytes)
1649 {
1650 if (STRING_MULTIBYTE (seq))
1651 {
62a6e103 1652 c = STRING_CHAR (SDATA (seq) + ibyte);
e517f19d
GM
1653 cbytes = CHAR_BYTES (c);
1654 }
1655 else
1656 {
d5db4077 1657 c = SREF (seq, i);
e517f19d
GM
1658 cbytes = 1;
1659 }
59f953a2 1660
e517f19d
GM
1661 if (!INTEGERP (elt) || c != XINT (elt))
1662 {
08663750
KR
1663 unsigned char *from = SDATA (seq) + ibyte;
1664 unsigned char *to = SDATA (tem) + nbytes;
d311d28c 1665 ptrdiff_t n;
59f953a2 1666
e517f19d
GM
1667 ++nchars;
1668 nbytes += cbytes;
59f953a2 1669
e517f19d
GM
1670 for (n = cbytes; n--; )
1671 *to++ = *from++;
1672 }
1673 }
1674
1675 seq = tem;
1e134a5f 1676 }
1e134a5f 1677 }
e517f19d
GM
1678 else
1679 {
1680 Lisp_Object tail, prev;
1681
9beb8baa 1682 for (tail = seq, prev = Qnil; CONSP (tail); tail = XCDR (tail))
e517f19d 1683 {
89662fc3 1684 CHECK_LIST_CONS (tail, seq);
59f953a2 1685
e517f19d
GM
1686 if (!NILP (Fequal (elt, XCAR (tail))))
1687 {
1688 if (NILP (prev))
1689 seq = XCDR (tail);
1690 else
1691 Fsetcdr (prev, XCDR (tail));
1692 }
1693 else
1694 prev = tail;
1695 QUIT;
1696 }
1697 }
59f953a2 1698
e517f19d 1699 return seq;
1e134a5f
RM
1700}
1701
a7ca3326 1702DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
e9d8ddc9 1703 doc: /* Reverse LIST by modifying cdr pointers.
6b61353c 1704Return the reversed list. */)
5842a27b 1705 (Lisp_Object list)
7b863bd5
JB
1706{
1707 register Lisp_Object prev, tail, next;
1708
265a9e55 1709 if (NILP (list)) return list;
7b863bd5
JB
1710 prev = Qnil;
1711 tail = list;
265a9e55 1712 while (!NILP (tail))
7b863bd5
JB
1713 {
1714 QUIT;
89662fc3 1715 CHECK_LIST_CONS (tail, list);
71a8e74b 1716 next = XCDR (tail);
7b863bd5
JB
1717 Fsetcdr (tail, prev);
1718 prev = tail;
1719 tail = next;
1720 }
1721 return prev;
1722}
1723
a7ca3326 1724DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
6b61353c 1725 doc: /* Reverse LIST, copying. Return the reversed list.
e9d8ddc9 1726See also the function `nreverse', which is used more often. */)
5842a27b 1727 (Lisp_Object list)
7b863bd5 1728{
9d14ae76 1729 Lisp_Object new;
7b863bd5 1730
70949dac 1731 for (new = Qnil; CONSP (list); list = XCDR (list))
5c3ea973
DL
1732 {
1733 QUIT;
1734 new = Fcons (XCAR (list), new);
1735 }
89662fc3 1736 CHECK_LIST_END (list, list);
9d14ae76 1737 return new;
7b863bd5
JB
1738}
1739\f
971de7fb 1740Lisp_Object merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred);
7b863bd5 1741
a7ca3326 1742DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
e9d8ddc9 1743 doc: /* Sort LIST, stably, comparing elements using PREDICATE.
47cebab1 1744Returns the sorted list. LIST is modified by side effects.
5c796e80 1745PREDICATE is called with two elements of LIST, and should return non-nil
71f6424d 1746if the first element should sort before the second. */)
5842a27b 1747 (Lisp_Object list, Lisp_Object predicate)
7b863bd5
JB
1748{
1749 Lisp_Object front, back;
1750 register Lisp_Object len, tem;
1751 struct gcpro gcpro1, gcpro2;
6346d301 1752 EMACS_INT length;
7b863bd5
JB
1753
1754 front = list;
1755 len = Flength (list);
1756 length = XINT (len);
1757 if (length < 2)
1758 return list;
1759
1760 XSETINT (len, (length / 2) - 1);
1761 tem = Fnthcdr (len, list);
1762 back = Fcdr (tem);
1763 Fsetcdr (tem, Qnil);
1764
1765 GCPRO2 (front, back);
88fe8140
EN
1766 front = Fsort (front, predicate);
1767 back = Fsort (back, predicate);
7b863bd5 1768 UNGCPRO;
88fe8140 1769 return merge (front, back, predicate);
7b863bd5
JB
1770}
1771
1772Lisp_Object
971de7fb 1773merge (Lisp_Object org_l1, Lisp_Object org_l2, Lisp_Object pred)
7b863bd5
JB
1774{
1775 Lisp_Object value;
1776 register Lisp_Object tail;
1777 Lisp_Object tem;
1778 register Lisp_Object l1, l2;
1779 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1780
1781 l1 = org_l1;
1782 l2 = org_l2;
1783 tail = Qnil;
1784 value = Qnil;
1785
1786 /* It is sufficient to protect org_l1 and org_l2.
1787 When l1 and l2 are updated, we copy the new values
1788 back into the org_ vars. */
1789 GCPRO4 (org_l1, org_l2, pred, value);
1790
1791 while (1)
1792 {
265a9e55 1793 if (NILP (l1))
7b863bd5
JB
1794 {
1795 UNGCPRO;
265a9e55 1796 if (NILP (tail))
7b863bd5
JB
1797 return l2;
1798 Fsetcdr (tail, l2);
1799 return value;
1800 }
265a9e55 1801 if (NILP (l2))
7b863bd5
JB
1802 {
1803 UNGCPRO;
265a9e55 1804 if (NILP (tail))
7b863bd5
JB
1805 return l1;
1806 Fsetcdr (tail, l1);
1807 return value;
1808 }
1809 tem = call2 (pred, Fcar (l2), Fcar (l1));
265a9e55 1810 if (NILP (tem))
7b863bd5
JB
1811 {
1812 tem = l1;
1813 l1 = Fcdr (l1);
1814 org_l1 = l1;
1815 }
1816 else
1817 {
1818 tem = l2;
1819 l2 = Fcdr (l2);
1820 org_l2 = l2;
1821 }
265a9e55 1822 if (NILP (tail))
7b863bd5
JB
1823 value = tem;
1824 else
1825 Fsetcdr (tail, tem);
1826 tail = tem;
1827 }
1828}
be9d483d 1829
2d6fabfc 1830\f
12ae7fc6 1831/* This does not check for quits. That is safe since it must terminate. */
7b863bd5 1832
a7ca3326 1833DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
27f604dd
KS
1834 doc: /* Extract a value from a property list.
1835PLIST is a property list, which is a list of the form
1836\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
12ae7fc6
KS
1837corresponding to the given PROP, or nil if PROP is not one of the
1838properties on the list. This function never signals an error. */)
5842a27b 1839 (Lisp_Object plist, Lisp_Object prop)
27f604dd
KS
1840{
1841 Lisp_Object tail, halftail;
1842
1843 /* halftail is used to detect circular lists. */
1844 tail = halftail = plist;
1845 while (CONSP (tail) && CONSP (XCDR (tail)))
1846 {
1847 if (EQ (prop, XCAR (tail)))
1848 return XCAR (XCDR (tail));
1849
1850 tail = XCDR (XCDR (tail));
1851 halftail = XCDR (halftail);
1852 if (EQ (tail, halftail))
1853 break;
af98fc7f
SM
1854
1855#if 0 /* Unsafe version. */
1856 /* This function can be called asynchronously
1857 (setup_coding_system). Don't QUIT in that case. */
1858 if (!interrupt_input_blocked)
1859 QUIT;
1860#endif
27f604dd
KS
1861 }
1862
1863 return Qnil;
1864}
1865
a7ca3326 1866DEFUN ("get", Fget, Sget, 2, 2, 0,
e9d8ddc9
MB
1867 doc: /* Return the value of SYMBOL's PROPNAME property.
1868This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */)
5842a27b 1869 (Lisp_Object symbol, Lisp_Object propname)
be9d483d 1870{
b7826503 1871 CHECK_SYMBOL (symbol);
c07289e0 1872 return Fplist_get (XSYMBOL (symbol)->plist, propname);
be9d483d
BG
1873}
1874
a7ca3326 1875DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
e9d8ddc9 1876 doc: /* Change value in PLIST of PROP to VAL.
47cebab1
GM
1877PLIST is a property list, which is a list of the form
1878\(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.
1879If PROP is already a property on the list, its value is set to VAL,
1880otherwise the new PROP VAL pair is added. The new plist is returned;
1881use `(setq x (plist-put x prop val))' to be sure to use the new value.
e9d8ddc9 1882The PLIST is modified by side effects. */)
5842a27b 1883 (Lisp_Object plist, register Lisp_Object prop, Lisp_Object val)
7b863bd5
JB
1884{
1885 register Lisp_Object tail, prev;
1886 Lisp_Object newcell;
1887 prev = Qnil;
70949dac
KR
1888 for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
1889 tail = XCDR (XCDR (tail)))
7b863bd5 1890 {
70949dac 1891 if (EQ (prop, XCAR (tail)))
be9d483d 1892 {
70949dac 1893 Fsetcar (XCDR (tail), val);
be9d483d
BG
1894 return plist;
1895 }
91f78c99 1896
7b863bd5 1897 prev = tail;
2d6fabfc 1898 QUIT;
7b863bd5 1899 }
088c8c37 1900 newcell = Fcons (prop, Fcons (val, NILP (prev) ? plist : XCDR (XCDR (prev))));
265a9e55 1901 if (NILP (prev))
be9d483d 1902 return newcell;
7b863bd5 1903 else
70949dac 1904 Fsetcdr (XCDR (prev), newcell);
be9d483d
BG
1905 return plist;
1906}
1907
a7ca3326 1908DEFUN ("put", Fput, Sput, 3, 3, 0,
e9d8ddc9
MB
1909 doc: /* Store SYMBOL's PROPNAME property with value VALUE.
1910It can be retrieved with `(get SYMBOL PROPNAME)'. */)
5842a27b 1911 (Lisp_Object symbol, Lisp_Object propname, Lisp_Object value)
be9d483d 1912{
b7826503 1913 CHECK_SYMBOL (symbol);
c07289e0
RS
1914 XSYMBOL (symbol)->plist
1915 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1916 return value;
7b863bd5 1917}
aebf4d42
RS
1918\f
1919DEFUN ("lax-plist-get", Flax_plist_get, Slax_plist_get, 2, 2, 0,
1920 doc: /* Extract a value from a property list, comparing with `equal'.
1921PLIST is a property list, which is a list of the form
1922\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
1923corresponding to the given PROP, or nil if PROP is not
1924one of the properties on the list. */)
5842a27b 1925 (Lisp_Object plist, Lisp_Object prop)
aebf4d42
RS
1926{
1927 Lisp_Object tail;
91f78c99 1928
aebf4d42
RS
1929 for (tail = plist;
1930 CONSP (tail) && CONSP (XCDR (tail));
1931 tail = XCDR (XCDR (tail)))
1932 {
1933 if (! NILP (Fequal (prop, XCAR (tail))))
1934 return XCAR (XCDR (tail));
1935
1936 QUIT;
1937 }
1938
89662fc3 1939 CHECK_LIST_END (tail, prop);
91f78c99 1940
aebf4d42
RS
1941 return Qnil;
1942}
7b863bd5 1943
aebf4d42
RS
1944DEFUN ("lax-plist-put", Flax_plist_put, Slax_plist_put, 3, 3, 0,
1945 doc: /* Change value in PLIST of PROP to VAL, comparing with `equal'.
1946PLIST is a property list, which is a list of the form
9e76ae05 1947\(PROP1 VALUE1 PROP2 VALUE2 ...). PROP and VAL are any objects.
aebf4d42
RS
1948If PROP is already a property on the list, its value is set to VAL,
1949otherwise the new PROP VAL pair is added. The new plist is returned;
1950use `(setq x (lax-plist-put x prop val))' to be sure to use the new value.
1951The PLIST is modified by side effects. */)
5842a27b 1952 (Lisp_Object plist, register Lisp_Object prop, Lisp_Object val)
aebf4d42
RS
1953{
1954 register Lisp_Object tail, prev;
1955 Lisp_Object newcell;
1956 prev = Qnil;
1957 for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
1958 tail = XCDR (XCDR (tail)))
1959 {
1960 if (! NILP (Fequal (prop, XCAR (tail))))
1961 {
1962 Fsetcar (XCDR (tail), val);
1963 return plist;
1964 }
91f78c99 1965
aebf4d42
RS
1966 prev = tail;
1967 QUIT;
1968 }
1969 newcell = Fcons (prop, Fcons (val, Qnil));
1970 if (NILP (prev))
1971 return newcell;
1972 else
1973 Fsetcdr (XCDR (prev), newcell);
1974 return plist;
1975}
1976\f
95f8c3b9
JPW
1977DEFUN ("eql", Feql, Seql, 2, 2, 0,
1978 doc: /* Return t if the two args are the same Lisp object.
1979Floating-point numbers of equal value are `eql', but they may not be `eq'. */)
5842a27b 1980 (Lisp_Object obj1, Lisp_Object obj2)
95f8c3b9
JPW
1981{
1982 if (FLOATP (obj1))
1983 return internal_equal (obj1, obj2, 0, 0) ? Qt : Qnil;
1984 else
1985 return EQ (obj1, obj2) ? Qt : Qnil;
1986}
1987
a7ca3326 1988DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
e9d8ddc9 1989 doc: /* Return t if two Lisp objects have similar structure and contents.
47cebab1
GM
1990They must have the same data type.
1991Conses are compared by comparing the cars and the cdrs.
1992Vectors and strings are compared element by element.
1993Numbers are compared by value, but integers cannot equal floats.
1994 (Use `=' if you want integers and floats to be able to be equal.)
e9d8ddc9 1995Symbols must match exactly. */)
5842a27b 1996 (register Lisp_Object o1, Lisp_Object o2)
7b863bd5 1997{
6b61353c
KH
1998 return internal_equal (o1, o2, 0, 0) ? Qt : Qnil;
1999}
2000
2001DEFUN ("equal-including-properties", Fequal_including_properties, Sequal_including_properties, 2, 2, 0,
2002 doc: /* Return t if two Lisp objects have similar structure and contents.
2003This is like `equal' except that it compares the text properties
2004of strings. (`equal' ignores text properties.) */)
5842a27b 2005 (register Lisp_Object o1, Lisp_Object o2)
6b61353c
KH
2006{
2007 return internal_equal (o1, o2, 0, 1) ? Qt : Qnil;
e0f5cf5a
RS
2008}
2009
6b61353c
KH
2010/* DEPTH is current depth of recursion. Signal an error if it
2011 gets too deep.
2012 PROPS, if non-nil, means compare string text properties too. */
2013
6cb9cafb 2014static int
971de7fb 2015internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int props)
e0f5cf5a
RS
2016{
2017 if (depth > 200)
2018 error ("Stack overflow in equal");
4ff1aed9 2019
6cb9cafb 2020 tail_recurse:
7b863bd5 2021 QUIT;
4ff1aed9
RS
2022 if (EQ (o1, o2))
2023 return 1;
2024 if (XTYPE (o1) != XTYPE (o2))
2025 return 0;
2026
2027 switch (XTYPE (o1))
2028 {
4ff1aed9 2029 case Lisp_Float:
6b61353c
KH
2030 {
2031 double d1, d2;
2032
2033 d1 = extract_float (o1);
2034 d2 = extract_float (o2);
2035 /* If d is a NaN, then d != d. Two NaNs should be `equal' even
2036 though they are not =. */
2037 return d1 == d2 || (d1 != d1 && d2 != d2);
2038 }
4ff1aed9
RS
2039
2040 case Lisp_Cons:
6b61353c 2041 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1, props))
4cab5074 2042 return 0;
70949dac
KR
2043 o1 = XCDR (o1);
2044 o2 = XCDR (o2);
4cab5074 2045 goto tail_recurse;
4ff1aed9
RS
2046
2047 case Lisp_Misc:
81d1fba6 2048 if (XMISCTYPE (o1) != XMISCTYPE (o2))
6cb9cafb 2049 return 0;
4ff1aed9 2050 if (OVERLAYP (o1))
7b863bd5 2051 {
e23f814f 2052 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
6b61353c 2053 depth + 1, props)
e23f814f 2054 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
43f15d4a 2055 depth + 1, props))
6cb9cafb 2056 return 0;
4ff1aed9
RS
2057 o1 = XOVERLAY (o1)->plist;
2058 o2 = XOVERLAY (o2)->plist;
2059 goto tail_recurse;
7b863bd5 2060 }
4ff1aed9
RS
2061 if (MARKERP (o1))
2062 {
2063 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
2064 && (XMARKER (o1)->buffer == 0
6ced1284 2065 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
4ff1aed9
RS
2066 }
2067 break;
2068
2069 case Lisp_Vectorlike:
4cab5074 2070 {
6b61353c 2071 register int i;
d311d28c 2072 ptrdiff_t size = ASIZE (o1);
4cab5074
KH
2073 /* Pseudovectors have the type encoded in the size field, so this test
2074 actually checks that the objects have the same type as well as the
2075 same size. */
7edbb0da 2076 if (ASIZE (o2) != size)
4cab5074 2077 return 0;
e03f7933
RS
2078 /* Boolvectors are compared much like strings. */
2079 if (BOOL_VECTOR_P (o1))
2080 {
e03f7933
RS
2081 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
2082 return 0;
72af86bd 2083 if (memcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
9b821a21
PE
2084 ((XBOOL_VECTOR (o1)->size
2085 + BOOL_VECTOR_BITS_PER_CHAR - 1)
2086 / BOOL_VECTOR_BITS_PER_CHAR)))
e03f7933
RS
2087 return 0;
2088 return 1;
2089 }
ed73fcc1 2090 if (WINDOW_CONFIGURATIONP (o1))
48646924 2091 return compare_window_configurations (o1, o2, 0);
e03f7933 2092
876c194c 2093 /* Aside from them, only true vectors, char-tables, compiled
66699ad3 2094 functions, and fonts (font-spec, font-entity, font-object)
876c194c 2095 are sensible to compare, so eliminate the others now. */
4cab5074
KH
2096 if (size & PSEUDOVECTOR_FLAG)
2097 {
876c194c
SM
2098 if (!(size & (PVEC_COMPILED
2099 | PVEC_CHAR_TABLE | PVEC_SUB_CHAR_TABLE | PVEC_FONT)))
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++)
2153 XCHAR_TABLE (array)->contents[i] = item;
2154 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]);
2821 val = make_unibyte_string (str, strlen (str));
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]);
2845 val = make_unibyte_string (str, strlen (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
799c08ac 2975 SAFE_ALLOCA (encoded, char *, 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. */
799c08ac 3030 SAFE_ALLOCA (encoded, char *, 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;
799c08ac 3174 SAFE_ALLOCA (decoded, char *, 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. */
799c08ac 3225 SAFE_ALLOCA (decoded, char *, 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);
d80c6c11 3437 xassert (VECTORP (vec));
8c172e82 3438 xassert (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);
6b61353c 3517 xassert ((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);
6b61353c 3534 xassert ((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);
6b61353c 3547 xassert ((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 \
3572 ((ptrdiff_t) min (MOST_POSITIVE_FIXNUM, PTRDIFF_MAX / sizeof (Lisp_Object)))
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. */
3608 xassert (SYMBOLP (test));
1fd4c450 3609 xassert (INTEGERP (size) && XINT (size) >= 0);
d80c6c11 3610 xassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
0de4bb68 3611 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size)));
d80c6c11 3612 xassert (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)
3666 HASH_NEXT (h, i) = make_number (i + 1);
3667 h->next_free = make_number (0);
3668
3669 XSET_HASH_TABLE (table, h);
3670 xassert (HASH_TABLE_P (table));
3671 xassert (XHASH_TABLE (table) == h);
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)
3773 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
d80c6c11
GM
3784 HASH_NEXT (h, XFASTINT (last)) = make_number (old_size);
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);
d80c6c11
GM
3795 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3796 HASH_INDEX (h, start_of_bucket) = make_number (i);
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
6b61353c 3846 xassert ((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);
3855 HASH_KEY (h, i) = key;
3856 HASH_VALUE (h, i) = value;
3857
3858 /* Remember its hash code. */
3859 HASH_HASH (h, i) = make_number (hash);
3860
3861 /* Add new entry to its collision chain. */
7edbb0da 3862 start_of_bucket = hash % ASIZE (h->index);
d80c6c11
GM
3863 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3864 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))
3895 HASH_INDEX (h, start_of_bucket) = HASH_NEXT (h, i);
3896 else
3897 HASH_NEXT (h, XFASTINT (prev)) = HASH_NEXT (h, i);
3898
3899 /* Clear slots in key_and_value and add the slots to
3900 the free list. */
3901 HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil;
3902 HASH_NEXT (h, i) = h->next_free;
3903 h->next_free = make_number (i);
878f97ff
SM
3904 h->count--;
3905 xassert (h->count >= 0);
d80c6c11
GM
3906 break;
3907 }
3908 else
3909 {
3910 prev = idx;
3911 idx = HASH_NEXT (h, i);
3912 }
3913 }
3914}
3915
3916
3917/* Clear hash table H. */
3918
2f7c71a1 3919static void
971de7fb 3920hash_clear (struct Lisp_Hash_Table *h)
d80c6c11 3921{
878f97ff 3922 if (h->count > 0)
d80c6c11 3923 {
d311d28c 3924 ptrdiff_t i, size = HASH_TABLE_SIZE (h);
d80c6c11
GM
3925
3926 for (i = 0; i < size; ++i)
3927 {
3928 HASH_NEXT (h, i) = i < size - 1 ? make_number (i + 1) : Qnil;
3929 HASH_KEY (h, i) = Qnil;
3930 HASH_VALUE (h, i) = Qnil;
3931 HASH_HASH (h, i) = Qnil;
3932 }
3933
7edbb0da 3934 for (i = 0; i < ASIZE (h->index); ++i)
68b587a6 3935 ASET (h->index, i, Qnil);
d80c6c11
GM
3936
3937 h->next_free = make_number (0);
878f97ff 3938 h->count = 0;
d80c6c11
GM
3939 }
3940}
3941
3942
3943\f
3944/************************************************************************
3945 Weak Hash Tables
3946 ************************************************************************/
3947
14067ea7 3948void
971de7fb 3949init_weak_hash_tables (void)
14067ea7
CY
3950{
3951 weak_hash_tables = NULL;
3952}
3953
a0b581cc
GM
3954/* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove
3955 entries from the table that don't survive the current GC.
3956 REMOVE_ENTRIES_P zero means mark entries that are in use. Value is
3957 non-zero if anything was marked. */
3958
3959static int
971de7fb 3960sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p)
a0b581cc 3961{
d311d28c 3962 ptrdiff_t bucket, n;
0de4bb68 3963 int marked;
59f953a2 3964
7edbb0da 3965 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG;
a0b581cc 3966 marked = 0;
59f953a2 3967
a0b581cc
GM
3968 for (bucket = 0; bucket < n; ++bucket)
3969 {
1e546714 3970 Lisp_Object idx, next, prev;
a0b581cc
GM
3971
3972 /* Follow collision chain, removing entries that
3973 don't survive this garbage collection. */
a0b581cc 3974 prev = Qnil;
8e50cc2d 3975 for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next)
a0b581cc 3976 {
d311d28c 3977 ptrdiff_t i = XFASTINT (idx);
1e546714
GM
3978 int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
3979 int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
3980 int remove_p;
59f953a2 3981
a0b581cc 3982 if (EQ (h->weak, Qkey))
aee625fa 3983 remove_p = !key_known_to_survive_p;
a0b581cc 3984 else if (EQ (h->weak, Qvalue))
aee625fa 3985 remove_p = !value_known_to_survive_p;
ec504e6f 3986 else if (EQ (h->weak, Qkey_or_value))
728c5d9d 3987 remove_p = !(key_known_to_survive_p || value_known_to_survive_p);
ec504e6f 3988 else if (EQ (h->weak, Qkey_and_value))
728c5d9d 3989 remove_p = !(key_known_to_survive_p && value_known_to_survive_p);
a0b581cc
GM
3990 else
3991 abort ();
59f953a2 3992
a0b581cc
GM
3993 next = HASH_NEXT (h, i);
3994
3995 if (remove_entries_p)
3996 {
3997 if (remove_p)
3998 {
3999 /* Take out of collision chain. */
8e50cc2d 4000 if (NILP (prev))
1e546714 4001 HASH_INDEX (h, bucket) = next;
a0b581cc
GM
4002 else
4003 HASH_NEXT (h, XFASTINT (prev)) = next;
59f953a2 4004
a0b581cc
GM
4005 /* Add to free list. */
4006 HASH_NEXT (h, i) = h->next_free;
4007 h->next_free = idx;
59f953a2 4008
a0b581cc
GM
4009 /* Clear key, value, and hash. */
4010 HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil;
4011 HASH_HASH (h, i) = Qnil;
59f953a2 4012
878f97ff 4013 h->count--;
a0b581cc 4014 }
d278cde0
KS
4015 else
4016 {
4017 prev = idx;
4018 }
a0b581cc
GM
4019 }
4020 else
4021 {
4022 if (!remove_p)
4023 {
4024 /* Make sure key and value survive. */
aee625fa
GM
4025 if (!key_known_to_survive_p)
4026 {
9568e3d8 4027 mark_object (HASH_KEY (h, i));
aee625fa
GM
4028 marked = 1;
4029 }
4030
4031 if (!value_known_to_survive_p)
4032 {
9568e3d8 4033 mark_object (HASH_VALUE (h, i));
aee625fa
GM
4034 marked = 1;
4035 }
a0b581cc
GM
4036 }
4037 }
a0b581cc
GM
4038 }
4039 }
4040
4041 return marked;
4042}
4043
d80c6c11
GM
4044/* Remove elements from weak hash tables that don't survive the
4045 current garbage collection. Remove weak tables that don't survive
4046 from Vweak_hash_tables. Called from gc_sweep. */
4047
4048void
971de7fb 4049sweep_weak_hash_tables (void)
d80c6c11 4050{
6c661ec9 4051 struct Lisp_Hash_Table *h, *used, *next;
a0b581cc
GM
4052 int marked;
4053
4054 /* Mark all keys and values that are in use. Keep on marking until
4055 there is no more change. This is necessary for cases like
4056 value-weak table A containing an entry X -> Y, where Y is used in a
4057 key-weak table B, Z -> Y. If B comes after A in the list of weak
4058 tables, X -> Y might be removed from A, although when looking at B
4059 one finds that it shouldn't. */
4060 do
4061 {
4062 marked = 0;
6c661ec9 4063 for (h = weak_hash_tables; h; h = h->next_weak)
a0b581cc 4064 {
eab3844f 4065 if (h->header.size & ARRAY_MARK_FLAG)
a0b581cc
GM
4066 marked |= sweep_weak_table (h, 0);
4067 }
4068 }
4069 while (marked);
d80c6c11 4070
a0b581cc 4071 /* Remove tables and entries that aren't used. */
6c661ec9 4072 for (h = weak_hash_tables, used = NULL; h; h = next)
d80c6c11 4073 {
ac0e96ee 4074 next = h->next_weak;
91f78c99 4075
eab3844f 4076 if (h->header.size & ARRAY_MARK_FLAG)
d80c6c11 4077 {
ac0e96ee 4078 /* TABLE is marked as used. Sweep its contents. */
878f97ff 4079 if (h->count > 0)
a0b581cc 4080 sweep_weak_table (h, 1);
ac0e96ee
GM
4081
4082 /* Add table to the list of used weak hash tables. */
4083 h->next_weak = used;
6c661ec9 4084 used = h;
d80c6c11
GM
4085 }
4086 }
ac0e96ee 4087
6c661ec9 4088 weak_hash_tables = used;
d80c6c11
GM
4089}
4090
4091
4092\f
4093/***********************************************************************
4094 Hash Code Computation
4095 ***********************************************************************/
4096
4097/* Maximum depth up to which to dive into Lisp structures. */
4098
4099#define SXHASH_MAX_DEPTH 3
4100
4101/* Maximum length up to which to take list and vector elements into
4102 account. */
4103
4104#define SXHASH_MAX_LEN 7
4105
0de4bb68
PE
4106/* Combine two integers X and Y for hashing. The result might not fit
4107 into a Lisp integer. */
d80c6c11
GM
4108
4109#define SXHASH_COMBINE(X, Y) \
0de4bb68
PE
4110 ((((EMACS_UINT) (X) << 4) + ((EMACS_UINT) (X) >> (BITS_PER_EMACS_INT - 4))) \
4111 + (EMACS_UINT) (Y))
d80c6c11 4112
0de4bb68
PE
4113/* Hash X, returning a value that fits into a Lisp integer. */
4114#define SXHASH_REDUCE(X) \
4115 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
d80c6c11 4116
3cc5a532
PE
4117/* Return a hash for string PTR which has length LEN. The hash value
4118 can be any EMACS_UINT value. */
d80c6c11 4119
3cc5a532
PE
4120EMACS_UINT
4121hash_string (char const *ptr, ptrdiff_t len)
d80c6c11 4122{
3cc5a532
PE
4123 char const *p = ptr;
4124 char const *end = p + len;
d80c6c11 4125 unsigned char c;
0de4bb68 4126 EMACS_UINT hash = 0;
d80c6c11
GM
4127
4128 while (p != end)
4129 {
4130 c = *p++;
0de4bb68 4131 hash = SXHASH_COMBINE (hash, c);
d80c6c11 4132 }
59f953a2 4133
3cc5a532
PE
4134 return hash;
4135}
4136
4137/* Return a hash for string PTR which has length LEN. The hash
4138 code returned is guaranteed to fit in a Lisp integer. */
4139
4140static EMACS_UINT
4141sxhash_string (char const *ptr, ptrdiff_t len)
4142{
4143 EMACS_UINT hash = hash_string (ptr, len);
0de4bb68 4144 return SXHASH_REDUCE (hash);
d80c6c11
GM
4145}
4146
0de4bb68
PE
4147/* Return a hash for the floating point value VAL. */
4148
4149static EMACS_INT
4150sxhash_float (double val)
4151{
4152 EMACS_UINT hash = 0;
4153 enum {
4154 WORDS_PER_DOUBLE = (sizeof val / sizeof hash
4155 + (sizeof val % sizeof hash != 0))
4156 };
4157 union {
4158 double val;
4159 EMACS_UINT word[WORDS_PER_DOUBLE];
4160 } u;
4161 int i;
4162 u.val = val;
4163 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4164 for (i = 0; i < WORDS_PER_DOUBLE; i++)
4165 hash = SXHASH_COMBINE (hash, u.word[i]);
4166 return SXHASH_REDUCE (hash);
4167}
d80c6c11
GM
4168
4169/* Return a hash for list LIST. DEPTH is the current depth in the
4170 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
4171
0de4bb68 4172static EMACS_UINT
971de7fb 4173sxhash_list (Lisp_Object list, int depth)
d80c6c11 4174{
0de4bb68 4175 EMACS_UINT hash = 0;
d80c6c11 4176 int i;
59f953a2 4177
d80c6c11
GM
4178 if (depth < SXHASH_MAX_DEPTH)
4179 for (i = 0;
4180 CONSP (list) && i < SXHASH_MAX_LEN;
4181 list = XCDR (list), ++i)
4182 {
0de4bb68 4183 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
d80c6c11
GM
4184 hash = SXHASH_COMBINE (hash, hash2);
4185 }
4186
ea284f33
KS
4187 if (!NILP (list))
4188 {
0de4bb68 4189 EMACS_UINT hash2 = sxhash (list, depth + 1);
ea284f33
KS
4190 hash = SXHASH_COMBINE (hash, hash2);
4191 }
4192
0de4bb68 4193 return SXHASH_REDUCE (hash);
d80c6c11
GM
4194}
4195
4196
4197/* Return a hash for vector VECTOR. DEPTH is the current depth in
4198 the Lisp structure. */
4199
0de4bb68 4200static EMACS_UINT
971de7fb 4201sxhash_vector (Lisp_Object vec, int depth)
d80c6c11 4202{
0de4bb68 4203 EMACS_UINT hash = ASIZE (vec);
d80c6c11
GM
4204 int i, n;
4205
7edbb0da 4206 n = min (SXHASH_MAX_LEN, ASIZE (vec));
d80c6c11
GM
4207 for (i = 0; i < n; ++i)
4208 {
0de4bb68 4209 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
d80c6c11
GM
4210 hash = SXHASH_COMBINE (hash, hash2);
4211 }
4212
0de4bb68 4213 return SXHASH_REDUCE (hash);
d80c6c11
GM
4214}
4215
d80c6c11
GM
4216/* Return a hash for bool-vector VECTOR. */
4217
0de4bb68 4218static EMACS_UINT
971de7fb 4219sxhash_bool_vector (Lisp_Object vec)
d80c6c11 4220{
0de4bb68 4221 EMACS_UINT hash = XBOOL_VECTOR (vec)->size;
d80c6c11
GM
4222 int i, n;
4223
eab3844f 4224 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
d80c6c11
GM
4225 for (i = 0; i < n; ++i)
4226 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
4227
0de4bb68 4228 return SXHASH_REDUCE (hash);
d80c6c11
GM
4229}
4230
4231
4232/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
6b61353c 4233 structure. Value is an unsigned integer clipped to INTMASK. */
d80c6c11 4234
0de4bb68 4235EMACS_UINT
971de7fb 4236sxhash (Lisp_Object obj, int depth)
d80c6c11 4237{
0de4bb68 4238 EMACS_UINT hash;
d80c6c11
GM
4239
4240 if (depth > SXHASH_MAX_DEPTH)
4241 return 0;
59f953a2 4242
d80c6c11
GM
4243 switch (XTYPE (obj))
4244 {
2de9f71c 4245 case_Lisp_Int:
d80c6c11
GM
4246 hash = XUINT (obj);
4247 break;
4248
d80c6c11
GM
4249 case Lisp_Misc:
4250 hash = XUINT (obj);
4251 break;
4252
32bfb2d5
EZ
4253 case Lisp_Symbol:
4254 obj = SYMBOL_NAME (obj);
4255 /* Fall through. */
4256
d80c6c11 4257 case Lisp_String:
3cc5a532 4258 hash = sxhash_string (SSDATA (obj), SBYTES (obj));
d80c6c11
GM
4259 break;
4260
4261 /* This can be everything from a vector to an overlay. */
4262 case Lisp_Vectorlike:
4263 if (VECTORP (obj))
4264 /* According to the CL HyperSpec, two arrays are equal only if
4265 they are `eq', except for strings and bit-vectors. In
4266 Emacs, this works differently. We have to compare element
4267 by element. */
4268 hash = sxhash_vector (obj, depth);
4269 else if (BOOL_VECTOR_P (obj))
4270 hash = sxhash_bool_vector (obj);
4271 else
4272 /* Others are `equal' if they are `eq', so let's take their
4273 address as hash. */
4274 hash = XUINT (obj);
4275 break;
4276
4277 case Lisp_Cons:
4278 hash = sxhash_list (obj, depth);
4279 break;
4280
4281 case Lisp_Float:
0de4bb68
PE
4282 hash = sxhash_float (XFLOAT_DATA (obj));
4283 break;
d80c6c11
GM
4284
4285 default:
4286 abort ();
4287 }
4288
0de4bb68 4289 return hash;
d80c6c11
GM
4290}
4291
4292
4293\f
4294/***********************************************************************
4295 Lisp Interface
4296 ***********************************************************************/
4297
4298
4299DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
e9d8ddc9 4300 doc: /* Compute a hash code for OBJ and return it as integer. */)
5842a27b 4301 (Lisp_Object obj)
d80c6c11 4302{
0de4bb68 4303 EMACS_UINT hash = sxhash (obj, 0);
d80c6c11
GM
4304 return make_number (hash);
4305}
4306
4307
a7ca3326 4308DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
e9d8ddc9 4309 doc: /* Create and return a new hash table.
91f78c99 4310
47cebab1
GM
4311Arguments are specified as keyword/argument pairs. The following
4312arguments are defined:
4313
4314:test TEST -- TEST must be a symbol that specifies how to compare
4315keys. Default is `eql'. Predefined are the tests `eq', `eql', and
4316`equal'. User-supplied test and hash functions can be specified via
4317`define-hash-table-test'.
4318
4319:size SIZE -- A hint as to how many elements will be put in the table.
4320Default is 65.
4321
4322:rehash-size REHASH-SIZE - Indicates how to expand the table when it
79d6f59e
CY
4323fills up. If REHASH-SIZE is an integer, increase the size by that
4324amount. If it is a float, it must be > 1.0, and the new size is the
4325old size multiplied by that factor. Default is 1.5.
47cebab1
GM
4326
4327:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
b756c005 4328Resize the hash table when the ratio (number of entries / table size)
e1025755 4329is greater than or equal to THRESHOLD. Default is 0.8.
47cebab1
GM
4330
4331:weakness WEAK -- WEAK must be one of nil, t, `key', `value',
4332`key-or-value', or `key-and-value'. If WEAK is not nil, the table
4333returned is a weak table. Key/value pairs are removed from a weak
4334hash table when there are no non-weak references pointing to their
4335key, value, one of key or value, or both key and value, depending on
4336WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK
4bf8e2a3
MB
4337is nil.
4338
4339usage: (make-hash-table &rest KEYWORD-ARGS) */)
f66c7cf8 4340 (ptrdiff_t nargs, Lisp_Object *args)
d80c6c11
GM
4341{
4342 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4343 Lisp_Object user_test, user_hash;
4344 char *used;
f66c7cf8 4345 ptrdiff_t i;
d80c6c11
GM
4346
4347 /* The vector `used' is used to keep track of arguments that
4348 have been consumed. */
4349 used = (char *) alloca (nargs * sizeof *used);
72af86bd 4350 memset (used, 0, nargs * sizeof *used);
d80c6c11
GM
4351
4352 /* See if there's a `:test TEST' among the arguments. */
4353 i = get_key_arg (QCtest, nargs, args, used);
c5101a77 4354 test = i ? args[i] : Qeql;
d80c6c11
GM
4355 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal))
4356 {
4357 /* See if it is a user-defined test. */
4358 Lisp_Object prop;
59f953a2 4359
d80c6c11 4360 prop = Fget (test, Qhash_table_test);
c1dd95fc 4361 if (!CONSP (prop) || !CONSP (XCDR (prop)))
692ae65c 4362 signal_error ("Invalid hash table test", test);
c1dd95fc
RS
4363 user_test = XCAR (prop);
4364 user_hash = XCAR (XCDR (prop));
d80c6c11
GM
4365 }
4366 else
4367 user_test = user_hash = Qnil;
4368
4369 /* See if there's a `:size SIZE' argument. */
4370 i = get_key_arg (QCsize, nargs, args, used);
c5101a77 4371 size = i ? args[i] : Qnil;
cf42cb72
SM
4372 if (NILP (size))
4373 size = make_number (DEFAULT_HASH_SIZE);
4374 else if (!INTEGERP (size) || XINT (size) < 0)
692ae65c 4375 signal_error ("Invalid hash table size", size);
d80c6c11
GM
4376
4377 /* Look for `:rehash-size SIZE'. */
4378 i = get_key_arg (QCrehash_size, nargs, args, used);
c5101a77 4379 rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE);
0de4bb68
PE
4380 if (! ((INTEGERP (rehash_size) && 0 < XINT (rehash_size))
4381 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))))
692ae65c 4382 signal_error ("Invalid hash table rehash size", rehash_size);
59f953a2 4383
d80c6c11
GM
4384 /* Look for `:rehash-threshold THRESHOLD'. */
4385 i = get_key_arg (QCrehash_threshold, nargs, args, used);
c5101a77 4386 rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD);
0de4bb68
PE
4387 if (! (FLOATP (rehash_threshold)
4388 && 0 < XFLOAT_DATA (rehash_threshold)
4389 && XFLOAT_DATA (rehash_threshold) <= 1))
692ae65c 4390 signal_error ("Invalid hash table rehash threshold", rehash_threshold);
59f953a2 4391
ee0403b3
GM
4392 /* Look for `:weakness WEAK'. */
4393 i = get_key_arg (QCweakness, nargs, args, used);
c5101a77 4394 weak = i ? args[i] : Qnil;
ec504e6f
GM
4395 if (EQ (weak, Qt))
4396 weak = Qkey_and_value;
d80c6c11 4397 if (!NILP (weak)
f899c503 4398 && !EQ (weak, Qkey)
ec504e6f
GM
4399 && !EQ (weak, Qvalue)
4400 && !EQ (weak, Qkey_or_value)
4401 && !EQ (weak, Qkey_and_value))
692ae65c 4402 signal_error ("Invalid hash table weakness", weak);
59f953a2 4403
d80c6c11
GM
4404 /* Now, all args should have been used up, or there's a problem. */
4405 for (i = 0; i < nargs; ++i)
4406 if (!used[i])
692ae65c 4407 signal_error ("Invalid argument list", args[i]);
d80c6c11
GM
4408
4409 return make_hash_table (test, size, rehash_size, rehash_threshold, weak,
4410 user_test, user_hash);
4411}
4412
4413
f899c503 4414DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
e9d8ddc9 4415 doc: /* Return a copy of hash table TABLE. */)
5842a27b 4416 (Lisp_Object table)
f899c503
GM
4417{
4418 return copy_hash_table (check_hash_table (table));
4419}
4420
4421
d80c6c11 4422DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
e9d8ddc9 4423 doc: /* Return the number of elements in TABLE. */)
5842a27b 4424 (Lisp_Object table)
d80c6c11 4425{
878f97ff 4426 return make_number (check_hash_table (table)->count);
d80c6c11
GM
4427}
4428
59f953a2 4429
d80c6c11
GM
4430DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
4431 Shash_table_rehash_size, 1, 1, 0,
e9d8ddc9 4432 doc: /* Return the current rehash size of TABLE. */)
5842a27b 4433 (Lisp_Object table)
d80c6c11
GM
4434{
4435 return check_hash_table (table)->rehash_size;
4436}
59f953a2 4437
d80c6c11
GM
4438
4439DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold,
4440 Shash_table_rehash_threshold, 1, 1, 0,
e9d8ddc9 4441 doc: /* Return the current rehash threshold of TABLE. */)
5842a27b 4442 (Lisp_Object table)
d80c6c11
GM
4443{
4444 return check_hash_table (table)->rehash_threshold;
4445}
59f953a2 4446
d80c6c11
GM
4447
4448DEFUN ("hash-table-size", Fhash_table_size, Shash_table_size, 1, 1, 0,
e9d8ddc9 4449 doc: /* Return the size of TABLE.
47cebab1 4450The size can be used as an argument to `make-hash-table' to create
b756c005 4451a hash table than can hold as many elements as TABLE holds
e9d8ddc9 4452without need for resizing. */)
5842a27b 4453 (Lisp_Object table)
d80c6c11
GM
4454{
4455 struct Lisp_Hash_Table *h = check_hash_table (table);
4456 return make_number (HASH_TABLE_SIZE (h));
4457}
59f953a2 4458
d80c6c11
GM
4459
4460DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
e9d8ddc9 4461 doc: /* Return the test TABLE uses. */)
5842a27b 4462 (Lisp_Object table)
d80c6c11
GM
4463{
4464 return check_hash_table (table)->test;
4465}
4466
59f953a2 4467
e84b1dea
GM
4468DEFUN ("hash-table-weakness", Fhash_table_weakness, Shash_table_weakness,
4469 1, 1, 0,
e9d8ddc9 4470 doc: /* Return the weakness of TABLE. */)
5842a27b 4471 (Lisp_Object table)
d80c6c11
GM
4472{
4473 return check_hash_table (table)->weak;
4474}
4475
59f953a2 4476
d80c6c11 4477DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
e9d8ddc9 4478 doc: /* Return t if OBJ is a Lisp hash table object. */)
5842a27b 4479 (Lisp_Object obj)
d80c6c11
GM
4480{
4481 return HASH_TABLE_P (obj) ? Qt : Qnil;
4482}
4483
4484
4485DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
ccd8f7fe 4486 doc: /* Clear hash table TABLE and return it. */)
5842a27b 4487 (Lisp_Object table)
d80c6c11
GM
4488{
4489 hash_clear (check_hash_table (table));
ccd8f7fe
TTN
4490 /* Be compatible with XEmacs. */
4491 return table;
d80c6c11
GM
4492}
4493
4494
a7ca3326 4495DEFUN ("gethash", Fgethash, Sgethash, 2, 3, 0,
e9d8ddc9
MB
4496 doc: /* Look up KEY in TABLE and return its associated value.
4497If KEY is not found, return DFLT which defaults to nil. */)
5842a27b 4498 (Lisp_Object key, Lisp_Object table, Lisp_Object dflt)
d80c6c11
GM
4499{
4500 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4501 ptrdiff_t i = hash_lookup (h, key, NULL);
d80c6c11
GM
4502 return i >= 0 ? HASH_VALUE (h, i) : dflt;
4503}
4504
4505
a7ca3326 4506DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
e9d8ddc9 4507 doc: /* Associate KEY with VALUE in hash table TABLE.
47cebab1 4508If KEY is already present in table, replace its current value with
a54e3482 4509VALUE. In any case, return VALUE. */)
5842a27b 4510 (Lisp_Object key, Lisp_Object value, Lisp_Object table)
d80c6c11
GM
4511{
4512 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4513 ptrdiff_t i;
0de4bb68 4514 EMACS_UINT hash;
d80c6c11
GM
4515
4516 i = hash_lookup (h, key, &hash);
4517 if (i >= 0)
4518 HASH_VALUE (h, i) = value;
4519 else
4520 hash_put (h, key, value, hash);
59f953a2 4521
d9c4f922 4522 return value;
d80c6c11
GM
4523}
4524
4525
a7ca3326 4526DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
e9d8ddc9 4527 doc: /* Remove KEY from TABLE. */)
5842a27b 4528 (Lisp_Object key, Lisp_Object table)
d80c6c11
GM
4529{
4530 struct Lisp_Hash_Table *h = check_hash_table (table);
5a2d7ab6 4531 hash_remove_from_table (h, key);
d80c6c11
GM
4532 return Qnil;
4533}
4534
4535
4536DEFUN ("maphash", Fmaphash, Smaphash, 2, 2, 0,
e9d8ddc9 4537 doc: /* Call FUNCTION for all entries in hash table TABLE.
c14ec135 4538FUNCTION is called with two arguments, KEY and VALUE. */)
5842a27b 4539 (Lisp_Object function, Lisp_Object table)
d80c6c11
GM
4540{
4541 struct Lisp_Hash_Table *h = check_hash_table (table);
4542 Lisp_Object args[3];
d311d28c 4543 ptrdiff_t i;
d80c6c11
GM
4544
4545 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
4546 if (!NILP (HASH_HASH (h, i)))
4547 {
4548 args[0] = function;
4549 args[1] = HASH_KEY (h, i);
4550 args[2] = HASH_VALUE (h, i);
4551 Ffuncall (3, args);
4552 }
59f953a2 4553
d80c6c11
GM
4554 return Qnil;
4555}
4556
4557
4558DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
4559 Sdefine_hash_table_test, 3, 3, 0,
e9d8ddc9 4560 doc: /* Define a new hash table test with name NAME, a symbol.
91f78c99 4561
47cebab1
GM
4562In hash tables created with NAME specified as test, use TEST to
4563compare keys, and HASH for computing hash codes of keys.
4564
4565TEST must be a function taking two arguments and returning non-nil if
4566both arguments are the same. HASH must be a function taking one
4567argument and return an integer that is the hash code of the argument.
4568Hash code computation should use the whole value range of integers,
e9d8ddc9 4569including negative integers. */)
5842a27b 4570 (Lisp_Object name, Lisp_Object test, Lisp_Object hash)
d80c6c11
GM
4571{
4572 return Fput (name, Qhash_table_test, list2 (test, hash));
4573}
4574
a3b210c4 4575
57916a7a 4576\f
5c302da4 4577/************************************************************************
7f3f739f 4578 MD5, SHA-1, and SHA-2
5c302da4
GM
4579 ************************************************************************/
4580
57916a7a 4581#include "md5.h"
e1b90ef6 4582#include "sha1.h"
7f3f739f
LL
4583#include "sha256.h"
4584#include "sha512.h"
57916a7a 4585
7f3f739f 4586/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
47cebab1 4587
f1b54466 4588static Lisp_Object
7f3f739f 4589secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary)
57916a7a 4590{
57916a7a 4591 int i;
d311d28c 4592 ptrdiff_t size;
e6d4aefa 4593 EMACS_INT start_char = 0, end_char = 0;
d311d28c 4594 ptrdiff_t start_byte, end_byte;
e6d4aefa 4595 register EMACS_INT b, e;
57916a7a 4596 register struct buffer *bp;
e6d4aefa 4597 EMACS_INT temp;
7f3f739f
LL
4598 int digest_size;
4599 void *(*hash_func) (const char *, size_t, void *);
4600 Lisp_Object digest;
4601
4602 CHECK_SYMBOL (algorithm);
57916a7a 4603
5c302da4 4604 if (STRINGP (object))
57916a7a
GM
4605 {
4606 if (NILP (coding_system))
4607 {
5c302da4 4608 /* Decide the coding-system to encode the data with. */
57916a7a 4609
5c302da4
GM
4610 if (STRING_MULTIBYTE (object))
4611 /* use default, we can't guess correct value */
38583a69 4612 coding_system = preferred_coding_system ();
91f78c99 4613 else
5c302da4 4614 coding_system = Qraw_text;
57916a7a 4615 }
91f78c99 4616
5c302da4 4617 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4618 {
5c302da4 4619 /* Invalid coding system. */
91f78c99 4620
5c302da4
GM
4621 if (!NILP (noerror))
4622 coding_system = Qraw_text;
4623 else
692ae65c 4624 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4625 }
4626
5c302da4 4627 if (STRING_MULTIBYTE (object))
38583a69 4628 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
5c302da4 4629
d5db4077 4630 size = SCHARS (object);
57916a7a
GM
4631
4632 if (!NILP (start))
4633 {
b7826503 4634 CHECK_NUMBER (start);
57916a7a
GM
4635
4636 start_char = XINT (start);
4637
4638 if (start_char < 0)
4639 start_char += size;
57916a7a
GM
4640 }
4641
4642 if (NILP (end))
d311d28c 4643 end_char = size;
57916a7a
GM
4644 else
4645 {
b7826503 4646 CHECK_NUMBER (end);
91f78c99 4647
57916a7a
GM
4648 end_char = XINT (end);
4649
4650 if (end_char < 0)
4651 end_char += size;
57916a7a 4652 }
91f78c99 4653
57916a7a
GM
4654 if (!(0 <= start_char && start_char <= end_char && end_char <= size))
4655 args_out_of_range_3 (object, make_number (start_char),
4656 make_number (end_char));
d311d28c
PE
4657
4658 start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char);
4659 end_byte =
4660 NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char);
57916a7a
GM
4661 }
4662 else
4663 {
6b61353c
KH
4664 struct buffer *prev = current_buffer;
4665
4666 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
4667
b7826503 4668 CHECK_BUFFER (object);
57916a7a
GM
4669
4670 bp = XBUFFER (object);
6b61353c
KH
4671 if (bp != current_buffer)
4672 set_buffer_internal (bp);
91f78c99 4673
57916a7a 4674 if (NILP (start))
6b61353c 4675 b = BEGV;
57916a7a
GM
4676 else
4677 {
b7826503 4678 CHECK_NUMBER_COERCE_MARKER (start);
57916a7a
GM
4679 b = XINT (start);
4680 }
4681
4682 if (NILP (end))
6b61353c 4683 e = ZV;
57916a7a
GM
4684 else
4685 {
b7826503 4686 CHECK_NUMBER_COERCE_MARKER (end);
57916a7a
GM
4687 e = XINT (end);
4688 }
91f78c99 4689
57916a7a
GM
4690 if (b > e)
4691 temp = b, b = e, e = temp;
91f78c99 4692
6b61353c 4693 if (!(BEGV <= b && e <= ZV))
57916a7a 4694 args_out_of_range (start, end);
91f78c99 4695
57916a7a
GM
4696 if (NILP (coding_system))
4697 {
91f78c99 4698 /* Decide the coding-system to encode the data with.
5c302da4
GM
4699 See fileio.c:Fwrite-region */
4700
4701 if (!NILP (Vcoding_system_for_write))
4702 coding_system = Vcoding_system_for_write;
4703 else
4704 {
4705 int force_raw_text = 0;
4706
4b4deea2 4707 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4708 if (NILP (coding_system)
4709 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4710 {
4711 coding_system = Qnil;
4b4deea2 4712 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
5c302da4
GM
4713 force_raw_text = 1;
4714 }
4715
5e617bc2 4716 if (NILP (coding_system) && !NILP (Fbuffer_file_name (object)))
5c302da4
GM
4717 {
4718 /* Check file-coding-system-alist. */
4719 Lisp_Object args[4], val;
91f78c99 4720
5c302da4 4721 args[0] = Qwrite_region; args[1] = start; args[2] = end;
5e617bc2 4722 args[3] = Fbuffer_file_name (object);
5c302da4
GM
4723 val = Ffind_operation_coding_system (4, args);
4724 if (CONSP (val) && !NILP (XCDR (val)))
4725 coding_system = XCDR (val);
4726 }
4727
4728 if (NILP (coding_system)
4b4deea2 4729 && !NILP (BVAR (XBUFFER (object), buffer_file_coding_system)))
5c302da4
GM
4730 {
4731 /* If we still have not decided a coding system, use the
4732 default value of buffer-file-coding-system. */
4b4deea2 4733 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4734 }
4735
4736 if (!force_raw_text
4737 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4738 /* Confirm that VAL can surely encode the current region. */
1e59646d 4739 coding_system = call4 (Vselect_safe_coding_system_function,
70da6a76 4740 make_number (b), make_number (e),
1e59646d 4741 coding_system, Qnil);
5c302da4
GM
4742
4743 if (force_raw_text)
4744 coding_system = Qraw_text;
4745 }
4746
4747 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4748 {
5c302da4
GM
4749 /* Invalid coding system. */
4750
4751 if (!NILP (noerror))
4752 coding_system = Qraw_text;
4753 else
692ae65c 4754 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4755 }
4756 }
4757
4758 object = make_buffer_string (b, e, 0);
6b61353c
KH
4759 if (prev != current_buffer)
4760 set_buffer_internal (prev);
4761 /* Discard the unwind protect for recovering the current
4762 buffer. */
4763 specpdl_ptr--;
57916a7a
GM
4764
4765 if (STRING_MULTIBYTE (object))
8f924df7 4766 object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
d311d28c
PE
4767 start_byte = 0;
4768 end_byte = SBYTES (object);
57916a7a
GM
4769 }
4770
7f3f739f 4771 if (EQ (algorithm, Qmd5))
e1b90ef6 4772 {
7f3f739f
LL
4773 digest_size = MD5_DIGEST_SIZE;
4774 hash_func = md5_buffer;
4775 }
4776 else if (EQ (algorithm, Qsha1))
4777 {
4778 digest_size = SHA1_DIGEST_SIZE;
4779 hash_func = sha1_buffer;
4780 }
4781 else if (EQ (algorithm, Qsha224))
4782 {
4783 digest_size = SHA224_DIGEST_SIZE;
4784 hash_func = sha224_buffer;
4785 }
4786 else if (EQ (algorithm, Qsha256))
4787 {
4788 digest_size = SHA256_DIGEST_SIZE;
4789 hash_func = sha256_buffer;
4790 }
4791 else if (EQ (algorithm, Qsha384))
4792 {
4793 digest_size = SHA384_DIGEST_SIZE;
4794 hash_func = sha384_buffer;
4795 }
4796 else if (EQ (algorithm, Qsha512))
4797 {
4798 digest_size = SHA512_DIGEST_SIZE;
4799 hash_func = sha512_buffer;
4800 }
4801 else
4802 error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm)));
57916a7a 4803
7f3f739f
LL
4804 /* allocate 2 x digest_size so that it can be re-used to hold the
4805 hexified value */
4806 digest = make_uninit_string (digest_size * 2);
57916a7a 4807
7f3f739f 4808 hash_func (SSDATA (object) + start_byte,
d311d28c 4809 end_byte - start_byte,
7f3f739f 4810 SSDATA (digest));
e1b90ef6 4811
7f3f739f
LL
4812 if (NILP (binary))
4813 {
4814 unsigned char *p = SDATA (digest);
4815 for (i = digest_size - 1; i >= 0; i--)
4816 {
4817 static char const hexdigit[16] = "0123456789abcdef";
4818 int p_i = p[i];
4819 p[2 * i] = hexdigit[p_i >> 4];
4820 p[2 * i + 1] = hexdigit[p_i & 0xf];
4821 }
4822 return digest;
4823 }
4824 else
a9041e6c 4825 return make_unibyte_string (SSDATA (digest), digest_size);
e1b90ef6
LL
4826}
4827
4828DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
4829 doc: /* Return MD5 message digest of OBJECT, a buffer or string.
4830
4831A message digest is a cryptographic checksum of a document, and the
4832algorithm to calculate it is defined in RFC 1321.
4833
4834The two optional arguments START and END are character positions
4835specifying for which part of OBJECT the message digest should be
4836computed. If nil or omitted, the digest is computed for the whole
4837OBJECT.
4838
4839The MD5 message digest is computed from the result of encoding the
4840text in a coding system, not directly from the internal Emacs form of
4841the text. The optional fourth argument CODING-SYSTEM specifies which
4842coding system to encode the text with. It should be the same coding
4843system that you used or will use when actually writing the text into a
4844file.
4845
4846If CODING-SYSTEM is nil or omitted, the default depends on OBJECT. If
4847OBJECT is a buffer, the default for CODING-SYSTEM is whatever coding
4848system would be chosen by default for writing this text into a file.
4849
4850If OBJECT is a string, the most preferred coding system (see the
4851command `prefer-coding-system') is used.
4852
4853If NOERROR is non-nil, silently assume the `raw-text' coding if the
4854guesswork fails. Normally, an error is signaled in such case. */)
4855 (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror)
4856{
7f3f739f 4857 return secure_hash (Qmd5, object, start, end, coding_system, noerror, Qnil);
e1b90ef6
LL
4858}
4859
7f3f739f 4860DEFUN ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0,
49241268
GM
4861 doc: /* Return the secure hash of OBJECT, a buffer or string.
4862ALGORITHM is a symbol specifying the hash to use:
4863md5, sha1, sha224, sha256, sha384 or sha512.
4864
4865The two optional arguments START and END are positions specifying for
4866which part of OBJECT to compute the hash. If nil or omitted, uses the
4867whole OBJECT.
4868
4869If BINARY is non-nil, returns a string in binary form. */)
7f3f739f 4870 (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
e1b90ef6 4871{
7f3f739f 4872 return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary);
57916a7a 4873}
24c129e4 4874\f
dfcf069d 4875void
971de7fb 4876syms_of_fns (void)
7b863bd5 4877{
7f3f739f
LL
4878 DEFSYM (Qmd5, "md5");
4879 DEFSYM (Qsha1, "sha1");
4880 DEFSYM (Qsha224, "sha224");
4881 DEFSYM (Qsha256, "sha256");
4882 DEFSYM (Qsha384, "sha384");
4883 DEFSYM (Qsha512, "sha512");
4884
d80c6c11 4885 /* Hash table stuff. */
cd3520a4
JB
4886 DEFSYM (Qhash_table_p, "hash-table-p");
4887 DEFSYM (Qeq, "eq");
4888 DEFSYM (Qeql, "eql");
4889 DEFSYM (Qequal, "equal");
4890 DEFSYM (QCtest, ":test");
4891 DEFSYM (QCsize, ":size");
4892 DEFSYM (QCrehash_size, ":rehash-size");
4893 DEFSYM (QCrehash_threshold, ":rehash-threshold");
4894 DEFSYM (QCweakness, ":weakness");
4895 DEFSYM (Qkey, "key");
4896 DEFSYM (Qvalue, "value");
4897 DEFSYM (Qhash_table_test, "hash-table-test");
4898 DEFSYM (Qkey_or_value, "key-or-value");
4899 DEFSYM (Qkey_and_value, "key-and-value");
d80c6c11
GM
4900
4901 defsubr (&Ssxhash);
4902 defsubr (&Smake_hash_table);
f899c503 4903 defsubr (&Scopy_hash_table);
d80c6c11
GM
4904 defsubr (&Shash_table_count);
4905 defsubr (&Shash_table_rehash_size);
4906 defsubr (&Shash_table_rehash_threshold);
4907 defsubr (&Shash_table_size);
4908 defsubr (&Shash_table_test);
e84b1dea 4909 defsubr (&Shash_table_weakness);
d80c6c11
GM
4910 defsubr (&Shash_table_p);
4911 defsubr (&Sclrhash);
4912 defsubr (&Sgethash);
4913 defsubr (&Sputhash);
4914 defsubr (&Sremhash);
4915 defsubr (&Smaphash);
4916 defsubr (&Sdefine_hash_table_test);
59f953a2 4917
cd3520a4
JB
4918 DEFSYM (Qstring_lessp, "string-lessp");
4919 DEFSYM (Qprovide, "provide");
4920 DEFSYM (Qrequire, "require");
4921 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history");
4922 DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area");
4923 DEFSYM (Qwidget_type, "widget-type");
7b863bd5 4924
09ab3c3b
KH
4925 staticpro (&string_char_byte_cache_string);
4926 string_char_byte_cache_string = Qnil;
4927
1f79789d
RS
4928 require_nesting_list = Qnil;
4929 staticpro (&require_nesting_list);
4930
52a9879b
RS
4931 Fset (Qyes_or_no_p_history, Qnil);
4932
29208e82 4933 DEFVAR_LISP ("features", Vfeatures,
4774b68e 4934 doc: /* A list of symbols which are the features of the executing Emacs.
47cebab1 4935Used by `featurep' and `require', and altered by `provide'. */);
d67b4f80 4936 Vfeatures = Fcons (intern_c_string ("emacs"), Qnil);
cd3520a4 4937 DEFSYM (Qsubfeatures, "subfeatures");
7b863bd5 4938
dec002ca 4939#ifdef HAVE_LANGINFO_CODESET
cd3520a4
JB
4940 DEFSYM (Qcodeset, "codeset");
4941 DEFSYM (Qdays, "days");
4942 DEFSYM (Qmonths, "months");
4943 DEFSYM (Qpaper, "paper");
dec002ca
DL
4944#endif /* HAVE_LANGINFO_CODESET */
4945
29208e82 4946 DEFVAR_BOOL ("use-dialog-box", use_dialog_box,
fb7ada5f 4947 doc: /* Non-nil means mouse commands use dialog boxes to ask questions.
436fa78b 4948This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands
7e861e0d
CY
4949invoked by mouse clicks and mouse menu items.
4950
4951On some platforms, file selection dialogs are also enabled if this is
4952non-nil. */);
bdd8d692
RS
4953 use_dialog_box = 1;
4954
29208e82 4955 DEFVAR_BOOL ("use-file-dialog", use_file_dialog,
fb7ada5f 4956 doc: /* Non-nil means mouse commands use a file dialog to ask for files.
1f1d0797 4957This applies to commands from menus and tool bar buttons even when
2fd0161b
CY
4958they are initiated from the keyboard. If `use-dialog-box' is nil,
4959that disables the use of a file dialog, regardless of the value of
4960this variable. */);
6b61353c
KH
4961 use_file_dialog = 1;
4962
7b863bd5
JB
4963 defsubr (&Sidentity);
4964 defsubr (&Srandom);
4965 defsubr (&Slength);
5a30fab8 4966 defsubr (&Ssafe_length);
026f59ce 4967 defsubr (&Sstring_bytes);
7b863bd5 4968 defsubr (&Sstring_equal);
0e1e9f8d 4969 defsubr (&Scompare_strings);
7b863bd5
JB
4970 defsubr (&Sstring_lessp);
4971 defsubr (&Sappend);
4972 defsubr (&Sconcat);
4973 defsubr (&Svconcat);
4974 defsubr (&Scopy_sequence);
09ab3c3b
KH
4975 defsubr (&Sstring_make_multibyte);
4976 defsubr (&Sstring_make_unibyte);
6d475204
RS
4977 defsubr (&Sstring_as_multibyte);
4978 defsubr (&Sstring_as_unibyte);
2df18cdb 4979 defsubr (&Sstring_to_multibyte);
b4480f16 4980 defsubr (&Sstring_to_unibyte);
7b863bd5
JB
4981 defsubr (&Scopy_alist);
4982 defsubr (&Ssubstring);
aebf4d42 4983 defsubr (&Ssubstring_no_properties);
7b863bd5
JB
4984 defsubr (&Snthcdr);
4985 defsubr (&Snth);
4986 defsubr (&Selt);
4987 defsubr (&Smember);
4988 defsubr (&Smemq);
008ef0ef 4989 defsubr (&Smemql);
7b863bd5
JB
4990 defsubr (&Sassq);
4991 defsubr (&Sassoc);
4992 defsubr (&Srassq);
0fb5a19c 4993 defsubr (&Srassoc);
7b863bd5 4994 defsubr (&Sdelq);
ca8dd546 4995 defsubr (&Sdelete);
7b863bd5
JB
4996 defsubr (&Snreverse);
4997 defsubr (&Sreverse);
4998 defsubr (&Ssort);
be9d483d 4999 defsubr (&Splist_get);
7b863bd5 5000 defsubr (&Sget);
be9d483d 5001 defsubr (&Splist_put);
7b863bd5 5002 defsubr (&Sput);
aebf4d42
RS
5003 defsubr (&Slax_plist_get);
5004 defsubr (&Slax_plist_put);
95f8c3b9 5005 defsubr (&Seql);
7b863bd5 5006 defsubr (&Sequal);
6b61353c 5007 defsubr (&Sequal_including_properties);
7b863bd5 5008 defsubr (&Sfillarray);
85cad579 5009 defsubr (&Sclear_string);
7b863bd5
JB
5010 defsubr (&Snconc);
5011 defsubr (&Smapcar);
5c6740c9 5012 defsubr (&Smapc);
7b863bd5 5013 defsubr (&Smapconcat);
7b863bd5
JB
5014 defsubr (&Syes_or_no_p);
5015 defsubr (&Sload_average);
5016 defsubr (&Sfeaturep);
5017 defsubr (&Srequire);
5018 defsubr (&Sprovide);
a5254817 5019 defsubr (&Splist_member);
b4f334f7
KH
5020 defsubr (&Swidget_put);
5021 defsubr (&Swidget_get);
5022 defsubr (&Swidget_apply);
24c129e4
KH
5023 defsubr (&Sbase64_encode_region);
5024 defsubr (&Sbase64_decode_region);
5025 defsubr (&Sbase64_encode_string);
5026 defsubr (&Sbase64_decode_string);
57916a7a 5027 defsubr (&Smd5);
7f3f739f 5028 defsubr (&Ssecure_hash);
d68beb2f 5029 defsubr (&Slocale_info);
7b863bd5 5030}
d80c6c11
GM
5031
5032
5033void
971de7fb 5034init_fns (void)
d80c6c11 5035{
d80c6c11 5036}