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