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