Since Qmenu_enable is used by non-X-specific code, it shouldn't be
[bpt/emacs.git] / src / data.c
CommitLineData
7921925c 1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
f58b3686 2 Copyright (C) 1985, 1986, 1988, 1992 Free Software Foundation, Inc.
7921925c
JB
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <signal.h>
22
23#include "config.h"
24#include "lisp.h"
29eab336 25#include "puresize.h"
7921925c
JB
26
27#ifndef standalone
28#include "buffer.h"
29#endif
30
a44804c2 31#include "syssignal.h"
fb8e9847 32
7921925c
JB
33#ifdef LISP_FLOAT_TYPE
34#include <math.h>
35#endif /* LISP_FLOAT_TYPE */
36
37Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound;
38Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
39Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
ffd56f97 40Lisp_Object Qvoid_variable, Qvoid_function, Qcyclic_function_indirection;
7921925c
JB
41Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
42Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
43Lisp_Object Qend_of_file, Qarith_error;
44Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
45Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qlistp, Qconsp;
46Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
47Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
07bd8472 48Lisp_Object Qbuffer_or_string_p;
7921925c
JB
49Lisp_Object Qboundp, Qfboundp;
50Lisp_Object Qcdr;
51
6315e761
RS
52Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
53Lisp_Object Qoverflow_error, Qunderflow_error;
54
7921925c 55#ifdef LISP_FLOAT_TYPE
464f8898 56Lisp_Object Qfloatp;
7921925c
JB
57Lisp_Object Qnumberp, Qnumber_or_marker_p;
58#endif
59
60static Lisp_Object swap_in_symval_forwarding ();
61
62Lisp_Object
63wrong_type_argument (predicate, value)
64 register Lisp_Object predicate, value;
65{
66 register Lisp_Object tem;
67 do
68 {
69 if (!EQ (Vmocklisp_arguments, Qt))
70 {
71 if (XTYPE (value) == Lisp_String &&
72 (EQ (predicate, Qintegerp) || EQ (predicate, Qinteger_or_marker_p)))
25e40a4b 73 return Fstring_to_number (value);
7921925c 74 if (XTYPE (value) == Lisp_Int && EQ (predicate, Qstringp))
f2980264 75 return Fnumber_to_string (value);
7921925c
JB
76 }
77 value = Fsignal (Qwrong_type_argument, Fcons (predicate, Fcons (value, Qnil)));
78 tem = call1 (predicate, value);
79 }
a33ef3ab 80 while (NILP (tem));
7921925c
JB
81 return value;
82}
83
84pure_write_error ()
85{
86 error ("Attempt to modify read-only object");
87}
88
89void
90args_out_of_range (a1, a2)
91 Lisp_Object a1, a2;
92{
93 while (1)
94 Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Qnil)));
95}
96
97void
98args_out_of_range_3 (a1, a2, a3)
99 Lisp_Object a1, a2, a3;
100{
101 while (1)
102 Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Fcons (a3, Qnil))));
103}
104
105Lisp_Object
106make_number (num)
107 int num;
108{
109 register Lisp_Object val;
110 XSET (val, Lisp_Int, num);
111 return val;
112}
113
114/* On some machines, XINT needs a temporary location.
115 Here it is, in case it is needed. */
116
117int sign_extend_temp;
118
119/* On a few machines, XINT can only be done by calling this. */
120
121int
122sign_extend_lisp_int (num)
123 int num;
124{
125 if (num & (1 << (VALBITS - 1)))
126 return num | ((-1) << VALBITS);
127 else
128 return num & ((1 << VALBITS) - 1);
129}
130\f
131/* Data type predicates */
132
133DEFUN ("eq", Feq, Seq, 2, 2, 0,
134 "T if the two args are the same Lisp object.")
135 (obj1, obj2)
136 Lisp_Object obj1, obj2;
137{
138 if (EQ (obj1, obj2))
139 return Qt;
140 return Qnil;
141}
142
143DEFUN ("null", Fnull, Snull, 1, 1, 0, "T if OBJECT is nil.")
144 (obj)
145 Lisp_Object obj;
146{
a33ef3ab 147 if (NILP (obj))
7921925c
JB
148 return Qt;
149 return Qnil;
150}
151
152DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, "T if OBJECT is a cons cell.")
153 (obj)
154 Lisp_Object obj;
155{
156 if (XTYPE (obj) == Lisp_Cons)
157 return Qt;
158 return Qnil;
159}
160
161DEFUN ("atom", Fatom, Satom, 1, 1, 0, "T if OBJECT is not a cons cell. This includes nil.")
162 (obj)
163 Lisp_Object obj;
164{
165 if (XTYPE (obj) == Lisp_Cons)
166 return Qnil;
167 return Qt;
168}
169
170DEFUN ("listp", Flistp, Slistp, 1, 1, 0, "T if OBJECT is a list. This includes nil.")
171 (obj)
172 Lisp_Object obj;
173{
a33ef3ab 174 if (XTYPE (obj) == Lisp_Cons || NILP (obj))
7921925c
JB
175 return Qt;
176 return Qnil;
177}
178
179DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, "T if OBJECT is not a list. Lists include nil.")
180 (obj)
181 Lisp_Object obj;
182{
a33ef3ab 183 if (XTYPE (obj) == Lisp_Cons || NILP (obj))
7921925c
JB
184 return Qnil;
185 return Qt;
186}
187\f
188DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0, "T if OBJECT is a symbol.")
189 (obj)
190 Lisp_Object obj;
191{
192 if (XTYPE (obj) == Lisp_Symbol)
193 return Qt;
194 return Qnil;
195}
196
197DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0, "T if OBJECT is a vector.")
198 (obj)
199 Lisp_Object obj;
200{
201 if (XTYPE (obj) == Lisp_Vector)
202 return Qt;
203 return Qnil;
204}
205
206DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, "T if OBJECT is a string.")
207 (obj)
208 Lisp_Object obj;
209{
210 if (XTYPE (obj) == Lisp_String)
211 return Qt;
212 return Qnil;
213}
214
215DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0, "T if OBJECT is an array (string or vector).")
216 (obj)
217 Lisp_Object obj;
218{
219 if (XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
220 return Qt;
221 return Qnil;
222}
223
224DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0,
225 "T if OBJECT is a sequence (list or array).")
226 (obj)
227 register Lisp_Object obj;
228{
a33ef3ab 229 if (CONSP (obj) || NILP (obj) ||
7921925c
JB
230 XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
231 return Qt;
232 return Qnil;
233}
234
235DEFUN ("bufferp", Fbufferp, Sbufferp, 1, 1, 0, "T if OBJECT is an editor buffer.")
236 (obj)
237 Lisp_Object obj;
238{
239 if (XTYPE (obj) == Lisp_Buffer)
240 return Qt;
241 return Qnil;
242}
243
244DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0, "T if OBJECT is a marker (editor pointer).")
245 (obj)
246 Lisp_Object obj;
247{
248 if (XTYPE (obj) == Lisp_Marker)
249 return Qt;
250 return Qnil;
251}
252
7921925c
JB
253DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0, "T if OBJECT is a built-in function.")
254 (obj)
255 Lisp_Object obj;
256{
257 if (XTYPE (obj) == Lisp_Subr)
258 return Qt;
259 return Qnil;
260}
261
dbc4e1c1
JB
262DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
263 1, 1, 0, "T if OBJECT is a byte-compiled function object.")
7921925c
JB
264 (obj)
265 Lisp_Object obj;
266{
267 if (XTYPE (obj) == Lisp_Compiled)
268 return Qt;
269 return Qnil;
270}
271
272DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0, "T if OBJECT is a character (a number) or a string.")
273 (obj)
274 register Lisp_Object obj;
275{
276 if (XTYPE (obj) == Lisp_Int || XTYPE (obj) == Lisp_String)
277 return Qt;
278 return Qnil;
279}
280\f
281DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0, "T if OBJECT is a number.")
282 (obj)
283 Lisp_Object obj;
284{
285 if (XTYPE (obj) == Lisp_Int)
286 return Qt;
287 return Qnil;
288}
289
464f8898
RS
290DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0,
291 "T if OBJECT is an integer or a marker (editor pointer).")
7921925c 292 (obj)
464f8898 293 register Lisp_Object obj;
7921925c 294{
464f8898 295 if (XTYPE (obj) == Lisp_Marker || XTYPE (obj) == Lisp_Int)
7921925c
JB
296 return Qt;
297 return Qnil;
298}
299
464f8898 300DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0, "T if OBJECT is a nonnegative number.")
7921925c
JB
301 (obj)
302 Lisp_Object obj;
303{
464f8898 304 if (XTYPE (obj) == Lisp_Int && XINT (obj) >= 0)
7921925c
JB
305 return Qt;
306 return Qnil;
307}
308
309DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
310 "T if OBJECT is a number (floating point or integer).")
311 (obj)
312 Lisp_Object obj;
313{
dbc4e1c1 314 if (NUMBERP (obj))
7921925c 315 return Qt;
dbc4e1c1
JB
316 else
317 return Qnil;
7921925c
JB
318}
319
320DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
321 Snumber_or_marker_p, 1, 1, 0,
322 "T if OBJECT is a number or a marker.")
323 (obj)
324 Lisp_Object obj;
325{
dbc4e1c1 326 if (NUMBERP (obj)
7921925c
JB
327 || XTYPE (obj) == Lisp_Marker)
328 return Qt;
329 return Qnil;
330}
464f8898
RS
331
332#ifdef LISP_FLOAT_TYPE
333DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
334 "T if OBJECT is a floating point number.")
335 (obj)
336 Lisp_Object obj;
337{
338 if (XTYPE (obj) == Lisp_Float)
339 return Qt;
340 return Qnil;
341}
7921925c
JB
342#endif /* LISP_FLOAT_TYPE */
343\f
344/* Extract and set components of lists */
345
346DEFUN ("car", Fcar, Scar, 1, 1, 0,
347 "Return the car of CONSCELL. If arg is nil, return nil.\n\
348Error if arg is not nil and not a cons cell. See also `car-safe'.")
349 (list)
350 register Lisp_Object list;
351{
352 while (1)
353 {
354 if (XTYPE (list) == Lisp_Cons)
355 return XCONS (list)->car;
356 else if (EQ (list, Qnil))
357 return Qnil;
358 else
359 list = wrong_type_argument (Qlistp, list);
360 }
361}
362
363DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
364 "Return the car of OBJECT if it is a cons cell, or else nil.")
365 (object)
366 Lisp_Object object;
367{
368 if (XTYPE (object) == Lisp_Cons)
369 return XCONS (object)->car;
370 else
371 return Qnil;
372}
373
374DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
375 "Return the cdr of CONSCELL. If arg is nil, return nil.\n\
376Error if arg is not nil and not a cons cell. See also `cdr-safe'.")
377
378 (list)
379 register Lisp_Object list;
380{
381 while (1)
382 {
383 if (XTYPE (list) == Lisp_Cons)
384 return XCONS (list)->cdr;
385 else if (EQ (list, Qnil))
386 return Qnil;
387 else
388 list = wrong_type_argument (Qlistp, list);
389 }
390}
391
392DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
393 "Return the cdr of OBJECT if it is a cons cell, or else nil.")
394 (object)
395 Lisp_Object object;
396{
397 if (XTYPE (object) == Lisp_Cons)
398 return XCONS (object)->cdr;
399 else
400 return Qnil;
401}
402
403DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
404 "Set the car of CONSCELL to be NEWCAR. Returns NEWCAR.")
405 (cell, newcar)
406 register Lisp_Object cell, newcar;
407{
408 if (XTYPE (cell) != Lisp_Cons)
409 cell = wrong_type_argument (Qconsp, cell);
410
411 CHECK_IMPURE (cell);
412 XCONS (cell)->car = newcar;
413 return newcar;
414}
415
416DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
417 "Set the cdr of CONSCELL to be NEWCDR. Returns NEWCDR.")
418 (cell, newcdr)
419 register Lisp_Object cell, newcdr;
420{
421 if (XTYPE (cell) != Lisp_Cons)
422 cell = wrong_type_argument (Qconsp, cell);
423
424 CHECK_IMPURE (cell);
425 XCONS (cell)->cdr = newcdr;
426 return newcdr;
427}
428\f
429/* Extract and set components of symbols */
430
431DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, "T if SYMBOL's value is not void.")
432 (sym)
433 register Lisp_Object sym;
434{
435 Lisp_Object valcontents;
436 CHECK_SYMBOL (sym, 0);
437
438 valcontents = XSYMBOL (sym)->value;
439
440#ifdef SWITCH_ENUM_BUG
441 switch ((int) XTYPE (valcontents))
442#else
443 switch (XTYPE (valcontents))
444#endif
445 {
446 case Lisp_Buffer_Local_Value:
447 case Lisp_Some_Buffer_Local_Value:
448 valcontents = swap_in_symval_forwarding (sym, valcontents);
449 }
450
451 return (XTYPE (valcontents) == Lisp_Void || EQ (valcontents, Qunbound)
452 ? Qnil : Qt);
453}
454
455DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, "T if SYMBOL's function definition is not void.")
456 (sym)
457 register Lisp_Object sym;
458{
459 CHECK_SYMBOL (sym, 0);
460 return (XTYPE (XSYMBOL (sym)->function) == Lisp_Void
461 || EQ (XSYMBOL (sym)->function, Qunbound))
462 ? Qnil : Qt;
463}
464
465DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, "Make SYMBOL's value be void.")
466 (sym)
467 register Lisp_Object sym;
468{
469 CHECK_SYMBOL (sym, 0);
a33ef3ab 470 if (NILP (sym) || EQ (sym, Qt))
7921925c
JB
471 return Fsignal (Qsetting_constant, Fcons (sym, Qnil));
472 Fset (sym, Qunbound);
473 return sym;
474}
475
476DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0, "Make SYMBOL's function definition be void.")
477 (sym)
478 register Lisp_Object sym;
479{
480 CHECK_SYMBOL (sym, 0);
481 XSYMBOL (sym)->function = Qunbound;
482 return sym;
483}
484
485DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
486 "Return SYMBOL's function definition. Error if that is void.")
ffd56f97
JB
487 (symbol)
488 register Lisp_Object symbol;
7921925c 489{
ffd56f97
JB
490 CHECK_SYMBOL (symbol, 0);
491 if (EQ (XSYMBOL (symbol)->function, Qunbound))
492 return Fsignal (Qvoid_function, Fcons (symbol, Qnil));
493 return XSYMBOL (symbol)->function;
7921925c
JB
494}
495
496DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, "Return SYMBOL's property list.")
497 (sym)
498 register Lisp_Object sym;
499{
500 CHECK_SYMBOL (sym, 0);
501 return XSYMBOL (sym)->plist;
502}
503
504DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, "Return SYMBOL's name, a string.")
505 (sym)
506 register Lisp_Object sym;
507{
508 register Lisp_Object name;
509
510 CHECK_SYMBOL (sym, 0);
511 XSET (name, Lisp_String, XSYMBOL (sym)->name);
512 return name;
513}
514
515DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
516 "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.")
517 (sym, newdef)
518 register Lisp_Object sym, newdef;
519{
520 CHECK_SYMBOL (sym, 0);
a33ef3ab 521 if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound))
7921925c
JB
522 Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function),
523 Vautoload_queue);
524 XSYMBOL (sym)->function = newdef;
525 return newdef;
526}
527
528DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0,
529 "Set SYMBOL's property list to NEWVAL, and return NEWVAL.")
530 (sym, newplist)
531 register Lisp_Object sym, newplist;
532{
533 CHECK_SYMBOL (sym, 0);
534 XSYMBOL (sym)->plist = newplist;
535 return newplist;
536}
ffd56f97 537
7921925c
JB
538\f
539/* Getting and setting values of symbols */
540
541/* Given the raw contents of a symbol value cell,
542 return the Lisp value of the symbol.
543 This does not handle buffer-local variables; use
544 swap_in_symval_forwarding for that. */
545
546Lisp_Object
547do_symval_forwarding (valcontents)
548 register Lisp_Object valcontents;
549{
550 register Lisp_Object val;
551#ifdef SWITCH_ENUM_BUG
552 switch ((int) XTYPE (valcontents))
553#else
554 switch (XTYPE (valcontents))
555#endif
556 {
557 case Lisp_Intfwd:
558 XSET (val, Lisp_Int, *XINTPTR (valcontents));
559 return val;
560
561 case Lisp_Boolfwd:
562 if (*XINTPTR (valcontents))
563 return Qt;
564 return Qnil;
565
566 case Lisp_Objfwd:
567 return *XOBJFWD (valcontents);
568
569 case Lisp_Buffer_Objfwd:
570 return *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer);
571 }
572 return valcontents;
573}
574
575/* Store NEWVAL into SYM, where VALCONTENTS is found in the value cell
576 of SYM. If SYM is buffer-local, VALCONTENTS should be the
577 buffer-independent contents of the value cell: forwarded just one
578 step past the buffer-localness. */
579
580void
581store_symval_forwarding (sym, valcontents, newval)
582 Lisp_Object sym;
583 register Lisp_Object valcontents, newval;
584{
585#ifdef SWITCH_ENUM_BUG
586 switch ((int) XTYPE (valcontents))
587#else
588 switch (XTYPE (valcontents))
589#endif
590 {
591 case Lisp_Intfwd:
592 CHECK_NUMBER (newval, 1);
593 *XINTPTR (valcontents) = XINT (newval);
594 break;
595
596 case Lisp_Boolfwd:
a33ef3ab 597 *XINTPTR (valcontents) = NILP(newval) ? 0 : 1;
7921925c
JB
598 break;
599
600 case Lisp_Objfwd:
601 *XOBJFWD (valcontents) = newval;
602 break;
603
604 case Lisp_Buffer_Objfwd:
bc540f9f
JB
605 {
606 unsigned int offset = XUINT (valcontents);
607 Lisp_Object type =
608 *(Lisp_Object *)(offset + (char *)&buffer_local_types);
609
610 if (! NILP (type) && ! NILP (newval)
611 && XTYPE (newval) != XINT (type))
612 buffer_slot_type_mismatch (valcontents, newval);
613
614 *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer)
615 = newval;
616 break;
617 }
7921925c
JB
618
619 default:
620 valcontents = XSYMBOL (sym)->value;
621 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
622 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
623 XCONS (XSYMBOL (sym)->value)->car = newval;
624 else
625 XSYMBOL (sym)->value = newval;
626 }
627}
628
629/* Set up the buffer-local symbol SYM for validity in the current
630 buffer. VALCONTENTS is the contents of its value cell.
631 Return the value forwarded one step past the buffer-local indicator. */
632
633static Lisp_Object
634swap_in_symval_forwarding (sym, valcontents)
635 Lisp_Object sym, valcontents;
636{
637 /* valcontents is a list
638 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE)).
639
640 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
533984a8
JB
641 local_var_alist, that being the element whose car is this
642 variable. Or it can be a pointer to the
643 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not have
644 an element in its alist for this variable.
645
646 If the current buffer is not BUFFER, we store the current
647 REALVALUE value into CURRENT-ALIST-ELEMENT, then find the
648 appropriate alist element for the buffer now current and set up
649 CURRENT-ALIST-ELEMENT. Then we set REALVALUE out of that
650 element, and store into BUFFER.
651
7921925c
JB
652 Note that REALVALUE can be a forwarding pointer. */
653
654 register Lisp_Object tem1;
655 tem1 = XCONS (XCONS (valcontents)->cdr)->car;
656
a33ef3ab 657 if (NILP (tem1) || current_buffer != XBUFFER (tem1))
7921925c
JB
658 {
659 tem1 = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
660 Fsetcdr (tem1, do_symval_forwarding (XCONS (valcontents)->car));
661 tem1 = assq_no_quit (sym, current_buffer->local_var_alist);
a33ef3ab 662 if (NILP (tem1))
7921925c
JB
663 tem1 = XCONS (XCONS (valcontents)->cdr)->cdr;
664 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car = tem1;
665 XSET (XCONS (XCONS (valcontents)->cdr)->car, Lisp_Buffer, current_buffer);
666 store_symval_forwarding (sym, XCONS (valcontents)->car, Fcdr (tem1));
667 }
668 return XCONS (valcontents)->car;
669}
670\f
14e76af9
JB
671/* Find the value of a symbol, returning Qunbound if it's not bound.
672 This is helpful for code which just wants to get a variable's value
673 if it has one, without signalling an error.
674 Note that it must not be possible to quit
675 within this function. Great care is required for this. */
7921925c 676
14e76af9
JB
677Lisp_Object
678find_symbol_value (sym)
7921925c
JB
679 Lisp_Object sym;
680{
681 register Lisp_Object valcontents, tem1;
682 register Lisp_Object val;
683 CHECK_SYMBOL (sym, 0);
684 valcontents = XSYMBOL (sym)->value;
685
686 retry:
687#ifdef SWITCH_ENUM_BUG
688 switch ((int) XTYPE (valcontents))
689#else
690 switch (XTYPE (valcontents))
691#endif
692 {
693 case Lisp_Buffer_Local_Value:
694 case Lisp_Some_Buffer_Local_Value:
695 valcontents = swap_in_symval_forwarding (sym, valcontents);
696 goto retry;
697
698 case Lisp_Intfwd:
699 XSET (val, Lisp_Int, *XINTPTR (valcontents));
700 return val;
701
702 case Lisp_Boolfwd:
703 if (*XINTPTR (valcontents))
704 return Qt;
705 return Qnil;
706
707 case Lisp_Objfwd:
708 return *XOBJFWD (valcontents);
709
710 case Lisp_Buffer_Objfwd:
711 return *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer);
712
7921925c 713 case Lisp_Void:
14e76af9 714 return Qunbound;
7921925c
JB
715 }
716
717 return valcontents;
718}
719
14e76af9
JB
720DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
721 "Return SYMBOL's value. Error if that is void.")
722 (sym)
723 Lisp_Object sym;
724{
725 Lisp_Object val = find_symbol_value (sym);
726
727 if (EQ (val, Qunbound))
728 return Fsignal (Qvoid_variable, Fcons (sym, Qnil));
729 else
730 return val;
731}
732
7921925c
JB
733DEFUN ("set", Fset, Sset, 2, 2, 0,
734 "Set SYMBOL's value to NEWVAL, and return NEWVAL.")
735 (sym, newval)
736 register Lisp_Object sym, newval;
737{
738 int voide = (XTYPE (newval) == Lisp_Void || EQ (newval, Qunbound));
739
740#ifndef RTPC_REGISTER_BUG
741 register Lisp_Object valcontents, tem1, current_alist_element;
742#else /* RTPC_REGISTER_BUG */
743 register Lisp_Object tem1;
744 Lisp_Object valcontents, current_alist_element;
745#endif /* RTPC_REGISTER_BUG */
746
747 CHECK_SYMBOL (sym, 0);
a33ef3ab 748 if (NILP (sym) || EQ (sym, Qt))
7921925c
JB
749 return Fsignal (Qsetting_constant, Fcons (sym, Qnil));
750 valcontents = XSYMBOL (sym)->value;
751
752 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
753 {
754 register int idx = XUINT (valcontents);
755 register int mask = *(int *)(idx + (char *) &buffer_local_flags);
756 if (mask > 0)
757 current_buffer->local_var_flags |= mask;
758 }
759
d8cafeb5
JB
760 else if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
761 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
7921925c 762 {
d8cafeb5
JB
763 /* valcontents is actually a pointer to a cons heading something like:
764 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE).
765
766 BUFFER is the last buffer for which this symbol's value was
767 made up to date.
768
769 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
770 local_var_alist, that being the element whose car is this
771 variable. Or it can be a pointer to the
772 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not
773 have an element in its alist for this variable (that is, if
774 BUFFER sees the default value of this variable).
775
776 If we want to examine or set the value and BUFFER is current,
777 we just examine or set REALVALUE. If BUFFER is not current, we
778 store the current REALVALUE value into CURRENT-ALIST-ELEMENT,
779 then find the appropriate alist element for the buffer now
780 current and set up CURRENT-ALIST-ELEMENT. Then we set
781 REALVALUE out of that element, and store into BUFFER.
782
783 If we are setting the variable and the current buffer does
784 not have an alist entry for this variable, an alist entry is
785 created.
786
787 Note that REALVALUE can be a forwarding pointer. Each time
788 it is examined or set, forwarding must be done. */
789
790 /* What value are we caching right now? */
791 current_alist_element =
792 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
793
794 /* If the current buffer is not the buffer whose binding is
795 currently cached, or if it's a Lisp_Buffer_Local_Value and
796 we're looking at the default value, the cache is invalid; we
797 need to write it out, and find the new CURRENT-ALIST-ELEMENT. */
798 if ((current_buffer
799 != XBUFFER (XCONS (XCONS (valcontents)->cdr)->car))
800 || (XTYPE (valcontents) == Lisp_Buffer_Local_Value
b06faa91
JB
801 && EQ (XCONS (current_alist_element)->car,
802 current_alist_element)))
7921925c 803 {
d8cafeb5
JB
804 /* Write out the cached value for the old buffer; copy it
805 back to its alist element. This works if the current
806 buffer only sees the default value, too. */
807 Fsetcdr (current_alist_element,
808 do_symval_forwarding (XCONS (valcontents)->car));
7921925c 809
d8cafeb5 810 /* Find the new value for CURRENT-ALIST-ELEMENT. */
7921925c 811 tem1 = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 812 if (NILP (tem1))
d8cafeb5
JB
813 {
814 /* This buffer still sees the default value. */
815
816 /* If the variable is a Lisp_Some_Buffer_Local_Value,
817 make CURRENT-ALIST-ELEMENT point to itself,
818 indicating that we're seeing the default value. */
819 if (XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
820 tem1 = XCONS (XCONS (valcontents)->cdr)->cdr;
821
822 /* If it's a Lisp_Buffer_Local_Value, give this buffer a
823 new assoc for a local value and set
824 CURRENT-ALIST-ELEMENT to point to that. */
825 else
826 {
827 tem1 = Fcons (sym, Fcdr (current_alist_element));
828 current_buffer->local_var_alist =
829 Fcons (tem1, current_buffer->local_var_alist);
830 }
831 }
832 /* Cache the new buffer's assoc in CURRENT-ALIST-ELEMENT. */
7921925c 833 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car = tem1;
d8cafeb5
JB
834
835 /* Set BUFFER, now that CURRENT-ALIST-ELEMENT is accurate. */
836 XSET (XCONS (XCONS (valcontents)->cdr)->car,
837 Lisp_Buffer, current_buffer);
7921925c
JB
838 }
839 valcontents = XCONS (valcontents)->car;
840 }
d8cafeb5 841
7921925c
JB
842 /* If storing void (making the symbol void), forward only through
843 buffer-local indicator, not through Lisp_Objfwd, etc. */
844 if (voide)
845 store_symval_forwarding (sym, Qnil, newval);
846 else
847 store_symval_forwarding (sym, valcontents, newval);
d8cafeb5 848
7921925c
JB
849 return newval;
850}
851\f
852/* Access or set a buffer-local symbol's default value. */
853
854/* Return the default value of SYM, but don't check for voidness.
855 Return Qunbound or a Lisp_Void object if it is void. */
856
857Lisp_Object
858default_value (sym)
859 Lisp_Object sym;
860{
861 register Lisp_Object valcontents;
862
863 CHECK_SYMBOL (sym, 0);
864 valcontents = XSYMBOL (sym)->value;
865
866 /* For a built-in buffer-local variable, get the default value
867 rather than letting do_symval_forwarding get the current value. */
868 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
869 {
870 register int idx = XUINT (valcontents);
871
872 if (*(int *) (idx + (char *) &buffer_local_flags) != 0)
873 return *(Lisp_Object *)(idx + (char *) &buffer_defaults);
874 }
875
876 /* Handle user-created local variables. */
877 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
878 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
879 {
880 /* If var is set up for a buffer that lacks a local value for it,
881 the current value is nominally the default value.
882 But the current value slot may be more up to date, since
883 ordinary setq stores just that slot. So use that. */
884 Lisp_Object current_alist_element, alist_element_car;
885 current_alist_element
886 = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
887 alist_element_car = XCONS (current_alist_element)->car;
888 if (EQ (alist_element_car, current_alist_element))
889 return do_symval_forwarding (XCONS (valcontents)->car);
890 else
891 return XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->cdr;
892 }
893 /* For other variables, get the current value. */
894 return do_symval_forwarding (valcontents);
895}
896
897DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
898 "Return T if SYMBOL has a non-void default value.\n\
899This is the value that is seen in buffers that do not have their own values\n\
900for this variable.")
901 (sym)
902 Lisp_Object sym;
903{
904 register Lisp_Object value;
905
906 value = default_value (sym);
907 return (XTYPE (value) == Lisp_Void || EQ (value, Qunbound)
908 ? Qnil : Qt);
909}
910
911DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0,
912 "Return SYMBOL's default value.\n\
913This is the value that is seen in buffers that do not have their own values\n\
914for this variable. The default value is meaningful for variables with\n\
915local bindings in certain buffers.")
916 (sym)
917 Lisp_Object sym;
918{
919 register Lisp_Object value;
920
921 value = default_value (sym);
922 if (XTYPE (value) == Lisp_Void || EQ (value, Qunbound))
923 return Fsignal (Qvoid_variable, Fcons (sym, Qnil));
924 return value;
925}
926
927DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
928 "Set SYMBOL's default value to VAL. SYMBOL and VAL are evaluated.\n\
929The default value is seen in buffers that do not have their own values\n\
930for this variable.")
931 (sym, value)
932 Lisp_Object sym, value;
933{
934 register Lisp_Object valcontents, current_alist_element, alist_element_buffer;
935
936 CHECK_SYMBOL (sym, 0);
937 valcontents = XSYMBOL (sym)->value;
938
939 /* Handle variables like case-fold-search that have special slots
940 in the buffer. Make them work apparently like Lisp_Buffer_Local_Value
941 variables. */
942 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
943 {
944 register int idx = XUINT (valcontents);
945#ifndef RTPC_REGISTER_BUG
946 register struct buffer *b;
947#else
948 struct buffer *b;
949#endif
950 register int mask = *(int *) (idx + (char *) &buffer_local_flags);
951
952 if (mask > 0)
953 {
954 *(Lisp_Object *)(idx + (char *) &buffer_defaults) = value;
955 for (b = all_buffers; b; b = b->next)
956 if (!(b->local_var_flags & mask))
957 *(Lisp_Object *)(idx + (char *) b) = value;
958 }
959 return value;
960 }
961
962 if (XTYPE (valcontents) != Lisp_Buffer_Local_Value &&
963 XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
964 return Fset (sym, value);
965
966 /* Store new value into the DEFAULT-VALUE slot */
967 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->cdr = value;
968
969 /* If that slot is current, we must set the REALVALUE slot too */
970 current_alist_element = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
971 alist_element_buffer = Fcar (current_alist_element);
972 if (EQ (alist_element_buffer, current_alist_element))
973 store_symval_forwarding (sym, XCONS (valcontents)->car, value);
974
975 return value;
976}
977
978DEFUN ("setq-default", Fsetq_default, Ssetq_default, 2, UNEVALLED, 0,
979 "\
980(setq-default SYM VAL SYM VAL ...): set each SYM's default value to its VAL.\n\
981VAL is evaluated; SYM is not. The default value is seen in buffers that do\n\
982not have their own values for this variable.")
983 (args)
984 Lisp_Object args;
985{
986 register Lisp_Object args_left;
987 register Lisp_Object val, sym;
988 struct gcpro gcpro1;
989
a33ef3ab 990 if (NILP (args))
7921925c
JB
991 return Qnil;
992
993 args_left = args;
994 GCPRO1 (args);
995
996 do
997 {
998 val = Feval (Fcar (Fcdr (args_left)));
999 sym = Fcar (args_left);
1000 Fset_default (sym, val);
1001 args_left = Fcdr (Fcdr (args_left));
1002 }
a33ef3ab 1003 while (!NILP (args_left));
7921925c
JB
1004
1005 UNGCPRO;
1006 return val;
1007}
1008\f
a5ca2b75
JB
1009/* Lisp functions for creating and removing buffer-local variables. */
1010
7921925c
JB
1011DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local,
1012 1, 1, "vMake Variable Buffer Local: ",
1013 "Make VARIABLE have a separate value for each buffer.\n\
1014At any time, the value for the current buffer is in effect.\n\
1015There is also a default value which is seen in any buffer which has not yet\n\
1016set its own value.\n\
1017Using `set' or `setq' to set the variable causes it to have a separate value\n\
1018for the current buffer if it was previously using the default value.\n\
1019The function `default-value' gets the default value and `set-default' sets it.")
1020 (sym)
1021 register Lisp_Object sym;
1022{
1023 register Lisp_Object tem, valcontents;
1024
1025 CHECK_SYMBOL (sym, 0);
1026
1027 if (EQ (sym, Qnil) || EQ (sym, Qt))
1028 error ("Symbol %s may not be buffer-local", XSYMBOL (sym)->name->data);
1029
1030 valcontents = XSYMBOL (sym)->value;
1031 if ((XTYPE (valcontents) == Lisp_Buffer_Local_Value) ||
1032 (XTYPE (valcontents) == Lisp_Buffer_Objfwd))
1033 return sym;
1034 if (XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
1035 {
1036 XSETTYPE (XSYMBOL (sym)->value, Lisp_Buffer_Local_Value);
1037 return sym;
1038 }
1039 if (EQ (valcontents, Qunbound))
1040 XSYMBOL (sym)->value = Qnil;
1041 tem = Fcons (Qnil, Fsymbol_value (sym));
1042 XCONS (tem)->car = tem;
1043 XSYMBOL (sym)->value = Fcons (XSYMBOL (sym)->value, Fcons (Fcurrent_buffer (), tem));
1044 XSETTYPE (XSYMBOL (sym)->value, Lisp_Buffer_Local_Value);
1045 return sym;
1046}
1047
1048DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable,
1049 1, 1, "vMake Local Variable: ",
1050 "Make VARIABLE have a separate value in the current buffer.\n\
1051Other buffers will continue to share a common default value.\n\
1052See also `make-variable-buffer-local'.\n\n\
1053If the variable is already arranged to become local when set,\n\
1054this function causes a local value to exist for this buffer,\n\
1055just as if the variable were set.")
1056 (sym)
1057 register Lisp_Object sym;
1058{
1059 register Lisp_Object tem, valcontents;
1060
1061 CHECK_SYMBOL (sym, 0);
1062
1063 if (EQ (sym, Qnil) || EQ (sym, Qt))
1064 error ("Symbol %s may not be buffer-local", XSYMBOL (sym)->name->data);
1065
1066 valcontents = XSYMBOL (sym)->value;
1067 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
1068 || XTYPE (valcontents) == Lisp_Buffer_Objfwd)
1069 {
1070 tem = Fboundp (sym);
1071
1072 /* Make sure the symbol has a local value in this particular buffer,
1073 by setting it to the same value it already has. */
1074 Fset (sym, (EQ (tem, Qt) ? Fsymbol_value (sym) : Qunbound));
1075 return sym;
1076 }
1077 /* Make sure sym is set up to hold per-buffer values */
1078 if (XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
1079 {
1080 if (EQ (valcontents, Qunbound))
1081 XSYMBOL (sym)->value = Qnil;
1082 tem = Fcons (Qnil, do_symval_forwarding (valcontents));
1083 XCONS (tem)->car = tem;
1084 XSYMBOL (sym)->value = Fcons (XSYMBOL (sym)->value, Fcons (Qnil, tem));
1085 XSETTYPE (XSYMBOL (sym)->value, Lisp_Some_Buffer_Local_Value);
1086 }
1087 /* Make sure this buffer has its own value of sym */
1088 tem = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 1089 if (NILP (tem))
7921925c
JB
1090 {
1091 current_buffer->local_var_alist
1092 = Fcons (Fcons (sym, XCONS (XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->cdr)->cdr),
1093 current_buffer->local_var_alist);
1094
1095 /* Make sure symbol does not think it is set up for this buffer;
1096 force it to look once again for this buffer's value */
1097 {
1098 /* This local variable avoids "expression too complex" on IBM RT. */
1099 Lisp_Object xs;
1100
1101 xs = XSYMBOL (sym)->value;
1102 if (current_buffer == XBUFFER (XCONS (XCONS (xs)->cdr)->car))
1103 XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->car = Qnil;
1104 }
7921925c 1105 }
a5ca2b75
JB
1106
1107 /* If the symbol forwards into a C variable, then swap in the
1108 variable for this buffer immediately. If C code modifies the
1109 variable before we swap in, then that new value will clobber the
1110 default value the next time we swap. */
1111 valcontents = XCONS (XSYMBOL (sym)->value)->car;
1112 if (XTYPE (valcontents) == Lisp_Intfwd
1113 || XTYPE (valcontents) == Lisp_Boolfwd
1114 || XTYPE (valcontents) == Lisp_Objfwd)
1115 swap_in_symval_forwarding (sym, XSYMBOL (sym)->value);
1116
7921925c
JB
1117 return sym;
1118}
1119
1120DEFUN ("kill-local-variable", Fkill_local_variable, Skill_local_variable,
1121 1, 1, "vKill Local Variable: ",
1122 "Make VARIABLE no longer have a separate value in the current buffer.\n\
1123From now on the default value will apply in this buffer.")
1124 (sym)
1125 register Lisp_Object sym;
1126{
1127 register Lisp_Object tem, valcontents;
1128
1129 CHECK_SYMBOL (sym, 0);
1130
1131 valcontents = XSYMBOL (sym)->value;
1132
1133 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
1134 {
1135 register int idx = XUINT (valcontents);
1136 register int mask = *(int *) (idx + (char *) &buffer_local_flags);
1137
1138 if (mask > 0)
1139 {
1140 *(Lisp_Object *)(idx + (char *) current_buffer)
1141 = *(Lisp_Object *)(idx + (char *) &buffer_defaults);
1142 current_buffer->local_var_flags &= ~mask;
1143 }
1144 return sym;
1145 }
1146
1147 if (XTYPE (valcontents) != Lisp_Buffer_Local_Value &&
1148 XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
1149 return sym;
1150
1151 /* Get rid of this buffer's alist element, if any */
1152
1153 tem = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 1154 if (!NILP (tem))
7921925c
JB
1155 current_buffer->local_var_alist = Fdelq (tem, current_buffer->local_var_alist);
1156
1157 /* Make sure symbol does not think it is set up for this buffer;
1158 force it to look once again for this buffer's value */
1159 {
1160 Lisp_Object sv;
1161 sv = XSYMBOL (sym)->value;
1162 if (current_buffer == XBUFFER (XCONS (XCONS (sv)->cdr)->car))
1163 XCONS (XCONS (sv)->cdr)->car = Qnil;
1164 }
1165
1166 return sym;
1167}
1168\f
ffd56f97
JB
1169/* Find the function at the end of a chain of symbol function indirections. */
1170
1171/* If OBJECT is a symbol, find the end of its function chain and
1172 return the value found there. If OBJECT is not a symbol, just
1173 return it. If there is a cycle in the function chain, signal a
1174 cyclic-function-indirection error.
1175
1176 This is like Findirect_function, except that it doesn't signal an
1177 error if the chain ends up unbound. */
1178Lisp_Object
a2932990 1179indirect_function (object)
ffd56f97
JB
1180 register Lisp_Object object;
1181{
1182 Lisp_Object tortise, hare;
1183
1184 hare = tortise = object;
1185
1186 for (;;)
1187 {
1188 if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound))
1189 break;
1190 hare = XSYMBOL (hare)->function;
1191 if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound))
1192 break;
1193 hare = XSYMBOL (hare)->function;
1194
1195 tortise = XSYMBOL (tortise)->function;
1196
1197 if (EQ (hare, tortise))
1198 Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
1199 }
1200
1201 return hare;
1202}
1203
1204DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0,
1205 "Return the function at the end of OBJECT's function chain.\n\
1206If OBJECT is a symbol, follow all function indirections and return the final\n\
1207function binding.\n\
1208If OBJECT is not a symbol, just return it.\n\
1209Signal a void-function error if the final symbol is unbound.\n\
1210Signal a cyclic-function-indirection error if there is a loop in the\n\
1211function chain of symbols.")
1212 (object)
1213 register Lisp_Object object;
1214{
1215 Lisp_Object result;
1216
1217 result = indirect_function (object);
1218
1219 if (EQ (result, Qunbound))
1220 return Fsignal (Qvoid_function, Fcons (object, Qnil));
1221 return result;
1222}
1223\f
7921925c
JB
1224/* Extract and set vector and string elements */
1225
1226DEFUN ("aref", Faref, Saref, 2, 2, 0,
1227 "Return the element of ARRAY at index INDEX.\n\
1228ARRAY may be a vector or a string, or a byte-code object. INDEX starts at 0.")
1229 (array, idx)
1230 register Lisp_Object array;
1231 Lisp_Object idx;
1232{
1233 register int idxval;
1234
1235 CHECK_NUMBER (idx, 1);
1236 idxval = XINT (idx);
1237 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String
1238 && XTYPE (array) != Lisp_Compiled)
1239 array = wrong_type_argument (Qarrayp, array);
1240 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1241 args_out_of_range (array, idx);
1242 if (XTYPE (array) == Lisp_String)
1243 {
1244 Lisp_Object val;
1245 XFASTINT (val) = (unsigned char) XSTRING (array)->data[idxval];
1246 return val;
1247 }
1248 else
1249 return XVECTOR (array)->contents[idxval];
1250}
1251
1252DEFUN ("aset", Faset, Saset, 3, 3, 0,
1253 "Store into the element of ARRAY at index INDEX the value NEWVAL.\n\
1254ARRAY may be a vector or a string. INDEX starts at 0.")
1255 (array, idx, newelt)
1256 register Lisp_Object array;
1257 Lisp_Object idx, newelt;
1258{
1259 register int idxval;
1260
1261 CHECK_NUMBER (idx, 1);
1262 idxval = XINT (idx);
1263 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String)
1264 array = wrong_type_argument (Qarrayp, array);
1265 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1266 args_out_of_range (array, idx);
1267 CHECK_IMPURE (array);
1268
1269 if (XTYPE (array) == Lisp_Vector)
1270 XVECTOR (array)->contents[idxval] = newelt;
1271 else
1272 {
1273 CHECK_NUMBER (newelt, 2);
1274 XSTRING (array)->data[idxval] = XINT (newelt);
1275 }
1276
1277 return newelt;
1278}
1279
1280Lisp_Object
1281Farray_length (array)
1282 register Lisp_Object array;
1283{
1284 register Lisp_Object size;
1285 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String
1286 && XTYPE (array) != Lisp_Compiled)
1287 array = wrong_type_argument (Qarrayp, array);
1288 XFASTINT (size) = XVECTOR (array)->size;
1289 return size;
1290}
1291\f
1292/* Arithmetic functions */
1293
1294enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
1295
1296Lisp_Object
1297arithcompare (num1, num2, comparison)
1298 Lisp_Object num1, num2;
1299 enum comparison comparison;
1300{
1301 double f1, f2;
1302 int floatp = 0;
1303
1304#ifdef LISP_FLOAT_TYPE
1305 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1306 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
1307
1308 if (XTYPE (num1) == Lisp_Float || XTYPE (num2) == Lisp_Float)
1309 {
1310 floatp = 1;
1311 f1 = (XTYPE (num1) == Lisp_Float) ? XFLOAT (num1)->data : XINT (num1);
1312 f2 = (XTYPE (num2) == Lisp_Float) ? XFLOAT (num2)->data : XINT (num2);
1313 }
1314#else
1315 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1316 CHECK_NUMBER_COERCE_MARKER (num2, 0);
1317#endif /* LISP_FLOAT_TYPE */
1318
1319 switch (comparison)
1320 {
1321 case equal:
1322 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
1323 return Qt;
1324 return Qnil;
1325
1326 case notequal:
1327 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
1328 return Qt;
1329 return Qnil;
1330
1331 case less:
1332 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
1333 return Qt;
1334 return Qnil;
1335
1336 case less_or_equal:
1337 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
1338 return Qt;
1339 return Qnil;
1340
1341 case grtr:
1342 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
1343 return Qt;
1344 return Qnil;
1345
1346 case grtr_or_equal:
1347 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
1348 return Qt;
1349 return Qnil;
25e40a4b
JB
1350
1351 default:
1352 abort ();
7921925c
JB
1353 }
1354}
1355
1356DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0,
1357 "T if two args, both numbers or markers, are equal.")
1358 (num1, num2)
1359 register Lisp_Object num1, num2;
1360{
1361 return arithcompare (num1, num2, equal);
1362}
1363
1364DEFUN ("<", Flss, Slss, 2, 2, 0,
1365 "T if first arg is less than second arg. Both must be numbers or markers.")
1366 (num1, num2)
1367 register Lisp_Object num1, num2;
1368{
1369 return arithcompare (num1, num2, less);
1370}
1371
1372DEFUN (">", Fgtr, Sgtr, 2, 2, 0,
1373 "T if first arg is greater than second arg. Both must be numbers or markers.")
1374 (num1, num2)
1375 register Lisp_Object num1, num2;
1376{
1377 return arithcompare (num1, num2, grtr);
1378}
1379
1380DEFUN ("<=", Fleq, Sleq, 2, 2, 0,
1381 "T if first arg is less than or equal to second arg.\n\
1382Both must be numbers or markers.")
1383 (num1, num2)
1384 register Lisp_Object num1, num2;
1385{
1386 return arithcompare (num1, num2, less_or_equal);
1387}
1388
1389DEFUN (">=", Fgeq, Sgeq, 2, 2, 0,
1390 "T if first arg is greater than or equal to second arg.\n\
1391Both must be numbers or markers.")
1392 (num1, num2)
1393 register Lisp_Object num1, num2;
1394{
1395 return arithcompare (num1, num2, grtr_or_equal);
1396}
1397
1398DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
1399 "T if first arg is not equal to second arg. Both must be numbers or markers.")
1400 (num1, num2)
1401 register Lisp_Object num1, num2;
1402{
1403 return arithcompare (num1, num2, notequal);
1404}
1405
1406DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, "T if NUMBER is zero.")
1407 (num)
1408 register Lisp_Object num;
1409{
1410#ifdef LISP_FLOAT_TYPE
1411 CHECK_NUMBER_OR_FLOAT (num, 0);
1412
1413 if (XTYPE(num) == Lisp_Float)
1414 {
1415 if (XFLOAT(num)->data == 0.0)
1416 return Qt;
1417 return Qnil;
1418 }
1419#else
1420 CHECK_NUMBER (num, 0);
1421#endif /* LISP_FLOAT_TYPE */
1422
1423 if (!XINT (num))
1424 return Qt;
1425 return Qnil;
1426}
1427\f
f2980264 1428DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
25e40a4b
JB
1429 "Convert NUM to a string by printing it in decimal.\n\
1430Uses a minus sign if negative.\n\
1431NUM may be an integer or a floating point number.")
7921925c
JB
1432 (num)
1433 Lisp_Object num;
1434{
1435 char buffer[20];
1436
1437#ifndef LISP_FLOAT_TYPE
1438 CHECK_NUMBER (num, 0);
1439#else
1440 CHECK_NUMBER_OR_FLOAT (num, 0);
1441
1442 if (XTYPE(num) == Lisp_Float)
1443 {
1444 char pigbuf[350]; /* see comments in float_to_string */
1445
1446 float_to_string (pigbuf, XFLOAT(num)->data);
1447 return build_string (pigbuf);
1448 }
1449#endif /* LISP_FLOAT_TYPE */
1450
1451 sprintf (buffer, "%d", XINT (num));
1452 return build_string (buffer);
1453}
1454
25e40a4b
JB
1455DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 1, 0,
1456 "Convert STRING to a number by parsing it as a decimal number.\n\
1457This parses both integers and floating point numbers.")
7921925c
JB
1458 (str)
1459 register Lisp_Object str;
1460{
0a3e4d65 1461 unsigned char *p;
25e40a4b 1462
7921925c
JB
1463 CHECK_STRING (str, 0);
1464
25e40a4b
JB
1465 p = XSTRING (str)->data;
1466
1467 /* Skip any whitespace at the front of the number. Some versions of
1468 atoi do this anyway, so we might as well make Emacs lisp consistent. */
0a3e4d65 1469 while (*p == ' ' || *p == '\t')
25e40a4b
JB
1470 p++;
1471
7921925c 1472#ifdef LISP_FLOAT_TYPE
25e40a4b
JB
1473 if (isfloat_string (p))
1474 return make_float (atof (p));
7921925c
JB
1475#endif /* LISP_FLOAT_TYPE */
1476
25e40a4b 1477 return make_number (atoi (p));
7921925c
JB
1478}
1479\f
1480enum arithop
1481 { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin };
1482
b06faa91
JB
1483extern Lisp_Object float_arith_driver ();
1484
7921925c
JB
1485Lisp_Object
1486arith_driver
1487 (code, nargs, args)
1488 enum arithop code;
1489 int nargs;
1490 register Lisp_Object *args;
1491{
1492 register Lisp_Object val;
1493 register int argnum;
1494 register int accum;
1495 register int next;
1496
1497#ifdef SWITCH_ENUM_BUG
1498 switch ((int) code)
1499#else
1500 switch (code)
1501#endif
1502 {
1503 case Alogior:
1504 case Alogxor:
1505 case Aadd:
1506 case Asub:
1507 accum = 0; break;
1508 case Amult:
1509 accum = 1; break;
1510 case Alogand:
1511 accum = -1; break;
1512 }
1513
1514 for (argnum = 0; argnum < nargs; argnum++)
1515 {
1516 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
1517#ifdef LISP_FLOAT_TYPE
1518 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
1519
1520 if (XTYPE (val) == Lisp_Float) /* time to do serious math */
1521 return (float_arith_driver ((double) accum, argnum, code,
1522 nargs, args));
1523#else
1524 CHECK_NUMBER_COERCE_MARKER (val, argnum);
1525#endif /* LISP_FLOAT_TYPE */
1526 args[argnum] = val; /* runs into a compiler bug. */
1527 next = XINT (args[argnum]);
1528#ifdef SWITCH_ENUM_BUG
1529 switch ((int) code)
1530#else
1531 switch (code)
1532#endif
1533 {
1534 case Aadd: accum += next; break;
1535 case Asub:
1536 if (!argnum && nargs != 1)
1537 next = - next;
1538 accum -= next;
1539 break;
1540 case Amult: accum *= next; break;
1541 case Adiv:
1542 if (!argnum) accum = next;
1543 else accum /= next;
1544 break;
1545 case Alogand: accum &= next; break;
1546 case Alogior: accum |= next; break;
1547 case Alogxor: accum ^= next; break;
1548 case Amax: if (!argnum || next > accum) accum = next; break;
1549 case Amin: if (!argnum || next < accum) accum = next; break;
1550 }
1551 }
1552
1553 XSET (val, Lisp_Int, accum);
1554 return val;
1555}
1556
1557#ifdef LISP_FLOAT_TYPE
1558Lisp_Object
1559float_arith_driver (accum, argnum, code, nargs, args)
1560 double accum;
1561 register int argnum;
1562 enum arithop code;
1563 int nargs;
1564 register Lisp_Object *args;
1565{
1566 register Lisp_Object val;
1567 double next;
1568
1569 for (; argnum < nargs; argnum++)
1570 {
1571 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
1572 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
1573
1574 if (XTYPE (val) == Lisp_Float)
1575 {
1576 next = XFLOAT (val)->data;
1577 }
1578 else
1579 {
1580 args[argnum] = val; /* runs into a compiler bug. */
1581 next = XINT (args[argnum]);
1582 }
1583#ifdef SWITCH_ENUM_BUG
1584 switch ((int) code)
1585#else
1586 switch (code)
1587#endif
1588 {
1589 case Aadd:
1590 accum += next;
1591 break;
1592 case Asub:
1593 if (!argnum && nargs != 1)
1594 next = - next;
1595 accum -= next;
1596 break;
1597 case Amult:
1598 accum *= next;
1599 break;
1600 case Adiv:
1601 if (!argnum)
1602 accum = next;
1603 else
1604 accum /= next;
1605 break;
1606 case Alogand:
1607 case Alogior:
1608 case Alogxor:
1609 return wrong_type_argument (Qinteger_or_marker_p, val);
1610 case Amax:
1611 if (!argnum || next > accum)
1612 accum = next;
1613 break;
1614 case Amin:
1615 if (!argnum || next < accum)
1616 accum = next;
1617 break;
1618 }
1619 }
1620
1621 return make_float (accum);
1622}
1623#endif /* LISP_FLOAT_TYPE */
1624
1625DEFUN ("+", Fplus, Splus, 0, MANY, 0,
1626 "Return sum of any number of arguments, which are numbers or markers.")
1627 (nargs, args)
1628 int nargs;
1629 Lisp_Object *args;
1630{
1631 return arith_driver (Aadd, nargs, args);
1632}
1633
1634DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
1635 "Negate number or subtract numbers or markers.\n\
1636With one arg, negates it. With more than one arg,\n\
1637subtracts all but the first from the first.")
1638 (nargs, args)
1639 int nargs;
1640 Lisp_Object *args;
1641{
1642 return arith_driver (Asub, nargs, args);
1643}
1644
1645DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
1646 "Returns product of any number of arguments, which are numbers or markers.")
1647 (nargs, args)
1648 int nargs;
1649 Lisp_Object *args;
1650{
1651 return arith_driver (Amult, nargs, args);
1652}
1653
1654DEFUN ("/", Fquo, Squo, 2, MANY, 0,
1655 "Returns first argument divided by all the remaining arguments.\n\
1656The arguments must be numbers or markers.")
1657 (nargs, args)
1658 int nargs;
1659 Lisp_Object *args;
1660{
1661 return arith_driver (Adiv, nargs, args);
1662}
1663
1664DEFUN ("%", Frem, Srem, 2, 2, 0,
1665 "Returns remainder of first arg divided by second.\n\
1666Both must be numbers or markers.")
1667 (num1, num2)
1668 register Lisp_Object num1, num2;
1669{
1670 Lisp_Object val;
1671
1672#ifdef LISP_FLOAT_TYPE
1673 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1674 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
1675
1676 if (XTYPE (num1) == Lisp_Float || XTYPE (num2) == Lisp_Float)
1677 {
1678 double f1, f2;
1679
1680 f1 = XTYPE (num1) == Lisp_Float ? XFLOAT (num1)->data : XINT (num1);
1681 f2 = XTYPE (num2) == Lisp_Float ? XFLOAT (num2)->data : XINT (num2);
a080486e 1682#if defined (USG) || defined (sun) || defined (ultrix) || defined (hpux)
bc540f9f
JB
1683 f1 = fmod (f1, f2);
1684#else
d8cafeb5 1685 f1 = drem (f1, f2);
bc540f9f 1686#endif
d8cafeb5
JB
1687 if (f1 < 0)
1688 f1 += f2;
1689 return (make_float (f1));
7921925c
JB
1690 }
1691#else /* not LISP_FLOAT_TYPE */
1692 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1693 CHECK_NUMBER_COERCE_MARKER (num2, 1);
1694#endif /* not LISP_FLOAT_TYPE */
1695
1696 XSET (val, Lisp_Int, XINT (num1) % XINT (num2));
1697 return val;
1698}
1699
1700DEFUN ("max", Fmax, Smax, 1, MANY, 0,
1701 "Return largest of all the arguments (which must be numbers or markers).\n\
1702The value is always a number; markers are converted to numbers.")
1703 (nargs, args)
1704 int nargs;
1705 Lisp_Object *args;
1706{
1707 return arith_driver (Amax, nargs, args);
1708}
1709
1710DEFUN ("min", Fmin, Smin, 1, MANY, 0,
1711 "Return smallest of all the arguments (which must be numbers or markers).\n\
1712The value is always a number; markers are converted to numbers.")
1713 (nargs, args)
1714 int nargs;
1715 Lisp_Object *args;
1716{
1717 return arith_driver (Amin, nargs, args);
1718}
1719
1720DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
1721 "Return bitwise-and of all the arguments.\n\
1722Arguments may be integers, or markers converted to integers.")
1723 (nargs, args)
1724 int nargs;
1725 Lisp_Object *args;
1726{
1727 return arith_driver (Alogand, nargs, args);
1728}
1729
1730DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
1731 "Return bitwise-or of all the arguments.\n\
1732Arguments may be integers, or markers converted to integers.")
1733 (nargs, args)
1734 int nargs;
1735 Lisp_Object *args;
1736{
1737 return arith_driver (Alogior, nargs, args);
1738}
1739
1740DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
1741 "Return bitwise-exclusive-or of all the arguments.\n\
1742Arguments may be integers, or markers converted to integers.")
1743 (nargs, args)
1744 int nargs;
1745 Lisp_Object *args;
1746{
1747 return arith_driver (Alogxor, nargs, args);
1748}
1749
1750DEFUN ("ash", Fash, Sash, 2, 2, 0,
1751 "Return VALUE with its bits shifted left by COUNT.\n\
1752If COUNT is negative, shifting is actually to the right.\n\
1753In this case, the sign bit is duplicated.")
1754 (num1, num2)
1755 register Lisp_Object num1, num2;
1756{
1757 register Lisp_Object val;
1758
1759 CHECK_NUMBER (num1, 0);
1760 CHECK_NUMBER (num2, 1);
1761
1762 if (XINT (num2) > 0)
1763 XSET (val, Lisp_Int, XINT (num1) << XFASTINT (num2));
1764 else
1765 XSET (val, Lisp_Int, XINT (num1) >> -XINT (num2));
1766 return val;
1767}
1768
1769DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
1770 "Return VALUE with its bits shifted left by COUNT.\n\
1771If COUNT is negative, shifting is actually to the right.\n\
1772In this case, zeros are shifted in on the left.")
1773 (num1, num2)
1774 register Lisp_Object num1, num2;
1775{
1776 register Lisp_Object val;
1777
1778 CHECK_NUMBER (num1, 0);
1779 CHECK_NUMBER (num2, 1);
1780
1781 if (XINT (num2) > 0)
1782 XSET (val, Lisp_Int, (unsigned) XFASTINT (num1) << XFASTINT (num2));
1783 else
1784 XSET (val, Lisp_Int, (unsigned) XFASTINT (num1) >> -XINT (num2));
1785 return val;
1786}
1787
1788DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
1789 "Return NUMBER plus one. NUMBER may be a number or a marker.\n\
1790Markers are converted to integers.")
1791 (num)
1792 register Lisp_Object num;
1793{
1794#ifdef LISP_FLOAT_TYPE
1795 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num, 0);
1796
1797 if (XTYPE (num) == Lisp_Float)
1798 return (make_float (1.0 + XFLOAT (num)->data));
1799#else
1800 CHECK_NUMBER_COERCE_MARKER (num, 0);
1801#endif /* LISP_FLOAT_TYPE */
1802
1803 XSETINT (num, XFASTINT (num) + 1);
1804 return num;
1805}
1806
1807DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
1808 "Return NUMBER minus one. NUMBER may be a number or a marker.\n\
1809Markers are converted to integers.")
1810 (num)
1811 register Lisp_Object num;
1812{
1813#ifdef LISP_FLOAT_TYPE
1814 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num, 0);
1815
1816 if (XTYPE (num) == Lisp_Float)
1817 return (make_float (-1.0 + XFLOAT (num)->data));
1818#else
1819 CHECK_NUMBER_COERCE_MARKER (num, 0);
1820#endif /* LISP_FLOAT_TYPE */
1821
1822 XSETINT (num, XFASTINT (num) - 1);
1823 return num;
1824}
1825
1826DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
1827 "Return the bitwise complement of ARG. ARG must be an integer.")
1828 (num)
1829 register Lisp_Object num;
1830{
1831 CHECK_NUMBER (num, 0);
1832 XSETINT (num, ~XFASTINT (num));
1833 return num;
1834}
1835\f
1836void
1837syms_of_data ()
1838{
6315e761
RS
1839 Lisp_Object error_tail, arith_tail;
1840
7921925c
JB
1841 Qquote = intern ("quote");
1842 Qlambda = intern ("lambda");
1843 Qsubr = intern ("subr");
1844 Qerror_conditions = intern ("error-conditions");
1845 Qerror_message = intern ("error-message");
1846 Qtop_level = intern ("top-level");
1847
1848 Qerror = intern ("error");
1849 Qquit = intern ("quit");
1850 Qwrong_type_argument = intern ("wrong-type-argument");
1851 Qargs_out_of_range = intern ("args-out-of-range");
1852 Qvoid_function = intern ("void-function");
ffd56f97 1853 Qcyclic_function_indirection = intern ("cyclic-function-indirection");
7921925c
JB
1854 Qvoid_variable = intern ("void-variable");
1855 Qsetting_constant = intern ("setting-constant");
1856 Qinvalid_read_syntax = intern ("invalid-read-syntax");
1857
1858 Qinvalid_function = intern ("invalid-function");
1859 Qwrong_number_of_arguments = intern ("wrong-number-of-arguments");
1860 Qno_catch = intern ("no-catch");
1861 Qend_of_file = intern ("end-of-file");
1862 Qarith_error = intern ("arith-error");
1863 Qbeginning_of_buffer = intern ("beginning-of-buffer");
1864 Qend_of_buffer = intern ("end-of-buffer");
1865 Qbuffer_read_only = intern ("buffer-read-only");
1866
1867 Qlistp = intern ("listp");
1868 Qconsp = intern ("consp");
1869 Qsymbolp = intern ("symbolp");
1870 Qintegerp = intern ("integerp");
1871 Qnatnump = intern ("natnump");
1872 Qstringp = intern ("stringp");
1873 Qarrayp = intern ("arrayp");
1874 Qsequencep = intern ("sequencep");
1875 Qbufferp = intern ("bufferp");
1876 Qvectorp = intern ("vectorp");
1877 Qchar_or_string_p = intern ("char-or-string-p");
1878 Qmarkerp = intern ("markerp");
07bd8472 1879 Qbuffer_or_string_p = intern ("buffer-or-string-p");
7921925c
JB
1880 Qinteger_or_marker_p = intern ("integer-or-marker-p");
1881 Qboundp = intern ("boundp");
1882 Qfboundp = intern ("fboundp");
1883
1884#ifdef LISP_FLOAT_TYPE
1885 Qfloatp = intern ("floatp");
1886 Qnumberp = intern ("numberp");
1887 Qnumber_or_marker_p = intern ("number-or-marker-p");
1888#endif /* LISP_FLOAT_TYPE */
1889
1890 Qcdr = intern ("cdr");
1891
6315e761
RS
1892 error_tail = Fcons (Qerror, Qnil);
1893
7921925c
JB
1894 /* ERROR is used as a signaler for random errors for which nothing else is right */
1895
1896 Fput (Qerror, Qerror_conditions,
6315e761 1897 error_tail);
7921925c
JB
1898 Fput (Qerror, Qerror_message,
1899 build_string ("error"));
1900
1901 Fput (Qquit, Qerror_conditions,
1902 Fcons (Qquit, Qnil));
1903 Fput (Qquit, Qerror_message,
1904 build_string ("Quit"));
1905
1906 Fput (Qwrong_type_argument, Qerror_conditions,
6315e761 1907 Fcons (Qwrong_type_argument, error_tail));
7921925c
JB
1908 Fput (Qwrong_type_argument, Qerror_message,
1909 build_string ("Wrong type argument"));
1910
1911 Fput (Qargs_out_of_range, Qerror_conditions,
6315e761 1912 Fcons (Qargs_out_of_range, error_tail));
7921925c
JB
1913 Fput (Qargs_out_of_range, Qerror_message,
1914 build_string ("Args out of range"));
1915
1916 Fput (Qvoid_function, Qerror_conditions,
6315e761 1917 Fcons (Qvoid_function, error_tail));
7921925c
JB
1918 Fput (Qvoid_function, Qerror_message,
1919 build_string ("Symbol's function definition is void"));
1920
ffd56f97 1921 Fput (Qcyclic_function_indirection, Qerror_conditions,
6315e761 1922 Fcons (Qcyclic_function_indirection, error_tail));
ffd56f97
JB
1923 Fput (Qcyclic_function_indirection, Qerror_message,
1924 build_string ("Symbol's chain of function indirections contains a loop"));
1925
7921925c 1926 Fput (Qvoid_variable, Qerror_conditions,
6315e761 1927 Fcons (Qvoid_variable, error_tail));
7921925c
JB
1928 Fput (Qvoid_variable, Qerror_message,
1929 build_string ("Symbol's value as variable is void"));
1930
1931 Fput (Qsetting_constant, Qerror_conditions,
6315e761 1932 Fcons (Qsetting_constant, error_tail));
7921925c
JB
1933 Fput (Qsetting_constant, Qerror_message,
1934 build_string ("Attempt to set a constant symbol"));
1935
1936 Fput (Qinvalid_read_syntax, Qerror_conditions,
6315e761 1937 Fcons (Qinvalid_read_syntax, error_tail));
7921925c
JB
1938 Fput (Qinvalid_read_syntax, Qerror_message,
1939 build_string ("Invalid read syntax"));
1940
1941 Fput (Qinvalid_function, Qerror_conditions,
6315e761 1942 Fcons (Qinvalid_function, error_tail));
7921925c
JB
1943 Fput (Qinvalid_function, Qerror_message,
1944 build_string ("Invalid function"));
1945
1946 Fput (Qwrong_number_of_arguments, Qerror_conditions,
6315e761 1947 Fcons (Qwrong_number_of_arguments, error_tail));
7921925c
JB
1948 Fput (Qwrong_number_of_arguments, Qerror_message,
1949 build_string ("Wrong number of arguments"));
1950
1951 Fput (Qno_catch, Qerror_conditions,
6315e761 1952 Fcons (Qno_catch, error_tail));
7921925c
JB
1953 Fput (Qno_catch, Qerror_message,
1954 build_string ("No catch for tag"));
1955
1956 Fput (Qend_of_file, Qerror_conditions,
6315e761 1957 Fcons (Qend_of_file, error_tail));
7921925c
JB
1958 Fput (Qend_of_file, Qerror_message,
1959 build_string ("End of file during parsing"));
1960
6315e761 1961 arith_tail = Fcons (Qarith_error, error_tail);
7921925c 1962 Fput (Qarith_error, Qerror_conditions,
6315e761 1963 arith_tail);
7921925c
JB
1964 Fput (Qarith_error, Qerror_message,
1965 build_string ("Arithmetic error"));
1966
1967 Fput (Qbeginning_of_buffer, Qerror_conditions,
6315e761 1968 Fcons (Qbeginning_of_buffer, error_tail));
7921925c
JB
1969 Fput (Qbeginning_of_buffer, Qerror_message,
1970 build_string ("Beginning of buffer"));
1971
1972 Fput (Qend_of_buffer, Qerror_conditions,
6315e761 1973 Fcons (Qend_of_buffer, error_tail));
7921925c
JB
1974 Fput (Qend_of_buffer, Qerror_message,
1975 build_string ("End of buffer"));
1976
1977 Fput (Qbuffer_read_only, Qerror_conditions,
6315e761 1978 Fcons (Qbuffer_read_only, error_tail));
7921925c
JB
1979 Fput (Qbuffer_read_only, Qerror_message,
1980 build_string ("Buffer is read-only"));
1981
6315e761
RS
1982#ifdef LISP_FLOAT_TYPE
1983 Qrange_error = intern ("range-error");
1984 Qdomain_error = intern ("domain-error");
1985 Qsingularity_error = intern ("singularity-error");
1986 Qoverflow_error = intern ("overflow-error");
1987 Qunderflow_error = intern ("underflow-error");
1988
1989 Fput (Qdomain_error, Qerror_conditions,
1990 Fcons (Qdomain_error, arith_tail));
1991 Fput (Qdomain_error, Qerror_message,
1992 build_string ("Arithmetic domain error"));
1993
1994 Fput (Qrange_error, Qerror_conditions,
1995 Fcons (Qrange_error, arith_tail));
1996 Fput (Qrange_error, Qerror_message,
1997 build_string ("Arithmetic range error"));
1998
1999 Fput (Qsingularity_error, Qerror_conditions,
2000 Fcons (Qsingularity_error, Fcons (Qdomain_error, arith_tail)));
2001 Fput (Qsingularity_error, Qerror_message,
2002 build_string ("Arithmetic singularity error"));
2003
2004 Fput (Qoverflow_error, Qerror_conditions,
2005 Fcons (Qoverflow_error, Fcons (Qdomain_error, arith_tail)));
2006 Fput (Qoverflow_error, Qerror_message,
2007 build_string ("Arithmetic overflow error"));
2008
2009 Fput (Qunderflow_error, Qerror_conditions,
2010 Fcons (Qunderflow_error, Fcons (Qdomain_error, arith_tail)));
2011 Fput (Qunderflow_error, Qerror_message,
2012 build_string ("Arithmetic underflow error"));
2013
2014 staticpro (&Qrange_error);
2015 staticpro (&Qdomain_error);
2016 staticpro (&Qsingularity_error);
2017 staticpro (&Qoverflow_error);
2018 staticpro (&Qunderflow_error);
2019#endif /* LISP_FLOAT_TYPE */
2020
7921925c
JB
2021 staticpro (&Qnil);
2022 staticpro (&Qt);
2023 staticpro (&Qquote);
2024 staticpro (&Qlambda);
2025 staticpro (&Qsubr);
2026 staticpro (&Qunbound);
2027 staticpro (&Qerror_conditions);
2028 staticpro (&Qerror_message);
2029 staticpro (&Qtop_level);
2030
2031 staticpro (&Qerror);
2032 staticpro (&Qquit);
2033 staticpro (&Qwrong_type_argument);
2034 staticpro (&Qargs_out_of_range);
2035 staticpro (&Qvoid_function);
ffd56f97 2036 staticpro (&Qcyclic_function_indirection);
7921925c
JB
2037 staticpro (&Qvoid_variable);
2038 staticpro (&Qsetting_constant);
2039 staticpro (&Qinvalid_read_syntax);
2040 staticpro (&Qwrong_number_of_arguments);
2041 staticpro (&Qinvalid_function);
2042 staticpro (&Qno_catch);
2043 staticpro (&Qend_of_file);
2044 staticpro (&Qarith_error);
2045 staticpro (&Qbeginning_of_buffer);
2046 staticpro (&Qend_of_buffer);
2047 staticpro (&Qbuffer_read_only);
2048
2049 staticpro (&Qlistp);
2050 staticpro (&Qconsp);
2051 staticpro (&Qsymbolp);
2052 staticpro (&Qintegerp);
2053 staticpro (&Qnatnump);
2054 staticpro (&Qstringp);
2055 staticpro (&Qarrayp);
2056 staticpro (&Qsequencep);
2057 staticpro (&Qbufferp);
2058 staticpro (&Qvectorp);
2059 staticpro (&Qchar_or_string_p);
2060 staticpro (&Qmarkerp);
07bd8472 2061 staticpro (&Qbuffer_or_string_p);
7921925c
JB
2062 staticpro (&Qinteger_or_marker_p);
2063#ifdef LISP_FLOAT_TYPE
2064 staticpro (&Qfloatp);
464f8898
RS
2065 staticpro (&Qnumberp);
2066 staticpro (&Qnumber_or_marker_p);
7921925c
JB
2067#endif /* LISP_FLOAT_TYPE */
2068
2069 staticpro (&Qboundp);
2070 staticpro (&Qfboundp);
2071 staticpro (&Qcdr);
2072
2073 defsubr (&Seq);
2074 defsubr (&Snull);
2075 defsubr (&Slistp);
2076 defsubr (&Snlistp);
2077 defsubr (&Sconsp);
2078 defsubr (&Satom);
2079 defsubr (&Sintegerp);
464f8898 2080 defsubr (&Sinteger_or_marker_p);
7921925c
JB
2081 defsubr (&Snumberp);
2082 defsubr (&Snumber_or_marker_p);
464f8898
RS
2083#ifdef LISP_FLOAT_TYPE
2084 defsubr (&Sfloatp);
7921925c
JB
2085#endif /* LISP_FLOAT_TYPE */
2086 defsubr (&Snatnump);
2087 defsubr (&Ssymbolp);
2088 defsubr (&Sstringp);
2089 defsubr (&Svectorp);
2090 defsubr (&Sarrayp);
2091 defsubr (&Ssequencep);
2092 defsubr (&Sbufferp);
2093 defsubr (&Smarkerp);
7921925c 2094 defsubr (&Ssubrp);
dbc4e1c1 2095 defsubr (&Sbyte_code_function_p);
7921925c
JB
2096 defsubr (&Schar_or_string_p);
2097 defsubr (&Scar);
2098 defsubr (&Scdr);
2099 defsubr (&Scar_safe);
2100 defsubr (&Scdr_safe);
2101 defsubr (&Ssetcar);
2102 defsubr (&Ssetcdr);
2103 defsubr (&Ssymbol_function);
ffd56f97 2104 defsubr (&Sindirect_function);
7921925c
JB
2105 defsubr (&Ssymbol_plist);
2106 defsubr (&Ssymbol_name);
2107 defsubr (&Smakunbound);
2108 defsubr (&Sfmakunbound);
2109 defsubr (&Sboundp);
2110 defsubr (&Sfboundp);
2111 defsubr (&Sfset);
2112 defsubr (&Ssetplist);
2113 defsubr (&Ssymbol_value);
2114 defsubr (&Sset);
2115 defsubr (&Sdefault_boundp);
2116 defsubr (&Sdefault_value);
2117 defsubr (&Sset_default);
2118 defsubr (&Ssetq_default);
2119 defsubr (&Smake_variable_buffer_local);
2120 defsubr (&Smake_local_variable);
2121 defsubr (&Skill_local_variable);
2122 defsubr (&Saref);
2123 defsubr (&Saset);
f2980264 2124 defsubr (&Snumber_to_string);
25e40a4b 2125 defsubr (&Sstring_to_number);
7921925c
JB
2126 defsubr (&Seqlsign);
2127 defsubr (&Slss);
2128 defsubr (&Sgtr);
2129 defsubr (&Sleq);
2130 defsubr (&Sgeq);
2131 defsubr (&Sneq);
2132 defsubr (&Szerop);
2133 defsubr (&Splus);
2134 defsubr (&Sminus);
2135 defsubr (&Stimes);
2136 defsubr (&Squo);
2137 defsubr (&Srem);
2138 defsubr (&Smax);
2139 defsubr (&Smin);
2140 defsubr (&Slogand);
2141 defsubr (&Slogior);
2142 defsubr (&Slogxor);
2143 defsubr (&Slsh);
2144 defsubr (&Sash);
2145 defsubr (&Sadd1);
2146 defsubr (&Ssub1);
2147 defsubr (&Slognot);
2148}
2149
a33ef3ab 2150SIGTYPE
7921925c
JB
2151arith_error (signo)
2152 int signo;
2153{
2154#ifdef USG
2155 /* USG systems forget handlers when they are used;
2156 must reestablish each time */
2157 signal (signo, arith_error);
2158#endif /* USG */
2159#ifdef VMS
2160 /* VMS systems are like USG. */
2161 signal (signo, arith_error);
2162#endif /* VMS */
2163#ifdef BSD4_1
2164 sigrelse (SIGFPE);
2165#else /* not BSD4_1 */
e065a56e 2166 sigsetmask (SIGEMPTYMASK);
7921925c
JB
2167#endif /* not BSD4_1 */
2168
2169 Fsignal (Qarith_error, Qnil);
2170}
2171
2172init_data ()
2173{
2174 /* Don't do this if just dumping out.
2175 We don't want to call `signal' in this case
2176 so that we don't have trouble with dumping
2177 signal-delivering routines in an inconsistent state. */
2178#ifndef CANNOT_DUMP
2179 if (!initialized)
2180 return;
2181#endif /* CANNOT_DUMP */
2182 signal (SIGFPE, arith_error);
f58b3686 2183
7921925c
JB
2184#ifdef uts
2185 signal (SIGEMT, arith_error);
2186#endif /* uts */
2187}