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