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