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