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