]> code.delx.au - gnu-emacs/blob - src/fns.c
(Frequire): New arg NOERROR.
[gnu-emacs] / src / fns.c
1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <config.h>
23
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #include <time.h>
28
29 /* Note on some machines this defines `vector' as a typedef,
30 so make sure we don't use that name in this file. */
31 #undef vector
32 #define vector *****
33
34 #include "lisp.h"
35 #include "commands.h"
36 #include "charset.h"
37
38 #include "buffer.h"
39 #include "keyboard.h"
40 #include "intervals.h"
41 #include "frame.h"
42 #include "window.h"
43 #if defined (HAVE_MENUS) && defined (HAVE_X_WINDOWS)
44 #include "xterm.h"
45 #endif
46
47 #ifndef NULL
48 #define NULL (void *)0
49 #endif
50
51 /* Nonzero enables use of dialog boxes for questions
52 asked by mouse commands. */
53 int use_dialog_box;
54
55 extern int minibuffer_auto_raise;
56 extern Lisp_Object minibuf_window;
57
58 Lisp_Object Qstring_lessp, Qprovide, Qrequire;
59 Lisp_Object Qyes_or_no_p_history;
60 Lisp_Object Qcursor_in_echo_area;
61 Lisp_Object Qwidget_type;
62
63 extern Lisp_Object Qinput_method_function;
64
65 static int internal_equal ();
66
67 extern long get_random ();
68 extern void seed_random ();
69
70 #ifndef HAVE_UNISTD_H
71 extern long time ();
72 #endif
73 \f
74 DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
75 "Return the argument unchanged.")
76 (arg)
77 Lisp_Object arg;
78 {
79 return arg;
80 }
81
82 DEFUN ("random", Frandom, Srandom, 0, 1, 0,
83 "Return a pseudo-random number.\n\
84 All integers representable in Lisp are equally likely.\n\
85 On most systems, this is 28 bits' worth.\n\
86 With positive integer argument N, return random number in interval [0,N).\n\
87 With argument t, set the random number seed from the current time and pid.")
88 (n)
89 Lisp_Object n;
90 {
91 EMACS_INT val;
92 Lisp_Object lispy_val;
93 unsigned long denominator;
94
95 if (EQ (n, Qt))
96 seed_random (getpid () + time (NULL));
97 if (NATNUMP (n) && XFASTINT (n) != 0)
98 {
99 /* Try to take our random number from the higher bits of VAL,
100 not the lower, since (says Gentzel) the low bits of `random'
101 are less random than the higher ones. We do this by using the
102 quotient rather than the remainder. At the high end of the RNG
103 it's possible to get a quotient larger than n; discarding
104 these values eliminates the bias that would otherwise appear
105 when using a large n. */
106 denominator = ((unsigned long)1 << VALBITS) / XFASTINT (n);
107 do
108 val = get_random () / denominator;
109 while (val >= XFASTINT (n));
110 }
111 else
112 val = get_random ();
113 XSETINT (lispy_val, val);
114 return lispy_val;
115 }
116 \f
117 /* Random data-structure functions */
118
119 DEFUN ("length", Flength, Slength, 1, 1, 0,
120 "Return the length of vector, list or string SEQUENCE.\n\
121 A byte-code function object is also allowed.\n\
122 If the string contains multibyte characters, this is not the necessarily\n\
123 the number of bytes in the string; it is the number of characters.\n\
124 To get the number of bytes, use `string-bytes'")
125 (sequence)
126 register Lisp_Object sequence;
127 {
128 register Lisp_Object tail, val;
129 register int i;
130
131 retry:
132 if (STRINGP (sequence))
133 XSETFASTINT (val, XSTRING (sequence)->size);
134 else if (VECTORP (sequence))
135 XSETFASTINT (val, XVECTOR (sequence)->size);
136 else if (CHAR_TABLE_P (sequence))
137 XSETFASTINT (val, (MIN_CHAR_COMPOSITION
138 + (CHAR_FIELD2_MASK | CHAR_FIELD3_MASK)
139 - 1));
140 else if (BOOL_VECTOR_P (sequence))
141 XSETFASTINT (val, XBOOL_VECTOR (sequence)->size);
142 else if (COMPILEDP (sequence))
143 XSETFASTINT (val, XVECTOR (sequence)->size & PSEUDOVECTOR_SIZE_MASK);
144 else if (CONSP (sequence))
145 {
146 for (i = 0, tail = sequence; !NILP (tail); i++)
147 {
148 QUIT;
149 tail = Fcdr (tail);
150 }
151
152 XSETFASTINT (val, i);
153 }
154 else if (NILP (sequence))
155 XSETFASTINT (val, 0);
156 else
157 {
158 sequence = wrong_type_argument (Qsequencep, sequence);
159 goto retry;
160 }
161 return val;
162 }
163
164 /* This does not check for quits. That is safe
165 since it must terminate. */
166
167 DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
168 "Return the length of a list, but avoid error or infinite loop.\n\
169 This function never gets an error. If LIST is not really a list,\n\
170 it returns 0. If LIST is circular, it returns a finite value\n\
171 which is at least the number of distinct elements.")
172 (list)
173 Lisp_Object list;
174 {
175 Lisp_Object tail, halftail, length;
176 int len = 0;
177
178 /* halftail is used to detect circular lists. */
179 halftail = list;
180 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
181 {
182 if (EQ (tail, halftail) && len != 0)
183 break;
184 len++;
185 if ((len & 1) == 0)
186 halftail = XCONS (halftail)->cdr;
187 }
188
189 XSETINT (length, len);
190 return length;
191 }
192
193 DEFUN ("string-bytes", Fstring_bytes, Sstring_bytes, 1, 1, 0,
194 "Return the number of bytes in STRING.\n\
195 If STRING is a multibyte string, this is greater than the length of STRING.")
196 (string)
197 Lisp_Object string;
198 {
199 CHECK_STRING (string, 1);
200 return make_number (STRING_BYTES (XSTRING (string)));
201 }
202
203 DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
204 "Return t if two strings have identical contents.\n\
205 Case is significant, but text properties are ignored.\n\
206 Symbols are also allowed; their print names are used instead.")
207 (s1, s2)
208 register Lisp_Object s1, s2;
209 {
210 if (SYMBOLP (s1))
211 XSETSTRING (s1, XSYMBOL (s1)->name);
212 if (SYMBOLP (s2))
213 XSETSTRING (s2, XSYMBOL (s2)->name);
214 CHECK_STRING (s1, 0);
215 CHECK_STRING (s2, 1);
216
217 if (XSTRING (s1)->size != XSTRING (s2)->size
218 || STRING_BYTES (XSTRING (s1)) != STRING_BYTES (XSTRING (s2))
219 || bcmp (XSTRING (s1)->data, XSTRING (s2)->data, STRING_BYTES (XSTRING (s1))))
220 return Qnil;
221 return Qt;
222 }
223
224 DEFUN ("compare-strings", Fcompare_strings,
225 Scompare_strings, 6, 7, 0,
226 "Compare the contents of two strings, converting to multibyte if needed.\n\
227 In string STR1, skip the first START1 characters and stop at END1.\n\
228 In string STR2, skip the first START2 characters and stop at END2.\n\
229 END1 and END2 default to the full lengths of the respective strings.\n\
230 \n\
231 Case is significant in this comparison if IGNORE-CASE is nil.\n\
232 Unibyte strings are converted to multibyte for comparison.\n\
233 \n\
234 The value is t if the strings (or specified portions) match.\n\
235 If string STR1 is less, the value is a negative number N;\n\
236 - 1 - N is the number of characters that match at the beginning.\n\
237 If string STR1 is greater, the value is a positive number N;\n\
238 N - 1 is the number of characters that match at the beginning.")
239 (str1, start1, end1, str2, start2, end2, ignore_case)
240 Lisp_Object str1, start1, end1, start2, str2, end2, ignore_case;
241 {
242 register int end1_char, end2_char;
243 register int i1, i1_byte, i2, i2_byte;
244
245 CHECK_STRING (str1, 0);
246 CHECK_STRING (str2, 1);
247 if (NILP (start1))
248 start1 = make_number (0);
249 if (NILP (start2))
250 start2 = make_number (0);
251 CHECK_NATNUM (start1, 2);
252 CHECK_NATNUM (start2, 3);
253 if (! NILP (end1))
254 CHECK_NATNUM (end1, 4);
255 if (! NILP (end2))
256 CHECK_NATNUM (end2, 4);
257
258 i1 = XINT (start1);
259 i2 = XINT (start2);
260
261 i1_byte = string_char_to_byte (str1, i1);
262 i2_byte = string_char_to_byte (str2, i2);
263
264 end1_char = XSTRING (str1)->size;
265 if (! NILP (end1) && end1_char > XINT (end1))
266 end1_char = XINT (end1);
267
268 end2_char = XSTRING (str2)->size;
269 if (! NILP (end2) && end2_char > XINT (end2))
270 end2_char = XINT (end2);
271
272 while (i1 < end1_char && i2 < end2_char)
273 {
274 /* When we find a mismatch, we must compare the
275 characters, not just the bytes. */
276 int c1, c2;
277
278 if (STRING_MULTIBYTE (str1))
279 FETCH_STRING_CHAR_ADVANCE (c1, str1, i1, i1_byte);
280 else
281 {
282 c1 = XSTRING (str1)->data[i1++];
283 c1 = unibyte_char_to_multibyte (c1);
284 }
285
286 if (STRING_MULTIBYTE (str2))
287 FETCH_STRING_CHAR_ADVANCE (c2, str2, i2, i2_byte);
288 else
289 {
290 c2 = XSTRING (str2)->data[i2++];
291 c2 = unibyte_char_to_multibyte (c2);
292 }
293
294 if (c1 == c2)
295 continue;
296
297 if (! NILP (ignore_case))
298 {
299 Lisp_Object tem;
300
301 tem = Fupcase (make_number (c1));
302 c1 = XINT (tem);
303 tem = Fupcase (make_number (c2));
304 c2 = XINT (tem);
305 }
306
307 if (c1 == c2)
308 continue;
309
310 /* Note that I1 has already been incremented
311 past the character that we are comparing;
312 hence we don't add or subtract 1 here. */
313 if (c1 < c2)
314 return make_number (- i1);
315 else
316 return make_number (i1);
317 }
318
319 if (i1 < end1_char)
320 return make_number (i1 - XINT (start1) + 1);
321 if (i2 < end2_char)
322 return make_number (- i1 + XINT (start1) - 1);
323
324 return Qt;
325 }
326
327 DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
328 "Return t if first arg string is less than second in lexicographic order.\n\
329 Case is significant.\n\
330 Symbols are also allowed; their print names are used instead.")
331 (s1, s2)
332 register Lisp_Object s1, s2;
333 {
334 register int end;
335 register int i1, i1_byte, i2, i2_byte;
336
337 if (SYMBOLP (s1))
338 XSETSTRING (s1, XSYMBOL (s1)->name);
339 if (SYMBOLP (s2))
340 XSETSTRING (s2, XSYMBOL (s2)->name);
341 CHECK_STRING (s1, 0);
342 CHECK_STRING (s2, 1);
343
344 i1 = i1_byte = i2 = i2_byte = 0;
345
346 end = XSTRING (s1)->size;
347 if (end > XSTRING (s2)->size)
348 end = XSTRING (s2)->size;
349
350 while (i1 < end)
351 {
352 /* When we find a mismatch, we must compare the
353 characters, not just the bytes. */
354 int c1, c2;
355
356 if (STRING_MULTIBYTE (s1))
357 FETCH_STRING_CHAR_ADVANCE (c1, s1, i1, i1_byte);
358 else
359 c1 = XSTRING (s1)->data[i1++];
360
361 if (STRING_MULTIBYTE (s2))
362 FETCH_STRING_CHAR_ADVANCE (c2, s2, i2, i2_byte);
363 else
364 c2 = XSTRING (s2)->data[i2++];
365
366 if (c1 != c2)
367 return c1 < c2 ? Qt : Qnil;
368 }
369 return i1 < XSTRING (s2)->size ? Qt : Qnil;
370 }
371 \f
372 static Lisp_Object concat ();
373
374 /* ARGSUSED */
375 Lisp_Object
376 concat2 (s1, s2)
377 Lisp_Object s1, s2;
378 {
379 #ifdef NO_ARG_ARRAY
380 Lisp_Object args[2];
381 args[0] = s1;
382 args[1] = s2;
383 return concat (2, args, Lisp_String, 0);
384 #else
385 return concat (2, &s1, Lisp_String, 0);
386 #endif /* NO_ARG_ARRAY */
387 }
388
389 /* ARGSUSED */
390 Lisp_Object
391 concat3 (s1, s2, s3)
392 Lisp_Object s1, s2, s3;
393 {
394 #ifdef NO_ARG_ARRAY
395 Lisp_Object args[3];
396 args[0] = s1;
397 args[1] = s2;
398 args[2] = s3;
399 return concat (3, args, Lisp_String, 0);
400 #else
401 return concat (3, &s1, Lisp_String, 0);
402 #endif /* NO_ARG_ARRAY */
403 }
404
405 DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
406 "Concatenate all the arguments and make the result a list.\n\
407 The result is a list whose elements are the elements of all the arguments.\n\
408 Each argument may be a list, vector or string.\n\
409 The last argument is not copied, just used as the tail of the new list.")
410 (nargs, args)
411 int nargs;
412 Lisp_Object *args;
413 {
414 return concat (nargs, args, Lisp_Cons, 1);
415 }
416
417 DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
418 "Concatenate all the arguments and make the result a string.\n\
419 The result is a string whose elements are the elements of all the arguments.\n\
420 Each argument may be a string or a list or vector of characters (integers).\n\
421 \n\
422 Do not use individual integers as arguments!\n\
423 The behavior of `concat' in that case will be changed later!\n\
424 If your program passes an integer as an argument to `concat',\n\
425 you should change it right away not to do so.")
426 (nargs, args)
427 int nargs;
428 Lisp_Object *args;
429 {
430 return concat (nargs, args, Lisp_String, 0);
431 }
432
433 DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
434 "Concatenate all the arguments and make the result a vector.\n\
435 The result is a vector whose elements are the elements of all the arguments.\n\
436 Each argument may be a list, vector or string.")
437 (nargs, args)
438 int nargs;
439 Lisp_Object *args;
440 {
441 return concat (nargs, args, Lisp_Vectorlike, 0);
442 }
443
444 /* Retrun a copy of a sub char table ARG. The elements except for a
445 nested sub char table are not copied. */
446 static Lisp_Object
447 copy_sub_char_table (arg)
448 Lisp_Object arg;
449 {
450 Lisp_Object copy = make_sub_char_table (XCHAR_TABLE (arg)->defalt);
451 int i;
452
453 /* Copy all the contents. */
454 bcopy (XCHAR_TABLE (arg)->contents, XCHAR_TABLE (copy)->contents,
455 SUB_CHAR_TABLE_ORDINARY_SLOTS * sizeof (Lisp_Object));
456 /* Recursively copy any sub char-tables in the ordinary slots. */
457 for (i = 32; i < SUB_CHAR_TABLE_ORDINARY_SLOTS; i++)
458 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
459 XCHAR_TABLE (copy)->contents[i]
460 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
461
462 return copy;
463 }
464
465
466 DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
467 "Return a copy of a list, vector or string.\n\
468 The elements of a list or vector are not copied; they are shared\n\
469 with the original.")
470 (arg)
471 Lisp_Object arg;
472 {
473 if (NILP (arg)) return arg;
474
475 if (CHAR_TABLE_P (arg))
476 {
477 int i;
478 Lisp_Object copy;
479
480 copy = Fmake_char_table (XCHAR_TABLE (arg)->purpose, Qnil);
481 /* Copy all the slots, including the extra ones. */
482 bcopy (XVECTOR (arg)->contents, XVECTOR (copy)->contents,
483 ((XCHAR_TABLE (arg)->size & PSEUDOVECTOR_SIZE_MASK)
484 * sizeof (Lisp_Object)));
485
486 /* Recursively copy any sub char tables in the ordinary slots
487 for multibyte characters. */
488 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS;
489 i < CHAR_TABLE_ORDINARY_SLOTS; i++)
490 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg)->contents[i]))
491 XCHAR_TABLE (copy)->contents[i]
492 = copy_sub_char_table (XCHAR_TABLE (copy)->contents[i]);
493
494 return copy;
495 }
496
497 if (BOOL_VECTOR_P (arg))
498 {
499 Lisp_Object val;
500 int size_in_chars
501 = (XBOOL_VECTOR (arg)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
502
503 val = Fmake_bool_vector (Flength (arg), Qnil);
504 bcopy (XBOOL_VECTOR (arg)->data, XBOOL_VECTOR (val)->data,
505 size_in_chars);
506 return val;
507 }
508
509 if (!CONSP (arg) && !VECTORP (arg) && !STRINGP (arg))
510 arg = wrong_type_argument (Qsequencep, arg);
511 return concat (1, &arg, CONSP (arg) ? Lisp_Cons : XTYPE (arg), 0);
512 }
513
514 static Lisp_Object
515 concat (nargs, args, target_type, last_special)
516 int nargs;
517 Lisp_Object *args;
518 enum Lisp_Type target_type;
519 int last_special;
520 {
521 Lisp_Object val;
522 register Lisp_Object tail;
523 register Lisp_Object this;
524 int toindex;
525 int toindex_byte;
526 register int result_len;
527 register int result_len_byte;
528 register int argnum;
529 Lisp_Object last_tail;
530 Lisp_Object prev;
531 int some_multibyte;
532 /* When we make a multibyte string, we must pay attention to the
533 byte combining problem, i.e., a byte may be combined with a
534 multibyte charcter of the previous string. This flag tells if we
535 must consider such a situation or not. */
536 int maybe_combine_byte;
537
538 /* In append, the last arg isn't treated like the others */
539 if (last_special && nargs > 0)
540 {
541 nargs--;
542 last_tail = args[nargs];
543 }
544 else
545 last_tail = Qnil;
546
547 /* Canonicalize each argument. */
548 for (argnum = 0; argnum < nargs; argnum++)
549 {
550 this = args[argnum];
551 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
552 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
553 {
554 if (INTEGERP (this))
555 args[argnum] = Fnumber_to_string (this);
556 else
557 args[argnum] = wrong_type_argument (Qsequencep, this);
558 }
559 }
560
561 /* Compute total length in chars of arguments in RESULT_LEN.
562 If desired output is a string, also compute length in bytes
563 in RESULT_LEN_BYTE, and determine in SOME_MULTIBYTE
564 whether the result should be a multibyte string. */
565 result_len_byte = 0;
566 result_len = 0;
567 some_multibyte = 0;
568 for (argnum = 0; argnum < nargs; argnum++)
569 {
570 int len;
571 this = args[argnum];
572 len = XFASTINT (Flength (this));
573 if (target_type == Lisp_String)
574 {
575 /* We must count the number of bytes needed in the string
576 as well as the number of characters. */
577 int i;
578 Lisp_Object ch;
579 int this_len_byte;
580
581 if (VECTORP (this))
582 for (i = 0; i < len; i++)
583 {
584 ch = XVECTOR (this)->contents[i];
585 if (! INTEGERP (ch))
586 wrong_type_argument (Qintegerp, ch);
587 this_len_byte = CHAR_BYTES (XINT (ch));
588 result_len_byte += this_len_byte;
589 if (this_len_byte > 1)
590 some_multibyte = 1;
591 }
592 else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size > 0)
593 wrong_type_argument (Qintegerp, Faref (this, make_number (0)));
594 else if (CONSP (this))
595 for (; CONSP (this); this = XCONS (this)->cdr)
596 {
597 ch = XCONS (this)->car;
598 if (! INTEGERP (ch))
599 wrong_type_argument (Qintegerp, ch);
600 this_len_byte = CHAR_BYTES (XINT (ch));
601 result_len_byte += this_len_byte;
602 if (this_len_byte > 1)
603 some_multibyte = 1;
604 }
605 else if (STRINGP (this))
606 {
607 if (STRING_MULTIBYTE (this))
608 {
609 some_multibyte = 1;
610 result_len_byte += STRING_BYTES (XSTRING (this));
611 }
612 else
613 result_len_byte += count_size_as_multibyte (XSTRING (this)->data,
614 XSTRING (this)->size);
615 }
616 }
617
618 result_len += len;
619 }
620
621 if (! some_multibyte)
622 result_len_byte = result_len;
623
624 /* Create the output object. */
625 if (target_type == Lisp_Cons)
626 val = Fmake_list (make_number (result_len), Qnil);
627 else if (target_type == Lisp_Vectorlike)
628 val = Fmake_vector (make_number (result_len), Qnil);
629 else if (some_multibyte)
630 val = make_uninit_multibyte_string (result_len, result_len_byte);
631 else
632 val = make_uninit_string (result_len);
633
634 /* In `append', if all but last arg are nil, return last arg. */
635 if (target_type == Lisp_Cons && EQ (val, Qnil))
636 return last_tail;
637
638 /* Copy the contents of the args into the result. */
639 if (CONSP (val))
640 tail = val, toindex = -1; /* -1 in toindex is flag we are making a list */
641 else
642 toindex = 0, toindex_byte = 0;
643
644 prev = Qnil;
645
646 maybe_combine_byte = 0;
647 for (argnum = 0; argnum < nargs; argnum++)
648 {
649 Lisp_Object thislen;
650 int thisleni;
651 register unsigned int thisindex = 0;
652 register unsigned int thisindex_byte = 0;
653
654 this = args[argnum];
655 if (!CONSP (this))
656 thislen = Flength (this), thisleni = XINT (thislen);
657
658 if (STRINGP (this) && STRINGP (val)
659 && ! NULL_INTERVAL_P (XSTRING (this)->intervals))
660 copy_text_properties (make_number (0), thislen, this,
661 make_number (toindex), val, Qnil);
662
663 /* Between strings of the same kind, copy fast. */
664 if (STRINGP (this) && STRINGP (val)
665 && STRING_MULTIBYTE (this) == some_multibyte)
666 {
667 int thislen_byte = STRING_BYTES (XSTRING (this));
668 bcopy (XSTRING (this)->data, XSTRING (val)->data + toindex_byte,
669 STRING_BYTES (XSTRING (this)));
670 if (some_multibyte
671 && toindex_byte > 0
672 && !ASCII_BYTE_P (XSTRING (val)->data[toindex_byte - 1])
673 && !CHAR_HEAD_P (XSTRING (this)->data[0]))
674 maybe_combine_byte = 1;
675 toindex_byte += thislen_byte;
676 toindex += thisleni;
677 }
678 /* Copy a single-byte string to a multibyte string. */
679 else if (STRINGP (this) && STRINGP (val))
680 {
681 toindex_byte += copy_text (XSTRING (this)->data,
682 XSTRING (val)->data + toindex_byte,
683 XSTRING (this)->size, 0, 1);
684 toindex += thisleni;
685 }
686 else
687 /* Copy element by element. */
688 while (1)
689 {
690 register Lisp_Object elt;
691
692 /* Fetch next element of `this' arg into `elt', or break if
693 `this' is exhausted. */
694 if (NILP (this)) break;
695 if (CONSP (this))
696 elt = XCONS (this)->car, this = XCONS (this)->cdr;
697 else if (thisindex >= thisleni)
698 break;
699 else if (STRINGP (this))
700 {
701 int c;
702 if (STRING_MULTIBYTE (this))
703 {
704 FETCH_STRING_CHAR_ADVANCE (c, this,
705 thisindex,
706 thisindex_byte);
707 XSETFASTINT (elt, c);
708 }
709 else
710 {
711 XSETFASTINT (elt, XSTRING (this)->data[thisindex++]);
712 if (some_multibyte
713 && (XINT (elt) >= 0240
714 || ! NILP (Vnonascii_translation_table))
715 && XINT (elt) < 0400)
716 {
717 c = unibyte_char_to_multibyte (XINT (elt));
718 XSETINT (elt, c);
719 }
720 }
721 }
722 else if (BOOL_VECTOR_P (this))
723 {
724 int byte;
725 byte = XBOOL_VECTOR (this)->data[thisindex / BITS_PER_CHAR];
726 if (byte & (1 << (thisindex % BITS_PER_CHAR)))
727 elt = Qt;
728 else
729 elt = Qnil;
730 thisindex++;
731 }
732 else
733 elt = XVECTOR (this)->contents[thisindex++];
734
735 /* Store this element into the result. */
736 if (toindex < 0)
737 {
738 XCONS (tail)->car = elt;
739 prev = tail;
740 tail = XCONS (tail)->cdr;
741 }
742 else if (VECTORP (val))
743 XVECTOR (val)->contents[toindex++] = elt;
744 else
745 {
746 CHECK_NUMBER (elt, 0);
747 if (SINGLE_BYTE_CHAR_P (XINT (elt)))
748 {
749 if (some_multibyte
750 && toindex_byte > 0
751 && !ASCII_BYTE_P (XSTRING (val)->data[toindex_byte - 1])
752 && !CHAR_HEAD_P (XINT (elt)))
753 maybe_combine_byte = 1;
754 XSTRING (val)->data[toindex_byte++] = XINT (elt);
755 toindex++;
756 }
757 else
758 /* If we have any multibyte characters,
759 we already decided to make a multibyte string. */
760 {
761 int c = XINT (elt);
762 unsigned char work[4], *str;
763 int i = CHAR_STRING (c, work, str);
764
765 /* P exists as a variable
766 to avoid a bug on the Masscomp C compiler. */
767 unsigned char *p = & XSTRING (val)->data[toindex_byte];
768 bcopy (str, p, i);
769 toindex_byte += i;
770 toindex++;
771 }
772 }
773 }
774 }
775 if (!NILP (prev))
776 XCONS (prev)->cdr = last_tail;
777
778 if (maybe_combine_byte)
779 /* Character counter of the multibyte string VAL may be wrong
780 because of byte combining problem. We must re-calculate it. */
781 XSTRING (val)->size = multibyte_chars_in_text (XSTRING (val)->data,
782 XSTRING (val)->size_byte);
783
784 return val;
785 }
786 \f
787 static Lisp_Object string_char_byte_cache_string;
788 static int string_char_byte_cache_charpos;
789 static int string_char_byte_cache_bytepos;
790
791 void
792 clear_string_char_byte_cache ()
793 {
794 string_char_byte_cache_string = Qnil;
795 }
796
797 /* Return the character index corresponding to CHAR_INDEX in STRING. */
798
799 int
800 string_char_to_byte (string, char_index)
801 Lisp_Object string;
802 int char_index;
803 {
804 int i, i_byte;
805 int best_below, best_below_byte;
806 int best_above, best_above_byte;
807
808 if (! STRING_MULTIBYTE (string))
809 return char_index;
810
811 best_below = best_below_byte = 0;
812 best_above = XSTRING (string)->size;
813 best_above_byte = STRING_BYTES (XSTRING (string));
814
815 if (EQ (string, string_char_byte_cache_string))
816 {
817 if (string_char_byte_cache_charpos < char_index)
818 {
819 best_below = string_char_byte_cache_charpos;
820 best_below_byte = string_char_byte_cache_bytepos;
821 }
822 else
823 {
824 best_above = string_char_byte_cache_charpos;
825 best_above_byte = string_char_byte_cache_bytepos;
826 }
827 }
828
829 if (char_index - best_below < best_above - char_index)
830 {
831 while (best_below < char_index)
832 {
833 int c;
834 FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
835 }
836 i = best_below;
837 i_byte = best_below_byte;
838 }
839 else
840 {
841 while (best_above > char_index)
842 {
843 int best_above_byte_saved = --best_above_byte;
844
845 while (best_above_byte > 0
846 && !CHAR_HEAD_P (XSTRING (string)->data[best_above_byte]))
847 best_above_byte--;
848 if (XSTRING (string)->data[best_above_byte] < 0x80)
849 best_above_byte = best_above_byte_saved;
850 best_above--;
851 }
852 i = best_above;
853 i_byte = best_above_byte;
854 }
855
856 string_char_byte_cache_bytepos = i_byte;
857 string_char_byte_cache_charpos = i;
858 string_char_byte_cache_string = string;
859
860 return i_byte;
861 }
862 \f
863 /* Return the character index corresponding to BYTE_INDEX in STRING. */
864
865 int
866 string_byte_to_char (string, byte_index)
867 Lisp_Object string;
868 int byte_index;
869 {
870 int i, i_byte;
871 int best_below, best_below_byte;
872 int best_above, best_above_byte;
873
874 if (! STRING_MULTIBYTE (string))
875 return byte_index;
876
877 best_below = best_below_byte = 0;
878 best_above = XSTRING (string)->size;
879 best_above_byte = STRING_BYTES (XSTRING (string));
880
881 if (EQ (string, string_char_byte_cache_string))
882 {
883 if (string_char_byte_cache_bytepos < byte_index)
884 {
885 best_below = string_char_byte_cache_charpos;
886 best_below_byte = string_char_byte_cache_bytepos;
887 }
888 else
889 {
890 best_above = string_char_byte_cache_charpos;
891 best_above_byte = string_char_byte_cache_bytepos;
892 }
893 }
894
895 if (byte_index - best_below_byte < best_above_byte - byte_index)
896 {
897 while (best_below_byte < byte_index)
898 {
899 int c;
900 FETCH_STRING_CHAR_ADVANCE (c, string, best_below, best_below_byte);
901 }
902 i = best_below;
903 i_byte = best_below_byte;
904 }
905 else
906 {
907 while (best_above_byte > byte_index)
908 {
909 int best_above_byte_saved = --best_above_byte;
910
911 while (best_above_byte > 0
912 && !CHAR_HEAD_P (XSTRING (string)->data[best_above_byte]))
913 best_above_byte--;
914 if (XSTRING (string)->data[best_above_byte] < 0x80)
915 best_above_byte = best_above_byte_saved;
916 best_above--;
917 }
918 i = best_above;
919 i_byte = best_above_byte;
920 }
921
922 string_char_byte_cache_bytepos = i_byte;
923 string_char_byte_cache_charpos = i;
924 string_char_byte_cache_string = string;
925
926 return i;
927 }
928 \f
929 /* Convert STRING to a multibyte string.
930 Single-byte characters 0240 through 0377 are converted
931 by adding nonascii_insert_offset to each. */
932
933 Lisp_Object
934 string_make_multibyte (string)
935 Lisp_Object string;
936 {
937 unsigned char *buf;
938 int nbytes;
939
940 if (STRING_MULTIBYTE (string))
941 return string;
942
943 nbytes = count_size_as_multibyte (XSTRING (string)->data,
944 XSTRING (string)->size);
945 /* If all the chars are ASCII, they won't need any more bytes
946 once converted. In that case, we can return STRING itself. */
947 if (nbytes == STRING_BYTES (XSTRING (string)))
948 return string;
949
950 buf = (unsigned char *) alloca (nbytes);
951 copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
952 0, 1);
953
954 return make_multibyte_string (buf, XSTRING (string)->size, nbytes);
955 }
956
957 /* Convert STRING to a single-byte string. */
958
959 Lisp_Object
960 string_make_unibyte (string)
961 Lisp_Object string;
962 {
963 unsigned char *buf;
964
965 if (! STRING_MULTIBYTE (string))
966 return string;
967
968 buf = (unsigned char *) alloca (XSTRING (string)->size);
969
970 copy_text (XSTRING (string)->data, buf, STRING_BYTES (XSTRING (string)),
971 1, 0);
972
973 return make_unibyte_string (buf, XSTRING (string)->size);
974 }
975
976 DEFUN ("string-make-multibyte", Fstring_make_multibyte, Sstring_make_multibyte,
977 1, 1, 0,
978 "Return the multibyte equivalent of STRING.\n\
979 The function `unibyte-char-to-multibyte' is used to convert\n\
980 each unibyte character to a multibyte character.")
981 (string)
982 Lisp_Object string;
983 {
984 CHECK_STRING (string, 0);
985
986 return string_make_multibyte (string);
987 }
988
989 DEFUN ("string-make-unibyte", Fstring_make_unibyte, Sstring_make_unibyte,
990 1, 1, 0,
991 "Return the unibyte equivalent of STRING.\n\
992 Multibyte character codes are converted to unibyte\n\
993 by using just the low 8 bits.")
994 (string)
995 Lisp_Object string;
996 {
997 CHECK_STRING (string, 0);
998
999 return string_make_unibyte (string);
1000 }
1001
1002 DEFUN ("string-as-unibyte", Fstring_as_unibyte, Sstring_as_unibyte,
1003 1, 1, 0,
1004 "Return a unibyte string with the same individual bytes as STRING.\n\
1005 If STRING is unibyte, the result is STRING itself.")
1006 (string)
1007 Lisp_Object string;
1008 {
1009 CHECK_STRING (string, 0);
1010
1011 if (STRING_MULTIBYTE (string))
1012 {
1013 string = Fcopy_sequence (string);
1014 XSTRING (string)->size = STRING_BYTES (XSTRING (string));
1015 SET_STRING_BYTES (XSTRING (string), -1);
1016 }
1017 return string;
1018 }
1019
1020 DEFUN ("string-as-multibyte", Fstring_as_multibyte, Sstring_as_multibyte,
1021 1, 1, 0,
1022 "Return a multibyte string with the same individual bytes as STRING.\n\
1023 If STRING is multibyte, the result is STRING itself.")
1024 (string)
1025 Lisp_Object string;
1026 {
1027 CHECK_STRING (string, 0);
1028
1029 if (! STRING_MULTIBYTE (string))
1030 {
1031 int nbytes = STRING_BYTES (XSTRING (string));
1032 int newlen = multibyte_chars_in_text (XSTRING (string)->data, nbytes);
1033
1034 string = Fcopy_sequence (string);
1035 XSTRING (string)->size = newlen;
1036 XSTRING (string)->size_byte = nbytes;
1037 }
1038 return string;
1039 }
1040 \f
1041 DEFUN ("copy-alist", Fcopy_alist, Scopy_alist, 1, 1, 0,
1042 "Return a copy of ALIST.\n\
1043 This is an alist which represents the same mapping from objects to objects,\n\
1044 but does not share the alist structure with ALIST.\n\
1045 The objects mapped (cars and cdrs of elements of the alist)\n\
1046 are shared, however.\n\
1047 Elements of ALIST that are not conses are also shared.")
1048 (alist)
1049 Lisp_Object alist;
1050 {
1051 register Lisp_Object tem;
1052
1053 CHECK_LIST (alist, 0);
1054 if (NILP (alist))
1055 return alist;
1056 alist = concat (1, &alist, Lisp_Cons, 0);
1057 for (tem = alist; CONSP (tem); tem = XCONS (tem)->cdr)
1058 {
1059 register Lisp_Object car;
1060 car = XCONS (tem)->car;
1061
1062 if (CONSP (car))
1063 XCONS (tem)->car = Fcons (XCONS (car)->car, XCONS (car)->cdr);
1064 }
1065 return alist;
1066 }
1067
1068 DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
1069 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
1070 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
1071 If FROM or TO is negative, it counts from the end.\n\
1072 \n\
1073 This function allows vectors as well as strings.")
1074 (string, from, to)
1075 Lisp_Object string;
1076 register Lisp_Object from, to;
1077 {
1078 Lisp_Object res;
1079 int size;
1080 int size_byte;
1081 int from_char, to_char;
1082 int from_byte, to_byte;
1083
1084 if (! (STRINGP (string) || VECTORP (string)))
1085 wrong_type_argument (Qarrayp, string);
1086
1087 CHECK_NUMBER (from, 1);
1088
1089 if (STRINGP (string))
1090 {
1091 size = XSTRING (string)->size;
1092 size_byte = STRING_BYTES (XSTRING (string));
1093 }
1094 else
1095 size = XVECTOR (string)->size;
1096
1097 if (NILP (to))
1098 {
1099 to_char = size;
1100 to_byte = size_byte;
1101 }
1102 else
1103 {
1104 CHECK_NUMBER (to, 2);
1105
1106 to_char = XINT (to);
1107 if (to_char < 0)
1108 to_char += size;
1109
1110 if (STRINGP (string))
1111 to_byte = string_char_to_byte (string, to_char);
1112 }
1113
1114 from_char = XINT (from);
1115 if (from_char < 0)
1116 from_char += size;
1117 if (STRINGP (string))
1118 from_byte = string_char_to_byte (string, from_char);
1119
1120 if (!(0 <= from_char && from_char <= to_char && to_char <= size))
1121 args_out_of_range_3 (string, make_number (from_char),
1122 make_number (to_char));
1123
1124 if (STRINGP (string))
1125 {
1126 res = make_specified_string (XSTRING (string)->data + from_byte,
1127 to_char - from_char, to_byte - from_byte,
1128 STRING_MULTIBYTE (string));
1129 copy_text_properties (make_number (from_char), make_number (to_char),
1130 string, make_number (0), res, Qnil);
1131 }
1132 else
1133 res = Fvector (to_char - from_char,
1134 XVECTOR (string)->contents + from_char);
1135
1136 return res;
1137 }
1138
1139 /* Extract a substring of STRING, giving start and end positions
1140 both in characters and in bytes. */
1141
1142 Lisp_Object
1143 substring_both (string, from, from_byte, to, to_byte)
1144 Lisp_Object string;
1145 int from, from_byte, to, to_byte;
1146 {
1147 Lisp_Object res;
1148 int size;
1149 int size_byte;
1150
1151 if (! (STRINGP (string) || VECTORP (string)))
1152 wrong_type_argument (Qarrayp, string);
1153
1154 if (STRINGP (string))
1155 {
1156 size = XSTRING (string)->size;
1157 size_byte = STRING_BYTES (XSTRING (string));
1158 }
1159 else
1160 size = XVECTOR (string)->size;
1161
1162 if (!(0 <= from && from <= to && to <= size))
1163 args_out_of_range_3 (string, make_number (from), make_number (to));
1164
1165 if (STRINGP (string))
1166 {
1167 res = make_specified_string (XSTRING (string)->data + from_byte,
1168 to - from, to_byte - from_byte,
1169 STRING_MULTIBYTE (string));
1170 copy_text_properties (make_number (from), make_number (to),
1171 string, make_number (0), res, Qnil);
1172 }
1173 else
1174 res = Fvector (to - from,
1175 XVECTOR (string)->contents + from);
1176
1177 return res;
1178 }
1179 \f
1180 DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
1181 "Take cdr N times on LIST, returns the result.")
1182 (n, list)
1183 Lisp_Object n;
1184 register Lisp_Object list;
1185 {
1186 register int i, num;
1187 CHECK_NUMBER (n, 0);
1188 num = XINT (n);
1189 for (i = 0; i < num && !NILP (list); i++)
1190 {
1191 QUIT;
1192 list = Fcdr (list);
1193 }
1194 return list;
1195 }
1196
1197 DEFUN ("nth", Fnth, Snth, 2, 2, 0,
1198 "Return the Nth element of LIST.\n\
1199 N counts from zero. If LIST is not that long, nil is returned.")
1200 (n, list)
1201 Lisp_Object n, list;
1202 {
1203 return Fcar (Fnthcdr (n, list));
1204 }
1205
1206 DEFUN ("elt", Felt, Selt, 2, 2, 0,
1207 "Return element of SEQUENCE at index N.")
1208 (sequence, n)
1209 register Lisp_Object sequence, n;
1210 {
1211 CHECK_NUMBER (n, 0);
1212 while (1)
1213 {
1214 if (CONSP (sequence) || NILP (sequence))
1215 return Fcar (Fnthcdr (n, sequence));
1216 else if (STRINGP (sequence) || VECTORP (sequence)
1217 || BOOL_VECTOR_P (sequence) || CHAR_TABLE_P (sequence))
1218 return Faref (sequence, n);
1219 else
1220 sequence = wrong_type_argument (Qsequencep, sequence);
1221 }
1222 }
1223
1224 DEFUN ("member", Fmember, Smember, 2, 2, 0,
1225 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
1226 The value is actually the tail of LIST whose car is ELT.")
1227 (elt, list)
1228 register Lisp_Object elt;
1229 Lisp_Object list;
1230 {
1231 register Lisp_Object tail;
1232 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1233 {
1234 register Lisp_Object tem;
1235 tem = Fcar (tail);
1236 if (! NILP (Fequal (elt, tem)))
1237 return tail;
1238 QUIT;
1239 }
1240 return Qnil;
1241 }
1242
1243 DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
1244 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
1245 The value is actually the tail of LIST whose car is ELT.")
1246 (elt, list)
1247 register Lisp_Object elt;
1248 Lisp_Object list;
1249 {
1250 register Lisp_Object tail;
1251 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1252 {
1253 register Lisp_Object tem;
1254 tem = Fcar (tail);
1255 if (EQ (elt, tem)) return tail;
1256 QUIT;
1257 }
1258 return Qnil;
1259 }
1260
1261 DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
1262 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
1263 The value is actually the element of LIST whose car is KEY.\n\
1264 Elements of LIST that are not conses are ignored.")
1265 (key, list)
1266 register Lisp_Object key;
1267 Lisp_Object list;
1268 {
1269 register Lisp_Object tail;
1270 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1271 {
1272 register Lisp_Object elt, tem;
1273 elt = Fcar (tail);
1274 if (!CONSP (elt)) continue;
1275 tem = XCONS (elt)->car;
1276 if (EQ (key, tem)) return elt;
1277 QUIT;
1278 }
1279 return Qnil;
1280 }
1281
1282 /* Like Fassq but never report an error and do not allow quits.
1283 Use only on lists known never to be circular. */
1284
1285 Lisp_Object
1286 assq_no_quit (key, list)
1287 register Lisp_Object key;
1288 Lisp_Object list;
1289 {
1290 register Lisp_Object tail;
1291 for (tail = list; CONSP (tail); tail = XCONS (tail)->cdr)
1292 {
1293 register Lisp_Object elt, tem;
1294 elt = Fcar (tail);
1295 if (!CONSP (elt)) continue;
1296 tem = XCONS (elt)->car;
1297 if (EQ (key, tem)) return elt;
1298 }
1299 return Qnil;
1300 }
1301
1302 DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
1303 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
1304 The value is actually the element of LIST whose car equals KEY.")
1305 (key, list)
1306 register Lisp_Object key;
1307 Lisp_Object list;
1308 {
1309 register Lisp_Object tail;
1310 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1311 {
1312 register Lisp_Object elt, tem;
1313 elt = Fcar (tail);
1314 if (!CONSP (elt)) continue;
1315 tem = Fequal (XCONS (elt)->car, key);
1316 if (!NILP (tem)) return elt;
1317 QUIT;
1318 }
1319 return Qnil;
1320 }
1321
1322 DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
1323 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
1324 The value is actually the element of LIST whose cdr is ELT.")
1325 (key, list)
1326 register Lisp_Object key;
1327 Lisp_Object list;
1328 {
1329 register Lisp_Object tail;
1330 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1331 {
1332 register Lisp_Object elt, tem;
1333 elt = Fcar (tail);
1334 if (!CONSP (elt)) continue;
1335 tem = XCONS (elt)->cdr;
1336 if (EQ (key, tem)) return elt;
1337 QUIT;
1338 }
1339 return Qnil;
1340 }
1341
1342 DEFUN ("rassoc", Frassoc, Srassoc, 2, 2, 0,
1343 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
1344 The value is actually the element of LIST whose cdr equals KEY.")
1345 (key, list)
1346 register Lisp_Object key;
1347 Lisp_Object list;
1348 {
1349 register Lisp_Object tail;
1350 for (tail = list; !NILP (tail); tail = XCONS (tail)->cdr)
1351 {
1352 register Lisp_Object elt, tem;
1353 elt = Fcar (tail);
1354 if (!CONSP (elt)) continue;
1355 tem = Fequal (XCONS (elt)->cdr, key);
1356 if (!NILP (tem)) return elt;
1357 QUIT;
1358 }
1359 return Qnil;
1360 }
1361 \f
1362 DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
1363 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1364 The modified LIST is returned. Comparison is done with `eq'.\n\
1365 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
1366 therefore, write `(setq foo (delq element foo))'\n\
1367 to be sure of changing the value of `foo'.")
1368 (elt, list)
1369 register Lisp_Object elt;
1370 Lisp_Object list;
1371 {
1372 register Lisp_Object tail, prev;
1373 register Lisp_Object tem;
1374
1375 tail = list;
1376 prev = Qnil;
1377 while (!NILP (tail))
1378 {
1379 tem = Fcar (tail);
1380 if (EQ (elt, tem))
1381 {
1382 if (NILP (prev))
1383 list = XCONS (tail)->cdr;
1384 else
1385 Fsetcdr (prev, XCONS (tail)->cdr);
1386 }
1387 else
1388 prev = tail;
1389 tail = XCONS (tail)->cdr;
1390 QUIT;
1391 }
1392 return list;
1393 }
1394
1395 DEFUN ("delete", Fdelete, Sdelete, 2, 2, 0,
1396 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1397 The modified LIST is returned. Comparison is done with `equal'.\n\
1398 If the first member of LIST is ELT, deleting it is not a side effect;\n\
1399 it is simply using a different list.\n\
1400 Therefore, write `(setq foo (delete element foo))'\n\
1401 to be sure of changing the value of `foo'.")
1402 (elt, list)
1403 register Lisp_Object elt;
1404 Lisp_Object list;
1405 {
1406 register Lisp_Object tail, prev;
1407 register Lisp_Object tem;
1408
1409 tail = list;
1410 prev = Qnil;
1411 while (!NILP (tail))
1412 {
1413 tem = Fcar (tail);
1414 if (! NILP (Fequal (elt, tem)))
1415 {
1416 if (NILP (prev))
1417 list = XCONS (tail)->cdr;
1418 else
1419 Fsetcdr (prev, XCONS (tail)->cdr);
1420 }
1421 else
1422 prev = tail;
1423 tail = XCONS (tail)->cdr;
1424 QUIT;
1425 }
1426 return list;
1427 }
1428
1429 DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
1430 "Reverse LIST by modifying cdr pointers.\n\
1431 Returns the beginning of the reversed list.")
1432 (list)
1433 Lisp_Object list;
1434 {
1435 register Lisp_Object prev, tail, next;
1436
1437 if (NILP (list)) return list;
1438 prev = Qnil;
1439 tail = list;
1440 while (!NILP (tail))
1441 {
1442 QUIT;
1443 next = Fcdr (tail);
1444 Fsetcdr (tail, prev);
1445 prev = tail;
1446 tail = next;
1447 }
1448 return prev;
1449 }
1450
1451 DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
1452 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
1453 See also the function `nreverse', which is used more often.")
1454 (list)
1455 Lisp_Object list;
1456 {
1457 Lisp_Object new;
1458
1459 for (new = Qnil; CONSP (list); list = XCONS (list)->cdr)
1460 new = Fcons (XCONS (list)->car, new);
1461 if (!NILP (list))
1462 wrong_type_argument (Qconsp, list);
1463 return new;
1464 }
1465 \f
1466 Lisp_Object merge ();
1467
1468 DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
1469 "Sort LIST, stably, comparing elements using PREDICATE.\n\
1470 Returns the sorted list. LIST is modified by side effects.\n\
1471 PREDICATE is called with two elements of LIST, and should return T\n\
1472 if the first element is \"less\" than the second.")
1473 (list, predicate)
1474 Lisp_Object list, predicate;
1475 {
1476 Lisp_Object front, back;
1477 register Lisp_Object len, tem;
1478 struct gcpro gcpro1, gcpro2;
1479 register int length;
1480
1481 front = list;
1482 len = Flength (list);
1483 length = XINT (len);
1484 if (length < 2)
1485 return list;
1486
1487 XSETINT (len, (length / 2) - 1);
1488 tem = Fnthcdr (len, list);
1489 back = Fcdr (tem);
1490 Fsetcdr (tem, Qnil);
1491
1492 GCPRO2 (front, back);
1493 front = Fsort (front, predicate);
1494 back = Fsort (back, predicate);
1495 UNGCPRO;
1496 return merge (front, back, predicate);
1497 }
1498
1499 Lisp_Object
1500 merge (org_l1, org_l2, pred)
1501 Lisp_Object org_l1, org_l2;
1502 Lisp_Object pred;
1503 {
1504 Lisp_Object value;
1505 register Lisp_Object tail;
1506 Lisp_Object tem;
1507 register Lisp_Object l1, l2;
1508 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1509
1510 l1 = org_l1;
1511 l2 = org_l2;
1512 tail = Qnil;
1513 value = Qnil;
1514
1515 /* It is sufficient to protect org_l1 and org_l2.
1516 When l1 and l2 are updated, we copy the new values
1517 back into the org_ vars. */
1518 GCPRO4 (org_l1, org_l2, pred, value);
1519
1520 while (1)
1521 {
1522 if (NILP (l1))
1523 {
1524 UNGCPRO;
1525 if (NILP (tail))
1526 return l2;
1527 Fsetcdr (tail, l2);
1528 return value;
1529 }
1530 if (NILP (l2))
1531 {
1532 UNGCPRO;
1533 if (NILP (tail))
1534 return l1;
1535 Fsetcdr (tail, l1);
1536 return value;
1537 }
1538 tem = call2 (pred, Fcar (l2), Fcar (l1));
1539 if (NILP (tem))
1540 {
1541 tem = l1;
1542 l1 = Fcdr (l1);
1543 org_l1 = l1;
1544 }
1545 else
1546 {
1547 tem = l2;
1548 l2 = Fcdr (l2);
1549 org_l2 = l2;
1550 }
1551 if (NILP (tail))
1552 value = tem;
1553 else
1554 Fsetcdr (tail, tem);
1555 tail = tem;
1556 }
1557 }
1558 \f
1559
1560 DEFUN ("plist-get", Fplist_get, Splist_get, 2, 2, 0,
1561 "Extract a value from a property list.\n\
1562 PLIST is a property list, which is a list of the form\n\
1563 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
1564 corresponding to the given PROP, or nil if PROP is not\n\
1565 one of the properties on the list.")
1566 (plist, prop)
1567 Lisp_Object plist;
1568 register Lisp_Object prop;
1569 {
1570 register Lisp_Object tail;
1571 for (tail = plist; !NILP (tail); tail = Fcdr (XCONS (tail)->cdr))
1572 {
1573 register Lisp_Object tem;
1574 tem = Fcar (tail);
1575 if (EQ (prop, tem))
1576 return Fcar (XCONS (tail)->cdr);
1577 }
1578 return Qnil;
1579 }
1580
1581 DEFUN ("get", Fget, Sget, 2, 2, 0,
1582 "Return the value of SYMBOL's PROPNAME property.\n\
1583 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
1584 (symbol, propname)
1585 Lisp_Object symbol, propname;
1586 {
1587 CHECK_SYMBOL (symbol, 0);
1588 return Fplist_get (XSYMBOL (symbol)->plist, propname);
1589 }
1590
1591 DEFUN ("plist-put", Fplist_put, Splist_put, 3, 3, 0,
1592 "Change value in PLIST of PROP to VAL.\n\
1593 PLIST is a property list, which is a list of the form\n\
1594 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
1595 If PROP is already a property on the list, its value is set to VAL,\n\
1596 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
1597 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
1598 The PLIST is modified by side effects.")
1599 (plist, prop, val)
1600 Lisp_Object plist;
1601 register Lisp_Object prop;
1602 Lisp_Object val;
1603 {
1604 register Lisp_Object tail, prev;
1605 Lisp_Object newcell;
1606 prev = Qnil;
1607 for (tail = plist; CONSP (tail) && CONSP (XCONS (tail)->cdr);
1608 tail = XCONS (XCONS (tail)->cdr)->cdr)
1609 {
1610 if (EQ (prop, XCONS (tail)->car))
1611 {
1612 Fsetcar (XCONS (tail)->cdr, val);
1613 return plist;
1614 }
1615 prev = tail;
1616 }
1617 newcell = Fcons (prop, Fcons (val, Qnil));
1618 if (NILP (prev))
1619 return newcell;
1620 else
1621 Fsetcdr (XCONS (prev)->cdr, newcell);
1622 return plist;
1623 }
1624
1625 DEFUN ("put", Fput, Sput, 3, 3, 0,
1626 "Store SYMBOL's PROPNAME property with value VALUE.\n\
1627 It can be retrieved with `(get SYMBOL PROPNAME)'.")
1628 (symbol, propname, value)
1629 Lisp_Object symbol, propname, value;
1630 {
1631 CHECK_SYMBOL (symbol, 0);
1632 XSYMBOL (symbol)->plist
1633 = Fplist_put (XSYMBOL (symbol)->plist, propname, value);
1634 return value;
1635 }
1636
1637 DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
1638 "Return t if two Lisp objects have similar structure and contents.\n\
1639 They must have the same data type.\n\
1640 Conses are compared by comparing the cars and the cdrs.\n\
1641 Vectors and strings are compared element by element.\n\
1642 Numbers are compared by value, but integers cannot equal floats.\n\
1643 (Use `=' if you want integers and floats to be able to be equal.)\n\
1644 Symbols must match exactly.")
1645 (o1, o2)
1646 register Lisp_Object o1, o2;
1647 {
1648 return internal_equal (o1, o2, 0) ? Qt : Qnil;
1649 }
1650
1651 static int
1652 internal_equal (o1, o2, depth)
1653 register Lisp_Object o1, o2;
1654 int depth;
1655 {
1656 if (depth > 200)
1657 error ("Stack overflow in equal");
1658
1659 tail_recurse:
1660 QUIT;
1661 if (EQ (o1, o2))
1662 return 1;
1663 if (XTYPE (o1) != XTYPE (o2))
1664 return 0;
1665
1666 switch (XTYPE (o1))
1667 {
1668 #ifdef LISP_FLOAT_TYPE
1669 case Lisp_Float:
1670 return (extract_float (o1) == extract_float (o2));
1671 #endif
1672
1673 case Lisp_Cons:
1674 if (!internal_equal (XCONS (o1)->car, XCONS (o2)->car, depth + 1))
1675 return 0;
1676 o1 = XCONS (o1)->cdr;
1677 o2 = XCONS (o2)->cdr;
1678 goto tail_recurse;
1679
1680 case Lisp_Misc:
1681 if (XMISCTYPE (o1) != XMISCTYPE (o2))
1682 return 0;
1683 if (OVERLAYP (o1))
1684 {
1685 if (!internal_equal (OVERLAY_START (o1), OVERLAY_START (o1),
1686 depth + 1)
1687 || !internal_equal (OVERLAY_END (o1), OVERLAY_END (o1),
1688 depth + 1))
1689 return 0;
1690 o1 = XOVERLAY (o1)->plist;
1691 o2 = XOVERLAY (o2)->plist;
1692 goto tail_recurse;
1693 }
1694 if (MARKERP (o1))
1695 {
1696 return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
1697 && (XMARKER (o1)->buffer == 0
1698 || XMARKER (o1)->bytepos == XMARKER (o2)->bytepos));
1699 }
1700 break;
1701
1702 case Lisp_Vectorlike:
1703 {
1704 register int i, size;
1705 size = XVECTOR (o1)->size;
1706 /* Pseudovectors have the type encoded in the size field, so this test
1707 actually checks that the objects have the same type as well as the
1708 same size. */
1709 if (XVECTOR (o2)->size != size)
1710 return 0;
1711 /* Boolvectors are compared much like strings. */
1712 if (BOOL_VECTOR_P (o1))
1713 {
1714 int size_in_chars
1715 = (XBOOL_VECTOR (o1)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1716
1717 if (XBOOL_VECTOR (o1)->size != XBOOL_VECTOR (o2)->size)
1718 return 0;
1719 if (bcmp (XBOOL_VECTOR (o1)->data, XBOOL_VECTOR (o2)->data,
1720 size_in_chars))
1721 return 0;
1722 return 1;
1723 }
1724 if (WINDOW_CONFIGURATIONP (o1))
1725 return compare_window_configurations (o1, o2, 0);
1726
1727 /* Aside from them, only true vectors, char-tables, and compiled
1728 functions are sensible to compare, so eliminate the others now. */
1729 if (size & PSEUDOVECTOR_FLAG)
1730 {
1731 if (!(size & (PVEC_COMPILED | PVEC_CHAR_TABLE)))
1732 return 0;
1733 size &= PSEUDOVECTOR_SIZE_MASK;
1734 }
1735 for (i = 0; i < size; i++)
1736 {
1737 Lisp_Object v1, v2;
1738 v1 = XVECTOR (o1)->contents [i];
1739 v2 = XVECTOR (o2)->contents [i];
1740 if (!internal_equal (v1, v2, depth + 1))
1741 return 0;
1742 }
1743 return 1;
1744 }
1745 break;
1746
1747 case Lisp_String:
1748 if (XSTRING (o1)->size != XSTRING (o2)->size)
1749 return 0;
1750 if (STRING_BYTES (XSTRING (o1)) != STRING_BYTES (XSTRING (o2)))
1751 return 0;
1752 if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data,
1753 STRING_BYTES (XSTRING (o1))))
1754 return 0;
1755 return 1;
1756 }
1757 return 0;
1758 }
1759 \f
1760 extern Lisp_Object Fmake_char_internal ();
1761
1762 DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
1763 "Store each element of ARRAY with ITEM.\n\
1764 ARRAY is a vector, string, char-table, or bool-vector.")
1765 (array, item)
1766 Lisp_Object array, item;
1767 {
1768 register int size, index, charval;
1769 retry:
1770 if (VECTORP (array))
1771 {
1772 register Lisp_Object *p = XVECTOR (array)->contents;
1773 size = XVECTOR (array)->size;
1774 for (index = 0; index < size; index++)
1775 p[index] = item;
1776 }
1777 else if (CHAR_TABLE_P (array))
1778 {
1779 register Lisp_Object *p = XCHAR_TABLE (array)->contents;
1780 size = CHAR_TABLE_ORDINARY_SLOTS;
1781 for (index = 0; index < size; index++)
1782 p[index] = item;
1783 XCHAR_TABLE (array)->defalt = Qnil;
1784 }
1785 else if (STRINGP (array))
1786 {
1787 register unsigned char *p = XSTRING (array)->data;
1788 CHECK_NUMBER (item, 1);
1789 charval = XINT (item);
1790 size = XSTRING (array)->size;
1791 if (STRING_MULTIBYTE (array))
1792 {
1793 unsigned char workbuf[4], *str;
1794 int len = CHAR_STRING (charval, workbuf, str);
1795 int size_byte = STRING_BYTES (XSTRING (array));
1796 unsigned char *p1 = p, *endp = p + size_byte;
1797 int i;
1798
1799 if (size != size_byte)
1800 while (p1 < endp)
1801 {
1802 int this_len = MULTIBYTE_FORM_LENGTH (p1, endp - p1);
1803 if (len != this_len)
1804 error ("Attempt to change byte length of a string");
1805 p1 += this_len;
1806 }
1807 for (i = 0; i < size_byte; i++)
1808 *p++ = str[i % len];
1809 }
1810 else
1811 for (index = 0; index < size; index++)
1812 p[index] = charval;
1813 }
1814 else if (BOOL_VECTOR_P (array))
1815 {
1816 register unsigned char *p = XBOOL_VECTOR (array)->data;
1817 int size_in_chars
1818 = (XBOOL_VECTOR (array)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
1819
1820 charval = (! NILP (item) ? -1 : 0);
1821 for (index = 0; index < size_in_chars; index++)
1822 p[index] = charval;
1823 }
1824 else
1825 {
1826 array = wrong_type_argument (Qarrayp, array);
1827 goto retry;
1828 }
1829 return array;
1830 }
1831 \f
1832 DEFUN ("char-table-subtype", Fchar_table_subtype, Schar_table_subtype,
1833 1, 1, 0,
1834 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1835 (char_table)
1836 Lisp_Object char_table;
1837 {
1838 CHECK_CHAR_TABLE (char_table, 0);
1839
1840 return XCHAR_TABLE (char_table)->purpose;
1841 }
1842
1843 DEFUN ("char-table-parent", Fchar_table_parent, Schar_table_parent,
1844 1, 1, 0,
1845 "Return the parent char-table of CHAR-TABLE.\n\
1846 The value is either nil or another char-table.\n\
1847 If CHAR-TABLE holds nil for a given character,\n\
1848 then the actual applicable value is inherited from the parent char-table\n\
1849 \(or from its parents, if necessary).")
1850 (char_table)
1851 Lisp_Object char_table;
1852 {
1853 CHECK_CHAR_TABLE (char_table, 0);
1854
1855 return XCHAR_TABLE (char_table)->parent;
1856 }
1857
1858 DEFUN ("set-char-table-parent", Fset_char_table_parent, Sset_char_table_parent,
1859 2, 2, 0,
1860 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1861 PARENT must be either nil or another char-table.")
1862 (char_table, parent)
1863 Lisp_Object char_table, parent;
1864 {
1865 Lisp_Object temp;
1866
1867 CHECK_CHAR_TABLE (char_table, 0);
1868
1869 if (!NILP (parent))
1870 {
1871 CHECK_CHAR_TABLE (parent, 0);
1872
1873 for (temp = parent; !NILP (temp); temp = XCHAR_TABLE (temp)->parent)
1874 if (EQ (temp, char_table))
1875 error ("Attempt to make a chartable be its own parent");
1876 }
1877
1878 XCHAR_TABLE (char_table)->parent = parent;
1879
1880 return parent;
1881 }
1882
1883 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot, Schar_table_extra_slot,
1884 2, 2, 0,
1885 "Return the value of CHAR-TABLE's extra-slot number N.")
1886 (char_table, n)
1887 Lisp_Object char_table, n;
1888 {
1889 CHECK_CHAR_TABLE (char_table, 1);
1890 CHECK_NUMBER (n, 2);
1891 if (XINT (n) < 0
1892 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1893 args_out_of_range (char_table, n);
1894
1895 return XCHAR_TABLE (char_table)->extras[XINT (n)];
1896 }
1897
1898 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot,
1899 Sset_char_table_extra_slot,
1900 3, 3, 0,
1901 "Set CHAR-TABLE's extra-slot number N to VALUE.")
1902 (char_table, n, value)
1903 Lisp_Object char_table, n, value;
1904 {
1905 CHECK_CHAR_TABLE (char_table, 1);
1906 CHECK_NUMBER (n, 2);
1907 if (XINT (n) < 0
1908 || XINT (n) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table)))
1909 args_out_of_range (char_table, n);
1910
1911 return XCHAR_TABLE (char_table)->extras[XINT (n)] = value;
1912 }
1913 \f
1914 DEFUN ("char-table-range", Fchar_table_range, Schar_table_range,
1915 2, 2, 0,
1916 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
1917 RANGE should be nil (for the default value)\n\
1918 a vector which identifies a character set or a row of a character set,\n\
1919 a character set name, or a character code.")
1920 (char_table, range)
1921 Lisp_Object char_table, range;
1922 {
1923 int i;
1924
1925 CHECK_CHAR_TABLE (char_table, 0);
1926
1927 if (EQ (range, Qnil))
1928 return XCHAR_TABLE (char_table)->defalt;
1929 else if (INTEGERP (range))
1930 return Faref (char_table, range);
1931 else if (SYMBOLP (range))
1932 {
1933 Lisp_Object charset_info;
1934
1935 charset_info = Fget (range, Qcharset);
1936 CHECK_VECTOR (charset_info, 0);
1937
1938 return Faref (char_table,
1939 make_number (XINT (XVECTOR (charset_info)->contents[0])
1940 + 128));
1941 }
1942 else if (VECTORP (range))
1943 {
1944 if (XVECTOR (range)->size == 1)
1945 return Faref (char_table,
1946 make_number (XINT (XVECTOR (range)->contents[0]) + 128));
1947 else
1948 {
1949 int size = XVECTOR (range)->size;
1950 Lisp_Object *val = XVECTOR (range)->contents;
1951 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
1952 size <= 1 ? Qnil : val[1],
1953 size <= 2 ? Qnil : val[2]);
1954 return Faref (char_table, ch);
1955 }
1956 }
1957 else
1958 error ("Invalid RANGE argument to `char-table-range'");
1959 }
1960
1961 DEFUN ("set-char-table-range", Fset_char_table_range, Sset_char_table_range,
1962 3, 3, 0,
1963 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
1964 RANGE should be t (for all characters), nil (for the default value)\n\
1965 a vector which identifies a character set or a row of a character set,\n\
1966 a coding system, or a character code.")
1967 (char_table, range, value)
1968 Lisp_Object char_table, range, value;
1969 {
1970 int i;
1971
1972 CHECK_CHAR_TABLE (char_table, 0);
1973
1974 if (EQ (range, Qt))
1975 for (i = 0; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
1976 XCHAR_TABLE (char_table)->contents[i] = value;
1977 else if (EQ (range, Qnil))
1978 XCHAR_TABLE (char_table)->defalt = value;
1979 else if (SYMBOLP (range))
1980 {
1981 Lisp_Object charset_info;
1982
1983 charset_info = Fget (range, Qcharset);
1984 CHECK_VECTOR (charset_info, 0);
1985
1986 return Faset (char_table,
1987 make_number (XINT (XVECTOR (charset_info)->contents[0])
1988 + 128),
1989 value);
1990 }
1991 else if (INTEGERP (range))
1992 Faset (char_table, range, value);
1993 else if (VECTORP (range))
1994 {
1995 if (XVECTOR (range)->size == 1)
1996 return Faset (char_table,
1997 make_number (XINT (XVECTOR (range)->contents[0]) + 128),
1998 value);
1999 else
2000 {
2001 int size = XVECTOR (range)->size;
2002 Lisp_Object *val = XVECTOR (range)->contents;
2003 Lisp_Object ch = Fmake_char_internal (size <= 0 ? Qnil : val[0],
2004 size <= 1 ? Qnil : val[1],
2005 size <= 2 ? Qnil : val[2]);
2006 return Faset (char_table, ch, value);
2007 }
2008 }
2009 else
2010 error ("Invalid RANGE argument to `set-char-table-range'");
2011
2012 return value;
2013 }
2014
2015 DEFUN ("set-char-table-default", Fset_char_table_default,
2016 Sset_char_table_default, 3, 3, 0,
2017 "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
2018 The generic character specifies the group of characters.\n\
2019 See also the documentation of make-char.")
2020 (char_table, ch, value)
2021 Lisp_Object char_table, ch, value;
2022 {
2023 int c, i, charset, code1, code2;
2024 Lisp_Object temp;
2025
2026 CHECK_CHAR_TABLE (char_table, 0);
2027 CHECK_NUMBER (ch, 1);
2028
2029 c = XINT (ch);
2030 SPLIT_NON_ASCII_CHAR (c, charset, code1, code2);
2031
2032 /* Since we may want to set the default value for a character set
2033 not yet defined, we check only if the character set is in the
2034 valid range or not, instead of it is already defined or not. */
2035 if (! CHARSET_VALID_P (charset))
2036 invalid_character (c);
2037
2038 if (charset == CHARSET_ASCII)
2039 return (XCHAR_TABLE (char_table)->defalt = value);
2040
2041 /* Even if C is not a generic char, we had better behave as if a
2042 generic char is specified. */
2043 if (charset == CHARSET_COMPOSITION || CHARSET_DIMENSION (charset) == 1)
2044 code1 = 0;
2045 temp = XCHAR_TABLE (char_table)->contents[charset + 128];
2046 if (!code1)
2047 {
2048 if (SUB_CHAR_TABLE_P (temp))
2049 XCHAR_TABLE (temp)->defalt = value;
2050 else
2051 XCHAR_TABLE (char_table)->contents[charset + 128] = value;
2052 return value;
2053 }
2054 char_table = temp;
2055 if (! SUB_CHAR_TABLE_P (char_table))
2056 char_table = (XCHAR_TABLE (char_table)->contents[charset + 128]
2057 = make_sub_char_table (temp));
2058 temp = XCHAR_TABLE (char_table)->contents[code1];
2059 if (SUB_CHAR_TABLE_P (temp))
2060 XCHAR_TABLE (temp)->defalt = value;
2061 else
2062 XCHAR_TABLE (char_table)->contents[code1] = value;
2063 return value;
2064 }
2065
2066 /* Look up the element in TABLE at index CH,
2067 and return it as an integer.
2068 If the element is nil, return CH itself.
2069 (Actually we do that for any non-integer.) */
2070
2071 int
2072 char_table_translate (table, ch)
2073 Lisp_Object table;
2074 int ch;
2075 {
2076 Lisp_Object value;
2077 value = Faref (table, make_number (ch));
2078 if (! INTEGERP (value))
2079 return ch;
2080 return XINT (value);
2081 }
2082 \f
2083 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
2084 character or group of characters that share a value.
2085 DEPTH is the current depth in the originally specified
2086 chartable, and INDICES contains the vector indices
2087 for the levels our callers have descended.
2088
2089 ARG is passed to C_FUNCTION when that is called. */
2090
2091 void
2092 map_char_table (c_function, function, subtable, arg, depth, indices)
2093 void (*c_function) P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
2094 Lisp_Object function, subtable, arg, *indices;
2095 int depth;
2096 {
2097 int i, to;
2098
2099 if (depth == 0)
2100 {
2101 /* At first, handle ASCII and 8-bit European characters. */
2102 for (i = 0; i < CHAR_TABLE_SINGLE_BYTE_SLOTS; i++)
2103 {
2104 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
2105 if (c_function)
2106 (*c_function) (arg, make_number (i), elt);
2107 else
2108 call2 (function, make_number (i), elt);
2109 }
2110 #if 0 /* If the char table has entries for higher characters,
2111 we should report them. */
2112 if (NILP (current_buffer->enable_multibyte_characters))
2113 return;
2114 #endif
2115 to = CHAR_TABLE_ORDINARY_SLOTS;
2116 }
2117 else
2118 {
2119 i = 32;
2120 to = SUB_CHAR_TABLE_ORDINARY_SLOTS;
2121 }
2122
2123 for (; i < to; i++)
2124 {
2125 Lisp_Object elt = XCHAR_TABLE (subtable)->contents[i];
2126
2127 XSETFASTINT (indices[depth], i);
2128
2129 if (SUB_CHAR_TABLE_P (elt))
2130 {
2131 if (depth >= 3)
2132 error ("Too deep char table");
2133 map_char_table (c_function, function, elt, arg, depth + 1, indices);
2134 }
2135 else
2136 {
2137 int charset = XFASTINT (indices[0]) - 128, c1, c2, c;
2138
2139 if (CHARSET_DEFINED_P (charset))
2140 {
2141 c1 = depth >= 1 ? XFASTINT (indices[1]) : 0;
2142 c2 = depth >= 2 ? XFASTINT (indices[2]) : 0;
2143 c = MAKE_NON_ASCII_CHAR (charset, c1, c2);
2144 if (c_function)
2145 (*c_function) (arg, make_number (c), elt);
2146 else
2147 call2 (function, make_number (c), elt);
2148 }
2149 }
2150 }
2151 }
2152
2153 DEFUN ("map-char-table", Fmap_char_table, Smap_char_table,
2154 2, 2, 0,
2155 "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
2156 FUNCTION is called with two arguments--a key and a value.\n\
2157 The key is always a possible IDX argument to `aref'.")
2158 (function, char_table)
2159 Lisp_Object function, char_table;
2160 {
2161 /* The depth of char table is at most 3. */
2162 Lisp_Object indices[3];
2163
2164 CHECK_CHAR_TABLE (char_table, 1);
2165
2166 map_char_table (NULL, function, char_table, char_table, 0, indices);
2167 return Qnil;
2168 }
2169 \f
2170 /* ARGSUSED */
2171 Lisp_Object
2172 nconc2 (s1, s2)
2173 Lisp_Object s1, s2;
2174 {
2175 #ifdef NO_ARG_ARRAY
2176 Lisp_Object args[2];
2177 args[0] = s1;
2178 args[1] = s2;
2179 return Fnconc (2, args);
2180 #else
2181 return Fnconc (2, &s1);
2182 #endif /* NO_ARG_ARRAY */
2183 }
2184
2185 DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
2186 "Concatenate any number of lists by altering them.\n\
2187 Only the last argument is not altered, and need not be a list.")
2188 (nargs, args)
2189 int nargs;
2190 Lisp_Object *args;
2191 {
2192 register int argnum;
2193 register Lisp_Object tail, tem, val;
2194
2195 val = Qnil;
2196
2197 for (argnum = 0; argnum < nargs; argnum++)
2198 {
2199 tem = args[argnum];
2200 if (NILP (tem)) continue;
2201
2202 if (NILP (val))
2203 val = tem;
2204
2205 if (argnum + 1 == nargs) break;
2206
2207 if (!CONSP (tem))
2208 tem = wrong_type_argument (Qlistp, tem);
2209
2210 while (CONSP (tem))
2211 {
2212 tail = tem;
2213 tem = Fcdr (tail);
2214 QUIT;
2215 }
2216
2217 tem = args[argnum + 1];
2218 Fsetcdr (tail, tem);
2219 if (NILP (tem))
2220 args[argnum + 1] = tail;
2221 }
2222
2223 return val;
2224 }
2225 \f
2226 /* This is the guts of all mapping functions.
2227 Apply FN to each element of SEQ, one by one,
2228 storing the results into elements of VALS, a C vector of Lisp_Objects.
2229 LENI is the length of VALS, which should also be the length of SEQ. */
2230
2231 static void
2232 mapcar1 (leni, vals, fn, seq)
2233 int leni;
2234 Lisp_Object *vals;
2235 Lisp_Object fn, seq;
2236 {
2237 register Lisp_Object tail;
2238 Lisp_Object dummy;
2239 register int i;
2240 struct gcpro gcpro1, gcpro2, gcpro3;
2241
2242 /* Don't let vals contain any garbage when GC happens. */
2243 for (i = 0; i < leni; i++)
2244 vals[i] = Qnil;
2245
2246 GCPRO3 (dummy, fn, seq);
2247 gcpro1.var = vals;
2248 gcpro1.nvars = leni;
2249 /* We need not explicitly protect `tail' because it is used only on lists, and
2250 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
2251
2252 if (VECTORP (seq))
2253 {
2254 for (i = 0; i < leni; i++)
2255 {
2256 dummy = XVECTOR (seq)->contents[i];
2257 vals[i] = call1 (fn, dummy);
2258 }
2259 }
2260 else if (BOOL_VECTOR_P (seq))
2261 {
2262 for (i = 0; i < leni; i++)
2263 {
2264 int byte;
2265 byte = XBOOL_VECTOR (seq)->data[i / BITS_PER_CHAR];
2266 if (byte & (1 << (i % BITS_PER_CHAR)))
2267 dummy = Qt;
2268 else
2269 dummy = Qnil;
2270
2271 vals[i] = call1 (fn, dummy);
2272 }
2273 }
2274 else if (STRINGP (seq) && ! STRING_MULTIBYTE (seq))
2275 {
2276 /* Single-byte string. */
2277 for (i = 0; i < leni; i++)
2278 {
2279 XSETFASTINT (dummy, XSTRING (seq)->data[i]);
2280 vals[i] = call1 (fn, dummy);
2281 }
2282 }
2283 else if (STRINGP (seq))
2284 {
2285 /* Multi-byte string. */
2286 int len_byte = STRING_BYTES (XSTRING (seq));
2287 int i_byte;
2288
2289 for (i = 0, i_byte = 0; i < leni;)
2290 {
2291 int c;
2292 int i_before = i;
2293
2294 FETCH_STRING_CHAR_ADVANCE (c, seq, i, i_byte);
2295 XSETFASTINT (dummy, c);
2296 vals[i_before] = call1 (fn, dummy);
2297 }
2298 }
2299 else /* Must be a list, since Flength did not get an error */
2300 {
2301 tail = seq;
2302 for (i = 0; i < leni; i++)
2303 {
2304 vals[i] = call1 (fn, Fcar (tail));
2305 tail = XCONS (tail)->cdr;
2306 }
2307 }
2308
2309 UNGCPRO;
2310 }
2311
2312 DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
2313 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
2314 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
2315 SEPARATOR results in spaces between the values returned by FUNCTION.\n\
2316 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2317 (function, sequence, separator)
2318 Lisp_Object function, sequence, separator;
2319 {
2320 Lisp_Object len;
2321 register int leni;
2322 int nargs;
2323 register Lisp_Object *args;
2324 register int i;
2325 struct gcpro gcpro1;
2326
2327 len = Flength (sequence);
2328 leni = XINT (len);
2329 nargs = leni + leni - 1;
2330 if (nargs < 0) return build_string ("");
2331
2332 args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
2333
2334 GCPRO1 (separator);
2335 mapcar1 (leni, args, function, sequence);
2336 UNGCPRO;
2337
2338 for (i = leni - 1; i >= 0; i--)
2339 args[i + i] = args[i];
2340
2341 for (i = 1; i < nargs; i += 2)
2342 args[i] = separator;
2343
2344 return Fconcat (nargs, args);
2345 }
2346
2347 DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
2348 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
2349 The result is a list just as long as SEQUENCE.\n\
2350 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2351 (function, sequence)
2352 Lisp_Object function, sequence;
2353 {
2354 register Lisp_Object len;
2355 register int leni;
2356 register Lisp_Object *args;
2357
2358 len = Flength (sequence);
2359 leni = XFASTINT (len);
2360 args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
2361
2362 mapcar1 (leni, args, function, sequence);
2363
2364 return Flist (leni, args);
2365 }
2366 \f
2367 /* Anything that calls this function must protect from GC! */
2368
2369 DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
2370 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
2371 Takes one argument, which is the string to display to ask the question.\n\
2372 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
2373 No confirmation of the answer is requested; a single character is enough.\n\
2374 Also accepts Space to mean yes, or Delete to mean no.")
2375 (prompt)
2376 Lisp_Object prompt;
2377 {
2378 register Lisp_Object obj, key, def, answer_string, map;
2379 register int answer;
2380 Lisp_Object xprompt;
2381 Lisp_Object args[2];
2382 struct gcpro gcpro1, gcpro2;
2383 int count = specpdl_ptr - specpdl;
2384
2385 specbind (Qcursor_in_echo_area, Qt);
2386
2387 map = Fsymbol_value (intern ("query-replace-map"));
2388
2389 CHECK_STRING (prompt, 0);
2390 xprompt = prompt;
2391 GCPRO2 (prompt, xprompt);
2392
2393 while (1)
2394 {
2395
2396 #ifdef HAVE_MENUS
2397 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2398 && use_dialog_box
2399 && have_menus_p ())
2400 {
2401 Lisp_Object pane, menu;
2402 redisplay_preserve_echo_area ();
2403 pane = Fcons (Fcons (build_string ("Yes"), Qt),
2404 Fcons (Fcons (build_string ("No"), Qnil),
2405 Qnil));
2406 menu = Fcons (prompt, pane);
2407 obj = Fx_popup_dialog (Qt, menu);
2408 answer = !NILP (obj);
2409 break;
2410 }
2411 #endif /* HAVE_MENUS */
2412 cursor_in_echo_area = 1;
2413 choose_minibuf_frame ();
2414 message_with_string ("%s(y or n) ", xprompt, 0);
2415
2416 if (minibuffer_auto_raise)
2417 {
2418 Lisp_Object mini_frame;
2419
2420 mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
2421
2422 Fraise_frame (mini_frame);
2423 }
2424
2425 obj = read_filtered_event (1, 0, 0, 0);
2426 cursor_in_echo_area = 0;
2427 /* If we need to quit, quit with cursor_in_echo_area = 0. */
2428 QUIT;
2429
2430 key = Fmake_vector (make_number (1), obj);
2431 def = Flookup_key (map, key, Qt);
2432 answer_string = Fsingle_key_description (obj);
2433
2434 if (EQ (def, intern ("skip")))
2435 {
2436 answer = 0;
2437 break;
2438 }
2439 else if (EQ (def, intern ("act")))
2440 {
2441 answer = 1;
2442 break;
2443 }
2444 else if (EQ (def, intern ("recenter")))
2445 {
2446 Frecenter (Qnil);
2447 xprompt = prompt;
2448 continue;
2449 }
2450 else if (EQ (def, intern ("quit")))
2451 Vquit_flag = Qt;
2452 /* We want to exit this command for exit-prefix,
2453 and this is the only way to do it. */
2454 else if (EQ (def, intern ("exit-prefix")))
2455 Vquit_flag = Qt;
2456
2457 QUIT;
2458
2459 /* If we don't clear this, then the next call to read_char will
2460 return quit_char again, and we'll enter an infinite loop. */
2461 Vquit_flag = Qnil;
2462
2463 Fding (Qnil);
2464 Fdiscard_input ();
2465 if (EQ (xprompt, prompt))
2466 {
2467 args[0] = build_string ("Please answer y or n. ");
2468 args[1] = prompt;
2469 xprompt = Fconcat (2, args);
2470 }
2471 }
2472 UNGCPRO;
2473
2474 if (! noninteractive)
2475 {
2476 cursor_in_echo_area = -1;
2477 message_with_string (answer ? "%s(y or n) y" : "%s(y or n) n",
2478 xprompt, 0);
2479 }
2480
2481 unbind_to (count, Qnil);
2482 return answer ? Qt : Qnil;
2483 }
2484 \f
2485 /* This is how C code calls `yes-or-no-p' and allows the user
2486 to redefined it.
2487
2488 Anything that calls this function must protect from GC! */
2489
2490 Lisp_Object
2491 do_yes_or_no_p (prompt)
2492 Lisp_Object prompt;
2493 {
2494 return call1 (intern ("yes-or-no-p"), prompt);
2495 }
2496
2497 /* Anything that calls this function must protect from GC! */
2498
2499 DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
2500 "Ask user a yes-or-no question. Return t if answer is yes.\n\
2501 Takes one argument, which is the string to display to ask the question.\n\
2502 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
2503 The user must confirm the answer with RET,\n\
2504 and can edit it until it has been confirmed.")
2505 (prompt)
2506 Lisp_Object prompt;
2507 {
2508 register Lisp_Object ans;
2509 Lisp_Object args[2];
2510 struct gcpro gcpro1;
2511 Lisp_Object menu;
2512
2513 CHECK_STRING (prompt, 0);
2514
2515 #ifdef HAVE_MENUS
2516 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
2517 && use_dialog_box
2518 && have_menus_p ())
2519 {
2520 Lisp_Object pane, menu, obj;
2521 redisplay_preserve_echo_area ();
2522 pane = Fcons (Fcons (build_string ("Yes"), Qt),
2523 Fcons (Fcons (build_string ("No"), Qnil),
2524 Qnil));
2525 GCPRO1 (pane);
2526 menu = Fcons (prompt, pane);
2527 obj = Fx_popup_dialog (Qt, menu);
2528 UNGCPRO;
2529 return obj;
2530 }
2531 #endif /* HAVE_MENUS */
2532
2533 args[0] = prompt;
2534 args[1] = build_string ("(yes or no) ");
2535 prompt = Fconcat (2, args);
2536
2537 GCPRO1 (prompt);
2538
2539 while (1)
2540 {
2541 ans = Fdowncase (Fread_from_minibuffer (prompt, Qnil, Qnil, Qnil,
2542 Qyes_or_no_p_history, Qnil,
2543 Qnil));
2544 if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
2545 {
2546 UNGCPRO;
2547 return Qt;
2548 }
2549 if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
2550 {
2551 UNGCPRO;
2552 return Qnil;
2553 }
2554
2555 Fding (Qnil);
2556 Fdiscard_input ();
2557 message ("Please answer yes or no.");
2558 Fsleep_for (make_number (2), Qnil);
2559 }
2560 }
2561 \f
2562 DEFUN ("load-average", Fload_average, Sload_average, 0, 1, 0,
2563 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
2564 Each of the three load averages is multiplied by 100,\n\
2565 then converted to integer.\n\
2566 When USE-FLOATS is non-nil, floats will be used instead of integers.\n\
2567 These floats are not multiplied by 100.\n\n\
2568 If the 5-minute or 15-minute load averages are not available, return a\n\
2569 shortened list, containing only those averages which are available.")
2570 (use_floats)
2571 Lisp_Object use_floats;
2572 {
2573 double load_ave[3];
2574 int loads = getloadavg (load_ave, 3);
2575 Lisp_Object ret = Qnil;
2576
2577 if (loads < 0)
2578 error ("load-average not implemented for this operating system");
2579
2580 while (loads-- > 0)
2581 {
2582 Lisp_Object load = (NILP (use_floats) ?
2583 make_number ((int) (100.0 * load_ave[loads]))
2584 : make_float (load_ave[loads]));
2585 ret = Fcons (load, ret);
2586 }
2587
2588 return ret;
2589 }
2590 \f
2591 Lisp_Object Vfeatures;
2592
2593 DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
2594 "Returns t if FEATURE is present in this Emacs.\n\
2595 Use this to conditionalize execution of lisp code based on the presence or\n\
2596 absence of emacs or environment extensions.\n\
2597 Use `provide' to declare that a feature is available.\n\
2598 This function looks at the value of the variable `features'.")
2599 (feature)
2600 Lisp_Object feature;
2601 {
2602 register Lisp_Object tem;
2603 CHECK_SYMBOL (feature, 0);
2604 tem = Fmemq (feature, Vfeatures);
2605 return (NILP (tem)) ? Qnil : Qt;
2606 }
2607
2608 DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
2609 "Announce that FEATURE is a feature of the current Emacs.")
2610 (feature)
2611 Lisp_Object feature;
2612 {
2613 register Lisp_Object tem;
2614 CHECK_SYMBOL (feature, 0);
2615 if (!NILP (Vautoload_queue))
2616 Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
2617 tem = Fmemq (feature, Vfeatures);
2618 if (NILP (tem))
2619 Vfeatures = Fcons (feature, Vfeatures);
2620 LOADHIST_ATTACH (Fcons (Qprovide, feature));
2621 return feature;
2622 }
2623
2624 DEFUN ("require", Frequire, Srequire, 1, 3, 0,
2625 "If feature FEATURE is not loaded, load it from FILENAME.\n\
2626 If FEATURE is not a member of the list `features', then the feature\n\
2627 is not loaded; so load the file FILENAME.\n\
2628 If FILENAME is omitted, the printname of FEATURE is used as the file name,\n\
2629 but in this case `load' insists on adding the suffix `.el' or `.elc'.\n\
2630 If the optional third argument NOERROR is non-nil,\n\
2631 then return nil if the file is not found.\n\
2632 Normally the return value is FEATURE.")
2633 (feature, file_name, noerror)
2634 Lisp_Object feature, file_name, noerror;
2635 {
2636 register Lisp_Object tem;
2637 CHECK_SYMBOL (feature, 0);
2638 tem = Fmemq (feature, Vfeatures);
2639 LOADHIST_ATTACH (Fcons (Qrequire, feature));
2640 if (NILP (tem))
2641 {
2642 int count = specpdl_ptr - specpdl;
2643
2644 /* Value saved here is to be restored into Vautoload_queue */
2645 record_unwind_protect (un_autoload, Vautoload_queue);
2646 Vautoload_queue = Qt;
2647
2648 tem = Fload (NILP (file_name) ? Fsymbol_name (feature) : file_name,
2649 noerror, Qt, Qnil, (NILP (file_name) ? Qt : Qnil));
2650 /* If load failed entirely, return nil. */
2651 if (NILP (tem))
2652 return Qnil;
2653
2654 tem = Fmemq (feature, Vfeatures);
2655 if (NILP (tem))
2656 error ("Required feature %s was not provided",
2657 XSYMBOL (feature)->name->data);
2658
2659 /* Once loading finishes, don't undo it. */
2660 Vautoload_queue = Qt;
2661 feature = unbind_to (count, feature);
2662 }
2663 return feature;
2664 }
2665 \f
2666 /* Primitives for work of the "widget" library.
2667 In an ideal world, this section would not have been necessary.
2668 However, lisp function calls being as slow as they are, it turns
2669 out that some functions in the widget library (wid-edit.el) are the
2670 bottleneck of Widget operation. Here is their translation to C,
2671 for the sole reason of efficiency. */
2672
2673 DEFUN ("widget-plist-member", Fwidget_plist_member, Swidget_plist_member, 2, 2, 0,
2674 "Return non-nil if PLIST has the property PROP.\n\
2675 PLIST is a property list, which is a list of the form\n\
2676 \(PROP1 VALUE1 PROP2 VALUE2 ...\). PROP is a symbol.\n\
2677 Unlike `plist-get', this allows you to distinguish between a missing\n\
2678 property and a property with the value nil.\n\
2679 The value is actually the tail of PLIST whose car is PROP.")
2680 (plist, prop)
2681 Lisp_Object plist, prop;
2682 {
2683 while (CONSP (plist) && !EQ (XCAR (plist), prop))
2684 {
2685 QUIT;
2686 plist = XCDR (plist);
2687 plist = CDR (plist);
2688 }
2689 return plist;
2690 }
2691
2692 DEFUN ("widget-put", Fwidget_put, Swidget_put, 3, 3, 0,
2693 "In WIDGET, set PROPERTY to VALUE.\n\
2694 The value can later be retrieved with `widget-get'.")
2695 (widget, property, value)
2696 Lisp_Object widget, property, value;
2697 {
2698 CHECK_CONS (widget, 1);
2699 XCDR (widget) = Fplist_put (XCDR (widget), property, value);
2700 return value;
2701 }
2702
2703 DEFUN ("widget-get", Fwidget_get, Swidget_get, 2, 2, 0,
2704 "In WIDGET, get the value of PROPERTY.\n\
2705 The value could either be specified when the widget was created, or\n\
2706 later with `widget-put'.")
2707 (widget, property)
2708 Lisp_Object widget, property;
2709 {
2710 Lisp_Object tmp;
2711
2712 while (1)
2713 {
2714 if (NILP (widget))
2715 return Qnil;
2716 CHECK_CONS (widget, 1);
2717 tmp = Fwidget_plist_member (XCDR (widget), property);
2718 if (CONSP (tmp))
2719 {
2720 tmp = XCDR (tmp);
2721 return CAR (tmp);
2722 }
2723 tmp = XCAR (widget);
2724 if (NILP (tmp))
2725 return Qnil;
2726 widget = Fget (tmp, Qwidget_type);
2727 }
2728 }
2729
2730 DEFUN ("widget-apply", Fwidget_apply, Swidget_apply, 2, MANY, 0,
2731 "Apply the value of WIDGET's PROPERTY to the widget itself.\n\
2732 ARGS are passed as extra arguments to the function.")
2733 (nargs, args)
2734 int nargs;
2735 Lisp_Object *args;
2736 {
2737 /* This function can GC. */
2738 Lisp_Object newargs[3];
2739 struct gcpro gcpro1, gcpro2;
2740 Lisp_Object result;
2741
2742 newargs[0] = Fwidget_get (args[0], args[1]);
2743 newargs[1] = args[0];
2744 newargs[2] = Flist (nargs - 2, args + 2);
2745 GCPRO2 (newargs[0], newargs[2]);
2746 result = Fapply (3, newargs);
2747 UNGCPRO;
2748 return result;
2749 }
2750 \f
2751 /* base64 encode/decode functions.
2752 Based on code from GNU recode. */
2753
2754 #define MIME_LINE_LENGTH 76
2755
2756 #define IS_ASCII(Character) \
2757 ((Character) < 128)
2758 #define IS_BASE64(Character) \
2759 (IS_ASCII (Character) && base64_char_to_value[Character] >= 0)
2760
2761 /* Don't use alloca for regions larger than this, lest we overflow
2762 their stack. */
2763 #define MAX_ALLOCA 16*1024
2764
2765 /* Table of characters coding the 64 values. */
2766 static char base64_value_to_char[64] =
2767 {
2768 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', /* 0- 9 */
2769 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', /* 10-19 */
2770 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', /* 20-29 */
2771 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', /* 30-39 */
2772 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', /* 40-49 */
2773 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', /* 50-59 */
2774 '8', '9', '+', '/' /* 60-63 */
2775 };
2776
2777 /* Table of base64 values for first 128 characters. */
2778 static short base64_char_to_value[128] =
2779 {
2780 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0- 9 */
2781 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10- 19 */
2782 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 20- 29 */
2783 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 30- 39 */
2784 -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, /* 40- 49 */
2785 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, /* 50- 59 */
2786 -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, /* 60- 69 */
2787 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 70- 79 */
2788 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /* 80- 89 */
2789 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, /* 90- 99 */
2790 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, /* 100-109 */
2791 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, /* 110-119 */
2792 49, 50, 51, -1, -1, -1, -1, -1 /* 120-127 */
2793 };
2794
2795 /* The following diagram shows the logical steps by which three octets
2796 get transformed into four base64 characters.
2797
2798 .--------. .--------. .--------.
2799 |aaaaaabb| |bbbbcccc| |ccdddddd|
2800 `--------' `--------' `--------'
2801 6 2 4 4 2 6
2802 .--------+--------+--------+--------.
2803 |00aaaaaa|00bbbbbb|00cccccc|00dddddd|
2804 `--------+--------+--------+--------'
2805
2806 .--------+--------+--------+--------.
2807 |AAAAAAAA|BBBBBBBB|CCCCCCCC|DDDDDDDD|
2808 `--------+--------+--------+--------'
2809
2810 The octets are divided into 6 bit chunks, which are then encoded into
2811 base64 characters. */
2812
2813
2814 static int base64_encode_1 P_ ((const char *, char *, int, int));
2815 static int base64_decode_1 P_ ((const char *, char *, int));
2816
2817 DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region,
2818 2, 3, "r",
2819 "Base64-encode the region between BEG and END.\n\
2820 Return the length of the encoded text.\n\
2821 Optional third argument NO-LINE-BREAK means do not break long lines\n\
2822 into shorter lines.")
2823 (beg, end, no_line_break)
2824 Lisp_Object beg, end, no_line_break;
2825 {
2826 char *encoded;
2827 int allength, length;
2828 int ibeg, iend, encoded_length;
2829 int old_pos = PT;
2830
2831 validate_region (&beg, &end);
2832
2833 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
2834 iend = CHAR_TO_BYTE (XFASTINT (end));
2835 move_gap_both (XFASTINT (beg), ibeg);
2836
2837 /* We need to allocate enough room for encoding the text.
2838 We need 33 1/3% more space, plus a newline every 76
2839 characters, and then we round up. */
2840 length = iend - ibeg;
2841 allength = length + length/3 + 1;
2842 allength += allength / MIME_LINE_LENGTH + 1 + 6;
2843
2844 if (allength <= MAX_ALLOCA)
2845 encoded = (char *) alloca (allength);
2846 else
2847 encoded = (char *) xmalloc (allength);
2848 encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length,
2849 NILP (no_line_break));
2850 if (encoded_length > allength)
2851 abort ();
2852
2853 /* Now we have encoded the region, so we insert the new contents
2854 and delete the old. (Insert first in order to preserve markers.) */
2855 SET_PT_BOTH (XFASTINT (beg), ibeg);
2856 insert (encoded, encoded_length);
2857 if (allength > MAX_ALLOCA)
2858 free (encoded);
2859 del_range_byte (ibeg + encoded_length, iend + encoded_length, 1);
2860
2861 /* If point was outside of the region, restore it exactly; else just
2862 move to the beginning of the region. */
2863 if (old_pos >= XFASTINT (end))
2864 old_pos += encoded_length - (XFASTINT (end) - XFASTINT (beg));
2865 else if (old_pos > XFASTINT (beg))
2866 old_pos = XFASTINT (beg);
2867 SET_PT (old_pos);
2868
2869 /* We return the length of the encoded text. */
2870 return make_number (encoded_length);
2871 }
2872
2873 DEFUN ("base64-encode-string", Fbase64_encode_string, Sbase64_encode_string,
2874 1, 1, 0,
2875 "Base64-encode STRING and return the result.")
2876 (string)
2877 Lisp_Object string;
2878 {
2879 int allength, length, encoded_length;
2880 char *encoded;
2881 Lisp_Object encoded_string;
2882
2883 CHECK_STRING (string, 1);
2884
2885 length = STRING_BYTES (XSTRING (string));
2886 allength = length + length/3 + 1 + 6;
2887
2888 /* We need to allocate enough room for decoding the text. */
2889 if (allength <= MAX_ALLOCA)
2890 encoded = (char *) alloca (allength);
2891 else
2892 encoded = (char *) xmalloc (allength);
2893
2894 encoded_length = base64_encode_1 (XSTRING (string)->data,
2895 encoded, length, 0);
2896 if (encoded_length > allength)
2897 abort ();
2898
2899 encoded_string = make_unibyte_string (encoded, encoded_length);
2900 if (allength > MAX_ALLOCA)
2901 free (encoded);
2902
2903 return encoded_string;
2904 }
2905
2906 static int
2907 base64_encode_1 (from, to, length, line_break)
2908 const char *from;
2909 char *to;
2910 int length;
2911 int line_break;
2912 {
2913 int counter = 0, i = 0;
2914 char *e = to;
2915 unsigned char c;
2916 unsigned int value;
2917
2918 while (i < length)
2919 {
2920 c = from[i++];
2921
2922 /* Wrap line every 76 characters. */
2923
2924 if (line_break)
2925 {
2926 if (counter < MIME_LINE_LENGTH / 4)
2927 counter++;
2928 else
2929 {
2930 *e++ = '\n';
2931 counter = 1;
2932 }
2933 }
2934
2935 /* Process first byte of a triplet. */
2936
2937 *e++ = base64_value_to_char[0x3f & c >> 2];
2938 value = (0x03 & c) << 4;
2939
2940 /* Process second byte of a triplet. */
2941
2942 if (i == length)
2943 {
2944 *e++ = base64_value_to_char[value];
2945 *e++ = '=';
2946 *e++ = '=';
2947 break;
2948 }
2949
2950 c = from[i++];
2951
2952 *e++ = base64_value_to_char[value | (0x0f & c >> 4)];
2953 value = (0x0f & c) << 2;
2954
2955 /* Process third byte of a triplet. */
2956
2957 if (i == length)
2958 {
2959 *e++ = base64_value_to_char[value];
2960 *e++ = '=';
2961 break;
2962 }
2963
2964 c = from[i++];
2965
2966 *e++ = base64_value_to_char[value | (0x03 & c >> 6)];
2967 *e++ = base64_value_to_char[0x3f & c];
2968 }
2969
2970 /* Complete last partial line. */
2971
2972 if (line_break)
2973 if (counter > 0)
2974 *e++ = '\n';
2975
2976 return e - to;
2977 }
2978
2979
2980 DEFUN ("base64-decode-region", Fbase64_decode_region, Sbase64_decode_region,
2981 2, 2, "r",
2982 "Base64-decode the region between BEG and END.\n\
2983 Return the length of the decoded text.\n\
2984 If the region can't be decoded, return nil and don't modify the buffer.")
2985 (beg, end)
2986 Lisp_Object beg, end;
2987 {
2988 int ibeg, iend, length;
2989 char *decoded;
2990 int old_pos = PT;
2991 int decoded_length;
2992 int inserted_chars;
2993
2994 validate_region (&beg, &end);
2995
2996 ibeg = CHAR_TO_BYTE (XFASTINT (beg));
2997 iend = CHAR_TO_BYTE (XFASTINT (end));
2998
2999 length = iend - ibeg;
3000 /* We need to allocate enough room for decoding the text. */
3001 if (length <= MAX_ALLOCA)
3002 decoded = (char *) alloca (length);
3003 else
3004 decoded = (char *) xmalloc (length);
3005
3006 move_gap_both (XFASTINT (beg), ibeg);
3007 decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length);
3008 if (decoded_length > length)
3009 abort ();
3010
3011 if (decoded_length < 0)
3012 /* The decoding wasn't possible. */
3013 return Qnil;
3014
3015 /* Now we have decoded the region, so we insert the new contents
3016 and delete the old. (Insert first in order to preserve markers.) */
3017 /* We insert two spaces, then insert the decoded text in between
3018 them, at last, delete those extra two spaces. This is to avoid
3019 byte combining while inserting. */
3020 TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg);
3021 insert_1_both (" ", 2, 2, 0, 1, 0);
3022 TEMP_SET_PT_BOTH (XFASTINT (beg) + 1, ibeg + 1);
3023 insert (decoded, decoded_length);
3024 inserted_chars = PT - (XFASTINT (beg) + 1);
3025 if (length > MAX_ALLOCA)
3026 free (decoded);
3027 /* At first delete the original text. This never cause byte
3028 combining. */
3029 del_range_both (PT + 1, PT_BYTE + 1, XFASTINT (end) + inserted_chars + 2,
3030 iend + decoded_length + 2, 1);
3031 /* Next delete the extra spaces. This will cause byte combining
3032 error. */
3033 del_range_both (PT, PT_BYTE, PT + 1, PT_BYTE + 1, 0);
3034 del_range_both (XFASTINT (beg), ibeg, XFASTINT (beg) + 1, ibeg + 1, 0);
3035 inserted_chars = PT - XFASTINT (beg);
3036
3037 /* If point was outside of the region, restore it exactly; else just
3038 move to the beginning of the region. */
3039 if (old_pos >= XFASTINT (end))
3040 old_pos += inserted_chars - (XFASTINT (end) - XFASTINT (beg));
3041 else if (old_pos > XFASTINT (beg))
3042 old_pos = XFASTINT (beg);
3043 SET_PT (old_pos);
3044
3045 return make_number (inserted_chars);
3046 }
3047
3048 DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3049 1, 1, 0,
3050 "Base64-decode STRING and return the result.")
3051 (string)
3052 Lisp_Object string;
3053 {
3054 char *decoded;
3055 int length, decoded_length;
3056 Lisp_Object decoded_string;
3057
3058 CHECK_STRING (string, 1);
3059
3060 length = STRING_BYTES (XSTRING (string));
3061 /* We need to allocate enough room for decoding the text. */
3062 if (length <= MAX_ALLOCA)
3063 decoded = (char *) alloca (length);
3064 else
3065 decoded = (char *) xmalloc (length);
3066
3067 decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length);
3068 if (decoded_length > length)
3069 abort ();
3070
3071 if (decoded_length < 0)
3072 return Qnil;
3073
3074 decoded_string = make_string (decoded, decoded_length);
3075 if (length > MAX_ALLOCA)
3076 free (decoded);
3077
3078 return decoded_string;
3079 }
3080
3081 static int
3082 base64_decode_1 (from, to, length)
3083 const char *from;
3084 char *to;
3085 int length;
3086 {
3087 int counter = 0, i = 0;
3088 char *e = to;
3089 unsigned char c;
3090 unsigned long value;
3091
3092 while (i < length)
3093 {
3094 /* Accept wrapping lines, reversibly if at each 76 characters. */
3095
3096 c = from[i++];
3097 if (c == '\n')
3098 {
3099 if (i == length)
3100 break;
3101 c = from[i++];
3102 if (i == length)
3103 break;
3104 if (counter != MIME_LINE_LENGTH / 4)
3105 return -1;
3106 counter = 1;
3107 }
3108 else
3109 counter++;
3110
3111 /* Process first byte of a quadruplet. */
3112
3113 if (!IS_BASE64 (c))
3114 return -1;
3115 value = base64_char_to_value[c] << 18;
3116
3117 /* Process second byte of a quadruplet. */
3118
3119 if (i == length)
3120 return -1;
3121 c = from[i++];
3122
3123 if (!IS_BASE64 (c))
3124 return -1;
3125 value |= base64_char_to_value[c] << 12;
3126
3127 *e++ = (unsigned char) (value >> 16);
3128
3129 /* Process third byte of a quadruplet. */
3130
3131 if (i == length)
3132 return -1;
3133 c = from[i++];
3134
3135 if (c == '=')
3136 {
3137 c = from[i++];
3138 if (c != '=')
3139 return -1;
3140 continue;
3141 }
3142
3143 if (!IS_BASE64 (c))
3144 return -1;
3145 value |= base64_char_to_value[c] << 6;
3146
3147 *e++ = (unsigned char) (0xff & value >> 8);
3148
3149 /* Process fourth byte of a quadruplet. */
3150
3151 if (i == length)
3152 return -1;
3153 c = from[i++];
3154
3155 if (c == '=')
3156 continue;
3157
3158 if (!IS_BASE64 (c))
3159 return -1;
3160 value |= base64_char_to_value[c];
3161
3162 *e++ = (unsigned char) (0xff & value);
3163 }
3164
3165 return e - to;
3166 }
3167 \f
3168 void
3169 syms_of_fns ()
3170 {
3171 Qstring_lessp = intern ("string-lessp");
3172 staticpro (&Qstring_lessp);
3173 Qprovide = intern ("provide");
3174 staticpro (&Qprovide);
3175 Qrequire = intern ("require");
3176 staticpro (&Qrequire);
3177 Qyes_or_no_p_history = intern ("yes-or-no-p-history");
3178 staticpro (&Qyes_or_no_p_history);
3179 Qcursor_in_echo_area = intern ("cursor-in-echo-area");
3180 staticpro (&Qcursor_in_echo_area);
3181 Qwidget_type = intern ("widget-type");
3182 staticpro (&Qwidget_type);
3183
3184 staticpro (&string_char_byte_cache_string);
3185 string_char_byte_cache_string = Qnil;
3186
3187 Fset (Qyes_or_no_p_history, Qnil);
3188
3189 DEFVAR_LISP ("features", &Vfeatures,
3190 "A list of symbols which are the features of the executing emacs.\n\
3191 Used by `featurep' and `require', and altered by `provide'.");
3192 Vfeatures = Qnil;
3193
3194 DEFVAR_BOOL ("use-dialog-box", &use_dialog_box,
3195 "*Non-nil means mouse commands use dialog boxes to ask questions.\n\
3196 This applies to y-or-n and yes-or-no questions asked by commands\n\
3197 invoked by mouse clicks and mouse menu items.");
3198 use_dialog_box = 1;
3199
3200 defsubr (&Sidentity);
3201 defsubr (&Srandom);
3202 defsubr (&Slength);
3203 defsubr (&Ssafe_length);
3204 defsubr (&Sstring_bytes);
3205 defsubr (&Sstring_equal);
3206 defsubr (&Scompare_strings);
3207 defsubr (&Sstring_lessp);
3208 defsubr (&Sappend);
3209 defsubr (&Sconcat);
3210 defsubr (&Svconcat);
3211 defsubr (&Scopy_sequence);
3212 defsubr (&Sstring_make_multibyte);
3213 defsubr (&Sstring_make_unibyte);
3214 defsubr (&Sstring_as_multibyte);
3215 defsubr (&Sstring_as_unibyte);
3216 defsubr (&Scopy_alist);
3217 defsubr (&Ssubstring);
3218 defsubr (&Snthcdr);
3219 defsubr (&Snth);
3220 defsubr (&Selt);
3221 defsubr (&Smember);
3222 defsubr (&Smemq);
3223 defsubr (&Sassq);
3224 defsubr (&Sassoc);
3225 defsubr (&Srassq);
3226 defsubr (&Srassoc);
3227 defsubr (&Sdelq);
3228 defsubr (&Sdelete);
3229 defsubr (&Snreverse);
3230 defsubr (&Sreverse);
3231 defsubr (&Ssort);
3232 defsubr (&Splist_get);
3233 defsubr (&Sget);
3234 defsubr (&Splist_put);
3235 defsubr (&Sput);
3236 defsubr (&Sequal);
3237 defsubr (&Sfillarray);
3238 defsubr (&Schar_table_subtype);
3239 defsubr (&Schar_table_parent);
3240 defsubr (&Sset_char_table_parent);
3241 defsubr (&Schar_table_extra_slot);
3242 defsubr (&Sset_char_table_extra_slot);
3243 defsubr (&Schar_table_range);
3244 defsubr (&Sset_char_table_range);
3245 defsubr (&Sset_char_table_default);
3246 defsubr (&Smap_char_table);
3247 defsubr (&Snconc);
3248 defsubr (&Smapcar);
3249 defsubr (&Smapconcat);
3250 defsubr (&Sy_or_n_p);
3251 defsubr (&Syes_or_no_p);
3252 defsubr (&Sload_average);
3253 defsubr (&Sfeaturep);
3254 defsubr (&Srequire);
3255 defsubr (&Sprovide);
3256 defsubr (&Swidget_plist_member);
3257 defsubr (&Swidget_put);
3258 defsubr (&Swidget_get);
3259 defsubr (&Swidget_apply);
3260 defsubr (&Sbase64_encode_region);
3261 defsubr (&Sbase64_decode_region);
3262 defsubr (&Sbase64_encode_string);
3263 defsubr (&Sbase64_decode_string);
3264 }