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