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