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