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