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