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