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