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