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