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