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