widen multitable column to avoid underfull box
[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;
7aed223d 69extern int load_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
12ae7fc6 189/* This does not check for quits. That is safe since it must terminate. */
5a30fab8
RS
190
191DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
e9d8ddc9 192 doc: /* Return the length of a list, but avoid error or infinite loop.
47cebab1
GM
193This function never gets an error. If LIST is not really a list,
194it returns 0. If LIST is circular, it returns a finite value
e9d8ddc9
MB
195which is at least the number of distinct elements. */)
196 (list)
5a30fab8
RS
197 Lisp_Object list;
198{
199 Lisp_Object tail, halftail, length;
200 int len = 0;
201
202 /* halftail is used to detect circular lists. */
203 halftail = list;
70949dac 204 for (tail = list; CONSP (tail); tail = XCDR (tail))
5a30fab8
RS
205 {
206 if (EQ (tail, halftail) && len != 0)
cb3d1a0a 207 break;
5a30fab8 208 len++;
3a61aeb4 209 if ((len & 1) == 0)
70949dac 210 halftail = XCDR (halftail);
5a30fab8
RS
211 }
212
213 XSETINT (length, len);
214 return length;
215}
216
91f78c99 217DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
e9d8ddc9
MB
218 doc: /* Return the number of bytes in STRING.
219If STRING is a multibyte string, this is greater than the length of STRING. */)
220 (string)
eaf17c6b 221 Lisp_Object string;
026f59ce 222{
b7826503 223 CHECK_STRING (string);
d5db4077 224 return make_number (SBYTES (string));
026f59ce
RS
225}
226
7b863bd5 227DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
e9d8ddc9 228 doc: /* Return t if two strings have identical contents.
47cebab1 229Case is significant, but text properties are ignored.
e9d8ddc9
MB
230Symbols are also allowed; their print names are used instead. */)
231 (s1, s2)
7b863bd5
JB
232 register Lisp_Object s1, s2;
233{
7650760e 234 if (SYMBOLP (s1))
c06583e1 235 s1 = SYMBOL_NAME (s1);
7650760e 236 if (SYMBOLP (s2))
c06583e1 237 s2 = SYMBOL_NAME (s2);
b7826503
PJ
238 CHECK_STRING (s1);
239 CHECK_STRING (s2);
7b863bd5 240
d5db4077
KR
241 if (SCHARS (s1) != SCHARS (s2)
242 || SBYTES (s1) != SBYTES (s2)
243 || bcmp (SDATA (s1), SDATA (s2), SBYTES (s1)))
7b863bd5
JB
244 return Qnil;
245 return Qt;
246}
247
0e1e9f8d 248DEFUN ("compare-strings", Fcompare_strings,
f95837d0 249 Scompare_strings, 6, 7, 0,
e9d8ddc9 250doc: /* Compare the contents of two strings, converting to multibyte if needed.
47cebab1
GM
251In string STR1, skip the first START1 characters and stop at END1.
252In string STR2, skip the first START2 characters and stop at END2.
253END1 and END2 default to the full lengths of the respective strings.
254
255Case is significant in this comparison if IGNORE-CASE is nil.
256Unibyte strings are converted to multibyte for comparison.
257
258The value is t if the strings (or specified portions) match.
259If string STR1 is less, the value is a negative number N;
260 - 1 - N is the number of characters that match at the beginning.
261If string STR1 is greater, the value is a positive number N;
e9d8ddc9
MB
262 N - 1 is the number of characters that match at the beginning. */)
263 (str1, start1, end1, str2, start2, end2, ignore_case)
0e1e9f8d
RS
264 Lisp_Object str1, start1, end1, start2, str2, end2, ignore_case;
265{
266 register int end1_char, end2_char;
267 register int i1, i1_byte, i2, i2_byte;
268
b7826503
PJ
269 CHECK_STRING (str1);
270 CHECK_STRING (str2);
0e1e9f8d
RS
271 if (NILP (start1))
272 start1 = make_number (0);
273 if (NILP (start2))
274 start2 = make_number (0);
b7826503
PJ
275 CHECK_NATNUM (start1);
276 CHECK_NATNUM (start2);
0e1e9f8d 277 if (! NILP (end1))
b7826503 278 CHECK_NATNUM (end1);
0e1e9f8d 279 if (! NILP (end2))
b7826503 280 CHECK_NATNUM (end2);
0e1e9f8d
RS
281
282 i1 = XINT (start1);
283 i2 = XINT (start2);
284
285 i1_byte = string_char_to_byte (str1, i1);
286 i2_byte = string_char_to_byte (str2, i2);
287
d5db4077 288 end1_char = SCHARS (str1);
0e1e9f8d
RS
289 if (! NILP (end1) && end1_char > XINT (end1))
290 end1_char = XINT (end1);
291
d5db4077 292 end2_char = SCHARS (str2);
0e1e9f8d
RS
293 if (! NILP (end2) && end2_char > XINT (end2))
294 end2_char = XINT (end2);
295
296 while (i1 < end1_char && i2 < end2_char)
297 {
298 /* When we find a mismatch, we must compare the
299 characters, not just the bytes. */
300 int c1, c2;
301
302 if (STRING_MULTIBYTE (str1))
2efdd1b9 303 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c1, str1, i1, i1_byte);
0e1e9f8d
RS
304 else
305 {
d5db4077 306 c1 = SREF (str1, i1++);
0e1e9f8d
RS
307 c1 = unibyte_char_to_multibyte (c1);
308 }
309
310 if (STRING_MULTIBYTE (str2))
2efdd1b9 311 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c2, str2, i2, i2_byte);
0e1e9f8d
RS
312 else
313 {
d5db4077 314 c2 = SREF (str2, i2++);
0e1e9f8d
RS
315 c2 = unibyte_char_to_multibyte (c2);
316 }
317
318 if (c1 == c2)
319 continue;
320
321 if (! NILP (ignore_case))
322 {
323 Lisp_Object tem;
324
325 tem = Fupcase (make_number (c1));
326 c1 = XINT (tem);
327 tem = Fupcase (make_number (c2));
328 c2 = XINT (tem);
329 }
330
331 if (c1 == c2)
332 continue;
333
334 /* Note that I1 has already been incremented
335 past the character that we are comparing;
336 hence we don't add or subtract 1 here. */
337 if (c1 < c2)
60f8d735 338 return make_number (- i1 + XINT (start1));
0e1e9f8d 339 else
60f8d735 340 return make_number (i1 - XINT (start1));
0e1e9f8d
RS
341 }
342
343 if (i1 < end1_char)
344 return make_number (i1 - XINT (start1) + 1);
345 if (i2 < end2_char)
346 return make_number (- i1 + XINT (start1) - 1);
347
348 return Qt;
349}
350
7b863bd5 351DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
e9d8ddc9 352 doc: /* Return t if first arg string is less than second in lexicographic order.
47cebab1 353Case is significant.
e9d8ddc9
MB
354Symbols are also allowed; their print names are used instead. */)
355 (s1, s2)
7b863bd5
JB
356 register Lisp_Object s1, s2;
357{
7b863bd5 358 register int end;
09ab3c3b 359 register int i1, i1_byte, i2, i2_byte;
7b863bd5 360
7650760e 361 if (SYMBOLP (s1))
c06583e1 362 s1 = SYMBOL_NAME (s1);
7650760e 363 if (SYMBOLP (s2))
c06583e1 364 s2 = SYMBOL_NAME (s2);
b7826503
PJ
365 CHECK_STRING (s1);
366 CHECK_STRING (s2);
7b863bd5 367
09ab3c3b
KH
368 i1 = i1_byte = i2 = i2_byte = 0;
369
d5db4077
KR
370 end = SCHARS (s1);
371 if (end > SCHARS (s2))
372 end = SCHARS (s2);
7b863bd5 373
09ab3c3b 374 while (i1 < end)
7b863bd5 375 {
09ab3c3b
KH
376 /* When we find a mismatch, we must compare the
377 characters, not just the bytes. */
378 int c1, c2;
379
2efdd1b9
KH
380 FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte);
381 FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte);
09ab3c3b
KH
382
383 if (c1 != c2)
384 return c1 < c2 ? Qt : Qnil;
7b863bd5 385 }
d5db4077 386 return i1 < SCHARS (s2) ? Qt : Qnil;
7b863bd5
JB
387}
388\f
389static Lisp_Object concat ();
390
391/* ARGSUSED */
392Lisp_Object
393concat2 (s1, s2)
394 Lisp_Object s1, s2;
395{
396#ifdef NO_ARG_ARRAY
397 Lisp_Object args[2];
398 args[0] = s1;
399 args[1] = s2;
400 return concat (2, args, Lisp_String, 0);
401#else
402 return concat (2, &s1, Lisp_String, 0);
403#endif /* NO_ARG_ARRAY */
404}
405
d4af3687
RS
406/* ARGSUSED */
407Lisp_Object
408concat3 (s1, s2, s3)
409 Lisp_Object s1, s2, s3;
410{
411#ifdef NO_ARG_ARRAY
412 Lisp_Object args[3];
413 args[0] = s1;
414 args[1] = s2;
415 args[2] = s3;
416 return concat (3, args, Lisp_String, 0);
417#else
418 return concat (3, &s1, Lisp_String, 0);
419#endif /* NO_ARG_ARRAY */
420}
421
7b863bd5 422DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
e9d8ddc9 423 doc: /* Concatenate all the arguments and make the result a list.
47cebab1
GM
424The result is a list whose elements are the elements of all the arguments.
425Each argument may be a list, vector or string.
4bf8e2a3
MB
426The last argument is not copied, just used as the tail of the new list.
427usage: (append &rest SEQUENCES) */)
e9d8ddc9 428 (nargs, args)
7b863bd5
JB
429 int nargs;
430 Lisp_Object *args;
431{
432 return concat (nargs, args, Lisp_Cons, 1);
433}
434
435DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
e9d8ddc9 436 doc: /* Concatenate all the arguments and make the result a string.
47cebab1 437The result is a string whose elements are the elements of all the arguments.
4bf8e2a3
MB
438Each argument may be a string or a list or vector of characters (integers).
439usage: (concat &rest SEQUENCES) */)
e9d8ddc9 440 (nargs, args)
7b863bd5
JB
441 int nargs;
442 Lisp_Object *args;
443{
444 return concat (nargs, args, Lisp_String, 0);
445}
446
447DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
e9d8ddc9 448 doc: /* Concatenate all the arguments and make the result a vector.
47cebab1 449The result is a vector whose elements are the elements of all the arguments.
4bf8e2a3
MB
450Each argument may be a list, vector or string.
451usage: (vconcat &rest SEQUENCES) */)
e9d8ddc9 452 (nargs, args)
7b863bd5
JB
453 int nargs;
454 Lisp_Object *args;
455{
3e7383eb 456 return concat (nargs, args, Lisp_Vectorlike, 0);
7b863bd5
JB
457}
458
f5965ada 459/* Return a copy of a sub char table ARG. The elements except for a
3720677d
KH
460 nested sub char table are not copied. */
461static Lisp_Object
462copy_sub_char_table (arg)
e1335ba2 463 Lisp_Object arg;
3720677d 464{
1468c19b 465 Lisp_Object copy = make_sub_char_table (Qnil);
3720677d
KH
466 int i;
467
1468c19b 468 XCHAR_TABLE (copy)->defalt = XCHAR_TABLE (arg)->defalt;
3720677d
KH
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.
c14ec135 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
12ae7fc6 1984#if 0 /* Unsafe version. */
be9d483d 1985DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
e9d8ddc9 1986 doc: /* Extract a value from a property list.
47cebab1
GM
1987PLIST is a property list, which is a list of the form
1988\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
1989corresponding to the given PROP, or nil if PROP is not
e9d8ddc9
MB
1990one of the properties on the list. */)
1991 (plist, prop)
1fbb64aa 1992 Lisp_Object plist;
2d6fabfc 1993 Lisp_Object prop;
7b863bd5 1994{
2d6fabfc 1995 Lisp_Object tail;
91f78c99 1996
2d6fabfc
GM
1997 for (tail = plist;
1998 CONSP (tail) && CONSP (XCDR (tail));
1999 tail = XCDR (XCDR (tail)))
7b863bd5 2000 {
2d6fabfc
GM
2001 if (EQ (prop, XCAR (tail)))
2002 return XCAR (XCDR (tail));
ec2423c9
GM
2003
2004 /* This function can be called asynchronously
2005 (setup_coding_system). Don't QUIT in that case. */
2006 if (!interrupt_input_blocked)
2007 QUIT;
7b863bd5 2008 }
2d6fabfc
GM
2009
2010 if (!NILP (tail))
2011 wrong_type_argument (Qlistp, prop);
91f78c99 2012
7b863bd5
JB
2013 return Qnil;
2014}
12ae7fc6
KS
2015#endif
2016
2017/* This does not check for quits. That is safe since it must terminate. */
7b863bd5 2018
12ae7fc6 2019DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
27f604dd
KS
2020 doc: /* Extract a value from a property list.
2021PLIST is a property list, which is a list of the form
2022\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
12ae7fc6
KS
2023corresponding to the given PROP, or nil if PROP is not one of the
2024properties on the list. This function never signals an error. */)
27f604dd
KS
2025 (plist, prop)
2026 Lisp_Object plist;
2027 Lisp_Object prop;
2028{
2029 Lisp_Object tail, halftail;
2030
2031 /* halftail is used to detect circular lists. */
2032 tail = halftail = plist;
2033 while (CONSP (tail) && CONSP (XCDR (tail)))
2034 {
2035 if (EQ (prop, XCAR (tail)))
2036 return XCAR (XCDR (tail));
2037
2038 tail = XCDR (XCDR (tail));
2039 halftail = XCDR (halftail);
2040 if (EQ (tail, halftail))
2041 break;
2042 }
2043
2044 return Qnil;
2045}
2046
be9d483d 2047DEFUN ("get", Fget, Sget, 2, 2, 0,
e9d8ddc9
MB
2048 doc: /* Return the value of SYMBOL's PROPNAME property.
2049This is the last value stored with `(put SYMBOL PROPNAME VALUE)'. */)
2050 (symbol, propname)
c07289e0 2051 Lisp_Object symbol, propname;
be9d483d 2052{
b7826503 2053 CHECK_SYMBOL (symbol);
c07289e0 2054 return Fplist_get (XSYMBOL (symbol)->plist, propname);
be9d483d
BG
2055}
2056
2057DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
e9d8ddc9 2058 doc: /* Change value in PLIST of PROP to VAL.
47cebab1
GM
2059PLIST is a property list, which is a list of the form
2060\(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.
2061If PROP is already a property on the list, its value is set to VAL,
2062otherwise the new PROP VAL pair is added. The new plist is returned;
2063use `(setq x (plist-put x prop val))' to be sure to use the new value.
e9d8ddc9
MB
2064The PLIST is modified by side effects. */)
2065 (plist, prop, val)
b4f334f7
KH
2066 Lisp_Object plist;
2067 register Lisp_Object prop;
2068 Lisp_Object val;
7b863bd5
JB
2069{
2070 register Lisp_Object tail, prev;
2071 Lisp_Object newcell;
2072 prev = Qnil;
70949dac
KR
2073 for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
2074 tail = XCDR (XCDR (tail)))
7b863bd5 2075 {
70949dac 2076 if (EQ (prop, XCAR (tail)))
be9d483d 2077 {
70949dac 2078 Fsetcar (XCDR (tail), val);
be9d483d
BG
2079 return plist;
2080 }
91f78c99 2081
7b863bd5 2082 prev = tail;
2d6fabfc 2083 QUIT;
7b863bd5
JB
2084 }
2085 newcell = Fcons (prop, Fcons (val, Qnil));
265a9e55 2086 if (NILP (prev))
be9d483d 2087 return newcell;
7b863bd5 2088 else
70949dac 2089 Fsetcdr (XCDR (prev), newcell);
be9d483d
BG
2090 return plist;
2091}
2092
2093DEFUN ("put", Fput, Sput, 3, 3, 0,
e9d8ddc9
MB
2094 doc: /* Store SYMBOL's PROPNAME property with value VALUE.
2095It can be retrieved with `(get SYMBOL PROPNAME)'. */)
2096 (symbol, propname, value)
c07289e0 2097 Lisp_Object symbol, propname, value;
be9d483d 2098{
b7826503 2099 CHECK_SYMBOL (symbol);
c07289e0
RS
2100 XSYMBOL (symbol)->plist
2101 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
2102 return value;
7b863bd5 2103}
aebf4d42
RS
2104\f
2105DEFUN ("lax-plist-get", Flax_plist_get, Slax_plist_get, 2, 2, 0,
2106 doc: /* Extract a value from a property list, comparing with `equal'.
2107PLIST is a property list, which is a list of the form
2108\(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value
2109corresponding to the given PROP, or nil if PROP is not
2110one of the properties on the list. */)
2111 (plist, prop)
2112 Lisp_Object plist;
2113 Lisp_Object prop;
2114{
2115 Lisp_Object tail;
91f78c99 2116
aebf4d42
RS
2117 for (tail = plist;
2118 CONSP (tail) && CONSP (XCDR (tail));
2119 tail = XCDR (XCDR (tail)))
2120 {
2121 if (! NILP (Fequal (prop, XCAR (tail))))
2122 return XCAR (XCDR (tail));
2123
2124 QUIT;
2125 }
2126
2127 if (!NILP (tail))
2128 wrong_type_argument (Qlistp, prop);
91f78c99 2129
aebf4d42
RS
2130 return Qnil;
2131}
7b863bd5 2132
aebf4d42
RS
2133DEFUN ("lax-plist-put", Flax_plist_put, Slax_plist_put, 3, 3, 0,
2134 doc: /* Change value in PLIST of PROP to VAL, comparing with `equal'.
2135PLIST is a property list, which is a list of the form
9e76ae05 2136\(PROP1 VALUE1 PROP2 VALUE2 ...). PROP and VAL are any objects.
aebf4d42
RS
2137If PROP is already a property on the list, its value is set to VAL,
2138otherwise the new PROP VAL pair is added. The new plist is returned;
2139use `(setq x (lax-plist-put x prop val))' to be sure to use the new value.
2140The PLIST is modified by side effects. */)
2141 (plist, prop, val)
2142 Lisp_Object plist;
2143 register Lisp_Object prop;
2144 Lisp_Object val;
2145{
2146 register Lisp_Object tail, prev;
2147 Lisp_Object newcell;
2148 prev = Qnil;
2149 for (tail = plist; CONSP (tail) && CONSP (XCDR (tail));
2150 tail = XCDR (XCDR (tail)))
2151 {
2152 if (! NILP (Fequal (prop, XCAR (tail))))
2153 {
2154 Fsetcar (XCDR (tail), val);
2155 return plist;
2156 }
91f78c99 2157
aebf4d42
RS
2158 prev = tail;
2159 QUIT;
2160 }
2161 newcell = Fcons (prop, Fcons (val, Qnil));
2162 if (NILP (prev))
2163 return newcell;
2164 else
2165 Fsetcdr (XCDR (prev), newcell);
2166 return plist;
2167}
2168\f
95f8c3b9
JPW
2169DEFUN ("eql", Feql, Seql, 2, 2, 0,
2170 doc: /* Return t if the two args are the same Lisp object.
2171Floating-point numbers of equal value are `eql', but they may not be `eq'. */)
474d0535 2172 (obj1, obj2)
95f8c3b9
JPW
2173 Lisp_Object obj1, obj2;
2174{
2175 if (FLOATP (obj1))
2176 return internal_equal (obj1, obj2, 0, 0) ? Qt : Qnil;
2177 else
2178 return EQ (obj1, obj2) ? Qt : Qnil;
2179}
2180
7b863bd5 2181DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
e9d8ddc9 2182 doc: /* Return t if two Lisp objects have similar structure and contents.
47cebab1
GM
2183They must have the same data type.
2184Conses are compared by comparing the cars and the cdrs.
2185Vectors and strings are compared element by element.
2186Numbers are compared by value, but integers cannot equal floats.
2187 (Use `=' if you want integers and floats to be able to be equal.)
e9d8ddc9
MB
2188Symbols must match exactly. */)
2189 (o1, o2)
7b863bd5
JB
2190 register Lisp_Object o1, o2;
2191{
6054c582 2192 return internal_equal (o1, o2, 0, 0) ? Qt : Qnil;
e0f5cf5a
RS
2193}
2194
6054c582
RS
2195DEFUN ("equal-including-properties", Fequal_including_properties, Sequal_including_properties, 2, 2, 0,
2196 doc: /* Return t if two Lisp objects have similar structure and contents.
2197This is like `equal' except that it compares the text properties
2198of strings. (`equal' ignores text properties.) */)
2199 (o1, o2)
2200 register Lisp_Object o1, o2;
2201{
2202 return internal_equal (o1, o2, 0, 1) ? Qt : Qnil;
2203}
2204
2205/* DEPTH is current depth of recursion. Signal an error if it
2206 gets too deep.
2207 PROPS, if non-nil, means compare string text properties too. */
2208
6cb9cafb 2209static int
6054c582 2210internal_equal (o1, o2, depth, props)
e0f5cf5a 2211 register Lisp_Object o1, o2;
6054c582 2212 int depth, props;
e0f5cf5a
RS
2213{
2214 if (depth > 200)
2215 error ("Stack overflow in equal");
4ff1aed9 2216
6cb9cafb 2217 tail_recurse:
7b863bd5 2218 QUIT;
4ff1aed9
RS
2219 if (EQ (o1, o2))
2220 return 1;
2221 if (XTYPE (o1) != XTYPE (o2))
2222 return 0;
2223
2224 switch (XTYPE (o1))
2225 {
4ff1aed9 2226 case Lisp_Float:
74a47d1f
EZ
2227 {
2228 double d1, d2;
2229
2230 d1 = extract_float (o1);
2231 d2 = extract_float (o2);
2232 /* If d is a NaN, then d != d. Two NaNs should be `equal' even
2233 though they are not =. */
2234 return d1 == d2 || (d1 != d1 && d2 != d2);
2235 }
4ff1aed9
RS
2236
2237 case Lisp_Cons:
6054c582 2238 if (!internal_equal (XCAR (o1), XCAR (o2), depth + 1, props))
4cab5074 2239 return 0;
70949dac
KR
2240 o1 = XCDR (o1);
2241 o2 = XCDR (o2);
4cab5074 2242 goto tail_recurse;
4ff1aed9
RS
2243
2244 case Lisp_Misc:
81d1fba6 2245 if (XMISCTYPE (o1) != XMISCTYPE (o2))
6cb9cafb 2246 return 0;
4ff1aed9 2247 if (OVERLAYP (o1))
7b863bd5 2248 {
e23f814f 2249 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o2),
6054c582 2250 depth + 1, props)
e23f814f 2251 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o2),
4ff1aed9 2252 depth + 1))
6cb9cafb 2253 return 0;
4ff1aed9
RS
2254 o1 = XOVERLAY (o1)->plist;
2255 o2 = XOVERLAY (o2)->plist;
2256 goto tail_recurse;
7b863bd5 2257 }
4ff1aed9
RS
2258 if (MARKERP (o1))
2259 {
2260 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
2261 && (XMARKER (o1)->buffer == 0
6ced1284 2262 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
4ff1aed9
RS
2263 }
2264 break;
2265
2266 case Lisp_Vectorlike:
4cab5074 2267 {
00498bfc
AS
2268 register int i;
2269 EMACS_INT size = XVECTOR (o1)->size;
4cab5074
KH
2270 /* Pseudovectors have the type encoded in the size field, so this test
2271 actually checks that the objects have the same type as well as the
2272 same size. */
2273 if (XVECTOR (o2)->size != size)
2274 return 0;
e03f7933
RS
2275 /* Boolvectors are compared much like strings. */
2276 if (BOOL_VECTOR_P (o1))
2277 {
e03f7933 2278 int size_in_chars
db85986c
AS
2279 = ((XBOOL_VECTOR (o1)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
2280 / BOOL_VECTOR_BITS_PER_CHAR);
e03f7933
RS
2281
2282 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
2283 return 0;
2284 if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
2285 size_in_chars))
2286 return 0;
2287 return 1;
2288 }
ed73fcc1 2289 if (WINDOW_CONFIGURATIONP (o1))
48646924 2290 return compare_window_configurations (o1, o2, 0);
e03f7933
RS
2291
2292 /* Aside from them, only true vectors, char-tables, and compiled
2293 functions are sensible to compare, so eliminate the others now. */
4cab5074
KH
2294 if (size & PSEUDOVECTOR_FLAG)
2295 {
e03f7933 2296 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
4cab5074
KH
2297 return 0;
2298 size &= PSEUDOVECTOR_SIZE_MASK;
2299 }
2300 for (i = 0; i < size; i++)
2301 {
2302 Lisp_Object v1, v2;
2303 v1 = XVECTOR (o1)->contents [i];
2304 v2 = XVECTOR (o2)->contents [i];
6054c582 2305 if (!internal_equal (v1, v2, depth + 1, props))
4cab5074
KH
2306 return 0;
2307 }
2308 return 1;
2309 }
4ff1aed9
RS
2310 break;
2311
2312 case Lisp_String:
d5db4077 2313 if (SCHARS (o1) != SCHARS (o2))
4cab5074 2314 return 0;
d5db4077 2315 if (SBYTES (o1) != SBYTES (o2))
ea35ce3d 2316 return 0;
d5db4077
KR
2317 if (bcmp (SDATA (o1), SDATA (o2),
2318 SBYTES (o1)))
4cab5074 2319 return 0;
6054c582
RS
2320 if (props && !compare_string_intervals (o1, o2))
2321 return 0;
4cab5074 2322 return 1;
093386ca
GM
2323
2324 case Lisp_Int:
2325 case Lisp_Symbol:
2326 case Lisp_Type_Limit:
2327 break;
7b863bd5 2328 }
91f78c99 2329
6cb9cafb 2330 return 0;
7b863bd5
JB
2331}
2332\f
2e34157c
RS
2333extern Lisp_Object Fmake_char_internal ();
2334
7b863bd5 2335DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
e9d8ddc9
MB
2336 doc: /* Store each element of ARRAY with ITEM.
2337ARRAY is a vector, string, char-table, or bool-vector. */)
2338 (array, item)
7b863bd5
JB
2339 Lisp_Object array, item;
2340{
2341 register int size, index, charval;
2342 retry:
7650760e 2343 if (VECTORP (array))
7b863bd5
JB
2344 {
2345 register Lisp_Object *p = XVECTOR (array)->contents;
2346 size = XVECTOR (array)->size;
2347 for (index = 0; index < size; index++)
2348 p[index] = item;
2349 }
e03f7933
RS
2350 else if (CHAR_TABLE_P (array))
2351 {
2352 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
2353 size = CHAR_TABLE_ORDINARY_SLOTS;
2354 for (index = 0; index < size; index++)
2355 p[index] = item;
2356 XCHAR_TABLE (array)->defalt = Qnil;
2357 }
7650760e 2358 else if (STRINGP (array))
7b863bd5 2359 {
d5db4077 2360 register unsigned char *p = SDATA (array);
b7826503 2361 CHECK_NUMBER (item);
7b863bd5 2362 charval = XINT (item);
d5db4077 2363 size = SCHARS (array);
57247650
KH
2364 if (STRING_MULTIBYTE (array))
2365 {
64a5094a
KH
2366 unsigned char str[MAX_MULTIBYTE_LENGTH];
2367 int len = CHAR_STRING (charval, str);
d5db4077 2368 int size_byte = SBYTES (array);
57247650 2369 unsigned char *p1 = p, *endp = p + size_byte;
95b8aba7 2370 int i;
57247650 2371
95b8aba7
KH
2372 if (size != size_byte)
2373 while (p1 < endp)
2374 {
2375 int this_len = MULTIBYTE_FORM_LENGTH (p1, endp - p1);
2376 if (len != this_len)
2377 error ("Attempt to change byte length of a string");
2378 p1 += this_len;
2379 }
57247650
KH
2380 for (i = 0; i < size_byte; i++)
2381 *p++ = str[i % len];
2382 }
2383 else
2384 for (index = 0; index < size; index++)
2385 p[index] = charval;
7b863bd5 2386 }
e03f7933
RS
2387 else if (BOOL_VECTOR_P (array))
2388 {
2389 register unsigned char *p = XBOOL_VECTOR (array)->data;
e03f7933 2390 int size_in_chars
db85986c
AS
2391 = ((XBOOL_VECTOR (array)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
2392 / BOOL_VECTOR_BITS_PER_CHAR);
e03f7933
RS
2393
2394 charval = (! NILP (item) ? -1 : 0);
00498bfc 2395 for (index = 0; index < size_in_chars - 1; index++)
e03f7933 2396 p[index] = charval;
00498bfc
AS
2397 if (index < size_in_chars)
2398 {
2399 /* Mask out bits beyond the vector size. */
db85986c
AS
2400 if (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)
2401 charval &= (1 << (XBOOL_VECTOR (array)->size % BOOL_VECTOR_BITS_PER_CHAR)) - 1;
00498bfc
AS
2402 p[index] = charval;
2403 }
e03f7933 2404 }
7b863bd5
JB
2405 else
2406 {
2407 array = wrong_type_argument (Qarrayp, array);
2408 goto retry;
2409 }
2410 return array;
2411}
85cad579
RS
2412
2413DEFUN ("clear-string", Fclear_string, Sclear_string,
2414 1, 1, 0,
2415 doc: /* Clear the contents of STRING.
2416This makes STRING unibyte and may change its length. */)
2417 (string)
2418 Lisp_Object string;
2419{
cfd23693 2420 int len;
a085bf9d 2421 CHECK_STRING (string);
cfd23693 2422 len = SBYTES (string);
85cad579
RS
2423 bzero (SDATA (string), len);
2424 STRING_SET_CHARS (string, len);
2425 STRING_SET_UNIBYTE (string);
2426 return Qnil;
2427}
ea35ce3d 2428\f
999de246
RS
2429DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
2430 1, 1, 0,
e9d8ddc9
MB
2431 doc: /* Return the subtype of char-table CHAR-TABLE. The value is a symbol. */)
2432 (char_table)
88fe8140 2433 Lisp_Object char_table;
999de246 2434{
b7826503 2435 CHECK_CHAR_TABLE (char_table);
999de246 2436
88fe8140 2437 return XCHAR_TABLE (char_table)->purpose;
999de246
RS
2438}
2439
e03f7933
RS
2440DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
2441 1, 1, 0,
e9d8ddc9 2442 doc: /* Return the parent char-table of CHAR-TABLE.
47cebab1
GM
2443The value is either nil or another char-table.
2444If CHAR-TABLE holds nil for a given character,
2445then the actual applicable value is inherited from the parent char-table
e9d8ddc9
MB
2446\(or from its parents, if necessary). */)
2447 (char_table)
88fe8140 2448 Lisp_Object char_table;
e03f7933 2449{
b7826503 2450 CHECK_CHAR_TABLE (char_table);
e03f7933 2451
88fe8140 2452 return XCHAR_TABLE (char_table)->parent;
e03f7933
RS
2453}
2454
2455DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
2456 2, 2, 0,
e9d8ddc9 2457 doc: /* Set the parent char-table of CHAR-TABLE to PARENT.
c541e2a0 2458Return PARENT. PARENT must be either nil or another char-table. */)
e9d8ddc9 2459 (char_table, parent)
88fe8140 2460 Lisp_Object char_table, parent;
e03f7933
RS
2461{
2462 Lisp_Object temp;
2463
b7826503 2464 CHECK_CHAR_TABLE (char_table);
e03f7933 2465
c8640abf
RS
2466 if (!NILP (parent))
2467 {
b7826503 2468 CHECK_CHAR_TABLE (parent);
c8640abf
RS
2469
2470 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
55cc974d 2471 if (EQ (temp, char_table))
c8640abf
RS
2472 error ("Attempt to make a chartable be its own parent");
2473 }
e03f7933 2474
88fe8140 2475 XCHAR_TABLE (char_table)->parent = parent;
e03f7933
RS
2476
2477 return parent;
2478}
2479
2480DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
2481 2, 2, 0,
e9d8ddc9
MB
2482 doc: /* Return the value of CHAR-TABLE's extra-slot number N. */)
2483 (char_table, n)
88fe8140 2484 Lisp_Object char_table, n;
e03f7933 2485{
b7826503
PJ
2486 CHECK_CHAR_TABLE (char_table);
2487 CHECK_NUMBER (n);
e03f7933 2488 if (XINT (n) < 0
88fe8140
EN
2489 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
2490 args_out_of_range (char_table, n);
e03f7933 2491
88fe8140 2492 return XCHAR_TABLE (char_table)->extras[XINT (n)];
e03f7933
RS
2493}
2494
2495DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
2496 Sset_char_table_extra_slot,
2497 3, 3, 0,
e9d8ddc9
MB
2498 doc: /* Set CHAR-TABLE's extra-slot number N to VALUE. */)
2499 (char_table, n, value)
88fe8140 2500 Lisp_Object char_table, n, value;
e03f7933 2501{
b7826503
PJ
2502 CHECK_CHAR_TABLE (char_table);
2503 CHECK_NUMBER (n);
e03f7933 2504 if (XINT (n) < 0
88fe8140
EN
2505 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
2506 args_out_of_range (char_table, n);
e03f7933 2507
88fe8140 2508 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
e03f7933 2509}
ea35ce3d 2510\f
38f60cd9
KH
2511static Lisp_Object
2512char_table_range (table, from, to, defalt)
2513 Lisp_Object table;
2514 int from, to;
2515 Lisp_Object defalt;
2516{
2517 Lisp_Object val;
2518
2519 if (! NILP (XCHAR_TABLE (table)->defalt))
2520 defalt = XCHAR_TABLE (table)->defalt;
2521 val = XCHAR_TABLE (table)->contents[from];
2522 if (SUB_CHAR_TABLE_P (val))
2523 val = char_table_range (val, 32, 127, defalt);
2524 else if (NILP (val))
2525 val = defalt;
2526 for (from++; from <= to; from++)
2527 {
2528 Lisp_Object this_val;
2529
2530 this_val = XCHAR_TABLE (table)->contents[from];
2531 if (SUB_CHAR_TABLE_P (this_val))
2532 this_val = char_table_range (this_val, 32, 127, defalt);
2533 else if (NILP (this_val))
2534 this_val = defalt;
2535 if (! EQ (val, this_val))
2536 error ("Characters in the range have inconsistent values");
2537 }
2538 return val;
e475c66a 2539}
38f60cd9
KH
2540
2541
999de246
RS
2542DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
2543 2, 2, 0,
e9d8ddc9 2544 doc: /* Return the value in CHAR-TABLE for a range of characters RANGE.
e475c66a 2545RANGE should be nil (for the default value),
47cebab1 2546a vector which identifies a character set or a row of a character set,
38f60cd9
KH
2547a character set name, or a character code.
2548If the characters in the specified range have different values,
2549an error is signalled.
2550
e475c66a 2551Note that this function doesn't check the parent of CHAR-TABLE. */)
e9d8ddc9 2552 (char_table, range)
88fe8140 2553 Lisp_Object char_table, range;
999de246 2554{
38f60cd9
KH
2555 int charset_id, c1 = 0, c2 = 0;
2556 int size, i;
2557 Lisp_Object ch, val, current_default;
2558
b7826503 2559 CHECK_CHAR_TABLE (char_table);
b4f334f7 2560
999de246 2561 if (EQ (range, Qnil))
88fe8140 2562 return XCHAR_TABLE (char_table)->defalt;
38f60cd9
KH
2563 if (INTEGERP (range))
2564 {
2565 int c = XINT (range);
2566 if (! CHAR_VALID_P (c, 0))
2567 error ("Invalid character code: %d", c);
2568 ch = range;
2569 SPLIT_CHAR (c, charset_id, c1, c2);
2570 }
6d475204
RS
2571 else if (SYMBOLP (range))
2572 {
2573 Lisp_Object charset_info;
2574
2575 charset_info = Fget (range, Qcharset);
b7826503 2576 CHECK_VECTOR (charset_info);
38f60cd9
KH
2577 charset_id = XINT (XVECTOR (charset_info)->contents[0]);
2578 ch = Fmake_char_internal (make_number (charset_id),
2579 make_number (0), make_number (0));
6d475204 2580 }
999de246
RS
2581 else if (VECTORP (range))
2582 {
38f60cd9
KH
2583 size = ASIZE (range);
2584 if (size == 0)
7ec64183 2585 args_out_of_range (range, make_number (0));
38f60cd9
KH
2586 CHECK_NUMBER (AREF (range, 0));
2587 charset_id = XINT (AREF (range, 0));
2588 if (size > 1)
e814a159 2589 {
38f60cd9
KH
2590 CHECK_NUMBER (AREF (range, 1));
2591 c1 = XINT (AREF (range, 1));
2592 if (size > 2)
2593 {
2594 CHECK_NUMBER (AREF (range, 2));
2595 c2 = XINT (AREF (range, 2));
2596 }
e814a159 2597 }
38f60cd9
KH
2598
2599 /* This checks if charset_id, c0, and c1 are all valid or not. */
2600 ch = Fmake_char_internal (make_number (charset_id),
2601 make_number (c1), make_number (c2));
999de246
RS
2602 }
2603 else
2604 error ("Invalid RANGE argument to `char-table-range'");
38f60cd9
KH
2605
2606 if (c1 > 0 && (CHARSET_DIMENSION (charset_id) == 1 || c2 > 0))
2607 {
2608 /* Fully specified character. */
2609 Lisp_Object parent = XCHAR_TABLE (char_table)->parent;
2610
2611 XCHAR_TABLE (char_table)->parent = Qnil;
2612 val = Faref (char_table, ch);
2613 XCHAR_TABLE (char_table)->parent = parent;
2614 return val;
2615 }
2616
2617 current_default = XCHAR_TABLE (char_table)->defalt;
2618 if (charset_id == CHARSET_ASCII
2619 || charset_id == CHARSET_8_BIT_CONTROL
2620 || charset_id == CHARSET_8_BIT_GRAPHIC)
2621 {
2622 int from, to, defalt;
2623
2624 if (charset_id == CHARSET_ASCII)
2625 from = 0, to = 127, defalt = CHAR_TABLE_DEFAULT_SLOT_ASCII;
2626 else if (charset_id == CHARSET_8_BIT_CONTROL)
2627 from = 128, to = 159, defalt = CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL;
2628 else
2629 from = 160, to = 255, defalt = CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC;
2630 if (! NILP (XCHAR_TABLE (char_table)->contents[defalt]))
2631 current_default = XCHAR_TABLE (char_table)->contents[defalt];
2632 return char_table_range (char_table, from, to, current_default);
2633 }
e475c66a 2634
38f60cd9
KH
2635 val = XCHAR_TABLE (char_table)->contents[128 + charset_id];
2636 if (! SUB_CHAR_TABLE_P (val))
2637 return (NILP (val) ? current_default : val);
2638 if (! NILP (XCHAR_TABLE (val)->defalt))
2639 current_default = XCHAR_TABLE (val)->defalt;
2640 if (c1 == 0)
2641 return char_table_range (val, 32, 127, current_default);
2642 val = XCHAR_TABLE (val)->contents[c1];
2643 if (! SUB_CHAR_TABLE_P (val))
2644 return (NILP (val) ? current_default : val);
2645 if (! NILP (XCHAR_TABLE (val)->defalt))
2646 current_default = XCHAR_TABLE (val)->defalt;
2647 return char_table_range (val, 32, 127, current_default);
999de246
RS
2648}
2649
e03f7933
RS
2650DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
2651 3, 3, 0,
e9d8ddc9 2652 doc: /* Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.
ac1106fc
LT
2653RANGE should be t (for all characters), nil (for the default value),
2654a character set, a vector which identifies a character set, a row of a
2655character set, or a character code. Return VALUE. */)
e9d8ddc9 2656 (char_table, range, value)
88fe8140 2657 Lisp_Object char_table, range, value;
e03f7933
RS
2658{
2659 int i;
2660
b7826503 2661 CHECK_CHAR_TABLE (char_table);
b4f334f7 2662
e03f7933
RS
2663 if (EQ (range, Qt))
2664 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
2b048bf5
KH
2665 {
2666 /* Don't set these special slots used for default values of
2667 ascii, eight-bit-control, and eight-bit-graphic. */
2668 if (i != CHAR_TABLE_DEFAULT_SLOT_ASCII
2669 && i != CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
2670 && i != CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC)
2671 XCHAR_TABLE (char_table)->contents[i] = value;
2672 }
e03f7933 2673 else if (EQ (range, Qnil))
88fe8140 2674 XCHAR_TABLE (char_table)->defalt = value;
6d475204
RS
2675 else if (SYMBOLP (range))
2676 {
2677 Lisp_Object charset_info;
13c5d120 2678 int charset_id;
6d475204
RS
2679
2680 charset_info = Fget (range, Qcharset);
13c5d120
KH
2681 if (! VECTORP (charset_info)
2682 || ! NATNUMP (AREF (charset_info, 0))
2683 || (charset_id = XINT (AREF (charset_info, 0)),
2684 ! CHARSET_DEFINED_P (charset_id)))
ebaff4af 2685 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (range)));
13c5d120
KH
2686
2687 if (charset_id == CHARSET_ASCII)
2688 for (i = 0; i < 128; i++)
2689 XCHAR_TABLE (char_table)->contents[i] = value;
2690 else if (charset_id == CHARSET_8_BIT_CONTROL)
2691 for (i = 128; i < 160; i++)
2692 XCHAR_TABLE (char_table)->contents[i] = value;
2693 else if (charset_id == CHARSET_8_BIT_GRAPHIC)
2694 for (i = 160; i < 256; i++)
2695 XCHAR_TABLE (char_table)->contents[i] = value;
2696 else
2697 XCHAR_TABLE (char_table)->contents[charset_id + 128] = value;
6d475204 2698 }
e03f7933 2699 else if (INTEGERP (range))
88fe8140 2700 Faset (char_table, range, value);
e03f7933
RS
2701 else if (VECTORP (range))
2702 {
2b048bf5
KH
2703 int size = XVECTOR (range)->size;
2704 Lisp_Object *val = XVECTOR (range)->contents;
2705 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
2706 size <= 1 ? Qnil : val[1],
2707 size <= 2 ? Qnil : val[2]);
2708 Faset (char_table, ch, value);
e03f7933
RS
2709 }
2710 else
2711 error ("Invalid RANGE argument to `set-char-table-range'");
2712
2713 return value;
2714}
e1335ba2
KH
2715
2716DEFUN ("set-char-table-default", Fset_char_table_default,
2717 Sset_char_table_default, 3, 3, 0,
30b1b0cf 2718 doc: /* Set the default value in CHAR-TABLE for generic character CH to VALUE.
47cebab1 2719The generic character specifies the group of characters.
2b048bf5
KH
2720If CH is a normal character, set the default value for a group of
2721characters to which CH belongs.
30b1b0cf 2722See also the documentation of `make-char'. */)
e9d8ddc9 2723 (char_table, ch, value)
e1335ba2
KH
2724 Lisp_Object char_table, ch, value;
2725{
ada0fa14 2726 int c, charset, code1, code2;
e1335ba2
KH
2727 Lisp_Object temp;
2728
b7826503
PJ
2729 CHECK_CHAR_TABLE (char_table);
2730 CHECK_NUMBER (ch);
e1335ba2
KH
2731
2732 c = XINT (ch);
2db66414 2733 SPLIT_CHAR (c, charset, code1, code2);
0da528a9
KH
2734
2735 /* Since we may want to set the default value for a character set
2736 not yet defined, we check only if the character set is in the
2737 valid range or not, instead of it is already defined or not. */
2738 if (! CHARSET_VALID_P (charset))
f71599f4 2739 invalid_character (c);
e1335ba2 2740
2b048bf5
KH
2741 if (SINGLE_BYTE_CHAR_P (c))
2742 {
2743 /* We use special slots for the default values of single byte
2744 characters. */
2745 int default_slot
2746 = (c < 0x80 ? CHAR_TABLE_DEFAULT_SLOT_ASCII
2747 : c < 0xA0 ? CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
2748 : CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC);
2749
2750 return (XCHAR_TABLE (char_table)->contents[default_slot] = value);
2751 }
e1335ba2
KH
2752
2753 /* Even if C is not a generic char, we had better behave as if a
2754 generic char is specified. */
c1fd9232 2755 if (!CHARSET_DEFINED_P (charset) || CHARSET_DIMENSION (charset) == 1)
e1335ba2
KH
2756 code1 = 0;
2757 temp = XCHAR_TABLE (char_table)->contents[charset + 128];
2b048bf5
KH
2758 if (! SUB_CHAR_TABLE_P (temp))
2759 {
2760 temp = make_sub_char_table (temp);
2761 XCHAR_TABLE (char_table)->contents[charset + 128] = temp;
2762 }
e1335ba2
KH
2763 if (!code1)
2764 {
2b048bf5 2765 XCHAR_TABLE (temp)->defalt = value;
e1335ba2
KH
2766 return value;
2767 }
2b048bf5 2768 char_table = temp;
e1335ba2
KH
2769 temp = XCHAR_TABLE (char_table)->contents[code1];
2770 if (SUB_CHAR_TABLE_P (temp))
2771 XCHAR_TABLE (temp)->defalt = value;
2772 else
2773 XCHAR_TABLE (char_table)->contents[code1] = value;
2774 return value;
2775}
1d969a23
RS
2776
2777/* Look up the element in TABLE at index CH,
2778 and return it as an integer.
2779 If the element is nil, return CH itself.
2780 (Actually we do that for any non-integer.) */
2781
2782int
2783char_table_translate (table, ch)
2784 Lisp_Object table;
2785 int ch;
2786{
2787 Lisp_Object value;
2788 value = Faref (table, make_number (ch));
2789 if (! INTEGERP (value))
2790 return ch;
2791 return XINT (value);
2792}
52ef6c89
KH
2793
2794static void
2795optimize_sub_char_table (table, chars)
2796 Lisp_Object *table;
2797 int chars;
2798{
2799 Lisp_Object elt;
2800 int from, to;
2801
2802 if (chars == 94)
2803 from = 33, to = 127;
2804 else
2805 from = 32, to = 128;
2806
2807 if (!SUB_CHAR_TABLE_P (*table))
2808 return;
2809 elt = XCHAR_TABLE (*table)->contents[from++];
2810 for (; from < to; from++)
2811 if (NILP (Fequal (elt, XCHAR_TABLE (*table)->contents[from])))
2812 return;
2813 *table = elt;
2814}
2815
2816DEFUN ("optimize-char-table", Foptimize_char_table, Soptimize_char_table,
e9d8ddc9
MB
2817 1, 1, 0, doc: /* Optimize char table TABLE. */)
2818 (table)
52ef6c89
KH
2819 Lisp_Object table;
2820{
2821 Lisp_Object elt;
2822 int dim;
2823 int i, j;
2824
b7826503 2825 CHECK_CHAR_TABLE (table);
52ef6c89
KH
2826
2827 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
2828 {
2829 elt = XCHAR_TABLE (table)->contents[i];
2830 if (!SUB_CHAR_TABLE_P (elt))
2831 continue;
4a8009a0 2832 dim = CHARSET_DIMENSION (i - 128);
52ef6c89
KH
2833 if (dim == 2)
2834 for (j = 32; j < SUB_CHAR_TABLE_ORDINARY_SLOTS; j++)
2835 optimize_sub_char_table (XCHAR_TABLE (elt)->contents + j, dim);
2836 optimize_sub_char_table (XCHAR_TABLE (table)->contents + i, dim);
2837 }
2838 return Qnil;
2839}
2840
e03f7933 2841\f
46ed603f 2842/* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
c8640abf
RS
2843 character or group of characters that share a value.
2844 DEPTH is the current depth in the originally specified
2845 chartable, and INDICES contains the vector indices
46ed603f
RS
2846 for the levels our callers have descended.
2847
2848 ARG is passed to C_FUNCTION when that is called. */
c8640abf
RS
2849
2850void
44356f63 2851map_char_table (c_function, function, table, subtable, arg, depth, indices)
22e6f12b 2852 void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
44356f63 2853 Lisp_Object function, table, subtable, arg, *indices;
1847b19b 2854 int depth;
e03f7933 2855{
3720677d 2856 int i, to;
91244343
SM
2857 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2858
2859 GCPRO4 (arg, table, subtable, function);
e03f7933 2860
a8283a4a 2861 if (depth == 0)
3720677d
KH
2862 {
2863 /* At first, handle ASCII and 8-bit European characters. */
2864 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
2865 {
44356f63
RS
2866 Lisp_Object elt= XCHAR_TABLE (subtable)->contents[i];
2867 if (NILP (elt))
2868 elt = XCHAR_TABLE (subtable)->defalt;
2869 if (NILP (elt))
2870 elt = Faref (subtable, make_number (i));
3720677d 2871 if (c_function)
46ed603f 2872 (*c_function) (arg, make_number (i), elt);
3720677d
KH
2873 else
2874 call2 (function, make_number (i), elt);
2875 }
ea35ce3d
RS
2876#if 0 /* If the char table has entries for higher characters,
2877 we should report them. */
de86fcba 2878 if (NILP (current_buffer->enable_multibyte_characters))
91244343
SM
2879 {
2880 UNGCPRO;
2881 return;
2882 }
ea35ce3d 2883#endif
3720677d
KH
2884 to = CHAR_TABLE_ORDINARY_SLOTS;
2885 }
a8283a4a 2886 else
e03f7933 2887 {
a3b210c4
KH
2888 int charset = XFASTINT (indices[0]) - 128;
2889
de86fcba 2890 i = 32;
3720677d 2891 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
a3b210c4
KH
2892 if (CHARSET_CHARS (charset) == 94)
2893 i++, to--;
e03f7933
RS
2894 }
2895
7e798f25 2896 for (; i < to; i++)
e03f7933 2897 {
a3b210c4
KH
2898 Lisp_Object elt;
2899 int charset;
3720677d 2900
a3b210c4 2901 elt = XCHAR_TABLE (subtable)->contents[i];
09ee221d 2902 XSETFASTINT (indices[depth], i);
a3b210c4 2903 charset = XFASTINT (indices[0]) - 128;
df2fbceb
KH
2904 if (depth == 0
2905 && (!CHARSET_DEFINED_P (charset)
2906 || charset == CHARSET_8_BIT_CONTROL
2907 || charset == CHARSET_8_BIT_GRAPHIC))
a3b210c4 2908 continue;
3720677d
KH
2909
2910 if (SUB_CHAR_TABLE_P (elt))
2911 {
2912 if (depth >= 3)
2913 error ("Too deep char table");
44356f63 2914 map_char_table (c_function, function, table, elt, arg, depth + 1, indices);
3720677d 2915 }
e03f7933 2916 else
a8283a4a 2917 {
a3b210c4 2918 int c1, c2, c;
3720677d 2919
a3b210c4
KH
2920 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
2921 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
2efdd1b9 2922 c = MAKE_CHAR (charset, c1, c2);
fdf91be0
RS
2923
2924 if (NILP (elt))
2925 elt = XCHAR_TABLE (subtable)->defalt;
2926 if (NILP (elt))
2927 elt = Faref (table, make_number (c));
2928
a3b210c4
KH
2929 if (c_function)
2930 (*c_function) (arg, make_number (c), elt);
2931 else
2932 call2 (function, make_number (c), elt);
b4f334f7 2933 }
e03f7933 2934 }
91244343 2935 UNGCPRO;
e03f7933
RS
2936}
2937
e52bd6b7
SM
2938static void void_call2 P_ ((Lisp_Object a, Lisp_Object b, Lisp_Object c));
2939static void
2940void_call2 (a, b, c)
2941 Lisp_Object a, b, c;
2942{
2943 call2 (a, b, c);
2944}
2945
e03f7933 2946DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
47cebab1 2947 2, 2, 0,
e9d8ddc9 2948 doc: /* Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.
47cebab1 2949FUNCTION is called with two arguments--a key and a value.
e9d8ddc9
MB
2950The key is always a possible IDX argument to `aref'. */)
2951 (function, char_table)
88fe8140 2952 Lisp_Object function, char_table;
e03f7933 2953{
3720677d 2954 /* The depth of char table is at most 3. */
7e798f25
KH
2955 Lisp_Object indices[3];
2956
b7826503 2957 CHECK_CHAR_TABLE (char_table);
e03f7933 2958
e52bd6b7
SM
2959 /* When Lisp_Object is represented as a union, `call2' cannot directly
2960 be passed to map_char_table because it returns a Lisp_Object rather
2961 than returning nothing.
2962 Casting leads to crashes on some architectures. -stef */
44356f63 2963 map_char_table (void_call2, Qnil, char_table, char_table, function, 0, indices);
e03f7933
RS
2964 return Qnil;
2965}
2f729392
KH
2966
2967/* Return a value for character C in char-table TABLE. Store the
2968 actual index for that value in *IDX. Ignore the default value of
2969 TABLE. */
2970
2971Lisp_Object
2972char_table_ref_and_index (table, c, idx)
2973 Lisp_Object table;
2974 int c, *idx;
2975{
2976 int charset, c1, c2;
2977 Lisp_Object elt;
2978
2979 if (SINGLE_BYTE_CHAR_P (c))
2980 {
2981 *idx = c;
2982 return XCHAR_TABLE (table)->contents[c];
2983 }
2984 SPLIT_CHAR (c, charset, c1, c2);
2985 elt = XCHAR_TABLE (table)->contents[charset + 128];
2986 *idx = MAKE_CHAR (charset, 0, 0);
2987 if (!SUB_CHAR_TABLE_P (elt))
2988 return elt;
2989 if (c1 < 32 || NILP (XCHAR_TABLE (elt)->contents[c1]))
2990 return XCHAR_TABLE (elt)->defalt;
2991 elt = XCHAR_TABLE (elt)->contents[c1];
2992 *idx = MAKE_CHAR (charset, c1, 0);
2993 if (!SUB_CHAR_TABLE_P (elt))
2994 return elt;
2995 if (c2 < 32 || NILP (XCHAR_TABLE (elt)->contents[c2]))
2996 return XCHAR_TABLE (elt)->defalt;
2997 *idx = c;
2998 return XCHAR_TABLE (elt)->contents[c2];
2999}
3000
e03f7933 3001\f
7b863bd5
JB
3002/* ARGSUSED */
3003Lisp_Object
3004nconc2 (s1, s2)
3005 Lisp_Object s1, s2;
3006{
3007#ifdef NO_ARG_ARRAY
3008 Lisp_Object args[2];
3009 args[0] = s1;
3010 args[1] = s2;
3011 return Fnconc (2, args);
3012#else
3013 return Fnconc (2, &s1);
3014#endif /* NO_ARG_ARRAY */
3015}
3016
3017DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
e9d8ddc9 3018 doc: /* Concatenate any number of lists by altering them.
4bf8e2a3
MB
3019Only the last argument is not altered, and need not be a list.
3020usage: (nconc &rest LISTS) */)
e9d8ddc9 3021 (nargs, args)
7b863bd5
JB
3022 int nargs;
3023 Lisp_Object *args;
3024{
3025 register int argnum;
3026 register Lisp_Object tail, tem, val;
3027
093386ca 3028 val = tail = Qnil;
7b863bd5
JB
3029
3030 for (argnum = 0; argnum < nargs; argnum++)
3031 {
3032 tem = args[argnum];
265a9e55 3033 if (NILP (tem)) continue;
7b863bd5 3034
265a9e55 3035 if (NILP (val))
7b863bd5
JB
3036 val = tem;
3037
3038 if (argnum + 1 == nargs) break;
3039
3040 if (!CONSP (tem))
3041 tem = wrong_type_argument (Qlistp, tem);
3042
3043 while (CONSP (tem))
3044 {
3045 tail = tem;
cf42cb72 3046 tem = XCDR (tail);
7b863bd5
JB
3047 QUIT;
3048 }
3049
3050 tem = args[argnum + 1];
3051 Fsetcdr (tail, tem);
265a9e55 3052 if (NILP (tem))
7b863bd5
JB
3053 args[argnum + 1] = tail;
3054 }
3055
3056 return val;
3057}
3058\f
3059/* This is the guts of all mapping functions.
ea35ce3d
RS
3060 Apply FN to each element of SEQ, one by one,
3061 storing the results into elements of VALS, a C vector of Lisp_Objects.
3062 LENI is the length of VALS, which should also be the length of SEQ. */
7b863bd5
JB
3063
3064static void
3065mapcar1 (leni, vals, fn, seq)
3066 int leni;
3067 Lisp_Object *vals;
3068 Lisp_Object fn, seq;
3069{
3070 register Lisp_Object tail;
3071 Lisp_Object dummy;
3072 register int i;
3073 struct gcpro gcpro1, gcpro2, gcpro3;
3074
f5c75033
DL
3075 if (vals)
3076 {
3077 /* Don't let vals contain any garbage when GC happens. */
3078 for (i = 0; i < leni; i++)
3079 vals[i] = Qnil;
7b863bd5 3080
f5c75033
DL
3081 GCPRO3 (dummy, fn, seq);
3082 gcpro1.var = vals;
3083 gcpro1.nvars = leni;
3084 }
3085 else
3086 GCPRO2 (fn, seq);
7b863bd5
JB
3087 /* We need not explicitly protect `tail' because it is used only on lists, and
3088 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
3089
7650760e 3090 if (VECTORP (seq))
7b863bd5
JB
3091 {
3092 for (i = 0; i < leni; i++)
3093 {
3094 dummy = XVECTOR (seq)->contents[i];
f5c75033
DL
3095 dummy = call1 (fn, dummy);
3096 if (vals)
3097 vals[i] = dummy;
7b863bd5
JB
3098 }
3099 }
33aa0881
KH
3100 else if (BOOL_VECTOR_P (seq))
3101 {
3102 for (i = 0; i < leni; i++)
3103 {
3104 int byte;
db85986c
AS
3105 byte = XBOOL_VECTOR (seq)->data[i / BOOL_VECTOR_BITS_PER_CHAR];
3106 if (byte & (1 << (i % BOOL_VECTOR_BITS_PER_CHAR)))
33aa0881
KH
3107 dummy = Qt;
3108 else
3109 dummy = Qnil;
3110
f5c75033
DL
3111 dummy = call1 (fn, dummy);
3112 if (vals)
3113 vals[i] = dummy;
33aa0881
KH
3114 }
3115 }
ea35ce3d
RS
3116 else if (STRINGP (seq))
3117 {
ea35ce3d
RS
3118 int i_byte;
3119
3120 for (i = 0, i_byte = 0; i < leni;)
3121 {
3122 int c;
0ab6a3d8
KH
3123 int i_before = i;
3124
3125 FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte);
ea35ce3d 3126 XSETFASTINT (dummy, c);
f5c75033
DL
3127 dummy = call1 (fn, dummy);
3128 if (vals)
3129 vals[i_before] = dummy;
ea35ce3d
RS
3130 }
3131 }
7b863bd5
JB
3132 else /* Must be a list, since Flength did not get an error */
3133 {
3134 tail = seq;
85946364 3135 for (i = 0; i < leni && CONSP (tail); i++)
7b863bd5 3136 {
85946364 3137 dummy = call1 (fn, XCAR (tail));
f5c75033
DL
3138 if (vals)
3139 vals[i] = dummy;
70949dac 3140 tail = XCDR (tail);
7b863bd5
JB
3141 }
3142 }
3143
3144 UNGCPRO;
3145}
3146
3147DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
e9d8ddc9 3148 doc: /* Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.
dd8d1e71 3149In between each pair of results, stick in SEPARATOR. Thus, " " as
47cebab1 3150SEPARATOR results in spaces between the values returned by FUNCTION.
e9d8ddc9
MB
3151SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
3152 (function, sequence, separator)
88fe8140 3153 Lisp_Object function, sequence, separator;
7b863bd5
JB
3154{
3155 Lisp_Object len;
3156 register int leni;
3157 int nargs;
3158 register Lisp_Object *args;
3159 register int i;
3160 struct gcpro gcpro1;
799c08ac
KS
3161 Lisp_Object ret;
3162 USE_SAFE_ALLOCA;
7b863bd5 3163
88fe8140 3164 len = Flength (sequence);
7b863bd5
JB
3165 leni = XINT (len);
3166 nargs = leni + leni - 1;
3167 if (nargs < 0) return build_string ("");
3168
7b4cd44a 3169 SAFE_ALLOCA_LISP (args, nargs);
7b863bd5 3170
88fe8140
EN
3171 GCPRO1 (separator);
3172 mapcar1 (leni, args, function, sequence);
7b863bd5
JB
3173 UNGCPRO;
3174
85946364 3175 for (i = leni - 1; i > 0; i--)
7b863bd5 3176 args[i + i] = args[i];
b4f334f7 3177
7b863bd5 3178 for (i = 1; i < nargs; i += 2)
88fe8140 3179 args[i] = separator;
7b863bd5 3180
799c08ac 3181 ret = Fconcat (nargs, args);
233f3db6 3182 SAFE_FREE ();
799c08ac
KS
3183
3184 return ret;
7b863bd5
JB
3185}
3186
3187DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
e9d8ddc9 3188 doc: /* Apply FUNCTION to each element of SEQUENCE, and make a list of the results.
47cebab1 3189The result is a list just as long as SEQUENCE.
e9d8ddc9
MB
3190SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
3191 (function, sequence)
88fe8140 3192 Lisp_Object function, sequence;
7b863bd5
JB
3193{
3194 register Lisp_Object len;
3195 register int leni;
3196 register Lisp_Object *args;
799c08ac
KS
3197 Lisp_Object ret;
3198 USE_SAFE_ALLOCA;
7b863bd5 3199
88fe8140 3200 len = Flength (sequence);
7b863bd5 3201 leni = XFASTINT (len);
799c08ac 3202
7b4cd44a 3203 SAFE_ALLOCA_LISP (args, leni);
7b863bd5 3204
88fe8140 3205 mapcar1 (leni, args, function, sequence);
7b863bd5 3206
799c08ac 3207 ret = Flist (leni, args);
233f3db6 3208 SAFE_FREE ();
799c08ac
KS
3209
3210 return ret;
7b863bd5 3211}
f5c75033
DL
3212
3213DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0,
e9d8ddc9 3214 doc: /* Apply FUNCTION to each element of SEQUENCE for side effects only.
47cebab1 3215Unlike `mapcar', don't accumulate the results. Return SEQUENCE.
e9d8ddc9
MB
3216SEQUENCE may be a list, a vector, a bool-vector, or a string. */)
3217 (function, sequence)
f5c75033
DL
3218 Lisp_Object function, sequence;
3219{
3220 register int leni;
3221
3222 leni = XFASTINT (Flength (sequence));
3223 mapcar1 (leni, 0, function, sequence);
3224
3225 return sequence;
3226}
7b863bd5
JB
3227\f
3228/* Anything that calls this function must protect from GC! */
3229
3230DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
e9d8ddc9 3231 doc: /* Ask user a "y or n" question. Return t if answer is "y".
47cebab1
GM
3232Takes one argument, which is the string to display to ask the question.
3233It should end in a space; `y-or-n-p' adds `(y or n) ' to it.
3234No confirmation of the answer is requested; a single character is enough.
3235Also accepts Space to mean yes, or Delete to mean no. \(Actually, it uses
3236the bindings in `query-replace-map'; see the documentation of that variable
3237for more information. In this case, the useful bindings are `act', `skip',
3238`recenter', and `quit'.\)
3239
3240Under a windowing system a dialog box will be used if `last-nonmenu-event'
e9d8ddc9
MB
3241is nil and `use-dialog-box' is non-nil. */)
3242 (prompt)
7b863bd5
JB
3243 Lisp_Object prompt;
3244{
2b8503ea 3245 register Lisp_Object obj, key, def, map;
f5313ed9 3246 register int answer;
7b863bd5
JB
3247 Lisp_Object xprompt;
3248 Lisp_Object args[2];
7b863bd5 3249 struct gcpro gcpro1, gcpro2;
aed13378 3250 int count = SPECPDL_INDEX ();
eb4ffa4e
RS
3251
3252 specbind (Qcursor_in_echo_area, Qt);
7b863bd5 3253
f5313ed9
RS
3254 map = Fsymbol_value (intern ("query-replace-map"));
3255
b7826503 3256 CHECK_STRING (prompt);
7b863bd5
JB
3257 xprompt = prompt;
3258 GCPRO2 (prompt, xprompt);
3259
eff95916 3260#ifdef HAVE_X_WINDOWS
df6c90d8
GM
3261 if (display_hourglass_p)
3262 cancel_hourglass ();
eff95916 3263#endif
59f953a2 3264
7b863bd5
JB
3265 while (1)
3266 {
eb4ffa4e 3267
0ef68e8a 3268#ifdef HAVE_MENUS
588064ce 3269 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
bdd8d692 3270 && use_dialog_box
0ef68e8a 3271 && have_menus_p ())
1db4cfb2
RS
3272 {
3273 Lisp_Object pane, menu;
3007ebfb 3274 redisplay_preserve_echo_area (3);
1db4cfb2
RS
3275 pane = Fcons (Fcons (build_string ("Yes"), Qt),
3276 Fcons (Fcons (build_string ("No"), Qnil),
3277 Qnil));
ec26e1b9 3278 menu = Fcons (prompt, pane);
f0a31d70 3279 obj = Fx_popup_dialog (Qt, menu, Qnil);
1db4cfb2
RS
3280 answer = !NILP (obj);
3281 break;
3282 }
0ef68e8a 3283#endif /* HAVE_MENUS */
dfa89228 3284 cursor_in_echo_area = 1;
b312cc52 3285 choose_minibuf_frame ();
927be332
PJ
3286
3287 {
3288 Lisp_Object pargs[3];
3289
bcb31b2a 3290 /* Colorize prompt according to `minibuffer-prompt' face. */
927be332
PJ
3291 pargs[0] = build_string ("%s(y or n) ");
3292 pargs[1] = intern ("face");
3293 pargs[2] = intern ("minibuffer-prompt");
3294 args[0] = Fpropertize (3, pargs);
3295 args[1] = xprompt;
3296 Fmessage (2, args);
3297 }
7b863bd5 3298
2d8e7e1f
RS
3299 if (minibuffer_auto_raise)
3300 {
3301 Lisp_Object mini_frame;
3302
3303 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
3304
3305 Fraise_frame (mini_frame);
3306 }
3307
7ba13c57 3308 obj = read_filtered_event (1, 0, 0, 0);
dfa89228
KH
3309 cursor_in_echo_area = 0;
3310 /* If we need to quit, quit with cursor_in_echo_area = 0. */
3311 QUIT;
a63f658b 3312
f5313ed9 3313 key = Fmake_vector (make_number (1), obj);
aad2a123 3314 def = Flookup_key (map, key, Qt);
7b863bd5 3315
f5313ed9
RS
3316 if (EQ (def, intern ("skip")))
3317 {
3318 answer = 0;
3319 break;
3320 }
3321 else if (EQ (def, intern ("act")))
3322 {
3323 answer = 1;
3324 break;
3325 }
29944b73
RS
3326 else if (EQ (def, intern ("recenter")))
3327 {
3328 Frecenter (Qnil);
3329 xprompt = prompt;
3330 continue;
3331 }
f5313ed9 3332 else if (EQ (def, intern ("quit")))
7b863bd5 3333 Vquit_flag = Qt;
ec63af1b
RS
3334 /* We want to exit this command for exit-prefix,
3335 and this is the only way to do it. */
3336 else if (EQ (def, intern ("exit-prefix")))
3337 Vquit_flag = Qt;
f5313ed9 3338
7b863bd5 3339 QUIT;
20aa96aa
JB
3340
3341 /* If we don't clear this, then the next call to read_char will
3342 return quit_char again, and we'll enter an infinite loop. */
088880f1 3343 Vquit_flag = Qnil;
7b863bd5
JB
3344
3345 Fding (Qnil);
3346 Fdiscard_input ();
3347 if (EQ (xprompt, prompt))
3348 {
3349 args[0] = build_string ("Please answer y or n. ");
3350 args[1] = prompt;
3351 xprompt = Fconcat (2, args);
3352 }
3353 }
3354 UNGCPRO;
6a8a9750 3355
09c95874
RS
3356 if (! noninteractive)
3357 {
3358 cursor_in_echo_area = -1;
ea35ce3d
RS
3359 message_with_string (answer ? "%s(y or n) y" : "%s(y or n) n",
3360 xprompt, 0);
09c95874 3361 }
6a8a9750 3362
eb4ffa4e 3363 unbind_to (count, Qnil);
f5313ed9 3364 return answer ? Qt : Qnil;
7b863bd5
JB
3365}
3366\f
3367/* This is how C code calls `yes-or-no-p' and allows the user
3368 to redefined it.
3369
3370 Anything that calls this function must protect from GC! */
3371
3372Lisp_Object
3373do_yes_or_no_p (prompt)
3374 Lisp_Object prompt;
3375{
3376 return call1 (intern ("yes-or-no-p"), prompt);
3377}
3378
3379/* Anything that calls this function must protect from GC! */
3380
3381DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
e9d8ddc9 3382 doc: /* Ask user a yes-or-no question. Return t if answer is yes.
47cebab1
GM
3383Takes one argument, which is the string to display to ask the question.
3384It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.
3385The user must confirm the answer with RET,
3386and can edit it until it has been confirmed.
3387
3388Under a windowing system a dialog box will be used if `last-nonmenu-event'
e9d8ddc9
MB
3389is nil, and `use-dialog-box' is non-nil. */)
3390 (prompt)
7b863bd5
JB
3391 Lisp_Object prompt;
3392{
3393 register Lisp_Object ans;
3394 Lisp_Object args[2];
3395 struct gcpro gcpro1;
3396
b7826503 3397 CHECK_STRING (prompt);
7b863bd5 3398
0ef68e8a 3399#ifdef HAVE_MENUS
b4f334f7 3400 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
bdd8d692 3401 && use_dialog_box
0ef68e8a 3402 && have_menus_p ())
1db4cfb2
RS
3403 {
3404 Lisp_Object pane, menu, obj;
3007ebfb 3405 redisplay_preserve_echo_area (4);
1db4cfb2
RS
3406 pane = Fcons (Fcons (build_string ("Yes"), Qt),
3407 Fcons (Fcons (build_string ("No"), Qnil),
3408 Qnil));
3409 GCPRO1 (pane);
ec26e1b9 3410 menu = Fcons (prompt, pane);
f0a31d70 3411 obj = Fx_popup_dialog (Qt, menu, Qnil);
1db4cfb2
RS
3412 UNGCPRO;
3413 return obj;
3414 }
0ef68e8a 3415#endif /* HAVE_MENUS */
1db4cfb2 3416
7b863bd5
JB
3417 args[0] = prompt;
3418 args[1] = build_string ("(yes or no) ");
3419 prompt = Fconcat (2, args);
3420
3421 GCPRO1 (prompt);
1db4cfb2 3422
7b863bd5
JB
3423 while (1)
3424 {
0ce830bc 3425 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
b24014d4 3426 Qyes_or_no_p_history, Qnil,
8181f402 3427 Qnil, Qnil));
d5db4077 3428 if (SCHARS (ans) == 3 && !strcmp (SDATA (ans), "yes"))
7b863bd5
JB
3429 {
3430 UNGCPRO;
3431 return Qt;
3432 }
d5db4077 3433 if (SCHARS (ans) == 2 && !strcmp (SDATA (ans), "no"))
7b863bd5
JB
3434 {
3435 UNGCPRO;
3436 return Qnil;
3437 }
3438
3439 Fding (Qnil);
3440 Fdiscard_input ();
3441 message ("Please answer yes or no.");
99dc4745 3442 Fsleep_for (make_number (2), Qnil);
7b863bd5 3443 }
7b863bd5
JB
3444}
3445\f
f4b50f66 3446DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
e9d8ddc9 3447 doc: /* Return list of 1 minute, 5 minute and 15 minute load averages.
91f78c99 3448
47cebab1
GM
3449Each of the three load averages is multiplied by 100, then converted
3450to integer.
3451
3452When USE-FLOATS is non-nil, floats will be used instead of integers.
3453These floats are not multiplied by 100.
3454
3455If the 5-minute or 15-minute load averages are not available, return a
30b1b0cf
DL
3456shortened list, containing only those averages which are available.
3457
3458An error is thrown if the load average can't be obtained. In some
3459cases making it work would require Emacs being installed setuid or
3460setgid so that it can read kernel information, and that usually isn't
3461advisable. */)
e9d8ddc9 3462 (use_floats)
f4b50f66 3463 Lisp_Object use_floats;
7b863bd5 3464{
daa37602
JB
3465 double load_ave[3];
3466 int loads = getloadavg (load_ave, 3);
f4b50f66 3467 Lisp_Object ret = Qnil;
7b863bd5 3468
daa37602
JB
3469 if (loads < 0)
3470 error ("load-average not implemented for this operating system");
3471
f4b50f66
RS
3472 while (loads-- > 0)
3473 {
3474 Lisp_Object load = (NILP (use_floats) ?
3475 make_number ((int) (100.0 * load_ave[loads]))
3476 : make_float (load_ave[loads]));
3477 ret = Fcons (load, ret);
3478 }
daa37602
JB
3479
3480 return ret;
3481}
7b863bd5 3482\f
b56ba8de
SS
3483Lisp_Object Vfeatures, Qsubfeatures;
3484extern Lisp_Object Vafter_load_alist;
7b863bd5 3485
65550192 3486DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 2, 0,
e9d8ddc9 3487 doc: /* Returns t if FEATURE is present in this Emacs.
91f78c99 3488
47cebab1
GM
3489Use this to conditionalize execution of lisp code based on the
3490presence or absence of emacs or environment extensions.
3491Use `provide' to declare that a feature is available. This function
3492looks at the value of the variable `features'. The optional argument
e9d8ddc9
MB
3493SUBFEATURE can be used to check a specific subfeature of FEATURE. */)
3494 (feature, subfeature)
65550192 3495 Lisp_Object feature, subfeature;
7b863bd5
JB
3496{
3497 register Lisp_Object tem;
b7826503 3498 CHECK_SYMBOL (feature);
7b863bd5 3499 tem = Fmemq (feature, Vfeatures);
65550192 3500 if (!NILP (tem) && !NILP (subfeature))
37ebddef 3501 tem = Fmember (subfeature, Fget (feature, Qsubfeatures));
265a9e55 3502 return (NILP (tem)) ? Qnil : Qt;
7b863bd5
JB
3503}
3504
65550192 3505DEFUN ("provide", Fprovide, Sprovide, 1, 2, 0,
e9d8ddc9 3506 doc: /* Announce that FEATURE is a feature of the current Emacs.
47cebab1 3507The optional argument SUBFEATURES should be a list of symbols listing
e9d8ddc9
MB
3508particular subfeatures supported in this version of FEATURE. */)
3509 (feature, subfeatures)
65550192 3510 Lisp_Object feature, subfeatures;
7b863bd5
JB
3511{
3512 register Lisp_Object tem;
b7826503 3513 CHECK_SYMBOL (feature);
37ebddef 3514 CHECK_LIST (subfeatures);
265a9e55 3515 if (!NILP (Vautoload_queue))
7b863bd5
JB
3516 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
3517 tem = Fmemq (feature, Vfeatures);
265a9e55 3518 if (NILP (tem))
7b863bd5 3519 Vfeatures = Fcons (feature, Vfeatures);
65550192
SM
3520 if (!NILP (subfeatures))
3521 Fput (feature, Qsubfeatures, subfeatures);
68732608 3522 LOADHIST_ATTACH (Fcons (Qprovide, feature));
65550192
SM
3523
3524 /* Run any load-hooks for this file. */
3525 tem = Fassq (feature, Vafter_load_alist);
cf42cb72
SM
3526 if (CONSP (tem))
3527 Fprogn (XCDR (tem));
65550192 3528
7b863bd5
JB
3529 return feature;
3530}
1f79789d
RS
3531\f
3532/* `require' and its subroutines. */
3533
3534/* List of features currently being require'd, innermost first. */
3535
3536Lisp_Object require_nesting_list;
3537
b9d9a9b9 3538Lisp_Object
1f79789d
RS
3539require_unwind (old_value)
3540 Lisp_Object old_value;
3541{
b9d9a9b9 3542 return require_nesting_list = old_value;
1f79789d 3543}
7b863bd5 3544
53d5acf5 3545DEFUN ("require", Frequire, Srequire, 1, 3, 0,
e9d8ddc9 3546 doc: /* If feature FEATURE is not loaded, load it from FILENAME.
47cebab1
GM
3547If FEATURE is not a member of the list `features', then the feature
3548is not loaded; so load the file FILENAME.
3549If FILENAME is omitted, the printname of FEATURE is used as the file name,
8d70d574
LT
3550and `load' will try to load this name appended with the suffix `.elc' or
3551`.el', in that order. The name without appended suffix will not be used.
47cebab1
GM
3552If the optional third argument NOERROR is non-nil,
3553then return nil if the file is not found instead of signaling an error.
3554Normally the return value is FEATURE.
e9d8ddc9
MB
3555The normal messages at start and end of loading FILENAME are suppressed. */)
3556 (feature, filename, noerror)
81a81c0f 3557 Lisp_Object feature, filename, noerror;
7b863bd5
JB
3558{
3559 register Lisp_Object tem;
1f79789d
RS
3560 struct gcpro gcpro1, gcpro2;
3561
b7826503 3562 CHECK_SYMBOL (feature);
1f79789d 3563
5ba8f83d 3564 /* Record the presence of `require' in this file
9d5c2e7e
RS
3565 even if the feature specified is already loaded.
3566 But not more than once in any file,
3567 and not when we aren't loading a file. */
7aed223d 3568 if (load_in_progress)
9d5c2e7e
RS
3569 {
3570 tem = Fcons (Qrequire, feature);
3571 if (NILP (Fmember (tem, Vcurrent_load_list)))
3572 LOADHIST_ATTACH (tem);
3573 }
7b863bd5 3574 tem = Fmemq (feature, Vfeatures);
91f78c99 3575
265a9e55 3576 if (NILP (tem))
7b863bd5 3577 {
aed13378 3578 int count = SPECPDL_INDEX ();
1f79789d 3579 int nesting = 0;
bcb31b2a 3580
aea6173f
RS
3581 /* This is to make sure that loadup.el gives a clear picture
3582 of what files are preloaded and when. */
bcb31b2a
RS
3583 if (! NILP (Vpurify_flag))
3584 error ("(require %s) while preparing to dump",
d5db4077 3585 SDATA (SYMBOL_NAME (feature)));
91f78c99 3586
1f79789d
RS
3587 /* A certain amount of recursive `require' is legitimate,
3588 but if we require the same feature recursively 3 times,
3589 signal an error. */
3590 tem = require_nesting_list;
3591 while (! NILP (tem))
3592 {
3593 if (! NILP (Fequal (feature, XCAR (tem))))
3594 nesting++;
3595 tem = XCDR (tem);
3596 }
f707342d 3597 if (nesting > 3)
1f79789d 3598 error ("Recursive `require' for feature `%s'",
d5db4077 3599 SDATA (SYMBOL_NAME (feature)));
1f79789d
RS
3600
3601 /* Update the list for any nested `require's that occur. */
3602 record_unwind_protect (require_unwind, require_nesting_list);
3603 require_nesting_list = Fcons (feature, require_nesting_list);
7b863bd5
JB
3604
3605 /* Value saved here is to be restored into Vautoload_queue */
3606 record_unwind_protect (un_autoload, Vautoload_queue);
3607 Vautoload_queue = Qt;
3608
1f79789d
RS
3609 /* Load the file. */
3610 GCPRO2 (feature, filename);
81a81c0f
GM
3611 tem = Fload (NILP (filename) ? Fsymbol_name (feature) : filename,
3612 noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil));
1f79789d
RS
3613 UNGCPRO;
3614
53d5acf5
RS
3615 /* If load failed entirely, return nil. */
3616 if (NILP (tem))
41857307 3617 return unbind_to (count, Qnil);
7b863bd5
JB
3618
3619 tem = Fmemq (feature, Vfeatures);
265a9e55 3620 if (NILP (tem))
1f79789d 3621 error ("Required feature `%s' was not provided",
d5db4077 3622 SDATA (SYMBOL_NAME (feature)));
7b863bd5
JB
3623
3624 /* Once loading finishes, don't undo it. */
3625 Vautoload_queue = Qt;
3626 feature = unbind_to (count, feature);
3627 }
1f79789d 3628
7b863bd5
JB
3629 return feature;
3630}
3631\f
b4f334f7
KH
3632/* Primitives for work of the "widget" library.
3633 In an ideal world, this section would not have been necessary.
3634 However, lisp function calls being as slow as they are, it turns
3635 out that some functions in the widget library (wid-edit.el) are the
3636 bottleneck of Widget operation. Here is their translation to C,
3637 for the sole reason of efficiency. */
3638
a5254817 3639DEFUN ("plist-member", Fplist_member, Splist_member, 2, 2, 0,
e9d8ddc9 3640 doc: /* Return non-nil if PLIST has the property PROP.
47cebab1
GM
3641PLIST is a property list, which is a list of the form
3642\(PROP1 VALUE1 PROP2 VALUE2 ...\). PROP is a symbol.
3643Unlike `plist-get', this allows you to distinguish between a missing
3644property and a property with the value nil.
e9d8ddc9
MB
3645The value is actually the tail of PLIST whose car is PROP. */)
3646 (plist, prop)
b4f334f7
KH
3647 Lisp_Object plist, prop;
3648{
3649 while (CONSP (plist) && !EQ (XCAR (plist), prop))
3650 {
3651 QUIT;
3652 plist = XCDR (plist);
3653 plist = CDR (plist);
3654 }
3655 return plist;
3656}
3657
3658DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
e9d8ddc9
MB
3659 doc: /* In WIDGET, set PROPERTY to VALUE.
3660The value can later be retrieved with `widget-get'. */)
3661 (widget, property, value)
b4f334f7
KH
3662 Lisp_Object widget, property, value;
3663{
b7826503 3664 CHECK_CONS (widget);
f3fbd155 3665 XSETCDR (widget, Fplist_put (XCDR (widget), property, value));
f7993597 3666 return value;
b4f334f7
KH
3667}
3668
3669DEFUN ("widget-get", Fwidget_get, Swidget_get, 2, 2, 0,
e9d8ddc9 3670 doc: /* In WIDGET, get the value of PROPERTY.
47cebab1 3671The value could either be specified when the widget was created, or
e9d8ddc9
MB
3672later with `widget-put'. */)
3673 (widget, property)
b4f334f7
KH
3674 Lisp_Object widget, property;
3675{
3676 Lisp_Object tmp;
3677
3678 while (1)
3679 {
3680 if (NILP (widget))
3681 return Qnil;
b7826503 3682 CHECK_CONS (widget);
a5254817 3683 tmp = Fplist_member (XCDR (widget), property);
b4f334f7
KH
3684 if (CONSP (tmp))
3685 {
3686 tmp = XCDR (tmp);
3687 return CAR (tmp);
3688 }
3689 tmp = XCAR (widget);
3690 if (NILP (tmp))
3691 return Qnil;
3692 widget = Fget (tmp, Qwidget_type);
3693 }
3694}
3695
3696DEFUN ("widget-apply", Fwidget_apply, Swidget_apply, 2, MANY, 0,
e9d8ddc9 3697 doc: /* Apply the value of WIDGET's PROPERTY to the widget itself.
4bf8e2a3
MB
3698ARGS are passed as extra arguments to the function.
3699usage: (widget-apply WIDGET PROPERTY &rest ARGS) */)
e9d8ddc9 3700 (nargs, args)
b4f334f7
KH
3701 int nargs;
3702 Lisp_Object *args;
3703{
3704 /* This function can GC. */
3705 Lisp_Object newargs[3];
3706 struct gcpro gcpro1, gcpro2;
3707 Lisp_Object result;
3708
3709 newargs[0] = Fwidget_get (args[0], args[1]);
3710 newargs[1] = args[0];
3711 newargs[2] = Flist (nargs - 2, args + 2);
3712 GCPRO2 (newargs[0], newargs[2]);
3713 result = Fapply (3, newargs);
3714 UNGCPRO;
3715 return result;
3716}
dec002ca
DL
3717
3718#ifdef HAVE_LANGINFO_CODESET
3719#include <langinfo.h>
3720#endif
3721
d68beb2f
RS
3722DEFUN ("locale-info", Flocale_info, Slocale_info, 1, 1, 0,
3723 doc: /* Access locale data ITEM for the current C locale, if available.
3724ITEM should be one of the following:
30b1b0cf 3725
98aeeaa1 3726`codeset', returning the character set as a string (locale item CODESET);
30b1b0cf 3727
98aeeaa1 3728`days', returning a 7-element vector of day names (locale items DAY_n);
30b1b0cf 3729
98aeeaa1 3730`months', returning a 12-element vector of month names (locale items MON_n);
30b1b0cf 3731
d68beb2f
RS
3732`paper', returning a list (WIDTH HEIGHT) for the default paper size,
3733 both measured in milimeters (locale items PAPER_WIDTH, PAPER_HEIGHT).
dec002ca
DL
3734
3735If the system can't provide such information through a call to
d68beb2f 3736`nl_langinfo', or if ITEM isn't from the list above, return nil.
dec002ca 3737
98aeeaa1
DL
3738See also Info node `(libc)Locales'.
3739
dec002ca
DL
3740The data read from the system are decoded using `locale-coding-system'. */)
3741 (item)
3742 Lisp_Object item;
3743{
3744 char *str = NULL;
3745#ifdef HAVE_LANGINFO_CODESET
3746 Lisp_Object val;
3747 if (EQ (item, Qcodeset))
3748 {
3749 str = nl_langinfo (CODESET);
3750 return build_string (str);
3751 }
3752#ifdef DAY_1
3753 else if (EQ (item, Qdays)) /* e.g. for calendar-day-name-array */
3754 {
3755 Lisp_Object v = Fmake_vector (make_number (7), Qnil);
3756 int days[7] = {DAY_1, DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7};
3757 int i;
3758 synchronize_system_time_locale ();
3759 for (i = 0; i < 7; i++)
3760 {
3761 str = nl_langinfo (days[i]);
3762 val = make_unibyte_string (str, strlen (str));
3763 /* Fixme: Is this coding system necessarily right, even if
3764 it is consistent with CODESET? If not, what to do? */
3765 Faset (v, make_number (i),
3766 code_convert_string_norecord (val, Vlocale_coding_system,
e52bd6b7 3767 0));
dec002ca
DL
3768 }
3769 return v;
3770 }
3771#endif /* DAY_1 */
3772#ifdef MON_1
3773 else if (EQ (item, Qmonths)) /* e.g. for calendar-month-name-array */
3774 {
3775 struct Lisp_Vector *p = allocate_vector (12);
3776 int months[12] = {MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7,
3777 MON_8, MON_9, MON_10, MON_11, MON_12};
3778 int i;
3779 synchronize_system_time_locale ();
3780 for (i = 0; i < 12; i++)
3781 {
3782 str = nl_langinfo (months[i]);
3783 val = make_unibyte_string (str, strlen (str));
3784 p->contents[i] =
e52bd6b7 3785 code_convert_string_norecord (val, Vlocale_coding_system, 0);
dec002ca
DL
3786 }
3787 XSETVECTOR (val, p);
3788 return val;
3789 }
3790#endif /* MON_1 */
3791/* LC_PAPER stuff isn't defined as accessible in glibc as of 2.3.1,
3792 but is in the locale files. This could be used by ps-print. */
3793#ifdef PAPER_WIDTH
3794 else if (EQ (item, Qpaper))
3795 {
3796 return list2 (make_number (nl_langinfo (PAPER_WIDTH)),
3797 make_number (nl_langinfo (PAPER_HEIGHT)));
3798 }
3799#endif /* PAPER_WIDTH */
3800#endif /* HAVE_LANGINFO_CODESET*/
30b1b0cf 3801 return Qnil;
dec002ca 3802}
b4f334f7 3803\f
a90e80bf 3804/* base64 encode/decode functions (RFC 2045).
24c129e4
KH
3805 Based on code from GNU recode. */
3806
3807#define MIME_LINE_LENGTH 76
3808
3809#define IS_ASCII(Character) \
3810 ((Character) < 128)
3811#define IS_BASE64(Character) \
3812 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
9a092df0
PF
3813#define IS_BASE64_IGNORABLE(Character) \
3814 ((Character) == ' ' || (Character) == '\t' || (Character) == '\n' \
3815 || (Character) == '\f' || (Character) == '\r')
3816
3817/* Used by base64_decode_1 to retrieve a non-base64-ignorable
3818 character or return retval if there are no characters left to
3819 process. */
caff31d4
KH
3820#define READ_QUADRUPLET_BYTE(retval) \
3821 do \
3822 { \
3823 if (i == length) \
3824 { \
3825 if (nchars_return) \
3826 *nchars_return = nchars; \
3827 return (retval); \
3828 } \
3829 c = from[i++]; \
3830 } \
9a092df0 3831 while (IS_BASE64_IGNORABLE (c))
24c129e4
KH
3832
3833/* Table of characters coding the 64 values. */
3834static char base64_value_to_char[64] =
3835{
3836 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
3837 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
3838 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
3839 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
3840 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
3841 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
3842 '8', '9', '+', '/' /* 60-63 */
3843};
3844
3845/* Table of base64 values for first 128 characters. */
3846static short base64_char_to_value[128] =
3847{
3848 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
3849 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */
3850 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */
3851 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
3852 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
3853 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
3854 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
3855 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
3856 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
3857 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
3858 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
3859 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
3860 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
3861};
3862
3863/* The following diagram shows the logical steps by which three octets
3864 get transformed into four base64 characters.
3865
3866 .--------. .--------. .--------.
3867 |aaaaaabb| |bbbbcccc| |ccdddddd|
3868 `--------' `--------' `--------'
3869 6 2 4 4 2 6
3870 .--------+--------+--------+--------.
3871 |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
3872 `--------+--------+--------+--------'
3873
3874 .--------+--------+--------+--------.
3875 |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
3876 `--------+--------+--------+--------'
3877
3878 The octets are divided into 6 bit chunks, which are then encoded into
3879 base64 characters. */
3880
3881
2efdd1b9 3882static int base64_encode_1 P_ ((const char *, char *, int, int, int));
caff31d4 3883static int base64_decode_1 P_ ((const char *, char *, int, int, int *));
24c129e4
KH
3884
3885DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region,
3886 2, 3, "r",
e9d8ddc9 3887 doc: /* Base64-encode the region between BEG and END.
47cebab1
GM
3888Return the length of the encoded text.
3889Optional third argument NO-LINE-BREAK means do not break long lines
e9d8ddc9
MB
3890into shorter lines. */)
3891 (beg, end, no_line_break)
24c129e4
KH
3892 Lisp_Object beg, end, no_line_break;
3893{
3894 char *encoded;
3895 int allength, length;
3896 int ibeg, iend, encoded_length;
3897 int old_pos = PT;
799c08ac 3898 USE_SAFE_ALLOCA;
24c129e4
KH
3899
3900 validate_region (&beg, &end);
3901
3902 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
3903 iend = CHAR_TO_BYTE (XFASTINT (end));
3904 move_gap_both (XFASTINT (beg), ibeg);
3905
3906 /* We need to allocate enough room for encoding the text.
3907 We need 33 1/3% more space, plus a newline every 76
3908 characters, and then we round up. */
3909 length = iend - ibeg;
3910 allength = length + length/3 + 1;
3911 allength += allength / MIME_LINE_LENGTH + 1 + 6;
3912
799c08ac 3913 SAFE_ALLOCA (encoded, char *, allength);
24c129e4 3914 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
2efdd1b9
KH
3915 NILP (no_line_break),
3916 !NILP (current_buffer->enable_multibyte_characters));
24c129e4
KH
3917 if (encoded_length > allength)
3918 abort ();
3919
2efdd1b9
KH
3920 if (encoded_length < 0)
3921 {
3922 /* The encoding wasn't possible. */
233f3db6 3923 SAFE_FREE ();
a90e80bf 3924 error ("Multibyte character in data for base64 encoding");
2efdd1b9
KH
3925 }
3926
24c129e4
KH
3927 /* Now we have encoded the region, so we insert the new contents
3928 and delete the old. (Insert first in order to preserve markers.) */
8b835738 3929 SET_PT_BOTH (XFASTINT (beg), ibeg);
24c129e4 3930 insert (encoded, encoded_length);
233f3db6 3931 SAFE_FREE ();
24c129e4
KH
3932 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
3933
3934 /* If point was outside of the region, restore it exactly; else just
3935 move to the beginning of the region. */
3936 if (old_pos >= XFASTINT (end))
3937 old_pos += encoded_length - (XFASTINT (end) - XFASTINT (beg));
8b835738
AS
3938 else if (old_pos > XFASTINT (beg))
3939 old_pos = XFASTINT (beg);
24c129e4
KH
3940 SET_PT (old_pos);
3941
3942 /* We return the length of the encoded text. */
3943 return make_number (encoded_length);
3944}
3945
3946DEFUN ("base64-encode-string", Fbase64_encode_string, Sbase64_encode_string,
c22554ac 3947 1, 2, 0,
e9d8ddc9 3948 doc: /* Base64-encode STRING and return the result.
47cebab1 3949Optional second argument NO-LINE-BREAK means do not break long lines
e9d8ddc9
MB
3950into shorter lines. */)
3951 (string, no_line_break)
915b8312 3952 Lisp_Object string, no_line_break;
24c129e4
KH
3953{
3954 int allength, length, encoded_length;
3955 char *encoded;
4b2e75e6 3956 Lisp_Object encoded_string;
799c08ac 3957 USE_SAFE_ALLOCA;
24c129e4 3958
b7826503 3959 CHECK_STRING (string);
24c129e4 3960
7f8a0840
KH
3961 /* We need to allocate enough room for encoding the text.
3962 We need 33 1/3% more space, plus a newline every 76
3963 characters, and then we round up. */
d5db4077 3964 length = SBYTES (string);
7f8a0840
KH
3965 allength = length + length/3 + 1;
3966 allength += allength / MIME_LINE_LENGTH + 1 + 6;
24c129e4
KH
3967
3968 /* We need to allocate enough room for decoding the text. */
799c08ac 3969 SAFE_ALLOCA (encoded, char *, allength);
24c129e4 3970
d5db4077 3971 encoded_length = base64_encode_1 (SDATA (string),
2efdd1b9
KH
3972 encoded, length, NILP (no_line_break),
3973 STRING_MULTIBYTE (string));
24c129e4
KH
3974 if (encoded_length > allength)
3975 abort ();
3976
2efdd1b9
KH
3977 if (encoded_length < 0)
3978 {
3979 /* The encoding wasn't possible. */
233f3db6 3980 SAFE_FREE ();
a90e80bf 3981 error ("Multibyte character in data for base64 encoding");
2efdd1b9
KH
3982 }
3983
4b2e75e6 3984 encoded_string = make_unibyte_string (encoded, encoded_length);
233f3db6 3985 SAFE_FREE ();
4b2e75e6
EZ
3986
3987 return encoded_string;
24c129e4
KH
3988}
3989
3990static int
2efdd1b9 3991base64_encode_1 (from, to, length, line_break, multibyte)
24c129e4
KH
3992 const char *from;
3993 char *to;
3994 int length;
3995 int line_break;
2efdd1b9 3996 int multibyte;
24c129e4
KH
3997{
3998 int counter = 0, i = 0;
3999 char *e = to;
844eb643 4000 int c;
24c129e4 4001 unsigned int value;
2efdd1b9 4002 int bytes;
24c129e4
KH
4003
4004 while (i < length)
4005 {
2efdd1b9
KH
4006 if (multibyte)
4007 {
4008 c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
caff31d4 4009 if (c >= 256)
2efdd1b9 4010 return -1;
caff31d4 4011 i += bytes;
2efdd1b9
KH
4012 }
4013 else
4014 c = from[i++];
24c129e4
KH
4015
4016 /* Wrap line every 76 characters. */
4017
4018 if (line_break)
4019 {
4020 if (counter < MIME_LINE_LENGTH / 4)
4021 counter++;
4022 else
4023 {
4024 *e++ = '\n';
4025 counter = 1;
4026 }
4027 }
4028
4029 /* Process first byte of a triplet. */
4030
4031 *e++ = base64_value_to_char[0x3f & c >> 2];
4032 value = (0x03 & c) << 4;
4033
4034 /* Process second byte of a triplet. */
4035
4036 if (i == length)
4037 {
4038 *e++ = base64_value_to_char[value];
4039 *e++ = '=';
4040 *e++ = '=';
4041 break;
4042 }
4043
2efdd1b9
KH
4044 if (multibyte)
4045 {
4046 c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
caff31d4 4047 if (c >= 256)
844eb643 4048 return -1;
caff31d4 4049 i += bytes;
2efdd1b9
KH
4050 }
4051 else
4052 c = from[i++];
24c129e4
KH
4053
4054 *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
4055 value = (0x0f & c) << 2;
4056
4057 /* Process third byte of a triplet. */
4058
4059 if (i == length)
4060 {
4061 *e++ = base64_value_to_char[value];
4062 *e++ = '=';
4063 break;
4064 }
4065
2efdd1b9
KH
4066 if (multibyte)
4067 {
4068 c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes);
caff31d4 4069 if (c >= 256)
844eb643 4070 return -1;
caff31d4 4071 i += bytes;
2efdd1b9
KH
4072 }
4073 else
4074 c = from[i++];
24c129e4
KH
4075
4076 *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
4077 *e++ = base64_value_to_char[0x3f & c];
4078 }
4079
24c129e4
KH
4080 return e - to;
4081}
4082
4083
4084DEFUN ("base64-decode-region", Fbase64_decode_region, Sbase64_decode_region,
47cebab1 4085 2, 2, "r",
e9d8ddc9 4086 doc: /* Base64-decode the region between BEG and END.
47cebab1 4087Return the length of the decoded text.
e9d8ddc9
MB
4088If the region can't be decoded, signal an error and don't modify the buffer. */)
4089 (beg, end)
24c129e4
KH
4090 Lisp_Object beg, end;
4091{
caff31d4 4092 int ibeg, iend, length, allength;
24c129e4
KH
4093 char *decoded;
4094 int old_pos = PT;
4095 int decoded_length;
9b703a38 4096 int inserted_chars;
caff31d4 4097 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
799c08ac 4098 USE_SAFE_ALLOCA;
24c129e4
KH
4099
4100 validate_region (&beg, &end);
4101
4102 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
4103 iend = CHAR_TO_BYTE (XFASTINT (end));
4104
4105 length = iend - ibeg;
caff31d4
KH
4106
4107 /* We need to allocate enough room for decoding the text. If we are
4108 working on a multibyte buffer, each decoded code may occupy at
4109 most two bytes. */
4110 allength = multibyte ? length * 2 : length;
799c08ac 4111 SAFE_ALLOCA (decoded, char *, allength);
24c129e4
KH
4112
4113 move_gap_both (XFASTINT (beg), ibeg);
caff31d4
KH
4114 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length,
4115 multibyte, &inserted_chars);
4116 if (decoded_length > allength)
24c129e4
KH
4117 abort ();
4118
4119 if (decoded_length < 0)
8c217645
KH
4120 {
4121 /* The decoding wasn't possible. */
233f3db6 4122 SAFE_FREE ();
a90e80bf 4123 error ("Invalid base64 data");
8c217645 4124 }
24c129e4
KH
4125
4126 /* Now we have decoded the region, so we insert the new contents
4127 and delete the old. (Insert first in order to preserve markers.) */
59f953a2 4128 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
2efdd1b9 4129 insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0);
233f3db6 4130 SAFE_FREE ();
799c08ac 4131
2efdd1b9
KH
4132 /* Delete the original text. */
4133 del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars,
4134 iend + decoded_length, 1);
24c129e4
KH
4135
4136 /* If point was outside of the region, restore it exactly; else just
4137 move to the beginning of the region. */
4138 if (old_pos >= XFASTINT (end))
9b703a38
KH
4139 old_pos += inserted_chars - (XFASTINT (end) - XFASTINT (beg));
4140 else if (old_pos > XFASTINT (beg))
4141 old_pos = XFASTINT (beg);
e52ad9c9 4142 SET_PT (old_pos > ZV ? ZV : old_pos);
24c129e4 4143
9b703a38 4144 return make_number (inserted_chars);
24c129e4
KH
4145}
4146
4147DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
4148 1, 1, 0,
e9d8ddc9
MB
4149 doc: /* Base64-decode STRING and return the result. */)
4150 (string)
24c129e4
KH
4151 Lisp_Object string;
4152{
4153 char *decoded;
4154 int length, decoded_length;
4b2e75e6 4155 Lisp_Object decoded_string;
799c08ac 4156 USE_SAFE_ALLOCA;
24c129e4 4157
b7826503 4158 CHECK_STRING (string);
24c129e4 4159
d5db4077 4160 length = SBYTES (string);
24c129e4 4161 /* We need to allocate enough room for decoding the text. */
799c08ac 4162 SAFE_ALLOCA (decoded, char *, length);
24c129e4 4163
8ec118cd 4164 /* The decoded result should be unibyte. */
d5db4077 4165 decoded_length = base64_decode_1 (SDATA (string), decoded, length,
8ec118cd 4166 0, NULL);
24c129e4
KH
4167 if (decoded_length > length)
4168 abort ();
3d6c79c5 4169 else if (decoded_length >= 0)
2efdd1b9 4170 decoded_string = make_unibyte_string (decoded, decoded_length);
3d6c79c5
GM
4171 else
4172 decoded_string = Qnil;
24c129e4 4173
233f3db6 4174 SAFE_FREE ();
3d6c79c5 4175 if (!STRINGP (decoded_string))
a90e80bf 4176 error ("Invalid base64 data");
4b2e75e6
EZ
4177
4178 return decoded_string;
24c129e4
KH
4179}
4180
caff31d4
KH
4181/* Base64-decode the data at FROM of LENGHT bytes into TO. If
4182 MULTIBYTE is nonzero, the decoded result should be in multibyte
4183 form. If NCHARS_RETRUN is not NULL, store the number of produced
4184 characters in *NCHARS_RETURN. */
4185
24c129e4 4186static int
caff31d4 4187base64_decode_1 (from, to, length, multibyte, nchars_return)
24c129e4
KH
4188 const char *from;
4189 char *to;
4190 int length;
caff31d4
KH
4191 int multibyte;
4192 int *nchars_return;
24c129e4 4193{
9a092df0 4194 int i = 0;
24c129e4
KH
4195 char *e = to;
4196 unsigned char c;
4197 unsigned long value;
caff31d4 4198 int nchars = 0;
24c129e4 4199
9a092df0 4200 while (1)
24c129e4 4201 {
9a092df0 4202 /* Process first byte of a quadruplet. */
24c129e4 4203
9a092df0 4204 READ_QUADRUPLET_BYTE (e-to);
24c129e4
KH
4205
4206 if (!IS_BASE64 (c))
4207 return -1;
4208 value = base64_char_to_value[c] << 18;
4209
4210 /* Process second byte of a quadruplet. */
4211
9a092df0 4212 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
4213
4214 if (!IS_BASE64 (c))
4215 return -1;
4216 value |= base64_char_to_value[c] << 12;
4217
caff31d4
KH
4218 c = (unsigned char) (value >> 16);
4219 if (multibyte)
4220 e += CHAR_STRING (c, e);
4221 else
4222 *e++ = c;
4223 nchars++;
24c129e4
KH
4224
4225 /* Process third byte of a quadruplet. */
59f953a2 4226
9a092df0 4227 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
4228
4229 if (c == '=')
4230 {
9a092df0 4231 READ_QUADRUPLET_BYTE (-1);
59f953a2 4232
24c129e4
KH
4233 if (c != '=')
4234 return -1;
4235 continue;
4236 }
4237
4238 if (!IS_BASE64 (c))
4239 return -1;
4240 value |= base64_char_to_value[c] << 6;
4241
caff31d4
KH
4242 c = (unsigned char) (0xff & value >> 8);
4243 if (multibyte)
4244 e += CHAR_STRING (c, e);
4245 else
4246 *e++ = c;
4247 nchars++;
24c129e4
KH
4248
4249 /* Process fourth byte of a quadruplet. */
4250
9a092df0 4251 READ_QUADRUPLET_BYTE (-1);
24c129e4
KH
4252
4253 if (c == '=')
4254 continue;
4255
4256 if (!IS_BASE64 (c))
4257 return -1;
4258 value |= base64_char_to_value[c];
4259
caff31d4
KH
4260 c = (unsigned char) (0xff & value);
4261 if (multibyte)
4262 e += CHAR_STRING (c, e);
4263 else
4264 *e++ = c;
4265 nchars++;
24c129e4 4266 }
24c129e4 4267}
d80c6c11
GM
4268
4269
4270\f
4271/***********************************************************************
4272 ***** *****
4273 ***** Hash Tables *****
4274 ***** *****
4275 ***********************************************************************/
4276
4277/* Implemented by gerd@gnu.org. This hash table implementation was
4278 inspired by CMUCL hash tables. */
4279
4280/* Ideas:
4281
4282 1. For small tables, association lists are probably faster than
4283 hash tables because they have lower overhead.
4284
4285 For uses of hash tables where the O(1) behavior of table
4286 operations is not a requirement, it might therefore be a good idea
4287 not to hash. Instead, we could just do a linear search in the
4288 key_and_value vector of the hash table. This could be done
4289 if a `:linear-search t' argument is given to make-hash-table. */
4290
4291
d80c6c11
GM
4292/* The list of all weak hash tables. Don't staticpro this one. */
4293
4294Lisp_Object Vweak_hash_tables;
4295
4296/* Various symbols. */
4297
f899c503 4298Lisp_Object Qhash_table_p, Qeq, Qeql, Qequal, Qkey, Qvalue;
ee0403b3 4299Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
ec504e6f 4300Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
d80c6c11
GM
4301
4302/* Function prototypes. */
4303
4304static struct Lisp_Hash_Table *check_hash_table P_ ((Lisp_Object));
d80c6c11 4305static int get_key_arg P_ ((Lisp_Object, int, Lisp_Object *, char *));
d80c6c11 4306static void maybe_resize_hash_table P_ ((struct Lisp_Hash_Table *));
d80c6c11
GM
4307static int cmpfn_eql P_ ((struct Lisp_Hash_Table *, Lisp_Object, unsigned,
4308 Lisp_Object, unsigned));
4309static int cmpfn_equal P_ ((struct Lisp_Hash_Table *, Lisp_Object, unsigned,
4310 Lisp_Object, unsigned));
4311static int cmpfn_user_defined P_ ((struct Lisp_Hash_Table *, Lisp_Object,
4312 unsigned, Lisp_Object, unsigned));
4313static unsigned hashfn_eq P_ ((struct Lisp_Hash_Table *, Lisp_Object));
4314static unsigned hashfn_eql P_ ((struct Lisp_Hash_Table *, Lisp_Object));
4315static unsigned hashfn_equal P_ ((struct Lisp_Hash_Table *, Lisp_Object));
4316static unsigned hashfn_user_defined P_ ((struct Lisp_Hash_Table *,
4317 Lisp_Object));
4318static unsigned sxhash_string P_ ((unsigned char *, int));
4319static unsigned sxhash_list P_ ((Lisp_Object, int));
4320static unsigned sxhash_vector P_ ((Lisp_Object, int));
4321static unsigned sxhash_bool_vector P_ ((Lisp_Object));
a0b581cc 4322static int sweep_weak_table P_ ((struct Lisp_Hash_Table *, int));
d80c6c11
GM
4323
4324
4325\f
4326/***********************************************************************
4327 Utilities
4328 ***********************************************************************/
4329
4330/* If OBJ is a Lisp hash table, return a pointer to its struct
4331 Lisp_Hash_Table. Otherwise, signal an error. */
4332
4333static struct Lisp_Hash_Table *
4334check_hash_table (obj)
4335 Lisp_Object obj;
4336{
b7826503 4337 CHECK_HASH_TABLE (obj);
d80c6c11
GM
4338 return XHASH_TABLE (obj);
4339}
4340
4341
4342/* Value is the next integer I >= N, N >= 0 which is "almost" a prime
4343 number. */
4344
6e509e80 4345int
d80c6c11
GM
4346next_almost_prime (n)
4347 int n;
4348{
4349 if (n % 2 == 0)
4350 n += 1;
4351 if (n % 3 == 0)
4352 n += 2;
4353 if (n % 7 == 0)
4354 n += 4;
4355 return n;
4356}
4357
4358
4359/* Find KEY in ARGS which has size NARGS. Don't consider indices for
4360 which USED[I] is non-zero. If found at index I in ARGS, set
4361 USED[I] and USED[I + 1] to 1, and return I + 1. Otherwise return
4362 -1. This function is used to extract a keyword/argument pair from
4363 a DEFUN parameter list. */
4364
4365static int
4366get_key_arg (key, nargs, args, used)
4367 Lisp_Object key;
4368 int nargs;
4369 Lisp_Object *args;
4370 char *used;
4371{
4372 int i;
59f953a2 4373
d80c6c11
GM
4374 for (i = 0; i < nargs - 1; ++i)
4375 if (!used[i] && EQ (args[i], key))
4376 break;
59f953a2 4377
d80c6c11
GM
4378 if (i >= nargs - 1)
4379 i = -1;
4380 else
4381 {
4382 used[i++] = 1;
4383 used[i] = 1;
4384 }
59f953a2 4385
d80c6c11
GM
4386 return i;
4387}
4388
4389
4390/* Return a Lisp vector which has the same contents as VEC but has
4391 size NEW_SIZE, NEW_SIZE >= VEC->size. Entries in the resulting
4392 vector that are not copied from VEC are set to INIT. */
4393
fa7dad5b 4394Lisp_Object
d80c6c11
GM
4395larger_vector (vec, new_size, init)
4396 Lisp_Object vec;
4397 int new_size;
4398 Lisp_Object init;
4399{
4400 struct Lisp_Vector *v;
4401 int i, old_size;
4402
4403 xassert (VECTORP (vec));
4404 old_size = XVECTOR (vec)->size;
4405 xassert (new_size >= old_size);
4406
b3660ef6 4407 v = allocate_vector (new_size);
d80c6c11
GM
4408 bcopy (XVECTOR (vec)->contents, v->contents,
4409 old_size * sizeof *v->contents);
4410 for (i = old_size; i < new_size; ++i)
4411 v->contents[i] = init;
4412 XSETVECTOR (vec, v);
4413 return vec;
4414}
4415
4416
4417/***********************************************************************
4418 Low-level Functions
4419 ***********************************************************************/
4420
d80c6c11
GM
4421/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
4422 HASH2 in hash table H using `eql'. Value is non-zero if KEY1 and
4423 KEY2 are the same. */
4424
4425static int
4426cmpfn_eql (h, key1, hash1, key2, hash2)
4427 struct Lisp_Hash_Table *h;
4428 Lisp_Object key1, key2;
4429 unsigned hash1, hash2;
4430{
2e5da676
GM
4431 return (FLOATP (key1)
4432 && FLOATP (key2)
e84b1dea 4433 && XFLOAT_DATA (key1) == XFLOAT_DATA (key2));
d80c6c11
GM
4434}
4435
4436
4437/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
4438 HASH2 in hash table H using `equal'. Value is non-zero if KEY1 and
4439 KEY2 are the same. */
4440
4441static int
4442cmpfn_equal (h, key1, hash1, key2, hash2)
4443 struct Lisp_Hash_Table *h;
4444 Lisp_Object key1, key2;
4445 unsigned hash1, hash2;
4446{
2e5da676 4447 return hash1 == hash2 && !NILP (Fequal (key1, key2));
d80c6c11
GM
4448}
4449
59f953a2 4450
d80c6c11
GM
4451/* Compare KEY1 which has hash code HASH1, and KEY2 with hash code
4452 HASH2 in hash table H using H->user_cmp_function. Value is non-zero
4453 if KEY1 and KEY2 are the same. */
4454
4455static int
4456cmpfn_user_defined (h, key1, hash1, key2, hash2)
4457 struct Lisp_Hash_Table *h;
4458 Lisp_Object key1, key2;
4459 unsigned hash1, hash2;
4460{
4461 if (hash1 == hash2)
4462 {
4463 Lisp_Object args[3];
59f953a2 4464
d80c6c11
GM
4465 args[0] = h->user_cmp_function;
4466 args[1] = key1;
4467 args[2] = key2;
4468 return !NILP (Ffuncall (3, args));
4469 }
4470 else
4471 return 0;
4472}
4473
4474
4475/* Value is a hash code for KEY for use in hash table H which uses
4476 `eq' to compare keys. The hash code returned is guaranteed to fit
4477 in a Lisp integer. */
4478
4479static unsigned
4480hashfn_eq (h, key)
4481 struct Lisp_Hash_Table *h;
4482 Lisp_Object key;
4483{
cf681889 4484 unsigned hash = XUINT (key) ^ XGCTYPE (key);
854c1a59 4485 xassert ((hash & ~INTMASK) == 0);
cf681889 4486 return hash;
d80c6c11
GM
4487}
4488
4489
4490/* Value is a hash code for KEY for use in hash table H which uses
4491 `eql' to compare keys. The hash code returned is guaranteed to fit
4492 in a Lisp integer. */
4493
4494static unsigned
4495hashfn_eql (h, key)
4496 struct Lisp_Hash_Table *h;
4497 Lisp_Object key;
4498{
cf681889
GM
4499 unsigned hash;
4500 if (FLOATP (key))
4501 hash = sxhash (key, 0);
d80c6c11 4502 else
cf681889 4503 hash = XUINT (key) ^ XGCTYPE (key);
854c1a59 4504 xassert ((hash & ~INTMASK) == 0);
cf681889 4505 return hash;
d80c6c11
GM
4506}
4507
4508
4509/* Value is a hash code for KEY for use in hash table H which uses
4510 `equal' to compare keys. The hash code returned is guaranteed to fit
4511 in a Lisp integer. */
4512
4513static unsigned
4514hashfn_equal (h, key)
4515 struct Lisp_Hash_Table *h;
4516 Lisp_Object key;
4517{
cf681889 4518 unsigned hash = sxhash (key, 0);
854c1a59 4519 xassert ((hash & ~INTMASK) == 0);
cf681889 4520 return hash;
d80c6c11
GM
4521}
4522
4523
4524/* Value is a hash code for KEY for use in hash table H which uses as
4525 user-defined function to compare keys. The hash code returned is
4526 guaranteed to fit in a Lisp integer. */
4527
4528static unsigned
4529hashfn_user_defined (h, key)
4530 struct Lisp_Hash_Table *h;
4531 Lisp_Object key;
4532{
4533 Lisp_Object args[2], hash;
59f953a2 4534
d80c6c11
GM
4535 args[0] = h->user_hash_function;
4536 args[1] = key;
4537 hash = Ffuncall (2, args);
4538 if (!INTEGERP (hash))
4539 Fsignal (Qerror,
1fd4c450 4540 list2 (build_string ("Invalid hash code returned from \
d80c6c11
GM
4541user-supplied hash function"),
4542 hash));
4543 return XUINT (hash);
4544}
4545
4546
4547/* Create and initialize a new hash table.
4548
4549 TEST specifies the test the hash table will use to compare keys.
4550 It must be either one of the predefined tests `eq', `eql' or
4551 `equal' or a symbol denoting a user-defined test named TEST with
4552 test and hash functions USER_TEST and USER_HASH.
59f953a2 4553
1fd4c450 4554 Give the table initial capacity SIZE, SIZE >= 0, an integer.
d80c6c11
GM
4555
4556 If REHASH_SIZE is an integer, it must be > 0, and this hash table's
4557 new size when it becomes full is computed by adding REHASH_SIZE to
4558 its old size. If REHASH_SIZE is a float, it must be > 1.0, and the
4559 table's new size is computed by multiplying its old size with
4560 REHASH_SIZE.
4561
4562 REHASH_THRESHOLD must be a float <= 1.0, and > 0. The table will
4563 be resized when the ratio of (number of entries in the table) /
4564 (table size) is >= REHASH_THRESHOLD.
4565
4566 WEAK specifies the weakness of the table. If non-nil, it must be
ec504e6f 4567 one of the symbols `key', `value', `key-or-value', or `key-and-value'. */
d80c6c11
GM
4568
4569Lisp_Object
4570make_hash_table (test, size, rehash_size, rehash_threshold, weak,
4571 user_test, user_hash)
4572 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
4573 Lisp_Object user_test, user_hash;
4574{
4575 struct Lisp_Hash_Table *h;
d80c6c11 4576 Lisp_Object table;
b3660ef6 4577 int index_size, i, sz;
d80c6c11
GM
4578
4579 /* Preconditions. */
4580 xassert (SYMBOLP (test));
1fd4c450 4581 xassert (INTEGERP (size) && XINT (size) >= 0);
d80c6c11
GM
4582 xassert ((INTEGERP (rehash_size) && XINT (rehash_size) > 0)
4583 || (FLOATP (rehash_size) && XFLOATINT (rehash_size) > 1.0));
4584 xassert (FLOATP (rehash_threshold)
4585 && XFLOATINT (rehash_threshold) > 0
4586 && XFLOATINT (rehash_threshold) <= 1.0);
4587
1fd4c450
GM
4588 if (XFASTINT (size) == 0)
4589 size = make_number (1);
4590
b3660ef6
GM
4591 /* Allocate a table and initialize it. */
4592 h = allocate_hash_table ();
d80c6c11
GM
4593
4594 /* Initialize hash table slots. */
4595 sz = XFASTINT (size);
59f953a2 4596
d80c6c11
GM
4597 h->test = test;
4598 if (EQ (test, Qeql))
4599 {
4600 h->cmpfn = cmpfn_eql;
4601 h->hashfn = hashfn_eql;
4602 }
4603 else if (EQ (test, Qeq))
4604 {
2e5da676 4605 h->cmpfn = NULL;
d80c6c11
GM
4606 h->hashfn = hashfn_eq;
4607 }
4608 else if (EQ (test, Qequal))
4609 {
4610 h->cmpfn = cmpfn_equal;
4611 h->hashfn = hashfn_equal;
4612 }
4613 else
4614 {
4615 h->user_cmp_function = user_test;
4616 h->user_hash_function = user_hash;
4617 h->cmpfn = cmpfn_user_defined;
4618 h->hashfn = hashfn_user_defined;
4619 }
59f953a2 4620
d80c6c11
GM
4621 h->weak = weak;
4622 h->rehash_threshold = rehash_threshold;
4623 h->rehash_size = rehash_size;
4624 h->count = make_number (0);
4625 h->key_and_value = Fmake_vector (make_number (2 * sz), Qnil);
4626 h->hash = Fmake_vector (size, Qnil);
4627 h->next = Fmake_vector (size, Qnil);
0690cb37
DL
4628 /* Cast to int here avoids losing with gcc 2.95 on Tru64/Alpha... */
4629 index_size = next_almost_prime ((int) (sz / XFLOATINT (rehash_threshold)));
d80c6c11
GM
4630 h->index = Fmake_vector (make_number (index_size), Qnil);
4631
4632 /* Set up the free list. */
4633 for (i = 0; i < sz - 1; ++i)
4634 HASH_NEXT (h, i) = make_number (i + 1);
4635 h->next_free = make_number (0);
4636
4637 XSET_HASH_TABLE (table, h);
4638 xassert (HASH_TABLE_P (table));
4639 xassert (XHASH_TABLE (table) == h);
4640
4641 /* Maybe add this hash table to the list of all weak hash tables. */
4642 if (NILP (h->weak))
4643 h->next_weak = Qnil;
4644 else
4645 {
4646 h->next_weak = Vweak_hash_tables;
4647 Vweak_hash_tables = table;
4648 }
4649
4650 return table;
4651}
4652
4653
f899c503
GM
4654/* Return a copy of hash table H1. Keys and values are not copied,
4655 only the table itself is. */
4656
4657Lisp_Object
4658copy_hash_table (h1)
4659 struct Lisp_Hash_Table *h1;
4660{
4661 Lisp_Object table;
4662 struct Lisp_Hash_Table *h2;
44dc78e0 4663 struct Lisp_Vector *next;
59f953a2 4664
b3660ef6 4665 h2 = allocate_hash_table ();
f899c503
GM
4666 next = h2->vec_next;
4667 bcopy (h1, h2, sizeof *h2);
4668 h2->vec_next = next;
4669 h2->key_and_value = Fcopy_sequence (h1->key_and_value);
4670 h2->hash = Fcopy_sequence (h1->hash);
4671 h2->next = Fcopy_sequence (h1->next);
4672 h2->index = Fcopy_sequence (h1->index);
4673 XSET_HASH_TABLE (table, h2);
4674
4675 /* Maybe add this hash table to the list of all weak hash tables. */
4676 if (!NILP (h2->weak))
4677 {
4678 h2->next_weak = Vweak_hash_tables;
4679 Vweak_hash_tables = table;
4680 }
4681
4682 return table;
4683}
4684
4685
d80c6c11
GM
4686/* Resize hash table H if it's too full. If H cannot be resized
4687 because it's already too large, throw an error. */
4688
4689static INLINE void
4690maybe_resize_hash_table (h)
4691 struct Lisp_Hash_Table *h;
4692{
4693 if (NILP (h->next_free))
4694 {
4695 int old_size = HASH_TABLE_SIZE (h);
4696 int i, new_size, index_size;
59f953a2 4697
d80c6c11
GM
4698 if (INTEGERP (h->rehash_size))
4699 new_size = old_size + XFASTINT (h->rehash_size);
4700 else
4701 new_size = old_size * XFLOATINT (h->rehash_size);
0d6ba42e 4702 new_size = max (old_size + 1, new_size);
0690cb37
DL
4703 index_size = next_almost_prime ((int)
4704 (new_size
4705 / XFLOATINT (h->rehash_threshold)));
854c1a59 4706 if (max (index_size, 2 * new_size) > MOST_POSITIVE_FIXNUM)
d80c6c11
GM
4707 error ("Hash table too large to resize");
4708
4709 h->key_and_value = larger_vector (h->key_and_value, 2 * new_size, Qnil);
4710 h->next = larger_vector (h->next, new_size, Qnil);
4711 h->hash = larger_vector (h->hash, new_size, Qnil);
4712 h->index = Fmake_vector (make_number (index_size), Qnil);
4713
4714 /* Update the free list. Do it so that new entries are added at
4715 the end of the free list. This makes some operations like
4716 maphash faster. */
4717 for (i = old_size; i < new_size - 1; ++i)
4718 HASH_NEXT (h, i) = make_number (i + 1);
59f953a2 4719
d80c6c11
GM
4720 if (!NILP (h->next_free))
4721 {
4722 Lisp_Object last, next;
59f953a2 4723
d80c6c11
GM
4724 last = h->next_free;
4725 while (next = HASH_NEXT (h, XFASTINT (last)),
4726 !NILP (next))
4727 last = next;
59f953a2 4728
d80c6c11
GM
4729 HASH_NEXT (h, XFASTINT (last)) = make_number (old_size);
4730 }
4731 else
4732 XSETFASTINT (h->next_free, old_size);
4733
4734 /* Rehash. */
4735 for (i = 0; i < old_size; ++i)
4736 if (!NILP (HASH_HASH (h, i)))
4737 {
4738 unsigned hash_code = XUINT (HASH_HASH (h, i));
4739 int start_of_bucket = hash_code % XVECTOR (h->index)->size;
4740 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
4741 HASH_INDEX (h, start_of_bucket) = make_number (i);
4742 }
59f953a2 4743 }
d80c6c11
GM
4744}
4745
4746
4747/* Lookup KEY in hash table H. If HASH is non-null, return in *HASH
4748 the hash code of KEY. Value is the index of the entry in H
4749 matching KEY, or -1 if not found. */
4750
4751int
4752hash_lookup (h, key, hash)
4753 struct Lisp_Hash_Table *h;
4754 Lisp_Object key;
4755 unsigned *hash;
4756{
4757 unsigned hash_code;
4758 int start_of_bucket;
4759 Lisp_Object idx;
4760
4761 hash_code = h->hashfn (h, key);
4762 if (hash)
4763 *hash = hash_code;
59f953a2 4764
d80c6c11
GM
4765 start_of_bucket = hash_code % XVECTOR (h->index)->size;
4766 idx = HASH_INDEX (h, start_of_bucket);
4767
f5c75033 4768 /* We need not gcpro idx since it's either an integer or nil. */
d80c6c11
GM
4769 while (!NILP (idx))
4770 {
4771 int i = XFASTINT (idx);
2e5da676
GM
4772 if (EQ (key, HASH_KEY (h, i))
4773 || (h->cmpfn
4774 && h->cmpfn (h, key, hash_code,
7c752c80 4775 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
d80c6c11
GM
4776 break;
4777 idx = HASH_NEXT (h, i);
4778 }
4779
4780 return NILP (idx) ? -1 : XFASTINT (idx);
4781}
4782
4783
4784/* Put an entry into hash table H that associates KEY with VALUE.
64a5094a
KH
4785 HASH is a previously computed hash code of KEY.
4786 Value is the index of the entry in H matching KEY. */
d80c6c11 4787
64a5094a 4788int
d80c6c11
GM
4789hash_put (h, key, value, hash)
4790 struct Lisp_Hash_Table *h;
4791 Lisp_Object key, value;
4792 unsigned hash;
4793{
4794 int start_of_bucket, i;
4795
854c1a59 4796 xassert ((hash & ~INTMASK) == 0);
d80c6c11
GM
4797
4798 /* Increment count after resizing because resizing may fail. */
4799 maybe_resize_hash_table (h);
4800 h->count = make_number (XFASTINT (h->count) + 1);
59f953a2 4801
d80c6c11
GM
4802 /* Store key/value in the key_and_value vector. */
4803 i = XFASTINT (h->next_free);
4804 h->next_free = HASH_NEXT (h, i);
4805 HASH_KEY (h, i) = key;
4806 HASH_VALUE (h, i) = value;
4807
4808 /* Remember its hash code. */
4809 HASH_HASH (h, i) = make_number (hash);
4810
4811 /* Add new entry to its collision chain. */
4812 start_of_bucket = hash % XVECTOR (h->index)->size;
4813 HASH_NEXT (h, i) = HASH_INDEX (h, start_of_bucket);
4814 HASH_INDEX (h, start_of_bucket) = make_number (i);
64a5094a 4815 return i;
d80c6c11
GM
4816}
4817
4818
4819/* Remove the entry matching KEY from hash table H, if there is one. */
4820
4821void
4822hash_remove (h, key)
4823 struct Lisp_Hash_Table *h;
4824 Lisp_Object key;
4825{
4826 unsigned hash_code;
4827 int start_of_bucket;
4828 Lisp_Object idx, prev;
4829
4830 hash_code = h->hashfn (h, key);
4831 start_of_bucket = hash_code % XVECTOR (h->index)->size;
4832 idx = HASH_INDEX (h, start_of_bucket);
4833 prev = Qnil;
4834
f5c75033 4835 /* We need not gcpro idx, prev since they're either integers or nil. */
d80c6c11
GM
4836 while (!NILP (idx))
4837 {
4838 int i = XFASTINT (idx);
4839
2e5da676
GM
4840 if (EQ (key, HASH_KEY (h, i))
4841 || (h->cmpfn
4842 && h->cmpfn (h, key, hash_code,
7c752c80 4843 HASH_KEY (h, i), XUINT (HASH_HASH (h, i)))))
d80c6c11
GM
4844 {
4845 /* Take entry out of collision chain. */
4846 if (NILP (prev))
4847 HASH_INDEX (h, start_of_bucket) = HASH_NEXT (h, i);
4848 else
4849 HASH_NEXT (h, XFASTINT (prev)) = HASH_NEXT (h, i);
4850
4851 /* Clear slots in key_and_value and add the slots to
4852 the free list. */
4853 HASH_KEY (h, i) = HASH_VALUE (h, i) = HASH_HASH (h, i) = Qnil;
4854 HASH_NEXT (h, i) = h->next_free;
4855 h->next_free = make_number (i);
4856 h->count = make_number (XFASTINT (h->count) - 1);
4857 xassert (XINT (h->count) >= 0);
4858 break;
4859 }
4860 else
4861 {
4862 prev = idx;
4863 idx = HASH_NEXT (h, i);
4864 }
4865 }
4866}
4867
4868
4869/* Clear hash table H. */
4870
4871void
4872hash_clear (h)
4873 struct Lisp_Hash_Table *h;
4874{
4875 if (XFASTINT (h->count) > 0)
4876 {
4877 int i, size = HASH_TABLE_SIZE (h);
4878
4879 for (i = 0; i < size; ++i)
4880 {
4881 HASH_NEXT (h, i) = i < size - 1 ? make_number (i + 1) : Qnil;
4882 HASH_KEY (h, i) = Qnil;
4883 HASH_VALUE (h, i) = Qnil;
4884 HASH_HASH (h, i) = Qnil;
4885 }
4886
4887 for (i = 0; i < XVECTOR (h->index)->size; ++i)
4888 XVECTOR (h->index)->contents[i] = Qnil;
4889
4890 h->next_free = make_number (0);
4891 h->count = make_number (0);
4892 }
4893}
4894
4895
4896\f
4897/************************************************************************
4898 Weak Hash Tables
4899 ************************************************************************/
4900
a0b581cc
GM
4901/* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove
4902 entries from the table that don't survive the current GC.
4903 REMOVE_ENTRIES_P zero means mark entries that are in use. Value is
4904 non-zero if anything was marked. */
4905
4906static int
4907sweep_weak_table (h, remove_entries_p)
4908 struct Lisp_Hash_Table *h;
4909 int remove_entries_p;
4910{
4911 int bucket, n, marked;
59f953a2 4912
a0b581cc
GM
4913 n = XVECTOR (h->index)->size & ~ARRAY_MARK_FLAG;
4914 marked = 0;
59f953a2 4915
a0b581cc
GM
4916 for (bucket = 0; bucket < n; ++bucket)
4917 {
1e546714 4918 Lisp_Object idx, next, prev;
a0b581cc
GM
4919
4920 /* Follow collision chain, removing entries that
4921 don't survive this garbage collection. */
a0b581cc 4922 prev = Qnil;
1e546714 4923 for (idx = HASH_INDEX (h, bucket); !GC_NILP (idx); idx = next)
a0b581cc 4924 {
a0b581cc 4925 int i = XFASTINT (idx);
1e546714
GM
4926 int key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
4927 int value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
4928 int remove_p;
59f953a2 4929
a0b581cc 4930 if (EQ (h->weak, Qkey))
aee625fa 4931 remove_p = !key_known_to_survive_p;
a0b581cc 4932 else if (EQ (h->weak, Qvalue))
aee625fa 4933 remove_p = !value_known_to_survive_p;
ec504e6f 4934 else if (EQ (h->weak, Qkey_or_value))
728c5d9d 4935 remove_p = !(key_known_to_survive_p || value_known_to_survive_p);
ec504e6f 4936 else if (EQ (h->weak, Qkey_and_value))
728c5d9d 4937 remove_p = !(key_known_to_survive_p && value_known_to_survive_p);
a0b581cc
GM
4938 else
4939 abort ();
59f953a2 4940
a0b581cc
GM
4941 next = HASH_NEXT (h, i);
4942
4943 if (remove_entries_p)
4944 {
4945 if (remove_p)
4946 {
4947 /* Take out of collision chain. */
4948 if (GC_NILP (prev))
1e546714 4949 HASH_INDEX (h, bucket) = next;
a0b581cc
GM
4950 else
4951 HASH_NEXT (h, XFASTINT (prev)) = next;
59f953a2 4952
a0b581cc
GM
4953 /* Add to free list. */
4954 HASH_NEXT (h, i) = h->next_free;
4955 h->next_free = idx;
59f953a2 4956
a0b581cc
GM
4957 /* Clear key, value, and hash. */
4958 HASH_KEY (h, i) = HASH_VALUE (h, i) = Qnil;
4959 HASH_HASH (h, i) = Qnil;
59f953a2 4960
a0b581cc
GM
4961 h->count = make_number (XFASTINT (h->count) - 1);
4962 }
d278cde0
KS
4963 else
4964 {
4965 prev = idx;
4966 }
a0b581cc
GM
4967 }
4968 else
4969 {
4970 if (!remove_p)
4971 {
4972 /* Make sure key and value survive. */
aee625fa
GM
4973 if (!key_known_to_survive_p)
4974 {
9568e3d8 4975 mark_object (HASH_KEY (h, i));
aee625fa
GM
4976 marked = 1;
4977 }
4978
4979 if (!value_known_to_survive_p)
4980 {
9568e3d8 4981 mark_object (HASH_VALUE (h, i));
aee625fa
GM
4982 marked = 1;
4983 }
a0b581cc
GM
4984 }
4985 }
a0b581cc
GM
4986 }
4987 }
4988
4989 return marked;
4990}
4991
d80c6c11
GM
4992/* Remove elements from weak hash tables that don't survive the
4993 current garbage collection. Remove weak tables that don't survive
4994 from Vweak_hash_tables. Called from gc_sweep. */
4995
4996void
4997sweep_weak_hash_tables ()
4998{
ac0e96ee
GM
4999 Lisp_Object table, used, next;
5000 struct Lisp_Hash_Table *h;
a0b581cc
GM
5001 int marked;
5002
5003 /* Mark all keys and values that are in use. Keep on marking until
5004 there is no more change. This is necessary for cases like
5005 value-weak table A containing an entry X -> Y, where Y is used in a
5006 key-weak table B, Z -> Y. If B comes after A in the list of weak
5007 tables, X -> Y might be removed from A, although when looking at B
5008 one finds that it shouldn't. */
5009 do
5010 {
5011 marked = 0;
5012 for (table = Vweak_hash_tables; !GC_NILP (table); table = h->next_weak)
5013 {
5014 h = XHASH_TABLE (table);
5015 if (h->size & ARRAY_MARK_FLAG)
5016 marked |= sweep_weak_table (h, 0);
5017 }
5018 }
5019 while (marked);
d80c6c11 5020
a0b581cc 5021 /* Remove tables and entries that aren't used. */
ac0e96ee 5022 for (table = Vweak_hash_tables, used = Qnil; !GC_NILP (table); table = next)
d80c6c11 5023 {
d80c6c11 5024 h = XHASH_TABLE (table);
ac0e96ee 5025 next = h->next_weak;
91f78c99 5026
d80c6c11
GM
5027 if (h->size & ARRAY_MARK_FLAG)
5028 {
ac0e96ee 5029 /* TABLE is marked as used. Sweep its contents. */
d80c6c11 5030 if (XFASTINT (h->count) > 0)
a0b581cc 5031 sweep_weak_table (h, 1);
ac0e96ee
GM
5032
5033 /* Add table to the list of used weak hash tables. */
5034 h->next_weak = used;
5035 used = table;
d80c6c11
GM
5036 }
5037 }
ac0e96ee
GM
5038
5039 Vweak_hash_tables = used;
d80c6c11
GM
5040}
5041
5042
5043\f
5044/***********************************************************************
5045 Hash Code Computation
5046 ***********************************************************************/
5047
5048/* Maximum depth up to which to dive into Lisp structures. */
5049
5050#define SXHASH_MAX_DEPTH 3
5051
5052/* Maximum length up to which to take list and vector elements into
5053 account. */
5054
5055#define SXHASH_MAX_LEN 7
5056
5057/* Combine two integers X and Y for hashing. */
5058
5059#define SXHASH_COMBINE(X, Y) \
ada0fa14 5060 ((((unsigned)(X) << 4) + (((unsigned)(X) >> 24) & 0x0fffffff)) \
d80c6c11
GM
5061 + (unsigned)(Y))
5062
5063
cf681889
GM
5064/* Return a hash for string PTR which has length LEN. The hash
5065 code returned is guaranteed to fit in a Lisp integer. */
d80c6c11
GM
5066
5067static unsigned
5068sxhash_string (ptr, len)
5069 unsigned char *ptr;
5070 int len;
5071{
5072 unsigned char *p = ptr;
5073 unsigned char *end = p + len;
5074 unsigned char c;
5075 unsigned hash = 0;
5076
5077 while (p != end)
5078 {
5079 c = *p++;
5080 if (c >= 0140)
5081 c -= 40;
5082 hash = ((hash << 3) + (hash >> 28) + c);
5083 }
59f953a2 5084
854c1a59 5085 return hash & INTMASK;
d80c6c11
GM
5086}
5087
5088
5089/* Return a hash for list LIST. DEPTH is the current depth in the
5090 list. We don't recurse deeper than SXHASH_MAX_DEPTH in it. */
5091
5092static unsigned
5093sxhash_list (list, depth)
5094 Lisp_Object list;
5095 int depth;
5096{
5097 unsigned hash = 0;
5098 int i;
59f953a2 5099
d80c6c11
GM
5100 if (depth < SXHASH_MAX_DEPTH)
5101 for (i = 0;
5102 CONSP (list) && i < SXHASH_MAX_LEN;
5103 list = XCDR (list), ++i)
5104 {
5105 unsigned hash2 = sxhash (XCAR (list), depth + 1);
5106 hash = SXHASH_COMBINE (hash, hash2);
5107 }
5108
5109 return hash;
5110}
5111
5112
5113/* Return a hash for vector VECTOR. DEPTH is the current depth in
5114 the Lisp structure. */
5115
5116static unsigned
5117sxhash_vector (vec, depth)
5118 Lisp_Object vec;
5119 int depth;
5120{
5121 unsigned hash = XVECTOR (vec)->size;
5122 int i, n;
5123
5124 n = min (SXHASH_MAX_LEN, XVECTOR (vec)->size);
5125 for (i = 0; i < n; ++i)
5126 {
5127 unsigned hash2 = sxhash (XVECTOR (vec)->contents[i], depth + 1);
5128 hash = SXHASH_COMBINE (hash, hash2);
5129 }
5130
5131 return hash;
5132}
5133
5134
5135/* Return a hash for bool-vector VECTOR. */
5136
5137static unsigned
5138sxhash_bool_vector (vec)
5139 Lisp_Object vec;
5140{
5141 unsigned hash = XBOOL_VECTOR (vec)->size;
5142 int i, n;
5143
5144 n = min (SXHASH_MAX_LEN, XBOOL_VECTOR (vec)->vector_size);
5145 for (i = 0; i < n; ++i)
5146 hash = SXHASH_COMBINE (hash, XBOOL_VECTOR (vec)->data[i]);
5147
5148 return hash;
5149}
5150
5151
5152/* Return a hash code for OBJ. DEPTH is the current depth in the Lisp
854c1a59 5153 structure. Value is an unsigned integer clipped to INTMASK. */
d80c6c11
GM
5154
5155unsigned
5156sxhash (obj, depth)
5157 Lisp_Object obj;
5158 int depth;
5159{
5160 unsigned hash;
5161
5162 if (depth > SXHASH_MAX_DEPTH)
5163 return 0;
59f953a2 5164
d80c6c11
GM
5165 switch (XTYPE (obj))
5166 {
5167 case Lisp_Int:
5168 hash = XUINT (obj);
5169 break;
5170
d80c6c11
GM
5171 case Lisp_Misc:
5172 hash = XUINT (obj);
5173 break;
5174
32bfb2d5
EZ
5175 case Lisp_Symbol:
5176 obj = SYMBOL_NAME (obj);
5177 /* Fall through. */
5178
d80c6c11 5179 case Lisp_String:
d5db4077 5180 hash = sxhash_string (SDATA (obj), SCHARS (obj));
d80c6c11
GM
5181 break;
5182
5183 /* This can be everything from a vector to an overlay. */
5184 case Lisp_Vectorlike:
5185 if (VECTORP (obj))
5186 /* According to the CL HyperSpec, two arrays are equal only if
5187 they are `eq', except for strings and bit-vectors. In
5188 Emacs, this works differently. We have to compare element
5189 by element. */
5190 hash = sxhash_vector (obj, depth);
5191 else if (BOOL_VECTOR_P (obj))
5192 hash = sxhash_bool_vector (obj);
5193 else
5194 /* Others are `equal' if they are `eq', so let's take their
5195 address as hash. */
5196 hash = XUINT (obj);
5197 break;
5198
5199 case Lisp_Cons:
5200 hash = sxhash_list (obj, depth);
5201 break;
5202
5203 case Lisp_Float:
5204 {
e84b1dea
GM
5205 unsigned char *p = (unsigned char *) &XFLOAT_DATA (obj);
5206 unsigned char *e = p + sizeof XFLOAT_DATA (obj);
d80c6c11
GM
5207 for (hash = 0; p < e; ++p)
5208 hash = SXHASH_COMBINE (hash, *p);
5209 break;
5210 }
5211
5212 default:
5213 abort ();
5214 }
5215
854c1a59 5216 return hash & INTMASK;
d80c6c11
GM
5217}
5218
5219
5220\f
5221/***********************************************************************
5222 Lisp Interface
5223 ***********************************************************************/
5224
5225
5226DEFUN ("sxhash", Fsxhash, Ssxhash, 1, 1, 0,
e9d8ddc9
MB
5227 doc: /* Compute a hash code for OBJ and return it as integer. */)
5228 (obj)
d80c6c11
GM
5229 Lisp_Object obj;
5230{
5231 unsigned hash = sxhash (obj, 0);;
5232 return make_number (hash);
5233}
5234
5235
5236DEFUN ("make-hash-table", Fmake_hash_table, Smake_hash_table, 0, MANY, 0,
e9d8ddc9 5237 doc: /* Create and return a new hash table.
91f78c99 5238
47cebab1
GM
5239Arguments are specified as keyword/argument pairs. The following
5240arguments are defined:
5241
5242:test TEST -- TEST must be a symbol that specifies how to compare
5243keys. Default is `eql'. Predefined are the tests `eq', `eql', and
5244`equal'. User-supplied test and hash functions can be specified via
5245`define-hash-table-test'.
5246
5247:size SIZE -- A hint as to how many elements will be put in the table.
5248Default is 65.
5249
5250:rehash-size REHASH-SIZE - Indicates how to expand the table when it
5251fills up. If REHASH-SIZE is an integer, add that many space. If it
5252is a float, it must be > 1.0, and the new size is computed by
5253multiplying the old size with that factor. Default is 1.5.
5254
5255:rehash-threshold THRESHOLD -- THRESHOLD must a float > 0, and <= 1.0.
5256Resize the hash table when ratio of the number of entries in the
5257table. Default is 0.8.
5258
5259:weakness WEAK -- WEAK must be one of nil, t, `key', `value',
5260`key-or-value', or `key-and-value'. If WEAK is not nil, the table
5261returned is a weak table. Key/value pairs are removed from a weak
5262hash table when there are no non-weak references pointing to their
5263key, value, one of key or value, or both key and value, depending on
5264WEAK. WEAK t is equivalent to `key-and-value'. Default value of WEAK
4bf8e2a3
MB
5265is nil.
5266
5267usage: (make-hash-table &rest KEYWORD-ARGS) */)
e9d8ddc9 5268 (nargs, args)
d80c6c11
GM
5269 int nargs;
5270 Lisp_Object *args;
5271{
5272 Lisp_Object test, size, rehash_size, rehash_threshold, weak;
5273 Lisp_Object user_test, user_hash;
5274 char *used;
5275 int i;
5276
5277 /* The vector `used' is used to keep track of arguments that
5278 have been consumed. */
5279 used = (char *) alloca (nargs * sizeof *used);
5280 bzero (used, nargs * sizeof *used);
5281
5282 /* See if there's a `:test TEST' among the arguments. */
5283 i = get_key_arg (QCtest, nargs, args, used);
5284 test = i < 0 ? Qeql : args[i];
5285 if (!EQ (test, Qeq) && !EQ (test, Qeql) && !EQ (test, Qequal))
5286 {
5287 /* See if it is a user-defined test. */
5288 Lisp_Object prop;
59f953a2 5289
d80c6c11 5290 prop = Fget (test, Qhash_table_test);
c1dd95fc 5291 if (!CONSP (prop) || !CONSP (XCDR (prop)))
1fd4c450 5292 Fsignal (Qerror, list2 (build_string ("Invalid hash table test"),
d80c6c11 5293 test));
c1dd95fc
RS
5294 user_test = XCAR (prop);
5295 user_hash = XCAR (XCDR (prop));
d80c6c11
GM
5296 }
5297 else
5298 user_test = user_hash = Qnil;
5299
5300 /* See if there's a `:size SIZE' argument. */
5301 i = get_key_arg (QCsize, nargs, args, used);
cf42cb72
SM
5302 size = i < 0 ? Qnil : args[i];
5303 if (NILP (size))
5304 size = make_number (DEFAULT_HASH_SIZE);
5305 else if (!INTEGERP (size) || XINT (size) < 0)
d80c6c11 5306 Fsignal (Qerror,
1fd4c450 5307 list2 (build_string ("Invalid hash table size"),
d80c6c11
GM
5308 size));
5309
5310 /* Look for `:rehash-size SIZE'. */
5311 i = get_key_arg (QCrehash_size, nargs, args, used);
5312 rehash_size = i < 0 ? make_float (DEFAULT_REHASH_SIZE) : args[i];
5313 if (!NUMBERP (rehash_size)
5314 || (INTEGERP (rehash_size) && XINT (rehash_size) <= 0)
5315 || XFLOATINT (rehash_size) <= 1.0)
5316 Fsignal (Qerror,
1fd4c450 5317 list2 (build_string ("Invalid hash table rehash size"),
d80c6c11 5318 rehash_size));
59f953a2 5319
d80c6c11
GM
5320 /* Look for `:rehash-threshold THRESHOLD'. */
5321 i = get_key_arg (QCrehash_threshold, nargs, args, used);
5322 rehash_threshold = i < 0 ? make_float (DEFAULT_REHASH_THRESHOLD) : args[i];
5323 if (!FLOATP (rehash_threshold)
5324 || XFLOATINT (rehash_threshold) <= 0.0
5325 || XFLOATINT (rehash_threshold) > 1.0)
5326 Fsignal (Qerror,
1fd4c450 5327 list2 (build_string ("Invalid hash table rehash threshold"),
d80c6c11 5328 rehash_threshold));
59f953a2 5329
ee0403b3
GM
5330 /* Look for `:weakness WEAK'. */
5331 i = get_key_arg (QCweakness, nargs, args, used);
d80c6c11 5332 weak = i < 0 ? Qnil : args[i];
ec504e6f
GM
5333 if (EQ (weak, Qt))
5334 weak = Qkey_and_value;
d80c6c11 5335 if (!NILP (weak)
f899c503 5336 && !EQ (weak, Qkey)
ec504e6f
GM
5337 && !EQ (weak, Qvalue)
5338 && !EQ (weak, Qkey_or_value)
5339 && !EQ (weak, Qkey_and_value))
1fd4c450 5340 Fsignal (Qerror, list2 (build_string ("Invalid hash table weakness"),
d80c6c11 5341 weak));
59f953a2 5342
d80c6c11
GM
5343 /* Now, all args should have been used up, or there's a problem. */
5344 for (i = 0; i < nargs; ++i)
5345 if (!used[i])
5346 Fsignal (Qerror,
5347 list2 (build_string ("Invalid argument list"), args[i]));
5348
5349 return make_hash_table (test, size, rehash_size, rehash_threshold, weak,
5350 user_test, user_hash);
5351}
5352
5353
f899c503 5354DEFUN ("copy-hash-table", Fcopy_hash_table, Scopy_hash_table, 1, 1, 0,
e9d8ddc9
MB
5355 doc: /* Return a copy of hash table TABLE. */)
5356 (table)
f899c503
GM
5357 Lisp_Object table;
5358{
5359 return copy_hash_table (check_hash_table (table));
5360}
5361
5362
d80c6c11 5363DEFUN ("hash-table-count", Fhash_table_count, Shash_table_count, 1, 1, 0,
e9d8ddc9
MB
5364 doc: /* Return the number of elements in TABLE. */)
5365 (table)
47cebab1 5366 Lisp_Object table;
d80c6c11
GM
5367{
5368 return check_hash_table (table)->count;
5369}
5370
59f953a2 5371
d80c6c11
GM
5372DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size,
5373 Shash_table_rehash_size, 1, 1, 0,
e9d8ddc9
MB
5374 doc: /* Return the current rehash size of TABLE. */)
5375 (table)
47cebab1 5376 Lisp_Object table;
d80c6c11
GM
5377{
5378 return check_hash_table (table)->rehash_size;
5379}
59f953a2 5380
d80c6c11
GM
5381
5382DEFUN ("hash-table-rehash-threshold", Fhash_table_rehash_threshold,
5383 Shash_table_rehash_threshold, 1, 1, 0,
e9d8ddc9
MB
5384 doc: /* Return the current rehash threshold of TABLE. */)
5385 (table)
47cebab1 5386 Lisp_Object table;
d80c6c11
GM
5387{
5388 return check_hash_table (table)->rehash_threshold;
5389}
59f953a2 5390
d80c6c11
GM
5391
5392DEFUN ("hash-table-size", Fhash_table_size, Shash_table_size, 1, 1, 0,
e9d8ddc9 5393 doc: /* Return the size of TABLE.
47cebab1
GM
5394The size can be used as an argument to `make-hash-table' to create
5395a hash table than can hold as many elements of TABLE holds
e9d8ddc9
MB
5396without need for resizing. */)
5397 (table)
d80c6c11
GM
5398 Lisp_Object table;
5399{
5400 struct Lisp_Hash_Table *h = check_hash_table (table);
5401 return make_number (HASH_TABLE_SIZE (h));
5402}
59f953a2 5403
d80c6c11
GM
5404
5405DEFUN ("hash-table-test", Fhash_table_test, Shash_table_test, 1, 1, 0,
e9d8ddc9
MB
5406 doc: /* Return the test TABLE uses. */)
5407 (table)
47cebab1 5408 Lisp_Object table;
d80c6c11
GM
5409{
5410 return check_hash_table (table)->test;
5411}
5412
59f953a2 5413
e84b1dea
GM
5414DEFUN ("hash-table-weakness", Fhash_table_weakness, Shash_table_weakness,
5415 1, 1, 0,
e9d8ddc9
MB
5416 doc: /* Return the weakness of TABLE. */)
5417 (table)
47cebab1 5418 Lisp_Object table;
d80c6c11
GM
5419{
5420 return check_hash_table (table)->weak;
5421}
5422
59f953a2 5423
d80c6c11 5424DEFUN ("hash-table-p", Fhash_table_p, Shash_table_p, 1, 1, 0,
e9d8ddc9
MB
5425 doc: /* Return t if OBJ is a Lisp hash table object. */)
5426 (obj)
d80c6c11
GM
5427 Lisp_Object obj;
5428{
5429 return HASH_TABLE_P (obj) ? Qt : Qnil;
5430}
5431
5432
5433DEFUN ("clrhash", Fclrhash, Sclrhash, 1, 1, 0,
e9d8ddc9
MB
5434 doc: /* Clear hash table TABLE. */)
5435 (table)
d80c6c11
GM
5436 Lisp_Object table;
5437{
5438 hash_clear (check_hash_table (table));
5439 return Qnil;
5440}
5441
5442
5443DEFUN ("gethash", Fgethash, Sgethash, 2, 3, 0,
e9d8ddc9
MB
5444 doc: /* Look up KEY in TABLE and return its associated value.
5445If KEY is not found, return DFLT which defaults to nil. */)
5446 (key, table, dflt)
68c45bf0 5447 Lisp_Object key, table, dflt;
d80c6c11
GM
5448{
5449 struct Lisp_Hash_Table *h = check_hash_table (table);
5450 int i = hash_lookup (h, key, NULL);
5451 return i >= 0 ? HASH_VALUE (h, i) : dflt;
5452}
5453
5454
5455DEFUN ("puthash", Fputhash, Sputhash, 3, 3, 0,
e9d8ddc9 5456 doc: /* Associate KEY with VALUE in hash table TABLE.
47cebab1 5457If KEY is already present in table, replace its current value with
e9d8ddc9
MB
5458VALUE. */)
5459 (key, value, table)
1fffe870 5460 Lisp_Object key, value, table;
d80c6c11
GM
5461{
5462 struct Lisp_Hash_Table *h = check_hash_table (table);
5463 int i;
5464 unsigned hash;
5465
5466 i = hash_lookup (h, key, &hash);
5467 if (i >= 0)
5468 HASH_VALUE (h, i) = value;
5469 else
5470 hash_put (h, key, value, hash);
59f953a2 5471
d9c4f922 5472 return value;
d80c6c11
GM
5473}
5474
5475
5476DEFUN ("remhash", Fremhash, Sremhash, 2, 2, 0,
e9d8ddc9
MB
5477 doc: /* Remove KEY from TABLE. */)
5478 (key, table)
1fffe870 5479 Lisp_Object key, table;
d80c6c11
GM
5480{
5481 struct Lisp_Hash_Table *h = check_hash_table (table);
5482 hash_remove (h, key);
5483 return Qnil;
5484}
5485
5486
5487DEFUN ("maphash", Fmaphash, Smaphash, 2, 2, 0,
e9d8ddc9 5488 doc: /* Call FUNCTION for all entries in hash table TABLE.
c14ec135 5489FUNCTION is called with two arguments, KEY and VALUE. */)
e9d8ddc9 5490 (function, table)
d80c6c11
GM
5491 Lisp_Object function, table;
5492{
5493 struct Lisp_Hash_Table *h = check_hash_table (table);
5494 Lisp_Object args[3];
5495 int i;
5496
5497 for (i = 0; i < HASH_TABLE_SIZE (h); ++i)
5498 if (!NILP (HASH_HASH (h, i)))
5499 {
5500 args[0] = function;
5501 args[1] = HASH_KEY (h, i);
5502 args[2] = HASH_VALUE (h, i);
5503 Ffuncall (3, args);
5504 }
59f953a2 5505
d80c6c11
GM
5506 return Qnil;
5507}
5508
5509
5510DEFUN ("define-hash-table-test", Fdefine_hash_table_test,
5511 Sdefine_hash_table_test, 3, 3, 0,
e9d8ddc9 5512 doc: /* Define a new hash table test with name NAME, a symbol.
91f78c99 5513
47cebab1
GM
5514In hash tables created with NAME specified as test, use TEST to
5515compare keys, and HASH for computing hash codes of keys.
5516
5517TEST must be a function taking two arguments and returning non-nil if
5518both arguments are the same. HASH must be a function taking one
5519argument and return an integer that is the hash code of the argument.
5520Hash code computation should use the whole value range of integers,
e9d8ddc9
MB
5521including negative integers. */)
5522 (name, test, hash)
d80c6c11
GM
5523 Lisp_Object name, test, hash;
5524{
5525 return Fput (name, Qhash_table_test, list2 (test, hash));
5526}
5527
a3b210c4 5528
57916a7a 5529\f
5c302da4
GM
5530/************************************************************************
5531 MD5
5532 ************************************************************************/
5533
57916a7a 5534#include "md5.h"
5c302da4 5535#include "coding.h"
57916a7a
GM
5536
5537DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
e9d8ddc9 5538 doc: /* Return MD5 message digest of OBJECT, a buffer or string.
91f78c99 5539
47cebab1
GM
5540A message digest is a cryptographic checksum of a document, and the
5541algorithm to calculate it is defined in RFC 1321.
5542
5543The two optional arguments START and END are character positions
5544specifying for which part of OBJECT the message digest should be
5545computed. If nil or omitted, the digest is computed for the whole
5546OBJECT.
5547
5548The MD5 message digest is computed from the result of encoding the
5549text in a coding system, not directly from the internal Emacs form of
5550the text. The optional fourth argument CODING-SYSTEM specifies which
5551coding system to encode the text with. It should be the same coding
5552system that you used or will use when actually writing the text into a
5553file.
5554
5555If CODING-SYSTEM is nil or omitted, the default depends on OBJECT. If
5556OBJECT is a buffer, the default for CODING-SYSTEM is whatever coding
5557system would be chosen by default for writing this text into a file.
5558
5559If OBJECT is a string, the most preferred coding system (see the
5560command `prefer-coding-system') is used.
5561
5562If NOERROR is non-nil, silently assume the `raw-text' coding if the
e9d8ddc9
MB
5563guesswork fails. Normally, an error is signaled in such case. */)
5564 (object, start, end, coding_system, noerror)
57916a7a
GM
5565 Lisp_Object object, start, end, coding_system, noerror;
5566{
5567 unsigned char digest[16];
5568 unsigned char value[33];
5569 int i;
5570 int size;
5571 int size_byte = 0;
5572 int start_char = 0, end_char = 0;
5573 int start_byte = 0, end_byte = 0;
5574 register int b, e;
5575 register struct buffer *bp;
5576 int temp;
5577
5c302da4 5578 if (STRINGP (object))
57916a7a
GM
5579 {
5580 if (NILP (coding_system))
5581 {
5c302da4 5582 /* Decide the coding-system to encode the data with. */
57916a7a 5583
5c302da4
GM
5584 if (STRING_MULTIBYTE (object))
5585 /* use default, we can't guess correct value */
f5c1dd0d 5586 coding_system = SYMBOL_VALUE (XCAR (Vcoding_category_list));
91f78c99 5587 else
5c302da4 5588 coding_system = Qraw_text;
57916a7a 5589 }
91f78c99 5590
5c302da4 5591 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 5592 {
5c302da4 5593 /* Invalid coding system. */
91f78c99 5594
5c302da4
GM
5595 if (!NILP (noerror))
5596 coding_system = Qraw_text;
5597 else
5598 while (1)
5599 Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));
57916a7a
GM
5600 }
5601
5c302da4
GM
5602 if (STRING_MULTIBYTE (object))
5603 object = code_convert_string1 (object, coding_system, Qnil, 1);
5604
d5db4077
KR
5605 size = SCHARS (object);
5606 size_byte = SBYTES (object);
57916a7a
GM
5607
5608 if (!NILP (start))
5609 {
b7826503 5610 CHECK_NUMBER (start);
57916a7a
GM
5611
5612 start_char = XINT (start);
5613
5614 if (start_char < 0)
5615 start_char += size;
5616
5617 start_byte = string_char_to_byte (object, start_char);
5618 }
5619
5620 if (NILP (end))
5621 {
5622 end_char = size;
5623 end_byte = size_byte;
5624 }
5625 else
5626 {
b7826503 5627 CHECK_NUMBER (end);
91f78c99 5628
57916a7a
GM
5629 end_char = XINT (end);
5630
5631 if (end_char < 0)
5632 end_char += size;
91f78c99 5633
57916a7a
GM
5634 end_byte = string_char_to_byte (object, end_char);
5635 }
91f78c99 5636
57916a7a
GM
5637 if (!(0 <= start_char && start_char <= end_char && end_char <= size))
5638 args_out_of_range_3 (object, make_number (start_char),
5639 make_number (end_char));
5640 }
5641 else
5642 {
fe905025
KH
5643 struct buffer *prev = current_buffer;
5644
5645 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
5646
b7826503 5647 CHECK_BUFFER (object);
57916a7a
GM
5648
5649 bp = XBUFFER (object);
fe905025
KH
5650 if (bp != current_buffer)
5651 set_buffer_internal (bp);
91f78c99 5652
57916a7a 5653 if (NILP (start))
fe905025 5654 b = BEGV;
57916a7a
GM
5655 else
5656 {
b7826503 5657 CHECK_NUMBER_COERCE_MARKER (start);
57916a7a
GM
5658 b = XINT (start);
5659 }
5660
5661 if (NILP (end))
fe905025 5662 e = ZV;
57916a7a
GM
5663 else
5664 {
b7826503 5665 CHECK_NUMBER_COERCE_MARKER (end);
57916a7a
GM
5666 e = XINT (end);
5667 }
91f78c99 5668
57916a7a
GM
5669 if (b > e)
5670 temp = b, b = e, e = temp;
91f78c99 5671
fe905025 5672 if (!(BEGV <= b && e <= ZV))
57916a7a 5673 args_out_of_range (start, end);
91f78c99 5674
57916a7a
GM
5675 if (NILP (coding_system))
5676 {
91f78c99 5677 /* Decide the coding-system to encode the data with.
5c302da4
GM
5678 See fileio.c:Fwrite-region */
5679
5680 if (!NILP (Vcoding_system_for_write))
5681 coding_system = Vcoding_system_for_write;
5682 else
5683 {
5684 int force_raw_text = 0;
5685
5686 coding_system = XBUFFER (object)->buffer_file_coding_system;
5687 if (NILP (coding_system)
5688 || NILP (Flocal_variable_p (Qbuffer_file_coding_system, Qnil)))
5689 {
5690 coding_system = Qnil;
5691 if (NILP (current_buffer->enable_multibyte_characters))
5692 force_raw_text = 1;
5693 }
5694
5695 if (NILP (coding_system) && !NILP (Fbuffer_file_name(object)))
5696 {
5697 /* Check file-coding-system-alist. */
5698 Lisp_Object args[4], val;
91f78c99 5699
5c302da4
GM
5700 args[0] = Qwrite_region; args[1] = start; args[2] = end;
5701 args[3] = Fbuffer_file_name(object);
5702 val = Ffind_operation_coding_system (4, args);
5703 if (CONSP (val) && !NILP (XCDR (val)))
5704 coding_system = XCDR (val);
5705 }
5706
5707 if (NILP (coding_system)
5708 && !NILP (XBUFFER (object)->buffer_file_coding_system))
5709 {
5710 /* If we still have not decided a coding system, use the
5711 default value of buffer-file-coding-system. */
5712 coding_system = XBUFFER (object)->buffer_file_coding_system;
5713 }
5714
5715 if (!force_raw_text
5716 && !NILP (Ffboundp (Vselect_safe_coding_system_function)))
5717 /* Confirm that VAL can surely encode the current region. */
1e59646d 5718 coding_system = call4 (Vselect_safe_coding_system_function,
70da6a76 5719 make_number (b), make_number (e),
1e59646d 5720 coding_system, Qnil);
5c302da4
GM
5721
5722 if (force_raw_text)
5723 coding_system = Qraw_text;
5724 }
5725
5726 if (NILP (Fcoding_system_p (coding_system)))
57916a7a 5727 {
5c302da4
GM
5728 /* Invalid coding system. */
5729
5730 if (!NILP (noerror))
5731 coding_system = Qraw_text;
5732 else
5733 while (1)
5734 Fsignal (Qcoding_system_error, Fcons (coding_system, Qnil));
57916a7a
GM
5735 }
5736 }
5737
5738 object = make_buffer_string (b, e, 0);
fe905025
KH
5739 if (prev != current_buffer)
5740 set_buffer_internal (prev);
5741 /* Discard the unwind protect for recovering the current
5742 buffer. */
5743 specpdl_ptr--;
57916a7a
GM
5744
5745 if (STRING_MULTIBYTE (object))
5746 object = code_convert_string1 (object, coding_system, Qnil, 1);
5747 }
5748
91f78c99
FP
5749 md5_buffer (SDATA (object) + start_byte,
5750 SBYTES (object) - (size_byte - end_byte),
57916a7a
GM
5751 digest);
5752
5753 for (i = 0; i < 16; i++)
5c302da4 5754 sprintf (&value[2 * i], "%02x", digest[i]);
57916a7a
GM
5755 value[32] = '\0';
5756
5757 return make_string (value, 32);
5758}
5759
24c129e4 5760\f
dfcf069d 5761void
7b863bd5
JB
5762syms_of_fns ()
5763{
d80c6c11
GM
5764 /* Hash table stuff. */
5765 Qhash_table_p = intern ("hash-table-p");
5766 staticpro (&Qhash_table_p);
5767 Qeq = intern ("eq");
5768 staticpro (&Qeq);
5769 Qeql = intern ("eql");
5770 staticpro (&Qeql);
5771 Qequal = intern ("equal");
5772 staticpro (&Qequal);
5773 QCtest = intern (":test");
5774 staticpro (&QCtest);
5775 QCsize = intern (":size");
5776 staticpro (&QCsize);
5777 QCrehash_size = intern (":rehash-size");
5778 staticpro (&QCrehash_size);
5779 QCrehash_threshold = intern (":rehash-threshold");
5780 staticpro (&QCrehash_threshold);
ee0403b3
GM
5781 QCweakness = intern (":weakness");
5782 staticpro (&QCweakness);
f899c503
GM
5783 Qkey = intern ("key");
5784 staticpro (&Qkey);
5785 Qvalue = intern ("value");
5786 staticpro (&Qvalue);
d80c6c11
GM
5787 Qhash_table_test = intern ("hash-table-test");
5788 staticpro (&Qhash_table_test);
ec504e6f
GM
5789 Qkey_or_value = intern ("key-or-value");
5790 staticpro (&Qkey_or_value);
5791 Qkey_and_value = intern ("key-and-value");
5792 staticpro (&Qkey_and_value);
d80c6c11
GM
5793
5794 defsubr (&Ssxhash);
5795 defsubr (&Smake_hash_table);
f899c503 5796 defsubr (&Scopy_hash_table);
d80c6c11
GM
5797 defsubr (&Shash_table_count);
5798 defsubr (&Shash_table_rehash_size);
5799 defsubr (&Shash_table_rehash_threshold);
5800 defsubr (&Shash_table_size);
5801 defsubr (&Shash_table_test);
e84b1dea 5802 defsubr (&Shash_table_weakness);
d80c6c11
GM
5803 defsubr (&Shash_table_p);
5804 defsubr (&Sclrhash);
5805 defsubr (&Sgethash);
5806 defsubr (&Sputhash);
5807 defsubr (&Sremhash);
5808 defsubr (&Smaphash);
5809 defsubr (&Sdefine_hash_table_test);
59f953a2 5810
7b863bd5
JB
5811 Qstring_lessp = intern ("string-lessp");
5812 staticpro (&Qstring_lessp);
68732608
RS
5813 Qprovide = intern ("provide");
5814 staticpro (&Qprovide);
5815 Qrequire = intern ("require");
5816 staticpro (&Qrequire);
0ce830bc
RS
5817 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
5818 staticpro (&Qyes_or_no_p_history);
eb4ffa4e
RS
5819 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
5820 staticpro (&Qcursor_in_echo_area);
b4f334f7
KH
5821 Qwidget_type = intern ("widget-type");
5822 staticpro (&Qwidget_type);
7b863bd5 5823
09ab3c3b
KH
5824 staticpro (&string_char_byte_cache_string);
5825 string_char_byte_cache_string = Qnil;
5826
1f79789d
RS
5827 require_nesting_list = Qnil;
5828 staticpro (&require_nesting_list);
5829
52a9879b
RS
5830 Fset (Qyes_or_no_p_history, Qnil);
5831
e9d8ddc9
MB
5832 DEFVAR_LISP ("features", &Vfeatures,
5833 doc: /* A list of symbols which are the features of the executing emacs.
47cebab1 5834Used by `featurep' and `require', and altered by `provide'. */);
7b863bd5 5835 Vfeatures = Qnil;
65550192
SM
5836 Qsubfeatures = intern ("subfeatures");
5837 staticpro (&Qsubfeatures);
7b863bd5 5838
dec002ca
DL
5839#ifdef HAVE_LANGINFO_CODESET
5840 Qcodeset = intern ("codeset");
5841 staticpro (&Qcodeset);
5842 Qdays = intern ("days");
5843 staticpro (&Qdays);
5844 Qmonths = intern ("months");
5845 staticpro (&Qmonths);
5846 Qpaper = intern ("paper");
5847 staticpro (&Qpaper);
5848#endif /* HAVE_LANGINFO_CODESET */
5849
e9d8ddc9
MB
5850 DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
5851 doc: /* *Non-nil means mouse commands use dialog boxes to ask questions.
436fa78b 5852This applies to `y-or-n-p' and `yes-or-no-p' questions asked by commands
47cebab1 5853invoked by mouse clicks and mouse menu items. */);
bdd8d692
RS
5854 use_dialog_box = 1;
5855
03d6484e
JD
5856 DEFVAR_BOOL ("use-file-dialog", &use_file_dialog,
5857 doc: /* *Non-nil means mouse commands use a file dialog to ask for files.
5858This applies to commands from menus and tool bar buttons. The value of
5859`use-dialog-box' takes precedence over this variable, so a file dialog is only
5860used if both `use-dialog-box' and this variable are non-nil. */);
5861 use_file_dialog = 1;
0dc72b11 5862
7b863bd5
JB
5863 defsubr (&Sidentity);
5864 defsubr (&Srandom);
5865 defsubr (&Slength);
5a30fab8 5866 defsubr (&Ssafe_length);
026f59ce 5867 defsubr (&Sstring_bytes);
7b863bd5 5868 defsubr (&Sstring_equal);
0e1e9f8d 5869 defsubr (&Scompare_strings);
7b863bd5
JB
5870 defsubr (&Sstring_lessp);
5871 defsubr (&Sappend);
5872 defsubr (&Sconcat);
5873 defsubr (&Svconcat);
5874 defsubr (&Scopy_sequence);
09ab3c3b
KH
5875 defsubr (&Sstring_make_multibyte);
5876 defsubr (&Sstring_make_unibyte);
6d475204
RS
5877 defsubr (&Sstring_as_multibyte);
5878 defsubr (&Sstring_as_unibyte);
2df18cdb 5879 defsubr (&Sstring_to_multibyte);
7b863bd5
JB
5880 defsubr (&Scopy_alist);
5881 defsubr (&Ssubstring);
aebf4d42 5882 defsubr (&Ssubstring_no_properties);
7b863bd5
JB
5883 defsubr (&Snthcdr);
5884 defsubr (&Snth);
5885 defsubr (&Selt);
5886 defsubr (&Smember);
5887 defsubr (&Smemq);
5888 defsubr (&Sassq);
5889 defsubr (&Sassoc);
5890 defsubr (&Srassq);
0fb5a19c 5891 defsubr (&Srassoc);
7b863bd5 5892 defsubr (&Sdelq);
ca8dd546 5893 defsubr (&Sdelete);
7b863bd5
JB
5894 defsubr (&Snreverse);
5895 defsubr (&Sreverse);
5896 defsubr (&Ssort);
be9d483d 5897 defsubr (&Splist_get);
7b863bd5 5898 defsubr (&Sget);
be9d483d 5899 defsubr (&Splist_put);
7b863bd5 5900 defsubr (&Sput);
aebf4d42
RS
5901 defsubr (&Slax_plist_get);
5902 defsubr (&Slax_plist_put);
95f8c3b9 5903 defsubr (&Seql);
7b863bd5 5904 defsubr (&Sequal);
6054c582 5905 defsubr (&Sequal_including_properties);
7b863bd5 5906 defsubr (&Sfillarray);
85cad579 5907 defsubr (&Sclear_string);
999de246 5908 defsubr (&Schar_table_subtype);
e03f7933
RS
5909 defsubr (&Schar_table_parent);
5910 defsubr (&Sset_char_table_parent);
5911 defsubr (&Schar_table_extra_slot);
5912 defsubr (&Sset_char_table_extra_slot);
999de246 5913 defsubr (&Schar_table_range);
e03f7933 5914 defsubr (&Sset_char_table_range);
e1335ba2 5915 defsubr (&Sset_char_table_default);
52ef6c89 5916 defsubr (&Soptimize_char_table);
e03f7933 5917 defsubr (&Smap_char_table);
7b863bd5
JB
5918 defsubr (&Snconc);
5919 defsubr (&Smapcar);
5c6740c9 5920 defsubr (&Smapc);
7b863bd5
JB
5921 defsubr (&Smapconcat);
5922 defsubr (&Sy_or_n_p);
5923 defsubr (&Syes_or_no_p);
5924 defsubr (&Sload_average);
5925 defsubr (&Sfeaturep);
5926 defsubr (&Srequire);
5927 defsubr (&Sprovide);
a5254817 5928 defsubr (&Splist_member);
b4f334f7
KH
5929 defsubr (&Swidget_put);
5930 defsubr (&Swidget_get);
5931 defsubr (&Swidget_apply);
24c129e4
KH
5932 defsubr (&Sbase64_encode_region);
5933 defsubr (&Sbase64_decode_region);
5934 defsubr (&Sbase64_encode_string);
5935 defsubr (&Sbase64_decode_string);
57916a7a 5936 defsubr (&Smd5);
d68beb2f 5937 defsubr (&Slocale_info);
7b863bd5 5938}
d80c6c11
GM
5939
5940
5941void
5942init_fns ()
5943{
5944 Vweak_hash_tables = Qnil;
5945}
ab5796a9
MB
5946
5947/* arch-tag: 787f8219-5b74-46bd-8469-7e1cc475fa31
5948 (do not change this comment) */