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