Support higher-resolution time stamps.
[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
d311d28c
PE
3752 h->key_and_value = larger_vector (h->key_and_value,
3753 2 * (new_size - old_size), -1);
3754 h->next = larger_vector (h->next, new_size - old_size, -1);
3755 h->hash = larger_vector (h->hash, new_size - old_size, -1);
d80c6c11
GM
3756 h->index = Fmake_vector (make_number (index_size), Qnil);
3757
3758 /* Update the free list. Do it so that new entries are added at
3759 the end of the free list. This makes some operations like
3760 maphash faster. */
3761 for (i = old_size; i < new_size - 1; ++i)
3762 HASH_NEXT (h, i) = make_number (i + 1);
59f953a2 3763
d80c6c11
GM
3764 if (!NILP (h->next_free))
3765 {
3766 Lisp_Object last, next;
59f953a2 3767
d80c6c11
GM
3768 last = h->next_free;
3769 while (next = HASH_NEXT (h, XFASTINT (last)),
3770 !NILP (next))
3771 last = next;
59f953a2 3772
d80c6c11
GM
3773 HASH_NEXT (h, XFASTINT (last)) = make_number (old_size);
3774 }
3775 else
3776 XSETFASTINT (h->next_free, old_size);
3777
3778 /* Rehash. */
3779 for (i = 0; i < old_size; ++i)
3780 if (!NILP (HASH_HASH (h, i)))
3781 {
0de4bb68 3782 EMACS_UINT hash_code = XUINT (HASH_HASH (h, i));
d311d28c 3783 ptrdiff_t start_of_bucket = hash_code % ASIZE (h->index);
d80c6c11
GM
3784 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3785 HASH_INDEX (h, start_of_bucket) = make_number (i);
3786 }
59f953a2 3787 }
d80c6c11
GM
3788}
3789
3790
3791/* Lookup KEY in hash table H. If HASH is non-null, return in *HASH
3792 the hash code of KEY. Value is the index of the entry in H
3793 matching KEY, or -1 if not found. */
3794
d3411f89 3795ptrdiff_t
0de4bb68 3796hash_lookup (struct Lisp_Hash_Table *h, Lisp_Object key, EMACS_UINT *hash)
d80c6c11 3797{
0de4bb68 3798 EMACS_UINT hash_code;
d3411f89 3799 ptrdiff_t start_of_bucket;
d80c6c11
GM
3800 Lisp_Object idx;
3801
3802 hash_code = h->hashfn (h, key);
3803 if (hash)
3804 *hash = hash_code;
59f953a2 3805
7edbb0da 3806 start_of_bucket = hash_code % ASIZE (h->index);
d80c6c11
GM
3807 idx = HASH_INDEX (h, start_of_bucket);
3808
f5c75033 3809 /* We need not gcpro idx since it's either an integer or nil. */
d80c6c11
GM
3810 while (!NILP (idx))
3811 {
d311d28c 3812 ptrdiff_t i = XFASTINT (idx);
2e5da676
GM
3813 if (EQ (key, HASH_KEY (h, i))
3814 || (h->cmpfn
3815 && h->cmpfn (h, key, hash_code,
7c752c80 3816 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
d80c6c11
GM
3817 break;
3818 idx = HASH_NEXT (h, i);
3819 }
3820
3821 return NILP (idx) ? -1 : XFASTINT (idx);
3822}
3823
3824
3825/* Put an entry into hash table H that associates KEY with VALUE.
64a5094a
KH
3826 HASH is a previously computed hash code of KEY.
3827 Value is the index of the entry in H matching KEY. */
d80c6c11 3828
d3411f89 3829ptrdiff_t
0de4bb68
PE
3830hash_put (struct Lisp_Hash_Table *h, Lisp_Object key, Lisp_Object value,
3831 EMACS_UINT hash)
d80c6c11 3832{
d3411f89 3833 ptrdiff_t start_of_bucket, i;
d80c6c11 3834
6b61353c 3835 xassert ((hash & ~INTMASK) == 0);
d80c6c11
GM
3836
3837 /* Increment count after resizing because resizing may fail. */
3838 maybe_resize_hash_table (h);
878f97ff 3839 h->count++;
59f953a2 3840
d80c6c11
GM
3841 /* Store key/value in the key_and_value vector. */
3842 i = XFASTINT (h->next_free);
3843 h->next_free = HASH_NEXT (h, i);
3844 HASH_KEY (h, i) = key;
3845 HASH_VALUE (h, i) = value;
3846
3847 /* Remember its hash code. */
3848 HASH_HASH (h, i) = make_number (hash);
3849
3850 /* Add new entry to its collision chain. */
7edbb0da 3851 start_of_bucket = hash % ASIZE (h->index);
d80c6c11
GM
3852 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
3853 HASH_INDEX (h, start_of_bucket) = make_number (i);
64a5094a 3854 return i;
d80c6c11
GM
3855}
3856
3857
3858/* Remove the entry matching KEY from hash table H, if there is one. */
3859
2749d28e 3860static void
971de7fb 3861hash_remove_from_table (struct Lisp_Hash_Table *h, Lisp_Object key)
d80c6c11 3862{
0de4bb68 3863 EMACS_UINT hash_code;
d311d28c 3864 ptrdiff_t start_of_bucket;
d80c6c11
GM
3865 Lisp_Object idx, prev;
3866
3867 hash_code = h->hashfn (h, key);
7edbb0da 3868 start_of_bucket = hash_code % ASIZE (h->index);
d80c6c11
GM
3869 idx = HASH_INDEX (h, start_of_bucket);
3870 prev = Qnil;
3871
f5c75033 3872 /* We need not gcpro idx, prev since they're either integers or nil. */
d80c6c11
GM
3873 while (!NILP (idx))
3874 {
d311d28c 3875 ptrdiff_t i = XFASTINT (idx);
d80c6c11 3876
2e5da676
GM
3877 if (EQ (key, HASH_KEY (h, i))
3878 || (h->cmpfn
3879 && h->cmpfn (h, key, hash_code,
7c752c80 3880 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
d80c6c11
GM
3881 {
3882 /* Take entry out of collision chain. */
3883 if (NILP (prev))
3884 HASH_INDEX (h, start_of_bucket) = HASH_NEXT (h, i);
3885 else
3886 HASH_NEXT (h, XFASTINT (prev)) = HASH_NEXT (h, i);
3887
3888 /* Clear slots in key_and_value and add the slots to
3889 the free list. */
3890 HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil;
3891 HASH_NEXT (h, i) = h->next_free;
3892 h->next_free = make_number (i);
878f97ff
SM
3893 h->count--;
3894 xassert (h->count >= 0);
d80c6c11
GM
3895 break;
3896 }
3897 else
3898 {
3899 prev = idx;
3900 idx = HASH_NEXT (h, i);
3901 }
3902 }
3903}
3904
3905
3906/* Clear hash table H. */
3907
2f7c71a1 3908static void
971de7fb 3909hash_clear (struct Lisp_Hash_Table *h)
d80c6c11 3910{
878f97ff 3911 if (h->count > 0)
d80c6c11 3912 {
d311d28c 3913 ptrdiff_t i, size = HASH_TABLE_SIZE (h);
d80c6c11
GM
3914
3915 for (i = 0; i < size; ++i)
3916 {
3917 HASH_NEXT (h, i) = i < size - 1 ? make_number (i + 1) : Qnil;
3918 HASH_KEY (h, i) = Qnil;
3919 HASH_VALUE (h, i) = Qnil;
3920 HASH_HASH (h, i) = Qnil;
3921 }
3922
7edbb0da 3923 for (i = 0; i < ASIZE (h->index); ++i)
68b587a6 3924 ASET (h->index, i, Qnil);
d80c6c11
GM
3925
3926 h->next_free = make_number (0);
878f97ff 3927 h->count = 0;
d80c6c11
GM
3928 }
3929}
3930
3931
3932\f
3933/************************************************************************
3934 Weak Hash Tables
3935 ************************************************************************/
3936
14067ea7 3937void
971de7fb 3938init_weak_hash_tables (void)
14067ea7
CY
3939{
3940 weak_hash_tables = NULL;
3941}
3942
a0b581cc
GM
3943/* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove
3944 entries from the table that don't survive the current GC.
3945 REMOVE_ENTRIES_P zero means mark entries that are in use. Value is
3946 non-zero if anything was marked. */
3947
3948static int
971de7fb 3949sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p)
a0b581cc 3950{
d311d28c 3951 ptrdiff_t bucket, n;
0de4bb68 3952 int marked;
59f953a2 3953
7edbb0da 3954 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG;
a0b581cc 3955 marked = 0;
59f953a2 3956
a0b581cc
GM
3957 for (bucket = 0; bucket < n; ++bucket)
3958 {
1e546714 3959 Lisp_Object idx, next, prev;
a0b581cc
GM
3960
3961 /* Follow collision chain, removing entries that
3962 don't survive this garbage collection. */
a0b581cc 3963 prev = Qnil;
8e50cc2d 3964 for (idx = HASH_INDEX (h, bucket); !NILP (idx); idx = next)
a0b581cc 3965 {
d311d28c 3966 ptrdiff_t i = XFASTINT (idx);
1e546714
GM
3967 int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
3968 int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
3969 int remove_p;
59f953a2 3970
a0b581cc 3971 if (EQ (h->weak, Qkey))
aee625fa 3972 remove_p = !key_known_to_survive_p;
a0b581cc 3973 else if (EQ (h->weak, Qvalue))
aee625fa 3974 remove_p = !value_known_to_survive_p;
ec504e6f 3975 else if (EQ (h->weak, Qkey_or_value))
728c5d9d 3976 remove_p = !(key_known_to_survive_p || value_known_to_survive_p);
ec504e6f 3977 else if (EQ (h->weak, Qkey_and_value))
728c5d9d 3978 remove_p = !(key_known_to_survive_p && value_known_to_survive_p);
a0b581cc
GM
3979 else
3980 abort ();
59f953a2 3981
a0b581cc
GM
3982 next = HASH_NEXT (h, i);
3983
3984 if (remove_entries_p)
3985 {
3986 if (remove_p)
3987 {
3988 /* Take out of collision chain. */
8e50cc2d 3989 if (NILP (prev))
1e546714 3990 HASH_INDEX (h, bucket) = next;
a0b581cc
GM
3991 else
3992 HASH_NEXT (h, XFASTINT (prev)) = next;
59f953a2 3993
a0b581cc
GM
3994 /* Add to free list. */
3995 HASH_NEXT (h, i) = h->next_free;
3996 h->next_free = idx;
59f953a2 3997
a0b581cc
GM
3998 /* Clear key, value, and hash. */
3999 HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil;
4000 HASH_HASH (h, i) = Qnil;
59f953a2 4001
878f97ff 4002 h->count--;
a0b581cc 4003 }
d278cde0
KS
4004 else
4005 {
4006 prev = idx;
4007 }
a0b581cc
GM
4008 }
4009 else
4010 {
4011 if (!remove_p)
4012 {
4013 /* Make sure key and value survive. */
aee625fa
GM
4014 if (!key_known_to_survive_p)
4015 {
9568e3d8 4016 mark_object (HASH_KEY (h, i));
aee625fa
GM
4017 marked = 1;
4018 }
4019
4020 if (!value_known_to_survive_p)
4021 {
9568e3d8 4022 mark_object (HASH_VALUE (h, i));
aee625fa
GM
4023 marked = 1;
4024 }
a0b581cc
GM
4025 }
4026 }
a0b581cc
GM
4027 }
4028 }
4029
4030 return marked;
4031}
4032
d80c6c11
GM
4033/* Remove elements from weak hash tables that don't survive the
4034 current garbage collection. Remove weak tables that don't survive
4035 from Vweak_hash_tables. Called from gc_sweep. */
4036
4037void
971de7fb 4038sweep_weak_hash_tables (void)
d80c6c11 4039{
6c661ec9 4040 struct Lisp_Hash_Table *h, *used, *next;
a0b581cc
GM
4041 int marked;
4042
4043 /* Mark all keys and values that are in use. Keep on marking until
4044 there is no more change. This is necessary for cases like
4045 value-weak table A containing an entry X -> Y, where Y is used in a
4046 key-weak table B, Z -> Y. If B comes after A in the list of weak
4047 tables, X -> Y might be removed from A, although when looking at B
4048 one finds that it shouldn't. */
4049 do
4050 {
4051 marked = 0;
6c661ec9 4052 for (h = weak_hash_tables; h; h = h->next_weak)
a0b581cc 4053 {
eab3844f 4054 if (h->header.size & ARRAY_MARK_FLAG)
a0b581cc
GM
4055 marked |= sweep_weak_table (h, 0);
4056 }
4057 }
4058 while (marked);
d80c6c11 4059
a0b581cc 4060 /* Remove tables and entries that aren't used. */
6c661ec9 4061 for (h = weak_hash_tables, used = NULL; h; h = next)
d80c6c11 4062 {
ac0e96ee 4063 next = h->next_weak;
91f78c99 4064
eab3844f 4065 if (h->header.size & ARRAY_MARK_FLAG)
d80c6c11 4066 {
ac0e96ee 4067 /* TABLE is marked as used. Sweep its contents. */
878f97ff 4068 if (h->count > 0)
a0b581cc 4069 sweep_weak_table (h, 1);
ac0e96ee
GM
4070
4071 /* Add table to the list of used weak hash tables. */
4072 h->next_weak = used;
6c661ec9 4073 used = h;
d80c6c11
GM
4074 }
4075 }
ac0e96ee 4076
6c661ec9 4077 weak_hash_tables = used;
d80c6c11
GM
4078}
4079
4080
4081\f
4082/***********************************************************************
4083 Hash Code Computation
4084 ***********************************************************************/
4085
4086/* Maximum depth up to which to dive into Lisp structures. */
4087
4088#define SXHASH_MAX_DEPTH 3
4089
4090/* Maximum length up to which to take list and vector elements into
4091 account. */
4092
4093#define SXHASH_MAX_LEN 7
4094
0de4bb68
PE
4095/* Combine two integers X and Y for hashing. The result might not fit
4096 into a Lisp integer. */
d80c6c11
GM
4097
4098#define SXHASH_COMBINE(X, Y) \
0de4bb68
PE
4099 ((((EMACS_UINT) (X) << 4) + ((EMACS_UINT) (X) >> (BITS_PER_EMACS_INT - 4))) \
4100 + (EMACS_UINT) (Y))
d80c6c11 4101
0de4bb68
PE
4102/* Hash X, returning a value that fits into a Lisp integer. */
4103#define SXHASH_REDUCE(X) \
4104 ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
d80c6c11 4105
3cc5a532
PE
4106/* Return a hash for string PTR which has length LEN. The hash value
4107 can be any EMACS_UINT value. */
d80c6c11 4108
3cc5a532
PE
4109EMACS_UINT
4110hash_string (char const *ptr, ptrdiff_t len)
d80c6c11 4111{
3cc5a532
PE
4112 char const *p = ptr;
4113 char const *end = p + len;
d80c6c11 4114 unsigned char c;
0de4bb68 4115 EMACS_UINT hash = 0;
d80c6c11
GM
4116
4117 while (p != end)
4118 {
4119 c = *p++;
0de4bb68 4120 hash = SXHASH_COMBINE (hash, c);
d80c6c11 4121 }
59f953a2 4122
3cc5a532
PE
4123 return hash;
4124}
4125
4126/* Return a hash for string PTR which has length LEN. The hash
4127 code returned is guaranteed to fit in a Lisp integer. */
4128
4129static EMACS_UINT
4130sxhash_string (char const *ptr, ptrdiff_t len)
4131{
4132 EMACS_UINT hash = hash_string (ptr, len);
0de4bb68 4133 return SXHASH_REDUCE (hash);
d80c6c11
GM
4134}
4135
0de4bb68
PE
4136/* Return a hash for the floating point value VAL. */
4137
4138static EMACS_INT
4139sxhash_float (double val)
4140{
4141 EMACS_UINT hash = 0;
4142 enum {
4143 WORDS_PER_DOUBLE = (sizeof val / sizeof hash
4144 + (sizeof val % sizeof hash != 0))
4145 };
4146 union {
4147 double val;
4148 EMACS_UINT word[WORDS_PER_DOUBLE];
4149 } u;
4150 int i;
4151 u.val = val;
4152 memset (&u.val + 1, 0, sizeof u - sizeof u.val);
4153 for (i = 0; i < WORDS_PER_DOUBLE; i++)
4154 hash = SXHASH_COMBINE (hash, u.word[i]);
4155 return SXHASH_REDUCE (hash);
4156}
d80c6c11
GM
4157
4158/* Return a hash for list LIST. DEPTH is the current depth in the
4159 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
4160
0de4bb68 4161static EMACS_UINT
971de7fb 4162sxhash_list (Lisp_Object list, int depth)
d80c6c11 4163{
0de4bb68 4164 EMACS_UINT hash = 0;
d80c6c11 4165 int i;
59f953a2 4166
d80c6c11
GM
4167 if (depth < SXHASH_MAX_DEPTH)
4168 for (i = 0;
4169 CONSP (list) && i < SXHASH_MAX_LEN;
4170 list = XCDR (list), ++i)
4171 {
0de4bb68 4172 EMACS_UINT hash2 = sxhash (XCAR (list), depth + 1);
d80c6c11
GM
4173 hash = SXHASH_COMBINE (hash, hash2);
4174 }
4175
ea284f33
KS
4176 if (!NILP (list))
4177 {
0de4bb68 4178 EMACS_UINT hash2 = sxhash (list, depth + 1);
ea284f33
KS
4179 hash = SXHASH_COMBINE (hash, hash2);
4180 }
4181
0de4bb68 4182 return SXHASH_REDUCE (hash);
d80c6c11
GM
4183}
4184
4185
4186/* Return a hash for vector VECTOR. DEPTH is the current depth in
4187 the Lisp structure. */
4188
0de4bb68 4189static EMACS_UINT
971de7fb 4190sxhash_vector (Lisp_Object vec, int depth)
d80c6c11 4191{
0de4bb68 4192 EMACS_UINT hash = ASIZE (vec);
d80c6c11
GM
4193 int i, n;
4194
7edbb0da 4195 n = min (SXHASH_MAX_LEN, ASIZE (vec));
d80c6c11
GM
4196 for (i = 0; i < n; ++i)
4197 {
0de4bb68 4198 EMACS_UINT hash2 = sxhash (AREF (vec, i), depth + 1);
d80c6c11
GM
4199 hash = SXHASH_COMBINE (hash, hash2);
4200 }
4201
0de4bb68 4202 return SXHASH_REDUCE (hash);
d80c6c11
GM
4203}
4204
d80c6c11
GM
4205/* Return a hash for bool-vector VECTOR. */
4206
0de4bb68 4207static EMACS_UINT
971de7fb 4208sxhash_bool_vector (Lisp_Object vec)
d80c6c11 4209{
0de4bb68 4210 EMACS_UINT hash = XBOOL_VECTOR (vec)->size;
d80c6c11
GM
4211 int i, n;
4212
eab3844f 4213 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->header.size);
d80c6c11
GM
4214 for (i = 0; i < n; ++i)
4215 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
4216
0de4bb68 4217 return SXHASH_REDUCE (hash);
d80c6c11
GM
4218}
4219
4220
4221/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
6b61353c 4222 structure. Value is an unsigned integer clipped to INTMASK. */
d80c6c11 4223
0de4bb68 4224EMACS_UINT
971de7fb 4225sxhash (Lisp_Object obj, int depth)
d80c6c11 4226{
0de4bb68 4227 EMACS_UINT hash;
d80c6c11
GM
4228
4229 if (depth > SXHASH_MAX_DEPTH)
4230 return 0;
59f953a2 4231
d80c6c11
GM
4232 switch (XTYPE (obj))
4233 {
2de9f71c 4234 case_Lisp_Int:
d80c6c11
GM
4235 hash = XUINT (obj);
4236 break;
4237
d80c6c11
GM
4238 case Lisp_Misc:
4239 hash = XUINT (obj);
4240 break;
4241
32bfb2d5
EZ
4242 case Lisp_Symbol:
4243 obj = SYMBOL_NAME (obj);
4244 /* Fall through. */
4245
d80c6c11 4246 case Lisp_String:
3cc5a532 4247 hash = sxhash_string (SSDATA (obj), SBYTES (obj));
d80c6c11
GM
4248 break;
4249
4250 /* This can be everything from a vector to an overlay. */
4251 case Lisp_Vectorlike:
4252 if (VECTORP (obj))
4253 /* According to the CL HyperSpec, two arrays are equal only if
4254 they are `eq', except for strings and bit-vectors. In
4255 Emacs, this works differently. We have to compare element
4256 by element. */
4257 hash = sxhash_vector (obj, depth);
4258 else if (BOOL_VECTOR_P (obj))
4259 hash = sxhash_bool_vector (obj);
4260 else
4261 /* Others are `equal' if they are `eq', so let's take their
4262 address as hash. */
4263 hash = XUINT (obj);
4264 break;
4265
4266 case Lisp_Cons:
4267 hash = sxhash_list (obj, depth);
4268 break;
4269
4270 case Lisp_Float:
0de4bb68
PE
4271 hash = sxhash_float (XFLOAT_DATA (obj));
4272 break;
d80c6c11
GM
4273
4274 default:
4275 abort ();
4276 }
4277
0de4bb68 4278 return hash;
d80c6c11
GM
4279}
4280
4281
4282\f
4283/***********************************************************************
4284 Lisp Interface
4285 ***********************************************************************/
4286
4287
4288DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
e9d8ddc9 4289 doc: /* Compute a hash code for OBJ and return it as integer. */)
5842a27b 4290 (Lisp_Object obj)
d80c6c11 4291{
0de4bb68 4292 EMACS_UINT hash = sxhash (obj, 0);
d80c6c11
GM
4293 return make_number (hash);
4294}
4295
4296
a7ca3326 4297DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
e9d8ddc9 4298 doc: /* Create and return a new hash table.
91f78c99 4299
47cebab1
GM
4300Arguments are specified as keyword/argument pairs. The following
4301arguments are defined:
4302
4303:test TEST -- TEST must be a symbol that specifies how to compare
4304keys. Default is `eql'. Predefined are the tests `eq', `eql', and
4305`equal'. User-supplied test and hash functions can be specified via
4306`define-hash-table-test'.
4307
4308:size SIZE -- A hint as to how many elements will be put in the table.
4309Default is 65.
4310
4311:rehash-size REHASH-SIZE - Indicates how to expand the table when it
79d6f59e
CY
4312fills up. If REHASH-SIZE is an integer, increase the size by that
4313amount. If it is a float, it must be > 1.0, and the new size is the
4314old size multiplied by that factor. Default is 1.5.
47cebab1
GM
4315
4316:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
b756c005 4317Resize the hash table when the ratio (number of entries / table size)
e1025755 4318is greater than or equal to THRESHOLD. Default is 0.8.
47cebab1
GM
4319
4320:weakness WEAK -- WEAK must be one of nil, t, `key', `value',
4321`key-or-value', or `key-and-value'. If WEAK is not nil, the table
4322returned is a weak table. Key/value pairs are removed from a weak
4323hash table when there are no non-weak references pointing to their
4324key, value, one of key or value, or both key and value, depending on
4325WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK
4bf8e2a3
MB
4326is nil.
4327
4328usage: (make-hash-table &rest KEYWORD-ARGS) */)
f66c7cf8 4329 (ptrdiff_t nargs, Lisp_Object *args)
d80c6c11
GM
4330{
4331 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4332 Lisp_Object user_test, user_hash;
4333 char *used;
f66c7cf8 4334 ptrdiff_t i;
d80c6c11
GM
4335
4336 /* The vector `used' is used to keep track of arguments that
4337 have been consumed. */
4338 used = (char *) alloca (nargs * sizeof *used);
72af86bd 4339 memset (used, 0, nargs * sizeof *used);
d80c6c11
GM
4340
4341 /* See if there's a `:test TEST' among the arguments. */
4342 i = get_key_arg (QCtest, nargs, args, used);
c5101a77 4343 test = i ? args[i] : Qeql;
d80c6c11
GM
4344 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal))
4345 {
4346 /* See if it is a user-defined test. */
4347 Lisp_Object prop;
59f953a2 4348
d80c6c11 4349 prop = Fget (test, Qhash_table_test);
c1dd95fc 4350 if (!CONSP (prop) || !CONSP (XCDR (prop)))
692ae65c 4351 signal_error ("Invalid hash table test", test);
c1dd95fc
RS
4352 user_test = XCAR (prop);
4353 user_hash = XCAR (XCDR (prop));
d80c6c11
GM
4354 }
4355 else
4356 user_test = user_hash = Qnil;
4357
4358 /* See if there's a `:size SIZE' argument. */
4359 i = get_key_arg (QCsize, nargs, args, used);
c5101a77 4360 size = i ? args[i] : Qnil;
cf42cb72
SM
4361 if (NILP (size))
4362 size = make_number (DEFAULT_HASH_SIZE);
4363 else if (!INTEGERP (size) || XINT (size) < 0)
692ae65c 4364 signal_error ("Invalid hash table size", size);
d80c6c11
GM
4365
4366 /* Look for `:rehash-size SIZE'. */
4367 i = get_key_arg (QCrehash_size, nargs, args, used);
c5101a77 4368 rehash_size = i ? args[i] : make_float (DEFAULT_REHASH_SIZE);
0de4bb68
PE
4369 if (! ((INTEGERP (rehash_size) && 0 < XINT (rehash_size))
4370 || (FLOATP (rehash_size) && 1 < XFLOAT_DATA (rehash_size))))
692ae65c 4371 signal_error ("Invalid hash table rehash size", rehash_size);
59f953a2 4372
d80c6c11
GM
4373 /* Look for `:rehash-threshold THRESHOLD'. */
4374 i = get_key_arg (QCrehash_threshold, nargs, args, used);
c5101a77 4375 rehash_threshold = i ? args[i] : make_float (DEFAULT_REHASH_THRESHOLD);
0de4bb68
PE
4376 if (! (FLOATP (rehash_threshold)
4377 && 0 < XFLOAT_DATA (rehash_threshold)
4378 && XFLOAT_DATA (rehash_threshold) <= 1))
692ae65c 4379 signal_error ("Invalid hash table rehash threshold", rehash_threshold);
59f953a2 4380
ee0403b3
GM
4381 /* Look for `:weakness WEAK'. */
4382 i = get_key_arg (QCweakness, nargs, args, used);
c5101a77 4383 weak = i ? args[i] : Qnil;
ec504e6f
GM
4384 if (EQ (weak, Qt))
4385 weak = Qkey_and_value;
d80c6c11 4386 if (!NILP (weak)
f899c503 4387 && !EQ (weak, Qkey)
ec504e6f
GM
4388 && !EQ (weak, Qvalue)
4389 && !EQ (weak, Qkey_or_value)
4390 && !EQ (weak, Qkey_and_value))
692ae65c 4391 signal_error ("Invalid hash table weakness", weak);
59f953a2 4392
d80c6c11
GM
4393 /* Now, all args should have been used up, or there's a problem. */
4394 for (i = 0; i < nargs; ++i)
4395 if (!used[i])
692ae65c 4396 signal_error ("Invalid argument list", args[i]);
d80c6c11
GM
4397
4398 return make_hash_table (test, size, rehash_size, rehash_threshold, weak,
4399 user_test, user_hash);
4400}
4401
4402
f899c503 4403DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
e9d8ddc9 4404 doc: /* Return a copy of hash table TABLE. */)
5842a27b 4405 (Lisp_Object table)
f899c503
GM
4406{
4407 return copy_hash_table (check_hash_table (table));
4408}
4409
4410
d80c6c11 4411DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
e9d8ddc9 4412 doc: /* Return the number of elements in TABLE. */)
5842a27b 4413 (Lisp_Object table)
d80c6c11 4414{
878f97ff 4415 return make_number (check_hash_table (table)->count);
d80c6c11
GM
4416}
4417
59f953a2 4418
d80c6c11
GM
4419DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
4420 Shash_table_rehash_size, 1, 1, 0,
e9d8ddc9 4421 doc: /* Return the current rehash size of TABLE. */)
5842a27b 4422 (Lisp_Object table)
d80c6c11
GM
4423{
4424 return check_hash_table (table)->rehash_size;
4425}
59f953a2 4426
d80c6c11
GM
4427
4428DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold,
4429 Shash_table_rehash_threshold, 1, 1, 0,
e9d8ddc9 4430 doc: /* Return the current rehash threshold of TABLE. */)
5842a27b 4431 (Lisp_Object table)
d80c6c11
GM
4432{
4433 return check_hash_table (table)->rehash_threshold;
4434}
59f953a2 4435
d80c6c11
GM
4436
4437DEFUN ("hash-table-size", Fhash_table_size, Shash_table_size, 1, 1, 0,
e9d8ddc9 4438 doc: /* Return the size of TABLE.
47cebab1 4439The size can be used as an argument to `make-hash-table' to create
b756c005 4440a hash table than can hold as many elements as TABLE holds
e9d8ddc9 4441without need for resizing. */)
5842a27b 4442 (Lisp_Object table)
d80c6c11
GM
4443{
4444 struct Lisp_Hash_Table *h = check_hash_table (table);
4445 return make_number (HASH_TABLE_SIZE (h));
4446}
59f953a2 4447
d80c6c11
GM
4448
4449DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
e9d8ddc9 4450 doc: /* Return the test TABLE uses. */)
5842a27b 4451 (Lisp_Object table)
d80c6c11
GM
4452{
4453 return check_hash_table (table)->test;
4454}
4455
59f953a2 4456
e84b1dea
GM
4457DEFUN ("hash-table-weakness", Fhash_table_weakness, Shash_table_weakness,
4458 1, 1, 0,
e9d8ddc9 4459 doc: /* Return the weakness of TABLE. */)
5842a27b 4460 (Lisp_Object table)
d80c6c11
GM
4461{
4462 return check_hash_table (table)->weak;
4463}
4464
59f953a2 4465
d80c6c11 4466DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
e9d8ddc9 4467 doc: /* Return t if OBJ is a Lisp hash table object. */)
5842a27b 4468 (Lisp_Object obj)
d80c6c11
GM
4469{
4470 return HASH_TABLE_P (obj) ? Qt : Qnil;
4471}
4472
4473
4474DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
ccd8f7fe 4475 doc: /* Clear hash table TABLE and return it. */)
5842a27b 4476 (Lisp_Object table)
d80c6c11
GM
4477{
4478 hash_clear (check_hash_table (table));
ccd8f7fe
TTN
4479 /* Be compatible with XEmacs. */
4480 return table;
d80c6c11
GM
4481}
4482
4483
a7ca3326 4484DEFUN ("gethash", Fgethash, Sgethash, 2, 3, 0,
e9d8ddc9
MB
4485 doc: /* Look up KEY in TABLE and return its associated value.
4486If KEY is not found, return DFLT which defaults to nil. */)
5842a27b 4487 (Lisp_Object key, Lisp_Object table, Lisp_Object dflt)
d80c6c11
GM
4488{
4489 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4490 ptrdiff_t i = hash_lookup (h, key, NULL);
d80c6c11
GM
4491 return i >= 0 ? HASH_VALUE (h, i) : dflt;
4492}
4493
4494
a7ca3326 4495DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
e9d8ddc9 4496 doc: /* Associate KEY with VALUE in hash table TABLE.
47cebab1 4497If KEY is already present in table, replace its current value with
a54e3482 4498VALUE. In any case, return VALUE. */)
5842a27b 4499 (Lisp_Object key, Lisp_Object value, Lisp_Object table)
d80c6c11
GM
4500{
4501 struct Lisp_Hash_Table *h = check_hash_table (table);
d3411f89 4502 ptrdiff_t i;
0de4bb68 4503 EMACS_UINT hash;
d80c6c11
GM
4504
4505 i = hash_lookup (h, key, &hash);
4506 if (i >= 0)
4507 HASH_VALUE (h, i) = value;
4508 else
4509 hash_put (h, key, value, hash);
59f953a2 4510
d9c4f922 4511 return value;
d80c6c11
GM
4512}
4513
4514
a7ca3326 4515DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
e9d8ddc9 4516 doc: /* Remove KEY from TABLE. */)
5842a27b 4517 (Lisp_Object key, Lisp_Object table)
d80c6c11
GM
4518{
4519 struct Lisp_Hash_Table *h = check_hash_table (table);
5a2d7ab6 4520 hash_remove_from_table (h, key);
d80c6c11
GM
4521 return Qnil;
4522}
4523
4524
4525DEFUN ("maphash", Fmaphash, Smaphash, 2, 2, 0,
e9d8ddc9 4526 doc: /* Call FUNCTION for all entries in hash table TABLE.
c14ec135 4527FUNCTION is called with two arguments, KEY and VALUE. */)
5842a27b 4528 (Lisp_Object function, Lisp_Object table)
d80c6c11
GM
4529{
4530 struct Lisp_Hash_Table *h = check_hash_table (table);
4531 Lisp_Object args[3];
d311d28c 4532 ptrdiff_t i;
d80c6c11
GM
4533
4534 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
4535 if (!NILP (HASH_HASH (h, i)))
4536 {
4537 args[0] = function;
4538 args[1] = HASH_KEY (h, i);
4539 args[2] = HASH_VALUE (h, i);
4540 Ffuncall (3, args);
4541 }
59f953a2 4542
d80c6c11
GM
4543 return Qnil;
4544}
4545
4546
4547DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
4548 Sdefine_hash_table_test, 3, 3, 0,
e9d8ddc9 4549 doc: /* Define a new hash table test with name NAME, a symbol.
91f78c99 4550
47cebab1
GM
4551In hash tables created with NAME specified as test, use TEST to
4552compare keys, and HASH for computing hash codes of keys.
4553
4554TEST must be a function taking two arguments and returning non-nil if
4555both arguments are the same. HASH must be a function taking one
4556argument and return an integer that is the hash code of the argument.
4557Hash code computation should use the whole value range of integers,
e9d8ddc9 4558including negative integers. */)
5842a27b 4559 (Lisp_Object name, Lisp_Object test, Lisp_Object hash)
d80c6c11
GM
4560{
4561 return Fput (name, Qhash_table_test, list2 (test, hash));
4562}
4563
a3b210c4 4564
57916a7a 4565\f
5c302da4 4566/************************************************************************
7f3f739f 4567 MD5, SHA-1, and SHA-2
5c302da4
GM
4568 ************************************************************************/
4569
57916a7a 4570#include "md5.h"
e1b90ef6 4571#include "sha1.h"
7f3f739f
LL
4572#include "sha256.h"
4573#include "sha512.h"
57916a7a 4574
7f3f739f 4575/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
47cebab1 4576
f1b54466 4577static Lisp_Object
7f3f739f 4578secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object binary)
57916a7a 4579{
57916a7a 4580 int i;
d311d28c 4581 ptrdiff_t size;
e6d4aefa 4582 EMACS_INT start_char = 0, end_char = 0;
d311d28c 4583 ptrdiff_t start_byte, end_byte;
e6d4aefa 4584 register EMACS_INT b, e;
57916a7a 4585 register struct buffer *bp;
e6d4aefa 4586 EMACS_INT temp;
7f3f739f
LL
4587 int digest_size;
4588 void *(*hash_func) (const char *, size_t, void *);
4589 Lisp_Object digest;
4590
4591 CHECK_SYMBOL (algorithm);
57916a7a 4592
5c302da4 4593 if (STRINGP (object))
57916a7a
GM
4594 {
4595 if (NILP (coding_system))
4596 {
5c302da4 4597 /* Decide the coding-system to encode the data with. */
57916a7a 4598
5c302da4
GM
4599 if (STRING_MULTIBYTE (object))
4600 /* use default, we can't guess correct value */
38583a69 4601 coding_system = preferred_coding_system ();
91f78c99 4602 else
5c302da4 4603 coding_system = Qraw_text;
57916a7a 4604 }
91f78c99 4605
5c302da4 4606 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4607 {
5c302da4 4608 /* Invalid coding system. */
91f78c99 4609
5c302da4
GM
4610 if (!NILP (noerror))
4611 coding_system = Qraw_text;
4612 else
692ae65c 4613 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4614 }
4615
5c302da4 4616 if (STRING_MULTIBYTE (object))
38583a69 4617 object = code_convert_string (object, coding_system, Qnil, 1, 0, 1);
5c302da4 4618
d5db4077 4619 size = SCHARS (object);
57916a7a
GM
4620
4621 if (!NILP (start))
4622 {
b7826503 4623 CHECK_NUMBER (start);
57916a7a
GM
4624
4625 start_char = XINT (start);
4626
4627 if (start_char < 0)
4628 start_char += size;
57916a7a
GM
4629 }
4630
4631 if (NILP (end))
d311d28c 4632 end_char = size;
57916a7a
GM
4633 else
4634 {
b7826503 4635 CHECK_NUMBER (end);
91f78c99 4636
57916a7a
GM
4637 end_char = XINT (end);
4638
4639 if (end_char < 0)
4640 end_char += size;
57916a7a 4641 }
91f78c99 4642
57916a7a
GM
4643 if (!(0 <= start_char && start_char <= end_char && end_char <= size))
4644 args_out_of_range_3 (object, make_number (start_char),
4645 make_number (end_char));
d311d28c
PE
4646
4647 start_byte = NILP (start) ? 0 : string_char_to_byte (object, start_char);
4648 end_byte =
4649 NILP (end) ? SBYTES (object) : string_char_to_byte (object, end_char);
57916a7a
GM
4650 }
4651 else
4652 {
6b61353c
KH
4653 struct buffer *prev = current_buffer;
4654
4655 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
4656
b7826503 4657 CHECK_BUFFER (object);
57916a7a
GM
4658
4659 bp = XBUFFER (object);
6b61353c
KH
4660 if (bp != current_buffer)
4661 set_buffer_internal (bp);
91f78c99 4662
57916a7a 4663 if (NILP (start))
6b61353c 4664 b = BEGV;
57916a7a
GM
4665 else
4666 {
b7826503 4667 CHECK_NUMBER_COERCE_MARKER (start);
57916a7a
GM
4668 b = XINT (start);
4669 }
4670
4671 if (NILP (end))
6b61353c 4672 e = ZV;
57916a7a
GM
4673 else
4674 {
b7826503 4675 CHECK_NUMBER_COERCE_MARKER (end);
57916a7a
GM
4676 e = XINT (end);
4677 }
91f78c99 4678
57916a7a
GM
4679 if (b > e)
4680 temp = b, b = e, e = temp;
91f78c99 4681
6b61353c 4682 if (!(BEGV <= b && e <= ZV))
57916a7a 4683 args_out_of_range (start, end);
91f78c99 4684
57916a7a
GM
4685 if (NILP (coding_system))
4686 {
91f78c99 4687 /* Decide the coding-system to encode the data with.
5c302da4
GM
4688 See fileio.c:Fwrite-region */
4689
4690 if (!NILP (Vcoding_system_for_write))
4691 coding_system = Vcoding_system_for_write;
4692 else
4693 {
4694 int force_raw_text = 0;
4695
4b4deea2 4696 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4697 if (NILP (coding_system)
4698 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
4699 {
4700 coding_system = Qnil;
4b4deea2 4701 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
5c302da4
GM
4702 force_raw_text = 1;
4703 }
4704
5e617bc2 4705 if (NILP (coding_system) && !NILP (Fbuffer_file_name (object)))
5c302da4
GM
4706 {
4707 /* Check file-coding-system-alist. */
4708 Lisp_Object args[4], val;
91f78c99 4709
5c302da4 4710 args[0] = Qwrite_region; args[1] = start; args[2] = end;
5e617bc2 4711 args[3] = Fbuffer_file_name (object);
5c302da4
GM
4712 val = Ffind_operation_coding_system (4, args);
4713 if (CONSP (val) && !NILP (XCDR (val)))
4714 coding_system = XCDR (val);
4715 }
4716
4717 if (NILP (coding_system)
4b4deea2 4718 && !NILP (BVAR (XBUFFER (object), buffer_file_coding_system)))
5c302da4
GM
4719 {
4720 /* If we still have not decided a coding system, use the
4721 default value of buffer-file-coding-system. */
4b4deea2 4722 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
5c302da4
GM
4723 }
4724
4725 if (!force_raw_text
4726 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
4727 /* Confirm that VAL can surely encode the current region. */
1e59646d 4728 coding_system = call4 (Vselect_safe_coding_system_function,
70da6a76 4729 make_number (b), make_number (e),
1e59646d 4730 coding_system, Qnil);
5c302da4
GM
4731
4732 if (force_raw_text)
4733 coding_system = Qraw_text;
4734 }
4735
4736 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 4737 {
5c302da4
GM
4738 /* Invalid coding system. */
4739
4740 if (!NILP (noerror))
4741 coding_system = Qraw_text;
4742 else
692ae65c 4743 xsignal1 (Qcoding_system_error, coding_system);
57916a7a
GM
4744 }
4745 }
4746
4747 object = make_buffer_string (b, e, 0);
6b61353c
KH
4748 if (prev != current_buffer)
4749 set_buffer_internal (prev);
4750 /* Discard the unwind protect for recovering the current
4751 buffer. */
4752 specpdl_ptr--;
57916a7a
GM
4753
4754 if (STRING_MULTIBYTE (object))
8f924df7 4755 object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
d311d28c
PE
4756 start_byte = 0;
4757 end_byte = SBYTES (object);
57916a7a
GM
4758 }
4759
7f3f739f 4760 if (EQ (algorithm, Qmd5))
e1b90ef6 4761 {
7f3f739f
LL
4762 digest_size = MD5_DIGEST_SIZE;
4763 hash_func = md5_buffer;
4764 }
4765 else if (EQ (algorithm, Qsha1))
4766 {
4767 digest_size = SHA1_DIGEST_SIZE;
4768 hash_func = sha1_buffer;
4769 }
4770 else if (EQ (algorithm, Qsha224))
4771 {
4772 digest_size = SHA224_DIGEST_SIZE;
4773 hash_func = sha224_buffer;
4774 }
4775 else if (EQ (algorithm, Qsha256))
4776 {
4777 digest_size = SHA256_DIGEST_SIZE;
4778 hash_func = sha256_buffer;
4779 }
4780 else if (EQ (algorithm, Qsha384))
4781 {
4782 digest_size = SHA384_DIGEST_SIZE;
4783 hash_func = sha384_buffer;
4784 }
4785 else if (EQ (algorithm, Qsha512))
4786 {
4787 digest_size = SHA512_DIGEST_SIZE;
4788 hash_func = sha512_buffer;
4789 }
4790 else
4791 error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm)));
57916a7a 4792
7f3f739f
LL
4793 /* allocate 2 x digest_size so that it can be re-used to hold the
4794 hexified value */
4795 digest = make_uninit_string (digest_size * 2);
57916a7a 4796
7f3f739f 4797 hash_func (SSDATA (object) + start_byte,
d311d28c 4798 end_byte - start_byte,
7f3f739f 4799 SSDATA (digest));
e1b90ef6 4800
7f3f739f
LL
4801 if (NILP (binary))
4802 {
4803 unsigned char *p = SDATA (digest);
4804 for (i = digest_size - 1; i >= 0; i--)
4805 {
4806 static char const hexdigit[16] = "0123456789abcdef";
4807 int p_i = p[i];
4808 p[2 * i] = hexdigit[p_i >> 4];
4809 p[2 * i + 1] = hexdigit[p_i & 0xf];
4810 }
4811 return digest;
4812 }
4813 else
a9041e6c 4814 return make_unibyte_string (SSDATA (digest), digest_size);
e1b90ef6
LL
4815}
4816
4817DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
4818 doc: /* Return MD5 message digest of OBJECT, a buffer or string.
4819
4820A message digest is a cryptographic checksum of a document, and the
4821algorithm to calculate it is defined in RFC 1321.
4822
4823The two optional arguments START and END are character positions
4824specifying for which part of OBJECT the message digest should be
4825computed. If nil or omitted, the digest is computed for the whole
4826OBJECT.
4827
4828The MD5 message digest is computed from the result of encoding the
4829text in a coding system, not directly from the internal Emacs form of
4830the text. The optional fourth argument CODING-SYSTEM specifies which
4831coding system to encode the text with. It should be the same coding
4832system that you used or will use when actually writing the text into a
4833file.
4834
4835If CODING-SYSTEM is nil or omitted, the default depends on OBJECT. If
4836OBJECT is a buffer, the default for CODING-SYSTEM is whatever coding
4837system would be chosen by default for writing this text into a file.
4838
4839If OBJECT is a string, the most preferred coding system (see the
4840command `prefer-coding-system') is used.
4841
4842If NOERROR is non-nil, silently assume the `raw-text' coding if the
4843guesswork fails. Normally, an error is signaled in such case. */)
4844 (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror)
4845{
7f3f739f 4846 return secure_hash (Qmd5, object, start, end, coding_system, noerror, Qnil);
e1b90ef6
LL
4847}
4848
7f3f739f 4849DEFUN ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0,
49241268
GM
4850 doc: /* Return the secure hash of OBJECT, a buffer or string.
4851ALGORITHM is a symbol specifying the hash to use:
4852md5, sha1, sha224, sha256, sha384 or sha512.
4853
4854The two optional arguments START and END are positions specifying for
4855which part of OBJECT to compute the hash. If nil or omitted, uses the
4856whole OBJECT.
4857
4858If BINARY is non-nil, returns a string in binary form. */)
7f3f739f 4859 (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
e1b90ef6 4860{
7f3f739f 4861 return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary);
57916a7a 4862}
24c129e4 4863\f
dfcf069d 4864void
971de7fb 4865syms_of_fns (void)
7b863bd5 4866{
7f3f739f
LL
4867 DEFSYM (Qmd5, "md5");
4868 DEFSYM (Qsha1, "sha1");
4869 DEFSYM (Qsha224, "sha224");
4870 DEFSYM (Qsha256, "sha256");
4871 DEFSYM (Qsha384, "sha384");
4872 DEFSYM (Qsha512, "sha512");
4873
d80c6c11 4874 /* Hash table stuff. */
cd3520a4
JB
4875 DEFSYM (Qhash_table_p, "hash-table-p");
4876 DEFSYM (Qeq, "eq");
4877 DEFSYM (Qeql, "eql");
4878 DEFSYM (Qequal, "equal");
4879 DEFSYM (QCtest, ":test");
4880 DEFSYM (QCsize, ":size");
4881 DEFSYM (QCrehash_size, ":rehash-size");
4882 DEFSYM (QCrehash_threshold, ":rehash-threshold");
4883 DEFSYM (QCweakness, ":weakness");
4884 DEFSYM (Qkey, "key");
4885 DEFSYM (Qvalue, "value");
4886 DEFSYM (Qhash_table_test, "hash-table-test");
4887 DEFSYM (Qkey_or_value, "key-or-value");
4888 DEFSYM (Qkey_and_value, "key-and-value");
d80c6c11
GM
4889
4890 defsubr (&Ssxhash);
4891 defsubr (&Smake_hash_table);
f899c503 4892 defsubr (&Scopy_hash_table);
d80c6c11
GM
4893 defsubr (&Shash_table_count);
4894 defsubr (&Shash_table_rehash_size);
4895 defsubr (&Shash_table_rehash_threshold);
4896 defsubr (&Shash_table_size);
4897 defsubr (&Shash_table_test);
e84b1dea 4898 defsubr (&Shash_table_weakness);
d80c6c11
GM
4899 defsubr (&Shash_table_p);
4900 defsubr (&Sclrhash);
4901 defsubr (&Sgethash);
4902 defsubr (&Sputhash);
4903 defsubr (&Sremhash);
4904 defsubr (&Smaphash);
4905 defsubr (&Sdefine_hash_table_test);
59f953a2 4906
cd3520a4
JB
4907 DEFSYM (Qstring_lessp, "string-lessp");
4908 DEFSYM (Qprovide, "provide");
4909 DEFSYM (Qrequire, "require");
4910 DEFSYM (Qyes_or_no_p_history, "yes-or-no-p-history");
4911 DEFSYM (Qcursor_in_echo_area, "cursor-in-echo-area");
4912 DEFSYM (Qwidget_type, "widget-type");
7b863bd5 4913
09ab3c3b
KH
4914 staticpro (&string_char_byte_cache_string);
4915 string_char_byte_cache_string = Qnil;
4916
1f79789d
RS
4917 require_nesting_list = Qnil;
4918 staticpro (&require_nesting_list);
4919
52a9879b
RS
4920 Fset (Qyes_or_no_p_history, Qnil);
4921
29208e82 4922 DEFVAR_LISP ("features", Vfeatures,
4774b68e 4923 doc: /* A list of symbols which are the features of the executing Emacs.
47cebab1 4924Used by `featurep' and `require', and altered by `provide'. */);
d67b4f80 4925 Vfeatures = Fcons (intern_c_string ("emacs"), Qnil);
cd3520a4 4926 DEFSYM (Qsubfeatures, "subfeatures");
7b863bd5 4927
dec002ca 4928#ifdef HAVE_LANGINFO_CODESET
cd3520a4
JB
4929 DEFSYM (Qcodeset, "codeset");
4930 DEFSYM (Qdays, "days");
4931 DEFSYM (Qmonths, "months");
4932 DEFSYM (Qpaper, "paper");
dec002ca
DL
4933#endif /* HAVE_LANGINFO_CODESET */
4934
29208e82 4935 DEFVAR_BOOL ("use-dialog-box", use_dialog_box,
fb7ada5f 4936 doc: /* Non-nil means mouse commands use dialog boxes to ask questions.
436fa78b 4937This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands
7e861e0d
CY
4938invoked by mouse clicks and mouse menu items.
4939
4940On some platforms, file selection dialogs are also enabled if this is
4941non-nil. */);
bdd8d692
RS
4942 use_dialog_box = 1;
4943
29208e82 4944 DEFVAR_BOOL ("use-file-dialog", use_file_dialog,
fb7ada5f 4945 doc: /* Non-nil means mouse commands use a file dialog to ask for files.
1f1d0797 4946This applies to commands from menus and tool bar buttons even when
2fd0161b
CY
4947they are initiated from the keyboard. If `use-dialog-box' is nil,
4948that disables the use of a file dialog, regardless of the value of
4949this variable. */);
6b61353c
KH
4950 use_file_dialog = 1;
4951
7b863bd5
JB
4952 defsubr (&Sidentity);
4953 defsubr (&Srandom);
4954 defsubr (&Slength);
5a30fab8 4955 defsubr (&Ssafe_length);
026f59ce 4956 defsubr (&Sstring_bytes);
7b863bd5 4957 defsubr (&Sstring_equal);
0e1e9f8d 4958 defsubr (&Scompare_strings);
7b863bd5
JB
4959 defsubr (&Sstring_lessp);
4960 defsubr (&Sappend);
4961 defsubr (&Sconcat);
4962 defsubr (&Svconcat);
4963 defsubr (&Scopy_sequence);
09ab3c3b
KH
4964 defsubr (&Sstring_make_multibyte);
4965 defsubr (&Sstring_make_unibyte);
6d475204
RS
4966 defsubr (&Sstring_as_multibyte);
4967 defsubr (&Sstring_as_unibyte);
2df18cdb 4968 defsubr (&Sstring_to_multibyte);
b4480f16 4969 defsubr (&Sstring_to_unibyte);
7b863bd5
JB
4970 defsubr (&Scopy_alist);
4971 defsubr (&Ssubstring);
aebf4d42 4972 defsubr (&Ssubstring_no_properties);
7b863bd5
JB
4973 defsubr (&Snthcdr);
4974 defsubr (&Snth);
4975 defsubr (&Selt);
4976 defsubr (&Smember);
4977 defsubr (&Smemq);
008ef0ef 4978 defsubr (&Smemql);
7b863bd5
JB
4979 defsubr (&Sassq);
4980 defsubr (&Sassoc);
4981 defsubr (&Srassq);
0fb5a19c 4982 defsubr (&Srassoc);
7b863bd5 4983 defsubr (&Sdelq);
ca8dd546 4984 defsubr (&Sdelete);
7b863bd5
JB
4985 defsubr (&Snreverse);
4986 defsubr (&Sreverse);
4987 defsubr (&Ssort);
be9d483d 4988 defsubr (&Splist_get);
7b863bd5 4989 defsubr (&Sget);
be9d483d 4990 defsubr (&Splist_put);
7b863bd5 4991 defsubr (&Sput);
aebf4d42
RS
4992 defsubr (&Slax_plist_get);
4993 defsubr (&Slax_plist_put);
95f8c3b9 4994 defsubr (&Seql);
7b863bd5 4995 defsubr (&Sequal);
6b61353c 4996 defsubr (&Sequal_including_properties);
7b863bd5 4997 defsubr (&Sfillarray);
85cad579 4998 defsubr (&Sclear_string);
7b863bd5
JB
4999 defsubr (&Snconc);
5000 defsubr (&Smapcar);
5c6740c9 5001 defsubr (&Smapc);
7b863bd5 5002 defsubr (&Smapconcat);
7b863bd5
JB
5003 defsubr (&Syes_or_no_p);
5004 defsubr (&Sload_average);
5005 defsubr (&Sfeaturep);
5006 defsubr (&Srequire);
5007 defsubr (&Sprovide);
a5254817 5008 defsubr (&Splist_member);
b4f334f7
KH
5009 defsubr (&Swidget_put);
5010 defsubr (&Swidget_get);
5011 defsubr (&Swidget_apply);
24c129e4
KH
5012 defsubr (&Sbase64_encode_region);
5013 defsubr (&Sbase64_decode_region);
5014 defsubr (&Sbase64_encode_string);
5015 defsubr (&Sbase64_decode_string);
57916a7a 5016 defsubr (&Smd5);
7f3f739f 5017 defsubr (&Ssecure_hash);
d68beb2f 5018 defsubr (&Slocale_info);
7b863bd5 5019}
d80c6c11
GM
5020
5021
5022void
971de7fb 5023init_fns (void)
d80c6c11 5024{
d80c6c11 5025}