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