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