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