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