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