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