1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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)
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.
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. */
24 /* Note on some machines this defines `vector' as a typedef,
25 so make sure we don't use that name in this file. */
35 #include "intervals.h"
40 #define NULL (void *)0
43 /* Nonzero enables use of dialog boxes for questions
44 asked by mouse commands. */
47 extern Lisp_Object
Flookup_key ();
49 extern int minibuffer_auto_raise
;
50 extern Lisp_Object minibuf_window
;
52 Lisp_Object Qstring_lessp
, Qprovide
, Qrequire
;
53 Lisp_Object Qyes_or_no_p_history
;
54 Lisp_Object Qcursor_in_echo_area
;
55 Lisp_Object Qwidget_type
;
57 static int internal_equal ();
59 DEFUN ("identity", Fidentity
, Sidentity
, 1, 1, 0,
60 "Return the argument unchanged.")
67 extern long get_random ();
68 extern void seed_random ();
71 DEFUN ("random", Frandom
, Srandom
, 0, 1, 0,
72 "Return a pseudo-random number.\n\
73 All integers representable in Lisp are equally likely.\n\
74 On most systems, this is 28 bits' worth.\n\
75 With positive integer argument N, return random number in interval [0,N).\n\
76 With argument t, set the random number seed from the current time and pid.")
81 Lisp_Object lispy_val
;
82 unsigned long denominator
;
85 seed_random (getpid () + time (NULL
));
86 if (NATNUMP (n
) && XFASTINT (n
) != 0)
88 /* Try to take our random number from the higher bits of VAL,
89 not the lower, since (says Gentzel) the low bits of `random'
90 are less random than the higher ones. We do this by using the
91 quotient rather than the remainder. At the high end of the RNG
92 it's possible to get a quotient larger than n; discarding
93 these values eliminates the bias that would otherwise appear
94 when using a large n. */
95 denominator
= ((unsigned long)1 << VALBITS
) / XFASTINT (n
);
97 val
= get_random () / denominator
;
98 while (val
>= XFASTINT (n
));
102 XSETINT (lispy_val
, val
);
106 /* Random data-structure functions */
108 DEFUN ("length", Flength
, Slength
, 1, 1, 0,
109 "Return the length of vector, list or string SEQUENCE.\n\
110 A byte-code function object is also allowed.\n\
111 If the string contains multibyte characters, this is not the necessarily\n\
112 the number of characters in the string; it is the number of bytes.\n\
113 To get the number of characters, use `chars-in-string'")
115 register Lisp_Object sequence
;
117 register Lisp_Object tail
, val
;
121 if (STRINGP (sequence
))
122 XSETFASTINT (val
, XSTRING (sequence
)->size
);
123 else if (VECTORP (sequence
))
124 XSETFASTINT (val
, XVECTOR (sequence
)->size
);
125 else if (CHAR_TABLE_P (sequence
))
126 XSETFASTINT (val
, (MIN_CHAR_COMPOSITION
127 + (CHAR_FIELD2_MASK
| CHAR_FIELD3_MASK
)
129 else if (BOOL_VECTOR_P (sequence
))
130 XSETFASTINT (val
, XBOOL_VECTOR (sequence
)->size
);
131 else if (COMPILEDP (sequence
))
132 XSETFASTINT (val
, XVECTOR (sequence
)->size
& PSEUDOVECTOR_SIZE_MASK
);
133 else if (CONSP (sequence
))
135 for (i
= 0, tail
= sequence
; !NILP (tail
); i
++)
141 XSETFASTINT (val
, i
);
143 else if (NILP (sequence
))
144 XSETFASTINT (val
, 0);
147 sequence
= wrong_type_argument (Qsequencep
, sequence
);
153 /* This does not check for quits. That is safe
154 since it must terminate. */
156 DEFUN ("safe-length", Fsafe_length
, Ssafe_length
, 1, 1, 0,
157 "Return the length of a list, but avoid error or infinite loop.\n\
158 This function never gets an error. If LIST is not really a list,\n\
159 it returns 0. If LIST is circular, it returns a finite value\n\
160 which is at least the number of distinct elements.")
164 Lisp_Object tail
, halftail
, length
;
167 /* halftail is used to detect circular lists. */
169 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
171 if (EQ (tail
, halftail
) && len
!= 0)
175 halftail
= XCONS (halftail
)->cdr
;
178 XSETINT (length
, len
);
182 DEFUN ("string-bytes", Fstring_bytes
, Sstring_bytes
, 1, 1, 0,
183 "Return the number of bytes in STRING.\n\
184 If STRING is a multibyte string, this is greater than the length of STRING.")
188 CHECK_STRING (string
, 1);
189 return make_number (STRING_BYTES (XSTRING (string
)));
192 DEFUN ("string-equal", Fstring_equal
, Sstring_equal
, 2, 2, 0,
193 "Return t if two strings have identical contents.\n\
194 Case is significant, but text properties are ignored.\n\
195 Symbols are also allowed; their print names are used instead.")
197 register Lisp_Object s1
, s2
;
200 XSETSTRING (s1
, XSYMBOL (s1
)->name
);
202 XSETSTRING (s2
, XSYMBOL (s2
)->name
);
203 CHECK_STRING (s1
, 0);
204 CHECK_STRING (s2
, 1);
206 if (XSTRING (s1
)->size
!= XSTRING (s2
)->size
207 || STRING_BYTES (XSTRING (s1
)) != STRING_BYTES (XSTRING (s2
))
208 || bcmp (XSTRING (s1
)->data
, XSTRING (s2
)->data
, STRING_BYTES (XSTRING (s1
))))
213 DEFUN ("string-lessp", Fstring_lessp
, Sstring_lessp
, 2, 2, 0,
214 "Return t if first arg string is less than second in lexicographic order.\n\
215 Case is significant.\n\
216 Symbols are also allowed; their print names are used instead.")
218 register Lisp_Object s1
, s2
;
221 register int i1
, i1_byte
, i2
, i2_byte
;
224 XSETSTRING (s1
, XSYMBOL (s1
)->name
);
226 XSETSTRING (s2
, XSYMBOL (s2
)->name
);
227 CHECK_STRING (s1
, 0);
228 CHECK_STRING (s2
, 1);
230 i1
= i1_byte
= i2
= i2_byte
= 0;
232 end
= XSTRING (s1
)->size
;
233 if (end
> XSTRING (s2
)->size
)
234 end
= XSTRING (s2
)->size
;
238 /* When we find a mismatch, we must compare the
239 characters, not just the bytes. */
242 if (STRING_MULTIBYTE (s1
))
243 FETCH_STRING_CHAR_ADVANCE (c1
, s1
, i1
, i1_byte
);
245 c1
= XSTRING (s1
)->data
[i1
++];
247 if (STRING_MULTIBYTE (s2
))
248 FETCH_STRING_CHAR_ADVANCE (c2
, s2
, i2
, i2_byte
);
250 c2
= XSTRING (s2
)->data
[i2
++];
253 return c1
< c2
? Qt
: Qnil
;
255 return i1
< XSTRING (s2
)->size
? Qt
: Qnil
;
258 static Lisp_Object
concat ();
269 return concat (2, args
, Lisp_String
, 0);
271 return concat (2, &s1
, Lisp_String
, 0);
272 #endif /* NO_ARG_ARRAY */
278 Lisp_Object s1
, s2
, s3
;
285 return concat (3, args
, Lisp_String
, 0);
287 return concat (3, &s1
, Lisp_String
, 0);
288 #endif /* NO_ARG_ARRAY */
291 DEFUN ("append", Fappend
, Sappend
, 0, MANY
, 0,
292 "Concatenate all the arguments and make the result a list.\n\
293 The result is a list whose elements are the elements of all the arguments.\n\
294 Each argument may be a list, vector or string.\n\
295 The last argument is not copied, just used as the tail of the new list.")
300 return concat (nargs
, args
, Lisp_Cons
, 1);
303 DEFUN ("concat", Fconcat
, Sconcat
, 0, MANY
, 0,
304 "Concatenate all the arguments and make the result a string.\n\
305 The result is a string whose elements are the elements of all the arguments.\n\
306 Each argument may be a string or a list or vector of characters (integers).\n\
308 Do not use individual integers as arguments!\n\
309 The behavior of `concat' in that case will be changed later!\n\
310 If your program passes an integer as an argument to `concat',\n\
311 you should change it right away not to do so.")
316 return concat (nargs
, args
, Lisp_String
, 0);
319 DEFUN ("vconcat", Fvconcat
, Svconcat
, 0, MANY
, 0,
320 "Concatenate all the arguments and make the result a vector.\n\
321 The result is a vector whose elements are the elements of all the arguments.\n\
322 Each argument may be a list, vector or string.")
327 return concat (nargs
, args
, Lisp_Vectorlike
, 0);
330 /* Retrun a copy of a sub char table ARG. The elements except for a
331 nested sub char table are not copied. */
333 copy_sub_char_table (arg
)
336 Lisp_Object copy
= make_sub_char_table (XCHAR_TABLE (arg
)->defalt
);
339 /* Copy all the contents. */
340 bcopy (XCHAR_TABLE (arg
)->contents
, XCHAR_TABLE (copy
)->contents
,
341 SUB_CHAR_TABLE_ORDINARY_SLOTS
* sizeof (Lisp_Object
));
342 /* Recursively copy any sub char-tables in the ordinary slots. */
343 for (i
= 32; i
< SUB_CHAR_TABLE_ORDINARY_SLOTS
; i
++)
344 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg
)->contents
[i
]))
345 XCHAR_TABLE (copy
)->contents
[i
]
346 = copy_sub_char_table (XCHAR_TABLE (copy
)->contents
[i
]);
352 DEFUN ("copy-sequence", Fcopy_sequence
, Scopy_sequence
, 1, 1, 0,
353 "Return a copy of a list, vector or string.\n\
354 The elements of a list or vector are not copied; they are shared\n\
359 if (NILP (arg
)) return arg
;
361 if (CHAR_TABLE_P (arg
))
366 copy
= Fmake_char_table (XCHAR_TABLE (arg
)->purpose
, Qnil
);
367 /* Copy all the slots, including the extra ones. */
368 bcopy (XVECTOR (arg
)->contents
, XVECTOR (copy
)->contents
,
369 ((XCHAR_TABLE (arg
)->size
& PSEUDOVECTOR_SIZE_MASK
)
370 * sizeof (Lisp_Object
)));
372 /* Recursively copy any sub char tables in the ordinary slots
373 for multibyte characters. */
374 for (i
= CHAR_TABLE_SINGLE_BYTE_SLOTS
;
375 i
< CHAR_TABLE_ORDINARY_SLOTS
; i
++)
376 if (SUB_CHAR_TABLE_P (XCHAR_TABLE (arg
)->contents
[i
]))
377 XCHAR_TABLE (copy
)->contents
[i
]
378 = copy_sub_char_table (XCHAR_TABLE (copy
)->contents
[i
]);
383 if (BOOL_VECTOR_P (arg
))
387 = (XBOOL_VECTOR (arg
)->size
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
389 val
= Fmake_bool_vector (Flength (arg
), Qnil
);
390 bcopy (XBOOL_VECTOR (arg
)->data
, XBOOL_VECTOR (val
)->data
,
395 if (!CONSP (arg
) && !VECTORP (arg
) && !STRINGP (arg
))
396 arg
= wrong_type_argument (Qsequencep
, arg
);
397 return concat (1, &arg
, CONSP (arg
) ? Lisp_Cons
: XTYPE (arg
), 0);
401 concat (nargs
, args
, target_type
, last_special
)
404 enum Lisp_Type target_type
;
408 register Lisp_Object tail
;
409 register Lisp_Object
this;
412 register int result_len
;
413 register int result_len_byte
;
415 Lisp_Object last_tail
;
419 /* In append, the last arg isn't treated like the others */
420 if (last_special
&& nargs
> 0)
423 last_tail
= args
[nargs
];
428 /* Canonicalize each argument. */
429 for (argnum
= 0; argnum
< nargs
; argnum
++)
432 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
433 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
436 args
[argnum
] = Fnumber_to_string (this);
438 args
[argnum
] = wrong_type_argument (Qsequencep
, this);
442 /* Compute total length in chars of arguments in RESULT_LEN.
443 If desired output is a string, also compute length in bytes
444 in RESULT_LEN_BYTE, and determine in SOME_MULTIBYTE
445 whether the result should be a multibyte string. */
449 for (argnum
= 0; argnum
< nargs
; argnum
++)
453 len
= XFASTINT (Flength (this));
454 if (target_type
== Lisp_String
)
456 /* We must count the number of bytes needed in the string
457 as well as the number of characters. */
463 for (i
= 0; i
< len
; i
++)
465 ch
= XVECTOR (this)->contents
[i
];
467 wrong_type_argument (Qintegerp
, ch
);
468 this_len_byte
= XFASTINT (Fchar_bytes (ch
));
469 result_len_byte
+= this_len_byte
;
470 if (this_len_byte
> 1)
473 else if (BOOL_VECTOR_P (this) && XBOOL_VECTOR (this)->size
> 0)
474 wrong_type_argument (Qintegerp
, Faref (this, make_number (0)));
475 else if (CONSP (this))
476 for (; CONSP (this); this = XCONS (this)->cdr
)
478 ch
= XCONS (this)->car
;
480 wrong_type_argument (Qintegerp
, ch
);
481 this_len_byte
= XFASTINT (Fchar_bytes (ch
));
482 result_len_byte
+= this_len_byte
;
483 if (this_len_byte
> 1)
486 else if (STRINGP (this))
488 if (STRING_MULTIBYTE (this))
491 result_len_byte
+= STRING_BYTES (XSTRING (this));
494 result_len_byte
+= count_size_as_multibyte (XSTRING (this)->data
,
495 XSTRING (this)->size
);
502 if (! some_multibyte
)
503 result_len_byte
= result_len
;
505 /* Create the output object. */
506 if (target_type
== Lisp_Cons
)
507 val
= Fmake_list (make_number (result_len
), Qnil
);
508 else if (target_type
== Lisp_Vectorlike
)
509 val
= Fmake_vector (make_number (result_len
), Qnil
);
511 val
= make_uninit_multibyte_string (result_len
, result_len_byte
);
513 /* In `append', if all but last arg are nil, return last arg. */
514 if (target_type
== Lisp_Cons
&& EQ (val
, Qnil
))
517 /* Copy the contents of the args into the result. */
519 tail
= val
, toindex
= -1; /* -1 in toindex is flag we are making a list */
521 toindex
= 0, toindex_byte
= 0;
525 for (argnum
= 0; argnum
< nargs
; argnum
++)
529 register unsigned int thisindex
= 0;
530 register unsigned int thisindex_byte
= 0;
534 thislen
= Flength (this), thisleni
= XINT (thislen
);
536 if (STRINGP (this) && STRINGP (val
)
537 && ! NULL_INTERVAL_P (XSTRING (this)->intervals
))
538 copy_text_properties (make_number (0), thislen
, this,
539 make_number (toindex
), val
, Qnil
);
541 /* Between strings of the same kind, copy fast. */
542 if (STRINGP (this) && STRINGP (val
)
543 && STRING_MULTIBYTE (this) == some_multibyte
)
545 int thislen_byte
= STRING_BYTES (XSTRING (this));
546 bcopy (XSTRING (this)->data
, XSTRING (val
)->data
+ toindex_byte
,
547 STRING_BYTES (XSTRING (this)));
548 toindex_byte
+= thislen_byte
;
551 /* Copy a single-byte string to a multibyte string. */
552 else if (STRINGP (this) && STRINGP (val
))
554 toindex_byte
+= copy_text (XSTRING (this)->data
,
555 XSTRING (val
)->data
+ toindex_byte
,
556 XSTRING (this)->size
, 0, 1);
560 /* Copy element by element. */
563 register Lisp_Object elt
;
565 /* Fetch next element of `this' arg into `elt', or break if
566 `this' is exhausted. */
567 if (NILP (this)) break;
569 elt
= XCONS (this)->car
, this = XCONS (this)->cdr
;
570 else if (thisindex
>= thisleni
)
572 else if (STRINGP (this))
575 if (STRING_MULTIBYTE (this))
577 FETCH_STRING_CHAR_ADVANCE (c
, this,
580 XSETFASTINT (elt
, c
);
584 XSETFASTINT (elt
, XSTRING (this)->data
[thisindex
++]);
585 if (some_multibyte
&& XINT (elt
) >= 0200
586 && XINT (elt
) < 0400)
588 c
= unibyte_char_to_multibyte (XINT (elt
));
593 else if (BOOL_VECTOR_P (this))
596 byte
= XBOOL_VECTOR (this)->data
[thisindex
/ BITS_PER_CHAR
];
597 if (byte
& (1 << (thisindex
% BITS_PER_CHAR
)))
604 elt
= XVECTOR (this)->contents
[thisindex
++];
606 /* Store this element into the result. */
609 XCONS (tail
)->car
= elt
;
611 tail
= XCONS (tail
)->cdr
;
613 else if (VECTORP (val
))
614 XVECTOR (val
)->contents
[toindex
++] = elt
;
617 CHECK_NUMBER (elt
, 0);
618 if (SINGLE_BYTE_CHAR_P (XINT (elt
)))
620 XSTRING (val
)->data
[toindex
++] = XINT (elt
);
624 /* If we have any multibyte characters,
625 we already decided to make a multibyte string. */
628 unsigned char work
[4], *str
;
629 int i
= CHAR_STRING (c
, work
, str
);
631 /* P exists as a variable
632 to avoid a bug on the Masscomp C compiler. */
633 unsigned char *p
= & XSTRING (val
)->data
[toindex_byte
];
642 XCONS (prev
)->cdr
= last_tail
;
647 static Lisp_Object string_char_byte_cache_string
;
648 static int string_char_byte_cache_charpos
;
649 static int string_char_byte_cache_bytepos
;
651 /* Return the character index corresponding to CHAR_INDEX in STRING. */
654 string_char_to_byte (string
, char_index
)
659 int best_below
, best_below_byte
;
660 int best_above
, best_above_byte
;
662 if (! STRING_MULTIBYTE (string
))
665 best_below
= best_below_byte
= 0;
666 best_above
= XSTRING (string
)->size
;
667 best_above_byte
= STRING_BYTES (XSTRING (string
));
669 if (EQ (string
, string_char_byte_cache_string
))
671 if (string_char_byte_cache_charpos
< char_index
)
673 best_below
= string_char_byte_cache_charpos
;
674 best_below_byte
= string_char_byte_cache_bytepos
;
678 best_above
= string_char_byte_cache_charpos
;
679 best_above_byte
= string_char_byte_cache_bytepos
;
683 if (char_index
- best_below
< best_above
- char_index
)
685 while (best_below
< char_index
)
688 FETCH_STRING_CHAR_ADVANCE (c
, string
, best_below
, best_below_byte
);
691 i_byte
= best_below_byte
;
695 while (best_above
> char_index
)
697 int best_above_byte_saved
= --best_above_byte
;
699 while (best_above_byte
> 0
700 && !CHAR_HEAD_P (XSTRING (string
)->data
[best_above_byte
]))
702 if (XSTRING (string
)->data
[best_above_byte
] < 0x80)
703 best_above_byte
= best_above_byte_saved
;
707 i_byte
= best_above_byte
;
710 string_char_byte_cache_bytepos
= i_byte
;
711 string_char_byte_cache_charpos
= i
;
712 string_char_byte_cache_string
= string
;
717 /* Return the character index corresponding to BYTE_INDEX in STRING. */
720 string_byte_to_char (string
, byte_index
)
725 int best_below
, best_below_byte
;
726 int best_above
, best_above_byte
;
728 if (! STRING_MULTIBYTE (string
))
731 best_below
= best_below_byte
= 0;
732 best_above
= XSTRING (string
)->size
;
733 best_above_byte
= STRING_BYTES (XSTRING (string
));
735 if (EQ (string
, string_char_byte_cache_string
))
737 if (string_char_byte_cache_bytepos
< byte_index
)
739 best_below
= string_char_byte_cache_charpos
;
740 best_below_byte
= string_char_byte_cache_bytepos
;
744 best_above
= string_char_byte_cache_charpos
;
745 best_above_byte
= string_char_byte_cache_bytepos
;
749 if (byte_index
- best_below_byte
< best_above_byte
- byte_index
)
751 while (best_below_byte
< byte_index
)
754 FETCH_STRING_CHAR_ADVANCE (c
, string
, best_below
, best_below_byte
);
757 i_byte
= best_below_byte
;
761 while (best_above_byte
> byte_index
)
763 int best_above_byte_saved
= --best_above_byte
;
765 while (best_above_byte
> 0
766 && !CHAR_HEAD_P (XSTRING (string
)->data
[best_above_byte
]))
768 if (XSTRING (string
)->data
[best_above_byte
] < 0x80)
769 best_above_byte
= best_above_byte_saved
;
773 i_byte
= best_above_byte
;
776 string_char_byte_cache_bytepos
= i_byte
;
777 string_char_byte_cache_charpos
= i
;
778 string_char_byte_cache_string
= string
;
783 /* Convert STRING to a multibyte string.
784 Single-byte characters 0240 through 0377 are converted
785 by adding nonascii_insert_offset to each. */
788 string_make_multibyte (string
)
794 if (STRING_MULTIBYTE (string
))
797 nbytes
= count_size_as_multibyte (XSTRING (string
)->data
,
798 XSTRING (string
)->size
);
799 /* If all the chars are ASCII, they won't need any more bytes
800 once converted. In that case, we can return STRING itself. */
801 if (nbytes
== STRING_BYTES (XSTRING (string
)))
804 buf
= (unsigned char *) alloca (nbytes
);
805 copy_text (XSTRING (string
)->data
, buf
, STRING_BYTES (XSTRING (string
)),
808 return make_multibyte_string (buf
, XSTRING (string
)->size
, nbytes
);
811 /* Convert STRING to a single-byte string. */
814 string_make_unibyte (string
)
819 if (! STRING_MULTIBYTE (string
))
822 buf
= (unsigned char *) alloca (XSTRING (string
)->size
);
824 copy_text (XSTRING (string
)->data
, buf
, STRING_BYTES (XSTRING (string
)),
827 return make_unibyte_string (buf
, XSTRING (string
)->size
);
830 DEFUN ("string-make-multibyte", Fstring_make_multibyte
, Sstring_make_multibyte
,
832 "Return the multibyte equivalent of STRING.")
836 return string_make_multibyte (string
);
839 DEFUN ("string-make-unibyte", Fstring_make_unibyte
, Sstring_make_unibyte
,
841 "Return the unibyte equivalent of STRING.")
845 return string_make_unibyte (string
);
848 DEFUN ("string-as-unibyte", Fstring_as_unibyte
, Sstring_as_unibyte
,
850 "Return a unibyte string with the same individual bytes as STRING.\n\
851 If STRING is unibyte, the result is STRING itself.")
855 if (STRING_MULTIBYTE (string
))
857 string
= Fcopy_sequence (string
);
858 XSTRING (string
)->size
= STRING_BYTES (XSTRING (string
));
863 DEFUN ("string-as-multibyte", Fstring_as_multibyte
, Sstring_as_multibyte
,
865 "Return a multibyte string with the same individual bytes as STRING.\n\
866 If STRING is multibyte, the result is STRING itself.")
870 if (! STRING_MULTIBYTE (string
))
872 int newlen
= multibyte_chars_in_text (XSTRING (string
)->data
,
873 STRING_BYTES (XSTRING (string
)));
874 /* If all the chars are ASCII, STRING is already suitable. */
875 if (newlen
!= STRING_BYTES (XSTRING (string
)))
877 string
= Fcopy_sequence (string
);
878 XSTRING (string
)->size
= newlen
;
884 DEFUN ("copy-alist", Fcopy_alist
, Scopy_alist
, 1, 1, 0,
885 "Return a copy of ALIST.\n\
886 This is an alist which represents the same mapping from objects to objects,\n\
887 but does not share the alist structure with ALIST.\n\
888 The objects mapped (cars and cdrs of elements of the alist)\n\
889 are shared, however.\n\
890 Elements of ALIST that are not conses are also shared.")
894 register Lisp_Object tem
;
896 CHECK_LIST (alist
, 0);
899 alist
= concat (1, &alist
, Lisp_Cons
, 0);
900 for (tem
= alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
902 register Lisp_Object car
;
903 car
= XCONS (tem
)->car
;
906 XCONS (tem
)->car
= Fcons (XCONS (car
)->car
, XCONS (car
)->cdr
);
911 DEFUN ("substring", Fsubstring
, Ssubstring
, 2, 3, 0,
912 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
913 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
914 If FROM or TO is negative, it counts from the end.\n\
916 This function allows vectors as well as strings.")
919 register Lisp_Object from
, to
;
924 int from_char
, to_char
;
925 int from_byte
, to_byte
;
927 if (! (STRINGP (string
) || VECTORP (string
)))
928 wrong_type_argument (Qarrayp
, string
);
930 CHECK_NUMBER (from
, 1);
932 if (STRINGP (string
))
934 size
= XSTRING (string
)->size
;
935 size_byte
= STRING_BYTES (XSTRING (string
));
938 size
= XVECTOR (string
)->size
;
947 CHECK_NUMBER (to
, 2);
953 if (STRINGP (string
))
954 to_byte
= string_char_to_byte (string
, to_char
);
957 from_char
= XINT (from
);
960 if (STRINGP (string
))
961 from_byte
= string_char_to_byte (string
, from_char
);
963 if (!(0 <= from_char
&& from_char
<= to_char
&& to_char
<= size
))
964 args_out_of_range_3 (string
, make_number (from_char
),
965 make_number (to_char
));
967 if (STRINGP (string
))
969 res
= make_multibyte_string (XSTRING (string
)->data
+ from_byte
,
970 to_char
- from_char
, to_byte
- from_byte
);
971 copy_text_properties (from_char
, to_char
, string
,
972 make_number (0), res
, Qnil
);
975 res
= Fvector (to_char
- from_char
,
976 XVECTOR (string
)->contents
+ from_char
);
981 /* Extract a substring of STRING, giving start and end positions
982 both in characters and in bytes. */
985 substring_both (string
, from
, from_byte
, to
, to_byte
)
987 int from
, from_byte
, to
, to_byte
;
993 if (! (STRINGP (string
) || VECTORP (string
)))
994 wrong_type_argument (Qarrayp
, string
);
996 if (STRINGP (string
))
998 size
= XSTRING (string
)->size
;
999 size_byte
= STRING_BYTES (XSTRING (string
));
1002 size
= XVECTOR (string
)->size
;
1004 if (!(0 <= from
&& from
<= to
&& to
<= size
))
1005 args_out_of_range_3 (string
, make_number (from
), make_number (to
));
1007 if (STRINGP (string
))
1009 res
= make_multibyte_string (XSTRING (string
)->data
+ from_byte
,
1010 to
- from
, to_byte
- from_byte
);
1011 copy_text_properties (from
, to
, string
, make_number (0), res
, Qnil
);
1014 res
= Fvector (to
- from
,
1015 XVECTOR (string
)->contents
+ from
);
1020 DEFUN ("nthcdr", Fnthcdr
, Snthcdr
, 2, 2, 0,
1021 "Take cdr N times on LIST, returns the result.")
1024 register Lisp_Object list
;
1026 register int i
, num
;
1027 CHECK_NUMBER (n
, 0);
1029 for (i
= 0; i
< num
&& !NILP (list
); i
++)
1037 DEFUN ("nth", Fnth
, Snth
, 2, 2, 0,
1038 "Return the Nth element of LIST.\n\
1039 N counts from zero. If LIST is not that long, nil is returned.")
1041 Lisp_Object n
, list
;
1043 return Fcar (Fnthcdr (n
, list
));
1046 DEFUN ("elt", Felt
, Selt
, 2, 2, 0,
1047 "Return element of SEQUENCE at index N.")
1049 register Lisp_Object sequence
, n
;
1051 CHECK_NUMBER (n
, 0);
1054 if (CONSP (sequence
) || NILP (sequence
))
1055 return Fcar (Fnthcdr (n
, sequence
));
1056 else if (STRINGP (sequence
) || VECTORP (sequence
)
1057 || BOOL_VECTOR_P (sequence
) || CHAR_TABLE_P (sequence
))
1058 return Faref (sequence
, n
);
1060 sequence
= wrong_type_argument (Qsequencep
, sequence
);
1064 DEFUN ("member", Fmember
, Smember
, 2, 2, 0,
1065 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
1066 The value is actually the tail of LIST whose car is ELT.")
1068 register Lisp_Object elt
;
1071 register Lisp_Object tail
;
1072 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1074 register Lisp_Object tem
;
1076 if (! NILP (Fequal (elt
, tem
)))
1083 DEFUN ("memq", Fmemq
, Smemq
, 2, 2, 0,
1084 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
1085 The value is actually the tail of LIST whose car is ELT.")
1087 register Lisp_Object elt
;
1090 register Lisp_Object tail
;
1091 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1093 register Lisp_Object tem
;
1095 if (EQ (elt
, tem
)) return tail
;
1101 DEFUN ("assq", Fassq
, Sassq
, 2, 2, 0,
1102 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
1103 The value is actually the element of LIST whose car is KEY.\n\
1104 Elements of LIST that are not conses are ignored.")
1106 register Lisp_Object key
;
1109 register Lisp_Object tail
;
1110 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1112 register Lisp_Object elt
, tem
;
1114 if (!CONSP (elt
)) continue;
1115 tem
= XCONS (elt
)->car
;
1116 if (EQ (key
, tem
)) return elt
;
1122 /* Like Fassq but never report an error and do not allow quits.
1123 Use only on lists known never to be circular. */
1126 assq_no_quit (key
, list
)
1127 register Lisp_Object key
;
1130 register Lisp_Object tail
;
1131 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
1133 register Lisp_Object elt
, tem
;
1135 if (!CONSP (elt
)) continue;
1136 tem
= XCONS (elt
)->car
;
1137 if (EQ (key
, tem
)) return elt
;
1142 DEFUN ("assoc", Fassoc
, Sassoc
, 2, 2, 0,
1143 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
1144 The value is actually the element of LIST whose car equals KEY.")
1146 register Lisp_Object key
;
1149 register Lisp_Object tail
;
1150 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1152 register Lisp_Object elt
, tem
;
1154 if (!CONSP (elt
)) continue;
1155 tem
= Fequal (XCONS (elt
)->car
, key
);
1156 if (!NILP (tem
)) return elt
;
1162 DEFUN ("rassq", Frassq
, Srassq
, 2, 2, 0,
1163 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
1164 The value is actually the element of LIST whose cdr is ELT.")
1166 register Lisp_Object key
;
1169 register Lisp_Object tail
;
1170 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1172 register Lisp_Object elt
, tem
;
1174 if (!CONSP (elt
)) continue;
1175 tem
= XCONS (elt
)->cdr
;
1176 if (EQ (key
, tem
)) return elt
;
1182 DEFUN ("rassoc", Frassoc
, Srassoc
, 2, 2, 0,
1183 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
1184 The value is actually the element of LIST whose cdr equals KEY.")
1186 register Lisp_Object key
;
1189 register Lisp_Object tail
;
1190 for (tail
= list
; !NILP (tail
); tail
= XCONS (tail
)->cdr
)
1192 register Lisp_Object elt
, tem
;
1194 if (!CONSP (elt
)) continue;
1195 tem
= Fequal (XCONS (elt
)->cdr
, key
);
1196 if (!NILP (tem
)) return elt
;
1202 DEFUN ("delq", Fdelq
, Sdelq
, 2, 2, 0,
1203 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1204 The modified LIST is returned. Comparison is done with `eq'.\n\
1205 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
1206 therefore, write `(setq foo (delq element foo))'\n\
1207 to be sure of changing the value of `foo'.")
1209 register Lisp_Object elt
;
1212 register Lisp_Object tail
, prev
;
1213 register Lisp_Object tem
;
1217 while (!NILP (tail
))
1223 list
= XCONS (tail
)->cdr
;
1225 Fsetcdr (prev
, XCONS (tail
)->cdr
);
1229 tail
= XCONS (tail
)->cdr
;
1235 DEFUN ("delete", Fdelete
, Sdelete
, 2, 2, 0,
1236 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
1237 The modified LIST is returned. Comparison is done with `equal'.\n\
1238 If the first member of LIST is ELT, deleting it is not a side effect;\n\
1239 it is simply using a different list.\n\
1240 Therefore, write `(setq foo (delete element foo))'\n\
1241 to be sure of changing the value of `foo'.")
1243 register Lisp_Object elt
;
1246 register Lisp_Object tail
, prev
;
1247 register Lisp_Object tem
;
1251 while (!NILP (tail
))
1254 if (! NILP (Fequal (elt
, tem
)))
1257 list
= XCONS (tail
)->cdr
;
1259 Fsetcdr (prev
, XCONS (tail
)->cdr
);
1263 tail
= XCONS (tail
)->cdr
;
1269 DEFUN ("nreverse", Fnreverse
, Snreverse
, 1, 1, 0,
1270 "Reverse LIST by modifying cdr pointers.\n\
1271 Returns the beginning of the reversed list.")
1275 register Lisp_Object prev
, tail
, next
;
1277 if (NILP (list
)) return list
;
1280 while (!NILP (tail
))
1284 Fsetcdr (tail
, prev
);
1291 DEFUN ("reverse", Freverse
, Sreverse
, 1, 1, 0,
1292 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
1293 See also the function `nreverse', which is used more often.")
1299 for (new = Qnil
; CONSP (list
); list
= XCONS (list
)->cdr
)
1300 new = Fcons (XCONS (list
)->car
, new);
1302 wrong_type_argument (Qconsp
, list
);
1306 Lisp_Object
merge ();
1308 DEFUN ("sort", Fsort
, Ssort
, 2, 2, 0,
1309 "Sort LIST, stably, comparing elements using PREDICATE.\n\
1310 Returns the sorted list. LIST is modified by side effects.\n\
1311 PREDICATE is called with two elements of LIST, and should return T\n\
1312 if the first element is \"less\" than the second.")
1314 Lisp_Object list
, predicate
;
1316 Lisp_Object front
, back
;
1317 register Lisp_Object len
, tem
;
1318 struct gcpro gcpro1
, gcpro2
;
1319 register int length
;
1322 len
= Flength (list
);
1323 length
= XINT (len
);
1327 XSETINT (len
, (length
/ 2) - 1);
1328 tem
= Fnthcdr (len
, list
);
1330 Fsetcdr (tem
, Qnil
);
1332 GCPRO2 (front
, back
);
1333 front
= Fsort (front
, predicate
);
1334 back
= Fsort (back
, predicate
);
1336 return merge (front
, back
, predicate
);
1340 merge (org_l1
, org_l2
, pred
)
1341 Lisp_Object org_l1
, org_l2
;
1345 register Lisp_Object tail
;
1347 register Lisp_Object l1
, l2
;
1348 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
1355 /* It is sufficient to protect org_l1 and org_l2.
1356 When l1 and l2 are updated, we copy the new values
1357 back into the org_ vars. */
1358 GCPRO4 (org_l1
, org_l2
, pred
, value
);
1378 tem
= call2 (pred
, Fcar (l2
), Fcar (l1
));
1394 Fsetcdr (tail
, tem
);
1400 DEFUN ("plist-get", Fplist_get
, Splist_get
, 2, 2, 0,
1401 "Extract a value from a property list.\n\
1402 PLIST is a property list, which is a list of the form\n\
1403 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
1404 corresponding to the given PROP, or nil if PROP is not\n\
1405 one of the properties on the list.")
1408 register Lisp_Object prop
;
1410 register Lisp_Object tail
;
1411 for (tail
= plist
; !NILP (tail
); tail
= Fcdr (XCONS (tail
)->cdr
))
1413 register Lisp_Object tem
;
1416 return Fcar (XCONS (tail
)->cdr
);
1421 DEFUN ("get", Fget
, Sget
, 2, 2, 0,
1422 "Return the value of SYMBOL's PROPNAME property.\n\
1423 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
1425 Lisp_Object symbol
, propname
;
1427 CHECK_SYMBOL (symbol
, 0);
1428 return Fplist_get (XSYMBOL (symbol
)->plist
, propname
);
1431 DEFUN ("plist-put", Fplist_put
, Splist_put
, 3, 3, 0,
1432 "Change value in PLIST of PROP to VAL.\n\
1433 PLIST is a property list, which is a list of the form\n\
1434 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
1435 If PROP is already a property on the list, its value is set to VAL,\n\
1436 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
1437 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
1438 The PLIST is modified by side effects.")
1441 register Lisp_Object prop
;
1444 register Lisp_Object tail
, prev
;
1445 Lisp_Object newcell
;
1447 for (tail
= plist
; CONSP (tail
) && CONSP (XCONS (tail
)->cdr
);
1448 tail
= XCONS (XCONS (tail
)->cdr
)->cdr
)
1450 if (EQ (prop
, XCONS (tail
)->car
))
1452 Fsetcar (XCONS (tail
)->cdr
, val
);
1457 newcell
= Fcons (prop
, Fcons (val
, Qnil
));
1461 Fsetcdr (XCONS (prev
)->cdr
, newcell
);
1465 DEFUN ("put", Fput
, Sput
, 3, 3, 0,
1466 "Store SYMBOL's PROPNAME property with value VALUE.\n\
1467 It can be retrieved with `(get SYMBOL PROPNAME)'.")
1468 (symbol
, propname
, value
)
1469 Lisp_Object symbol
, propname
, value
;
1471 CHECK_SYMBOL (symbol
, 0);
1472 XSYMBOL (symbol
)->plist
1473 = Fplist_put (XSYMBOL (symbol
)->plist
, propname
, value
);
1477 DEFUN ("equal", Fequal
, Sequal
, 2, 2, 0,
1478 "Return t if two Lisp objects have similar structure and contents.\n\
1479 They must have the same data type.\n\
1480 Conses are compared by comparing the cars and the cdrs.\n\
1481 Vectors and strings are compared element by element.\n\
1482 Numbers are compared by value, but integers cannot equal floats.\n\
1483 (Use `=' if you want integers and floats to be able to be equal.)\n\
1484 Symbols must match exactly.")
1486 register Lisp_Object o1
, o2
;
1488 return internal_equal (o1
, o2
, 0) ? Qt
: Qnil
;
1492 internal_equal (o1
, o2
, depth
)
1493 register Lisp_Object o1
, o2
;
1497 error ("Stack overflow in equal");
1503 if (XTYPE (o1
) != XTYPE (o2
))
1508 #ifdef LISP_FLOAT_TYPE
1510 return (extract_float (o1
) == extract_float (o2
));
1514 if (!internal_equal (XCONS (o1
)->car
, XCONS (o2
)->car
, depth
+ 1))
1516 o1
= XCONS (o1
)->cdr
;
1517 o2
= XCONS (o2
)->cdr
;
1521 if (XMISCTYPE (o1
) != XMISCTYPE (o2
))
1525 if (!internal_equal (OVERLAY_START (o1
), OVERLAY_START (o1
),
1527 || !internal_equal (OVERLAY_END (o1
), OVERLAY_END (o1
),
1530 o1
= XOVERLAY (o1
)->plist
;
1531 o2
= XOVERLAY (o2
)->plist
;
1536 return (XMARKER (o1
)->buffer
== XMARKER (o2
)->buffer
1537 && (XMARKER (o1
)->buffer
== 0
1538 || XMARKER (o1
)->bytepos
== XMARKER (o2
)->bytepos
));
1542 case Lisp_Vectorlike
:
1544 register int i
, size
;
1545 size
= XVECTOR (o1
)->size
;
1546 /* Pseudovectors have the type encoded in the size field, so this test
1547 actually checks that the objects have the same type as well as the
1549 if (XVECTOR (o2
)->size
!= size
)
1551 /* Boolvectors are compared much like strings. */
1552 if (BOOL_VECTOR_P (o1
))
1555 = (XBOOL_VECTOR (o1
)->size
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
1557 if (XBOOL_VECTOR (o1
)->size
!= XBOOL_VECTOR (o2
)->size
)
1559 if (bcmp (XBOOL_VECTOR (o1
)->data
, XBOOL_VECTOR (o2
)->data
,
1564 if (WINDOW_CONFIGURATIONP (o1
))
1565 return compare_window_configurations (o1
, o2
, 0);
1567 /* Aside from them, only true vectors, char-tables, and compiled
1568 functions are sensible to compare, so eliminate the others now. */
1569 if (size
& PSEUDOVECTOR_FLAG
)
1571 if (!(size
& (PVEC_COMPILED
| PVEC_CHAR_TABLE
)))
1573 size
&= PSEUDOVECTOR_SIZE_MASK
;
1575 for (i
= 0; i
< size
; i
++)
1578 v1
= XVECTOR (o1
)->contents
[i
];
1579 v2
= XVECTOR (o2
)->contents
[i
];
1580 if (!internal_equal (v1
, v2
, depth
+ 1))
1588 if (XSTRING (o1
)->size
!= XSTRING (o2
)->size
)
1590 if (STRING_BYTES (XSTRING (o1
)) != STRING_BYTES (XSTRING (o2
)))
1592 if (bcmp (XSTRING (o1
)->data
, XSTRING (o2
)->data
,
1593 STRING_BYTES (XSTRING (o1
))))
1600 extern Lisp_Object
Fmake_char_internal ();
1602 DEFUN ("fillarray", Ffillarray
, Sfillarray
, 2, 2, 0,
1603 "Store each element of ARRAY with ITEM.\n\
1604 ARRAY is a vector, string, char-table, or bool-vector.")
1606 Lisp_Object array
, item
;
1608 register int size
, index
, charval
;
1610 if (VECTORP (array
))
1612 register Lisp_Object
*p
= XVECTOR (array
)->contents
;
1613 size
= XVECTOR (array
)->size
;
1614 for (index
= 0; index
< size
; index
++)
1617 else if (CHAR_TABLE_P (array
))
1619 register Lisp_Object
*p
= XCHAR_TABLE (array
)->contents
;
1620 size
= CHAR_TABLE_ORDINARY_SLOTS
;
1621 for (index
= 0; index
< size
; index
++)
1623 XCHAR_TABLE (array
)->defalt
= Qnil
;
1625 else if (STRINGP (array
))
1627 register unsigned char *p
= XSTRING (array
)->data
;
1628 CHECK_NUMBER (item
, 1);
1629 charval
= XINT (item
);
1630 size
= XSTRING (array
)->size
;
1631 for (index
= 0; index
< size
; index
++)
1634 else if (BOOL_VECTOR_P (array
))
1636 register unsigned char *p
= XBOOL_VECTOR (array
)->data
;
1638 = (XBOOL_VECTOR (array
)->size
+ BITS_PER_CHAR
- 1) / BITS_PER_CHAR
;
1640 charval
= (! NILP (item
) ? -1 : 0);
1641 for (index
= 0; index
< size_in_chars
; index
++)
1646 array
= wrong_type_argument (Qarrayp
, array
);
1652 DEFUN ("char-table-subtype", Fchar_table_subtype
, Schar_table_subtype
,
1654 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1656 Lisp_Object char_table
;
1658 CHECK_CHAR_TABLE (char_table
, 0);
1660 return XCHAR_TABLE (char_table
)->purpose
;
1663 DEFUN ("char-table-parent", Fchar_table_parent
, Schar_table_parent
,
1665 "Return the parent char-table of CHAR-TABLE.\n\
1666 The value is either nil or another char-table.\n\
1667 If CHAR-TABLE holds nil for a given character,\n\
1668 then the actual applicable value is inherited from the parent char-table\n\
1669 \(or from its parents, if necessary).")
1671 Lisp_Object char_table
;
1673 CHECK_CHAR_TABLE (char_table
, 0);
1675 return XCHAR_TABLE (char_table
)->parent
;
1678 DEFUN ("set-char-table-parent", Fset_char_table_parent
, Sset_char_table_parent
,
1680 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1681 PARENT must be either nil or another char-table.")
1682 (char_table
, parent
)
1683 Lisp_Object char_table
, parent
;
1687 CHECK_CHAR_TABLE (char_table
, 0);
1691 CHECK_CHAR_TABLE (parent
, 0);
1693 for (temp
= parent
; !NILP (temp
); temp
= XCHAR_TABLE (temp
)->parent
)
1694 if (EQ (temp
, char_table
))
1695 error ("Attempt to make a chartable be its own parent");
1698 XCHAR_TABLE (char_table
)->parent
= parent
;
1703 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot
, Schar_table_extra_slot
,
1705 "Return the value of CHAR-TABLE's extra-slot number N.")
1707 Lisp_Object char_table
, n
;
1709 CHECK_CHAR_TABLE (char_table
, 1);
1710 CHECK_NUMBER (n
, 2);
1712 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
1713 args_out_of_range (char_table
, n
);
1715 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)];
1718 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot
,
1719 Sset_char_table_extra_slot
,
1721 "Set CHAR-TABLE's extra-slot number N to VALUE.")
1722 (char_table
, n
, value
)
1723 Lisp_Object char_table
, n
, value
;
1725 CHECK_CHAR_TABLE (char_table
, 1);
1726 CHECK_NUMBER (n
, 2);
1728 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (char_table
)))
1729 args_out_of_range (char_table
, n
);
1731 return XCHAR_TABLE (char_table
)->extras
[XINT (n
)] = value
;
1734 DEFUN ("char-table-range", Fchar_table_range
, Schar_table_range
,
1736 "Return the value in CHAR-TABLE for a range of characters RANGE.\n\
1737 RANGE should be nil (for the default value)\n\
1738 a vector which identifies a character set or a row of a character set,\n\
1739 a character set name, or a character code.")
1741 Lisp_Object char_table
, range
;
1745 CHECK_CHAR_TABLE (char_table
, 0);
1747 if (EQ (range
, Qnil
))
1748 return XCHAR_TABLE (char_table
)->defalt
;
1749 else if (INTEGERP (range
))
1750 return Faref (char_table
, range
);
1751 else if (SYMBOLP (range
))
1753 Lisp_Object charset_info
;
1755 charset_info
= Fget (range
, Qcharset
);
1756 CHECK_VECTOR (charset_info
, 0);
1758 return Faref (char_table
, XVECTOR (charset_info
)->contents
[0] + 128);
1760 else if (VECTORP (range
))
1762 if (XVECTOR (range
)->size
== 1)
1763 return Faref (char_table
, XVECTOR (range
)->contents
[0] + 128);
1766 int size
= XVECTOR (range
)->size
;
1767 Lisp_Object
*val
= XVECTOR (range
)->contents
;
1768 Lisp_Object ch
= Fmake_char_internal (size
<= 0 ? Qnil
: val
[0],
1769 size
<= 1 ? Qnil
: val
[1],
1770 size
<= 2 ? Qnil
: val
[2]);
1771 return Faref (char_table
, ch
);
1775 error ("Invalid RANGE argument to `char-table-range'");
1778 DEFUN ("set-char-table-range", Fset_char_table_range
, Sset_char_table_range
,
1780 "Set the value in CHAR-TABLE for a range of characters RANGE to VALUE.\n\
1781 RANGE should be t (for all characters), nil (for the default value)\n\
1782 a vector which identifies a character set or a row of a character set,\n\
1783 a coding system, or a character code.")
1784 (char_table
, range
, value
)
1785 Lisp_Object char_table
, range
, value
;
1789 CHECK_CHAR_TABLE (char_table
, 0);
1792 for (i
= 0; i
< CHAR_TABLE_ORDINARY_SLOTS
; i
++)
1793 XCHAR_TABLE (char_table
)->contents
[i
] = value
;
1794 else if (EQ (range
, Qnil
))
1795 XCHAR_TABLE (char_table
)->defalt
= value
;
1796 else if (SYMBOLP (range
))
1798 Lisp_Object charset_info
;
1800 charset_info
= Fget (range
, Qcharset
);
1801 CHECK_VECTOR (charset_info
, 0);
1803 return Faset (char_table
, XVECTOR (charset_info
)->contents
[0] + 128,
1806 else if (INTEGERP (range
))
1807 Faset (char_table
, range
, value
);
1808 else if (VECTORP (range
))
1810 if (XVECTOR (range
)->size
== 1)
1811 return Faset (char_table
, XVECTOR (range
)->contents
[0] + 128, value
);
1814 int size
= XVECTOR (range
)->size
;
1815 Lisp_Object
*val
= XVECTOR (range
)->contents
;
1816 Lisp_Object ch
= Fmake_char_internal (size
<= 0 ? Qnil
: val
[0],
1817 size
<= 1 ? Qnil
: val
[1],
1818 size
<= 2 ? Qnil
: val
[2]);
1819 return Faset (char_table
, ch
, value
);
1823 error ("Invalid RANGE argument to `set-char-table-range'");
1828 DEFUN ("set-char-table-default", Fset_char_table_default
,
1829 Sset_char_table_default
, 3, 3, 0,
1830 "Set the default value in CHAR-TABLE for a generic character CHAR to VALUE.\n\
1831 The generic character specifies the group of characters.\n\
1832 See also the documentation of make-char.")
1833 (char_table
, ch
, value
)
1834 Lisp_Object char_table
, ch
, value
;
1836 int c
, i
, charset
, code1
, code2
;
1839 CHECK_CHAR_TABLE (char_table
, 0);
1840 CHECK_NUMBER (ch
, 1);
1843 SPLIT_NON_ASCII_CHAR (c
, charset
, code1
, code2
);
1844 if (! CHARSET_DEFINED_P (charset
))
1845 invalid_character (c
);
1847 if (charset
== CHARSET_ASCII
)
1848 return (XCHAR_TABLE (char_table
)->defalt
= value
);
1850 /* Even if C is not a generic char, we had better behave as if a
1851 generic char is specified. */
1852 if (CHARSET_DIMENSION (charset
) == 1)
1854 temp
= XCHAR_TABLE (char_table
)->contents
[charset
+ 128];
1857 if (SUB_CHAR_TABLE_P (temp
))
1858 XCHAR_TABLE (temp
)->defalt
= value
;
1860 XCHAR_TABLE (char_table
)->contents
[charset
+ 128] = value
;
1864 if (! SUB_CHAR_TABLE_P (char_table
))
1865 char_table
= (XCHAR_TABLE (char_table
)->contents
[charset
+ 128]
1866 = make_sub_char_table (temp
));
1867 temp
= XCHAR_TABLE (char_table
)->contents
[code1
];
1868 if (SUB_CHAR_TABLE_P (temp
))
1869 XCHAR_TABLE (temp
)->defalt
= value
;
1871 XCHAR_TABLE (char_table
)->contents
[code1
] = value
;
1875 /* Map C_FUNCTION or FUNCTION over SUBTABLE, calling it for each
1876 character or group of characters that share a value.
1877 DEPTH is the current depth in the originally specified
1878 chartable, and INDICES contains the vector indices
1879 for the levels our callers have descended.
1881 ARG is passed to C_FUNCTION when that is called. */
1884 map_char_table (c_function
, function
, subtable
, arg
, depth
, indices
)
1885 void (*c_function
) P_ ((Lisp_Object
, Lisp_Object
, Lisp_Object
));
1886 Lisp_Object function
, subtable
, arg
, *indices
;
1893 /* At first, handle ASCII and 8-bit European characters. */
1894 for (i
= 0; i
< CHAR_TABLE_SINGLE_BYTE_SLOTS
; i
++)
1896 Lisp_Object elt
= XCHAR_TABLE (subtable
)->contents
[i
];
1898 (*c_function
) (arg
, make_number (i
), elt
);
1900 call2 (function
, make_number (i
), elt
);
1902 #if 0 /* If the char table has entries for higher characters,
1903 we should report them. */
1904 if (NILP (current_buffer
->enable_multibyte_characters
))
1907 to
= CHAR_TABLE_ORDINARY_SLOTS
;
1912 to
= SUB_CHAR_TABLE_ORDINARY_SLOTS
;
1917 Lisp_Object elt
= XCHAR_TABLE (subtable
)->contents
[i
];
1919 XSETFASTINT (indices
[depth
], i
);
1921 if (SUB_CHAR_TABLE_P (elt
))
1924 error ("Too deep char table");
1925 map_char_table (c_function
, function
, elt
, arg
, depth
+ 1, indices
);
1929 int charset
= XFASTINT (indices
[0]) - 128, c1
, c2
, c
;
1931 if (CHARSET_DEFINED_P (charset
))
1933 c1
= depth
>= 1 ? XFASTINT (indices
[1]) : 0;
1934 c2
= depth
>= 2 ? XFASTINT (indices
[2]) : 0;
1935 c
= MAKE_NON_ASCII_CHAR (charset
, c1
, c2
);
1937 (*c_function
) (arg
, make_number (c
), elt
);
1939 call2 (function
, make_number (c
), elt
);
1945 DEFUN ("map-char-table", Fmap_char_table
, Smap_char_table
,
1947 "Call FUNCTION for each (normal and generic) characters in CHAR-TABLE.\n\
1948 FUNCTION is called with two arguments--a key and a value.\n\
1949 The key is always a possible IDX argument to `aref'.")
1950 (function
, char_table
)
1951 Lisp_Object function
, char_table
;
1953 /* The depth of char table is at most 3. */
1954 Lisp_Object indices
[3];
1956 CHECK_CHAR_TABLE (char_table
, 1);
1958 map_char_table (NULL
, function
, char_table
, char_table
, 0, indices
);
1968 Lisp_Object args
[2];
1971 return Fnconc (2, args
);
1973 return Fnconc (2, &s1
);
1974 #endif /* NO_ARG_ARRAY */
1977 DEFUN ("nconc", Fnconc
, Snconc
, 0, MANY
, 0,
1978 "Concatenate any number of lists by altering them.\n\
1979 Only the last argument is not altered, and need not be a list.")
1984 register int argnum
;
1985 register Lisp_Object tail
, tem
, val
;
1989 for (argnum
= 0; argnum
< nargs
; argnum
++)
1992 if (NILP (tem
)) continue;
1997 if (argnum
+ 1 == nargs
) break;
2000 tem
= wrong_type_argument (Qlistp
, tem
);
2009 tem
= args
[argnum
+ 1];
2010 Fsetcdr (tail
, tem
);
2012 args
[argnum
+ 1] = tail
;
2018 /* This is the guts of all mapping functions.
2019 Apply FN to each element of SEQ, one by one,
2020 storing the results into elements of VALS, a C vector of Lisp_Objects.
2021 LENI is the length of VALS, which should also be the length of SEQ. */
2024 mapcar1 (leni
, vals
, fn
, seq
)
2027 Lisp_Object fn
, seq
;
2029 register Lisp_Object tail
;
2032 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2034 /* Don't let vals contain any garbage when GC happens. */
2035 for (i
= 0; i
< leni
; i
++)
2038 GCPRO3 (dummy
, fn
, seq
);
2040 gcpro1
.nvars
= leni
;
2041 /* We need not explicitly protect `tail' because it is used only on lists, and
2042 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
2046 for (i
= 0; i
< leni
; i
++)
2048 dummy
= XVECTOR (seq
)->contents
[i
];
2049 vals
[i
] = call1 (fn
, dummy
);
2052 else if (BOOL_VECTOR_P (seq
))
2054 for (i
= 0; i
< leni
; i
++)
2057 byte
= XBOOL_VECTOR (seq
)->data
[i
/ BITS_PER_CHAR
];
2058 if (byte
& (1 << (i
% BITS_PER_CHAR
)))
2063 vals
[i
] = call1 (fn
, dummy
);
2066 else if (STRINGP (seq
) && ! STRING_MULTIBYTE (seq
))
2068 /* Single-byte string. */
2069 for (i
= 0; i
< leni
; i
++)
2071 XSETFASTINT (dummy
, XSTRING (seq
)->data
[i
]);
2072 vals
[i
] = call1 (fn
, dummy
);
2075 else if (STRINGP (seq
))
2077 /* Multi-byte string. */
2078 int len_byte
= STRING_BYTES (XSTRING (seq
));
2081 for (i
= 0, i_byte
= 0; i
< leni
;)
2086 FETCH_STRING_CHAR_ADVANCE (c
, seq
, i
, i_byte
);
2087 XSETFASTINT (dummy
, c
);
2088 vals
[i_before
] = call1 (fn
, dummy
);
2091 else /* Must be a list, since Flength did not get an error */
2094 for (i
= 0; i
< leni
; i
++)
2096 vals
[i
] = call1 (fn
, Fcar (tail
));
2097 tail
= XCONS (tail
)->cdr
;
2104 DEFUN ("mapconcat", Fmapconcat
, Smapconcat
, 3, 3, 0,
2105 "Apply FUNCTION to each element of SEQUENCE, and concat the results as strings.\n\
2106 In between each pair of results, stick in SEPARATOR. Thus, \" \" as\n\
2107 SEPARATOR results in spaces between the values returned by FUNCTION.\n\
2108 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2109 (function
, sequence
, separator
)
2110 Lisp_Object function
, sequence
, separator
;
2115 register Lisp_Object
*args
;
2117 struct gcpro gcpro1
;
2119 len
= Flength (sequence
);
2121 nargs
= leni
+ leni
- 1;
2122 if (nargs
< 0) return build_string ("");
2124 args
= (Lisp_Object
*) alloca (nargs
* sizeof (Lisp_Object
));
2127 mapcar1 (leni
, args
, function
, sequence
);
2130 for (i
= leni
- 1; i
>= 0; i
--)
2131 args
[i
+ i
] = args
[i
];
2133 for (i
= 1; i
< nargs
; i
+= 2)
2134 args
[i
] = separator
;
2136 return Fconcat (nargs
, args
);
2139 DEFUN ("mapcar", Fmapcar
, Smapcar
, 2, 2, 0,
2140 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
2141 The result is a list just as long as SEQUENCE.\n\
2142 SEQUENCE may be a list, a vector, a bool-vector, or a string.")
2143 (function
, sequence
)
2144 Lisp_Object function
, sequence
;
2146 register Lisp_Object len
;
2148 register Lisp_Object
*args
;
2150 len
= Flength (sequence
);
2151 leni
= XFASTINT (len
);
2152 args
= (Lisp_Object
*) alloca (leni
* sizeof (Lisp_Object
));
2154 mapcar1 (leni
, args
, function
, sequence
);
2156 return Flist (leni
, args
);
2159 /* Anything that calls this function must protect from GC! */
2161 DEFUN ("y-or-n-p", Fy_or_n_p
, Sy_or_n_p
, 1, 1, 0,
2162 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
2163 Takes one argument, which is the string to display to ask the question.\n\
2164 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
2165 No confirmation of the answer is requested; a single character is enough.\n\
2166 Also accepts Space to mean yes, or Delete to mean no.")
2170 register Lisp_Object obj
, key
, def
, answer_string
, map
;
2171 register int answer
;
2172 Lisp_Object xprompt
;
2173 Lisp_Object args
[2];
2174 struct gcpro gcpro1
, gcpro2
;
2175 int count
= specpdl_ptr
- specpdl
;
2177 specbind (Qcursor_in_echo_area
, Qt
);
2179 map
= Fsymbol_value (intern ("query-replace-map"));
2181 CHECK_STRING (prompt
, 0);
2183 GCPRO2 (prompt
, xprompt
);
2189 if ((NILP (last_nonmenu_event
) || CONSP (last_nonmenu_event
))
2193 Lisp_Object pane
, menu
;
2194 redisplay_preserve_echo_area ();
2195 pane
= Fcons (Fcons (build_string ("Yes"), Qt
),
2196 Fcons (Fcons (build_string ("No"), Qnil
),
2198 menu
= Fcons (prompt
, pane
);
2199 obj
= Fx_popup_dialog (Qt
, menu
);
2200 answer
= !NILP (obj
);
2203 #endif /* HAVE_MENUS */
2204 cursor_in_echo_area
= 1;
2205 choose_minibuf_frame ();
2206 message_with_string ("%s(y or n) ", xprompt
, 0);
2208 if (minibuffer_auto_raise
)
2210 Lisp_Object mini_frame
;
2212 mini_frame
= WINDOW_FRAME (XWINDOW (minibuf_window
));
2214 Fraise_frame (mini_frame
);
2217 obj
= read_filtered_event (1, 0, 0);
2218 cursor_in_echo_area
= 0;
2219 /* If we need to quit, quit with cursor_in_echo_area = 0. */
2222 key
= Fmake_vector (make_number (1), obj
);
2223 def
= Flookup_key (map
, key
, Qt
);
2224 answer_string
= Fsingle_key_description (obj
);
2226 if (EQ (def
, intern ("skip")))
2231 else if (EQ (def
, intern ("act")))
2236 else if (EQ (def
, intern ("recenter")))
2242 else if (EQ (def
, intern ("quit")))
2244 /* We want to exit this command for exit-prefix,
2245 and this is the only way to do it. */
2246 else if (EQ (def
, intern ("exit-prefix")))
2251 /* If we don't clear this, then the next call to read_char will
2252 return quit_char again, and we'll enter an infinite loop. */
2257 if (EQ (xprompt
, prompt
))
2259 args
[0] = build_string ("Please answer y or n. ");
2261 xprompt
= Fconcat (2, args
);
2266 if (! noninteractive
)
2268 cursor_in_echo_area
= -1;
2269 message_with_string (answer
? "%s(y or n) y" : "%s(y or n) n",
2273 unbind_to (count
, Qnil
);
2274 return answer
? Qt
: Qnil
;
2277 /* This is how C code calls `yes-or-no-p' and allows the user
2280 Anything that calls this function must protect from GC! */
2283 do_yes_or_no_p (prompt
)
2286 return call1 (intern ("yes-or-no-p"), prompt
);
2289 /* Anything that calls this function must protect from GC! */
2291 DEFUN ("yes-or-no-p", Fyes_or_no_p
, Syes_or_no_p
, 1, 1, 0,
2292 "Ask user a yes-or-no question. Return t if answer is yes.\n\
2293 Takes one argument, which is the string to display to ask the question.\n\
2294 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
2295 The user must confirm the answer with RET,\n\
2296 and can edit it until it has been confirmed.")
2300 register Lisp_Object ans
;
2301 Lisp_Object args
[2];
2302 struct gcpro gcpro1
;
2305 CHECK_STRING (prompt
, 0);
2308 if ((NILP (last_nonmenu_event
) || CONSP (last_nonmenu_event
))
2312 Lisp_Object pane
, menu
, obj
;
2313 redisplay_preserve_echo_area ();
2314 pane
= Fcons (Fcons (build_string ("Yes"), Qt
),
2315 Fcons (Fcons (build_string ("No"), Qnil
),
2318 menu
= Fcons (prompt
, pane
);
2319 obj
= Fx_popup_dialog (Qt
, menu
);
2323 #endif /* HAVE_MENUS */
2326 args
[1] = build_string ("(yes or no) ");
2327 prompt
= Fconcat (2, args
);
2333 ans
= Fdowncase (Fread_from_minibuffer (prompt
, Qnil
, Qnil
, Qnil
,
2334 Qyes_or_no_p_history
, Qnil
,
2336 if (XSTRING (ans
)->size
== 3 && !strcmp (XSTRING (ans
)->data
, "yes"))
2341 if (XSTRING (ans
)->size
== 2 && !strcmp (XSTRING (ans
)->data
, "no"))
2349 message ("Please answer yes or no.");
2350 Fsleep_for (make_number (2), Qnil
);
2354 DEFUN ("load-average", Fload_average
, Sload_average
, 0, 0, 0,
2355 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
2356 Each of the three load averages is multiplied by 100,\n\
2357 then converted to integer.\n\
2358 If the 5-minute or 15-minute load averages are not available, return a\n\
2359 shortened list, containing only those averages which are available.")
2363 int loads
= getloadavg (load_ave
, 3);
2367 error ("load-average not implemented for this operating system");
2371 ret
= Fcons (make_number ((int) (load_ave
[--loads
] * 100.0)), ret
);
2376 Lisp_Object Vfeatures
;
2378 DEFUN ("featurep", Ffeaturep
, Sfeaturep
, 1, 1, 0,
2379 "Returns t if FEATURE is present in this Emacs.\n\
2380 Use this to conditionalize execution of lisp code based on the presence or\n\
2381 absence of emacs or environment extensions.\n\
2382 Use `provide' to declare that a feature is available.\n\
2383 This function looks at the value of the variable `features'.")
2385 Lisp_Object feature
;
2387 register Lisp_Object tem
;
2388 CHECK_SYMBOL (feature
, 0);
2389 tem
= Fmemq (feature
, Vfeatures
);
2390 return (NILP (tem
)) ? Qnil
: Qt
;
2393 DEFUN ("provide", Fprovide
, Sprovide
, 1, 1, 0,
2394 "Announce that FEATURE is a feature of the current Emacs.")
2396 Lisp_Object feature
;
2398 register Lisp_Object tem
;
2399 CHECK_SYMBOL (feature
, 0);
2400 if (!NILP (Vautoload_queue
))
2401 Vautoload_queue
= Fcons (Fcons (Vfeatures
, Qnil
), Vautoload_queue
);
2402 tem
= Fmemq (feature
, Vfeatures
);
2404 Vfeatures
= Fcons (feature
, Vfeatures
);
2405 LOADHIST_ATTACH (Fcons (Qprovide
, feature
));
2409 DEFUN ("require", Frequire
, Srequire
, 1, 2, 0,
2410 "If feature FEATURE is not loaded, load it from FILENAME.\n\
2411 If FEATURE is not a member of the list `features', then the feature\n\
2412 is not loaded; so load the file FILENAME.\n\
2413 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
2414 (feature
, file_name
)
2415 Lisp_Object feature
, file_name
;
2417 register Lisp_Object tem
;
2418 CHECK_SYMBOL (feature
, 0);
2419 tem
= Fmemq (feature
, Vfeatures
);
2420 LOADHIST_ATTACH (Fcons (Qrequire
, feature
));
2423 int count
= specpdl_ptr
- specpdl
;
2425 /* Value saved here is to be restored into Vautoload_queue */
2426 record_unwind_protect (un_autoload
, Vautoload_queue
);
2427 Vautoload_queue
= Qt
;
2429 Fload (NILP (file_name
) ? Fsymbol_name (feature
) : file_name
,
2430 Qnil
, Qt
, Qnil
, (NILP (file_name
) ? Qt
: Qnil
));
2432 tem
= Fmemq (feature
, Vfeatures
);
2434 error ("Required feature %s was not provided",
2435 XSYMBOL (feature
)->name
->data
);
2437 /* Once loading finishes, don't undo it. */
2438 Vautoload_queue
= Qt
;
2439 feature
= unbind_to (count
, feature
);
2444 /* Primitives for work of the "widget" library.
2445 In an ideal world, this section would not have been necessary.
2446 However, lisp function calls being as slow as they are, it turns
2447 out that some functions in the widget library (wid-edit.el) are the
2448 bottleneck of Widget operation. Here is their translation to C,
2449 for the sole reason of efficiency. */
2451 DEFUN ("widget-plist-member", Fwidget_plist_member
, Swidget_plist_member
, 2, 2, 0,
2452 "Return non-nil if PLIST has the property PROP.\n\
2453 PLIST is a property list, which is a list of the form\n\
2454 \(PROP1 VALUE1 PROP2 VALUE2 ...\). PROP is a symbol.\n\
2455 Unlike `plist-get', this allows you to distinguish between a missing\n\
2456 property and a property with the value nil.\n\
2457 The value is actually the tail of PLIST whose car is PROP.")
2459 Lisp_Object plist
, prop
;
2461 while (CONSP (plist
) && !EQ (XCAR (plist
), prop
))
2464 plist
= XCDR (plist
);
2465 plist
= CDR (plist
);
2470 DEFUN ("widget-put", Fwidget_put
, Swidget_put
, 3, 3, 0,
2471 "In WIDGET, set PROPERTY to VALUE.\n\
2472 The value can later be retrieved with `widget-get'.")
2473 (widget
, property
, value
)
2474 Lisp_Object widget
, property
, value
;
2476 CHECK_CONS (widget
, 1);
2477 XCDR (widget
) = Fplist_put (XCDR (widget
), property
, value
);
2480 DEFUN ("widget-get", Fwidget_get
, Swidget_get
, 2, 2, 0,
2481 "In WIDGET, get the value of PROPERTY.\n\
2482 The value could either be specified when the widget was created, or\n\
2483 later with `widget-put'.")
2485 Lisp_Object widget
, property
;
2493 CHECK_CONS (widget
, 1);
2494 tmp
= Fwidget_plist_member (XCDR (widget
), property
);
2500 tmp
= XCAR (widget
);
2503 widget
= Fget (tmp
, Qwidget_type
);
2507 DEFUN ("widget-apply", Fwidget_apply
, Swidget_apply
, 2, MANY
, 0,
2508 "Apply the value of WIDGET's PROPERTY to the widget itself.\n\
2509 ARGS are passed as extra arguments to the function.")
2514 /* This function can GC. */
2515 Lisp_Object newargs
[3];
2516 struct gcpro gcpro1
, gcpro2
;
2519 newargs
[0] = Fwidget_get (args
[0], args
[1]);
2520 newargs
[1] = args
[0];
2521 newargs
[2] = Flist (nargs
- 2, args
+ 2);
2522 GCPRO2 (newargs
[0], newargs
[2]);
2523 result
= Fapply (3, newargs
);
2530 Qstring_lessp
= intern ("string-lessp");
2531 staticpro (&Qstring_lessp
);
2532 Qprovide
= intern ("provide");
2533 staticpro (&Qprovide
);
2534 Qrequire
= intern ("require");
2535 staticpro (&Qrequire
);
2536 Qyes_or_no_p_history
= intern ("yes-or-no-p-history");
2537 staticpro (&Qyes_or_no_p_history
);
2538 Qcursor_in_echo_area
= intern ("cursor-in-echo-area");
2539 staticpro (&Qcursor_in_echo_area
);
2540 Qwidget_type
= intern ("widget-type");
2541 staticpro (&Qwidget_type
);
2543 staticpro (&string_char_byte_cache_string
);
2544 string_char_byte_cache_string
= Qnil
;
2546 Fset (Qyes_or_no_p_history
, Qnil
);
2548 DEFVAR_LISP ("features", &Vfeatures
,
2549 "A list of symbols which are the features of the executing emacs.\n\
2550 Used by `featurep' and `require', and altered by `provide'.");
2553 DEFVAR_BOOL ("use-dialog-box", &use_dialog_box
,
2554 "*Non-nil means mouse commands use dialog boxes to ask questions.\n\
2555 This applies to y-or-n and yes-or-no questions asked by commands\n\
2556 invoked by mouse clicks and mouse menu items.");
2559 defsubr (&Sidentity
);
2562 defsubr (&Ssafe_length
);
2563 defsubr (&Sstring_bytes
);
2564 defsubr (&Sstring_equal
);
2565 defsubr (&Sstring_lessp
);
2568 defsubr (&Svconcat
);
2569 defsubr (&Scopy_sequence
);
2570 defsubr (&Sstring_make_multibyte
);
2571 defsubr (&Sstring_make_unibyte
);
2572 defsubr (&Sstring_as_multibyte
);
2573 defsubr (&Sstring_as_unibyte
);
2574 defsubr (&Scopy_alist
);
2575 defsubr (&Ssubstring
);
2587 defsubr (&Snreverse
);
2588 defsubr (&Sreverse
);
2590 defsubr (&Splist_get
);
2592 defsubr (&Splist_put
);
2595 defsubr (&Sfillarray
);
2596 defsubr (&Schar_table_subtype
);
2597 defsubr (&Schar_table_parent
);
2598 defsubr (&Sset_char_table_parent
);
2599 defsubr (&Schar_table_extra_slot
);
2600 defsubr (&Sset_char_table_extra_slot
);
2601 defsubr (&Schar_table_range
);
2602 defsubr (&Sset_char_table_range
);
2603 defsubr (&Sset_char_table_default
);
2604 defsubr (&Smap_char_table
);
2607 defsubr (&Smapconcat
);
2608 defsubr (&Sy_or_n_p
);
2609 defsubr (&Syes_or_no_p
);
2610 defsubr (&Sload_average
);
2611 defsubr (&Sfeaturep
);
2612 defsubr (&Srequire
);
2613 defsubr (&Sprovide
);
2614 defsubr (&Swidget_plist_member
);
2615 defsubr (&Swidget_put
);
2616 defsubr (&Swidget_get
);
2617 defsubr (&Swidget_apply
);