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