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