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