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