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