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