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