Merged from emacs@sv.gnu.org.
[bpt/emacs.git] / src / data.c
CommitLineData
7921925c 1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
0b5538bd 2 Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
aaef169d 3 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
7921925c
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
7c938215 9the Free Software Foundation; either version 2, or (at your option)
7921925c
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
4fc5845f
LK
19the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20Boston, MA 02110-1301, USA. */
7921925c
JB
21
22
18160b98 23#include <config.h>
68c45bf0 24#include <signal.h>
dd8daec5 25#include <stdio.h>
7921925c 26#include "lisp.h"
29eab336 27#include "puresize.h"
8313c4e7 28#include "charset.h"
7921925c 29#include "buffer.h"
077d751f 30#include "keyboard.h"
b0c2d1c6 31#include "frame.h"
a44804c2 32#include "syssignal.h"
256c9c3a 33#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */
fb8e9847 34
93b91208 35#ifdef STDC_HEADERS
2f261542 36#include <float.h>
93b91208 37#endif
defa77b5 38
ad8d56b9
PE
39/* If IEEE_FLOATING_POINT isn't defined, default it from FLT_*. */
40#ifndef IEEE_FLOATING_POINT
41#if (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
42 && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
43#define IEEE_FLOATING_POINT 1
44#else
45#define IEEE_FLOATING_POINT 0
46#endif
47#endif
48
defa77b5
RS
49/* Work around a problem that happens because math.h on hpux 7
50 defines two static variables--which, in Emacs, are not really static,
51 because `static' is defined as nothing. The problem is that they are
52 here, in floatfns.c, and in lread.c.
53 These macros prevent the name conflict. */
54#if defined (HPUX) && !defined (HPUX8)
55#define _MAXLDBL data_c_maxldbl
56#define _NMAXLDBL data_c_nmaxldbl
57#endif
58
7921925c 59#include <math.h>
7921925c 60
024ec58f
BF
61#if !defined (atof)
62extern double atof ();
63#endif /* !atof */
64
7921925c
JB
65Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound;
66Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
67Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
ffd56f97 68Lisp_Object Qvoid_variable, Qvoid_function, Qcyclic_function_indirection;
13d95cc0 69Lisp_Object Qcyclic_variable_indirection, Qcircular_list;
7921925c
JB
70Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
71Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
3b8819d6 72Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
7921925c 73Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
8f9f49d7 74Lisp_Object Qtext_read_only;
aae13d36 75
8e86942b 76Lisp_Object Qintegerp, Qnatnump, Qwholenump, Qsymbolp, Qlistp, Qconsp;
7921925c
JB
77Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
78Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
cda9b832 79Lisp_Object Qbuffer_or_string_p, Qkeywordp;
7921925c 80Lisp_Object Qboundp, Qfboundp;
7f0edce7 81Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
39bcc759 82
7921925c 83Lisp_Object Qcdr;
c1307a23 84Lisp_Object Qad_advice_info, Qad_activate_internal;
7921925c 85
6315e761
RS
86Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
87Lisp_Object Qoverflow_error, Qunderflow_error;
88
464f8898 89Lisp_Object Qfloatp;
7921925c 90Lisp_Object Qnumberp, Qnumber_or_marker_p;
7921925c 91
aae13d36
LH
92Lisp_Object Qinteger;
93static Lisp_Object Qsymbol, Qstring, Qcons, Qmarker, Qoverlay;
8313c4e7
KH
94static Lisp_Object Qfloat, Qwindow_configuration, Qwindow;
95Lisp_Object Qprocess;
39bcc759 96static Lisp_Object Qcompiled_function, Qbuffer, Qframe, Qvector;
81dc5de5 97static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
6f0e897f 98static Lisp_Object Qsubrp, Qmany, Qunevalled;
39bcc759 99
7a283f36 100static Lisp_Object swap_in_symval_forwarding P_ ((Lisp_Object, Lisp_Object));
d02eeab3 101
9d113d9d 102Lisp_Object Vmost_positive_fixnum, Vmost_negative_fixnum;
e6190b11 103
13d95cc0
GM
104
105void
106circular_list_error (list)
107 Lisp_Object list;
108{
109 Fsignal (Qcircular_list, list);
110}
111
112
7921925c
JB
113Lisp_Object
114wrong_type_argument (predicate, value)
115 register Lisp_Object predicate, value;
116{
0c64a8cd
KS
117 /* If VALUE is not even a valid Lisp object, abort here
118 where we can get a backtrace showing where it came from. */
119 if ((unsigned int) XGCTYPE (value) >= Lisp_Type_Limit)
120 abort ();
121
122 Fsignal (Qwrong_type_argument, list2 (predicate, value));
e1351ff7 123
db926d80
DN
124 /* This function is marked as NO_RETURN, gcc would warn if it has a
125 return statement or if falls off the function. Other compilers
126 warn if no return statement is present. */
127#ifndef __GNUC__
7921925c 128 return value;
db926d80
DN
129#else
130 abort ();
131#endif
7921925c
JB
132}
133
dfcf069d 134void
7921925c
JB
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,
8c1a1077
PJ
176 doc: /* Return t if the two args are the same Lisp object. */)
177 (obj1, obj2)
7921925c
JB
178 Lisp_Object obj1, obj2;
179{
180 if (EQ (obj1, obj2))
181 return Qt;
182 return Qnil;
183}
184
8c1a1077
PJ
185DEFUN ("null", Fnull, Snull, 1, 1, 0,
186 doc: /* Return t if OBJECT is nil. */)
187 (object)
39bcc759 188 Lisp_Object object;
7921925c 189{
39bcc759 190 if (NILP (object))
7921925c
JB
191 return Qt;
192 return Qnil;
193}
194
39bcc759 195DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0,
8c1a1077
PJ
196 doc: /* Return a symbol representing the type of OBJECT.
197The symbol returned names the object's basic type;
198for example, (type-of 1) returns `integer'. */)
199 (object)
39bcc759
RS
200 Lisp_Object object;
201{
202 switch (XGCTYPE (object))
203 {
204 case Lisp_Int:
205 return Qinteger;
206
207 case Lisp_Symbol:
208 return Qsymbol;
209
210 case Lisp_String:
211 return Qstring;
212
213 case Lisp_Cons:
214 return Qcons;
215
216 case Lisp_Misc:
324a6eef 217 switch (XMISCTYPE (object))
39bcc759
RS
218 {
219 case Lisp_Misc_Marker:
220 return Qmarker;
221 case Lisp_Misc_Overlay:
222 return Qoverlay;
223 case Lisp_Misc_Float:
224 return Qfloat;
225 }
226 abort ();
227
228 case Lisp_Vectorlike:
229 if (GC_WINDOW_CONFIGURATIONP (object))
230 return Qwindow_configuration;
231 if (GC_PROCESSP (object))
232 return Qprocess;
233 if (GC_WINDOWP (object))
234 return Qwindow;
235 if (GC_SUBRP (object))
236 return Qsubr;
237 if (GC_COMPILEDP (object))
238 return Qcompiled_function;
239 if (GC_BUFFERP (object))
240 return Qbuffer;
fc67d5be
KH
241 if (GC_CHAR_TABLE_P (object))
242 return Qchar_table;
243 if (GC_BOOL_VECTOR_P (object))
244 return Qbool_vector;
39bcc759
RS
245 if (GC_FRAMEP (object))
246 return Qframe;
81dc5de5
GM
247 if (GC_HASH_TABLE_P (object))
248 return Qhash_table;
39bcc759
RS
249 return Qvector;
250
39bcc759
RS
251 case Lisp_Float:
252 return Qfloat;
39bcc759
RS
253
254 default:
255 abort ();
256 }
257}
258
8c1a1077
PJ
259DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0,
260 doc: /* Return t if OBJECT is a cons cell. */)
261 (object)
39bcc759 262 Lisp_Object object;
7921925c 263{
39bcc759 264 if (CONSP (object))
7921925c
JB
265 return Qt;
266 return Qnil;
267}
268
25638b07 269DEFUN ("atom", Fatom, Satom, 1, 1, 0,
8c1a1077
PJ
270 doc: /* Return t if OBJECT is not a cons cell. This includes nil. */)
271 (object)
39bcc759 272 Lisp_Object object;
7921925c 273{
39bcc759 274 if (CONSP (object))
7921925c
JB
275 return Qnil;
276 return Qt;
277}
278
25638b07 279DEFUN ("listp", Flistp, Slistp, 1, 1, 0,
4cdcdcc9
LT
280 doc: /* Return t if OBJECT is a list, that is, a cons cell or nil.
281Otherwise, return nil. */)
8c1a1077 282 (object)
39bcc759 283 Lisp_Object object;
7921925c 284{
39bcc759 285 if (CONSP (object) || NILP (object))
7921925c
JB
286 return Qt;
287 return Qnil;
288}
289
25638b07 290DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0,
8c1a1077
PJ
291 doc: /* Return t if OBJECT is not a list. Lists include nil. */)
292 (object)
39bcc759 293 Lisp_Object object;
7921925c 294{
39bcc759 295 if (CONSP (object) || NILP (object))
7921925c
JB
296 return Qnil;
297 return Qt;
298}
299\f
25638b07 300DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0,
8c1a1077
PJ
301 doc: /* Return t if OBJECT is a symbol. */)
302 (object)
39bcc759 303 Lisp_Object object;
7921925c 304{
39bcc759 305 if (SYMBOLP (object))
7921925c
JB
306 return Qt;
307 return Qnil;
308}
309
cda9b832
DL
310/* Define this in C to avoid unnecessarily consing up the symbol
311 name. */
312DEFUN ("keywordp", Fkeywordp, Skeywordp, 1, 1, 0,
8c1a1077
PJ
313 doc: /* Return t if OBJECT is a keyword.
314This means that it is a symbol with a print name beginning with `:'
315interned in the initial obarray. */)
316 (object)
cda9b832
DL
317 Lisp_Object object;
318{
319 if (SYMBOLP (object)
d5db4077 320 && SREF (SYMBOL_NAME (object), 0) == ':'
f35d5bad 321 && SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (object))
cda9b832
DL
322 return Qt;
323 return Qnil;
324}
325
25638b07 326DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0,
8c1a1077
PJ
327 doc: /* Return t if OBJECT is a vector. */)
328 (object)
39bcc759 329 Lisp_Object object;
7921925c 330{
39bcc759 331 if (VECTORP (object))
7921925c
JB
332 return Qt;
333 return Qnil;
334}
335
25638b07 336DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0,
8c1a1077
PJ
337 doc: /* Return t if OBJECT is a string. */)
338 (object)
39bcc759 339 Lisp_Object object;
7921925c 340{
39bcc759 341 if (STRINGP (object))
7921925c
JB
342 return Qt;
343 return Qnil;
344}
345
25638b07 346DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p,
8c1a1077
PJ
347 1, 1, 0,
348 doc: /* Return t if OBJECT is a multibyte string. */)
349 (object)
25638b07
RS
350 Lisp_Object object;
351{
352 if (STRINGP (object) && STRING_MULTIBYTE (object))
353 return Qt;
354 return Qnil;
355}
356
357DEFUN ("char-table-p", Fchar_table_p, Schar_table_p, 1, 1, 0,
8c1a1077
PJ
358 doc: /* Return t if OBJECT is a char-table. */)
359 (object)
4d276982
RS
360 Lisp_Object object;
361{
362 if (CHAR_TABLE_P (object))
363 return Qt;
364 return Qnil;
365}
366
7f0edce7
RS
367DEFUN ("vector-or-char-table-p", Fvector_or_char_table_p,
368 Svector_or_char_table_p, 1, 1, 0,
8c1a1077
PJ
369 doc: /* Return t if OBJECT is a char-table or vector. */)
370 (object)
7f0edce7
RS
371 Lisp_Object object;
372{
373 if (VECTORP (object) || CHAR_TABLE_P (object))
374 return Qt;
375 return Qnil;
376}
377
8c1a1077
PJ
378DEFUN ("bool-vector-p", Fbool_vector_p, Sbool_vector_p, 1, 1, 0,
379 doc: /* Return t if OBJECT is a bool-vector. */)
380 (object)
4d276982
RS
381 Lisp_Object object;
382{
383 if (BOOL_VECTOR_P (object))
384 return Qt;
385 return Qnil;
386}
387
8c1a1077
PJ
388DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0,
389 doc: /* Return t if OBJECT is an array (string or vector). */)
390 (object)
39bcc759 391 Lisp_Object object;
7921925c 392{
0c64a8cd 393 if (ARRAYP (object))
7921925c
JB
394 return Qt;
395 return Qnil;
396}
397
398DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0,
8c1a1077
PJ
399 doc: /* Return t if OBJECT is a sequence (list or array). */)
400 (object)
39bcc759 401 register Lisp_Object object;
7921925c 402{
0c64a8cd 403 if (CONSP (object) || NILP (object) || ARRAYP (object))
7921925c
JB
404 return Qt;
405 return Qnil;
406}
407
8c1a1077
PJ
408DEFUN ("bufferp", Fbufferp, Sbufferp, 1, 1, 0,
409 doc: /* Return t if OBJECT is an editor buffer. */)
410 (object)
39bcc759 411 Lisp_Object object;
7921925c 412{
39bcc759 413 if (BUFFERP (object))
7921925c
JB
414 return Qt;
415 return Qnil;
416}
417
8c1a1077
PJ
418DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0,
419 doc: /* Return t if OBJECT is a marker (editor pointer). */)
420 (object)
39bcc759 421 Lisp_Object object;
7921925c 422{
39bcc759 423 if (MARKERP (object))
7921925c
JB
424 return Qt;
425 return Qnil;
426}
427
8c1a1077
PJ
428DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0,
429 doc: /* Return t if OBJECT is a built-in function. */)
430 (object)
39bcc759 431 Lisp_Object object;
7921925c 432{
39bcc759 433 if (SUBRP (object))
7921925c
JB
434 return Qt;
435 return Qnil;
436}
437
dbc4e1c1 438DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
8c1a1077
PJ
439 1, 1, 0,
440 doc: /* Return t if OBJECT is a byte-compiled function object. */)
441 (object)
39bcc759 442 Lisp_Object object;
7921925c 443{
39bcc759 444 if (COMPILEDP (object))
7921925c
JB
445 return Qt;
446 return Qnil;
447}
448
0321d75c 449DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0,
8c1a1077
PJ
450 doc: /* Return t if OBJECT is a character (an integer) or a string. */)
451 (object)
39bcc759 452 register Lisp_Object object;
7921925c 453{
39bcc759 454 if (INTEGERP (object) || STRINGP (object))
7921925c
JB
455 return Qt;
456 return Qnil;
457}
458\f
8c1a1077
PJ
459DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0,
460 doc: /* Return t if OBJECT is an integer. */)
461 (object)
39bcc759 462 Lisp_Object object;
7921925c 463{
39bcc759 464 if (INTEGERP (object))
7921925c
JB
465 return Qt;
466 return Qnil;
467}
468
464f8898 469DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0,
8c1a1077
PJ
470 doc: /* Return t if OBJECT is an integer or a marker (editor pointer). */)
471 (object)
39bcc759 472 register Lisp_Object object;
7921925c 473{
39bcc759 474 if (MARKERP (object) || INTEGERP (object))
7921925c
JB
475 return Qt;
476 return Qnil;
477}
478
0321d75c 479DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0,
8c1a1077
PJ
480 doc: /* Return t if OBJECT is a nonnegative integer. */)
481 (object)
39bcc759 482 Lisp_Object object;
7921925c 483{
39bcc759 484 if (NATNUMP (object))
7921925c
JB
485 return Qt;
486 return Qnil;
487}
488
489DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
8c1a1077
PJ
490 doc: /* Return t if OBJECT is a number (floating point or integer). */)
491 (object)
39bcc759 492 Lisp_Object object;
7921925c 493{
39bcc759 494 if (NUMBERP (object))
7921925c 495 return Qt;
dbc4e1c1
JB
496 else
497 return Qnil;
7921925c
JB
498}
499
500DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
501 Snumber_or_marker_p, 1, 1, 0,
8c1a1077
PJ
502 doc: /* Return t if OBJECT is a number or a marker. */)
503 (object)
39bcc759 504 Lisp_Object object;
7921925c 505{
39bcc759 506 if (NUMBERP (object) || MARKERP (object))
7921925c
JB
507 return Qt;
508 return Qnil;
509}
464f8898 510
464f8898 511DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
8c1a1077
PJ
512 doc: /* Return t if OBJECT is a floating point number. */)
513 (object)
39bcc759 514 Lisp_Object object;
464f8898 515{
39bcc759 516 if (FLOATP (object))
464f8898
RS
517 return Qt;
518 return Qnil;
519}
cc94f3b2 520
7921925c
JB
521\f
522/* Extract and set components of lists */
523
524DEFUN ("car", Fcar, Scar, 1, 1, 0,
8c1a1077 525 doc: /* Return the car of LIST. If arg is nil, return nil.
9701c742
LT
526Error if arg is not nil and not a cons cell. See also `car-safe'.
527
da46c5be
LT
528See Info node `(elisp)Cons Cells' for a discussion of related basic
529Lisp concepts such as car, cdr, cons cell and list. */)
8c1a1077 530 (list)
7921925c
JB
531 register Lisp_Object list;
532{
0c64a8cd 533 return CAR (list);
7921925c
JB
534}
535
536DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
8c1a1077
PJ
537 doc: /* Return the car of OBJECT if it is a cons cell, or else nil. */)
538 (object)
7921925c
JB
539 Lisp_Object object;
540{
0c64a8cd 541 return CAR_SAFE (object);
7921925c
JB
542}
543
544DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
8c1a1077 545 doc: /* Return the cdr of LIST. If arg is nil, return nil.
9701c742
LT
546Error if arg is not nil and not a cons cell. See also `cdr-safe'.
547
da46c5be
LT
548See Info node `(elisp)Cons Cells' for a discussion of related basic
549Lisp concepts such as cdr, car, cons cell and list. */)
8c1a1077 550 (list)
7921925c
JB
551 register Lisp_Object list;
552{
0c64a8cd 553 return CDR (list);
7921925c
JB
554}
555
556DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
8c1a1077
PJ
557 doc: /* Return the cdr of OBJECT if it is a cons cell, or else nil. */)
558 (object)
7921925c
JB
559 Lisp_Object object;
560{
0c64a8cd 561 return CDR_SAFE (object);
7921925c
JB
562}
563
564DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
8c1a1077
PJ
565 doc: /* Set the car of CELL to be NEWCAR. Returns NEWCAR. */)
566 (cell, newcar)
7921925c
JB
567 register Lisp_Object cell, newcar;
568{
0c64a8cd 569 CHECK_CONS (cell);
7921925c 570 CHECK_IMPURE (cell);
f3fbd155 571 XSETCAR (cell, newcar);
7921925c
JB
572 return newcar;
573}
574
575DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
8c1a1077
PJ
576 doc: /* Set the cdr of CELL to be NEWCDR. Returns NEWCDR. */)
577 (cell, newcdr)
7921925c
JB
578 register Lisp_Object cell, newcdr;
579{
0c64a8cd 580 CHECK_CONS (cell);
7921925c 581 CHECK_IMPURE (cell);
f3fbd155 582 XSETCDR (cell, newcdr);
7921925c
JB
583 return newcdr;
584}
585\f
586/* Extract and set components of symbols */
587
8c1a1077
PJ
588DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0,
589 doc: /* Return t if SYMBOL's value is not void. */)
590 (symbol)
d9c2a0f2 591 register Lisp_Object symbol;
7921925c
JB
592{
593 Lisp_Object valcontents;
b7826503 594 CHECK_SYMBOL (symbol);
7921925c 595
f35d5bad 596 valcontents = SYMBOL_VALUE (symbol);
7921925c 597
aabf6bec
KH
598 if (BUFFER_LOCAL_VALUEP (valcontents)
599 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 600 valcontents = swap_in_symval_forwarding (symbol, valcontents);
7921925c 601
1bfcade3 602 return (EQ (valcontents, Qunbound) ? Qnil : Qt);
7921925c
JB
603}
604
8c1a1077
PJ
605DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0,
606 doc: /* Return t if SYMBOL's function definition is not void. */)
607 (symbol)
d9c2a0f2 608 register Lisp_Object symbol;
7921925c 609{
b7826503 610 CHECK_SYMBOL (symbol);
d9c2a0f2 611 return (EQ (XSYMBOL (symbol)->function, Qunbound) ? Qnil : Qt);
7921925c
JB
612}
613
8c1a1077 614DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0,
bfb96cb7
FP
615 doc: /* Make SYMBOL's value be void.
616Return SYMBOL. */)
8c1a1077 617 (symbol)
d9c2a0f2 618 register Lisp_Object symbol;
7921925c 619{
b7826503 620 CHECK_SYMBOL (symbol);
f35d5bad 621 if (XSYMBOL (symbol)->constant)
d9c2a0f2
EN
622 return Fsignal (Qsetting_constant, Fcons (symbol, Qnil));
623 Fset (symbol, Qunbound);
624 return symbol;
7921925c
JB
625}
626
8c1a1077 627DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0,
bfb96cb7
FP
628 doc: /* Make SYMBOL's function definition be void.
629Return SYMBOL. */)
8c1a1077 630 (symbol)
d9c2a0f2 631 register Lisp_Object symbol;
7921925c 632{
b7826503 633 CHECK_SYMBOL (symbol);
d9c2a0f2
EN
634 if (NILP (symbol) || EQ (symbol, Qt))
635 return Fsignal (Qsetting_constant, Fcons (symbol, Qnil));
636 XSYMBOL (symbol)->function = Qunbound;
637 return symbol;
7921925c
JB
638}
639
640DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
8c1a1077
PJ
641 doc: /* Return SYMBOL's function definition. Error if that is void. */)
642 (symbol)
ffd56f97 643 register Lisp_Object symbol;
7921925c 644{
b7826503 645 CHECK_SYMBOL (symbol);
ffd56f97
JB
646 if (EQ (XSYMBOL (symbol)->function, Qunbound))
647 return Fsignal (Qvoid_function, Fcons (symbol, Qnil));
648 return XSYMBOL (symbol)->function;
7921925c
JB
649}
650
8c1a1077
PJ
651DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0,
652 doc: /* Return SYMBOL's property list. */)
653 (symbol)
d9c2a0f2 654 register Lisp_Object symbol;
7921925c 655{
b7826503 656 CHECK_SYMBOL (symbol);
d9c2a0f2 657 return XSYMBOL (symbol)->plist;
7921925c
JB
658}
659
8c1a1077
PJ
660DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
661 doc: /* Return SYMBOL's name, a string. */)
662 (symbol)
d9c2a0f2 663 register Lisp_Object symbol;
7921925c
JB
664{
665 register Lisp_Object name;
666
b7826503 667 CHECK_SYMBOL (symbol);
84023177 668 name = SYMBOL_NAME (symbol);
7921925c
JB
669 return name;
670}
671
672DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
8c1a1077
PJ
673 doc: /* Set SYMBOL's function definition to DEFINITION, and return DEFINITION. */)
674 (symbol, definition)
8c0b5540 675 register Lisp_Object symbol, definition;
d9c2a0f2 676{
b7826503 677 CHECK_SYMBOL (symbol);
d9c2a0f2
EN
678 if (NILP (symbol) || EQ (symbol, Qt))
679 return Fsignal (Qsetting_constant, Fcons (symbol, Qnil));
680 if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (symbol)->function, Qunbound))
681 Vautoload_queue = Fcons (Fcons (symbol, XSYMBOL (symbol)->function),
7921925c 682 Vautoload_queue);
8c0b5540 683 XSYMBOL (symbol)->function = definition;
f845f2c9 684 /* Handle automatic advice activation */
d9c2a0f2 685 if (CONSP (XSYMBOL (symbol)->plist) && !NILP (Fget (symbol, Qad_advice_info)))
f845f2c9 686 {
c1307a23 687 call2 (Qad_activate_internal, symbol, Qnil);
8c0b5540 688 definition = XSYMBOL (symbol)->function;
f845f2c9 689 }
8c0b5540 690 return definition;
7921925c
JB
691}
692
d2fde41d
SM
693extern Lisp_Object Qfunction_documentation;
694
695DEFUN ("defalias", Fdefalias, Sdefalias, 2, 3, 0,
8c1a1077 696 doc: /* Set SYMBOL's function definition to DEFINITION, and return DEFINITION.
96143227
RS
697Associates the function with the current load file, if any.
698The optional third argument DOCSTRING specifies the documentation string
699for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string
700determined by DEFINITION. */)
d2fde41d
SM
701 (symbol, definition, docstring)
702 register Lisp_Object symbol, definition, docstring;
fc08c367 703{
8a658a52 704 CHECK_SYMBOL (symbol);
894f6538
RS
705 if (CONSP (XSYMBOL (symbol)->function)
706 && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload))
707 LOADHIST_ATTACH (Fcons (Qt, symbol));
32f532b7 708 definition = Ffset (symbol, definition);
62a29071 709 LOADHIST_ATTACH (Fcons (Qdefun, symbol));
d2fde41d
SM
710 if (!NILP (docstring))
711 Fput (symbol, Qfunction_documentation, docstring);
73e0d965 712 return definition;
fc08c367
RS
713}
714
7921925c 715DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0,
29802b85 716 doc: /* Set SYMBOL's property list to NEWPLIST, and return NEWPLIST. */)
8c1a1077 717 (symbol, newplist)
d9c2a0f2 718 register Lisp_Object symbol, newplist;
7921925c 719{
b7826503 720 CHECK_SYMBOL (symbol);
d9c2a0f2 721 XSYMBOL (symbol)->plist = newplist;
7921925c
JB
722 return newplist;
723}
ffd56f97 724
6f0e897f 725DEFUN ("subr-arity", Fsubr_arity, Ssubr_arity, 1, 1, 0,
8c1a1077
PJ
726 doc: /* Return minimum and maximum number of args allowed for SUBR.
727SUBR must be a built-in function.
728The returned value is a pair (MIN . MAX). MIN is the minimum number
729of args. MAX is the maximum number or the symbol `many', for a
730function with `&rest' args, or `unevalled' for a special form. */)
731 (subr)
6f0e897f
DL
732 Lisp_Object subr;
733{
734 short minargs, maxargs;
0c64a8cd 735 CHECK_SUBR (subr);
6f0e897f
DL
736 minargs = XSUBR (subr)->min_args;
737 maxargs = XSUBR (subr)->max_args;
738 if (maxargs == MANY)
739 return Fcons (make_number (minargs), Qmany);
740 else if (maxargs == UNEVALLED)
741 return Fcons (make_number (minargs), Qunevalled);
742 else
743 return Fcons (make_number (minargs), make_number (maxargs));
744}
745
0fddae66
SM
746DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
747 doc: /* Return name of subroutine SUBR.
748SUBR must be a built-in function. */)
749 (subr)
750 Lisp_Object subr;
751{
752 const char *name;
0c64a8cd 753 CHECK_SUBR (subr);
0fddae66
SM
754 name = XSUBR (subr)->symbol_name;
755 return make_string (name, strlen (name));
756}
757
f52a3ca3
SM
758DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0,
759 doc: /* Return the interactive form of CMD or nil if none.
df133612
LT
760If CMD is not a command, the return value is nil.
761Value, if non-nil, is a list \(interactive SPEC). */)
f52a3ca3
SM
762 (cmd)
763 Lisp_Object cmd;
cc515226 764{
f52a3ca3
SM
765 Lisp_Object fun = indirect_function (cmd);
766
767 if (SUBRP (fun))
768 {
769 if (XSUBR (fun)->prompt)
770 return list2 (Qinteractive, build_string (XSUBR (fun)->prompt));
771 }
772 else if (COMPILEDP (fun))
773 {
774 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE)
775 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE));
776 }
777 else if (CONSP (fun))
778 {
779 Lisp_Object funcar = XCAR (fun);
780 if (EQ (funcar, Qlambda))
781 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
782 else if (EQ (funcar, Qautoload))
783 {
784 struct gcpro gcpro1;
785 GCPRO1 (cmd);
786 do_autoload (fun, cmd);
787 UNGCPRO;
788 return Finteractive_form (cmd);
789 }
790 }
cc515226
GM
791 return Qnil;
792}
793
7921925c 794\f
f35d5bad
GM
795/***********************************************************************
796 Getting and Setting Values of Symbols
797 ***********************************************************************/
798
799/* Return the symbol holding SYMBOL's value. Signal
800 `cyclic-variable-indirection' if SYMBOL's chain of variable
801 indirections contains a loop. */
802
803Lisp_Object
804indirect_variable (symbol)
805 Lisp_Object symbol;
806{
807 Lisp_Object tortoise, hare;
808
809 hare = tortoise = symbol;
810
811 while (XSYMBOL (hare)->indirect_variable)
812 {
813 hare = XSYMBOL (hare)->value;
814 if (!XSYMBOL (hare)->indirect_variable)
815 break;
bfb96cb7 816
f35d5bad
GM
817 hare = XSYMBOL (hare)->value;
818 tortoise = XSYMBOL (tortoise)->value;
819
820 if (EQ (hare, tortoise))
821 Fsignal (Qcyclic_variable_indirection, Fcons (symbol, Qnil));
822 }
823
824 return hare;
825}
826
827
828DEFUN ("indirect-variable", Findirect_variable, Sindirect_variable, 1, 1, 0,
8c1a1077
PJ
829 doc: /* Return the variable at the end of OBJECT's variable chain.
830If OBJECT is a symbol, follow all variable indirections and return the final
831variable. If OBJECT is not a symbol, just return it.
832Signal a cyclic-variable-indirection error if there is a loop in the
833variable chain of symbols. */)
834 (object)
f35d5bad
GM
835 Lisp_Object object;
836{
837 if (SYMBOLP (object))
838 object = indirect_variable (object);
839 return object;
840}
841
7921925c
JB
842
843/* Given the raw contents of a symbol value cell,
844 return the Lisp value of the symbol.
845 This does not handle buffer-local variables; use
846 swap_in_symval_forwarding for that. */
847
848Lisp_Object
849do_symval_forwarding (valcontents)
850 register Lisp_Object valcontents;
851{
852 register Lisp_Object val;
46b2ac21
KH
853 int offset;
854 if (MISCP (valcontents))
324a6eef 855 switch (XMISCTYPE (valcontents))
46b2ac21
KH
856 {
857 case Lisp_Misc_Intfwd:
858 XSETINT (val, *XINTFWD (valcontents)->intvar);
859 return val;
7921925c 860
46b2ac21
KH
861 case Lisp_Misc_Boolfwd:
862 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
7921925c 863
46b2ac21
KH
864 case Lisp_Misc_Objfwd:
865 return *XOBJFWD (valcontents)->objvar;
7921925c 866
46b2ac21
KH
867 case Lisp_Misc_Buffer_Objfwd:
868 offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527 869 return PER_BUFFER_VALUE (current_buffer, offset);
7403b5c8 870
e5f8af9e
KH
871 case Lisp_Misc_Kboard_Objfwd:
872 offset = XKBOARD_OBJFWD (valcontents)->offset;
c40bb1ba
KL
873 /* We used to simply use current_kboard here, but from Lisp
874 code, it's value is often unexpected. It seems nicer to
875 allow constructions like this to work as intuitively expected:
876
877 (with-selected-frame frame
878 (define-key local-function-map "\eOP" [f1]))
879
880 On the other hand, this affects the semantics of
881 last-command and real-last-command, and people may rely on
882 that. I took a quick look at the Lisp codebase, and I
883 don't think anything will break. --lorentey */
884 return *(Lisp_Object *)(offset + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
46b2ac21 885 }
7921925c
JB
886 return valcontents;
887}
888
d9c2a0f2
EN
889/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
890 of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the
7921925c 891 buffer-independent contents of the value cell: forwarded just one
7a283f36
GM
892 step past the buffer-localness.
893
894 BUF non-zero means set the value in buffer BUF instead of the
895 current buffer. This only plays a role for per-buffer variables. */
7921925c
JB
896
897void
7a283f36 898store_symval_forwarding (symbol, valcontents, newval, buf)
d9c2a0f2 899 Lisp_Object symbol;
7921925c 900 register Lisp_Object valcontents, newval;
7a283f36 901 struct buffer *buf;
7921925c 902{
0220c518 903 switch (SWITCH_ENUM_CAST (XTYPE (valcontents)))
7921925c 904 {
46b2ac21 905 case Lisp_Misc:
324a6eef 906 switch (XMISCTYPE (valcontents))
46b2ac21
KH
907 {
908 case Lisp_Misc_Intfwd:
b7826503 909 CHECK_NUMBER (newval);
46b2ac21 910 *XINTFWD (valcontents)->intvar = XINT (newval);
e6c82a8d
RS
911 if (*XINTFWD (valcontents)->intvar != XINT (newval))
912 error ("Value out of range for variable `%s'",
d5db4077 913 SDATA (SYMBOL_NAME (symbol)));
46b2ac21
KH
914 break;
915
916 case Lisp_Misc_Boolfwd:
917 *XBOOLFWD (valcontents)->boolvar = NILP (newval) ? 0 : 1;
918 break;
919
920 case Lisp_Misc_Objfwd:
921 *XOBJFWD (valcontents)->objvar = newval;
7abd90ea
RS
922
923 /* If this variable is a default for something stored
924 in the buffer itself, such as default-fill-column,
925 find the buffers that don't have local values for it
926 and update them. */
927 if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults
928 && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1))
929 {
930 int offset = ((char *) XOBJFWD (valcontents)->objvar
931 - (char *) &buffer_defaults);
932 int idx = PER_BUFFER_IDX (offset);
933
43e50e40 934 Lisp_Object tail;
7abd90ea
RS
935
936 if (idx <= 0)
937 break;
938
939 for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
940 {
941 Lisp_Object buf;
942 struct buffer *b;
943
944 buf = Fcdr (XCAR (tail));
945 if (!BUFFERP (buf)) continue;
946 b = XBUFFER (buf);
947
948 if (! PER_BUFFER_VALUE_P (b, idx))
949 PER_BUFFER_VALUE (b, offset) = newval;
950 }
951 }
46b2ac21
KH
952 break;
953
954 case Lisp_Misc_Buffer_Objfwd:
955 {
956 int offset = XBUFFER_OBJFWD (valcontents)->offset;
957 Lisp_Object type;
958
d9b36d19 959 type = PER_BUFFER_TYPE (offset);
46b2ac21
KH
960 if (! NILP (type) && ! NILP (newval)
961 && XTYPE (newval) != XINT (type))
962 buffer_slot_type_mismatch (offset);
963
7a283f36
GM
964 if (buf == NULL)
965 buf = current_buffer;
966 PER_BUFFER_VALUE (buf, offset) = newval;
46b2ac21 967 }
7403b5c8
KH
968 break;
969
e5f8af9e 970 case Lisp_Misc_Kboard_Objfwd:
7a283f36 971 {
c40bb1ba 972 char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ());
7a283f36
GM
973 char *p = base + XKBOARD_OBJFWD (valcontents)->offset;
974 *(Lisp_Object *) p = newval;
975 }
7403b5c8
KH
976 break;
977
46b2ac21
KH
978 default:
979 goto def;
980 }
7921925c
JB
981 break;
982
7921925c 983 default:
46b2ac21 984 def:
f35d5bad 985 valcontents = SYMBOL_VALUE (symbol);
e9ebc175
KH
986 if (BUFFER_LOCAL_VALUEP (valcontents)
987 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
b0c2d1c6 988 XBUFFER_LOCAL_VALUE (valcontents)->realvalue = newval;
7921925c 989 else
f35d5bad 990 SET_SYMBOL_VALUE (symbol, newval);
7921925c
JB
991 }
992}
993
b0d53add
GM
994/* Set up SYMBOL to refer to its global binding.
995 This makes it safe to alter the status of other bindings. */
996
997void
998swap_in_global_binding (symbol)
999 Lisp_Object symbol;
1000{
1001 Lisp_Object valcontents, cdr;
bfb96cb7 1002
f35d5bad 1003 valcontents = SYMBOL_VALUE (symbol);
b0d53add
GM
1004 if (!BUFFER_LOCAL_VALUEP (valcontents)
1005 && !SOME_BUFFER_LOCAL_VALUEP (valcontents))
1006 abort ();
1007 cdr = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
1008
1009 /* Unload the previously loaded binding. */
1010 Fsetcdr (XCAR (cdr),
1011 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
bfb96cb7 1012
b0d53add 1013 /* Select the global binding in the symbol. */
f3fbd155 1014 XSETCAR (cdr, cdr);
7a283f36 1015 store_symval_forwarding (symbol, valcontents, XCDR (cdr), NULL);
b0d53add
GM
1016
1017 /* Indicate that the global binding is set up now. */
1018 XBUFFER_LOCAL_VALUE (valcontents)->frame = Qnil;
1019 XBUFFER_LOCAL_VALUE (valcontents)->buffer = Qnil;
1020 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0;
1021 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
1022}
1023
2829d05f 1024/* Set up the buffer-local symbol SYMBOL for validity in the current buffer.
42e975f0
RS
1025 VALCONTENTS is the contents of its value cell,
1026 which points to a struct Lisp_Buffer_Local_Value.
1027
1028 Return the value forwarded one step past the buffer-local stage.
1029 This could be another forwarding pointer. */
7921925c
JB
1030
1031static Lisp_Object
d9c2a0f2
EN
1032swap_in_symval_forwarding (symbol, valcontents)
1033 Lisp_Object symbol, valcontents;
7921925c 1034{
7921925c 1035 register Lisp_Object tem1;
bfb96cb7 1036
b0c2d1c6 1037 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->buffer;
7921925c 1038
42e975f0
RS
1039 if (NILP (tem1)
1040 || current_buffer != XBUFFER (tem1)
1041 || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1042 && ! EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame)))
7921925c 1043 {
f35d5bad
GM
1044 if (XSYMBOL (symbol)->indirect_variable)
1045 symbol = indirect_variable (symbol);
bfb96cb7 1046
42e975f0 1047 /* Unload the previously loaded binding. */
7539e11f 1048 tem1 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
8d4afcac 1049 Fsetcdr (tem1,
b0c2d1c6 1050 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
42e975f0 1051 /* Choose the new binding. */
d9c2a0f2 1052 tem1 = assq_no_quit (symbol, current_buffer->local_var_alist);
b0c2d1c6
RS
1053 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0;
1054 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
a33ef3ab 1055 if (NILP (tem1))
b0c2d1c6
RS
1056 {
1057 if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame)
1cc04aed 1058 tem1 = assq_no_quit (symbol, XFRAME (selected_frame)->param_alist);
b0c2d1c6
RS
1059 if (! NILP (tem1))
1060 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1;
1061 else
1062 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
1063 }
1064 else
1065 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1;
1066
42e975f0 1067 /* Load the new binding. */
f3fbd155 1068 XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, tem1);
b0c2d1c6 1069 XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, current_buffer);
1cc04aed 1070 XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame;
b0c2d1c6
RS
1071 store_symval_forwarding (symbol,
1072 XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
7a283f36 1073 Fcdr (tem1), NULL);
7921925c 1074 }
b0c2d1c6 1075 return XBUFFER_LOCAL_VALUE (valcontents)->realvalue;
7921925c
JB
1076}
1077\f
14e76af9
JB
1078/* Find the value of a symbol, returning Qunbound if it's not bound.
1079 This is helpful for code which just wants to get a variable's value
8e6208c5 1080 if it has one, without signaling an error.
14e76af9
JB
1081 Note that it must not be possible to quit
1082 within this function. Great care is required for this. */
7921925c 1083
14e76af9 1084Lisp_Object
d9c2a0f2
EN
1085find_symbol_value (symbol)
1086 Lisp_Object symbol;
7921925c 1087{
dd8daec5 1088 register Lisp_Object valcontents;
7921925c 1089 register Lisp_Object val;
bfb96cb7 1090
b7826503 1091 CHECK_SYMBOL (symbol);
f35d5bad 1092 valcontents = SYMBOL_VALUE (symbol);
7921925c 1093
aabf6bec
KH
1094 if (BUFFER_LOCAL_VALUEP (valcontents)
1095 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
2a359158 1096 valcontents = swap_in_symval_forwarding (symbol, valcontents);
7921925c 1097
536b772a
KH
1098 if (MISCP (valcontents))
1099 {
324a6eef 1100 switch (XMISCTYPE (valcontents))
46b2ac21
KH
1101 {
1102 case Lisp_Misc_Intfwd:
1103 XSETINT (val, *XINTFWD (valcontents)->intvar);
1104 return val;
7921925c 1105
46b2ac21
KH
1106 case Lisp_Misc_Boolfwd:
1107 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
7921925c 1108
46b2ac21
KH
1109 case Lisp_Misc_Objfwd:
1110 return *XOBJFWD (valcontents)->objvar;
7921925c 1111
46b2ac21 1112 case Lisp_Misc_Buffer_Objfwd:
f6cd0527 1113 return PER_BUFFER_VALUE (current_buffer,
999b32fd 1114 XBUFFER_OBJFWD (valcontents)->offset);
7403b5c8 1115
e5f8af9e
KH
1116 case Lisp_Misc_Kboard_Objfwd:
1117 return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset
c40bb1ba 1118 + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
46b2ac21 1119 }
7921925c
JB
1120 }
1121
1122 return valcontents;
1123}
1124
14e76af9 1125DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
8c1a1077
PJ
1126 doc: /* Return SYMBOL's value. Error if that is void. */)
1127 (symbol)
d9c2a0f2 1128 Lisp_Object symbol;
14e76af9 1129{
0671d7c0 1130 Lisp_Object val;
14e76af9 1131
d9c2a0f2 1132 val = find_symbol_value (symbol);
14e76af9 1133 if (EQ (val, Qunbound))
d9c2a0f2 1134 return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
14e76af9
JB
1135 else
1136 return val;
1137}
1138
7921925c 1139DEFUN ("set", Fset, Sset, 2, 2, 0,
8c1a1077
PJ
1140 doc: /* Set SYMBOL's value to NEWVAL, and return NEWVAL. */)
1141 (symbol, newval)
d9c2a0f2 1142 register Lisp_Object symbol, newval;
05ef7169 1143{
2829d05f 1144 return set_internal (symbol, newval, current_buffer, 0);
05ef7169
RS
1145}
1146
1f35ce36
RS
1147/* Return 1 if SYMBOL currently has a let-binding
1148 which was made in the buffer that is now current. */
1149
1150static int
1151let_shadows_buffer_binding_p (symbol)
1152 Lisp_Object symbol;
1153{
92426155 1154 volatile struct specbinding *p;
1f35ce36
RS
1155
1156 for (p = specpdl_ptr - 1; p >= specpdl; p--)
f35d5bad
GM
1157 if (p->func == NULL
1158 && CONSP (p->symbol))
1159 {
1160 Lisp_Object let_bound_symbol = XCAR (p->symbol);
1161 if ((EQ (symbol, let_bound_symbol)
1162 || (XSYMBOL (let_bound_symbol)->indirect_variable
1163 && EQ (symbol, indirect_variable (let_bound_symbol))))
1164 && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
1165 break;
1166 }
1f35ce36 1167
f35d5bad 1168 return p >= specpdl;
1f35ce36
RS
1169}
1170
25638b07 1171/* Store the value NEWVAL into SYMBOL.
2829d05f
RS
1172 If buffer-locality is an issue, BUF specifies which buffer to use.
1173 (0 stands for the current buffer.)
1174
05ef7169
RS
1175 If BINDFLAG is zero, then if this symbol is supposed to become
1176 local in every buffer where it is set, then we make it local.
1177 If BINDFLAG is nonzero, we don't do that. */
1178
1179Lisp_Object
2829d05f 1180set_internal (symbol, newval, buf, bindflag)
05ef7169 1181 register Lisp_Object symbol, newval;
2829d05f 1182 struct buffer *buf;
05ef7169 1183 int bindflag;
7921925c 1184{
1bfcade3 1185 int voide = EQ (newval, Qunbound);
7921925c 1186
4c47c973 1187 register Lisp_Object valcontents, innercontents, tem1, current_alist_element;
7921925c 1188
2829d05f
RS
1189 if (buf == 0)
1190 buf = current_buffer;
1191
1192 /* If restoring in a dead buffer, do nothing. */
1193 if (NILP (buf->name))
1194 return newval;
1195
b7826503 1196 CHECK_SYMBOL (symbol);
f35d5bad
GM
1197 if (SYMBOL_CONSTANT_P (symbol)
1198 && (NILP (Fkeywordp (symbol))
1199 || !EQ (newval, SYMBOL_VALUE (symbol))))
d9c2a0f2 1200 return Fsignal (Qsetting_constant, Fcons (symbol, Qnil));
4c47c973 1201
f35d5bad 1202 innercontents = valcontents = SYMBOL_VALUE (symbol);
bfb96cb7 1203
e9ebc175 1204 if (BUFFER_OBJFWDP (valcontents))
7921925c 1205 {
999b32fd 1206 int offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527 1207 int idx = PER_BUFFER_IDX (offset);
999b32fd
GM
1208 if (idx > 0
1209 && !bindflag
1210 && !let_shadows_buffer_binding_p (symbol))
f6cd0527 1211 SET_PER_BUFFER_VALUE_P (buf, idx, 1);
7921925c 1212 }
e9ebc175
KH
1213 else if (BUFFER_LOCAL_VALUEP (valcontents)
1214 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 1215 {
42e975f0 1216 /* valcontents is a struct Lisp_Buffer_Local_Value. */
f35d5bad
GM
1217 if (XSYMBOL (symbol)->indirect_variable)
1218 symbol = indirect_variable (symbol);
42e975f0
RS
1219
1220 /* What binding is loaded right now? */
b0c2d1c6 1221 current_alist_element
7539e11f 1222 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
d8cafeb5
JB
1223
1224 /* If the current buffer is not the buffer whose binding is
42e975f0
RS
1225 loaded, or if there may be frame-local bindings and the frame
1226 isn't the right one, or if it's a Lisp_Buffer_Local_Value and
1227 the default binding is loaded, the loaded binding may be the
1228 wrong one. */
8801a864
KR
1229 if (!BUFFERP (XBUFFER_LOCAL_VALUE (valcontents)->buffer)
1230 || buf != XBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer)
42e975f0
RS
1231 || (XBUFFER_LOCAL_VALUE (valcontents)->check_frame
1232 && !EQ (selected_frame, XBUFFER_LOCAL_VALUE (valcontents)->frame))
1233 || (BUFFER_LOCAL_VALUEP (valcontents)
1234 && EQ (XCAR (current_alist_element),
1235 current_alist_element)))
7921925c 1236 {
42e975f0
RS
1237 /* The currently loaded binding is not necessarily valid.
1238 We need to unload it, and choose a new binding. */
1239
1240 /* Write out `realvalue' to the old loaded binding. */
d8cafeb5 1241 Fsetcdr (current_alist_element,
b0c2d1c6 1242 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue));
7921925c 1243
42e975f0 1244 /* Find the new binding. */
2829d05f 1245 tem1 = Fassq (symbol, buf->local_var_alist);
b0c2d1c6
RS
1246 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 1;
1247 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 0;
1248
a33ef3ab 1249 if (NILP (tem1))
d8cafeb5
JB
1250 {
1251 /* This buffer still sees the default value. */
1252
1253 /* If the variable is a Lisp_Some_Buffer_Local_Value,
05ef7169 1254 or if this is `let' rather than `set',
d8cafeb5 1255 make CURRENT-ALIST-ELEMENT point to itself,
1f35ce36
RS
1256 indicating that we're seeing the default value.
1257 Likewise if the variable has been let-bound
1258 in the current buffer. */
1259 if (bindflag || SOME_BUFFER_LOCAL_VALUEP (valcontents)
1260 || let_shadows_buffer_binding_p (symbol))
b0c2d1c6
RS
1261 {
1262 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
1263
1264 if (XBUFFER_LOCAL_VALUE (valcontents)->check_frame)
1cc04aed
GM
1265 tem1 = Fassq (symbol,
1266 XFRAME (selected_frame)->param_alist);
d8cafeb5 1267
b0c2d1c6
RS
1268 if (! NILP (tem1))
1269 XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame = 1;
1270 else
1271 tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
1272 }
05ef7169 1273 /* If it's a Lisp_Buffer_Local_Value, being set not bound,
1f35ce36
RS
1274 and we're not within a let that was made for this buffer,
1275 create a new buffer-local binding for the variable.
1276 That means, give this buffer a new assoc for a local value
42e975f0 1277 and load that binding. */
d8cafeb5
JB
1278 else
1279 {
d2fde41d 1280 tem1 = Fcons (symbol, XCDR (current_alist_element));
2829d05f
RS
1281 buf->local_var_alist
1282 = Fcons (tem1, buf->local_var_alist);
d8cafeb5
JB
1283 }
1284 }
b0c2d1c6 1285
42e975f0 1286 /* Record which binding is now loaded. */
f3fbd155
KR
1287 XSETCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr,
1288 tem1);
d8cafeb5 1289
42e975f0 1290 /* Set `buffer' and `frame' slots for thebinding now loaded. */
2829d05f 1291 XSETBUFFER (XBUFFER_LOCAL_VALUE (valcontents)->buffer, buf);
1cc04aed 1292 XBUFFER_LOCAL_VALUE (valcontents)->frame = selected_frame;
7921925c 1293 }
4c47c973 1294 innercontents = XBUFFER_LOCAL_VALUE (valcontents)->realvalue;
7921925c 1295 }
d8cafeb5 1296
7921925c
JB
1297 /* If storing void (making the symbol void), forward only through
1298 buffer-local indicator, not through Lisp_Objfwd, etc. */
1299 if (voide)
7a283f36 1300 store_symval_forwarding (symbol, Qnil, newval, buf);
7921925c 1301 else
7a283f36 1302 store_symval_forwarding (symbol, innercontents, newval, buf);
4c47c973
GM
1303
1304 /* If we just set a variable whose current binding is frame-local,
1305 store the new value in the frame parameter too. */
1306
1307 if (BUFFER_LOCAL_VALUEP (valcontents)
1308 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
1309 {
1310 /* What binding is loaded right now? */
1311 current_alist_element
1312 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
1313
1314 /* If the current buffer is not the buffer whose binding is
1315 loaded, or if there may be frame-local bindings and the frame
1316 isn't the right one, or if it's a Lisp_Buffer_Local_Value and
1317 the default binding is loaded, the loaded binding may be the
1318 wrong one. */
1319 if (XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
f3fbd155 1320 XSETCDR (current_alist_element, newval);
4c47c973 1321 }
d8cafeb5 1322
7921925c
JB
1323 return newval;
1324}
1325\f
1326/* Access or set a buffer-local symbol's default value. */
1327
d9c2a0f2 1328/* Return the default value of SYMBOL, but don't check for voidness.
1bfcade3 1329 Return Qunbound if it is void. */
7921925c
JB
1330
1331Lisp_Object
d9c2a0f2
EN
1332default_value (symbol)
1333 Lisp_Object symbol;
7921925c
JB
1334{
1335 register Lisp_Object valcontents;
1336
b7826503 1337 CHECK_SYMBOL (symbol);
f35d5bad 1338 valcontents = SYMBOL_VALUE (symbol);
7921925c
JB
1339
1340 /* For a built-in buffer-local variable, get the default value
1341 rather than letting do_symval_forwarding get the current value. */
e9ebc175 1342 if (BUFFER_OBJFWDP (valcontents))
7921925c 1343 {
999b32fd 1344 int offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527
GM
1345 if (PER_BUFFER_IDX (offset) != 0)
1346 return PER_BUFFER_DEFAULT (offset);
7921925c
JB
1347 }
1348
1349 /* Handle user-created local variables. */
e9ebc175
KH
1350 if (BUFFER_LOCAL_VALUEP (valcontents)
1351 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c
JB
1352 {
1353 /* If var is set up for a buffer that lacks a local value for it,
1354 the current value is nominally the default value.
42e975f0 1355 But the `realvalue' slot may be more up to date, since
7921925c
JB
1356 ordinary setq stores just that slot. So use that. */
1357 Lisp_Object current_alist_element, alist_element_car;
1358 current_alist_element
7539e11f
KR
1359 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
1360 alist_element_car = XCAR (current_alist_element);
7921925c 1361 if (EQ (alist_element_car, current_alist_element))
b0c2d1c6 1362 return do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->realvalue);
7921925c 1363 else
7539e11f 1364 return XCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
7921925c
JB
1365 }
1366 /* For other variables, get the current value. */
1367 return do_symval_forwarding (valcontents);
1368}
1369
1370DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
8c1a1077
PJ
1371 doc: /* Return t if SYMBOL has a non-void default value.
1372This is the value that is seen in buffers that do not have their own values
1373for this variable. */)
1374 (symbol)
d9c2a0f2 1375 Lisp_Object symbol;
7921925c
JB
1376{
1377 register Lisp_Object value;
1378
d9c2a0f2 1379 value = default_value (symbol);
1bfcade3 1380 return (EQ (value, Qunbound) ? Qnil : Qt);
7921925c
JB
1381}
1382
1383DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0,
8c1a1077
PJ
1384 doc: /* Return SYMBOL's default value.
1385This is the value that is seen in buffers that do not have their own values
1386for this variable. The default value is meaningful for variables with
1387local bindings in certain buffers. */)
1388 (symbol)
d9c2a0f2 1389 Lisp_Object symbol;
7921925c
JB
1390{
1391 register Lisp_Object value;
1392
d9c2a0f2 1393 value = default_value (symbol);
1bfcade3 1394 if (EQ (value, Qunbound))
d9c2a0f2 1395 return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
7921925c
JB
1396 return value;
1397}
1398
1399DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
6e86a75d 1400 doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated.
8c1a1077
PJ
1401The default value is seen in buffers that do not have their own values
1402for this variable. */)
1403 (symbol, value)
d9c2a0f2 1404 Lisp_Object symbol, value;
7921925c
JB
1405{
1406 register Lisp_Object valcontents, current_alist_element, alist_element_buffer;
1407
b7826503 1408 CHECK_SYMBOL (symbol);
f35d5bad 1409 valcontents = SYMBOL_VALUE (symbol);
7921925c
JB
1410
1411 /* Handle variables like case-fold-search that have special slots
1412 in the buffer. Make them work apparently like Lisp_Buffer_Local_Value
1413 variables. */
e9ebc175 1414 if (BUFFER_OBJFWDP (valcontents))
7921925c 1415 {
999b32fd 1416 int offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527 1417 int idx = PER_BUFFER_IDX (offset);
7921925c 1418
f6cd0527 1419 PER_BUFFER_DEFAULT (offset) = value;
984ef137
KH
1420
1421 /* If this variable is not always local in all buffers,
1422 set it in the buffers that don't nominally have a local value. */
999b32fd 1423 if (idx > 0)
7921925c 1424 {
999b32fd 1425 struct buffer *b;
bfb96cb7 1426
7921925c 1427 for (b = all_buffers; b; b = b->next)
f6cd0527
GM
1428 if (!PER_BUFFER_VALUE_P (b, idx))
1429 PER_BUFFER_VALUE (b, offset) = value;
7921925c
JB
1430 }
1431 return value;
1432 }
1433
e9ebc175
KH
1434 if (!BUFFER_LOCAL_VALUEP (valcontents)
1435 && !SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 1436 return Fset (symbol, value);
7921925c 1437
42e975f0 1438 /* Store new value into the DEFAULT-VALUE slot. */
f3fbd155 1439 XSETCDR (XBUFFER_LOCAL_VALUE (valcontents)->cdr, value);
7921925c 1440
42e975f0 1441 /* If the default binding is now loaded, set the REALVALUE slot too. */
8d4afcac 1442 current_alist_element
7539e11f 1443 = XCAR (XBUFFER_LOCAL_VALUE (valcontents)->cdr);
7921925c
JB
1444 alist_element_buffer = Fcar (current_alist_element);
1445 if (EQ (alist_element_buffer, current_alist_element))
7a283f36
GM
1446 store_symval_forwarding (symbol,
1447 XBUFFER_LOCAL_VALUE (valcontents)->realvalue,
1448 value, NULL);
7921925c
JB
1449
1450 return value;
1451}
1452
7a7df7ac 1453DEFUN ("setq-default", Fsetq_default, Ssetq_default, 0, UNEVALLED, 0,
8c1a1077
PJ
1454 doc: /* Set the default value of variable VAR to VALUE.
1455VAR, the variable name, is literal (not evaluated);
bfb96cb7 1456VALUE is an expression: it is evaluated and its value returned.
8c1a1077
PJ
1457The default value of a variable is seen in buffers
1458that do not have their own values for the variable.
1459
1460More generally, you can use multiple variables and values, as in
948d2995
JB
1461 (setq-default VAR VALUE VAR VALUE...)
1462This sets each VAR's default value to the corresponding VALUE.
1463The VALUE for the Nth VAR can refer to the new default values
1464of previous VARs.
7a7df7ac 1465usage: (setq-default [VAR VALUE...]) */)
8c1a1077 1466 (args)
7921925c
JB
1467 Lisp_Object args;
1468{
1469 register Lisp_Object args_left;
d9c2a0f2 1470 register Lisp_Object val, symbol;
7921925c
JB
1471 struct gcpro gcpro1;
1472
a33ef3ab 1473 if (NILP (args))
7921925c
JB
1474 return Qnil;
1475
1476 args_left = args;
1477 GCPRO1 (args);
1478
1479 do
1480 {
1481 val = Feval (Fcar (Fcdr (args_left)));
d2fde41d 1482 symbol = XCAR (args_left);
d9c2a0f2 1483 Fset_default (symbol, val);
d2fde41d 1484 args_left = Fcdr (XCDR (args_left));
7921925c 1485 }
a33ef3ab 1486 while (!NILP (args_left));
7921925c
JB
1487
1488 UNGCPRO;
1489 return val;
1490}
1491\f
a5ca2b75
JB
1492/* Lisp functions for creating and removing buffer-local variables. */
1493
7921925c 1494DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local,
8c1a1077
PJ
1495 1, 1, "vMake Variable Buffer Local: ",
1496 doc: /* Make VARIABLE become buffer-local whenever it is set.
1497At any time, the value for the current buffer is in effect,
1498unless the variable has never been set in this buffer,
1499in which case the default value is in effect.
1500Note that binding the variable with `let', or setting it while
1501a `let'-style binding made in this buffer is in effect,
bfb96cb7 1502does not make the variable buffer-local. Return VARIABLE.
8c1a1077 1503
a9908653
RS
1504In most cases it is better to use `make-local-variable',
1505which makes a variable local in just one buffer.
1506
8c1a1077
PJ
1507The function `default-value' gets the default value and `set-default' sets it. */)
1508 (variable)
d9c2a0f2 1509 register Lisp_Object variable;
7921925c 1510{
8d4afcac 1511 register Lisp_Object tem, valcontents, newval;
7921925c 1512
b7826503 1513 CHECK_SYMBOL (variable);
14970b45 1514 variable = indirect_variable (variable);
7921925c 1515
f35d5bad 1516 valcontents = SYMBOL_VALUE (variable);
d9c2a0f2 1517 if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
d5db4077 1518 error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
7921925c 1519
e9ebc175 1520 if (BUFFER_LOCAL_VALUEP (valcontents) || BUFFER_OBJFWDP (valcontents))
d9c2a0f2 1521 return variable;
e9ebc175 1522 if (SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 1523 {
f35d5bad 1524 XMISCTYPE (SYMBOL_VALUE (variable)) = Lisp_Misc_Buffer_Local_Value;
d9c2a0f2 1525 return variable;
7921925c
JB
1526 }
1527 if (EQ (valcontents, Qunbound))
f35d5bad 1528 SET_SYMBOL_VALUE (variable, Qnil);
d9c2a0f2 1529 tem = Fcons (Qnil, Fsymbol_value (variable));
f3fbd155 1530 XSETCAR (tem, tem);
8d4afcac 1531 newval = allocate_misc ();
324a6eef 1532 XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value;
f35d5bad 1533 XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
b0c2d1c6
RS
1534 XBUFFER_LOCAL_VALUE (newval)->buffer = Fcurrent_buffer ();
1535 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil;
42e975f0 1536 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0;
b0c2d1c6
RS
1537 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1538 XBUFFER_LOCAL_VALUE (newval)->check_frame = 0;
1539 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
f35d5bad 1540 SET_SYMBOL_VALUE (variable, newval);
d9c2a0f2 1541 return variable;
7921925c
JB
1542}
1543
1544DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable,
8c1a1077
PJ
1545 1, 1, "vMake Local Variable: ",
1546 doc: /* Make VARIABLE have a separate value in the current buffer.
1547Other buffers will continue to share a common default value.
1548\(The buffer-local value of VARIABLE starts out as the same value
1549VARIABLE previously had. If VARIABLE was void, it remains void.\)
a9908653 1550Return VARIABLE.
8c1a1077
PJ
1551
1552If the variable is already arranged to become local when set,
1553this function causes a local value to exist for this buffer,
1554just as setting the variable would do.
1555
1556This function returns VARIABLE, and therefore
1557 (set (make-local-variable 'VARIABLE) VALUE-EXP)
1558works.
1559
a9908653
RS
1560See also `make-variable-buffer-local'.
1561
8c1a1077 1562Do not use `make-local-variable' to make a hook variable buffer-local.
515f3f25 1563Instead, use `add-hook' and specify t for the LOCAL argument. */)
8c1a1077 1564 (variable)
d9c2a0f2 1565 register Lisp_Object variable;
7921925c
JB
1566{
1567 register Lisp_Object tem, valcontents;
1568
b7826503 1569 CHECK_SYMBOL (variable);
14970b45 1570 variable = indirect_variable (variable);
7921925c 1571
f35d5bad 1572 valcontents = SYMBOL_VALUE (variable);
d9c2a0f2 1573 if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
d5db4077 1574 error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
7921925c 1575
e9ebc175 1576 if (BUFFER_LOCAL_VALUEP (valcontents) || BUFFER_OBJFWDP (valcontents))
7921925c 1577 {
d9c2a0f2 1578 tem = Fboundp (variable);
7403b5c8 1579
7921925c
JB
1580 /* Make sure the symbol has a local value in this particular buffer,
1581 by setting it to the same value it already has. */
d9c2a0f2
EN
1582 Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
1583 return variable;
7921925c 1584 }
42e975f0 1585 /* Make sure symbol is set up to hold per-buffer values. */
e9ebc175 1586 if (!SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 1587 {
8d4afcac 1588 Lisp_Object newval;
7921925c 1589 tem = Fcons (Qnil, do_symval_forwarding (valcontents));
f3fbd155 1590 XSETCAR (tem, tem);
8d4afcac 1591 newval = allocate_misc ();
324a6eef 1592 XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
f35d5bad 1593 XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
b0c2d1c6
RS
1594 XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil;
1595 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil;
1596 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0;
1597 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1598 XBUFFER_LOCAL_VALUE (newval)->check_frame = 0;
1599 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
f35d5bad 1600 SET_SYMBOL_VALUE (variable, newval);;
7921925c 1601 }
42e975f0 1602 /* Make sure this buffer has its own value of symbol. */
d9c2a0f2 1603 tem = Fassq (variable, current_buffer->local_var_alist);
a33ef3ab 1604 if (NILP (tem))
7921925c 1605 {
a5d004a1
RS
1606 /* Swap out any local binding for some other buffer, and make
1607 sure the current value is permanently recorded, if it's the
1608 default value. */
d9c2a0f2 1609 find_symbol_value (variable);
a5d004a1 1610
7921925c 1611 current_buffer->local_var_alist
f35d5bad 1612 = Fcons (Fcons (variable, XCDR (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (variable))->cdr)),
7921925c
JB
1613 current_buffer->local_var_alist);
1614
1615 /* Make sure symbol does not think it is set up for this buffer;
42e975f0 1616 force it to look once again for this buffer's value. */
7921925c 1617 {
8d4afcac 1618 Lisp_Object *pvalbuf;
a5d004a1 1619
f35d5bad 1620 valcontents = SYMBOL_VALUE (variable);
a5d004a1 1621
b0c2d1c6 1622 pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer;
8d4afcac
KH
1623 if (current_buffer == XBUFFER (*pvalbuf))
1624 *pvalbuf = Qnil;
b0c2d1c6 1625 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
7921925c 1626 }
7921925c 1627 }
a5ca2b75 1628
42e975f0
RS
1629 /* If the symbol forwards into a C variable, then load the binding
1630 for this buffer now. If C code modifies the variable before we
1631 load the binding in, then that new value will clobber the default
1632 binding the next time we unload it. */
f35d5bad 1633 valcontents = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (variable))->realvalue;
e9ebc175 1634 if (INTFWDP (valcontents) || BOOLFWDP (valcontents) || OBJFWDP (valcontents))
f35d5bad 1635 swap_in_symval_forwarding (variable, SYMBOL_VALUE (variable));
a5ca2b75 1636
d9c2a0f2 1637 return variable;
7921925c
JB
1638}
1639
1640DEFUN ("kill-local-variable", Fkill_local_variable, Skill_local_variable,
8c1a1077
PJ
1641 1, 1, "vKill Local Variable: ",
1642 doc: /* Make VARIABLE no longer have a separate value in the current buffer.
bfb96cb7 1643From now on the default value will apply in this buffer. Return VARIABLE. */)
8c1a1077 1644 (variable)
d9c2a0f2 1645 register Lisp_Object variable;
7921925c
JB
1646{
1647 register Lisp_Object tem, valcontents;
1648
b7826503 1649 CHECK_SYMBOL (variable);
14970b45 1650 variable = indirect_variable (variable);
7921925c 1651
f35d5bad 1652 valcontents = SYMBOL_VALUE (variable);
7921925c 1653
e9ebc175 1654 if (BUFFER_OBJFWDP (valcontents))
7921925c 1655 {
999b32fd 1656 int offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527 1657 int idx = PER_BUFFER_IDX (offset);
7921925c 1658
999b32fd 1659 if (idx > 0)
7921925c 1660 {
f6cd0527
GM
1661 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0);
1662 PER_BUFFER_VALUE (current_buffer, offset)
1663 = PER_BUFFER_DEFAULT (offset);
7921925c 1664 }
d9c2a0f2 1665 return variable;
7921925c
JB
1666 }
1667
e9ebc175
KH
1668 if (!BUFFER_LOCAL_VALUEP (valcontents)
1669 && !SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 1670 return variable;
7921925c 1671
42e975f0 1672 /* Get rid of this buffer's alist element, if any. */
7921925c 1673
d9c2a0f2 1674 tem = Fassq (variable, current_buffer->local_var_alist);
a33ef3ab 1675 if (!NILP (tem))
8d4afcac
KH
1676 current_buffer->local_var_alist
1677 = Fdelq (tem, current_buffer->local_var_alist);
7921925c 1678
42e975f0
RS
1679 /* If the symbol is set up with the current buffer's binding
1680 loaded, recompute its value. We have to do it now, or else
1681 forwarded objects won't work right. */
7921925c 1682 {
999e6484 1683 Lisp_Object *pvalbuf, buf;
f35d5bad 1684 valcontents = SYMBOL_VALUE (variable);
b0c2d1c6 1685 pvalbuf = &XBUFFER_LOCAL_VALUE (valcontents)->buffer;
999e6484
SM
1686 XSETBUFFER (buf, current_buffer);
1687 if (EQ (buf, *pvalbuf))
79c83e03
KH
1688 {
1689 *pvalbuf = Qnil;
b0c2d1c6 1690 XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
978dd578 1691 find_symbol_value (variable);
79c83e03 1692 }
7921925c
JB
1693 }
1694
d9c2a0f2 1695 return variable;
7921925c 1696}
62476adc 1697
b0c2d1c6
RS
1698/* Lisp functions for creating and removing buffer-local variables. */
1699
1700DEFUN ("make-variable-frame-local", Fmake_variable_frame_local, Smake_variable_frame_local,
8c1a1077
PJ
1701 1, 1, "vMake Variable Frame Local: ",
1702 doc: /* Enable VARIABLE to have frame-local bindings.
4d4d36b1
RS
1703This does not create any frame-local bindings for VARIABLE,
1704it just makes them possible.
1705
1706A frame-local binding is actually a frame parameter value.
1707If a frame F has a value for the frame parameter named VARIABLE,
1708that also acts as a frame-local binding for VARIABLE in F--
1709provided this function has been called to enable VARIABLE
1710to have frame-local bindings at all.
1711
1712The only way to create a frame-local binding for VARIABLE in a frame
1713is to set the VARIABLE frame parameter of that frame. See
1714`modify-frame-parameters' for how to set frame parameters.
1715
1716Buffer-local bindings take precedence over frame-local bindings. */)
8c1a1077 1717 (variable)
b0c2d1c6
RS
1718 register Lisp_Object variable;
1719{
1720 register Lisp_Object tem, valcontents, newval;
1721
b7826503 1722 CHECK_SYMBOL (variable);
14970b45 1723 variable = indirect_variable (variable);
b0c2d1c6 1724
f35d5bad 1725 valcontents = SYMBOL_VALUE (variable);
b0c2d1c6
RS
1726 if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents)
1727 || BUFFER_OBJFWDP (valcontents))
d5db4077 1728 error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable)));
b0c2d1c6
RS
1729
1730 if (BUFFER_LOCAL_VALUEP (valcontents)
1731 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
42e975f0
RS
1732 {
1733 XBUFFER_LOCAL_VALUE (valcontents)->check_frame = 1;
1734 return variable;
1735 }
b0c2d1c6
RS
1736
1737 if (EQ (valcontents, Qunbound))
f35d5bad 1738 SET_SYMBOL_VALUE (variable, Qnil);
b0c2d1c6 1739 tem = Fcons (Qnil, Fsymbol_value (variable));
f3fbd155 1740 XSETCAR (tem, tem);
b0c2d1c6
RS
1741 newval = allocate_misc ();
1742 XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
f35d5bad 1743 XBUFFER_LOCAL_VALUE (newval)->realvalue = SYMBOL_VALUE (variable);
b0c2d1c6
RS
1744 XBUFFER_LOCAL_VALUE (newval)->buffer = Qnil;
1745 XBUFFER_LOCAL_VALUE (newval)->frame = Qnil;
1746 XBUFFER_LOCAL_VALUE (newval)->found_for_buffer = 0;
1747 XBUFFER_LOCAL_VALUE (newval)->found_for_frame = 0;
1748 XBUFFER_LOCAL_VALUE (newval)->check_frame = 1;
1749 XBUFFER_LOCAL_VALUE (newval)->cdr = tem;
f35d5bad 1750 SET_SYMBOL_VALUE (variable, newval);
b0c2d1c6
RS
1751 return variable;
1752}
1753
62476adc 1754DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
8c1a1077
PJ
1755 1, 2, 0,
1756 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER.
1757BUFFER defaults to the current buffer. */)
1758 (variable, buffer)
d9c2a0f2 1759 register Lisp_Object variable, buffer;
62476adc
RS
1760{
1761 Lisp_Object valcontents;
c48ead86
KH
1762 register struct buffer *buf;
1763
1764 if (NILP (buffer))
1765 buf = current_buffer;
1766 else
1767 {
b7826503 1768 CHECK_BUFFER (buffer);
c48ead86
KH
1769 buf = XBUFFER (buffer);
1770 }
62476adc 1771
b7826503 1772 CHECK_SYMBOL (variable);
14970b45 1773 variable = indirect_variable (variable);
62476adc 1774
f35d5bad 1775 valcontents = SYMBOL_VALUE (variable);
c48ead86 1776 if (BUFFER_LOCAL_VALUEP (valcontents)
1e5f16fa 1777 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
c48ead86
KH
1778 {
1779 Lisp_Object tail, elt;
f35d5bad 1780
7539e11f 1781 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
c48ead86 1782 {
7539e11f
KR
1783 elt = XCAR (tail);
1784 if (EQ (variable, XCAR (elt)))
c48ead86
KH
1785 return Qt;
1786 }
1787 }
1788 if (BUFFER_OBJFWDP (valcontents))
1789 {
1790 int offset = XBUFFER_OBJFWD (valcontents)->offset;
f6cd0527
GM
1791 int idx = PER_BUFFER_IDX (offset);
1792 if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
c48ead86
KH
1793 return Qt;
1794 }
1795 return Qnil;
62476adc 1796}
f4f04cee
RS
1797
1798DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p,
8c1a1077 1799 1, 2, 0,
1dc5ba01
LT
1800 doc: /* Non-nil if VARIABLE will be local in buffer BUFFER when set there.
1801More precisely, this means that setting the variable \(with `set' or`setq'),
1802while it does not have a `let'-style binding that was made in BUFFER,
1803will produce a buffer local binding. See Info node
1804`(elisp)Creating Buffer-Local'.
8c1a1077
PJ
1805BUFFER defaults to the current buffer. */)
1806 (variable, buffer)
d9c2a0f2 1807 register Lisp_Object variable, buffer;
f4f04cee
RS
1808{
1809 Lisp_Object valcontents;
1810 register struct buffer *buf;
1811
1812 if (NILP (buffer))
1813 buf = current_buffer;
1814 else
1815 {
b7826503 1816 CHECK_BUFFER (buffer);
f4f04cee
RS
1817 buf = XBUFFER (buffer);
1818 }
1819
b7826503 1820 CHECK_SYMBOL (variable);
14970b45 1821 variable = indirect_variable (variable);
f4f04cee 1822
f35d5bad 1823 valcontents = SYMBOL_VALUE (variable);
f4f04cee
RS
1824
1825 /* This means that make-variable-buffer-local was done. */
1826 if (BUFFER_LOCAL_VALUEP (valcontents))
1827 return Qt;
1828 /* All these slots become local if they are set. */
1829 if (BUFFER_OBJFWDP (valcontents))
1830 return Qt;
1831 if (SOME_BUFFER_LOCAL_VALUEP (valcontents))
1832 {
1833 Lisp_Object tail, elt;
7539e11f 1834 for (tail = buf->local_var_alist; CONSP (tail); tail = XCDR (tail))
f4f04cee 1835 {
7539e11f
KR
1836 elt = XCAR (tail);
1837 if (EQ (variable, XCAR (elt)))
f4f04cee
RS
1838 return Qt;
1839 }
1840 }
1841 return Qnil;
1842}
0a2546d4
RS
1843
1844DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus,
1845 1, 1, 0,
1846 doc: /* Return a value indicating where VARIABLE's current binding comes from.
1847If the current binding is buffer-local, the value is the current buffer.
1848If the current binding is frame-local, the value is the selected frame.
1849If the current binding is global (the default), the value is nil. */)
1850 (variable)
1851 register Lisp_Object variable;
1852{
1853 Lisp_Object valcontents;
1854
1855 CHECK_SYMBOL (variable);
1856 variable = indirect_variable (variable);
1857
1858 /* Make sure the current binding is actually swapped in. */
1859 find_symbol_value (variable);
1860
1861 valcontents = XSYMBOL (variable)->value;
1862
1863 if (BUFFER_LOCAL_VALUEP (valcontents)
1864 || SOME_BUFFER_LOCAL_VALUEP (valcontents)
1865 || BUFFER_OBJFWDP (valcontents))
1866 {
1867 /* For a local variable, record both the symbol and which
1868 buffer's or frame's value we are saving. */
1869 if (!NILP (Flocal_variable_p (variable, Qnil)))
1870 return Fcurrent_buffer ();
1871 else if (!BUFFER_OBJFWDP (valcontents)
1872 && XBUFFER_LOCAL_VALUE (valcontents)->found_for_frame)
1873 return XBUFFER_LOCAL_VALUE (valcontents)->frame;
1874 }
1875
1876 return Qnil;
1877}
2a42d440 1878
c40bb1ba
KL
1879/* This code is disabled now that we use the selected frame to return
1880 keyboard-local-values. */
1881#if 0
6ed8eeff 1882extern struct terminal *get_terminal P_ ((Lisp_Object display, int));
2a42d440
KL
1883
1884DEFUN ("terminal-local-value", Fterminal_local_value, Sterminal_local_value, 2, 2, 0,
6ed8eeff 1885 doc: /* Return the terminal-local value of SYMBOL on TERMINAL.
2a42d440
KL
1886If SYMBOL is not a terminal-local variable, then return its normal
1887value, like `symbol-value'.
1888
6ed8eeff
KL
1889TERMINAL may be a terminal id, a frame, or nil (meaning the
1890selected frame's terminal device). */)
1891 (symbol, terminal)
2a42d440 1892 Lisp_Object symbol;
6ed8eeff 1893 Lisp_Object terminal;
2a42d440
KL
1894{
1895 Lisp_Object result;
6ed8eeff
KL
1896 struct terminal *t = get_terminal (terminal, 1);
1897 push_kboard (t->kboard);
2a42d440 1898 result = Fsymbol_value (symbol);
256c9c3a 1899 pop_kboard ();
2a42d440
KL
1900 return result;
1901}
1902
1903DEFUN ("set-terminal-local-value", Fset_terminal_local_value, Sset_terminal_local_value, 3, 3, 0,
6ed8eeff 1904 doc: /* Set the terminal-local binding of SYMBOL on TERMINAL to VALUE.
2a42d440 1905If VARIABLE is not a terminal-local variable, then set its normal
7e59217d
KL
1906binding, like `set'.
1907
6ed8eeff
KL
1908TERMINAL may be a terminal id, a frame, or nil (meaning the
1909selected frame's terminal device). */)
1910 (symbol, terminal, value)
2a42d440 1911 Lisp_Object symbol;
6ed8eeff 1912 Lisp_Object terminal;
2a42d440
KL
1913 Lisp_Object value;
1914{
1915 Lisp_Object result;
6ed8eeff 1916 struct terminal *t = get_terminal (terminal, 1);
256c9c3a 1917 push_kboard (d->kboard);
2a42d440 1918 result = Fset (symbol, value);
256c9c3a 1919 pop_kboard ();
2a42d440
KL
1920 return result;
1921}
c40bb1ba 1922#endif
7921925c 1923\f
ffd56f97
JB
1924/* Find the function at the end of a chain of symbol function indirections. */
1925
1926/* If OBJECT is a symbol, find the end of its function chain and
1927 return the value found there. If OBJECT is not a symbol, just
1928 return it. If there is a cycle in the function chain, signal a
1929 cyclic-function-indirection error.
1930
1931 This is like Findirect_function, except that it doesn't signal an
1932 error if the chain ends up unbound. */
1933Lisp_Object
a2932990 1934indirect_function (object)
62476adc 1935 register Lisp_Object object;
ffd56f97 1936{
eb8c3be9 1937 Lisp_Object tortoise, hare;
ffd56f97 1938
eb8c3be9 1939 hare = tortoise = object;
ffd56f97
JB
1940
1941 for (;;)
1942 {
e9ebc175 1943 if (!SYMBOLP (hare) || EQ (hare, Qunbound))
ffd56f97
JB
1944 break;
1945 hare = XSYMBOL (hare)->function;
e9ebc175 1946 if (!SYMBOLP (hare) || EQ (hare, Qunbound))
ffd56f97
JB
1947 break;
1948 hare = XSYMBOL (hare)->function;
1949
eb8c3be9 1950 tortoise = XSYMBOL (tortoise)->function;
ffd56f97 1951
eb8c3be9 1952 if (EQ (hare, tortoise))
ffd56f97
JB
1953 Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
1954 }
1955
1956 return hare;
1957}
1958
a7f96a35 1959DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 2, 0,
8c1a1077 1960 doc: /* Return the function at the end of OBJECT's function chain.
0ddb0ae8
TTN
1961If OBJECT is not a symbol, just return it. Otherwise, follow all
1962function indirections to find the final function binding and return it.
1963If the final symbol in the chain is unbound, signal a void-function error.
1964Optional arg NOERROR non-nil means to return nil instead of signalling.
8c1a1077
PJ
1965Signal a cyclic-function-indirection error if there is a loop in the
1966function chain of symbols. */)
0ddb0ae8 1967 (object, noerror)
8c1a1077 1968 register Lisp_Object object;
0ddb0ae8 1969 Lisp_Object noerror;
ffd56f97
JB
1970{
1971 Lisp_Object result;
1972
64de53d8
KS
1973 /* Optimize for no indirection. */
1974 result = object;
1975 if (SYMBOLP (result) && !EQ (result, Qunbound)
1976 && (result = XSYMBOL (result)->function, SYMBOLP (result)))
1977 result = indirect_function (result);
1978 if (!EQ (result, Qunbound))
1979 return result;
ffd56f97 1980
64de53d8
KS
1981 if (NILP (noerror))
1982 Fsignal (Qvoid_function, Fcons (object, Qnil));
1983
1984 return Qnil;
ffd56f97
JB
1985}
1986\f
7921925c
JB
1987/* Extract and set vector and string elements */
1988
1989DEFUN ("aref", Faref, Saref, 2, 2, 0,
8c1a1077
PJ
1990 doc: /* Return the element of ARRAY at index IDX.
1991ARRAY may be a vector, a string, a char-table, a bool-vector,
1992or a byte-code object. IDX starts at 0. */)
1993 (array, idx)
7921925c
JB
1994 register Lisp_Object array;
1995 Lisp_Object idx;
1996{
1997 register int idxval;
1998
b7826503 1999 CHECK_NUMBER (idx);
7921925c 2000 idxval = XINT (idx);
e9ebc175 2001 if (STRINGP (array))
7921925c 2002 {
25638b07
RS
2003 int c, idxval_byte;
2004
d5db4077 2005 if (idxval < 0 || idxval >= SCHARS (array))
c24e4efe 2006 args_out_of_range (array, idx);
25638b07 2007 if (! STRING_MULTIBYTE (array))
d5db4077 2008 return make_number ((unsigned char) SREF (array, idxval));
25638b07
RS
2009 idxval_byte = string_char_to_byte (array, idxval);
2010
29f44a37 2011 c = STRING_CHAR (SDATA (array) + idxval_byte,
d5db4077 2012 SBYTES (array) - idxval_byte);
25638b07 2013 return make_number (c);
7921925c 2014 }
4d276982
RS
2015 else if (BOOL_VECTOR_P (array))
2016 {
2017 int val;
4d276982
RS
2018
2019 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
2020 args_out_of_range (array, idx);
2021
b9ed2177
AS
2022 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR];
2023 return (val & (1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR)) ? Qt : Qnil);
4d276982
RS
2024 }
2025 else if (CHAR_TABLE_P (array))
2026 {
2027 Lisp_Object val;
2028
6bbd7a29
GM
2029 val = Qnil;
2030
4d276982
RS
2031 if (idxval < 0)
2032 args_out_of_range (array, idx);
ab5c3f93 2033 if (idxval < CHAR_TABLE_ORDINARY_SLOTS)
8313c4e7 2034 {
256d566c
KH
2035 if (! SINGLE_BYTE_CHAR_P (idxval))
2036 args_out_of_range (array, idx);
39e16e51 2037 /* For ASCII and 8-bit European characters, the element is
3a6cf6bd 2038 stored in the top table. */
8313c4e7 2039 val = XCHAR_TABLE (array)->contents[idxval];
256d566c
KH
2040 if (NILP (val))
2041 {
2042 int default_slot
2043 = (idxval < 0x80 ? CHAR_TABLE_DEFAULT_SLOT_ASCII
2044 : idxval < 0xA0 ? CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL
2045 : CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC);
2046 val = XCHAR_TABLE (array)->contents[default_slot];
2047 }
8313c4e7
KH
2048 if (NILP (val))
2049 val = XCHAR_TABLE (array)->defalt;
2050 while (NILP (val)) /* Follow parents until we find some value. */
2051 {
2052 array = XCHAR_TABLE (array)->parent;
2053 if (NILP (array))
2054 return Qnil;
2055 val = XCHAR_TABLE (array)->contents[idxval];
2056 if (NILP (val))
2057 val = XCHAR_TABLE (array)->defalt;
2058 }
2059 return val;
2060 }
4d276982
RS
2061 else
2062 {
39e16e51
KH
2063 int code[4], i;
2064 Lisp_Object sub_table;
256d566c 2065 Lisp_Object current_default;
8313c4e7 2066
37309c9d 2067 SPLIT_CHAR (idxval, code[0], code[1], code[2]);
e19c1eb4
KH
2068 if (code[1] < 32) code[1] = -1;
2069 else if (code[2] < 32) code[2] = -1;
2070
39e16e51
KH
2071 /* Here, the possible range of CODE[0] (== charset ID) is
2072 128..MAX_CHARSET. Since the top level char table contains
2073 data for multibyte characters after 256th element, we must
2074 increment CODE[0] by 128 to get a correct index. */
2075 code[0] += 128;
2076 code[3] = -1; /* anchor */
4d276982
RS
2077
2078 try_parent_char_table:
256d566c 2079 current_default = XCHAR_TABLE (array)->defalt;
39e16e51
KH
2080 sub_table = array;
2081 for (i = 0; code[i] >= 0; i++)
4d276982 2082 {
39e16e51
KH
2083 val = XCHAR_TABLE (sub_table)->contents[code[i]];
2084 if (SUB_CHAR_TABLE_P (val))
256d566c
KH
2085 {
2086 sub_table = val;
2087 if (! NILP (XCHAR_TABLE (sub_table)->defalt))
2088 current_default = XCHAR_TABLE (sub_table)->defalt;
2089 }
39e16e51 2090 else
8313c4e7 2091 {
39e16e51 2092 if (NILP (val))
256d566c 2093 val = current_default;
39e16e51
KH
2094 if (NILP (val))
2095 {
2096 array = XCHAR_TABLE (array)->parent;
2097 if (!NILP (array))
2098 goto try_parent_char_table;
2099 }
2100 return val;
8313c4e7 2101 }
4d276982 2102 }
256d566c
KH
2103 /* Reaching here means IDXVAL is a generic character in
2104 which each character or a group has independent value.
2105 Essentially it's nonsense to get a value for such a
2106 generic character, but for backward compatibility, we try
2107 the default value and parent. */
2108 val = current_default;
8313c4e7 2109 if (NILP (val))
4d276982
RS
2110 {
2111 array = XCHAR_TABLE (array)->parent;
39e16e51
KH
2112 if (!NILP (array))
2113 goto try_parent_char_table;
4d276982 2114 }
4d276982
RS
2115 return val;
2116 }
4d276982 2117 }
7921925c 2118 else
c24e4efe 2119 {
6bbd7a29 2120 int size = 0;
7f358972
RS
2121 if (VECTORP (array))
2122 size = XVECTOR (array)->size;
2123 else if (COMPILEDP (array))
2124 size = XVECTOR (array)->size & PSEUDOVECTOR_SIZE_MASK;
2125 else
2126 wrong_type_argument (Qarrayp, array);
2127
2128 if (idxval < 0 || idxval >= size)
c24e4efe
KH
2129 args_out_of_range (array, idx);
2130 return XVECTOR (array)->contents[idxval];
2131 }
7921925c
JB
2132}
2133
2134DEFUN ("aset", Faset, Saset, 3, 3, 0,
8c1a1077 2135 doc: /* Store into the element of ARRAY at index IDX the value NEWELT.
bfb96cb7
FP
2136Return NEWELT. ARRAY may be a vector, a string, a char-table or a
2137bool-vector. IDX starts at 0. */)
8c1a1077 2138 (array, idx, newelt)
7921925c
JB
2139 register Lisp_Object array;
2140 Lisp_Object idx, newelt;
2141{
2142 register int idxval;
2143
b7826503 2144 CHECK_NUMBER (idx);
7921925c 2145 idxval = XINT (idx);
0c64a8cd 2146 CHECK_ARRAY (array, Qarrayp);
7921925c
JB
2147 CHECK_IMPURE (array);
2148
e9ebc175 2149 if (VECTORP (array))
c24e4efe
KH
2150 {
2151 if (idxval < 0 || idxval >= XVECTOR (array)->size)
2152 args_out_of_range (array, idx);
2153 XVECTOR (array)->contents[idxval] = newelt;
2154 }
4d276982
RS
2155 else if (BOOL_VECTOR_P (array))
2156 {
2157 int val;
4d276982
RS
2158
2159 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
2160 args_out_of_range (array, idx);
2161
b9ed2177 2162 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR];
4d276982
RS
2163
2164 if (! NILP (newelt))
b9ed2177 2165 val |= 1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR);
4d276982 2166 else
b9ed2177
AS
2167 val &= ~(1 << (idxval % BOOL_VECTOR_BITS_PER_CHAR));
2168 XBOOL_VECTOR (array)->data[idxval / BOOL_VECTOR_BITS_PER_CHAR] = val;
4d276982
RS
2169 }
2170 else if (CHAR_TABLE_P (array))
2171 {
4d276982
RS
2172 if (idxval < 0)
2173 args_out_of_range (array, idx);
ab5c3f93 2174 if (idxval < CHAR_TABLE_ORDINARY_SLOTS)
256d566c
KH
2175 {
2176 if (! SINGLE_BYTE_CHAR_P (idxval))
2177 args_out_of_range (array, idx);
2178 XCHAR_TABLE (array)->contents[idxval] = newelt;
2179 }
4d276982
RS
2180 else
2181 {
39e16e51 2182 int code[4], i;
8313c4e7 2183 Lisp_Object val;
4d276982 2184
37309c9d 2185 SPLIT_CHAR (idxval, code[0], code[1], code[2]);
e19c1eb4
KH
2186 if (code[1] < 32) code[1] = -1;
2187 else if (code[2] < 32) code[2] = -1;
2188
39e16e51
KH
2189 /* See the comment of the corresponding part in Faref. */
2190 code[0] += 128;
2191 code[3] = -1; /* anchor */
2192 for (i = 0; code[i + 1] >= 0; i++)
8313c4e7 2193 {
39e16e51
KH
2194 val = XCHAR_TABLE (array)->contents[code[i]];
2195 if (SUB_CHAR_TABLE_P (val))
8313c4e7
KH
2196 array = val;
2197 else
3c8fccc3
RS
2198 {
2199 Lisp_Object temp;
2200
2201 /* VAL is a leaf. Create a sub char table with the
256d566c 2202 initial value VAL and look into it. */
3c8fccc3 2203
256d566c 2204 temp = make_sub_char_table (val);
3c8fccc3
RS
2205 XCHAR_TABLE (array)->contents[code[i]] = temp;
2206 array = temp;
2207 }
8313c4e7 2208 }
39e16e51 2209 XCHAR_TABLE (array)->contents[code[i]] = newelt;
4d276982 2210 }
4d276982 2211 }
25638b07
RS
2212 else if (STRING_MULTIBYTE (array))
2213 {
c6464167 2214 int idxval_byte, prev_bytes, new_bytes, nbytes;
3c9de1af 2215 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
25638b07 2216
d5db4077 2217 if (idxval < 0 || idxval >= SCHARS (array))
25638b07 2218 args_out_of_range (array, idx);
b7826503 2219 CHECK_NUMBER (newelt);
25638b07 2220
c6464167
MB
2221 nbytes = SBYTES (array);
2222
25638b07 2223 idxval_byte = string_char_to_byte (array, idxval);
29f44a37 2224 p1 = SDATA (array) + idxval_byte;
3c9de1af
KH
2225 PARSE_MULTIBYTE_SEQ (p1, nbytes - idxval_byte, prev_bytes);
2226 new_bytes = CHAR_STRING (XINT (newelt), p0);
2227 if (prev_bytes != new_bytes)
2228 {
2229 /* We must relocate the string data. */
d5db4077 2230 int nchars = SCHARS (array);
3c9de1af 2231 unsigned char *str;
f1a87317 2232 USE_SAFE_ALLOCA;
3c9de1af 2233
f1a87317 2234 SAFE_ALLOCA (str, unsigned char *, nbytes);
d5db4077 2235 bcopy (SDATA (array), str, nbytes);
3c9de1af
KH
2236 allocate_string_data (XSTRING (array), nchars,
2237 nbytes + new_bytes - prev_bytes);
d5db4077
KR
2238 bcopy (str, SDATA (array), idxval_byte);
2239 p1 = SDATA (array) + idxval_byte;
3c9de1af
KH
2240 bcopy (str + idxval_byte + prev_bytes, p1 + new_bytes,
2241 nbytes - (idxval_byte + prev_bytes));
233f3db6 2242 SAFE_FREE ();
3c9de1af
KH
2243 clear_string_char_byte_cache ();
2244 }
2245 while (new_bytes--)
2246 *p1++ = *p0++;
25638b07 2247 }
7921925c
JB
2248 else
2249 {
d5db4077 2250 if (idxval < 0 || idxval >= SCHARS (array))
c24e4efe 2251 args_out_of_range (array, idx);
b7826503 2252 CHECK_NUMBER (newelt);
3c9de1af
KH
2253
2254 if (XINT (newelt) < 0 || SINGLE_BYTE_CHAR_P (XINT (newelt)))
29f44a37 2255 SSET (array, idxval, XINT (newelt));
3c9de1af
KH
2256 else
2257 {
2258 /* We must relocate the string data while converting it to
2259 multibyte. */
2260 int idxval_byte, prev_bytes, new_bytes;
2261 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
d5db4077 2262 unsigned char *origstr = SDATA (array), *str;
3c9de1af 2263 int nchars, nbytes;
f1a87317 2264 USE_SAFE_ALLOCA;
3c9de1af 2265
d5db4077 2266 nchars = SCHARS (array);
3c9de1af
KH
2267 nbytes = idxval_byte = count_size_as_multibyte (origstr, idxval);
2268 nbytes += count_size_as_multibyte (origstr + idxval,
2269 nchars - idxval);
f1a87317 2270 SAFE_ALLOCA (str, unsigned char *, nbytes);
d5db4077 2271 copy_text (SDATA (array), str, nchars, 0, 1);
3c9de1af
KH
2272 PARSE_MULTIBYTE_SEQ (str + idxval_byte, nbytes - idxval_byte,
2273 prev_bytes);
2274 new_bytes = CHAR_STRING (XINT (newelt), p0);
2275 allocate_string_data (XSTRING (array), nchars,
2276 nbytes + new_bytes - prev_bytes);
d5db4077
KR
2277 bcopy (str, SDATA (array), idxval_byte);
2278 p1 = SDATA (array) + idxval_byte;
3c9de1af
KH
2279 while (new_bytes--)
2280 *p1++ = *p0++;
2281 bcopy (str + idxval_byte + prev_bytes, p1,
2282 nbytes - (idxval_byte + prev_bytes));
233f3db6 2283 SAFE_FREE ();
3c9de1af
KH
2284 clear_string_char_byte_cache ();
2285 }
7921925c
JB
2286 }
2287
2288 return newelt;
2289}
7921925c
JB
2290\f
2291/* Arithmetic functions */
2292
2293enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
2294
2295Lisp_Object
2296arithcompare (num1, num2, comparison)
2297 Lisp_Object num1, num2;
2298 enum comparison comparison;
2299{
6bbd7a29 2300 double f1 = 0, f2 = 0;
7921925c
JB
2301 int floatp = 0;
2302
b7826503
PJ
2303 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1);
2304 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2);
7921925c 2305
e9ebc175 2306 if (FLOATP (num1) || FLOATP (num2))
7921925c
JB
2307 {
2308 floatp = 1;
7539e11f
KR
2309 f1 = (FLOATP (num1)) ? XFLOAT_DATA (num1) : XINT (num1);
2310 f2 = (FLOATP (num2)) ? XFLOAT_DATA (num2) : XINT (num2);
7921925c 2311 }
7921925c
JB
2312
2313 switch (comparison)
2314 {
2315 case equal:
2316 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
2317 return Qt;
2318 return Qnil;
2319
2320 case notequal:
2321 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
2322 return Qt;
2323 return Qnil;
2324
2325 case less:
2326 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
2327 return Qt;
2328 return Qnil;
2329
2330 case less_or_equal:
2331 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
2332 return Qt;
2333 return Qnil;
2334
2335 case grtr:
2336 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
2337 return Qt;
2338 return Qnil;
2339
2340 case grtr_or_equal:
2341 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
2342 return Qt;
2343 return Qnil;
25e40a4b
JB
2344
2345 default:
2346 abort ();
7921925c
JB
2347 }
2348}
2349
2350DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0,
8c1a1077
PJ
2351 doc: /* Return t if two args, both numbers or markers, are equal. */)
2352 (num1, num2)
7921925c
JB
2353 register Lisp_Object num1, num2;
2354{
2355 return arithcompare (num1, num2, equal);
2356}
2357
2358DEFUN ("<", Flss, Slss, 2, 2, 0,
8c1a1077
PJ
2359 doc: /* Return t if first arg is less than second arg. Both must be numbers or markers. */)
2360 (num1, num2)
7921925c
JB
2361 register Lisp_Object num1, num2;
2362{
2363 return arithcompare (num1, num2, less);
2364}
2365
2366DEFUN (">", Fgtr, Sgtr, 2, 2, 0,
8c1a1077
PJ
2367 doc: /* Return t if first arg is greater than second arg. Both must be numbers or markers. */)
2368 (num1, num2)
7921925c
JB
2369 register Lisp_Object num1, num2;
2370{
2371 return arithcompare (num1, num2, grtr);
2372}
2373
2374DEFUN ("<=", Fleq, Sleq, 2, 2, 0,
8c1a1077
PJ
2375 doc: /* Return t if first arg is less than or equal to second arg.
2376Both must be numbers or markers. */)
2377 (num1, num2)
7921925c
JB
2378 register Lisp_Object num1, num2;
2379{
2380 return arithcompare (num1, num2, less_or_equal);
2381}
2382
2383DEFUN (">=", Fgeq, Sgeq, 2, 2, 0,
8c1a1077
PJ
2384 doc: /* Return t if first arg is greater than or equal to second arg.
2385Both must be numbers or markers. */)
2386 (num1, num2)
7921925c
JB
2387 register Lisp_Object num1, num2;
2388{
2389 return arithcompare (num1, num2, grtr_or_equal);
2390}
2391
2392DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
8c1a1077
PJ
2393 doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */)
2394 (num1, num2)
7921925c
JB
2395 register Lisp_Object num1, num2;
2396{
2397 return arithcompare (num1, num2, notequal);
2398}
2399
8c1a1077
PJ
2400DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0,
2401 doc: /* Return t if NUMBER is zero. */)
2402 (number)
d9c2a0f2 2403 register Lisp_Object number;
7921925c 2404{
b7826503 2405 CHECK_NUMBER_OR_FLOAT (number);
7921925c 2406
d9c2a0f2 2407 if (FLOATP (number))
7921925c 2408 {
7539e11f 2409 if (XFLOAT_DATA (number) == 0.0)
7921925c
JB
2410 return Qt;
2411 return Qnil;
2412 }
7921925c 2413
d9c2a0f2 2414 if (!XINT (number))
7921925c
JB
2415 return Qt;
2416 return Qnil;
2417}
2418\f
34f4f6c6 2419/* Convert between long values and pairs of Lisp integers. */
51cf3e31
JB
2420
2421Lisp_Object
2422long_to_cons (i)
2423 unsigned long i;
2424{
9bc7166b 2425 unsigned long top = i >> 16;
51cf3e31
JB
2426 unsigned int bot = i & 0xFFFF;
2427 if (top == 0)
2428 return make_number (bot);
b42cfa11 2429 if (top == (unsigned long)-1 >> 16)
51cf3e31
JB
2430 return Fcons (make_number (-1), make_number (bot));
2431 return Fcons (make_number (top), make_number (bot));
2432}
2433
2434unsigned long
2435cons_to_long (c)
2436 Lisp_Object c;
2437{
878a80cc 2438 Lisp_Object top, bot;
51cf3e31
JB
2439 if (INTEGERP (c))
2440 return XINT (c);
7539e11f
KR
2441 top = XCAR (c);
2442 bot = XCDR (c);
51cf3e31 2443 if (CONSP (bot))
7539e11f 2444 bot = XCAR (bot);
51cf3e31
JB
2445 return ((XINT (top) << 16) | XINT (bot));
2446}
2447\f
f2980264 2448DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
bfb96cb7 2449 doc: /* Return the decimal representation of NUMBER as a string.
8c1a1077
PJ
2450Uses a minus sign if negative.
2451NUMBER may be an integer or a floating point number. */)
2452 (number)
d9c2a0f2 2453 Lisp_Object number;
7921925c 2454{
6030ce64 2455 char buffer[VALBITS];
7921925c 2456
b7826503 2457 CHECK_NUMBER_OR_FLOAT (number);
7921925c 2458
d9c2a0f2 2459 if (FLOATP (number))
7921925c
JB
2460 {
2461 char pigbuf[350]; /* see comments in float_to_string */
2462
7539e11f 2463 float_to_string (pigbuf, XFLOAT_DATA (number));
7403b5c8 2464 return build_string (pigbuf);
7921925c 2465 }
7921925c 2466
e6c82a8d 2467 if (sizeof (int) == sizeof (EMACS_INT))
d9c2a0f2 2468 sprintf (buffer, "%d", XINT (number));
e6c82a8d 2469 else if (sizeof (long) == sizeof (EMACS_INT))
dd8daec5 2470 sprintf (buffer, "%ld", (long) XINT (number));
e6c82a8d
RS
2471 else
2472 abort ();
7921925c
JB
2473 return build_string (buffer);
2474}
2475
3883fbeb
RS
2476INLINE static int
2477digit_to_number (character, base)
2478 int character, base;
2479{
2480 int digit;
2481
2482 if (character >= '0' && character <= '9')
2483 digit = character - '0';
2484 else if (character >= 'a' && character <= 'z')
2485 digit = character - 'a' + 10;
2486 else if (character >= 'A' && character <= 'Z')
2487 digit = character - 'A' + 10;
2488 else
2489 return -1;
2490
2491 if (digit >= base)
2492 return -1;
2493 else
2494 return digit;
bfb96cb7 2495}
3883fbeb
RS
2496
2497DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,
558ee900 2498 doc: /* Parse STRING as a decimal number and return the number.
8c1a1077
PJ
2499This parses both integers and floating point numbers.
2500It ignores leading spaces and tabs.
2501
2502If BASE, interpret STRING as a number in that base. If BASE isn't
2503present, base 10 is used. BASE must be between 2 and 16 (inclusive).
2504If the base used is not 10, floating point is not recognized. */)
2505 (string, base)
3883fbeb 2506 register Lisp_Object string, base;
7921925c 2507{
3883fbeb 2508 register unsigned char *p;
342858a5
GM
2509 register int b;
2510 int sign = 1;
2511 Lisp_Object val;
25e40a4b 2512
b7826503 2513 CHECK_STRING (string);
7921925c 2514
3883fbeb
RS
2515 if (NILP (base))
2516 b = 10;
2517 else
2518 {
b7826503 2519 CHECK_NUMBER (base);
3883fbeb
RS
2520 b = XINT (base);
2521 if (b < 2 || b > 16)
2522 Fsignal (Qargs_out_of_range, Fcons (base, Qnil));
2523 }
2524
25e40a4b
JB
2525 /* Skip any whitespace at the front of the number. Some versions of
2526 atoi do this anyway, so we might as well make Emacs lisp consistent. */
d5db4077 2527 p = SDATA (string);
0a3e4d65 2528 while (*p == ' ' || *p == '\t')
25e40a4b
JB
2529 p++;
2530
3883fbeb
RS
2531 if (*p == '-')
2532 {
342858a5 2533 sign = -1;
3883fbeb
RS
2534 p++;
2535 }
2536 else if (*p == '+')
2537 p++;
bfb96cb7 2538
8e36ae7f 2539 if (isfloat_string (p) && b == 10)
342858a5
GM
2540 val = make_float (sign * atof (p));
2541 else
3883fbeb 2542 {
342858a5
GM
2543 double v = 0;
2544
2545 while (1)
2546 {
2547 int digit = digit_to_number (*p++, b);
2548 if (digit < 0)
2549 break;
2550 v = v * b + digit;
2551 }
2552
cb938d46 2553 val = make_fixnum_or_float (sign * v);
3883fbeb 2554 }
342858a5
GM
2555
2556 return val;
7921925c 2557}
3883fbeb 2558
7403b5c8 2559\f
7921925c 2560enum arithop
7a283f36
GM
2561 {
2562 Aadd,
2563 Asub,
2564 Amult,
2565 Adiv,
2566 Alogand,
2567 Alogior,
2568 Alogxor,
2569 Amax,
2570 Amin
2571 };
2572
2573static Lisp_Object float_arith_driver P_ ((double, int, enum arithop,
2574 int, Lisp_Object *));
ad8d56b9 2575extern Lisp_Object fmod_float ();
b06faa91 2576
7921925c 2577Lisp_Object
87fbf902 2578arith_driver (code, nargs, args)
7921925c
JB
2579 enum arithop code;
2580 int nargs;
2581 register Lisp_Object *args;
2582{
2583 register Lisp_Object val;
2584 register int argnum;
7a283f36 2585 register EMACS_INT accum = 0;
5260234d 2586 register EMACS_INT next;
7921925c 2587
0220c518 2588 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2589 {
2590 case Alogior:
2591 case Alogxor:
2592 case Aadd:
2593 case Asub:
7a283f36
GM
2594 accum = 0;
2595 break;
7921925c 2596 case Amult:
7a283f36
GM
2597 accum = 1;
2598 break;
7921925c 2599 case Alogand:
7a283f36
GM
2600 accum = -1;
2601 break;
2602 default:
2603 break;
7921925c
JB
2604 }
2605
2606 for (argnum = 0; argnum < nargs; argnum++)
2607 {
7a283f36
GM
2608 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2609 val = args[argnum];
b7826503 2610 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
7921925c 2611
7a283f36
GM
2612 if (FLOATP (val))
2613 return float_arith_driver ((double) accum, argnum, code,
2614 nargs, args);
2615 args[argnum] = val;
7921925c 2616 next = XINT (args[argnum]);
0220c518 2617 switch (SWITCH_ENUM_CAST (code))
7921925c 2618 {
7a283f36
GM
2619 case Aadd:
2620 accum += next;
2621 break;
7921925c 2622 case Asub:
e64981da 2623 accum = argnum ? accum - next : nargs == 1 ? - next : next;
7921925c 2624 break;
7a283f36
GM
2625 case Amult:
2626 accum *= next;
2627 break;
7921925c 2628 case Adiv:
7a283f36
GM
2629 if (!argnum)
2630 accum = next;
87fbf902
RS
2631 else
2632 {
2633 if (next == 0)
2634 Fsignal (Qarith_error, Qnil);
2635 accum /= next;
2636 }
7921925c 2637 break;
7a283f36
GM
2638 case Alogand:
2639 accum &= next;
2640 break;
2641 case Alogior:
2642 accum |= next;
2643 break;
2644 case Alogxor:
2645 accum ^= next;
2646 break;
2647 case Amax:
2648 if (!argnum || next > accum)
2649 accum = next;
2650 break;
2651 case Amin:
2652 if (!argnum || next < accum)
2653 accum = next;
2654 break;
7921925c
JB
2655 }
2656 }
2657
f187f1f7 2658 XSETINT (val, accum);
7921925c
JB
2659 return val;
2660}
2661
1a2f2d33
KH
2662#undef isnan
2663#define isnan(x) ((x) != (x))
2664
7a283f36 2665static Lisp_Object
7921925c
JB
2666float_arith_driver (accum, argnum, code, nargs, args)
2667 double accum;
2668 register int argnum;
2669 enum arithop code;
2670 int nargs;
2671 register Lisp_Object *args;
2672{
2673 register Lisp_Object val;
2674 double next;
7403b5c8 2675
7921925c
JB
2676 for (; argnum < nargs; argnum++)
2677 {
2678 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
b7826503 2679 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
7921925c 2680
e9ebc175 2681 if (FLOATP (val))
7921925c 2682 {
7539e11f 2683 next = XFLOAT_DATA (val);
7921925c
JB
2684 }
2685 else
2686 {
2687 args[argnum] = val; /* runs into a compiler bug. */
2688 next = XINT (args[argnum]);
2689 }
0220c518 2690 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2691 {
2692 case Aadd:
2693 accum += next;
2694 break;
2695 case Asub:
e64981da 2696 accum = argnum ? accum - next : nargs == 1 ? - next : next;
7921925c
JB
2697 break;
2698 case Amult:
2699 accum *= next;
2700 break;
2701 case Adiv:
2702 if (!argnum)
2703 accum = next;
2704 else
87fbf902 2705 {
ad8d56b9 2706 if (! IEEE_FLOATING_POINT && next == 0)
87fbf902
RS
2707 Fsignal (Qarith_error, Qnil);
2708 accum /= next;
2709 }
7921925c
JB
2710 break;
2711 case Alogand:
2712 case Alogior:
2713 case Alogxor:
2714 return wrong_type_argument (Qinteger_or_marker_p, val);
2715 case Amax:
1a2f2d33 2716 if (!argnum || isnan (next) || next > accum)
7921925c
JB
2717 accum = next;
2718 break;
2719 case Amin:
1a2f2d33 2720 if (!argnum || isnan (next) || next < accum)
7921925c
JB
2721 accum = next;
2722 break;
2723 }
2724 }
2725
2726 return make_float (accum);
2727}
cc94f3b2 2728
7921925c
JB
2729
2730DEFUN ("+", Fplus, Splus, 0, MANY, 0,
8c1a1077
PJ
2731 doc: /* Return sum of any number of arguments, which are numbers or markers.
2732usage: (+ &rest NUMBERS-OR-MARKERS) */)
2733 (nargs, args)
7921925c
JB
2734 int nargs;
2735 Lisp_Object *args;
2736{
2737 return arith_driver (Aadd, nargs, args);
2738}
2739
2740DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
558ee900 2741 doc: /* Negate number or subtract numbers or markers and return the result.
8c1a1077 2742With one arg, negates it. With more than one arg,
f44fba9e 2743subtracts all but the first from the first.
8c1a1077
PJ
2744usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */)
2745 (nargs, args)
7921925c
JB
2746 int nargs;
2747 Lisp_Object *args;
2748{
2749 return arith_driver (Asub, nargs, args);
2750}
2751
2752DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
be24eadf 2753 doc: /* Return product of any number of arguments, which are numbers or markers.
8c1a1077
PJ
2754usage: (* &rest NUMBERS-OR-MARKERS) */)
2755 (nargs, args)
7921925c
JB
2756 int nargs;
2757 Lisp_Object *args;
2758{
2759 return arith_driver (Amult, nargs, args);
2760}
2761
2762DEFUN ("/", Fquo, Squo, 2, MANY, 0,
be24eadf 2763 doc: /* Return first argument divided by all the remaining arguments.
f44fba9e 2764The arguments must be numbers or markers.
8c1a1077
PJ
2765usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */)
2766 (nargs, args)
7921925c
JB
2767 int nargs;
2768 Lisp_Object *args;
2769{
28712a21 2770 int argnum;
7ef98053 2771 for (argnum = 2; argnum < nargs; argnum++)
28712a21
JB
2772 if (FLOATP (args[argnum]))
2773 return float_arith_driver (0, 0, Adiv, nargs, args);
7921925c
JB
2774 return arith_driver (Adiv, nargs, args);
2775}
2776
2777DEFUN ("%", Frem, Srem, 2, 2, 0,
be24eadf 2778 doc: /* Return remainder of X divided by Y.
8c1a1077
PJ
2779Both must be integers or markers. */)
2780 (x, y)
d9c2a0f2 2781 register Lisp_Object x, y;
7921925c
JB
2782{
2783 Lisp_Object val;
2784
b7826503
PJ
2785 CHECK_NUMBER_COERCE_MARKER (x);
2786 CHECK_NUMBER_COERCE_MARKER (y);
7921925c 2787
d9c2a0f2 2788 if (XFASTINT (y) == 0)
87fbf902
RS
2789 Fsignal (Qarith_error, Qnil);
2790
d9c2a0f2 2791 XSETINT (val, XINT (x) % XINT (y));
7921925c
JB
2792 return val;
2793}
2794
1d66a5fa
KH
2795#ifndef HAVE_FMOD
2796double
2797fmod (f1, f2)
2798 double f1, f2;
2799{
bc1c9d7e
PE
2800 double r = f1;
2801
fa43b1e8
KH
2802 if (f2 < 0.0)
2803 f2 = -f2;
bc1c9d7e
PE
2804
2805 /* If the magnitude of the result exceeds that of the divisor, or
2806 the sign of the result does not agree with that of the dividend,
2807 iterate with the reduced value. This does not yield a
2808 particularly accurate result, but at least it will be in the
2809 range promised by fmod. */
2810 do
2811 r -= f2 * floor (r / f2);
2812 while (f2 <= (r < 0 ? -r : r) || ((r < 0) != (f1 < 0) && ! isnan (r)));
2813
2814 return r;
1d66a5fa
KH
2815}
2816#endif /* ! HAVE_FMOD */
2817
44fa9da5 2818DEFUN ("mod", Fmod, Smod, 2, 2, 0,
be24eadf 2819 doc: /* Return X modulo Y.
8c1a1077
PJ
2820The result falls between zero (inclusive) and Y (exclusive).
2821Both X and Y must be numbers or markers. */)
2822 (x, y)
d9c2a0f2 2823 register Lisp_Object x, y;
44fa9da5
PE
2824{
2825 Lisp_Object val;
5260234d 2826 EMACS_INT i1, i2;
44fa9da5 2827
b7826503
PJ
2828 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (x);
2829 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (y);
44fa9da5 2830
d9c2a0f2 2831 if (FLOATP (x) || FLOATP (y))
ad8d56b9
PE
2832 return fmod_float (x, y);
2833
d9c2a0f2
EN
2834 i1 = XINT (x);
2835 i2 = XINT (y);
44fa9da5
PE
2836
2837 if (i2 == 0)
2838 Fsignal (Qarith_error, Qnil);
7403b5c8 2839
44fa9da5
PE
2840 i1 %= i2;
2841
2842 /* If the "remainder" comes out with the wrong sign, fix it. */
04f7ec69 2843 if (i2 < 0 ? i1 > 0 : i1 < 0)
44fa9da5
PE
2844 i1 += i2;
2845
f187f1f7 2846 XSETINT (val, i1);
44fa9da5
PE
2847 return val;
2848}
2849
7921925c 2850DEFUN ("max", Fmax, Smax, 1, MANY, 0,
8c1a1077 2851 doc: /* Return largest of all the arguments (which must be numbers or markers).
f44fba9e 2852The value is always a number; markers are converted to numbers.
8c1a1077
PJ
2853usage: (max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2854 (nargs, args)
7921925c
JB
2855 int nargs;
2856 Lisp_Object *args;
2857{
2858 return arith_driver (Amax, nargs, args);
2859}
2860
2861DEFUN ("min", Fmin, Smin, 1, MANY, 0,
8c1a1077 2862 doc: /* Return smallest of all the arguments (which must be numbers or markers).
f44fba9e 2863The value is always a number; markers are converted to numbers.
8c1a1077
PJ
2864usage: (min NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
2865 (nargs, args)
7921925c
JB
2866 int nargs;
2867 Lisp_Object *args;
2868{
2869 return arith_driver (Amin, nargs, args);
2870}
2871
2872DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
8c1a1077 2873 doc: /* Return bitwise-and of all the arguments.
f44fba9e 2874Arguments may be integers, or markers converted to integers.
8c1a1077
PJ
2875usage: (logand &rest INTS-OR-MARKERS) */)
2876 (nargs, args)
7921925c
JB
2877 int nargs;
2878 Lisp_Object *args;
2879{
2880 return arith_driver (Alogand, nargs, args);
2881}
2882
2883DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
8c1a1077 2884 doc: /* Return bitwise-or of all the arguments.
f44fba9e 2885Arguments may be integers, or markers converted to integers.
8c1a1077
PJ
2886usage: (logior &rest INTS-OR-MARKERS) */)
2887 (nargs, args)
7921925c
JB
2888 int nargs;
2889 Lisp_Object *args;
2890{
2891 return arith_driver (Alogior, nargs, args);
2892}
2893
2894DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
8c1a1077 2895 doc: /* Return bitwise-exclusive-or of all the arguments.
f44fba9e 2896Arguments may be integers, or markers converted to integers.
8c1a1077
PJ
2897usage: (logxor &rest INTS-OR-MARKERS) */)
2898 (nargs, args)
7921925c
JB
2899 int nargs;
2900 Lisp_Object *args;
2901{
2902 return arith_driver (Alogxor, nargs, args);
2903}
2904
2905DEFUN ("ash", Fash, Sash, 2, 2, 0,
8c1a1077
PJ
2906 doc: /* Return VALUE with its bits shifted left by COUNT.
2907If COUNT is negative, shifting is actually to the right.
2908In this case, the sign bit is duplicated. */)
2909 (value, count)
3b9f7964 2910 register Lisp_Object value, count;
7921925c
JB
2911{
2912 register Lisp_Object val;
2913
b7826503
PJ
2914 CHECK_NUMBER (value);
2915 CHECK_NUMBER (count);
7921925c 2916
81d70626
RS
2917 if (XINT (count) >= BITS_PER_EMACS_INT)
2918 XSETINT (val, 0);
2919 else if (XINT (count) > 0)
3d9652eb 2920 XSETINT (val, XINT (value) << XFASTINT (count));
81d70626
RS
2921 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2922 XSETINT (val, XINT (value) < 0 ? -1 : 0);
7921925c 2923 else
3d9652eb 2924 XSETINT (val, XINT (value) >> -XINT (count));
7921925c
JB
2925 return val;
2926}
2927
2928DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
8c1a1077
PJ
2929 doc: /* Return VALUE with its bits shifted left by COUNT.
2930If COUNT is negative, shifting is actually to the right.
3a9b1297 2931In this case, zeros are shifted in on the left. */)
8c1a1077 2932 (value, count)
3d9652eb 2933 register Lisp_Object value, count;
7921925c
JB
2934{
2935 register Lisp_Object val;
2936
b7826503
PJ
2937 CHECK_NUMBER (value);
2938 CHECK_NUMBER (count);
7921925c 2939
81d70626
RS
2940 if (XINT (count) >= BITS_PER_EMACS_INT)
2941 XSETINT (val, 0);
2942 else if (XINT (count) > 0)
3d9652eb 2943 XSETINT (val, (EMACS_UINT) XUINT (value) << XFASTINT (count));
81d70626
RS
2944 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2945 XSETINT (val, 0);
7921925c 2946 else
3d9652eb 2947 XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count));
7921925c
JB
2948 return val;
2949}
2950
2951DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
8c1a1077
PJ
2952 doc: /* Return NUMBER plus one. NUMBER may be a number or a marker.
2953Markers are converted to integers. */)
2954 (number)
d9c2a0f2 2955 register Lisp_Object number;
7921925c 2956{
b7826503 2957 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number);
7921925c 2958
d9c2a0f2 2959 if (FLOATP (number))
7539e11f 2960 return (make_float (1.0 + XFLOAT_DATA (number)));
7921925c 2961
d9c2a0f2
EN
2962 XSETINT (number, XINT (number) + 1);
2963 return number;
7921925c
JB
2964}
2965
2966DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
8c1a1077
PJ
2967 doc: /* Return NUMBER minus one. NUMBER may be a number or a marker.
2968Markers are converted to integers. */)
2969 (number)
d9c2a0f2 2970 register Lisp_Object number;
7921925c 2971{
b7826503 2972 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number);
7921925c 2973
d9c2a0f2 2974 if (FLOATP (number))
7539e11f 2975 return (make_float (-1.0 + XFLOAT_DATA (number)));
7921925c 2976
d9c2a0f2
EN
2977 XSETINT (number, XINT (number) - 1);
2978 return number;
7921925c
JB
2979}
2980
2981DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
8c1a1077
PJ
2982 doc: /* Return the bitwise complement of NUMBER. NUMBER must be an integer. */)
2983 (number)
d9c2a0f2 2984 register Lisp_Object number;
7921925c 2985{
b7826503 2986 CHECK_NUMBER (number);
53924017 2987 XSETINT (number, ~XINT (number));
d9c2a0f2 2988 return number;
7921925c 2989}
d4be0d31
JD
2990
2991DEFUN ("byteorder", Fbyteorder, Sbyteorder, 0, 0, 0,
2992 doc: /* Return the byteorder for the machine.
2993Returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII
2994lowercase l) for small endian machines. */)
2995 ()
2996{
2997 unsigned i = 0x04030201;
7a8560d7 2998 int order = *(char *)&i == 1 ? 108 : 66;
d4be0d31 2999
d2f14999 3000 return make_number (order);
d4be0d31
JD
3001}
3002
3003
7921925c
JB
3004\f
3005void
3006syms_of_data ()
3007{
6315e761
RS
3008 Lisp_Object error_tail, arith_tail;
3009
7921925c
JB
3010 Qquote = intern ("quote");
3011 Qlambda = intern ("lambda");
3012 Qsubr = intern ("subr");
3013 Qerror_conditions = intern ("error-conditions");
3014 Qerror_message = intern ("error-message");
3015 Qtop_level = intern ("top-level");
3016
3017 Qerror = intern ("error");
3018 Qquit = intern ("quit");
3019 Qwrong_type_argument = intern ("wrong-type-argument");
3020 Qargs_out_of_range = intern ("args-out-of-range");
3021 Qvoid_function = intern ("void-function");
ffd56f97 3022 Qcyclic_function_indirection = intern ("cyclic-function-indirection");
f35d5bad 3023 Qcyclic_variable_indirection = intern ("cyclic-variable-indirection");
7921925c
JB
3024 Qvoid_variable = intern ("void-variable");
3025 Qsetting_constant = intern ("setting-constant");
3026 Qinvalid_read_syntax = intern ("invalid-read-syntax");
3027
3028 Qinvalid_function = intern ("invalid-function");
3029 Qwrong_number_of_arguments = intern ("wrong-number-of-arguments");
3030 Qno_catch = intern ("no-catch");
3031 Qend_of_file = intern ("end-of-file");
3032 Qarith_error = intern ("arith-error");
3033 Qbeginning_of_buffer = intern ("beginning-of-buffer");
3034 Qend_of_buffer = intern ("end-of-buffer");
3035 Qbuffer_read_only = intern ("buffer-read-only");
8f9f49d7 3036 Qtext_read_only = intern ("text-read-only");
3b8819d6 3037 Qmark_inactive = intern ("mark-inactive");
7921925c
JB
3038
3039 Qlistp = intern ("listp");
3040 Qconsp = intern ("consp");
3041 Qsymbolp = intern ("symbolp");
cda9b832 3042 Qkeywordp = intern ("keywordp");
7921925c
JB
3043 Qintegerp = intern ("integerp");
3044 Qnatnump = intern ("natnump");
8e86942b 3045 Qwholenump = intern ("wholenump");
7921925c
JB
3046 Qstringp = intern ("stringp");
3047 Qarrayp = intern ("arrayp");
3048 Qsequencep = intern ("sequencep");
3049 Qbufferp = intern ("bufferp");
3050 Qvectorp = intern ("vectorp");
3051 Qchar_or_string_p = intern ("char-or-string-p");
3052 Qmarkerp = intern ("markerp");
07bd8472 3053 Qbuffer_or_string_p = intern ("buffer-or-string-p");
7921925c
JB
3054 Qinteger_or_marker_p = intern ("integer-or-marker-p");
3055 Qboundp = intern ("boundp");
3056 Qfboundp = intern ("fboundp");
3057
7921925c
JB
3058 Qfloatp = intern ("floatp");
3059 Qnumberp = intern ("numberp");
3060 Qnumber_or_marker_p = intern ("number-or-marker-p");
7921925c 3061
4d276982 3062 Qchar_table_p = intern ("char-table-p");
7f0edce7 3063 Qvector_or_char_table_p = intern ("vector-or-char-table-p");
4d276982 3064
6f0e897f
DL
3065 Qsubrp = intern ("subrp");
3066 Qunevalled = intern ("unevalled");
3067 Qmany = intern ("many");
3068
7921925c
JB
3069 Qcdr = intern ("cdr");
3070
f845f2c9 3071 /* Handle automatic advice activation */
ab297811 3072 Qad_advice_info = intern ("ad-advice-info");
c1307a23 3073 Qad_activate_internal = intern ("ad-activate-internal");
f845f2c9 3074
6315e761
RS
3075 error_tail = Fcons (Qerror, Qnil);
3076
7921925c
JB
3077 /* ERROR is used as a signaler for random errors for which nothing else is right */
3078
3079 Fput (Qerror, Qerror_conditions,
6315e761 3080 error_tail);
7921925c
JB
3081 Fput (Qerror, Qerror_message,
3082 build_string ("error"));
3083
3084 Fput (Qquit, Qerror_conditions,
3085 Fcons (Qquit, Qnil));
3086 Fput (Qquit, Qerror_message,
3087 build_string ("Quit"));
3088
3089 Fput (Qwrong_type_argument, Qerror_conditions,
6315e761 3090 Fcons (Qwrong_type_argument, error_tail));
7921925c
JB
3091 Fput (Qwrong_type_argument, Qerror_message,
3092 build_string ("Wrong type argument"));
3093
3094 Fput (Qargs_out_of_range, Qerror_conditions,
6315e761 3095 Fcons (Qargs_out_of_range, error_tail));
7921925c
JB
3096 Fput (Qargs_out_of_range, Qerror_message,
3097 build_string ("Args out of range"));
3098
3099 Fput (Qvoid_function, Qerror_conditions,
6315e761 3100 Fcons (Qvoid_function, error_tail));
7921925c
JB
3101 Fput (Qvoid_function, Qerror_message,
3102 build_string ("Symbol's function definition is void"));
3103
ffd56f97 3104 Fput (Qcyclic_function_indirection, Qerror_conditions,
6315e761 3105 Fcons (Qcyclic_function_indirection, error_tail));
ffd56f97
JB
3106 Fput (Qcyclic_function_indirection, Qerror_message,
3107 build_string ("Symbol's chain of function indirections contains a loop"));
3108
f35d5bad
GM
3109 Fput (Qcyclic_variable_indirection, Qerror_conditions,
3110 Fcons (Qcyclic_variable_indirection, error_tail));
3111 Fput (Qcyclic_variable_indirection, Qerror_message,
3112 build_string ("Symbol's chain of variable indirections contains a loop"));
3113
13d95cc0
GM
3114 Qcircular_list = intern ("circular-list");
3115 staticpro (&Qcircular_list);
3116 Fput (Qcircular_list, Qerror_conditions,
3117 Fcons (Qcircular_list, error_tail));
3118 Fput (Qcircular_list, Qerror_message,
3119 build_string ("List contains a loop"));
3120
7921925c 3121 Fput (Qvoid_variable, Qerror_conditions,
6315e761 3122 Fcons (Qvoid_variable, error_tail));
7921925c
JB
3123 Fput (Qvoid_variable, Qerror_message,
3124 build_string ("Symbol's value as variable is void"));
3125
3126 Fput (Qsetting_constant, Qerror_conditions,
6315e761 3127 Fcons (Qsetting_constant, error_tail));
7921925c
JB
3128 Fput (Qsetting_constant, Qerror_message,
3129 build_string ("Attempt to set a constant symbol"));
3130
3131 Fput (Qinvalid_read_syntax, Qerror_conditions,
6315e761 3132 Fcons (Qinvalid_read_syntax, error_tail));
7921925c
JB
3133 Fput (Qinvalid_read_syntax, Qerror_message,
3134 build_string ("Invalid read syntax"));
3135
3136 Fput (Qinvalid_function, Qerror_conditions,
6315e761 3137 Fcons (Qinvalid_function, error_tail));
7921925c
JB
3138 Fput (Qinvalid_function, Qerror_message,
3139 build_string ("Invalid function"));
3140
3141 Fput (Qwrong_number_of_arguments, Qerror_conditions,
6315e761 3142 Fcons (Qwrong_number_of_arguments, error_tail));
7921925c
JB
3143 Fput (Qwrong_number_of_arguments, Qerror_message,
3144 build_string ("Wrong number of arguments"));
3145
3146 Fput (Qno_catch, Qerror_conditions,
6315e761 3147 Fcons (Qno_catch, error_tail));
7921925c
JB
3148 Fput (Qno_catch, Qerror_message,
3149 build_string ("No catch for tag"));
3150
3151 Fput (Qend_of_file, Qerror_conditions,
6315e761 3152 Fcons (Qend_of_file, error_tail));
7921925c
JB
3153 Fput (Qend_of_file, Qerror_message,
3154 build_string ("End of file during parsing"));
3155
6315e761 3156 arith_tail = Fcons (Qarith_error, error_tail);
7921925c 3157 Fput (Qarith_error, Qerror_conditions,
6315e761 3158 arith_tail);
7921925c
JB
3159 Fput (Qarith_error, Qerror_message,
3160 build_string ("Arithmetic error"));
3161
3162 Fput (Qbeginning_of_buffer, Qerror_conditions,
6315e761 3163 Fcons (Qbeginning_of_buffer, error_tail));
7921925c
JB
3164 Fput (Qbeginning_of_buffer, Qerror_message,
3165 build_string ("Beginning of buffer"));
3166
3167 Fput (Qend_of_buffer, Qerror_conditions,
6315e761 3168 Fcons (Qend_of_buffer, error_tail));
7921925c
JB
3169 Fput (Qend_of_buffer, Qerror_message,
3170 build_string ("End of buffer"));
3171
3172 Fput (Qbuffer_read_only, Qerror_conditions,
6315e761 3173 Fcons (Qbuffer_read_only, error_tail));
7921925c
JB
3174 Fput (Qbuffer_read_only, Qerror_message,
3175 build_string ("Buffer is read-only"));
3176
8f9f49d7
GM
3177 Fput (Qtext_read_only, Qerror_conditions,
3178 Fcons (Qtext_read_only, error_tail));
3179 Fput (Qtext_read_only, Qerror_message,
3180 build_string ("Text is read-only"));
3181
6315e761
RS
3182 Qrange_error = intern ("range-error");
3183 Qdomain_error = intern ("domain-error");
3184 Qsingularity_error = intern ("singularity-error");
3185 Qoverflow_error = intern ("overflow-error");
3186 Qunderflow_error = intern ("underflow-error");
3187
3188 Fput (Qdomain_error, Qerror_conditions,
3189 Fcons (Qdomain_error, arith_tail));
3190 Fput (Qdomain_error, Qerror_message,
3191 build_string ("Arithmetic domain error"));
3192
3193 Fput (Qrange_error, Qerror_conditions,
3194 Fcons (Qrange_error, arith_tail));
3195 Fput (Qrange_error, Qerror_message,
3196 build_string ("Arithmetic range error"));
3197
3198 Fput (Qsingularity_error, Qerror_conditions,
3199 Fcons (Qsingularity_error, Fcons (Qdomain_error, arith_tail)));
3200 Fput (Qsingularity_error, Qerror_message,
3201 build_string ("Arithmetic singularity error"));
3202
3203 Fput (Qoverflow_error, Qerror_conditions,
3204 Fcons (Qoverflow_error, Fcons (Qdomain_error, arith_tail)));
3205 Fput (Qoverflow_error, Qerror_message,
3206 build_string ("Arithmetic overflow error"));
3207
3208 Fput (Qunderflow_error, Qerror_conditions,
3209 Fcons (Qunderflow_error, Fcons (Qdomain_error, arith_tail)));
3210 Fput (Qunderflow_error, Qerror_message,
3211 build_string ("Arithmetic underflow error"));
3212
3213 staticpro (&Qrange_error);
3214 staticpro (&Qdomain_error);
3215 staticpro (&Qsingularity_error);
3216 staticpro (&Qoverflow_error);
3217 staticpro (&Qunderflow_error);
6315e761 3218
7921925c
JB
3219 staticpro (&Qnil);
3220 staticpro (&Qt);
3221 staticpro (&Qquote);
3222 staticpro (&Qlambda);
3223 staticpro (&Qsubr);
3224 staticpro (&Qunbound);
3225 staticpro (&Qerror_conditions);
3226 staticpro (&Qerror_message);
3227 staticpro (&Qtop_level);
3228
3229 staticpro (&Qerror);
3230 staticpro (&Qquit);
3231 staticpro (&Qwrong_type_argument);
3232 staticpro (&Qargs_out_of_range);
3233 staticpro (&Qvoid_function);
ffd56f97 3234 staticpro (&Qcyclic_function_indirection);
dfad0b34 3235 staticpro (&Qcyclic_variable_indirection);
7921925c
JB
3236 staticpro (&Qvoid_variable);
3237 staticpro (&Qsetting_constant);
3238 staticpro (&Qinvalid_read_syntax);
3239 staticpro (&Qwrong_number_of_arguments);
3240 staticpro (&Qinvalid_function);
3241 staticpro (&Qno_catch);
3242 staticpro (&Qend_of_file);
3243 staticpro (&Qarith_error);
3244 staticpro (&Qbeginning_of_buffer);
3245 staticpro (&Qend_of_buffer);
3246 staticpro (&Qbuffer_read_only);
8f9f49d7 3247 staticpro (&Qtext_read_only);
638b77e6 3248 staticpro (&Qmark_inactive);
7921925c
JB
3249
3250 staticpro (&Qlistp);
3251 staticpro (&Qconsp);
3252 staticpro (&Qsymbolp);
cda9b832 3253 staticpro (&Qkeywordp);
7921925c
JB
3254 staticpro (&Qintegerp);
3255 staticpro (&Qnatnump);
8e86942b 3256 staticpro (&Qwholenump);
7921925c
JB
3257 staticpro (&Qstringp);
3258 staticpro (&Qarrayp);
3259 staticpro (&Qsequencep);
3260 staticpro (&Qbufferp);
3261 staticpro (&Qvectorp);
3262 staticpro (&Qchar_or_string_p);
3263 staticpro (&Qmarkerp);
07bd8472 3264 staticpro (&Qbuffer_or_string_p);
7921925c 3265 staticpro (&Qinteger_or_marker_p);
7921925c 3266 staticpro (&Qfloatp);
464f8898
RS
3267 staticpro (&Qnumberp);
3268 staticpro (&Qnumber_or_marker_p);
4d276982 3269 staticpro (&Qchar_table_p);
7f0edce7 3270 staticpro (&Qvector_or_char_table_p);
6f0e897f
DL
3271 staticpro (&Qsubrp);
3272 staticpro (&Qmany);
3273 staticpro (&Qunevalled);
7921925c
JB
3274
3275 staticpro (&Qboundp);
3276 staticpro (&Qfboundp);
3277 staticpro (&Qcdr);
ab297811 3278 staticpro (&Qad_advice_info);
c1307a23 3279 staticpro (&Qad_activate_internal);
7921925c 3280
39bcc759
RS
3281 /* Types that type-of returns. */
3282 Qinteger = intern ("integer");
3283 Qsymbol = intern ("symbol");
3284 Qstring = intern ("string");
3285 Qcons = intern ("cons");
3286 Qmarker = intern ("marker");
3287 Qoverlay = intern ("overlay");
3288 Qfloat = intern ("float");
3289 Qwindow_configuration = intern ("window-configuration");
3290 Qprocess = intern ("process");
3291 Qwindow = intern ("window");
3292 /* Qsubr = intern ("subr"); */
3293 Qcompiled_function = intern ("compiled-function");
3294 Qbuffer = intern ("buffer");
3295 Qframe = intern ("frame");
3296 Qvector = intern ("vector");
fc67d5be
KH
3297 Qchar_table = intern ("char-table");
3298 Qbool_vector = intern ("bool-vector");
81dc5de5 3299 Qhash_table = intern ("hash-table");
39bcc759
RS
3300
3301 staticpro (&Qinteger);
3302 staticpro (&Qsymbol);
3303 staticpro (&Qstring);
3304 staticpro (&Qcons);
3305 staticpro (&Qmarker);
3306 staticpro (&Qoverlay);
3307 staticpro (&Qfloat);
3308 staticpro (&Qwindow_configuration);
3309 staticpro (&Qprocess);
3310 staticpro (&Qwindow);
3311 /* staticpro (&Qsubr); */
3312 staticpro (&Qcompiled_function);
3313 staticpro (&Qbuffer);
3314 staticpro (&Qframe);
3315 staticpro (&Qvector);
fc67d5be
KH
3316 staticpro (&Qchar_table);
3317 staticpro (&Qbool_vector);
81dc5de5 3318 staticpro (&Qhash_table);
39bcc759 3319
f35d5bad 3320 defsubr (&Sindirect_variable);
f52a3ca3 3321 defsubr (&Sinteractive_form);
7921925c
JB
3322 defsubr (&Seq);
3323 defsubr (&Snull);
39bcc759 3324 defsubr (&Stype_of);
7921925c
JB
3325 defsubr (&Slistp);
3326 defsubr (&Snlistp);
3327 defsubr (&Sconsp);
3328 defsubr (&Satom);
3329 defsubr (&Sintegerp);
464f8898 3330 defsubr (&Sinteger_or_marker_p);
7921925c
JB
3331 defsubr (&Snumberp);
3332 defsubr (&Snumber_or_marker_p);
464f8898 3333 defsubr (&Sfloatp);
7921925c
JB
3334 defsubr (&Snatnump);
3335 defsubr (&Ssymbolp);
cda9b832 3336 defsubr (&Skeywordp);
7921925c 3337 defsubr (&Sstringp);
0f56470d 3338 defsubr (&Smultibyte_string_p);
7921925c 3339 defsubr (&Svectorp);
4d276982 3340 defsubr (&Schar_table_p);
7f0edce7 3341 defsubr (&Svector_or_char_table_p);
4d276982 3342 defsubr (&Sbool_vector_p);
7921925c
JB
3343 defsubr (&Sarrayp);
3344 defsubr (&Ssequencep);
3345 defsubr (&Sbufferp);
3346 defsubr (&Smarkerp);
7921925c 3347 defsubr (&Ssubrp);
dbc4e1c1 3348 defsubr (&Sbyte_code_function_p);
7921925c
JB
3349 defsubr (&Schar_or_string_p);
3350 defsubr (&Scar);
3351 defsubr (&Scdr);
3352 defsubr (&Scar_safe);
3353 defsubr (&Scdr_safe);
3354 defsubr (&Ssetcar);
3355 defsubr (&Ssetcdr);
3356 defsubr (&Ssymbol_function);
ffd56f97 3357 defsubr (&Sindirect_function);
7921925c
JB
3358 defsubr (&Ssymbol_plist);
3359 defsubr (&Ssymbol_name);
3360 defsubr (&Smakunbound);
3361 defsubr (&Sfmakunbound);
3362 defsubr (&Sboundp);
3363 defsubr (&Sfboundp);
3364 defsubr (&Sfset);
80df38a2 3365 defsubr (&Sdefalias);
7921925c
JB
3366 defsubr (&Ssetplist);
3367 defsubr (&Ssymbol_value);
3368 defsubr (&Sset);
3369 defsubr (&Sdefault_boundp);
3370 defsubr (&Sdefault_value);
3371 defsubr (&Sset_default);
3372 defsubr (&Ssetq_default);
3373 defsubr (&Smake_variable_buffer_local);
3374 defsubr (&Smake_local_variable);
3375 defsubr (&Skill_local_variable);
b0c2d1c6 3376 defsubr (&Smake_variable_frame_local);
62476adc 3377 defsubr (&Slocal_variable_p);
f4f04cee 3378 defsubr (&Slocal_variable_if_set_p);
0a2546d4 3379 defsubr (&Svariable_binding_locus);
c40bb1ba 3380#if 0 /* XXX Remove this. --lorentey */
2a42d440
KL
3381 defsubr (&Sterminal_local_value);
3382 defsubr (&Sset_terminal_local_value);
c40bb1ba 3383#endif
7921925c
JB
3384 defsubr (&Saref);
3385 defsubr (&Saset);
f2980264 3386 defsubr (&Snumber_to_string);
25e40a4b 3387 defsubr (&Sstring_to_number);
7921925c
JB
3388 defsubr (&Seqlsign);
3389 defsubr (&Slss);
3390 defsubr (&Sgtr);
3391 defsubr (&Sleq);
3392 defsubr (&Sgeq);
3393 defsubr (&Sneq);
3394 defsubr (&Szerop);
3395 defsubr (&Splus);
3396 defsubr (&Sminus);
3397 defsubr (&Stimes);
3398 defsubr (&Squo);
3399 defsubr (&Srem);
44fa9da5 3400 defsubr (&Smod);
7921925c
JB
3401 defsubr (&Smax);
3402 defsubr (&Smin);
3403 defsubr (&Slogand);
3404 defsubr (&Slogior);
3405 defsubr (&Slogxor);
3406 defsubr (&Slsh);
3407 defsubr (&Sash);
3408 defsubr (&Sadd1);
3409 defsubr (&Ssub1);
3410 defsubr (&Slognot);
d4be0d31 3411 defsubr (&Sbyteorder);
6f0e897f 3412 defsubr (&Ssubr_arity);
0fddae66 3413 defsubr (&Ssubr_name);
8e86942b 3414
c80bd143 3415 XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function;
e6190b11 3416
9d113d9d
AS
3417 DEFVAR_LISP ("most-positive-fixnum", &Vmost_positive_fixnum,
3418 doc: /* The largest value that is representable in a Lisp integer. */);
3419 Vmost_positive_fixnum = make_number (MOST_POSITIVE_FIXNUM);
bfb96cb7 3420
9d113d9d
AS
3421 DEFVAR_LISP ("most-negative-fixnum", &Vmost_negative_fixnum,
3422 doc: /* The smallest value that is representable in a Lisp integer. */);
3423 Vmost_negative_fixnum = make_number (MOST_NEGATIVE_FIXNUM);
7921925c
JB
3424}
3425
a33ef3ab 3426SIGTYPE
7921925c
JB
3427arith_error (signo)
3428 int signo;
3429{
fe42a920 3430#if defined(USG) && !defined(POSIX_SIGNALS)
7921925c
JB
3431 /* USG systems forget handlers when they are used;
3432 must reestablish each time */
3433 signal (signo, arith_error);
3434#endif /* USG */
3435#ifdef VMS
3436 /* VMS systems are like USG. */
3437 signal (signo, arith_error);
3438#endif /* VMS */
3439#ifdef BSD4_1
3440 sigrelse (SIGFPE);
3441#else /* not BSD4_1 */
e065a56e 3442 sigsetmask (SIGEMPTYMASK);
7921925c
JB
3443#endif /* not BSD4_1 */
3444
333f1b6f 3445 SIGNAL_THREAD_CHECK (signo);
7921925c
JB
3446 Fsignal (Qarith_error, Qnil);
3447}
3448
dfcf069d 3449void
7921925c
JB
3450init_data ()
3451{
3452 /* Don't do this if just dumping out.
3453 We don't want to call `signal' in this case
3454 so that we don't have trouble with dumping
3455 signal-delivering routines in an inconsistent state. */
3456#ifndef CANNOT_DUMP
3457 if (!initialized)
3458 return;
3459#endif /* CANNOT_DUMP */
3460 signal (SIGFPE, arith_error);
7403b5c8 3461
7921925c
JB
3462#ifdef uts
3463 signal (SIGEMT, arith_error);
3464#endif /* uts */
3465}
ab5796a9
MB
3466
3467/* arch-tag: 25879798-b84d-479a-9c89-7d148e2109f7
3468 (do not change this comment) */