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