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