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