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