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