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