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