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