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