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