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