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