1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 1986, 1987, 1993 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 1, 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"
35 Lisp_Object Qstring_lessp
, Qprovide
, Qrequire
;
36 Lisp_Object Qyes_or_no_p_history
;
38 static Lisp_Object
internal_equal ();
40 DEFUN ("identity", Fidentity
, Sidentity
, 1, 1, 0,
41 "Return the argument unchanged.")
48 DEFUN ("random", Frandom
, Srandom
, 0, 1, 0,
49 "Return a pseudo-random number.\n\
50 On most systems all integers representable in Lisp are equally likely.\n\
51 This is 24 bits' worth.\n\
52 With argument N, return random number in interval [0,N).\n\
53 With argument t, set the random number seed from the current time and pid.")
58 extern long random ();
63 srandom (getpid () + time (0));
65 if (XTYPE (limit
) == Lisp_Int
&& XINT (limit
) != 0)
67 /* Try to take our random number from the higher bits of VAL,
68 not the lower, since (says Gentzel) the low bits of `random'
69 are less random than the higher ones. */
70 val
&= 0xfffffff; /* Ensure positive. */
72 if (XINT (limit
) < 10000)
76 return make_number (val
);
79 /* Random data-structure functions */
81 DEFUN ("length", Flength
, Slength
, 1, 1, 0,
82 "Return the length of vector, list or string SEQUENCE.\n\
83 A byte-code function object is also allowed.")
85 register Lisp_Object obj
;
87 register Lisp_Object tail
, val
;
91 if (XTYPE (obj
) == Lisp_Vector
|| XTYPE (obj
) == Lisp_String
92 || XTYPE (obj
) == Lisp_Compiled
)
93 return Farray_length (obj
);
96 for (i
= 0, tail
= obj
; !NILP(tail
); i
++)
112 obj
= wrong_type_argument (Qsequencep
, obj
);
117 DEFUN ("string-equal", Fstring_equal
, Sstring_equal
, 2, 2, 0,
118 "T if two strings have identical contents.\n\
119 Case is significant.\n\
120 Symbols are also allowed; their print names are used instead.")
122 register Lisp_Object s1
, s2
;
124 if (XTYPE (s1
) == Lisp_Symbol
)
125 XSETSTRING (s1
, XSYMBOL (s1
)->name
), XSETTYPE (s1
, Lisp_String
);
126 if (XTYPE (s2
) == Lisp_Symbol
)
127 XSETSTRING (s2
, XSYMBOL (s2
)->name
), XSETTYPE (s2
, Lisp_String
);
128 CHECK_STRING (s1
, 0);
129 CHECK_STRING (s2
, 1);
131 if (XSTRING (s1
)->size
!= XSTRING (s2
)->size
||
132 bcmp (XSTRING (s1
)->data
, XSTRING (s2
)->data
, XSTRING (s1
)->size
))
137 DEFUN ("string-lessp", Fstring_lessp
, Sstring_lessp
, 2, 2, 0,
138 "T if first arg string is less than second in lexicographic order.\n\
139 Case is significant.\n\
140 Symbols are also allowed; their print names are used instead.")
142 register Lisp_Object s1
, s2
;
145 register unsigned char *p1
, *p2
;
148 if (XTYPE (s1
) == Lisp_Symbol
)
149 XSETSTRING (s1
, XSYMBOL (s1
)->name
), XSETTYPE (s1
, Lisp_String
);
150 if (XTYPE (s2
) == Lisp_Symbol
)
151 XSETSTRING (s2
, XSYMBOL (s2
)->name
), XSETTYPE (s2
, Lisp_String
);
152 CHECK_STRING (s1
, 0);
153 CHECK_STRING (s2
, 1);
155 p1
= XSTRING (s1
)->data
;
156 p2
= XSTRING (s2
)->data
;
157 end
= XSTRING (s1
)->size
;
158 if (end
> XSTRING (s2
)->size
)
159 end
= XSTRING (s2
)->size
;
161 for (i
= 0; i
< end
; i
++)
164 return p1
[i
] < p2
[i
] ? Qt
: Qnil
;
166 return i
< XSTRING (s2
)->size
? Qt
: Qnil
;
169 static Lisp_Object
concat ();
180 return concat (2, args
, Lisp_String
, 0);
182 return concat (2, &s1
, Lisp_String
, 0);
183 #endif /* NO_ARG_ARRAY */
186 DEFUN ("append", Fappend
, Sappend
, 0, MANY
, 0,
187 "Concatenate all the arguments and make the result a list.\n\
188 The result is a list whose elements are the elements of all the arguments.\n\
189 Each argument may be a list, vector or string.\n\
190 The last argument is not copied, just used as the tail of the new list.")
195 return concat (nargs
, args
, Lisp_Cons
, 1);
198 DEFUN ("concat", Fconcat
, Sconcat
, 0, MANY
, 0,
199 "Concatenate all the arguments and make the result a string.\n\
200 The result is a string whose elements are the elements of all the arguments.\n\
201 Each argument may be a string, a list of numbers, or a vector of numbers.")
206 return concat (nargs
, args
, Lisp_String
, 0);
209 DEFUN ("vconcat", Fvconcat
, Svconcat
, 0, MANY
, 0,
210 "Concatenate all the arguments and make the result a vector.\n\
211 The result is a vector whose elements are the elements of all the arguments.\n\
212 Each argument may be a list, vector or string.")
217 return concat (nargs
, args
, Lisp_Vector
, 0);
220 DEFUN ("copy-sequence", Fcopy_sequence
, Scopy_sequence
, 1, 1, 0,
221 "Return a copy of a list, vector or string.\n\
222 The elements of a list or vector are not copied; they are shared\n\
227 if (NILP (arg
)) return arg
;
228 if (!CONSP (arg
) && XTYPE (arg
) != Lisp_Vector
&& XTYPE (arg
) != Lisp_String
)
229 arg
= wrong_type_argument (Qsequencep
, arg
);
230 return concat (1, &arg
, CONSP (arg
) ? Lisp_Cons
: XTYPE (arg
), 0);
234 concat (nargs
, args
, target_type
, last_special
)
237 enum Lisp_Type target_type
;
242 register Lisp_Object tail
;
243 register Lisp_Object
this;
247 Lisp_Object last_tail
;
250 /* In append, the last arg isn't treated like the others */
251 if (last_special
&& nargs
> 0)
254 last_tail
= args
[nargs
];
259 for (argnum
= 0; argnum
< nargs
; argnum
++)
262 if (!(CONSP (this) || NILP (this)
263 || XTYPE (this) == Lisp_Vector
|| XTYPE (this) == Lisp_String
264 || XTYPE (this) == Lisp_Compiled
))
266 if (XTYPE (this) == Lisp_Int
)
267 args
[argnum
] = Fnumber_to_string (this);
269 args
[argnum
] = wrong_type_argument (Qsequencep
, this);
273 for (argnum
= 0, leni
= 0; argnum
< nargs
; argnum
++)
276 len
= Flength (this);
277 leni
+= XFASTINT (len
);
280 XFASTINT (len
) = leni
;
282 if (target_type
== Lisp_Cons
)
283 val
= Fmake_list (len
, Qnil
);
284 else if (target_type
== Lisp_Vector
)
285 val
= Fmake_vector (len
, Qnil
);
287 val
= Fmake_string (len
, len
);
289 /* In append, if all but last arg are nil, return last arg */
290 if (target_type
== Lisp_Cons
&& EQ (val
, Qnil
))
294 tail
= val
, toindex
= -1; /* -1 in toindex is flag we are making a list */
300 for (argnum
= 0; argnum
< nargs
; argnum
++)
304 register int thisindex
= 0;
308 thislen
= Flength (this), thisleni
= XINT (thislen
);
310 if (XTYPE (this) == Lisp_String
&& XTYPE (val
) == Lisp_String
311 && ! NULL_INTERVAL_P (XSTRING (this)->intervals
))
313 copy_text_properties (make_number (0), thislen
, this,
314 make_number (toindex
), val
, Qnil
);
319 register Lisp_Object elt
;
321 /* Fetch next element of `this' arg into `elt', or break if
322 `this' is exhausted. */
323 if (NILP (this)) break;
325 elt
= Fcar (this), this = Fcdr (this);
328 if (thisindex
>= thisleni
) break;
329 if (XTYPE (this) == Lisp_String
)
330 XFASTINT (elt
) = XSTRING (this)->data
[thisindex
++];
332 elt
= XVECTOR (this)->contents
[thisindex
++];
335 /* Store into result */
338 XCONS (tail
)->car
= elt
;
340 tail
= XCONS (tail
)->cdr
;
342 else if (XTYPE (val
) == Lisp_Vector
)
343 XVECTOR (val
)->contents
[toindex
++] = elt
;
346 while (XTYPE (elt
) != Lisp_Int
)
347 elt
= wrong_type_argument (Qintegerp
, elt
);
349 #ifdef MASSC_REGISTER_BUG
350 /* Even removing all "register"s doesn't disable this bug!
351 Nothing simpler than this seems to work. */
352 unsigned char *p
= & XSTRING (val
)->data
[toindex
++];
355 XSTRING (val
)->data
[toindex
++] = XINT (elt
);
362 XCONS (prev
)->cdr
= last_tail
;
367 DEFUN ("copy-alist", Fcopy_alist
, Scopy_alist
, 1, 1, 0,
368 "Return a copy of ALIST.\n\
369 This is an alist which represents the same mapping from objects to objects,\n\
370 but does not share the alist structure with ALIST.\n\
371 The objects mapped (cars and cdrs of elements of the alist)\n\
372 are shared, however.\n\
373 Elements of ALIST that are not conses are also shared.")
377 register Lisp_Object tem
;
379 CHECK_LIST (alist
, 0);
382 alist
= concat (1, &alist
, Lisp_Cons
, 0);
383 for (tem
= alist
; CONSP (tem
); tem
= XCONS (tem
)->cdr
)
385 register Lisp_Object car
;
386 car
= XCONS (tem
)->car
;
389 XCONS (tem
)->car
= Fcons (XCONS (car
)->car
, XCONS (car
)->cdr
);
394 DEFUN ("substring", Fsubstring
, Ssubstring
, 2, 3, 0,
395 "Return a substring of STRING, starting at index FROM and ending before TO.\n\
396 TO may be nil or omitted; then the substring runs to the end of STRING.\n\
397 If FROM or TO is negative, it counts from the end.")
400 register Lisp_Object from
, to
;
404 CHECK_STRING (string
, 0);
405 CHECK_NUMBER (from
, 1);
407 to
= Flength (string
);
409 CHECK_NUMBER (to
, 2);
412 XSETINT (from
, XINT (from
) + XSTRING (string
)->size
);
414 XSETINT (to
, XINT (to
) + XSTRING (string
)->size
);
415 if (!(0 <= XINT (from
) && XINT (from
) <= XINT (to
)
416 && XINT (to
) <= XSTRING (string
)->size
))
417 args_out_of_range_3 (string
, from
, to
);
419 res
= make_string (XSTRING (string
)->data
+ XINT (from
),
420 XINT (to
) - XINT (from
));
421 copy_text_properties (from
, to
, string
, make_number (0), res
, Qnil
);
425 DEFUN ("nthcdr", Fnthcdr
, Snthcdr
, 2, 2, 0,
426 "Take cdr N times on LIST, returns the result.")
429 register Lisp_Object list
;
434 for (i
= 0; i
< num
&& !NILP (list
); i
++)
442 DEFUN ("nth", Fnth
, Snth
, 2, 2, 0,
443 "Return the Nth element of LIST.\n\
444 N counts from zero. If LIST is not that long, nil is returned.")
448 return Fcar (Fnthcdr (n
, list
));
451 DEFUN ("elt", Felt
, Selt
, 2, 2, 0,
452 "Return element of SEQUENCE at index N.")
454 register Lisp_Object seq
, n
;
459 if (XTYPE (seq
) == Lisp_Cons
|| NILP (seq
))
460 return Fcar (Fnthcdr (n
, seq
));
461 else if (XTYPE (seq
) == Lisp_String
462 || XTYPE (seq
) == Lisp_Vector
)
463 return Faref (seq
, n
);
465 seq
= wrong_type_argument (Qsequencep
, seq
);
469 DEFUN ("member", Fmember
, Smember
, 2, 2, 0,
470 "Return non-nil if ELT is an element of LIST. Comparison done with EQUAL.\n\
471 The value is actually the tail of LIST whose car is ELT.")
473 register Lisp_Object elt
;
476 register Lisp_Object tail
;
477 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
479 register Lisp_Object tem
;
481 if (! NILP (Fequal (elt
, tem
)))
488 DEFUN ("memq", Fmemq
, Smemq
, 2, 2, 0,
489 "Return non-nil if ELT is an element of LIST. Comparison done with EQ.\n\
490 The value is actually the tail of LIST whose car is ELT.")
492 register Lisp_Object elt
;
495 register Lisp_Object tail
;
496 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
498 register Lisp_Object tem
;
500 if (EQ (elt
, tem
)) return tail
;
506 DEFUN ("assq", Fassq
, Sassq
, 2, 2, 0,
507 "Return non-nil if ELT is `eq' to the car of an element of LIST.\n\
508 The value is actually the element of LIST whose car is ELT.\n\
509 Elements of LIST that are not conses are ignored.")
511 register Lisp_Object key
;
514 register Lisp_Object tail
;
515 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
517 register Lisp_Object elt
, tem
;
519 if (!CONSP (elt
)) continue;
521 if (EQ (key
, tem
)) return elt
;
527 /* Like Fassq but never report an error and do not allow quits.
528 Use only on lists known never to be circular. */
531 assq_no_quit (key
, list
)
532 register Lisp_Object key
;
535 register Lisp_Object tail
;
536 for (tail
= list
; CONSP (tail
); tail
= Fcdr (tail
))
538 register Lisp_Object elt
, tem
;
540 if (!CONSP (elt
)) continue;
542 if (EQ (key
, tem
)) return elt
;
547 DEFUN ("assoc", Fassoc
, Sassoc
, 2, 2, 0,
548 "Return non-nil if ELT is `equal' to the car of an element of LIST.\n\
549 The value is actually the element of LIST whose car is ELT.")
551 register Lisp_Object key
;
554 register Lisp_Object tail
;
555 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
557 register Lisp_Object elt
, tem
;
559 if (!CONSP (elt
)) continue;
560 tem
= Fequal (Fcar (elt
), key
);
561 if (!NILP (tem
)) return elt
;
567 DEFUN ("rassq", Frassq
, Srassq
, 2, 2, 0,
568 "Return non-nil if ELT is `eq' to the cdr of an element of LIST.\n\
569 The value is actually the element of LIST whose cdr is ELT.")
571 register Lisp_Object key
;
574 register Lisp_Object tail
;
575 for (tail
= list
; !NILP (tail
); tail
= Fcdr (tail
))
577 register Lisp_Object elt
, tem
;
579 if (!CONSP (elt
)) continue;
581 if (EQ (key
, tem
)) return elt
;
587 DEFUN ("delq", Fdelq
, Sdelq
, 2, 2, 0,
588 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
589 The modified LIST is returned. Comparison is done with `eq'.\n\
590 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
591 therefore, write `(setq foo (delq element foo))'\n\
592 to be sure of changing the value of `foo'.")
594 register Lisp_Object elt
;
597 register Lisp_Object tail
, prev
;
598 register Lisp_Object tem
;
610 Fsetcdr (prev
, Fcdr (tail
));
620 DEFUN ("delete", Fdelete
, Sdelete
, 2, 2, 0,
621 "Delete by side effect any occurrences of ELT as a member of LIST.\n\
622 The modified LIST is returned. Comparison is done with `equal'.\n\
623 If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
624 therefore, write `(setq foo (delete element foo))'\n\
625 to be sure of changing the value of `foo'.")
627 register Lisp_Object elt
;
630 register Lisp_Object tail
, prev
;
631 register Lisp_Object tem
;
638 if (! NILP (Fequal (elt
, tem
)))
643 Fsetcdr (prev
, Fcdr (tail
));
653 DEFUN ("nreverse", Fnreverse
, Snreverse
, 1, 1, 0,
654 "Reverse LIST by modifying cdr pointers.\n\
655 Returns the beginning of the reversed list.")
659 register Lisp_Object prev
, tail
, next
;
661 if (NILP (list
)) return list
;
668 Fsetcdr (tail
, prev
);
675 DEFUN ("reverse", Freverse
, Sreverse
, 1, 1, 0,
676 "Reverse LIST, copying. Returns the beginning of the reversed list.\n\
677 See also the function `nreverse', which is used more often.")
682 register Lisp_Object
*vec
;
683 register Lisp_Object tail
;
686 length
= Flength (list
);
687 vec
= (Lisp_Object
*) alloca (XINT (length
) * sizeof (Lisp_Object
));
688 for (i
= XINT (length
) - 1, tail
= list
; i
>= 0; i
--, tail
= Fcdr (tail
))
689 vec
[i
] = Fcar (tail
);
691 return Flist (XINT (length
), vec
);
694 Lisp_Object
merge ();
696 DEFUN ("sort", Fsort
, Ssort
, 2, 2, 0,
697 "Sort LIST, stably, comparing elements using PREDICATE.\n\
698 Returns the sorted list. LIST is modified by side effects.\n\
699 PREDICATE is called with two elements of LIST, and should return T\n\
700 if the first element is \"less\" than the second.")
702 Lisp_Object list
, pred
;
704 Lisp_Object front
, back
;
705 register Lisp_Object len
, tem
;
706 struct gcpro gcpro1
, gcpro2
;
710 len
= Flength (list
);
715 XSETINT (len
, (length
/ 2) - 1);
716 tem
= Fnthcdr (len
, list
);
720 GCPRO2 (front
, back
);
721 front
= Fsort (front
, pred
);
722 back
= Fsort (back
, pred
);
724 return merge (front
, back
, pred
);
728 merge (org_l1
, org_l2
, pred
)
729 Lisp_Object org_l1
, org_l2
;
733 register Lisp_Object tail
;
735 register Lisp_Object l1
, l2
;
736 struct gcpro gcpro1
, gcpro2
, gcpro3
, gcpro4
;
743 /* It is sufficient to protect org_l1 and org_l2.
744 When l1 and l2 are updated, we copy the new values
745 back into the org_ vars. */
746 GCPRO4 (org_l1
, org_l2
, pred
, value
);
766 tem
= call2 (pred
, Fcar (l2
), Fcar (l1
));
787 DEFUN ("get", Fget
, Sget
, 2, 2, 0,
788 "Return the value of SYMBOL's PROPNAME property.\n\
789 This is the last VALUE stored with `(put SYMBOL PROPNAME VALUE)'.")
792 register Lisp_Object prop
;
794 register Lisp_Object tail
;
795 for (tail
= Fsymbol_plist (sym
); !NILP (tail
); tail
= Fcdr (Fcdr (tail
)))
797 register Lisp_Object tem
;
800 return Fcar (Fcdr (tail
));
805 DEFUN ("put", Fput
, Sput
, 3, 3, 0,
806 "Store SYMBOL's PROPNAME property with value VALUE.\n\
807 It can be retrieved with `(get SYMBOL PROPNAME)'.")
810 register Lisp_Object prop
;
813 register Lisp_Object tail
, prev
;
816 for (tail
= Fsymbol_plist (sym
); !NILP (tail
); tail
= Fcdr (Fcdr (tail
)))
818 register Lisp_Object tem
;
821 return Fsetcar (Fcdr (tail
), val
);
824 newcell
= Fcons (prop
, Fcons (val
, Qnil
));
826 Fsetplist (sym
, newcell
);
828 Fsetcdr (Fcdr (prev
), newcell
);
832 DEFUN ("equal", Fequal
, Sequal
, 2, 2, 0,
833 "T if two Lisp objects have similar structure and contents.\n\
834 They must have the same data type.\n\
835 Conses are compared by comparing the cars and the cdrs.\n\
836 Vectors and strings are compared element by element.\n\
837 Numbers are compared by value, but integers cannot equal floats.\n\
838 (Use `=' if you want integers and floats to be able to be equal.)\n\
839 Symbols must match exactly.")
841 register Lisp_Object o1
, o2
;
843 return internal_equal (o1
, o2
, 0);
847 internal_equal (o1
, o2
, depth
)
848 register Lisp_Object o1
, o2
;
852 error ("Stack overflow in equal");
855 if (EQ (o1
, o2
)) return Qt
;
856 #ifdef LISP_FLOAT_TYPE
857 if (FLOATP (o1
) && FLOATP (o2
))
858 return (extract_float (o1
) == extract_float (o2
)) ? Qt
: Qnil
;
860 if (XTYPE (o1
) != XTYPE (o2
)) return Qnil
;
861 if (XTYPE (o1
) == Lisp_Cons
862 || XTYPE (o1
) == Lisp_Overlay
)
865 v1
= internal_equal (Fcar (o1
), Fcar (o2
), depth
+ 1);
868 o1
= Fcdr (o1
), o2
= Fcdr (o2
);
871 if (XTYPE (o1
) == Lisp_Marker
)
873 return ((XMARKER (o1
)->buffer
== XMARKER (o2
)->buffer
874 && (XMARKER (o1
)->buffer
== 0
875 || XMARKER (o1
)->bufpos
== XMARKER (o2
)->bufpos
))
878 if (XTYPE (o1
) == Lisp_Vector
879 || XTYPE (o1
) == Lisp_Compiled
)
882 if (XVECTOR (o1
)->size
!= XVECTOR (o2
)->size
)
884 for (index
= 0; index
< XVECTOR (o1
)->size
; index
++)
886 Lisp_Object v
, v1
, v2
;
887 v1
= XVECTOR (o1
)->contents
[index
];
888 v2
= XVECTOR (o2
)->contents
[index
];
889 v
= internal_equal (v1
, v2
, depth
+ 1);
890 if (NILP (v
)) return v
;
894 if (XTYPE (o1
) == Lisp_String
)
896 if (XSTRING (o1
)->size
!= XSTRING (o2
)->size
)
898 if (bcmp (XSTRING (o1
)->data
, XSTRING (o2
)->data
, XSTRING (o1
)->size
))
905 DEFUN ("fillarray", Ffillarray
, Sfillarray
, 2, 2, 0,
906 "Store each element of ARRAY with ITEM. ARRAY is a vector or string.")
908 Lisp_Object array
, item
;
910 register int size
, index
, charval
;
912 if (XTYPE (array
) == Lisp_Vector
)
914 register Lisp_Object
*p
= XVECTOR (array
)->contents
;
915 size
= XVECTOR (array
)->size
;
916 for (index
= 0; index
< size
; index
++)
919 else if (XTYPE (array
) == Lisp_String
)
921 register unsigned char *p
= XSTRING (array
)->data
;
922 CHECK_NUMBER (item
, 1);
923 charval
= XINT (item
);
924 size
= XSTRING (array
)->size
;
925 for (index
= 0; index
< size
; index
++)
930 array
= wrong_type_argument (Qarrayp
, array
);
945 return Fnconc (2, args
);
947 return Fnconc (2, &s1
);
948 #endif /* NO_ARG_ARRAY */
951 DEFUN ("nconc", Fnconc
, Snconc
, 0, MANY
, 0,
952 "Concatenate any number of lists by altering them.\n\
953 Only the last argument is not altered, and need not be a list.")
959 register Lisp_Object tail
, tem
, val
;
963 for (argnum
= 0; argnum
< nargs
; argnum
++)
966 if (NILP (tem
)) continue;
971 if (argnum
+ 1 == nargs
) break;
974 tem
= wrong_type_argument (Qlistp
, tem
);
983 tem
= args
[argnum
+ 1];
986 args
[argnum
+ 1] = tail
;
992 /* This is the guts of all mapping functions.
993 Apply fn to each element of seq, one by one,
994 storing the results into elements of vals, a C vector of Lisp_Objects.
995 leni is the length of vals, which should also be the length of seq. */
998 mapcar1 (leni
, vals
, fn
, seq
)
1001 Lisp_Object fn
, seq
;
1003 register Lisp_Object tail
;
1006 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1008 /* Don't let vals contain any garbage when GC happens. */
1009 for (i
= 0; i
< leni
; i
++)
1012 GCPRO3 (dummy
, fn
, seq
);
1014 gcpro1
.nvars
= leni
;
1015 /* We need not explicitly protect `tail' because it is used only on lists, and
1016 1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
1018 if (XTYPE (seq
) == Lisp_Vector
)
1020 for (i
= 0; i
< leni
; i
++)
1022 dummy
= XVECTOR (seq
)->contents
[i
];
1023 vals
[i
] = call1 (fn
, dummy
);
1026 else if (XTYPE (seq
) == Lisp_String
)
1028 for (i
= 0; i
< leni
; i
++)
1030 XFASTINT (dummy
) = XSTRING (seq
)->data
[i
];
1031 vals
[i
] = call1 (fn
, dummy
);
1034 else /* Must be a list, since Flength did not get an error */
1037 for (i
= 0; i
< leni
; i
++)
1039 vals
[i
] = call1 (fn
, Fcar (tail
));
1047 DEFUN ("mapconcat", Fmapconcat
, Smapconcat
, 3, 3, 0,
1048 "Apply FN to each element of SEQ, and concat the results as strings.\n\
1049 In between each pair of results, stick in SEP.\n\
1050 Thus, \" \" as SEP results in spaces between the values return by FN.")
1052 Lisp_Object fn
, seq
, sep
;
1057 register Lisp_Object
*args
;
1059 struct gcpro gcpro1
;
1061 len
= Flength (seq
);
1063 nargs
= leni
+ leni
- 1;
1064 if (nargs
< 0) return build_string ("");
1066 args
= (Lisp_Object
*) alloca (nargs
* sizeof (Lisp_Object
));
1069 mapcar1 (leni
, args
, fn
, seq
);
1072 for (i
= leni
- 1; i
>= 0; i
--)
1073 args
[i
+ i
] = args
[i
];
1075 for (i
= 1; i
< nargs
; i
+= 2)
1078 return Fconcat (nargs
, args
);
1081 DEFUN ("mapcar", Fmapcar
, Smapcar
, 2, 2, 0,
1082 "Apply FUNCTION to each element of SEQUENCE, and make a list of the results.\n\
1083 The result is a list just as long as SEQUENCE.\n\
1084 SEQUENCE may be a list, a vector or a string.")
1086 Lisp_Object fn
, seq
;
1088 register Lisp_Object len
;
1090 register Lisp_Object
*args
;
1092 len
= Flength (seq
);
1093 leni
= XFASTINT (len
);
1094 args
= (Lisp_Object
*) alloca (leni
* sizeof (Lisp_Object
));
1096 mapcar1 (leni
, args
, fn
, seq
);
1098 return Flist (leni
, args
);
1101 /* Anything that calls this function must protect from GC! */
1103 DEFUN ("y-or-n-p", Fy_or_n_p
, Sy_or_n_p
, 1, 1, 0,
1104 "Ask user a \"y or n\" question. Return t if answer is \"y\".\n\
1105 Takes one argument, which is the string to display to ask the question.\n\
1106 It should end in a space; `y-or-n-p' adds `(y or n) ' to it.\n\
1107 No confirmation of the answer is requested; a single character is enough.\n\
1108 Also accepts Space to mean yes, or Delete to mean no.")
1112 register Lisp_Object obj
, key
, def
, answer_string
, map
;
1113 register int answer
;
1114 Lisp_Object xprompt
;
1115 Lisp_Object args
[2];
1116 int ocech
= cursor_in_echo_area
;
1117 struct gcpro gcpro1
, gcpro2
;
1119 map
= Fsymbol_value (intern ("query-replace-map"));
1121 CHECK_STRING (prompt
, 0);
1123 GCPRO2 (prompt
, xprompt
);
1127 cursor_in_echo_area
= 1;
1128 message ("%s(y or n) ", XSTRING (xprompt
)->data
);
1130 obj
= read_filtered_event (1, 0, 0);
1131 cursor_in_echo_area
= 0;
1132 /* If we need to quit, quit with cursor_in_echo_area = 0. */
1135 key
= Fmake_vector (make_number (1), obj
);
1136 def
= Flookup_key (map
, key
);
1137 answer_string
= Fsingle_key_description (obj
);
1139 if (EQ (def
, intern ("skip")))
1144 else if (EQ (def
, intern ("act")))
1149 else if (EQ (def
, intern ("recenter")))
1155 else if (EQ (def
, intern ("quit")))
1160 /* If we don't clear this, then the next call to read_char will
1161 return quit_char again, and we'll enter an infinite loop. */
1166 if (EQ (xprompt
, prompt
))
1168 args
[0] = build_string ("Please answer y or n. ");
1170 xprompt
= Fconcat (2, args
);
1175 if (! noninteractive
)
1177 cursor_in_echo_area
= -1;
1178 message ("%s(y or n) %c", XSTRING (xprompt
)->data
, answer
? 'y' : 'n');
1179 cursor_in_echo_area
= ocech
;
1182 return answer
? Qt
: Qnil
;
1185 /* This is how C code calls `yes-or-no-p' and allows the user
1188 Anything that calls this function must protect from GC! */
1191 do_yes_or_no_p (prompt
)
1194 return call1 (intern ("yes-or-no-p"), prompt
);
1197 /* Anything that calls this function must protect from GC! */
1199 DEFUN ("yes-or-no-p", Fyes_or_no_p
, Syes_or_no_p
, 1, 1, 0,
1200 "Ask user a yes-or-no question. Return t if answer is yes.\n\
1201 Takes one argument, which is the string to display to ask the question.\n\
1202 It should end in a space; `yes-or-no-p' adds `(yes or no) ' to it.\n\
1203 The user must confirm the answer with RET,\n\
1204 and can edit it until it as been confirmed.")
1208 register Lisp_Object ans
;
1209 Lisp_Object args
[2];
1210 struct gcpro gcpro1
;
1212 CHECK_STRING (prompt
, 0);
1215 args
[1] = build_string ("(yes or no) ");
1216 prompt
= Fconcat (2, args
);
1221 ans
= Fdowncase (Fread_from_minibuffer (prompt
, Qnil
, Qnil
, Qnil
,
1222 Qyes_or_no_p_history
));
1223 if (XSTRING (ans
)->size
== 3 && !strcmp (XSTRING (ans
)->data
, "yes"))
1228 if (XSTRING (ans
)->size
== 2 && !strcmp (XSTRING (ans
)->data
, "no"))
1236 message ("Please answer yes or no.");
1237 Fsleep_for (make_number (2), Qnil
);
1241 DEFUN ("load-average", Fload_average
, Sload_average
, 0, 0, 0,
1242 "Return list of 1 minute, 5 minute and 15 minute load averages.\n\
1243 Each of the three load averages is multiplied by 100,\n\
1244 then converted to integer.\n\
1245 If the 5-minute or 15-minute load averages are not available, return a\n\
1246 shortened list, containing only those averages which are available.")
1250 int loads
= getloadavg (load_ave
, 3);
1254 error ("load-average not implemented for this operating system");
1258 ret
= Fcons (make_number ((int) (load_ave
[--loads
] * 100.0)), ret
);
1263 Lisp_Object Vfeatures
;
1265 DEFUN ("featurep", Ffeaturep
, Sfeaturep
, 1, 1, 0,
1266 "Returns t if FEATURE is present in this Emacs.\n\
1267 Use this to conditionalize execution of lisp code based on the presence or\n\
1268 absence of emacs or environment extensions.\n\
1269 Use `provide' to declare that a feature is available.\n\
1270 This function looks at the value of the variable `features'.")
1272 Lisp_Object feature
;
1274 register Lisp_Object tem
;
1275 CHECK_SYMBOL (feature
, 0);
1276 tem
= Fmemq (feature
, Vfeatures
);
1277 return (NILP (tem
)) ? Qnil
: Qt
;
1280 DEFUN ("provide", Fprovide
, Sprovide
, 1, 1, 0,
1281 "Announce that FEATURE is a feature of the current Emacs.")
1283 Lisp_Object feature
;
1285 register Lisp_Object tem
;
1286 CHECK_SYMBOL (feature
, 0);
1287 if (!NILP (Vautoload_queue
))
1288 Vautoload_queue
= Fcons (Fcons (Vfeatures
, Qnil
), Vautoload_queue
);
1289 tem
= Fmemq (feature
, Vfeatures
);
1291 Vfeatures
= Fcons (feature
, Vfeatures
);
1292 LOADHIST_ATTACH (Fcons (Qprovide
, feature
));
1296 DEFUN ("require", Frequire
, Srequire
, 1, 2, 0,
1297 "If feature FEATURE is not loaded, load it from FILENAME.\n\
1298 If FEATURE is not a member of the list `features', then the feature\n\
1299 is not loaded; so load the file FILENAME.\n\
1300 If FILENAME is omitted, the printname of FEATURE is used as the file name.")
1301 (feature
, file_name
)
1302 Lisp_Object feature
, file_name
;
1304 register Lisp_Object tem
;
1305 CHECK_SYMBOL (feature
, 0);
1306 tem
= Fmemq (feature
, Vfeatures
);
1307 LOADHIST_ATTACH (Fcons (Qrequire
, feature
));
1310 int count
= specpdl_ptr
- specpdl
;
1312 /* Value saved here is to be restored into Vautoload_queue */
1313 record_unwind_protect (un_autoload
, Vautoload_queue
);
1314 Vautoload_queue
= Qt
;
1316 Fload (NILP (file_name
) ? Fsymbol_name (feature
) : file_name
,
1319 tem
= Fmemq (feature
, Vfeatures
);
1321 error ("Required feature %s was not provided",
1322 XSYMBOL (feature
)->name
->data
);
1324 /* Once loading finishes, don't undo it. */
1325 Vautoload_queue
= Qt
;
1326 feature
= unbind_to (count
, feature
);
1333 Qstring_lessp
= intern ("string-lessp");
1334 staticpro (&Qstring_lessp
);
1335 Qprovide
= intern ("provide");
1336 staticpro (&Qprovide
);
1337 Qrequire
= intern ("require");
1338 staticpro (&Qrequire
);
1339 Qyes_or_no_p_history
= intern ("yes-or-no-p-history");
1340 staticpro (&Qyes_or_no_p_history
);
1342 DEFVAR_LISP ("features", &Vfeatures
,
1343 "A list of symbols which are the features of the executing emacs.\n\
1344 Used by `featurep' and `require', and altered by `provide'.");
1347 defsubr (&Sidentity
);
1350 defsubr (&Sstring_equal
);
1351 defsubr (&Sstring_lessp
);
1354 defsubr (&Svconcat
);
1355 defsubr (&Scopy_sequence
);
1356 defsubr (&Scopy_alist
);
1357 defsubr (&Ssubstring
);
1368 defsubr (&Snreverse
);
1369 defsubr (&Sreverse
);
1374 defsubr (&Sfillarray
);
1377 defsubr (&Smapconcat
);
1378 defsubr (&Sy_or_n_p
);
1379 defsubr (&Syes_or_no_p
);
1380 defsubr (&Sload_average
);
1381 defsubr (&Sfeaturep
);
1382 defsubr (&Srequire
);
1383 defsubr (&Sprovide
);