(copy_sub_char_table): New function.
[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);
3a6cf6bd 1550 if (idxval < CHAR_TABLE_SINGLE_BYTE_SLOTS)
8313c4e7 1551 {
3a6cf6bd
KH
1552 /* For ASCII or 8-bit European characters, the element is
1553 stored in the top table. */
8313c4e7
KH
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 {
8fb379fd
KH
1570 int idx[3]; /* For charset, code1, and code2. */
1571 int i, len;
8313c4e7
KH
1572 Lisp_Object sub_array;
1573
8313c4e7 1574 SPLIT_NON_ASCII_CHAR (idxval, idx[0], idx[1], idx[2]);
8fb379fd 1575 len = (COMPOSITE_CHAR_P (idxval) || idx[2]) ? 3 : (idx[1] ? 2 : 1);
3a6cf6bd
KH
1576 /* The top level char-table should be indexed from 256 for
1577 each non-ASCII charsets. */
1578 idx[0] += 128;
4d276982
RS
1579
1580 try_parent_char_table:
8313c4e7 1581 sub_array = array;
8fb379fd 1582 for (i = 0; i < len; i++)
4d276982 1583 {
8313c4e7
KH
1584 val = XCHAR_TABLE (sub_array)->contents[idx[i]];
1585 if (NILP (val))
1586 val = XCHAR_TABLE (sub_array)->defalt;
1587 if (NILP (val))
1588 {
1589 array = XCHAR_TABLE (array)->parent;
1590 if (NILP (array))
1591 return Qnil;
1592 goto try_parent_char_table;
1593 }
1594 if (!CHAR_TABLE_P (val))
1595 return val;
1596 sub_array = val;
4d276982 1597 }
8313c4e7
KH
1598 /* We come here because ARRAY is deeper than the specified
1599 indices. We return a default value stored at the deepest
1600 level specified. */
1601 val = XCHAR_TABLE (sub_array)->defalt;
1602 if (NILP (val))
4d276982
RS
1603 {
1604 array = XCHAR_TABLE (array)->parent;
8313c4e7
KH
1605 if (NILP (array))
1606 return Qnil;
4d276982
RS
1607 goto try_parent_char_table;
1608 }
4d276982
RS
1609 return val;
1610 }
4d276982 1611 }
7921925c 1612 else
c24e4efe 1613 {
7f358972
RS
1614 int size;
1615 if (VECTORP (array))
1616 size = XVECTOR (array)->size;
1617 else if (COMPILEDP (array))
1618 size = XVECTOR (array)->size & PSEUDOVECTOR_SIZE_MASK;
1619 else
1620 wrong_type_argument (Qarrayp, array);
1621
1622 if (idxval < 0 || idxval >= size)
c24e4efe
KH
1623 args_out_of_range (array, idx);
1624 return XVECTOR (array)->contents[idxval];
1625 }
7921925c
JB
1626}
1627
1628DEFUN ("aset", Faset, Saset, 3, 3, 0,
73d40355
RS
1629 "Store into the element of ARRAY at index IDX the value NEWELT.\n\
1630ARRAY may be a vector or a string. IDX starts at 0.")
7921925c
JB
1631 (array, idx, newelt)
1632 register Lisp_Object array;
1633 Lisp_Object idx, newelt;
1634{
1635 register int idxval;
1636
1637 CHECK_NUMBER (idx, 1);
1638 idxval = XINT (idx);
4d276982
RS
1639 if (!VECTORP (array) && !STRINGP (array) && !BOOL_VECTOR_P (array)
1640 && ! CHAR_TABLE_P (array))
7921925c 1641 array = wrong_type_argument (Qarrayp, array);
7921925c
JB
1642 CHECK_IMPURE (array);
1643
e9ebc175 1644 if (VECTORP (array))
c24e4efe
KH
1645 {
1646 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1647 args_out_of_range (array, idx);
1648 XVECTOR (array)->contents[idxval] = newelt;
1649 }
4d276982
RS
1650 else if (BOOL_VECTOR_P (array))
1651 {
1652 int val;
4d276982
RS
1653
1654 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
1655 args_out_of_range (array, idx);
1656
68be917d 1657 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BITS_PER_CHAR];
4d276982
RS
1658
1659 if (! NILP (newelt))
68be917d 1660 val |= 1 << (idxval % BITS_PER_CHAR);
4d276982 1661 else
68be917d
KH
1662 val &= ~(1 << (idxval % BITS_PER_CHAR));
1663 XBOOL_VECTOR (array)->data[idxval / BITS_PER_CHAR] = val;
4d276982
RS
1664 }
1665 else if (CHAR_TABLE_P (array))
1666 {
1667 Lisp_Object val;
1668
1669 if (idxval < 0)
1670 args_out_of_range (array, idx);
3a6cf6bd 1671 if (idxval < CHAR_TABLE_SINGLE_BYTE_SLOTS)
8313c4e7 1672 XCHAR_TABLE (array)->contents[idxval] = newelt;
4d276982
RS
1673 else
1674 {
8fb379fd
KH
1675 int idx[3]; /* For charset, code1, and code2. */
1676 int i, len;
8313c4e7 1677 Lisp_Object val;
4d276982 1678
8313c4e7 1679 SPLIT_NON_ASCII_CHAR (idxval, idx[0], idx[1], idx[2]);
8fb379fd 1680 len = (COMPOSITE_CHAR_P (idxval) || idx[2]) ? 2 : (idx[1] ? 1 : 0);
3a6cf6bd
KH
1681 /* The top level char-table should be indexed from 256 for
1682 each non-ASCII charsets. */
1683 idx[0] += 128;
4d276982 1684
8fb379fd 1685 for (i = 0; i < len; i++)
8313c4e7
KH
1686 {
1687 val = XCHAR_TABLE (array)->contents[idx[i]];
1688 if (CHAR_TABLE_P (val))
1689 /* Look into this deeper array. */
1690 array = val;
1691 else
1692 {
1693 /* VAL is the leaf. Create a deeper array with the
1694 default value VAL, set it in the slot of VAL, and
1695 look into it. */
1696 array = XCHAR_TABLE (array)->contents[idx[i]]
1697 = Fmake_char_table (Qnil, Qnil);
1698 XCHAR_TABLE (array)->defalt = val;
1699 }
1700 }
1701 return XCHAR_TABLE (array)->contents[idx[i]] = newelt;
4d276982 1702 }
4d276982 1703 }
7921925c
JB
1704 else
1705 {
c24e4efe
KH
1706 if (idxval < 0 || idxval >= XSTRING (array)->size)
1707 args_out_of_range (array, idx);
7921925c
JB
1708 CHECK_NUMBER (newelt, 2);
1709 XSTRING (array)->data[idxval] = XINT (newelt);
1710 }
1711
1712 return newelt;
1713}
7921925c
JB
1714\f
1715/* Arithmetic functions */
1716
1717enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
1718
1719Lisp_Object
1720arithcompare (num1, num2, comparison)
1721 Lisp_Object num1, num2;
1722 enum comparison comparison;
1723{
1724 double f1, f2;
1725 int floatp = 0;
1726
1727#ifdef LISP_FLOAT_TYPE
1728 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1729 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
1730
e9ebc175 1731 if (FLOATP (num1) || FLOATP (num2))
7921925c
JB
1732 {
1733 floatp = 1;
e9ebc175
KH
1734 f1 = (FLOATP (num1)) ? XFLOAT (num1)->data : XINT (num1);
1735 f2 = (FLOATP (num2)) ? XFLOAT (num2)->data : XINT (num2);
7921925c
JB
1736 }
1737#else
1738 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1739 CHECK_NUMBER_COERCE_MARKER (num2, 0);
1740#endif /* LISP_FLOAT_TYPE */
1741
1742 switch (comparison)
1743 {
1744 case equal:
1745 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
1746 return Qt;
1747 return Qnil;
1748
1749 case notequal:
1750 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
1751 return Qt;
1752 return Qnil;
1753
1754 case less:
1755 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
1756 return Qt;
1757 return Qnil;
1758
1759 case less_or_equal:
1760 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
1761 return Qt;
1762 return Qnil;
1763
1764 case grtr:
1765 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
1766 return Qt;
1767 return Qnil;
1768
1769 case grtr_or_equal:
1770 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
1771 return Qt;
1772 return Qnil;
25e40a4b
JB
1773
1774 default:
1775 abort ();
7921925c
JB
1776 }
1777}
1778
1779DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0,
1780 "T if two args, both numbers or markers, are equal.")
1781 (num1, num2)
1782 register Lisp_Object num1, num2;
1783{
1784 return arithcompare (num1, num2, equal);
1785}
1786
1787DEFUN ("<", Flss, Slss, 2, 2, 0,
1788 "T if first arg is less than second arg. Both must be numbers or markers.")
1789 (num1, num2)
1790 register Lisp_Object num1, num2;
1791{
1792 return arithcompare (num1, num2, less);
1793}
1794
1795DEFUN (">", Fgtr, Sgtr, 2, 2, 0,
1796 "T if first arg is greater than second arg. Both must be numbers or markers.")
1797 (num1, num2)
1798 register Lisp_Object num1, num2;
1799{
1800 return arithcompare (num1, num2, grtr);
1801}
1802
1803DEFUN ("<=", Fleq, Sleq, 2, 2, 0,
1804 "T if first arg is less than or equal to second arg.\n\
1805Both must be numbers or markers.")
1806 (num1, num2)
1807 register Lisp_Object num1, num2;
1808{
1809 return arithcompare (num1, num2, less_or_equal);
1810}
1811
1812DEFUN (">=", Fgeq, Sgeq, 2, 2, 0,
1813 "T if first arg is greater than or equal to second arg.\n\
1814Both must be numbers or markers.")
1815 (num1, num2)
1816 register Lisp_Object num1, num2;
1817{
1818 return arithcompare (num1, num2, grtr_or_equal);
1819}
1820
1821DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
1822 "T if first arg is not equal to second arg. Both must be numbers or markers.")
1823 (num1, num2)
1824 register Lisp_Object num1, num2;
1825{
1826 return arithcompare (num1, num2, notequal);
1827}
1828
1829DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, "T if NUMBER is zero.")
d9c2a0f2
EN
1830 (number)
1831 register Lisp_Object number;
7921925c
JB
1832{
1833#ifdef LISP_FLOAT_TYPE
d9c2a0f2 1834 CHECK_NUMBER_OR_FLOAT (number, 0);
7921925c 1835
d9c2a0f2 1836 if (FLOATP (number))
7921925c 1837 {
d9c2a0f2 1838 if (XFLOAT(number)->data == 0.0)
7921925c
JB
1839 return Qt;
1840 return Qnil;
1841 }
1842#else
d9c2a0f2 1843 CHECK_NUMBER (number, 0);
7921925c
JB
1844#endif /* LISP_FLOAT_TYPE */
1845
d9c2a0f2 1846 if (!XINT (number))
7921925c
JB
1847 return Qt;
1848 return Qnil;
1849}
1850\f
34f4f6c6 1851/* Convert between long values and pairs of Lisp integers. */
51cf3e31
JB
1852
1853Lisp_Object
1854long_to_cons (i)
1855 unsigned long i;
1856{
1857 unsigned int top = i >> 16;
1858 unsigned int bot = i & 0xFFFF;
1859 if (top == 0)
1860 return make_number (bot);
b42cfa11 1861 if (top == (unsigned long)-1 >> 16)
51cf3e31
JB
1862 return Fcons (make_number (-1), make_number (bot));
1863 return Fcons (make_number (top), make_number (bot));
1864}
1865
1866unsigned long
1867cons_to_long (c)
1868 Lisp_Object c;
1869{
878a80cc 1870 Lisp_Object top, bot;
51cf3e31
JB
1871 if (INTEGERP (c))
1872 return XINT (c);
1873 top = XCONS (c)->car;
1874 bot = XCONS (c)->cdr;
1875 if (CONSP (bot))
1876 bot = XCONS (bot)->car;
1877 return ((XINT (top) << 16) | XINT (bot));
1878}
1879\f
f2980264 1880DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
d9c2a0f2 1881 "Convert NUMBER to a string by printing it in decimal.\n\
25e40a4b 1882Uses a minus sign if negative.\n\
d9c2a0f2
EN
1883NUMBER may be an integer or a floating point number.")
1884 (number)
1885 Lisp_Object number;
7921925c 1886{
6030ce64 1887 char buffer[VALBITS];
7921925c
JB
1888
1889#ifndef LISP_FLOAT_TYPE
d9c2a0f2 1890 CHECK_NUMBER (number, 0);
7921925c 1891#else
d9c2a0f2 1892 CHECK_NUMBER_OR_FLOAT (number, 0);
7921925c 1893
d9c2a0f2 1894 if (FLOATP (number))
7921925c
JB
1895 {
1896 char pigbuf[350]; /* see comments in float_to_string */
1897
d9c2a0f2 1898 float_to_string (pigbuf, XFLOAT(number)->data);
7403b5c8 1899 return build_string (pigbuf);
7921925c
JB
1900 }
1901#endif /* LISP_FLOAT_TYPE */
1902
e6c82a8d 1903 if (sizeof (int) == sizeof (EMACS_INT))
d9c2a0f2 1904 sprintf (buffer, "%d", XINT (number));
e6c82a8d 1905 else if (sizeof (long) == sizeof (EMACS_INT))
d9c2a0f2 1906 sprintf (buffer, "%ld", XINT (number));
e6c82a8d
RS
1907 else
1908 abort ();
7921925c
JB
1909 return build_string (buffer);
1910}
1911
25e40a4b
JB
1912DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 1, 0,
1913 "Convert STRING to a number by parsing it as a decimal number.\n\
1c1c17eb
RS
1914This parses both integers and floating point numbers.\n\
1915It ignores leading spaces and tabs.")
d9c2a0f2
EN
1916 (string)
1917 register Lisp_Object string;
7921925c 1918{
e6c82a8d 1919 Lisp_Object value;
0a3e4d65 1920 unsigned char *p;
25e40a4b 1921
d9c2a0f2 1922 CHECK_STRING (string, 0);
7921925c 1923
d9c2a0f2 1924 p = XSTRING (string)->data;
25e40a4b
JB
1925
1926 /* Skip any whitespace at the front of the number. Some versions of
1927 atoi do this anyway, so we might as well make Emacs lisp consistent. */
0a3e4d65 1928 while (*p == ' ' || *p == '\t')
25e40a4b
JB
1929 p++;
1930
7921925c 1931#ifdef LISP_FLOAT_TYPE
25e40a4b
JB
1932 if (isfloat_string (p))
1933 return make_float (atof (p));
7921925c
JB
1934#endif /* LISP_FLOAT_TYPE */
1935
e6c82a8d
RS
1936 if (sizeof (int) == sizeof (EMACS_INT))
1937 XSETINT (value, atoi (p));
1938 else if (sizeof (long) == sizeof (EMACS_INT))
1939 XSETINT (value, atol (p));
1940 else
1941 abort ();
1942 return value;
7921925c 1943}
7403b5c8 1944\f
7921925c
JB
1945enum arithop
1946 { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin };
1947
b06faa91 1948extern Lisp_Object float_arith_driver ();
ad8d56b9 1949extern Lisp_Object fmod_float ();
b06faa91 1950
7921925c 1951Lisp_Object
87fbf902 1952arith_driver (code, nargs, args)
7921925c
JB
1953 enum arithop code;
1954 int nargs;
1955 register Lisp_Object *args;
1956{
1957 register Lisp_Object val;
1958 register int argnum;
5260234d
RS
1959 register EMACS_INT accum;
1960 register EMACS_INT next;
7921925c 1961
0220c518 1962 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
1963 {
1964 case Alogior:
1965 case Alogxor:
1966 case Aadd:
1967 case Asub:
1968 accum = 0; break;
1969 case Amult:
1970 accum = 1; break;
1971 case Alogand:
1972 accum = -1; break;
1973 }
1974
1975 for (argnum = 0; argnum < nargs; argnum++)
1976 {
1977 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
1978#ifdef LISP_FLOAT_TYPE
1979 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
1980
e9ebc175 1981 if (FLOATP (val)) /* time to do serious math */
7921925c
JB
1982 return (float_arith_driver ((double) accum, argnum, code,
1983 nargs, args));
1984#else
1985 CHECK_NUMBER_COERCE_MARKER (val, argnum);
1986#endif /* LISP_FLOAT_TYPE */
1987 args[argnum] = val; /* runs into a compiler bug. */
1988 next = XINT (args[argnum]);
0220c518 1989 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
1990 {
1991 case Aadd: accum += next; break;
1992 case Asub:
1993 if (!argnum && nargs != 1)
1994 next = - next;
1995 accum -= next;
1996 break;
1997 case Amult: accum *= next; break;
1998 case Adiv:
1999 if (!argnum) accum = next;
87fbf902
RS
2000 else
2001 {
2002 if (next == 0)
2003 Fsignal (Qarith_error, Qnil);
2004 accum /= next;
2005 }
7921925c
JB
2006 break;
2007 case Alogand: accum &= next; break;
2008 case Alogior: accum |= next; break;
2009 case Alogxor: accum ^= next; break;
2010 case Amax: if (!argnum || next > accum) accum = next; break;
2011 case Amin: if (!argnum || next < accum) accum = next; break;
2012 }
2013 }
2014
f187f1f7 2015 XSETINT (val, accum);
7921925c
JB
2016 return val;
2017}
2018
1a2f2d33
KH
2019#undef isnan
2020#define isnan(x) ((x) != (x))
2021
bc1c9d7e
PE
2022#ifdef LISP_FLOAT_TYPE
2023
7921925c
JB
2024Lisp_Object
2025float_arith_driver (accum, argnum, code, nargs, args)
2026 double accum;
2027 register int argnum;
2028 enum arithop code;
2029 int nargs;
2030 register Lisp_Object *args;
2031{
2032 register Lisp_Object val;
2033 double next;
7403b5c8 2034
7921925c
JB
2035 for (; argnum < nargs; argnum++)
2036 {
2037 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
2038 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
2039
e9ebc175 2040 if (FLOATP (val))
7921925c
JB
2041 {
2042 next = XFLOAT (val)->data;
2043 }
2044 else
2045 {
2046 args[argnum] = val; /* runs into a compiler bug. */
2047 next = XINT (args[argnum]);
2048 }
0220c518 2049 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2050 {
2051 case Aadd:
2052 accum += next;
2053 break;
2054 case Asub:
2055 if (!argnum && nargs != 1)
2056 next = - next;
2057 accum -= next;
2058 break;
2059 case Amult:
2060 accum *= next;
2061 break;
2062 case Adiv:
2063 if (!argnum)
2064 accum = next;
2065 else
87fbf902 2066 {
ad8d56b9 2067 if (! IEEE_FLOATING_POINT && next == 0)
87fbf902
RS
2068 Fsignal (Qarith_error, Qnil);
2069 accum /= next;
2070 }
7921925c
JB
2071 break;
2072 case Alogand:
2073 case Alogior:
2074 case Alogxor:
2075 return wrong_type_argument (Qinteger_or_marker_p, val);
2076 case Amax:
1a2f2d33 2077 if (!argnum || isnan (next) || next > accum)
7921925c
JB
2078 accum = next;
2079 break;
2080 case Amin:
1a2f2d33 2081 if (!argnum || isnan (next) || next < accum)
7921925c
JB
2082 accum = next;
2083 break;
2084 }
2085 }
2086
2087 return make_float (accum);
2088}
2089#endif /* LISP_FLOAT_TYPE */
2090
2091DEFUN ("+", Fplus, Splus, 0, MANY, 0,
2092 "Return sum of any number of arguments, which are numbers or markers.")
2093 (nargs, args)
2094 int nargs;
2095 Lisp_Object *args;
2096{
2097 return arith_driver (Aadd, nargs, args);
2098}
2099
2100DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
2101 "Negate number or subtract numbers or markers.\n\
2102With one arg, negates it. With more than one arg,\n\
2103subtracts all but the first from the first.")
2104 (nargs, args)
2105 int nargs;
2106 Lisp_Object *args;
2107{
2108 return arith_driver (Asub, nargs, args);
2109}
2110
2111DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
2112 "Returns product of any number of arguments, which are numbers or markers.")
2113 (nargs, args)
2114 int nargs;
2115 Lisp_Object *args;
2116{
2117 return arith_driver (Amult, nargs, args);
2118}
2119
2120DEFUN ("/", Fquo, Squo, 2, MANY, 0,
2121 "Returns first argument divided by all the remaining arguments.\n\
2122The arguments must be numbers or markers.")
2123 (nargs, args)
2124 int nargs;
2125 Lisp_Object *args;
2126{
2127 return arith_driver (Adiv, nargs, args);
2128}
2129
2130DEFUN ("%", Frem, Srem, 2, 2, 0,
d9c2a0f2 2131 "Returns remainder of X divided by Y.\n\
aa29f9b9 2132Both must be integers or markers.")
d9c2a0f2
EN
2133 (x, y)
2134 register Lisp_Object x, y;
7921925c
JB
2135{
2136 Lisp_Object val;
2137
d9c2a0f2
EN
2138 CHECK_NUMBER_COERCE_MARKER (x, 0);
2139 CHECK_NUMBER_COERCE_MARKER (y, 1);
7921925c 2140
d9c2a0f2 2141 if (XFASTINT (y) == 0)
87fbf902
RS
2142 Fsignal (Qarith_error, Qnil);
2143
d9c2a0f2 2144 XSETINT (val, XINT (x) % XINT (y));
7921925c
JB
2145 return val;
2146}
2147
1d66a5fa
KH
2148#ifndef HAVE_FMOD
2149double
2150fmod (f1, f2)
2151 double f1, f2;
2152{
bc1c9d7e
PE
2153 double r = f1;
2154
fa43b1e8
KH
2155 if (f2 < 0.0)
2156 f2 = -f2;
bc1c9d7e
PE
2157
2158 /* If the magnitude of the result exceeds that of the divisor, or
2159 the sign of the result does not agree with that of the dividend,
2160 iterate with the reduced value. This does not yield a
2161 particularly accurate result, but at least it will be in the
2162 range promised by fmod. */
2163 do
2164 r -= f2 * floor (r / f2);
2165 while (f2 <= (r < 0 ? -r : r) || ((r < 0) != (f1 < 0) && ! isnan (r)));
2166
2167 return r;
1d66a5fa
KH
2168}
2169#endif /* ! HAVE_FMOD */
2170
44fa9da5
PE
2171DEFUN ("mod", Fmod, Smod, 2, 2, 0,
2172 "Returns X modulo Y.\n\
2173The result falls between zero (inclusive) and Y (exclusive).\n\
2174Both X and Y must be numbers or markers.")
d9c2a0f2
EN
2175 (x, y)
2176 register Lisp_Object x, y;
44fa9da5
PE
2177{
2178 Lisp_Object val;
5260234d 2179 EMACS_INT i1, i2;
44fa9da5
PE
2180
2181#ifdef LISP_FLOAT_TYPE
d9c2a0f2
EN
2182 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (x, 0);
2183 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (y, 1);
44fa9da5 2184
d9c2a0f2 2185 if (FLOATP (x) || FLOATP (y))
ad8d56b9
PE
2186 return fmod_float (x, y);
2187
44fa9da5 2188#else /* not LISP_FLOAT_TYPE */
d9c2a0f2
EN
2189 CHECK_NUMBER_COERCE_MARKER (x, 0);
2190 CHECK_NUMBER_COERCE_MARKER (y, 1);
44fa9da5
PE
2191#endif /* not LISP_FLOAT_TYPE */
2192
d9c2a0f2
EN
2193 i1 = XINT (x);
2194 i2 = XINT (y);
44fa9da5
PE
2195
2196 if (i2 == 0)
2197 Fsignal (Qarith_error, Qnil);
7403b5c8 2198
44fa9da5
PE
2199 i1 %= i2;
2200
2201 /* If the "remainder" comes out with the wrong sign, fix it. */
04f7ec69 2202 if (i2 < 0 ? i1 > 0 : i1 < 0)
44fa9da5
PE
2203 i1 += i2;
2204
f187f1f7 2205 XSETINT (val, i1);
44fa9da5
PE
2206 return val;
2207}
2208
7921925c
JB
2209DEFUN ("max", Fmax, Smax, 1, MANY, 0,
2210 "Return largest of all the arguments (which must be numbers or markers).\n\
2211The value is always a number; markers are converted to numbers.")
2212 (nargs, args)
2213 int nargs;
2214 Lisp_Object *args;
2215{
2216 return arith_driver (Amax, nargs, args);
2217}
2218
2219DEFUN ("min", Fmin, Smin, 1, MANY, 0,
2220 "Return smallest of all the arguments (which must be numbers or markers).\n\
2221The value is always a number; markers are converted to numbers.")
2222 (nargs, args)
2223 int nargs;
2224 Lisp_Object *args;
2225{
2226 return arith_driver (Amin, nargs, args);
2227}
2228
2229DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
2230 "Return bitwise-and of all the arguments.\n\
2231Arguments may be integers, or markers converted to integers.")
2232 (nargs, args)
2233 int nargs;
2234 Lisp_Object *args;
2235{
2236 return arith_driver (Alogand, nargs, args);
2237}
2238
2239DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
2240 "Return bitwise-or of all the arguments.\n\
2241Arguments may be integers, or markers converted to integers.")
2242 (nargs, args)
2243 int nargs;
2244 Lisp_Object *args;
2245{
2246 return arith_driver (Alogior, nargs, args);
2247}
2248
2249DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
2250 "Return bitwise-exclusive-or of all the arguments.\n\
2251Arguments may be integers, or markers converted to integers.")
2252 (nargs, args)
2253 int nargs;
2254 Lisp_Object *args;
2255{
2256 return arith_driver (Alogxor, nargs, args);
2257}
2258
2259DEFUN ("ash", Fash, Sash, 2, 2, 0,
2260 "Return VALUE with its bits shifted left by COUNT.\n\
2261If COUNT is negative, shifting is actually to the right.\n\
2262In this case, the sign bit is duplicated.")
3b9f7964
RS
2263 (value, count)
2264 register Lisp_Object value, count;
7921925c
JB
2265{
2266 register Lisp_Object val;
2267
3d9652eb
RS
2268 CHECK_NUMBER (value, 0);
2269 CHECK_NUMBER (count, 1);
7921925c 2270
3d9652eb
RS
2271 if (XINT (count) > 0)
2272 XSETINT (val, XINT (value) << XFASTINT (count));
7921925c 2273 else
3d9652eb 2274 XSETINT (val, XINT (value) >> -XINT (count));
7921925c
JB
2275 return val;
2276}
2277
2278DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
2279 "Return VALUE with its bits shifted left by COUNT.\n\
2280If COUNT is negative, shifting is actually to the right.\n\
2281In this case, zeros are shifted in on the left.")
3d9652eb
RS
2282 (value, count)
2283 register Lisp_Object value, count;
7921925c
JB
2284{
2285 register Lisp_Object val;
2286
3d9652eb
RS
2287 CHECK_NUMBER (value, 0);
2288 CHECK_NUMBER (count, 1);
7921925c 2289
3d9652eb
RS
2290 if (XINT (count) > 0)
2291 XSETINT (val, (EMACS_UINT) XUINT (value) << XFASTINT (count));
7921925c 2292 else
3d9652eb 2293 XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count));
7921925c
JB
2294 return val;
2295}
2296
2297DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
2298 "Return NUMBER plus one. NUMBER may be a number or a marker.\n\
2299Markers are converted to integers.")
d9c2a0f2
EN
2300 (number)
2301 register Lisp_Object number;
7921925c
JB
2302{
2303#ifdef LISP_FLOAT_TYPE
d9c2a0f2 2304 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number, 0);
7921925c 2305
d9c2a0f2
EN
2306 if (FLOATP (number))
2307 return (make_float (1.0 + XFLOAT (number)->data));
7921925c 2308#else
d9c2a0f2 2309 CHECK_NUMBER_COERCE_MARKER (number, 0);
7921925c
JB
2310#endif /* LISP_FLOAT_TYPE */
2311
d9c2a0f2
EN
2312 XSETINT (number, XINT (number) + 1);
2313 return number;
7921925c
JB
2314}
2315
2316DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
2317 "Return NUMBER minus one. NUMBER may be a number or a marker.\n\
2318Markers are converted to integers.")
d9c2a0f2
EN
2319 (number)
2320 register Lisp_Object number;
7921925c
JB
2321{
2322#ifdef LISP_FLOAT_TYPE
d9c2a0f2 2323 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number, 0);
7921925c 2324
d9c2a0f2
EN
2325 if (FLOATP (number))
2326 return (make_float (-1.0 + XFLOAT (number)->data));
7921925c 2327#else
d9c2a0f2 2328 CHECK_NUMBER_COERCE_MARKER (number, 0);
7921925c
JB
2329#endif /* LISP_FLOAT_TYPE */
2330
d9c2a0f2
EN
2331 XSETINT (number, XINT (number) - 1);
2332 return number;
7921925c
JB
2333}
2334
2335DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
d9c2a0f2
EN
2336 "Return the bitwise complement of NUMBER. NUMBER must be an integer.")
2337 (number)
2338 register Lisp_Object number;
7921925c 2339{
d9c2a0f2 2340 CHECK_NUMBER (number, 0);
53924017 2341 XSETINT (number, ~XINT (number));
d9c2a0f2 2342 return number;
7921925c
JB
2343}
2344\f
2345void
2346syms_of_data ()
2347{
6315e761
RS
2348 Lisp_Object error_tail, arith_tail;
2349
7921925c
JB
2350 Qquote = intern ("quote");
2351 Qlambda = intern ("lambda");
2352 Qsubr = intern ("subr");
2353 Qerror_conditions = intern ("error-conditions");
2354 Qerror_message = intern ("error-message");
2355 Qtop_level = intern ("top-level");
2356
2357 Qerror = intern ("error");
2358 Qquit = intern ("quit");
2359 Qwrong_type_argument = intern ("wrong-type-argument");
2360 Qargs_out_of_range = intern ("args-out-of-range");
2361 Qvoid_function = intern ("void-function");
ffd56f97 2362 Qcyclic_function_indirection = intern ("cyclic-function-indirection");
7921925c
JB
2363 Qvoid_variable = intern ("void-variable");
2364 Qsetting_constant = intern ("setting-constant");
2365 Qinvalid_read_syntax = intern ("invalid-read-syntax");
2366
2367 Qinvalid_function = intern ("invalid-function");
2368 Qwrong_number_of_arguments = intern ("wrong-number-of-arguments");
2369 Qno_catch = intern ("no-catch");
2370 Qend_of_file = intern ("end-of-file");
2371 Qarith_error = intern ("arith-error");
2372 Qbeginning_of_buffer = intern ("beginning-of-buffer");
2373 Qend_of_buffer = intern ("end-of-buffer");
2374 Qbuffer_read_only = intern ("buffer-read-only");
3b8819d6 2375 Qmark_inactive = intern ("mark-inactive");
7921925c
JB
2376
2377 Qlistp = intern ("listp");
2378 Qconsp = intern ("consp");
2379 Qsymbolp = intern ("symbolp");
2380 Qintegerp = intern ("integerp");
2381 Qnatnump = intern ("natnump");
8e86942b 2382 Qwholenump = intern ("wholenump");
7921925c
JB
2383 Qstringp = intern ("stringp");
2384 Qarrayp = intern ("arrayp");
2385 Qsequencep = intern ("sequencep");
2386 Qbufferp = intern ("bufferp");
2387 Qvectorp = intern ("vectorp");
2388 Qchar_or_string_p = intern ("char-or-string-p");
2389 Qmarkerp = intern ("markerp");
07bd8472 2390 Qbuffer_or_string_p = intern ("buffer-or-string-p");
7921925c
JB
2391 Qinteger_or_marker_p = intern ("integer-or-marker-p");
2392 Qboundp = intern ("boundp");
2393 Qfboundp = intern ("fboundp");
2394
2395#ifdef LISP_FLOAT_TYPE
2396 Qfloatp = intern ("floatp");
2397 Qnumberp = intern ("numberp");
2398 Qnumber_or_marker_p = intern ("number-or-marker-p");
2399#endif /* LISP_FLOAT_TYPE */
2400
4d276982 2401 Qchar_table_p = intern ("char-table-p");
7f0edce7 2402 Qvector_or_char_table_p = intern ("vector-or-char-table-p");
4d276982 2403
7921925c
JB
2404 Qcdr = intern ("cdr");
2405
f845f2c9 2406 /* Handle automatic advice activation */
ab297811
RS
2407 Qad_advice_info = intern ("ad-advice-info");
2408 Qad_activate = intern ("ad-activate");
f845f2c9 2409
6315e761
RS
2410 error_tail = Fcons (Qerror, Qnil);
2411
7921925c
JB
2412 /* ERROR is used as a signaler for random errors for which nothing else is right */
2413
2414 Fput (Qerror, Qerror_conditions,
6315e761 2415 error_tail);
7921925c
JB
2416 Fput (Qerror, Qerror_message,
2417 build_string ("error"));
2418
2419 Fput (Qquit, Qerror_conditions,
2420 Fcons (Qquit, Qnil));
2421 Fput (Qquit, Qerror_message,
2422 build_string ("Quit"));
2423
2424 Fput (Qwrong_type_argument, Qerror_conditions,
6315e761 2425 Fcons (Qwrong_type_argument, error_tail));
7921925c
JB
2426 Fput (Qwrong_type_argument, Qerror_message,
2427 build_string ("Wrong type argument"));
2428
2429 Fput (Qargs_out_of_range, Qerror_conditions,
6315e761 2430 Fcons (Qargs_out_of_range, error_tail));
7921925c
JB
2431 Fput (Qargs_out_of_range, Qerror_message,
2432 build_string ("Args out of range"));
2433
2434 Fput (Qvoid_function, Qerror_conditions,
6315e761 2435 Fcons (Qvoid_function, error_tail));
7921925c
JB
2436 Fput (Qvoid_function, Qerror_message,
2437 build_string ("Symbol's function definition is void"));
2438
ffd56f97 2439 Fput (Qcyclic_function_indirection, Qerror_conditions,
6315e761 2440 Fcons (Qcyclic_function_indirection, error_tail));
ffd56f97
JB
2441 Fput (Qcyclic_function_indirection, Qerror_message,
2442 build_string ("Symbol's chain of function indirections contains a loop"));
2443
7921925c 2444 Fput (Qvoid_variable, Qerror_conditions,
6315e761 2445 Fcons (Qvoid_variable, error_tail));
7921925c
JB
2446 Fput (Qvoid_variable, Qerror_message,
2447 build_string ("Symbol's value as variable is void"));
2448
2449 Fput (Qsetting_constant, Qerror_conditions,
6315e761 2450 Fcons (Qsetting_constant, error_tail));
7921925c
JB
2451 Fput (Qsetting_constant, Qerror_message,
2452 build_string ("Attempt to set a constant symbol"));
2453
2454 Fput (Qinvalid_read_syntax, Qerror_conditions,
6315e761 2455 Fcons (Qinvalid_read_syntax, error_tail));
7921925c
JB
2456 Fput (Qinvalid_read_syntax, Qerror_message,
2457 build_string ("Invalid read syntax"));
2458
2459 Fput (Qinvalid_function, Qerror_conditions,
6315e761 2460 Fcons (Qinvalid_function, error_tail));
7921925c
JB
2461 Fput (Qinvalid_function, Qerror_message,
2462 build_string ("Invalid function"));
2463
2464 Fput (Qwrong_number_of_arguments, Qerror_conditions,
6315e761 2465 Fcons (Qwrong_number_of_arguments, error_tail));
7921925c
JB
2466 Fput (Qwrong_number_of_arguments, Qerror_message,
2467 build_string ("Wrong number of arguments"));
2468
2469 Fput (Qno_catch, Qerror_conditions,
6315e761 2470 Fcons (Qno_catch, error_tail));
7921925c
JB
2471 Fput (Qno_catch, Qerror_message,
2472 build_string ("No catch for tag"));
2473
2474 Fput (Qend_of_file, Qerror_conditions,
6315e761 2475 Fcons (Qend_of_file, error_tail));
7921925c
JB
2476 Fput (Qend_of_file, Qerror_message,
2477 build_string ("End of file during parsing"));
2478
6315e761 2479 arith_tail = Fcons (Qarith_error, error_tail);
7921925c 2480 Fput (Qarith_error, Qerror_conditions,
6315e761 2481 arith_tail);
7921925c
JB
2482 Fput (Qarith_error, Qerror_message,
2483 build_string ("Arithmetic error"));
2484
2485 Fput (Qbeginning_of_buffer, Qerror_conditions,
6315e761 2486 Fcons (Qbeginning_of_buffer, error_tail));
7921925c
JB
2487 Fput (Qbeginning_of_buffer, Qerror_message,
2488 build_string ("Beginning of buffer"));
2489
2490 Fput (Qend_of_buffer, Qerror_conditions,
6315e761 2491 Fcons (Qend_of_buffer, error_tail));
7921925c
JB
2492 Fput (Qend_of_buffer, Qerror_message,
2493 build_string ("End of buffer"));
2494
2495 Fput (Qbuffer_read_only, Qerror_conditions,
6315e761 2496 Fcons (Qbuffer_read_only, error_tail));
7921925c
JB
2497 Fput (Qbuffer_read_only, Qerror_message,
2498 build_string ("Buffer is read-only"));
2499
6315e761
RS
2500#ifdef LISP_FLOAT_TYPE
2501 Qrange_error = intern ("range-error");
2502 Qdomain_error = intern ("domain-error");
2503 Qsingularity_error = intern ("singularity-error");
2504 Qoverflow_error = intern ("overflow-error");
2505 Qunderflow_error = intern ("underflow-error");
2506
2507 Fput (Qdomain_error, Qerror_conditions,
2508 Fcons (Qdomain_error, arith_tail));
2509 Fput (Qdomain_error, Qerror_message,
2510 build_string ("Arithmetic domain error"));
2511
2512 Fput (Qrange_error, Qerror_conditions,
2513 Fcons (Qrange_error, arith_tail));
2514 Fput (Qrange_error, Qerror_message,
2515 build_string ("Arithmetic range error"));
2516
2517 Fput (Qsingularity_error, Qerror_conditions,
2518 Fcons (Qsingularity_error, Fcons (Qdomain_error, arith_tail)));
2519 Fput (Qsingularity_error, Qerror_message,
2520 build_string ("Arithmetic singularity error"));
2521
2522 Fput (Qoverflow_error, Qerror_conditions,
2523 Fcons (Qoverflow_error, Fcons (Qdomain_error, arith_tail)));
2524 Fput (Qoverflow_error, Qerror_message,
2525 build_string ("Arithmetic overflow error"));
2526
2527 Fput (Qunderflow_error, Qerror_conditions,
2528 Fcons (Qunderflow_error, Fcons (Qdomain_error, arith_tail)));
2529 Fput (Qunderflow_error, Qerror_message,
2530 build_string ("Arithmetic underflow error"));
2531
2532 staticpro (&Qrange_error);
2533 staticpro (&Qdomain_error);
2534 staticpro (&Qsingularity_error);
2535 staticpro (&Qoverflow_error);
2536 staticpro (&Qunderflow_error);
2537#endif /* LISP_FLOAT_TYPE */
2538
7921925c
JB
2539 staticpro (&Qnil);
2540 staticpro (&Qt);
2541 staticpro (&Qquote);
2542 staticpro (&Qlambda);
2543 staticpro (&Qsubr);
2544 staticpro (&Qunbound);
2545 staticpro (&Qerror_conditions);
2546 staticpro (&Qerror_message);
2547 staticpro (&Qtop_level);
2548
2549 staticpro (&Qerror);
2550 staticpro (&Qquit);
2551 staticpro (&Qwrong_type_argument);
2552 staticpro (&Qargs_out_of_range);
2553 staticpro (&Qvoid_function);
ffd56f97 2554 staticpro (&Qcyclic_function_indirection);
7921925c
JB
2555 staticpro (&Qvoid_variable);
2556 staticpro (&Qsetting_constant);
2557 staticpro (&Qinvalid_read_syntax);
2558 staticpro (&Qwrong_number_of_arguments);
2559 staticpro (&Qinvalid_function);
2560 staticpro (&Qno_catch);
2561 staticpro (&Qend_of_file);
2562 staticpro (&Qarith_error);
2563 staticpro (&Qbeginning_of_buffer);
2564 staticpro (&Qend_of_buffer);
2565 staticpro (&Qbuffer_read_only);
638b77e6 2566 staticpro (&Qmark_inactive);
7921925c
JB
2567
2568 staticpro (&Qlistp);
2569 staticpro (&Qconsp);
2570 staticpro (&Qsymbolp);
2571 staticpro (&Qintegerp);
2572 staticpro (&Qnatnump);
8e86942b 2573 staticpro (&Qwholenump);
7921925c
JB
2574 staticpro (&Qstringp);
2575 staticpro (&Qarrayp);
2576 staticpro (&Qsequencep);
2577 staticpro (&Qbufferp);
2578 staticpro (&Qvectorp);
2579 staticpro (&Qchar_or_string_p);
2580 staticpro (&Qmarkerp);
07bd8472 2581 staticpro (&Qbuffer_or_string_p);
7921925c
JB
2582 staticpro (&Qinteger_or_marker_p);
2583#ifdef LISP_FLOAT_TYPE
2584 staticpro (&Qfloatp);
464f8898
RS
2585 staticpro (&Qnumberp);
2586 staticpro (&Qnumber_or_marker_p);
7921925c 2587#endif /* LISP_FLOAT_TYPE */
4d276982 2588 staticpro (&Qchar_table_p);
7f0edce7 2589 staticpro (&Qvector_or_char_table_p);
7921925c
JB
2590
2591 staticpro (&Qboundp);
2592 staticpro (&Qfboundp);
2593 staticpro (&Qcdr);
ab297811
RS
2594 staticpro (&Qad_advice_info);
2595 staticpro (&Qad_activate);
7921925c 2596
39bcc759
RS
2597 /* Types that type-of returns. */
2598 Qinteger = intern ("integer");
2599 Qsymbol = intern ("symbol");
2600 Qstring = intern ("string");
2601 Qcons = intern ("cons");
2602 Qmarker = intern ("marker");
2603 Qoverlay = intern ("overlay");
2604 Qfloat = intern ("float");
2605 Qwindow_configuration = intern ("window-configuration");
2606 Qprocess = intern ("process");
2607 Qwindow = intern ("window");
2608 /* Qsubr = intern ("subr"); */
2609 Qcompiled_function = intern ("compiled-function");
2610 Qbuffer = intern ("buffer");
2611 Qframe = intern ("frame");
2612 Qvector = intern ("vector");
fc67d5be
KH
2613 Qchar_table = intern ("char-table");
2614 Qbool_vector = intern ("bool-vector");
39bcc759
RS
2615
2616 staticpro (&Qinteger);
2617 staticpro (&Qsymbol);
2618 staticpro (&Qstring);
2619 staticpro (&Qcons);
2620 staticpro (&Qmarker);
2621 staticpro (&Qoverlay);
2622 staticpro (&Qfloat);
2623 staticpro (&Qwindow_configuration);
2624 staticpro (&Qprocess);
2625 staticpro (&Qwindow);
2626 /* staticpro (&Qsubr); */
2627 staticpro (&Qcompiled_function);
2628 staticpro (&Qbuffer);
2629 staticpro (&Qframe);
2630 staticpro (&Qvector);
fc67d5be
KH
2631 staticpro (&Qchar_table);
2632 staticpro (&Qbool_vector);
39bcc759 2633
7921925c
JB
2634 defsubr (&Seq);
2635 defsubr (&Snull);
39bcc759 2636 defsubr (&Stype_of);
7921925c
JB
2637 defsubr (&Slistp);
2638 defsubr (&Snlistp);
2639 defsubr (&Sconsp);
2640 defsubr (&Satom);
2641 defsubr (&Sintegerp);
464f8898 2642 defsubr (&Sinteger_or_marker_p);
7921925c
JB
2643 defsubr (&Snumberp);
2644 defsubr (&Snumber_or_marker_p);
464f8898
RS
2645#ifdef LISP_FLOAT_TYPE
2646 defsubr (&Sfloatp);
7921925c
JB
2647#endif /* LISP_FLOAT_TYPE */
2648 defsubr (&Snatnump);
2649 defsubr (&Ssymbolp);
2650 defsubr (&Sstringp);
2651 defsubr (&Svectorp);
4d276982 2652 defsubr (&Schar_table_p);
7f0edce7 2653 defsubr (&Svector_or_char_table_p);
4d276982 2654 defsubr (&Sbool_vector_p);
7921925c
JB
2655 defsubr (&Sarrayp);
2656 defsubr (&Ssequencep);
2657 defsubr (&Sbufferp);
2658 defsubr (&Smarkerp);
7921925c 2659 defsubr (&Ssubrp);
dbc4e1c1 2660 defsubr (&Sbyte_code_function_p);
7921925c
JB
2661 defsubr (&Schar_or_string_p);
2662 defsubr (&Scar);
2663 defsubr (&Scdr);
2664 defsubr (&Scar_safe);
2665 defsubr (&Scdr_safe);
2666 defsubr (&Ssetcar);
2667 defsubr (&Ssetcdr);
2668 defsubr (&Ssymbol_function);
ffd56f97 2669 defsubr (&Sindirect_function);
7921925c
JB
2670 defsubr (&Ssymbol_plist);
2671 defsubr (&Ssymbol_name);
2672 defsubr (&Smakunbound);
2673 defsubr (&Sfmakunbound);
2674 defsubr (&Sboundp);
2675 defsubr (&Sfboundp);
2676 defsubr (&Sfset);
80df38a2 2677 defsubr (&Sdefalias);
7921925c
JB
2678 defsubr (&Ssetplist);
2679 defsubr (&Ssymbol_value);
2680 defsubr (&Sset);
2681 defsubr (&Sdefault_boundp);
2682 defsubr (&Sdefault_value);
2683 defsubr (&Sset_default);
2684 defsubr (&Ssetq_default);
2685 defsubr (&Smake_variable_buffer_local);
2686 defsubr (&Smake_local_variable);
2687 defsubr (&Skill_local_variable);
62476adc 2688 defsubr (&Slocal_variable_p);
f4f04cee 2689 defsubr (&Slocal_variable_if_set_p);
7921925c
JB
2690 defsubr (&Saref);
2691 defsubr (&Saset);
f2980264 2692 defsubr (&Snumber_to_string);
25e40a4b 2693 defsubr (&Sstring_to_number);
7921925c
JB
2694 defsubr (&Seqlsign);
2695 defsubr (&Slss);
2696 defsubr (&Sgtr);
2697 defsubr (&Sleq);
2698 defsubr (&Sgeq);
2699 defsubr (&Sneq);
2700 defsubr (&Szerop);
2701 defsubr (&Splus);
2702 defsubr (&Sminus);
2703 defsubr (&Stimes);
2704 defsubr (&Squo);
2705 defsubr (&Srem);
44fa9da5 2706 defsubr (&Smod);
7921925c
JB
2707 defsubr (&Smax);
2708 defsubr (&Smin);
2709 defsubr (&Slogand);
2710 defsubr (&Slogior);
2711 defsubr (&Slogxor);
2712 defsubr (&Slsh);
2713 defsubr (&Sash);
2714 defsubr (&Sadd1);
2715 defsubr (&Ssub1);
2716 defsubr (&Slognot);
8e86942b 2717
c80bd143 2718 XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function;
7921925c
JB
2719}
2720
a33ef3ab 2721SIGTYPE
7921925c
JB
2722arith_error (signo)
2723 int signo;
2724{
fe42a920 2725#if defined(USG) && !defined(POSIX_SIGNALS)
7921925c
JB
2726 /* USG systems forget handlers when they are used;
2727 must reestablish each time */
2728 signal (signo, arith_error);
2729#endif /* USG */
2730#ifdef VMS
2731 /* VMS systems are like USG. */
2732 signal (signo, arith_error);
2733#endif /* VMS */
2734#ifdef BSD4_1
2735 sigrelse (SIGFPE);
2736#else /* not BSD4_1 */
e065a56e 2737 sigsetmask (SIGEMPTYMASK);
7921925c
JB
2738#endif /* not BSD4_1 */
2739
2740 Fsignal (Qarith_error, Qnil);
2741}
2742
2743init_data ()
2744{
2745 /* Don't do this if just dumping out.
2746 We don't want to call `signal' in this case
2747 so that we don't have trouble with dumping
2748 signal-delivering routines in an inconsistent state. */
2749#ifndef CANNOT_DUMP
2750 if (!initialized)
2751 return;
2752#endif /* CANNOT_DUMP */
2753 signal (SIGFPE, arith_error);
7403b5c8 2754
7921925c
JB
2755#ifdef uts
2756 signal (SIGEMT, arith_error);
2757#endif /* uts */
2758}