1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 /* Note on some machines this defines `vector' as a typedef,
24 so make sure we don't use that name in this file. */
33 #include "intervals.h"
36 #define NULL (void *)0
39 extern Lisp_Object
Flookup_key ();
41 Lisp_Object Qstring_lessp
, Qprovide
, Qrequire
;
42 Lisp_Object Qyes_or_no_p_history
;
44 static int internal_equal ();
46 DEFUN ("identity", Fidentity
, Sidentity
, 1, 1, 0,
47 "Return the argument unchanged.")
54 extern long get_random ();
55 extern void seed_random ();
58 DEFUN ("random", Frandom
, Srandom
, 0, 1, 0,
59 "Return a pseudo-random number.\n\
60 All integers representable in Lisp are equally likely.\n\
61 On most systems, this is 28 bits' worth.\n\
62 With positive integer argument N, return random number in interval [0,N).\n\
63 With argument t, set the random number seed from the current time and pid.")
68 Lisp_Object lispy_val
;
69 unsigned long denominator
;
72 seed_random (getpid () + time (NULL
));
73 if (NATNUMP (limit
) && XFASTINT (limit
) != 0)
75 /* Try to take our random number from the higher bits of VAL,
76 not the lower, since (says Gentzel) the low bits of `random'
77 are less random than the higher ones. We do this by using the
78 quotient rather than the remainder. At the high end of the RNG
79 it's possible to get a quotient larger than limit; discarding
80 these values eliminates the bias that would otherwise appear
81 when using a large limit. */
82 denominator
= ((unsigned long)1 << VALBITS
) / XFASTINT (limit
);
84 val
= get_random () / denominator
;
85 while (val
>= XFASTINT (limit
));
89 XSETINT (lispy_val
, val
);
93 /* Random data-structure functions */
95 DEFUN ("length", Flength
, Slength
, 1, 1, 0,
96 "Return the length of vector, list or string SEQUENCE.\n\
97 A byte-code function object is also allowed.")
99 register Lisp_Object obj
;
101 register Lisp_Object tail
, val
;
106 XSETFASTINT (val
, XSTRING (obj
)->size
);
107 else if (VECTORP (obj
))
108 XSETFASTINT (val
, XVECTOR (obj
)->size
);
109 else if (CHAR_TABLE_P (obj
))
110 XSETFASTINT (val
, CHAR_TABLE_ORDINARY_SLOTS
);
111 else if (BOOL_VECTOR_P (obj
))
112 XSETFASTINT (val
, XBOOL_VECTOR (obj
)->size
);
113 else if (COMPILEDP (obj
))
114 XSETFASTINT (val
, XVECTOR (obj
)->size
& PSEUDOVECTOR_SIZE_MASK
);
115 else if (CONSP (obj
))
117 for (i
= 0, tail
= obj
; !NILP (tail
); i
++)
123 XSETFASTINT (val
, i
);
126 XSETFASTINT (val
, 0);
129 obj
= wrong_type_argument (Qsequencep
, obj
);
135 /* This does not check for quits. That is safe
136 since it must terminate. */
138 DEFUN ("safe-length", Fsafe_length
, Ssafe_length
, 1, 1, 0,
139 "Return the length of a list, but avoid error or infinite loop.\n\
140 This function never gets an error. If LIST is not really a list,\n\
141 it returns 0. If LIST is circular, it returns a finite value\n\
142 which is at least the number of distinct elements.")
146 Lisp_Object tail
, halftail
, length
;
149 /* halftail is used to detect circular lists. */
151 for (tail
= list
; CONSP (tail
); tail
= XCONS (tail
)->cdr
)
153 if (EQ (tail
, halftail
) && len
!= 0)
157 halftail
= XCONS (halftail
)->cdr
;
160 XSETINT (length
, len
);
164 DEFUN ("string-equal", Fstring_equal
, Sstring_equal
, 2, 2, 0,
165 "T if two strings have identical contents.\n\
166 Case is significant, but text properties are ignored.\n\
167 Symbols are also allowed; their print names are used instead.")
169 register Lisp_Object s1
, s2
;
172 XSETSTRING (s1
, XSYMBOL (s1
)->name
);
174 XSETSTRING (s2
, XSYMBOL (s2
)->name
);
175 CHECK_STRING (s1
, 0);
176 CHECK_STRING (s2
, 1);
178 if (XSTRING (s1
)->size
!= XSTRING (s2
)->size
||
179 bcmp (XSTRING (s1
)->data
, XSTRING (s2
)->data
, XSTRING (s1
)->size
))
184 DEFUN ("string-lessp", Fstring_lessp
, Sstring_lessp
, 2, 2, 0,
185 "T if first arg string is less than second in lexicographic order.\n\
186 Case is significant.\n\
187 Symbols are also allowed; their print names are used instead.")
189 register Lisp_Object s1
, s2
;
192 register unsigned char *p1
, *p2
;
196 XSETSTRING (s1
, XSYMBOL (s1
)->name
);
198 XSETSTRING (s2
, XSYMBOL (s2
)->name
);
199 CHECK_STRING (s1
, 0);
200 CHECK_STRING (s2
, 1);
202 p1
= XSTRING (s1
)->data
;
203 p2
= XSTRING (s2
)->data
;
204 end
= XSTRING (s1
)->size
;
205 if (end
> XSTRING (s2
)->size
)
206 end
= XSTRING (s2
)->size
;
208 for (i
= 0; i
< end
; i
++)
211 return p1
[i
] < p2
[i
] ? Qt
: Qnil
;
213 return i
< XSTRING (s2
)->size
? Qt
: Qnil
;
216 static Lisp_Object
concat ();
227 return concat (2, args
, Lisp_String
, 0);
229 return concat (2, &s1
, Lisp_String
, 0);
230 #endif /* NO_ARG_ARRAY */
236 Lisp_Object s1
, s2
, s3
;
243 return concat (3, args
, Lisp_String
, 0);
245 return concat (3, &s1
, Lisp_String
, 0);
246 #endif /* NO_ARG_ARRAY */
249 DEFUN ("append", Fappend
, Sappend
, 0, MANY
, 0,
250 "Concatenate all the arguments and make the result a list.\n\
251 The result is a list whose elements are the elements of all the arguments.\n\
252 Each argument may be a list, vector or string.\n\
253 The last argument is not copied, just used as the tail of the new list.")
258 return concat (nargs
, args
, Lisp_Cons
, 1);
261 DEFUN ("concat", Fconcat
, Sconcat
, 0, MANY
, 0,
262 "Concatenate all the arguments and make the result a string.\n\
263 The result is a string whose elements are the elements of all the arguments.\n\
264 Each argument may be a string or a list or vector of characters (integers).\n\
266 Do not use individual integers as arguments!\n\
267 The behavior of `concat' in that case will be changed later!\n\
268 If your program passes an integer as an argument to `concat',\n\
269 you should change it right away not to do so.")
274 return concat (nargs
, args
, Lisp_String
, 0);
277 DEFUN ("vconcat", Fvconcat
, Svconcat
, 0, MANY
, 0,
278 "Concatenate all the arguments and make the result a vector.\n\
279 The result is a vector whose elements are the elements of all the arguments.\n\
280 Each argument may be a list, vector or string.")
285 return concat (nargs
, args
, Lisp_Vectorlike
, 0);
288 DEFUN ("copy-sequence", Fcopy_sequence
, Scopy_sequence
, 1, 1, 0,
289 "Return a copy of a list, vector or string.\n\
290 The elements of a list or vector are not copied; they are shared\n\
295 if (NILP (arg
)) return arg
;
297 if (CHAR_TABLE_P (arg
))
302 /* Calculate the number of extra slots. */
303 size
= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (arg
));
304 copy
= Fmake_char_table (XCHAR_TABLE (arg
)->purpose
, Qnil
);
305 /* Copy all the slots, including the extra ones. */
306 bcopy (XCHAR_TABLE (arg
)->contents
, XCHAR_TABLE (copy
)->contents
,
307 (XCHAR_TABLE (arg
)->size
& PSEUDOVECTOR_SIZE_MASK
) * sizeof (Lisp_Object
));
309 /* Recursively copy any char-tables in the ordinary slots. */
310 for (i
= 0; i
< CHAR_TABLE_ORDINARY_SLOTS
; i
++)
311 if (CHAR_TABLE_P (XCHAR_TABLE (arg
)->contents
[i
]))
312 XCHAR_TABLE (copy
)->contents
[i
]
313 = Fcopy_sequence (XCHAR_TABLE (copy
)->contents
[i
]);
318 if (BOOL_VECTOR_P (arg
))
322 = (XBOOL_VECTOR (arg
)->size
+ BITS_PER_CHAR
) / BITS_PER_CHAR
;
324 val
= Fmake_bool_vector (Flength (arg
), Qnil
);
325 bcopy (XBOOL_VECTOR (arg
)->data
, XBOOL_VECTOR (val
)->data
,
330 if (!CONSP (arg
) && !VECTORP (arg
) && !STRINGP (arg
))
331 arg
= wrong_type_argument (Qsequencep
, arg
);
332 return concat (1, &arg
, CONSP (arg
) ? Lisp_Cons
: XTYPE (arg
), 0);
336 concat (nargs
, args
, target_type
, last_special
)
339 enum Lisp_Type target_type
;
344 register Lisp_Object tail
;
345 register Lisp_Object
this;
349 Lisp_Object last_tail
;
352 /* In append, the last arg isn't treated like the others */
353 if (last_special
&& nargs
> 0)
356 last_tail
= args
[nargs
];
361 for (argnum
= 0; argnum
< nargs
; argnum
++)
364 if (!(CONSP (this) || NILP (this) || VECTORP (this) || STRINGP (this)
365 || COMPILEDP (this) || BOOL_VECTOR_P (this)))
368 args
[argnum
] = Fnumber_to_string (this);
370 args
[argnum
] = wrong_type_argument (Qsequencep
, this);
374 for (argnum
= 0, leni
= 0; argnum
< nargs
; argnum
++)
377 len
= Flength (this);
378 leni
+= XFASTINT (len
);
381 XSETFASTINT (len
, leni
);
383 if (target_type
== Lisp_Cons
)
384 val
= Fmake_list (len
, Qnil
);
385 else if (target_type
== Lisp_Vectorlike
)
386 val
= Fmake_vector (len
, Qnil
);
388 val
= Fmake_string (len
, len
);
390 /* In append, if all but last arg are nil, return last arg */
391 if (target_type
== Lisp_Cons
&& EQ (val
, Qnil
))
395 tail
= val
, toindex
= -1; /* -1 in toindex is flag we are making a list */
401 for (argnum
= 0; argnum
< nargs
; argnum
++)
405 register int thisindex
= 0;
409 thislen
= Flength (this), thisleni
= XINT (thislen
);
411 if (STRINGP (this) && STRINGP (val
)
412 && ! NULL_INTERVAL_P (XSTRING (this)->intervals
))
414 copy_text_properties (make_number (0), thislen
, this,
415 make_number (toindex
), val
, Qnil
);
420 register Lisp_Object elt
;
422 /* Fetch next element of `this' arg into `elt', or break if
423 `this' is exhausted. */
424 if (NILP (this)) break;
426 elt
= Fcar (this), this = Fcdr (this);
429 if (thisindex
>= thisleni
) break;
431 XSETFASTINT (elt
, XSTRING (this)->data
[thisindex
++]);
432 else if (BOOL_VECTOR_P (this))
435 = ((XBOOL_VECTOR (this)->size
+ BITS_PER_CHAR
)
438 byte
= XBOOL_VECTOR (val
)->data
[thisindex
/ BITS_PER_CHAR
];
439 if (byte
& (1 << thisindex
))
445 elt
= XVECTOR (this)->contents
[thisindex
++];
448 /* Store into result */
451 XCONS (tail
)->car
= elt
;
453 tail
= XCONS (tail
)->cdr
;
455 else if (VECTORP (val
))
456 XVECTOR (val
)->contents
[toindex
++] = elt
;
459 while (!INTEGERP (elt
))
460 elt
= wrong_type_argument (Qintegerp
, elt
);
462 #ifdef MASSC_REGISTER_BUG
463 /* Even removing all "register"s doesn't disable this bug!
464 Nothing simpler than this seems to work. */
465 unsigned char *p
= & XSTRING (val
)->data
[toindex
++];
468 XSTRING (val
)->data
[toindex
++] = XINT (elt
);
475 XCONS (prev
)->cdr
= last_tail
;
480 DEFUN ("copy-alist", Fcopy_alist
, Scopy_alist
, 1, 1, 0,
481 "Return a copy of ALIST.\n\
482 This is an alist which represents the same mapping from objects to objects,\n\
483 but does not share the alist structure with ALIST.\n\
484 The objects mapped (cars and cdrs of elements of the alist)\n\
485 are shared, however.\n\
486 Elements of ALIST that are not conses are also shared.")
490 register Lisp_Object tem
;
492 CHECK_LIST (alist
, 0);
495 alist
= concat (1, &alist
, Lisp_Cons
, 0);
496 for (tem
= alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
498 register Lisp_Object car
;
499 car
= XCONS (tem
)->car
;
502 XCONS (tem
)->car
= Fcons (XCONS (car
)->car
, XCONS (car
)->cdr
);
507 DEFUN ("substring", Fsubstring
, Ssubstring
, 2, 3, 0,
508 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
509 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
510 If FROM or TO is negative, it counts from the end.")
513 register Lisp_Object from
, to
;
517 CHECK_STRING (string
, 0);
518 CHECK_NUMBER (from
, 1);
520 to
= Flength (string
);
522 CHECK_NUMBER (to
, 2);
525 XSETINT (from
, XINT (from
) + XSTRING (string
)->size
);
527 XSETINT (to
, XINT (to
) + XSTRING (string
)->size
);
528 if (!(0 <= XINT (from
) && XINT (from
) <= XINT (to
)
529 && XINT (to
) <= XSTRING (string
)->size
))
530 args_out_of_range_3 (string
, from
, to
);
532 res
= make_string (XSTRING (string
)->data
+ XINT (from
),
533 XINT (to
) - XINT (from
));
534 copy_text_properties (from
, to
, string
, make_number (0), res
, Qnil
);
538 DEFUN ("nthcdr", Fnthcdr
, Snthcdr
, 2, 2, 0,
539 "Take cdr N times on LIST, returns the result.")
542 register Lisp_Object list
;
547 for (i
= 0; i
< num
&& !NILP (list
); i
++)
555 DEFUN ("nth", Fnth
, Snth
, 2, 2, 0,
556 "Return the Nth element of LIST.\n\
557 N counts from zero. If LIST is not that long, nil is returned.")
561 return Fcar (Fnthcdr (n
, list
));
564 DEFUN ("elt", Felt
, Selt
, 2, 2, 0,
565 "Return element of SEQUENCE at index N.")
567 register Lisp_Object seq
, n
;
572 if (CONSP (seq
) || NILP (seq
))
573 return Fcar (Fnthcdr (n
, seq
));
574 else if (STRINGP (seq
) || VECTORP (seq
) || BOOL_VECTOR_P (seq
)
575 || CHAR_TABLE_P (seq
))
576 return Faref (seq
, n
);
578 seq
= wrong_type_argument (Qsequencep
, seq
);
582 DEFUN ("member", Fmember
, Smember
, 2, 2, 0,
583 "Return non-nil if ELT is an element of LIST. Comparison done with `equal'.\n\
584 The value is actually the tail of LIST whose car is ELT.")
586 register Lisp_Object elt
;
589 register Lisp_Object tail
;
590 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
592 register Lisp_Object tem
;
594 if (! NILP (Fequal (elt
, tem
)))
601 DEFUN ("memq", Fmemq
, Smemq
, 2, 2, 0,
602 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
603 The value is actually the tail of LIST whose car is ELT.")
605 register Lisp_Object elt
;
608 register Lisp_Object tail
;
609 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
611 register Lisp_Object tem
;
613 if (EQ (elt
, tem
)) return tail
;
619 DEFUN ("assq", Fassq
, Sassq
, 2, 2, 0,
620 "Return non-nil if KEY is `eq' to the car of an element of LIST.\n\
621 The value is actually the element of LIST whose car is KEY.\n\
622 Elements of LIST that are not conses are ignored.")
624 register Lisp_Object key
;
627 register Lisp_Object tail
;
628 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
630 register Lisp_Object elt
, tem
;
632 if (!CONSP (elt
)) continue;
634 if (EQ (key
, tem
)) return elt
;
640 /* Like Fassq but never report an error and do not allow quits.
641 Use only on lists known never to be circular. */
644 assq_no_quit (key
, list
)
645 register Lisp_Object key
;
648 register Lisp_Object tail
;
649 for (tail
= list
; CONSP (tail
); tail
= Fcdr (tail
))
651 register Lisp_Object elt
, tem
;
653 if (!CONSP (elt
)) continue;
655 if (EQ (key
, tem
)) return elt
;
660 DEFUN ("assoc", Fassoc
, Sassoc
, 2, 2, 0,
661 "Return non-nil if KEY is `equal' to the car of an element of LIST.\n\
662 The value is actually the element of LIST whose car equals KEY.")
664 register Lisp_Object key
;
667 register Lisp_Object tail
;
668 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
670 register Lisp_Object elt
, tem
;
672 if (!CONSP (elt
)) continue;
673 tem
= Fequal (Fcar (elt
), key
);
674 if (!NILP (tem
)) return elt
;
680 DEFUN ("rassq", Frassq
, Srassq
, 2, 2, 0,
681 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
682 The value is actually the element of LIST whose cdr is ELT.")
684 register Lisp_Object key
;
687 register Lisp_Object tail
;
688 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
690 register Lisp_Object elt
, tem
;
692 if (!CONSP (elt
)) continue;
694 if (EQ (key
, tem
)) return elt
;
700 DEFUN ("rassoc", Frassoc
, Srassoc
, 2, 2, 0,
701 "Return non-nil if KEY is `equal' to the cdr of an element of LIST.\n\
702 The value is actually the element of LIST whose cdr equals KEY.")
704 register Lisp_Object key
;
707 register Lisp_Object tail
;
708 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
710 register Lisp_Object elt
, tem
;
712 if (!CONSP (elt
)) continue;
713 tem
= Fequal (Fcdr (elt
), key
);
714 if (!NILP (tem
)) return elt
;
720 DEFUN ("delq", Fdelq
, Sdelq
, 2, 2, 0,
721 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
722 The modified LIST is returned. Comparison is done with `eq'.\n\
723 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
724 therefore, write `(setq foo (delq element foo))'\n\
725 to be sure of changing the value of `foo'.")
727 register Lisp_Object elt
;
730 register Lisp_Object tail
, prev
;
731 register Lisp_Object tem
;
743 Fsetcdr (prev
, Fcdr (tail
));
753 DEFUN ("delete", Fdelete
, Sdelete
, 2, 2, 0,
754 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
755 The modified LIST is returned. Comparison is done with `equal'.\n\
756 If the first member of LIST is ELT, deleting it is not a side effect;\n\
757 it is simply using a different list.\n\
758 Therefore, write `(setq foo (delete element foo))'\n\
759 to be sure of changing the value of `foo'.")
761 register Lisp_Object elt
;
764 register Lisp_Object tail
, prev
;
765 register Lisp_Object tem
;
772 if (! NILP (Fequal (elt
, tem
)))
777 Fsetcdr (prev
, Fcdr (tail
));
787 DEFUN ("nreverse", Fnreverse
, Snreverse
, 1, 1, 0,
788 "Reverse LIST by modifying cdr pointers.\n\
789 Returns the beginning of the reversed list.")
793 register Lisp_Object prev
, tail
, next
;
795 if (NILP (list
)) return list
;
802 Fsetcdr (tail
, prev
);
809 DEFUN ("reverse", Freverse
, Sreverse
, 1, 1, 0,
810 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
811 See also the function `nreverse', which is used more often.")
816 register Lisp_Object
*vec
;
817 register Lisp_Object tail
;
820 length
= Flength (list
);
821 vec
= (Lisp_Object
*) alloca (XINT (length
) * sizeof (Lisp_Object
));
822 for (i
= XINT (length
) - 1, tail
= list
; i
>= 0; i
--, tail
= Fcdr (tail
))
823 vec
[i
] = Fcar (tail
);
825 return Flist (XINT (length
), vec
);
828 Lisp_Object
merge ();
830 DEFUN ("sort", Fsort
, Ssort
, 2, 2, 0,
831 "Sort LIST, stably, comparing elements using PREDICATE.\n\
832 Returns the sorted list. LIST is modified by side effects.\n\
833 PREDICATE is called with two elements of LIST, and should return T\n\
834 if the first element is \"less\" than the second.")
836 Lisp_Object list
, pred
;
838 Lisp_Object front
, back
;
839 register Lisp_Object len
, tem
;
840 struct gcpro gcpro1
, gcpro2
;
844 len
= Flength (list
);
849 XSETINT (len
, (length
/ 2) - 1);
850 tem
= Fnthcdr (len
, list
);
854 GCPRO2 (front
, back
);
855 front
= Fsort (front
, pred
);
856 back
= Fsort (back
, pred
);
858 return merge (front
, back
, pred
);
862 merge (org_l1
, org_l2
, pred
)
863 Lisp_Object org_l1
, org_l2
;
867 register Lisp_Object tail
;
869 register Lisp_Object l1
, l2
;
870 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
877 /* It is sufficient to protect org_l1 and org_l2.
878 When l1 and l2 are updated, we copy the new values
879 back into the org_ vars. */
880 GCPRO4 (org_l1
, org_l2
, pred
, value
);
900 tem
= call2 (pred
, Fcar (l2
), Fcar (l1
));
922 DEFUN ("plist-get", Fplist_get
, Splist_get
, 2, 2, 0,
923 "Extract a value from a property list.\n\
924 PLIST is a property list, which is a list of the form\n\
925 \(PROP1 VALUE1 PROP2 VALUE2...). This function returns the value\n\
926 corresponding to the given PROP, or nil if PROP is not\n\
927 one of the properties on the list.")
930 register Lisp_Object prop
;
932 register Lisp_Object tail
;
933 for (tail
= val
; !NILP (tail
); tail
= Fcdr (Fcdr (tail
)))
935 register Lisp_Object tem
;
938 return Fcar (Fcdr (tail
));
943 DEFUN ("get", Fget
, Sget
, 2, 2, 0,
944 "Return the value of SYMBOL's PROPNAME property.\n\
945 This is the last value stored with `(put SYMBOL PROPNAME VALUE)'.")
947 Lisp_Object symbol
, propname
;
949 CHECK_SYMBOL (symbol
, 0);
950 return Fplist_get (XSYMBOL (symbol
)->plist
, propname
);
953 DEFUN ("plist-put", Fplist_put
, Splist_put
, 3, 3, 0,
954 "Change value in PLIST of PROP to VAL.\n\
955 PLIST is a property list, which is a list of the form\n\
956 \(PROP1 VALUE1 PROP2 VALUE2 ...). PROP is a symbol and VAL is any object.\n\
957 If PROP is already a property on the list, its value is set to VAL,\n\
958 otherwise the new PROP VAL pair is added. The new plist is returned;\n\
959 use `(setq x (plist-put x prop val))' to be sure to use the new value.\n\
960 The PLIST is modified by side effects.")
963 register Lisp_Object prop
;
966 register Lisp_Object tail
, prev
;
969 for (tail
= plist
; CONSP (tail
) && CONSP (XCONS (tail
)->cdr
);
970 tail
= XCONS (XCONS (tail
)->cdr
)->cdr
)
972 if (EQ (prop
, XCONS (tail
)->car
))
974 Fsetcar (XCONS (tail
)->cdr
, val
);
979 newcell
= Fcons (prop
, Fcons (val
, Qnil
));
983 Fsetcdr (XCONS (prev
)->cdr
, newcell
);
987 DEFUN ("put", Fput
, Sput
, 3, 3, 0,
988 "Store SYMBOL's PROPNAME property with value VALUE.\n\
989 It can be retrieved with `(get SYMBOL PROPNAME)'.")
990 (symbol
, propname
, value
)
991 Lisp_Object symbol
, propname
, value
;
993 CHECK_SYMBOL (symbol
, 0);
994 XSYMBOL (symbol
)->plist
995 = Fplist_put (XSYMBOL (symbol
)->plist
, propname
, value
);
999 DEFUN ("equal", Fequal
, Sequal
, 2, 2, 0,
1000 "T if two Lisp objects have similar structure and contents.\n\
1001 They must have the same data type.\n\
1002 Conses are compared by comparing the cars and the cdrs.\n\
1003 Vectors and strings are compared element by element.\n\
1004 Numbers are compared by value, but integers cannot equal floats.\n\
1005 (Use `=' if you want integers and floats to be able to be equal.)\n\
1006 Symbols must match exactly.")
1008 register Lisp_Object o1
, o2
;
1010 return internal_equal (o1
, o2
, 0) ? Qt
: Qnil
;
1014 internal_equal (o1
, o2
, depth
)
1015 register Lisp_Object o1
, o2
;
1019 error ("Stack overflow in equal");
1025 if (XTYPE (o1
) != XTYPE (o2
))
1030 #ifdef LISP_FLOAT_TYPE
1032 return (extract_float (o1
) == extract_float (o2
));
1036 if (!internal_equal (XCONS (o1
)->car
, XCONS (o2
)->car
, depth
+ 1))
1038 o1
= XCONS (o1
)->cdr
;
1039 o2
= XCONS (o2
)->cdr
;
1043 if (XMISCTYPE (o1
) != XMISCTYPE (o2
))
1047 if (!internal_equal (OVERLAY_START (o1
), OVERLAY_START (o1
),
1049 || !internal_equal (OVERLAY_END (o1
), OVERLAY_END (o1
),
1052 o1
= XOVERLAY (o1
)->plist
;
1053 o2
= XOVERLAY (o2
)->plist
;
1058 return (XMARKER (o1
)->buffer
== XMARKER (o2
)->buffer
1059 && (XMARKER (o1
)->buffer
== 0
1060 || XMARKER (o1
)->bufpos
== XMARKER (o2
)->bufpos
));
1064 case Lisp_Vectorlike
:
1066 register int i
, size
;
1067 size
= XVECTOR (o1
)->size
;
1068 /* Pseudovectors have the type encoded in the size field, so this test
1069 actually checks that the objects have the same type as well as the
1071 if (XVECTOR (o2
)->size
!= size
)
1073 /* Boolvectors are compared much like strings. */
1074 if (BOOL_VECTOR_P (o1
))
1077 = (XBOOL_VECTOR (o1
)->size
+ BITS_PER_CHAR
) / BITS_PER_CHAR
;
1079 if (XBOOL_VECTOR (o1
)->size
!= XBOOL_VECTOR (o2
)->size
)
1081 if (bcmp (XBOOL_VECTOR (o1
)->data
, XBOOL_VECTOR (o2
)->data
,
1087 /* Aside from them, only true vectors, char-tables, and compiled
1088 functions are sensible to compare, so eliminate the others now. */
1089 if (size
& PSEUDOVECTOR_FLAG
)
1091 if (!(size
& (PVEC_COMPILED
| PVEC_CHAR_TABLE
)))
1093 size
&= PSEUDOVECTOR_SIZE_MASK
;
1095 for (i
= 0; i
< size
; i
++)
1098 v1
= XVECTOR (o1
)->contents
[i
];
1099 v2
= XVECTOR (o2
)->contents
[i
];
1100 if (!internal_equal (v1
, v2
, depth
+ 1))
1108 if (XSTRING (o1
)->size
!= XSTRING (o2
)->size
)
1110 if (bcmp (XSTRING (o1
)->data
, XSTRING (o2
)->data
,
1111 XSTRING (o1
)->size
))
1113 #ifdef USE_TEXT_PROPERTIES
1114 /* If the strings have intervals, verify they match;
1115 if not, they are unequal. */
1116 if ((XSTRING (o1
)->intervals
!= 0 || XSTRING (o2
)->intervals
!= 0)
1117 && ! compare_string_intervals (o1
, o2
))
1125 DEFUN ("fillarray", Ffillarray
, Sfillarray
, 2, 2, 0,
1126 "Store each element of ARRAY with ITEM.\n\
1127 ARRAY is a vector, string, char-table, or bool-vector.")
1129 Lisp_Object array
, item
;
1131 register int size
, index
, charval
;
1133 if (VECTORP (array
))
1135 register Lisp_Object
*p
= XVECTOR (array
)->contents
;
1136 size
= XVECTOR (array
)->size
;
1137 for (index
= 0; index
< size
; index
++)
1140 else if (CHAR_TABLE_P (array
))
1142 register Lisp_Object
*p
= XCHAR_TABLE (array
)->contents
;
1143 size
= CHAR_TABLE_ORDINARY_SLOTS
;
1144 for (index
= 0; index
< size
; index
++)
1146 XCHAR_TABLE (array
)->defalt
= Qnil
;
1148 else if (STRINGP (array
))
1150 register unsigned char *p
= XSTRING (array
)->data
;
1151 CHECK_NUMBER (item
, 1);
1152 charval
= XINT (item
);
1153 size
= XSTRING (array
)->size
;
1154 for (index
= 0; index
< size
; index
++)
1157 else if (BOOL_VECTOR_P (array
))
1159 register unsigned char *p
= XBOOL_VECTOR (array
)->data
;
1161 = (XBOOL_VECTOR (array
)->size
+ BITS_PER_CHAR
) / BITS_PER_CHAR
;
1163 charval
= (! NILP (item
) ? -1 : 0);
1164 for (index
= 0; index
< size_in_chars
; index
++)
1169 array
= wrong_type_argument (Qarrayp
, array
);
1175 DEFUN ("char-table-subtype", Fchar_table_subtype
, Schar_table_subtype
,
1177 "Return the subtype of char-table CHAR-TABLE. The value is a symbol.")
1179 Lisp_Object chartable
;
1181 CHECK_CHAR_TABLE (chartable
, 0);
1183 return XCHAR_TABLE (chartable
)->purpose
;
1186 DEFUN ("char-table-parent", Fchar_table_parent
, Schar_table_parent
,
1188 "Return the parent char-table of CHAR-TABLE.\n\
1189 The value is either nil or another char-table.\n\
1190 If CHAR-TABLE holds nil for a given character,\n\
1191 then the actual applicable value is inherited from the parent char-table\n\
1192 \(or from its parents, if necessary).")
1194 Lisp_Object chartable
;
1196 CHECK_CHAR_TABLE (chartable
, 0);
1198 return XCHAR_TABLE (chartable
)->parent
;
1201 DEFUN ("set-char-table-parent", Fset_char_table_parent
, Sset_char_table_parent
,
1203 "Set the parent char-table of CHAR-TABLE to PARENT.\n\
1204 PARENT must be either nil or another char-table.")
1206 Lisp_Object chartable
, parent
;
1210 CHECK_CHAR_TABLE (chartable
, 0);
1214 CHECK_CHAR_TABLE (parent
, 0);
1216 for (temp
= parent
; !NILP (temp
); temp
= XCHAR_TABLE (temp
)->parent
)
1217 if (EQ (temp
, chartable
))
1218 error ("Attempt to make a chartable be its own parent");
1221 XCHAR_TABLE (chartable
)->parent
= parent
;
1226 DEFUN ("char-table-extra-slot", Fchar_table_extra_slot
, Schar_table_extra_slot
,
1228 "Return the value in extra-slot number N of char-table CHAR-TABLE.")
1230 Lisp_Object chartable
, n
;
1232 CHECK_CHAR_TABLE (chartable
, 1);
1233 CHECK_NUMBER (n
, 2);
1235 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (chartable
)))
1236 args_out_of_range (chartable
, n
);
1238 return XCHAR_TABLE (chartable
)->extras
[XINT (n
)];
1241 DEFUN ("set-char-table-extra-slot", Fset_char_table_extra_slot
,
1242 Sset_char_table_extra_slot
,
1244 "Set extra-slot number N of CHAR-TABLE to VALUE.")
1245 (chartable
, n
, value
)
1246 Lisp_Object chartable
, n
, value
;
1248 CHECK_CHAR_TABLE (chartable
, 1);
1249 CHECK_NUMBER (n
, 2);
1251 || XINT (n
) >= CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (chartable
)))
1252 args_out_of_range (chartable
, n
);
1254 return XCHAR_TABLE (chartable
)->extras
[XINT (n
)] = value
;
1257 DEFUN ("char-table-range", Fchar_table_range
, Schar_table_range
,
1259 "Return the value in CHARTABLE for a range of characters RANGE.\n\
1260 RANGE should be t (for all characters), nil (for the default value)\n\
1261 a vector which identifies a character set or a row of a character set,\n\
1262 or a character code.")
1264 Lisp_Object chartable
, range
;
1268 CHECK_CHAR_TABLE (chartable
, 0);
1270 if (EQ (range
, Qnil
))
1271 return XCHAR_TABLE (chartable
)->defalt
;
1272 else if (INTEGERP (range
))
1273 return Faref (chartable
, range
);
1274 else if (VECTORP (range
))
1276 for (i
= 0; i
< XVECTOR (range
)->size
- 1; i
++)
1277 chartable
= Faref (chartable
, XVECTOR (range
)->contents
[i
]);
1279 if (EQ (XVECTOR (range
)->contents
[i
], Qnil
))
1280 return XCHAR_TABLE (chartable
)->defalt
;
1282 return Faref (chartable
, XVECTOR (range
)->contents
[i
]);
1285 error ("Invalid RANGE argument to `char-table-range'");
1288 DEFUN ("set-char-table-range", Fset_char_table_range
, Sset_char_table_range
,
1290 "Set the value in CHARTABLE for a range of characters RANGE to VALUE.\n\
1291 RANGE should be t (for all characters), nil (for the default value)\n\
1292 a vector which identifies a character set or a row of a character set,\n\
1293 or a character code.")
1294 (chartable
, range
, value
)
1295 Lisp_Object chartable
, range
, value
;
1299 CHECK_CHAR_TABLE (chartable
, 0);
1302 for (i
= 0; i
< CHAR_TABLE_ORDINARY_SLOTS
; i
++)
1303 XCHAR_TABLE (chartable
)->contents
[i
] = value
;
1304 else if (EQ (range
, Qnil
))
1305 XCHAR_TABLE (chartable
)->defalt
= value
;
1306 else if (INTEGERP (range
))
1307 Faset (chartable
, range
, value
);
1308 else if (VECTORP (range
))
1310 for (i
= 0; i
< XVECTOR (range
)->size
- 1; i
++)
1311 chartable
= Faref (chartable
, XVECTOR (range
)->contents
[i
]);
1313 if (EQ (XVECTOR (range
)->contents
[i
], Qnil
))
1314 XCHAR_TABLE (chartable
)->defalt
= value
;
1316 Faset (chartable
, XVECTOR (range
)->contents
[i
], value
);
1319 error ("Invalid RANGE argument to `set-char-table-range'");
1324 /* Map C_FUNCTION or FUNCTION over CHARTABLE, calling it for each
1325 character or group of characters that share a value.
1326 DEPTH is the current depth in the originally specified
1327 chartable, and INDICES contains the vector indices
1328 for the levels our callers have descended. */
1331 map_char_table (c_function
, function
, chartable
, depth
, indices
)
1332 Lisp_Object (*c_function
) (), function
, chartable
, depth
, *indices
;
1335 int size
= CHAR_TABLE_ORDINARY_SLOTS
;
1337 /* Make INDICES longer if we are about to fill it up. */
1338 if ((depth
% 10) == 9)
1340 Lisp_Object
*new_indices
1341 = (Lisp_Object
*) alloca ((depth
+= 10) * sizeof (Lisp_Object
));
1342 bcopy (indices
, new_indices
, depth
* sizeof (Lisp_Object
));
1343 indices
= new_indices
;
1346 for (i
= 0; i
< size
; i
++)
1350 elt
= XCHAR_TABLE (chartable
)->contents
[i
];
1351 if (CHAR_TABLE_P (elt
))
1352 map_char_table (chartable
, c_function
, function
, depth
+ 1, indices
);
1353 else if (c_function
)
1354 (*c_function
) (depth
+ 1, indices
, elt
);
1355 /* Here we should handle all cases where the range is a single character
1356 by passing that character as a number. Currently, that is
1357 all the time, but with the MULE code this will have to be changed. */
1358 else if (depth
== 0)
1359 call2 (function
, make_number (i
), elt
);
1361 call2 (function
, Fvector (depth
+ 1, indices
), elt
);
1365 DEFUN ("map-char-table", Fmap_char_table
, Smap_char_table
,
1367 "Call FUNCTION for each range of like characters in CHARTABLE.\n\
1368 FUNCTION is called with two arguments--a key and a value.\n\
1369 The key is always a possible RANGE argument to `set-char-table-range'.")
1370 (function
, chartable
)
1371 Lisp_Object function
, chartable
;
1374 Lisp_Object
*indices
= (Lisp_Object
*) alloca (10 * sizeof (Lisp_Object
));
1376 map_char_table (NULL
, function
, chartable
, 0, indices
);
1386 Lisp_Object args
[2];
1389 return Fnconc (2, args
);
1391 return Fnconc (2, &s1
);
1392 #endif /* NO_ARG_ARRAY */
1395 DEFUN ("nconc", Fnconc
, Snconc
, 0, MANY
, 0,
1396 "Concatenate any number of lists by altering them.\n\
1397 Only the last argument is not altered, and need not be a list.")
1402 register int argnum
;
1403 register Lisp_Object tail
, tem
, val
;
1407 for (argnum
= 0; argnum
< nargs
; argnum
++)
1410 if (NILP (tem
)) continue;
1415 if (argnum
+ 1 == nargs
) break;
1418 tem
= wrong_type_argument (Qlistp
, tem
);
1427 tem
= args
[argnum
+ 1];
1428 Fsetcdr (tail
, tem
);
1430 args
[argnum
+ 1] = tail
;
1436 /* This is the guts of all mapping functions.
1437 Apply fn to each element of seq, one by one,
1438 storing the results into elements of vals, a C vector of Lisp_Objects.
1439 leni is the length of vals, which should also be the length of seq. */
1442 mapcar1 (leni
, vals
, fn
, seq
)
1445 Lisp_Object fn
, seq
;
1447 register Lisp_Object tail
;
1450 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1452 /* Don't let vals contain any garbage when GC happens. */
1453 for (i
= 0; i
< leni
; i
++)
1456 GCPRO3 (dummy
, fn
, seq
);
1458 gcpro1
.nvars
= leni
;
1459 /* We need not explicitly protect `tail' because it is used only on lists, and
1460 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
1464 for (i
= 0; i
< leni
; i
++)
1466 dummy
= XVECTOR (seq
)->contents
[i
];
1467 vals
[i
] = call1 (fn
, dummy
);
1470 else if (STRINGP (seq
))
1472 for (i
= 0; i
< leni
; i
++)
1474 XSETFASTINT (dummy
, XSTRING (seq
)->data
[i
]);
1475 vals
[i
] = call1 (fn
, dummy
);
1478 else /* Must be a list, since Flength did not get an error */
1481 for (i
= 0; i
< leni
; i
++)
1483 vals
[i
] = call1 (fn
, Fcar (tail
));
1491 DEFUN ("mapconcat", Fmapconcat
, Smapconcat
, 3, 3, 0,
1492 "Apply FN to each element of SEQ, and concat the results as strings.\n\
1493 In between each pair of results, stick in SEP.\n\
1494 Thus, \" \" as SEP results in spaces between the values returned by FN.")
1496 Lisp_Object fn
, seq
, sep
;
1501 register Lisp_Object
*args
;
1503 struct gcpro gcpro1
;
1505 len
= Flength (seq
);
1507 nargs
= leni
+ leni
- 1;
1508 if (nargs
< 0) return build_string ("");
1510 args
= (Lisp_Object
*) alloca (nargs
* sizeof (Lisp_Object
));
1513 mapcar1 (leni
, args
, fn
, seq
);
1516 for (i
= leni
- 1; i
>= 0; i
--)
1517 args
[i
+ i
] = args
[i
];
1519 for (i
= 1; i
< nargs
; i
+= 2)
1522 return Fconcat (nargs
, args
);
1525 DEFUN ("mapcar", Fmapcar
, Smapcar
, 2, 2, 0,
1526 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
1527 The result is a list just as long as SEQUENCE.\n\
1528 SEQUENCE may be a list, a vector or a string.")
1530 Lisp_Object fn
, seq
;
1532 register Lisp_Object len
;
1534 register Lisp_Object
*args
;
1536 len
= Flength (seq
);
1537 leni
= XFASTINT (len
);
1538 args
= (Lisp_Object
*) alloca (leni
* sizeof (Lisp_Object
));
1540 mapcar1 (leni
, args
, fn
, seq
);
1542 return Flist (leni
, args
);
1545 /* Anything that calls this function must protect from GC! */
1547 DEFUN ("y-or-n-p", Fy_or_n_p
, Sy_or_n_p
, 1, 1, 0,
1548 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
1549 Takes one argument, which is the string to display to ask the question.\n\
1550 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
1551 No confirmation of the answer is requested; a single character is enough.\n\
1552 Also accepts Space to mean yes, or Delete to mean no.")
1556 register Lisp_Object obj
, key
, def
, answer_string
, map
;
1557 register int answer
;
1558 Lisp_Object xprompt
;
1559 Lisp_Object args
[2];
1560 int ocech
= cursor_in_echo_area
;
1561 struct gcpro gcpro1
, gcpro2
;
1563 map
= Fsymbol_value (intern ("query-replace-map"));
1565 CHECK_STRING (prompt
, 0);
1567 GCPRO2 (prompt
, xprompt
);
1571 #if defined (HAVE_X_MENU) || defined (HAVE_NTGUI)
1572 if ((NILP (last_nonmenu_event
) || CONSP (last_nonmenu_event
))
1575 Lisp_Object pane
, menu
;
1576 redisplay_preserve_echo_area ();
1577 pane
= Fcons (Fcons (build_string ("Yes"), Qt
),
1578 Fcons (Fcons (build_string ("No"), Qnil
),
1580 menu
= Fcons (prompt
, pane
);
1581 obj
= Fx_popup_dialog (Qt
, menu
);
1582 answer
= !NILP (obj
);
1586 cursor_in_echo_area
= 1;
1587 message_nolog ("%s(y or n) ", XSTRING (xprompt
)->data
);
1589 obj
= read_filtered_event (1, 0, 0);
1590 cursor_in_echo_area
= 0;
1591 /* If we need to quit, quit with cursor_in_echo_area = 0. */
1594 key
= Fmake_vector (make_number (1), obj
);
1595 def
= Flookup_key (map
, key
);
1596 answer_string
= Fsingle_key_description (obj
);
1598 if (EQ (def
, intern ("skip")))
1603 else if (EQ (def
, intern ("act")))
1608 else if (EQ (def
, intern ("recenter")))
1614 else if (EQ (def
, intern ("quit")))
1616 /* We want to exit this command for exit-prefix,
1617 and this is the only way to do it. */
1618 else if (EQ (def
, intern ("exit-prefix")))
1623 /* If we don't clear this, then the next call to read_char will
1624 return quit_char again, and we'll enter an infinite loop. */
1629 if (EQ (xprompt
, prompt
))
1631 args
[0] = build_string ("Please answer y or n. ");
1633 xprompt
= Fconcat (2, args
);
1638 if (! noninteractive
)
1640 cursor_in_echo_area
= -1;
1641 message_nolog ("%s(y or n) %c",
1642 XSTRING (xprompt
)->data
, answer
? 'y' : 'n');
1643 cursor_in_echo_area
= ocech
;
1646 return answer
? Qt
: Qnil
;
1649 /* This is how C code calls `yes-or-no-p' and allows the user
1652 Anything that calls this function must protect from GC! */
1655 do_yes_or_no_p (prompt
)
1658 return call1 (intern ("yes-or-no-p"), prompt
);
1661 /* Anything that calls this function must protect from GC! */
1663 DEFUN ("yes-or-no-p", Fyes_or_no_p
, Syes_or_no_p
, 1, 1, 0,
1664 "Ask user a yes-or-no question. Return t if answer is yes.\n\
1665 Takes one argument, which is the string to display to ask the question.\n\
1666 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
1667 The user must confirm the answer with RET,\n\
1668 and can edit it until it has been confirmed.")
1672 register Lisp_Object ans
;
1673 Lisp_Object args
[2];
1674 struct gcpro gcpro1
;
1677 CHECK_STRING (prompt
, 0);
1679 #if defined (HAVE_X_MENU) || defined (HAVE_NTGUI)
1680 if ((NILP (last_nonmenu_event
) || CONSP (last_nonmenu_event
))
1683 Lisp_Object pane
, menu
, obj
;
1684 redisplay_preserve_echo_area ();
1685 pane
= Fcons (Fcons (build_string ("Yes"), Qt
),
1686 Fcons (Fcons (build_string ("No"), Qnil
),
1689 menu
= Fcons (prompt
, pane
);
1690 obj
= Fx_popup_dialog (Qt
, menu
);
1697 args
[1] = build_string ("(yes or no) ");
1698 prompt
= Fconcat (2, args
);
1704 ans
= Fdowncase (Fread_from_minibuffer (prompt
, Qnil
, Qnil
, Qnil
,
1705 Qyes_or_no_p_history
));
1706 if (XSTRING (ans
)->size
== 3 && !strcmp (XSTRING (ans
)->data
, "yes"))
1711 if (XSTRING (ans
)->size
== 2 && !strcmp (XSTRING (ans
)->data
, "no"))
1719 message ("Please answer yes or no.");
1720 Fsleep_for (make_number (2), Qnil
);
1724 DEFUN ("load-average", Fload_average
, Sload_average
, 0, 0, 0,
1725 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
1726 Each of the three load averages is multiplied by 100,\n\
1727 then converted to integer.\n\
1728 If the 5-minute or 15-minute load averages are not available, return a\n\
1729 shortened list, containing only those averages which are available.")
1733 int loads
= getloadavg (load_ave
, 3);
1737 error ("load-average not implemented for this operating system");
1741 ret
= Fcons (make_number ((int) (load_ave
[--loads
] * 100.0)), ret
);
1746 Lisp_Object Vfeatures
;
1748 DEFUN ("featurep", Ffeaturep
, Sfeaturep
, 1, 1, 0,
1749 "Returns t if FEATURE is present in this Emacs.\n\
1750 Use this to conditionalize execution of lisp code based on the presence or\n\
1751 absence of emacs or environment extensions.\n\
1752 Use `provide' to declare that a feature is available.\n\
1753 This function looks at the value of the variable `features'.")
1755 Lisp_Object feature
;
1757 register Lisp_Object tem
;
1758 CHECK_SYMBOL (feature
, 0);
1759 tem
= Fmemq (feature
, Vfeatures
);
1760 return (NILP (tem
)) ? Qnil
: Qt
;
1763 DEFUN ("provide", Fprovide
, Sprovide
, 1, 1, 0,
1764 "Announce that FEATURE is a feature of the current Emacs.")
1766 Lisp_Object feature
;
1768 register Lisp_Object tem
;
1769 CHECK_SYMBOL (feature
, 0);
1770 if (!NILP (Vautoload_queue
))
1771 Vautoload_queue
= Fcons (Fcons (Vfeatures
, Qnil
), Vautoload_queue
);
1772 tem
= Fmemq (feature
, Vfeatures
);
1774 Vfeatures
= Fcons (feature
, Vfeatures
);
1775 LOADHIST_ATTACH (Fcons (Qprovide
, feature
));
1779 DEFUN ("require", Frequire
, Srequire
, 1, 2, 0,
1780 "If feature FEATURE is not loaded, load it from FILENAME.\n\
1781 If FEATURE is not a member of the list `features', then the feature\n\
1782 is not loaded; so load the file FILENAME.\n\
1783 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
1784 (feature
, file_name
)
1785 Lisp_Object feature
, file_name
;
1787 register Lisp_Object tem
;
1788 CHECK_SYMBOL (feature
, 0);
1789 tem
= Fmemq (feature
, Vfeatures
);
1790 LOADHIST_ATTACH (Fcons (Qrequire
, feature
));
1793 int count
= specpdl_ptr
- specpdl
;
1795 /* Value saved here is to be restored into Vautoload_queue */
1796 record_unwind_protect (un_autoload
, Vautoload_queue
);
1797 Vautoload_queue
= Qt
;
1799 Fload (NILP (file_name
) ? Fsymbol_name (feature
) : file_name
,
1802 tem
= Fmemq (feature
, Vfeatures
);
1804 error ("Required feature %s was not provided",
1805 XSYMBOL (feature
)->name
->data
);
1807 /* Once loading finishes, don't undo it. */
1808 Vautoload_queue
= Qt
;
1809 feature
= unbind_to (count
, feature
);
1816 Qstring_lessp
= intern ("string-lessp");
1817 staticpro (&Qstring_lessp
);
1818 Qprovide
= intern ("provide");
1819 staticpro (&Qprovide
);
1820 Qrequire
= intern ("require");
1821 staticpro (&Qrequire
);
1822 Qyes_or_no_p_history
= intern ("yes-or-no-p-history");
1823 staticpro (&Qyes_or_no_p_history
);
1825 DEFVAR_LISP ("features", &Vfeatures
,
1826 "A list of symbols which are the features of the executing emacs.\n\
1827 Used by `featurep' and `require', and altered by `provide'.");
1830 defsubr (&Sidentity
);
1833 defsubr (&Ssafe_length
);
1834 defsubr (&Sstring_equal
);
1835 defsubr (&Sstring_lessp
);
1838 defsubr (&Svconcat
);
1839 defsubr (&Scopy_sequence
);
1840 defsubr (&Scopy_alist
);
1841 defsubr (&Ssubstring
);
1853 defsubr (&Snreverse
);
1854 defsubr (&Sreverse
);
1856 defsubr (&Splist_get
);
1858 defsubr (&Splist_put
);
1861 defsubr (&Sfillarray
);
1862 defsubr (&Schar_table_subtype
);
1863 defsubr (&Schar_table_parent
);
1864 defsubr (&Sset_char_table_parent
);
1865 defsubr (&Schar_table_extra_slot
);
1866 defsubr (&Sset_char_table_extra_slot
);
1867 defsubr (&Schar_table_range
);
1868 defsubr (&Sset_char_table_range
);
1869 defsubr (&Smap_char_table
);
1872 defsubr (&Smapconcat
);
1873 defsubr (&Sy_or_n_p
);
1874 defsubr (&Syes_or_no_p
);
1875 defsubr (&Sload_average
);
1876 defsubr (&Sfeaturep
);
1877 defsubr (&Srequire
);
1878 defsubr (&Sprovide
);