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