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