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