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