(fast_string_match): Give re_search byte size of
[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);
787 if (! NILP (type) && ! NILP (newval)
788 && XTYPE (newval) != XINT (type))
789 buffer_slot_type_mismatch (offset);
790
791 *(Lisp_Object *)(offset + (char *)current_buffer) = newval;
46b2ac21 792 }
7403b5c8
KH
793 break;
794
e5f8af9e
KH
795 case Lisp_Misc_Kboard_Objfwd:
796 (*(Lisp_Object *)((char *)current_kboard
797 + XKBOARD_OBJFWD (valcontents)->offset))
7403b5c8
KH
798 = newval;
799 break;
800
46b2ac21
KH
801 default:
802 goto def;
803 }
7921925c
JB
804 break;
805
7921925c 806 default:
46b2ac21 807 def:
d9c2a0f2 808 valcontents = XSYMBOL (symbol)->value;
e9ebc175
KH
809 if (BUFFER_LOCAL_VALUEP (valcontents)
810 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
8d4afcac 811 XBUFFER_LOCAL_VALUE (valcontents)->car = newval;
7921925c 812 else
d9c2a0f2 813 XSYMBOL (symbol)->value = newval;
7921925c
JB
814 }
815}
816
d9c2a0f2 817/* Set up the buffer-local symbol SYMBOL for validity in the current
7921925c
JB
818 buffer. VALCONTENTS is the contents of its value cell.
819 Return the value forwarded one step past the buffer-local indicator. */
820
821static Lisp_Object
d9c2a0f2
EN
822swap_in_symval_forwarding (symbol, valcontents)
823 Lisp_Object symbol, valcontents;
7921925c 824{
7403b5c8 825 /* valcontents is a pointer to a struct resembling the cons
7921925c 826 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE)).
7403b5c8 827
7921925c 828 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
533984a8
JB
829 local_var_alist, that being the element whose car is this
830 variable. Or it can be a pointer to the
831 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not have
832 an element in its alist for this variable.
833
834 If the current buffer is not BUFFER, we store the current
835 REALVALUE value into CURRENT-ALIST-ELEMENT, then find the
836 appropriate alist element for the buffer now current and set up
837 CURRENT-ALIST-ELEMENT. Then we set REALVALUE out of that
838 element, and store into BUFFER.
839
7921925c
JB
840 Note that REALVALUE can be a forwarding pointer. */
841
842 register Lisp_Object tem1;
8d4afcac 843 tem1 = XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car;
7921925c 844
a33ef3ab 845 if (NILP (tem1) || current_buffer != XBUFFER (tem1))
7921925c 846 {
8d4afcac
KH
847 tem1 = XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car;
848 Fsetcdr (tem1,
849 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->car));
d9c2a0f2 850 tem1 = assq_no_quit (symbol, current_buffer->local_var_alist);
a33ef3ab 851 if (NILP (tem1))
8d4afcac
KH
852 tem1 = XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr;
853 XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car = tem1;
854 XSETBUFFER (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car,
855 current_buffer);
d9c2a0f2 856 store_symval_forwarding (symbol, XBUFFER_LOCAL_VALUE (valcontents)->car,
8d4afcac 857 Fcdr (tem1));
7921925c 858 }
8d4afcac 859 return XBUFFER_LOCAL_VALUE (valcontents)->car;
7921925c
JB
860}
861\f
14e76af9
JB
862/* Find the value of a symbol, returning Qunbound if it's not bound.
863 This is helpful for code which just wants to get a variable's value
8e6208c5 864 if it has one, without signaling an error.
14e76af9
JB
865 Note that it must not be possible to quit
866 within this function. Great care is required for this. */
7921925c 867
14e76af9 868Lisp_Object
d9c2a0f2
EN
869find_symbol_value (symbol)
870 Lisp_Object symbol;
7921925c
JB
871{
872 register Lisp_Object valcontents, tem1;
873 register Lisp_Object val;
d9c2a0f2
EN
874 CHECK_SYMBOL (symbol, 0);
875 valcontents = XSYMBOL (symbol)->value;
7921925c 876
aabf6bec
KH
877 if (BUFFER_LOCAL_VALUEP (valcontents)
878 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 879 valcontents = swap_in_symval_forwarding (symbol, valcontents);
7921925c 880
536b772a
KH
881 if (MISCP (valcontents))
882 {
324a6eef 883 switch (XMISCTYPE (valcontents))
46b2ac21
KH
884 {
885 case Lisp_Misc_Intfwd:
886 XSETINT (val, *XINTFWD (valcontents)->intvar);
887 return val;
7921925c 888
46b2ac21
KH
889 case Lisp_Misc_Boolfwd:
890 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
7921925c 891
46b2ac21
KH
892 case Lisp_Misc_Objfwd:
893 return *XOBJFWD (valcontents)->objvar;
7921925c 894
46b2ac21
KH
895 case Lisp_Misc_Buffer_Objfwd:
896 return *(Lisp_Object *)(XBUFFER_OBJFWD (valcontents)->offset
897 + (char *)current_buffer);
7403b5c8 898
e5f8af9e
KH
899 case Lisp_Misc_Kboard_Objfwd:
900 return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset
901 + (char *)current_kboard);
46b2ac21 902 }
7921925c
JB
903 }
904
905 return valcontents;
906}
907
14e76af9
JB
908DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
909 "Return SYMBOL's value. Error if that is void.")
d9c2a0f2
EN
910 (symbol)
911 Lisp_Object symbol;
14e76af9 912{
0671d7c0 913 Lisp_Object val;
14e76af9 914
d9c2a0f2 915 val = find_symbol_value (symbol);
14e76af9 916 if (EQ (val, Qunbound))
d9c2a0f2 917 return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
14e76af9
JB
918 else
919 return val;
920}
921
7921925c
JB
922DEFUN ("set", Fset, Sset, 2, 2, 0,
923 "Set SYMBOL's value to NEWVAL, and return NEWVAL.")
d9c2a0f2
EN
924 (symbol, newval)
925 register Lisp_Object symbol, newval;
05ef7169
RS
926{
927 return set_internal (symbol, newval, 0);
928}
929
25638b07 930/* Store the value NEWVAL into SYMBOL.
05ef7169
RS
931 If BINDFLAG is zero, then if this symbol is supposed to become
932 local in every buffer where it is set, then we make it local.
933 If BINDFLAG is nonzero, we don't do that. */
934
935Lisp_Object
936set_internal (symbol, newval, bindflag)
937 register Lisp_Object symbol, newval;
938 int bindflag;
7921925c 939{
1bfcade3 940 int voide = EQ (newval, Qunbound);
7921925c 941
7921925c 942 register Lisp_Object valcontents, tem1, current_alist_element;
7921925c 943
d9c2a0f2
EN
944 CHECK_SYMBOL (symbol, 0);
945 if (NILP (symbol) || EQ (symbol, Qt))
946 return Fsignal (Qsetting_constant, Fcons (symbol, Qnil));
947 valcontents = XSYMBOL (symbol)->value;
7921925c 948
e9ebc175 949 if (BUFFER_OBJFWDP (valcontents))
7921925c 950 {
46b2ac21 951 register int idx = XBUFFER_OBJFWD (valcontents)->offset;
865c050f
KH
952 register int mask = XINT (*((Lisp_Object *)
953 (idx + (char *)&buffer_local_flags)));
7921925c
JB
954 if (mask > 0)
955 current_buffer->local_var_flags |= mask;
956 }
957
e9ebc175
KH
958 else if (BUFFER_LOCAL_VALUEP (valcontents)
959 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 960 {
8d4afcac
KH
961 /* valcontents is actually a pointer to a struct resembling a cons,
962 with contents something like:
d8cafeb5
JB
963 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE).
964
965 BUFFER is the last buffer for which this symbol's value was
966 made up to date.
967
968 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
969 local_var_alist, that being the element whose car is this
970 variable. Or it can be a pointer to the
971 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not
972 have an element in its alist for this variable (that is, if
973 BUFFER sees the default value of this variable).
974
975 If we want to examine or set the value and BUFFER is current,
976 we just examine or set REALVALUE. If BUFFER is not current, we
977 store the current REALVALUE value into CURRENT-ALIST-ELEMENT,
978 then find the appropriate alist element for the buffer now
979 current and set up CURRENT-ALIST-ELEMENT. Then we set
980 REALVALUE out of that element, and store into BUFFER.
981
982 If we are setting the variable and the current buffer does
983 not have an alist entry for this variable, an alist entry is
984 created.
985
986 Note that REALVALUE can be a forwarding pointer. Each time
987 it is examined or set, forwarding must be done. */
988
989 /* What value are we caching right now? */
990 current_alist_element =
8d4afcac 991 XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car;
d8cafeb5
JB
992
993 /* If the current buffer is not the buffer whose binding is
994 currently cached, or if it's a Lisp_Buffer_Local_Value and
995 we're looking at the default value, the cache is invalid; we
996 need to write it out, and find the new CURRENT-ALIST-ELEMENT. */
997 if ((current_buffer
8d4afcac 998 != XBUFFER (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car))
e9ebc175 999 || (BUFFER_LOCAL_VALUEP (valcontents)
b06faa91
JB
1000 && EQ (XCONS (current_alist_element)->car,
1001 current_alist_element)))
7921925c 1002 {
d8cafeb5
JB
1003 /* Write out the cached value for the old buffer; copy it
1004 back to its alist element. This works if the current
1005 buffer only sees the default value, too. */
1006 Fsetcdr (current_alist_element,
8d4afcac 1007 do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->car));
7921925c 1008
d8cafeb5 1009 /* Find the new value for CURRENT-ALIST-ELEMENT. */
d9c2a0f2 1010 tem1 = Fassq (symbol, current_buffer->local_var_alist);
a33ef3ab 1011 if (NILP (tem1))
d8cafeb5
JB
1012 {
1013 /* This buffer still sees the default value. */
1014
1015 /* If the variable is a Lisp_Some_Buffer_Local_Value,
05ef7169 1016 or if this is `let' rather than `set',
d8cafeb5
JB
1017 make CURRENT-ALIST-ELEMENT point to itself,
1018 indicating that we're seeing the default value. */
05ef7169 1019 if (bindflag || SOME_BUFFER_LOCAL_VALUEP (valcontents))
8d4afcac 1020 tem1 = XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr;
d8cafeb5 1021
05ef7169
RS
1022 /* If it's a Lisp_Buffer_Local_Value, being set not bound,
1023 give this buffer a new assoc for a local value and set
d8cafeb5
JB
1024 CURRENT-ALIST-ELEMENT to point to that. */
1025 else
1026 {
d9c2a0f2 1027 tem1 = Fcons (symbol, Fcdr (current_alist_element));
d8cafeb5
JB
1028 current_buffer->local_var_alist =
1029 Fcons (tem1, current_buffer->local_var_alist);
1030 }
1031 }
1032 /* Cache the new buffer's assoc in CURRENT-ALIST-ELEMENT. */
8d4afcac
KH
1033 XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car
1034 = tem1;
d8cafeb5
JB
1035
1036 /* Set BUFFER, now that CURRENT-ALIST-ELEMENT is accurate. */
8d4afcac
KH
1037 XSETBUFFER (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car,
1038 current_buffer);
7921925c 1039 }
8d4afcac 1040 valcontents = XBUFFER_LOCAL_VALUE (valcontents)->car;
7921925c 1041 }
d8cafeb5 1042
7921925c
JB
1043 /* If storing void (making the symbol void), forward only through
1044 buffer-local indicator, not through Lisp_Objfwd, etc. */
1045 if (voide)
d9c2a0f2 1046 store_symval_forwarding (symbol, Qnil, newval);
7921925c 1047 else
d9c2a0f2 1048 store_symval_forwarding (symbol, valcontents, newval);
d8cafeb5 1049
7921925c
JB
1050 return newval;
1051}
1052\f
1053/* Access or set a buffer-local symbol's default value. */
1054
d9c2a0f2 1055/* Return the default value of SYMBOL, but don't check for voidness.
1bfcade3 1056 Return Qunbound if it is void. */
7921925c
JB
1057
1058Lisp_Object
d9c2a0f2
EN
1059default_value (symbol)
1060 Lisp_Object symbol;
7921925c
JB
1061{
1062 register Lisp_Object valcontents;
1063
d9c2a0f2
EN
1064 CHECK_SYMBOL (symbol, 0);
1065 valcontents = XSYMBOL (symbol)->value;
7921925c
JB
1066
1067 /* For a built-in buffer-local variable, get the default value
1068 rather than letting do_symval_forwarding get the current value. */
e9ebc175 1069 if (BUFFER_OBJFWDP (valcontents))
7921925c 1070 {
46b2ac21 1071 register int idx = XBUFFER_OBJFWD (valcontents)->offset;
7921925c 1072
865c050f 1073 if (XINT (*(Lisp_Object *) (idx + (char *) &buffer_local_flags)) != 0)
7921925c
JB
1074 return *(Lisp_Object *)(idx + (char *) &buffer_defaults);
1075 }
1076
1077 /* Handle user-created local variables. */
e9ebc175
KH
1078 if (BUFFER_LOCAL_VALUEP (valcontents)
1079 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c
JB
1080 {
1081 /* If var is set up for a buffer that lacks a local value for it,
1082 the current value is nominally the default value.
1083 But the current value slot may be more up to date, since
1084 ordinary setq stores just that slot. So use that. */
1085 Lisp_Object current_alist_element, alist_element_car;
1086 current_alist_element
8d4afcac 1087 = XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car;
7921925c
JB
1088 alist_element_car = XCONS (current_alist_element)->car;
1089 if (EQ (alist_element_car, current_alist_element))
8d4afcac 1090 return do_symval_forwarding (XBUFFER_LOCAL_VALUE (valcontents)->car);
7921925c 1091 else
8d4afcac 1092 return XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->cdr;
7921925c
JB
1093 }
1094 /* For other variables, get the current value. */
1095 return do_symval_forwarding (valcontents);
1096}
1097
1098DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
c2124165 1099 "Return t if SYMBOL has a non-void default value.\n\
7921925c
JB
1100This is the value that is seen in buffers that do not have their own values\n\
1101for this variable.")
d9c2a0f2
EN
1102 (symbol)
1103 Lisp_Object symbol;
7921925c
JB
1104{
1105 register Lisp_Object value;
1106
d9c2a0f2 1107 value = default_value (symbol);
1bfcade3 1108 return (EQ (value, Qunbound) ? Qnil : Qt);
7921925c
JB
1109}
1110
1111DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0,
1112 "Return SYMBOL's default value.\n\
1113This is the value that is seen in buffers that do not have their own values\n\
1114for this variable. The default value is meaningful for variables with\n\
1115local bindings in certain buffers.")
d9c2a0f2
EN
1116 (symbol)
1117 Lisp_Object symbol;
7921925c
JB
1118{
1119 register Lisp_Object value;
1120
d9c2a0f2 1121 value = default_value (symbol);
1bfcade3 1122 if (EQ (value, Qunbound))
d9c2a0f2 1123 return Fsignal (Qvoid_variable, Fcons (symbol, Qnil));
7921925c
JB
1124 return value;
1125}
1126
1127DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
1128 "Set SYMBOL's default value to VAL. SYMBOL and VAL are evaluated.\n\
1129The default value is seen in buffers that do not have their own values\n\
1130for this variable.")
d9c2a0f2
EN
1131 (symbol, value)
1132 Lisp_Object symbol, value;
7921925c
JB
1133{
1134 register Lisp_Object valcontents, current_alist_element, alist_element_buffer;
1135
d9c2a0f2
EN
1136 CHECK_SYMBOL (symbol, 0);
1137 valcontents = XSYMBOL (symbol)->value;
7921925c
JB
1138
1139 /* Handle variables like case-fold-search that have special slots
1140 in the buffer. Make them work apparently like Lisp_Buffer_Local_Value
1141 variables. */
e9ebc175 1142 if (BUFFER_OBJFWDP (valcontents))
7921925c 1143 {
46b2ac21 1144 register int idx = XBUFFER_OBJFWD (valcontents)->offset;
7921925c 1145 register struct buffer *b;
865c050f
KH
1146 register int mask = XINT (*((Lisp_Object *)
1147 (idx + (char *)&buffer_local_flags)));
7921925c
JB
1148
1149 if (mask > 0)
1150 {
1151 *(Lisp_Object *)(idx + (char *) &buffer_defaults) = value;
1152 for (b = all_buffers; b; b = b->next)
1153 if (!(b->local_var_flags & mask))
1154 *(Lisp_Object *)(idx + (char *) b) = value;
1155 }
1156 return value;
1157 }
1158
e9ebc175
KH
1159 if (!BUFFER_LOCAL_VALUEP (valcontents)
1160 && !SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 1161 return Fset (symbol, value);
7921925c
JB
1162
1163 /* Store new value into the DEFAULT-VALUE slot */
8d4afcac 1164 XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->cdr = value;
7921925c
JB
1165
1166 /* If that slot is current, we must set the REALVALUE slot too */
8d4afcac
KH
1167 current_alist_element
1168 = XCONS (XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->cdr)->car;
7921925c
JB
1169 alist_element_buffer = Fcar (current_alist_element);
1170 if (EQ (alist_element_buffer, current_alist_element))
d9c2a0f2 1171 store_symval_forwarding (symbol, XBUFFER_LOCAL_VALUE (valcontents)->car,
8d4afcac 1172 value);
7921925c
JB
1173
1174 return value;
1175}
1176
1177DEFUN ("setq-default", Fsetq_default, Ssetq_default, 2, UNEVALLED, 0,
0412bf67
RS
1178 "Set the default value of variable VAR to VALUE.\n\
1179VAR, the variable name, is literal (not evaluated);\n\
1180VALUE is an expression and it is evaluated.\n\
1181The default value of a variable is seen in buffers\n\
1182that do not have their own values for the variable.\n\
1183\n\
1184More generally, you can use multiple variables and values, as in\n\
d9c2a0f2
EN
1185 (setq-default SYMBOL VALUE SYMBOL VALUE...)\n\
1186This sets each SYMBOL's default value to the corresponding VALUE.\n\
1187The VALUE for the Nth SYMBOL can refer to the new default values\n\
0412bf67 1188of previous SYMs.")
7921925c
JB
1189 (args)
1190 Lisp_Object args;
1191{
1192 register Lisp_Object args_left;
d9c2a0f2 1193 register Lisp_Object val, symbol;
7921925c
JB
1194 struct gcpro gcpro1;
1195
a33ef3ab 1196 if (NILP (args))
7921925c
JB
1197 return Qnil;
1198
1199 args_left = args;
1200 GCPRO1 (args);
1201
1202 do
1203 {
1204 val = Feval (Fcar (Fcdr (args_left)));
d9c2a0f2
EN
1205 symbol = Fcar (args_left);
1206 Fset_default (symbol, val);
7921925c
JB
1207 args_left = Fcdr (Fcdr (args_left));
1208 }
a33ef3ab 1209 while (!NILP (args_left));
7921925c
JB
1210
1211 UNGCPRO;
1212 return val;
1213}
1214\f
a5ca2b75
JB
1215/* Lisp functions for creating and removing buffer-local variables. */
1216
7921925c
JB
1217DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local,
1218 1, 1, "vMake Variable Buffer Local: ",
1219 "Make VARIABLE have a separate value for each buffer.\n\
1220At any time, the value for the current buffer is in effect.\n\
1221There is also a default value which is seen in any buffer which has not yet\n\
1222set its own value.\n\
1223Using `set' or `setq' to set the variable causes it to have a separate value\n\
1224for the current buffer if it was previously using the default value.\n\
1225The function `default-value' gets the default value and `set-default' sets it.")
d9c2a0f2
EN
1226 (variable)
1227 register Lisp_Object variable;
7921925c 1228{
8d4afcac 1229 register Lisp_Object tem, valcontents, newval;
7921925c 1230
d9c2a0f2 1231 CHECK_SYMBOL (variable, 0);
7921925c 1232
d9c2a0f2
EN
1233 valcontents = XSYMBOL (variable)->value;
1234 if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
1235 error ("Symbol %s may not be buffer-local", XSYMBOL (variable)->name->data);
7921925c 1236
e9ebc175 1237 if (BUFFER_LOCAL_VALUEP (valcontents) || BUFFER_OBJFWDP (valcontents))
d9c2a0f2 1238 return variable;
e9ebc175 1239 if (SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 1240 {
d9c2a0f2
EN
1241 XMISCTYPE (XSYMBOL (variable)->value) = Lisp_Misc_Buffer_Local_Value;
1242 return variable;
7921925c
JB
1243 }
1244 if (EQ (valcontents, Qunbound))
d9c2a0f2
EN
1245 XSYMBOL (variable)->value = Qnil;
1246 tem = Fcons (Qnil, Fsymbol_value (variable));
7921925c 1247 XCONS (tem)->car = tem;
8d4afcac 1248 newval = allocate_misc ();
324a6eef 1249 XMISCTYPE (newval) = Lisp_Misc_Buffer_Local_Value;
d9c2a0f2 1250 XBUFFER_LOCAL_VALUE (newval)->car = XSYMBOL (variable)->value;
8d4afcac 1251 XBUFFER_LOCAL_VALUE (newval)->cdr = Fcons (Fcurrent_buffer (), tem);
d9c2a0f2
EN
1252 XSYMBOL (variable)->value = newval;
1253 return variable;
7921925c
JB
1254}
1255
1256DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable,
1257 1, 1, "vMake Local Variable: ",
1258 "Make VARIABLE have a separate value in the current buffer.\n\
1259Other buffers will continue to share a common default value.\n\
a782f0d5
RS
1260\(The buffer-local value of VARIABLE starts out as the same value\n\
1261VARIABLE previously had. If VARIABLE was void, it remains void.\)\n\
7921925c
JB
1262See also `make-variable-buffer-local'.\n\n\
1263If the variable is already arranged to become local when set,\n\
1264this function causes a local value to exist for this buffer,\n\
62476adc
RS
1265just as setting the variable would do.\n\
1266\n\
1267Do not use `make-local-variable' to make a hook variable buffer-local.\n\
1268Use `make-local-hook' instead.")
d9c2a0f2
EN
1269 (variable)
1270 register Lisp_Object variable;
7921925c
JB
1271{
1272 register Lisp_Object tem, valcontents;
1273
d9c2a0f2 1274 CHECK_SYMBOL (variable, 0);
7921925c 1275
d9c2a0f2
EN
1276 valcontents = XSYMBOL (variable)->value;
1277 if (EQ (variable, Qnil) || EQ (variable, Qt) || KBOARD_OBJFWDP (valcontents))
1278 error ("Symbol %s may not be buffer-local", XSYMBOL (variable)->name->data);
7921925c 1279
e9ebc175 1280 if (BUFFER_LOCAL_VALUEP (valcontents) || BUFFER_OBJFWDP (valcontents))
7921925c 1281 {
d9c2a0f2 1282 tem = Fboundp (variable);
7403b5c8 1283
7921925c
JB
1284 /* Make sure the symbol has a local value in this particular buffer,
1285 by setting it to the same value it already has. */
d9c2a0f2
EN
1286 Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
1287 return variable;
7921925c 1288 }
d9c2a0f2 1289 /* Make sure symbol is set up to hold per-buffer values */
e9ebc175 1290 if (!SOME_BUFFER_LOCAL_VALUEP (valcontents))
7921925c 1291 {
8d4afcac 1292 Lisp_Object newval;
7921925c
JB
1293 tem = Fcons (Qnil, do_symval_forwarding (valcontents));
1294 XCONS (tem)->car = tem;
8d4afcac 1295 newval = allocate_misc ();
324a6eef 1296 XMISCTYPE (newval) = Lisp_Misc_Some_Buffer_Local_Value;
d9c2a0f2 1297 XBUFFER_LOCAL_VALUE (newval)->car = XSYMBOL (variable)->value;
8d4afcac 1298 XBUFFER_LOCAL_VALUE (newval)->cdr = Fcons (Qnil, tem);
d9c2a0f2 1299 XSYMBOL (variable)->value = newval;
7921925c 1300 }
d9c2a0f2
EN
1301 /* Make sure this buffer has its own value of symbol */
1302 tem = Fassq (variable, current_buffer->local_var_alist);
a33ef3ab 1303 if (NILP (tem))
7921925c 1304 {
a5d004a1
RS
1305 /* Swap out any local binding for some other buffer, and make
1306 sure the current value is permanently recorded, if it's the
1307 default value. */
d9c2a0f2 1308 find_symbol_value (variable);
a5d004a1 1309
7921925c 1310 current_buffer->local_var_alist
d9c2a0f2 1311 = Fcons (Fcons (variable, XCONS (XCONS (XBUFFER_LOCAL_VALUE (XSYMBOL (variable)->value)->cdr)->cdr)->cdr),
7921925c
JB
1312 current_buffer->local_var_alist);
1313
1314 /* Make sure symbol does not think it is set up for this buffer;
1315 force it to look once again for this buffer's value */
1316 {
8d4afcac 1317 Lisp_Object *pvalbuf;
a5d004a1 1318
d9c2a0f2 1319 valcontents = XSYMBOL (variable)->value;
a5d004a1 1320
8d4afcac
KH
1321 pvalbuf = &XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car;
1322 if (current_buffer == XBUFFER (*pvalbuf))
1323 *pvalbuf = Qnil;
7921925c 1324 }
7921925c 1325 }
a5ca2b75
JB
1326
1327 /* If the symbol forwards into a C variable, then swap in the
1328 variable for this buffer immediately. If C code modifies the
1329 variable before we swap in, then that new value will clobber the
1330 default value the next time we swap. */
d9c2a0f2 1331 valcontents = XBUFFER_LOCAL_VALUE (XSYMBOL (variable)->value)->car;
e9ebc175 1332 if (INTFWDP (valcontents) || BOOLFWDP (valcontents) || OBJFWDP (valcontents))
d9c2a0f2 1333 swap_in_symval_forwarding (variable, XSYMBOL (variable)->value);
a5ca2b75 1334
d9c2a0f2 1335 return variable;
7921925c
JB
1336}
1337
1338DEFUN ("kill-local-variable", Fkill_local_variable, Skill_local_variable,
1339 1, 1, "vKill Local Variable: ",
1340 "Make VARIABLE no longer have a separate value in the current buffer.\n\
1341From now on the default value will apply in this buffer.")
d9c2a0f2
EN
1342 (variable)
1343 register Lisp_Object variable;
7921925c
JB
1344{
1345 register Lisp_Object tem, valcontents;
1346
d9c2a0f2 1347 CHECK_SYMBOL (variable, 0);
7921925c 1348
d9c2a0f2 1349 valcontents = XSYMBOL (variable)->value;
7921925c 1350
e9ebc175 1351 if (BUFFER_OBJFWDP (valcontents))
7921925c 1352 {
46b2ac21 1353 register int idx = XBUFFER_OBJFWD (valcontents)->offset;
865c050f
KH
1354 register int mask = XINT (*((Lisp_Object*)
1355 (idx + (char *)&buffer_local_flags)));
7921925c
JB
1356
1357 if (mask > 0)
1358 {
1359 *(Lisp_Object *)(idx + (char *) current_buffer)
1360 = *(Lisp_Object *)(idx + (char *) &buffer_defaults);
1361 current_buffer->local_var_flags &= ~mask;
1362 }
d9c2a0f2 1363 return variable;
7921925c
JB
1364 }
1365
e9ebc175
KH
1366 if (!BUFFER_LOCAL_VALUEP (valcontents)
1367 && !SOME_BUFFER_LOCAL_VALUEP (valcontents))
d9c2a0f2 1368 return variable;
7921925c
JB
1369
1370 /* Get rid of this buffer's alist element, if any */
1371
d9c2a0f2 1372 tem = Fassq (variable, current_buffer->local_var_alist);
a33ef3ab 1373 if (!NILP (tem))
8d4afcac
KH
1374 current_buffer->local_var_alist
1375 = Fdelq (tem, current_buffer->local_var_alist);
7921925c 1376
79c83e03
KH
1377 /* If the symbol is set up for the current buffer, recompute its
1378 value. We have to do it now, or else forwarded objects won't
1379 work right. */
7921925c 1380 {
8d4afcac 1381 Lisp_Object *pvalbuf;
d9c2a0f2 1382 valcontents = XSYMBOL (variable)->value;
8d4afcac
KH
1383 pvalbuf = &XCONS (XBUFFER_LOCAL_VALUE (valcontents)->cdr)->car;
1384 if (current_buffer == XBUFFER (*pvalbuf))
79c83e03
KH
1385 {
1386 *pvalbuf = Qnil;
978dd578 1387 find_symbol_value (variable);
79c83e03 1388 }
7921925c
JB
1389 }
1390
d9c2a0f2 1391 return variable;
7921925c 1392}
62476adc
RS
1393
1394DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
c48ead86
KH
1395 1, 2, 0,
1396 "Non-nil if VARIABLE has a local binding in buffer BUFFER.\n\
1397BUFFER defaults to the current buffer.")
d9c2a0f2
EN
1398 (variable, buffer)
1399 register Lisp_Object variable, buffer;
62476adc
RS
1400{
1401 Lisp_Object valcontents;
c48ead86
KH
1402 register struct buffer *buf;
1403
1404 if (NILP (buffer))
1405 buf = current_buffer;
1406 else
1407 {
1408 CHECK_BUFFER (buffer, 0);
1409 buf = XBUFFER (buffer);
1410 }
62476adc 1411
d9c2a0f2 1412 CHECK_SYMBOL (variable, 0);
62476adc 1413
d9c2a0f2 1414 valcontents = XSYMBOL (variable)->value;
c48ead86 1415 if (BUFFER_LOCAL_VALUEP (valcontents)
1e5f16fa 1416 || SOME_BUFFER_LOCAL_VALUEP (valcontents))
c48ead86
KH
1417 {
1418 Lisp_Object tail, elt;
1419 for (tail = buf->local_var_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1420 {
1421 elt = XCONS (tail)->car;
d9c2a0f2 1422 if (EQ (variable, XCONS (elt)->car))
c48ead86
KH
1423 return Qt;
1424 }
1425 }
1426 if (BUFFER_OBJFWDP (valcontents))
1427 {
1428 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1429 int mask = XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_flags));
1430 if (mask == -1 || (buf->local_var_flags & mask))
1431 return Qt;
1432 }
1433 return Qnil;
62476adc 1434}
f4f04cee
RS
1435
1436DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p,
1437 1, 2, 0,
1438 "Non-nil if VARIABLE will be local in buffer BUFFER if it is set there.\n\
1439BUFFER defaults to the current buffer.")
d9c2a0f2
EN
1440 (variable, buffer)
1441 register Lisp_Object variable, buffer;
f4f04cee
RS
1442{
1443 Lisp_Object valcontents;
1444 register struct buffer *buf;
1445
1446 if (NILP (buffer))
1447 buf = current_buffer;
1448 else
1449 {
1450 CHECK_BUFFER (buffer, 0);
1451 buf = XBUFFER (buffer);
1452 }
1453
d9c2a0f2 1454 CHECK_SYMBOL (variable, 0);
f4f04cee 1455
d9c2a0f2 1456 valcontents = XSYMBOL (variable)->value;
f4f04cee
RS
1457
1458 /* This means that make-variable-buffer-local was done. */
1459 if (BUFFER_LOCAL_VALUEP (valcontents))
1460 return Qt;
1461 /* All these slots become local if they are set. */
1462 if (BUFFER_OBJFWDP (valcontents))
1463 return Qt;
1464 if (SOME_BUFFER_LOCAL_VALUEP (valcontents))
1465 {
1466 Lisp_Object tail, elt;
1467 for (tail = buf->local_var_alist; CONSP (tail); tail = XCONS (tail)->cdr)
1468 {
1469 elt = XCONS (tail)->car;
d9c2a0f2 1470 if (EQ (variable, XCONS (elt)->car))
f4f04cee
RS
1471 return Qt;
1472 }
1473 }
1474 return Qnil;
1475}
7921925c 1476\f
ffd56f97
JB
1477/* Find the function at the end of a chain of symbol function indirections. */
1478
1479/* If OBJECT is a symbol, find the end of its function chain and
1480 return the value found there. If OBJECT is not a symbol, just
1481 return it. If there is a cycle in the function chain, signal a
1482 cyclic-function-indirection error.
1483
1484 This is like Findirect_function, except that it doesn't signal an
1485 error if the chain ends up unbound. */
1486Lisp_Object
a2932990 1487indirect_function (object)
62476adc 1488 register Lisp_Object object;
ffd56f97 1489{
eb8c3be9 1490 Lisp_Object tortoise, hare;
ffd56f97 1491
eb8c3be9 1492 hare = tortoise = object;
ffd56f97
JB
1493
1494 for (;;)
1495 {
e9ebc175 1496 if (!SYMBOLP (hare) || EQ (hare, Qunbound))
ffd56f97
JB
1497 break;
1498 hare = XSYMBOL (hare)->function;
e9ebc175 1499 if (!SYMBOLP (hare) || EQ (hare, Qunbound))
ffd56f97
JB
1500 break;
1501 hare = XSYMBOL (hare)->function;
1502
eb8c3be9 1503 tortoise = XSYMBOL (tortoise)->function;
ffd56f97 1504
eb8c3be9 1505 if (EQ (hare, tortoise))
ffd56f97
JB
1506 Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
1507 }
1508
1509 return hare;
1510}
1511
1512DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0,
1513 "Return the function at the end of OBJECT's function chain.\n\
1514If OBJECT is a symbol, follow all function indirections and return the final\n\
1515function binding.\n\
1516If OBJECT is not a symbol, just return it.\n\
1517Signal a void-function error if the final symbol is unbound.\n\
1518Signal a cyclic-function-indirection error if there is a loop in the\n\
1519function chain of symbols.")
1520 (object)
1521 register Lisp_Object object;
1522{
1523 Lisp_Object result;
1524
1525 result = indirect_function (object);
1526
1527 if (EQ (result, Qunbound))
1528 return Fsignal (Qvoid_function, Fcons (object, Qnil));
1529 return result;
1530}
1531\f
7921925c
JB
1532/* Extract and set vector and string elements */
1533
1534DEFUN ("aref", Faref, Saref, 2, 2, 0,
d9c2a0f2 1535 "Return the element of ARRAY at index IDX.\n\
4d276982 1536ARRAY may be a vector, a string, a char-table, a bool-vector,\n\
d9c2a0f2 1537or a byte-code object. IDX starts at 0.")
7921925c
JB
1538 (array, idx)
1539 register Lisp_Object array;
1540 Lisp_Object idx;
1541{
1542 register int idxval;
1543
1544 CHECK_NUMBER (idx, 1);
1545 idxval = XINT (idx);
e9ebc175 1546 if (STRINGP (array))
7921925c
JB
1547 {
1548 Lisp_Object val;
25638b07
RS
1549 int c, idxval_byte;
1550
c24e4efe
KH
1551 if (idxval < 0 || idxval >= XSTRING (array)->size)
1552 args_out_of_range (array, idx);
25638b07
RS
1553 if (! STRING_MULTIBYTE (array))
1554 return make_number ((unsigned char) XSTRING (array)->data[idxval]);
1555 idxval_byte = string_char_to_byte (array, idxval);
1556
1557 c = STRING_CHAR (&XSTRING (array)->data[idxval_byte],
1558 XSTRING (array)->size_byte - idxval_byte);
1559 return make_number (c);
7921925c 1560 }
4d276982
RS
1561 else if (BOOL_VECTOR_P (array))
1562 {
1563 int val;
4d276982
RS
1564
1565 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
1566 args_out_of_range (array, idx);
1567
68be917d
KH
1568 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BITS_PER_CHAR];
1569 return (val & (1 << (idxval % BITS_PER_CHAR)) ? Qt : Qnil);
4d276982
RS
1570 }
1571 else if (CHAR_TABLE_P (array))
1572 {
1573 Lisp_Object val;
1574
1575 if (idxval < 0)
1576 args_out_of_range (array, idx);
3a6cf6bd 1577 if (idxval < CHAR_TABLE_SINGLE_BYTE_SLOTS)
8313c4e7 1578 {
39e16e51 1579 /* For ASCII and 8-bit European characters, the element is
3a6cf6bd 1580 stored in the top table. */
8313c4e7
KH
1581 val = XCHAR_TABLE (array)->contents[idxval];
1582 if (NILP (val))
1583 val = XCHAR_TABLE (array)->defalt;
1584 while (NILP (val)) /* Follow parents until we find some value. */
1585 {
1586 array = XCHAR_TABLE (array)->parent;
1587 if (NILP (array))
1588 return Qnil;
1589 val = XCHAR_TABLE (array)->contents[idxval];
1590 if (NILP (val))
1591 val = XCHAR_TABLE (array)->defalt;
1592 }
1593 return val;
1594 }
4d276982
RS
1595 else
1596 {
39e16e51
KH
1597 int code[4], i;
1598 Lisp_Object sub_table;
8313c4e7 1599
39e16e51
KH
1600 SPLIT_NON_ASCII_CHAR (idxval, code[0], code[1], code[2]);
1601 if (code[0] != CHARSET_COMPOSITION)
1602 {
1603 if (code[1] < 32) code[1] = -1;
1604 else if (code[2] < 32) code[2] = -1;
1605 }
1606 /* Here, the possible range of CODE[0] (== charset ID) is
1607 128..MAX_CHARSET. Since the top level char table contains
1608 data for multibyte characters after 256th element, we must
1609 increment CODE[0] by 128 to get a correct index. */
1610 code[0] += 128;
1611 code[3] = -1; /* anchor */
4d276982
RS
1612
1613 try_parent_char_table:
39e16e51
KH
1614 sub_table = array;
1615 for (i = 0; code[i] >= 0; i++)
4d276982 1616 {
39e16e51
KH
1617 val = XCHAR_TABLE (sub_table)->contents[code[i]];
1618 if (SUB_CHAR_TABLE_P (val))
1619 sub_table = val;
1620 else
8313c4e7 1621 {
39e16e51
KH
1622 if (NILP (val))
1623 val = XCHAR_TABLE (sub_table)->defalt;
1624 if (NILP (val))
1625 {
1626 array = XCHAR_TABLE (array)->parent;
1627 if (!NILP (array))
1628 goto try_parent_char_table;
1629 }
1630 return val;
8313c4e7 1631 }
4d276982 1632 }
39e16e51
KH
1633 /* Here, VAL is a sub char table. We try the default value
1634 and parent. */
1635 val = XCHAR_TABLE (val)->defalt;
8313c4e7 1636 if (NILP (val))
4d276982
RS
1637 {
1638 array = XCHAR_TABLE (array)->parent;
39e16e51
KH
1639 if (!NILP (array))
1640 goto try_parent_char_table;
4d276982 1641 }
4d276982
RS
1642 return val;
1643 }
4d276982 1644 }
7921925c 1645 else
c24e4efe 1646 {
7f358972
RS
1647 int size;
1648 if (VECTORP (array))
1649 size = XVECTOR (array)->size;
1650 else if (COMPILEDP (array))
1651 size = XVECTOR (array)->size & PSEUDOVECTOR_SIZE_MASK;
1652 else
1653 wrong_type_argument (Qarrayp, array);
1654
1655 if (idxval < 0 || idxval >= size)
c24e4efe
KH
1656 args_out_of_range (array, idx);
1657 return XVECTOR (array)->contents[idxval];
1658 }
7921925c
JB
1659}
1660
1661DEFUN ("aset", Faset, Saset, 3, 3, 0,
73d40355 1662 "Store into the element of ARRAY at index IDX the value NEWELT.\n\
9346f507
RS
1663ARRAY may be a vector, a string, a char-table or a bool-vector.\n\
1664IDX starts at 0.")
7921925c
JB
1665 (array, idx, newelt)
1666 register Lisp_Object array;
1667 Lisp_Object idx, newelt;
1668{
1669 register int idxval;
1670
1671 CHECK_NUMBER (idx, 1);
1672 idxval = XINT (idx);
4d276982
RS
1673 if (!VECTORP (array) && !STRINGP (array) && !BOOL_VECTOR_P (array)
1674 && ! CHAR_TABLE_P (array))
7921925c 1675 array = wrong_type_argument (Qarrayp, array);
7921925c
JB
1676 CHECK_IMPURE (array);
1677
e9ebc175 1678 if (VECTORP (array))
c24e4efe
KH
1679 {
1680 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1681 args_out_of_range (array, idx);
1682 XVECTOR (array)->contents[idxval] = newelt;
1683 }
4d276982
RS
1684 else if (BOOL_VECTOR_P (array))
1685 {
1686 int val;
4d276982
RS
1687
1688 if (idxval < 0 || idxval >= XBOOL_VECTOR (array)->size)
1689 args_out_of_range (array, idx);
1690
68be917d 1691 val = (unsigned char) XBOOL_VECTOR (array)->data[idxval / BITS_PER_CHAR];
4d276982
RS
1692
1693 if (! NILP (newelt))
68be917d 1694 val |= 1 << (idxval % BITS_PER_CHAR);
4d276982 1695 else
68be917d
KH
1696 val &= ~(1 << (idxval % BITS_PER_CHAR));
1697 XBOOL_VECTOR (array)->data[idxval / BITS_PER_CHAR] = val;
4d276982
RS
1698 }
1699 else if (CHAR_TABLE_P (array))
1700 {
1701 Lisp_Object val;
1702
1703 if (idxval < 0)
1704 args_out_of_range (array, idx);
3a6cf6bd 1705 if (idxval < CHAR_TABLE_SINGLE_BYTE_SLOTS)
8313c4e7 1706 XCHAR_TABLE (array)->contents[idxval] = newelt;
4d276982
RS
1707 else
1708 {
39e16e51 1709 int code[4], i;
8313c4e7 1710 Lisp_Object val;
4d276982 1711
39e16e51
KH
1712 SPLIT_NON_ASCII_CHAR (idxval, code[0], code[1], code[2]);
1713 if (code[0] != CHARSET_COMPOSITION)
1714 {
1715 if (code[1] < 32) code[1] = -1;
1716 else if (code[2] < 32) code[2] = -1;
1717 }
1718 /* See the comment of the corresponding part in Faref. */
1719 code[0] += 128;
1720 code[3] = -1; /* anchor */
1721 for (i = 0; code[i + 1] >= 0; i++)
8313c4e7 1722 {
39e16e51
KH
1723 val = XCHAR_TABLE (array)->contents[code[i]];
1724 if (SUB_CHAR_TABLE_P (val))
8313c4e7
KH
1725 array = val;
1726 else
3c8fccc3
RS
1727 {
1728 Lisp_Object temp;
1729
1730 /* VAL is a leaf. Create a sub char table with the
1731 default value VAL or XCHAR_TABLE (array)->defalt
1732 and look into it. */
1733
1734 temp = make_sub_char_table (NILP (val)
1735 ? XCHAR_TABLE (array)->defalt
1736 : val);
1737 XCHAR_TABLE (array)->contents[code[i]] = temp;
1738 array = temp;
1739 }
8313c4e7 1740 }
39e16e51 1741 XCHAR_TABLE (array)->contents[code[i]] = newelt;
4d276982 1742 }
4d276982 1743 }
25638b07
RS
1744 else if (STRING_MULTIBYTE (array))
1745 {
ca2f68f8 1746 Lisp_Object new_len;
25638b07 1747 int c, idxval_byte, actual_len;
ca2f68f8 1748 unsigned char *p, *str;
25638b07
RS
1749
1750 if (idxval < 0 || idxval >= XSTRING (array)->size)
1751 args_out_of_range (array, idx);
1752
1753 idxval_byte = string_char_to_byte (array, idxval);
ca2f68f8 1754 p = &XSTRING (array)->data[idxval_byte];
25638b07 1755
ca2f68f8
KH
1756 actual_len
1757 = MULTIBYTE_FORM_LENGTH (p, XSTRING (array)->size_byte - idxval_byte);
1758 new_len = Fchar_bytes (newelt);
1759 if (actual_len != XINT (new_len))
1760 error ("Attempt to change byte length of a string");
25638b07 1761
ca2f68f8
KH
1762 CHAR_STRING (XINT (newelt), p, str);
1763 if (p != str)
1764 bcopy (str, p, actual_len);
25638b07 1765 }
7921925c
JB
1766 else
1767 {
c24e4efe
KH
1768 if (idxval < 0 || idxval >= XSTRING (array)->size)
1769 args_out_of_range (array, idx);
7921925c
JB
1770 CHECK_NUMBER (newelt, 2);
1771 XSTRING (array)->data[idxval] = XINT (newelt);
1772 }
1773
1774 return newelt;
1775}
7921925c
JB
1776\f
1777/* Arithmetic functions */
1778
1779enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
1780
1781Lisp_Object
1782arithcompare (num1, num2, comparison)
1783 Lisp_Object num1, num2;
1784 enum comparison comparison;
1785{
1786 double f1, f2;
1787 int floatp = 0;
1788
1789#ifdef LISP_FLOAT_TYPE
1790 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1791 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
1792
e9ebc175 1793 if (FLOATP (num1) || FLOATP (num2))
7921925c
JB
1794 {
1795 floatp = 1;
e9ebc175
KH
1796 f1 = (FLOATP (num1)) ? XFLOAT (num1)->data : XINT (num1);
1797 f2 = (FLOATP (num2)) ? XFLOAT (num2)->data : XINT (num2);
7921925c
JB
1798 }
1799#else
1800 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1801 CHECK_NUMBER_COERCE_MARKER (num2, 0);
1802#endif /* LISP_FLOAT_TYPE */
1803
1804 switch (comparison)
1805 {
1806 case equal:
1807 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
1808 return Qt;
1809 return Qnil;
1810
1811 case notequal:
1812 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
1813 return Qt;
1814 return Qnil;
1815
1816 case less:
1817 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
1818 return Qt;
1819 return Qnil;
1820
1821 case less_or_equal:
1822 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
1823 return Qt;
1824 return Qnil;
1825
1826 case grtr:
1827 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
1828 return Qt;
1829 return Qnil;
1830
1831 case grtr_or_equal:
1832 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
1833 return Qt;
1834 return Qnil;
25e40a4b
JB
1835
1836 default:
1837 abort ();
7921925c
JB
1838 }
1839}
1840
1841DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0,
c2124165 1842 "Return t if two args, both numbers or markers, are equal.")
7921925c
JB
1843 (num1, num2)
1844 register Lisp_Object num1, num2;
1845{
1846 return arithcompare (num1, num2, equal);
1847}
1848
1849DEFUN ("<", Flss, Slss, 2, 2, 0,
c2124165 1850 "Return t if first arg is less than second arg. Both must be numbers or markers.")
7921925c
JB
1851 (num1, num2)
1852 register Lisp_Object num1, num2;
1853{
1854 return arithcompare (num1, num2, less);
1855}
1856
1857DEFUN (">", Fgtr, Sgtr, 2, 2, 0,
c2124165 1858 "Return t if first arg is greater than second arg. Both must be numbers or markers.")
7921925c
JB
1859 (num1, num2)
1860 register Lisp_Object num1, num2;
1861{
1862 return arithcompare (num1, num2, grtr);
1863}
1864
1865DEFUN ("<=", Fleq, Sleq, 2, 2, 0,
c2124165 1866 "Return t if first arg is less than or equal to second arg.\n\
7921925c
JB
1867Both must be numbers or markers.")
1868 (num1, num2)
1869 register Lisp_Object num1, num2;
1870{
1871 return arithcompare (num1, num2, less_or_equal);
1872}
1873
1874DEFUN (">=", Fgeq, Sgeq, 2, 2, 0,
c2124165 1875 "Return t if first arg is greater than or equal to second arg.\n\
7921925c
JB
1876Both must be numbers or markers.")
1877 (num1, num2)
1878 register Lisp_Object num1, num2;
1879{
1880 return arithcompare (num1, num2, grtr_or_equal);
1881}
1882
1883DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
c2124165 1884 "Return t if first arg is not equal to second arg. Both must be numbers or markers.")
7921925c
JB
1885 (num1, num2)
1886 register Lisp_Object num1, num2;
1887{
1888 return arithcompare (num1, num2, notequal);
1889}
1890
c2124165 1891DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, "Return t if NUMBER is zero.")
d9c2a0f2
EN
1892 (number)
1893 register Lisp_Object number;
7921925c
JB
1894{
1895#ifdef LISP_FLOAT_TYPE
d9c2a0f2 1896 CHECK_NUMBER_OR_FLOAT (number, 0);
7921925c 1897
d9c2a0f2 1898 if (FLOATP (number))
7921925c 1899 {
d9c2a0f2 1900 if (XFLOAT(number)->data == 0.0)
7921925c
JB
1901 return Qt;
1902 return Qnil;
1903 }
1904#else
d9c2a0f2 1905 CHECK_NUMBER (number, 0);
7921925c
JB
1906#endif /* LISP_FLOAT_TYPE */
1907
d9c2a0f2 1908 if (!XINT (number))
7921925c
JB
1909 return Qt;
1910 return Qnil;
1911}
1912\f
34f4f6c6 1913/* Convert between long values and pairs of Lisp integers. */
51cf3e31
JB
1914
1915Lisp_Object
1916long_to_cons (i)
1917 unsigned long i;
1918{
1919 unsigned int top = i >> 16;
1920 unsigned int bot = i & 0xFFFF;
1921 if (top == 0)
1922 return make_number (bot);
b42cfa11 1923 if (top == (unsigned long)-1 >> 16)
51cf3e31
JB
1924 return Fcons (make_number (-1), make_number (bot));
1925 return Fcons (make_number (top), make_number (bot));
1926}
1927
1928unsigned long
1929cons_to_long (c)
1930 Lisp_Object c;
1931{
878a80cc 1932 Lisp_Object top, bot;
51cf3e31
JB
1933 if (INTEGERP (c))
1934 return XINT (c);
1935 top = XCONS (c)->car;
1936 bot = XCONS (c)->cdr;
1937 if (CONSP (bot))
1938 bot = XCONS (bot)->car;
1939 return ((XINT (top) << 16) | XINT (bot));
1940}
1941\f
f2980264 1942DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
d9c2a0f2 1943 "Convert NUMBER to a string by printing it in decimal.\n\
25e40a4b 1944Uses a minus sign if negative.\n\
d9c2a0f2
EN
1945NUMBER may be an integer or a floating point number.")
1946 (number)
1947 Lisp_Object number;
7921925c 1948{
6030ce64 1949 char buffer[VALBITS];
7921925c
JB
1950
1951#ifndef LISP_FLOAT_TYPE
d9c2a0f2 1952 CHECK_NUMBER (number, 0);
7921925c 1953#else
d9c2a0f2 1954 CHECK_NUMBER_OR_FLOAT (number, 0);
7921925c 1955
d9c2a0f2 1956 if (FLOATP (number))
7921925c
JB
1957 {
1958 char pigbuf[350]; /* see comments in float_to_string */
1959
d9c2a0f2 1960 float_to_string (pigbuf, XFLOAT(number)->data);
7403b5c8 1961 return build_string (pigbuf);
7921925c
JB
1962 }
1963#endif /* LISP_FLOAT_TYPE */
1964
e6c82a8d 1965 if (sizeof (int) == sizeof (EMACS_INT))
d9c2a0f2 1966 sprintf (buffer, "%d", XINT (number));
e6c82a8d 1967 else if (sizeof (long) == sizeof (EMACS_INT))
d9c2a0f2 1968 sprintf (buffer, "%ld", XINT (number));
e6c82a8d
RS
1969 else
1970 abort ();
7921925c
JB
1971 return build_string (buffer);
1972}
1973
3883fbeb
RS
1974INLINE static int
1975digit_to_number (character, base)
1976 int character, base;
1977{
1978 int digit;
1979
1980 if (character >= '0' && character <= '9')
1981 digit = character - '0';
1982 else if (character >= 'a' && character <= 'z')
1983 digit = character - 'a' + 10;
1984 else if (character >= 'A' && character <= 'Z')
1985 digit = character - 'A' + 10;
1986 else
1987 return -1;
1988
1989 if (digit >= base)
1990 return -1;
1991 else
1992 return digit;
1993}
1994
1995DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,
25e40a4b 1996 "Convert STRING to a number by parsing it as a decimal number.\n\
1c1c17eb 1997This parses both integers and floating point numbers.\n\
3883fbeb
RS
1998It ignores leading spaces and tabs.\n\
1999\n\
2000If BASE, interpret STRING as a number in that base. If BASE isn't\n\
2001present, base 10 is used. BASE must be between 2 and 16 (inclusive).\n\
2002Floating point numbers always use base 10.")
2003 (string, base)
2004 register Lisp_Object string, base;
7921925c 2005{
3883fbeb
RS
2006 register unsigned char *p;
2007 register int b, digit, v = 0;
2008 int negative = 1;
25e40a4b 2009
d9c2a0f2 2010 CHECK_STRING (string, 0);
7921925c 2011
3883fbeb
RS
2012 if (NILP (base))
2013 b = 10;
2014 else
2015 {
2016 CHECK_NUMBER (base, 1);
2017 b = XINT (base);
2018 if (b < 2 || b > 16)
2019 Fsignal (Qargs_out_of_range, Fcons (base, Qnil));
2020 }
2021
d9c2a0f2 2022 p = XSTRING (string)->data;
25e40a4b
JB
2023
2024 /* Skip any whitespace at the front of the number. Some versions of
2025 atoi do this anyway, so we might as well make Emacs lisp consistent. */
0a3e4d65 2026 while (*p == ' ' || *p == '\t')
25e40a4b
JB
2027 p++;
2028
3883fbeb
RS
2029 if (*p == '-')
2030 {
2031 negative = -1;
2032 p++;
2033 }
2034 else if (*p == '+')
2035 p++;
2036
7921925c 2037#ifdef LISP_FLOAT_TYPE
25e40a4b 2038 if (isfloat_string (p))
142d9135 2039 return make_float (negative * atof (p));
7921925c
JB
2040#endif /* LISP_FLOAT_TYPE */
2041
3883fbeb
RS
2042 while (1)
2043 {
2044 int digit = digit_to_number (*p++, b);
2045 if (digit < 0)
2046 break;
2047 v = v * b + digit;
2048 }
2049
2050 return make_number (negative * v);
7921925c 2051}
3883fbeb 2052
7403b5c8 2053\f
7921925c
JB
2054enum arithop
2055 { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin };
2056
b06faa91 2057extern Lisp_Object float_arith_driver ();
ad8d56b9 2058extern Lisp_Object fmod_float ();
b06faa91 2059
7921925c 2060Lisp_Object
87fbf902 2061arith_driver (code, nargs, args)
7921925c
JB
2062 enum arithop code;
2063 int nargs;
2064 register Lisp_Object *args;
2065{
2066 register Lisp_Object val;
2067 register int argnum;
5260234d
RS
2068 register EMACS_INT accum;
2069 register EMACS_INT next;
7921925c 2070
0220c518 2071 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2072 {
2073 case Alogior:
2074 case Alogxor:
2075 case Aadd:
2076 case Asub:
2077 accum = 0; break;
2078 case Amult:
2079 accum = 1; break;
2080 case Alogand:
2081 accum = -1; break;
2082 }
2083
2084 for (argnum = 0; argnum < nargs; argnum++)
2085 {
2086 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
2087#ifdef LISP_FLOAT_TYPE
2088 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
2089
e9ebc175 2090 if (FLOATP (val)) /* time to do serious math */
7921925c
JB
2091 return (float_arith_driver ((double) accum, argnum, code,
2092 nargs, args));
2093#else
2094 CHECK_NUMBER_COERCE_MARKER (val, argnum);
2095#endif /* LISP_FLOAT_TYPE */
2096 args[argnum] = val; /* runs into a compiler bug. */
2097 next = XINT (args[argnum]);
0220c518 2098 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2099 {
2100 case Aadd: accum += next; break;
2101 case Asub:
2102 if (!argnum && nargs != 1)
2103 next = - next;
2104 accum -= next;
2105 break;
2106 case Amult: accum *= next; break;
2107 case Adiv:
2108 if (!argnum) accum = next;
87fbf902
RS
2109 else
2110 {
2111 if (next == 0)
2112 Fsignal (Qarith_error, Qnil);
2113 accum /= next;
2114 }
7921925c
JB
2115 break;
2116 case Alogand: accum &= next; break;
2117 case Alogior: accum |= next; break;
2118 case Alogxor: accum ^= next; break;
2119 case Amax: if (!argnum || next > accum) accum = next; break;
2120 case Amin: if (!argnum || next < accum) accum = next; break;
2121 }
2122 }
2123
f187f1f7 2124 XSETINT (val, accum);
7921925c
JB
2125 return val;
2126}
2127
1a2f2d33
KH
2128#undef isnan
2129#define isnan(x) ((x) != (x))
2130
bc1c9d7e
PE
2131#ifdef LISP_FLOAT_TYPE
2132
7921925c
JB
2133Lisp_Object
2134float_arith_driver (accum, argnum, code, nargs, args)
2135 double accum;
2136 register int argnum;
2137 enum arithop code;
2138 int nargs;
2139 register Lisp_Object *args;
2140{
2141 register Lisp_Object val;
2142 double next;
7403b5c8 2143
7921925c
JB
2144 for (; argnum < nargs; argnum++)
2145 {
2146 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
2147 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
2148
e9ebc175 2149 if (FLOATP (val))
7921925c
JB
2150 {
2151 next = XFLOAT (val)->data;
2152 }
2153 else
2154 {
2155 args[argnum] = val; /* runs into a compiler bug. */
2156 next = XINT (args[argnum]);
2157 }
0220c518 2158 switch (SWITCH_ENUM_CAST (code))
7921925c
JB
2159 {
2160 case Aadd:
2161 accum += next;
2162 break;
2163 case Asub:
2164 if (!argnum && nargs != 1)
2165 next = - next;
2166 accum -= next;
2167 break;
2168 case Amult:
2169 accum *= next;
2170 break;
2171 case Adiv:
2172 if (!argnum)
2173 accum = next;
2174 else
87fbf902 2175 {
ad8d56b9 2176 if (! IEEE_FLOATING_POINT && next == 0)
87fbf902
RS
2177 Fsignal (Qarith_error, Qnil);
2178 accum /= next;
2179 }
7921925c
JB
2180 break;
2181 case Alogand:
2182 case Alogior:
2183 case Alogxor:
2184 return wrong_type_argument (Qinteger_or_marker_p, val);
2185 case Amax:
1a2f2d33 2186 if (!argnum || isnan (next) || next > accum)
7921925c
JB
2187 accum = next;
2188 break;
2189 case Amin:
1a2f2d33 2190 if (!argnum || isnan (next) || next < accum)
7921925c
JB
2191 accum = next;
2192 break;
2193 }
2194 }
2195
2196 return make_float (accum);
2197}
2198#endif /* LISP_FLOAT_TYPE */
2199
2200DEFUN ("+", Fplus, Splus, 0, MANY, 0,
2201 "Return sum of any number of arguments, which are numbers or markers.")
2202 (nargs, args)
2203 int nargs;
2204 Lisp_Object *args;
2205{
2206 return arith_driver (Aadd, nargs, args);
2207}
2208
2209DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
2210 "Negate number or subtract numbers or markers.\n\
2211With one arg, negates it. With more than one arg,\n\
2212subtracts all but the first from the first.")
2213 (nargs, args)
2214 int nargs;
2215 Lisp_Object *args;
2216{
2217 return arith_driver (Asub, nargs, args);
2218}
2219
2220DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
2221 "Returns product of any number of arguments, which are numbers or markers.")
2222 (nargs, args)
2223 int nargs;
2224 Lisp_Object *args;
2225{
2226 return arith_driver (Amult, nargs, args);
2227}
2228
2229DEFUN ("/", Fquo, Squo, 2, MANY, 0,
2230 "Returns first argument divided by all the remaining arguments.\n\
2231The arguments must be numbers or markers.")
2232 (nargs, args)
2233 int nargs;
2234 Lisp_Object *args;
2235{
2236 return arith_driver (Adiv, nargs, args);
2237}
2238
2239DEFUN ("%", Frem, Srem, 2, 2, 0,
d9c2a0f2 2240 "Returns remainder of X divided by Y.\n\
aa29f9b9 2241Both must be integers or markers.")
d9c2a0f2
EN
2242 (x, y)
2243 register Lisp_Object x, y;
7921925c
JB
2244{
2245 Lisp_Object val;
2246
d9c2a0f2
EN
2247 CHECK_NUMBER_COERCE_MARKER (x, 0);
2248 CHECK_NUMBER_COERCE_MARKER (y, 1);
7921925c 2249
d9c2a0f2 2250 if (XFASTINT (y) == 0)
87fbf902
RS
2251 Fsignal (Qarith_error, Qnil);
2252
d9c2a0f2 2253 XSETINT (val, XINT (x) % XINT (y));
7921925c
JB
2254 return val;
2255}
2256
1d66a5fa
KH
2257#ifndef HAVE_FMOD
2258double
2259fmod (f1, f2)
2260 double f1, f2;
2261{
bc1c9d7e
PE
2262 double r = f1;
2263
fa43b1e8
KH
2264 if (f2 < 0.0)
2265 f2 = -f2;
bc1c9d7e
PE
2266
2267 /* If the magnitude of the result exceeds that of the divisor, or
2268 the sign of the result does not agree with that of the dividend,
2269 iterate with the reduced value. This does not yield a
2270 particularly accurate result, but at least it will be in the
2271 range promised by fmod. */
2272 do
2273 r -= f2 * floor (r / f2);
2274 while (f2 <= (r < 0 ? -r : r) || ((r < 0) != (f1 < 0) && ! isnan (r)));
2275
2276 return r;
1d66a5fa
KH
2277}
2278#endif /* ! HAVE_FMOD */
2279
44fa9da5
PE
2280DEFUN ("mod", Fmod, Smod, 2, 2, 0,
2281 "Returns X modulo Y.\n\
2282The result falls between zero (inclusive) and Y (exclusive).\n\
2283Both X and Y must be numbers or markers.")
d9c2a0f2
EN
2284 (x, y)
2285 register Lisp_Object x, y;
44fa9da5
PE
2286{
2287 Lisp_Object val;
5260234d 2288 EMACS_INT i1, i2;
44fa9da5
PE
2289
2290#ifdef LISP_FLOAT_TYPE
d9c2a0f2
EN
2291 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (x, 0);
2292 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (y, 1);
44fa9da5 2293
d9c2a0f2 2294 if (FLOATP (x) || FLOATP (y))
ad8d56b9
PE
2295 return fmod_float (x, y);
2296
44fa9da5 2297#else /* not LISP_FLOAT_TYPE */
d9c2a0f2
EN
2298 CHECK_NUMBER_COERCE_MARKER (x, 0);
2299 CHECK_NUMBER_COERCE_MARKER (y, 1);
44fa9da5
PE
2300#endif /* not LISP_FLOAT_TYPE */
2301
d9c2a0f2
EN
2302 i1 = XINT (x);
2303 i2 = XINT (y);
44fa9da5
PE
2304
2305 if (i2 == 0)
2306 Fsignal (Qarith_error, Qnil);
7403b5c8 2307
44fa9da5
PE
2308 i1 %= i2;
2309
2310 /* If the "remainder" comes out with the wrong sign, fix it. */
04f7ec69 2311 if (i2 < 0 ? i1 > 0 : i1 < 0)
44fa9da5
PE
2312 i1 += i2;
2313
f187f1f7 2314 XSETINT (val, i1);
44fa9da5
PE
2315 return val;
2316}
2317
7921925c
JB
2318DEFUN ("max", Fmax, Smax, 1, MANY, 0,
2319 "Return largest of all the arguments (which must be numbers or markers).\n\
2320The value is always a number; markers are converted to numbers.")
2321 (nargs, args)
2322 int nargs;
2323 Lisp_Object *args;
2324{
2325 return arith_driver (Amax, nargs, args);
2326}
2327
2328DEFUN ("min", Fmin, Smin, 1, MANY, 0,
2329 "Return smallest of all the arguments (which must be numbers or markers).\n\
2330The value is always a number; markers are converted to numbers.")
2331 (nargs, args)
2332 int nargs;
2333 Lisp_Object *args;
2334{
2335 return arith_driver (Amin, nargs, args);
2336}
2337
2338DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
2339 "Return bitwise-and of all the arguments.\n\
2340Arguments may be integers, or markers converted to integers.")
2341 (nargs, args)
2342 int nargs;
2343 Lisp_Object *args;
2344{
2345 return arith_driver (Alogand, nargs, args);
2346}
2347
2348DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
2349 "Return bitwise-or of all the arguments.\n\
2350Arguments may be integers, or markers converted to integers.")
2351 (nargs, args)
2352 int nargs;
2353 Lisp_Object *args;
2354{
2355 return arith_driver (Alogior, nargs, args);
2356}
2357
2358DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
2359 "Return bitwise-exclusive-or of all the arguments.\n\
2360Arguments may be integers, or markers converted to integers.")
2361 (nargs, args)
2362 int nargs;
2363 Lisp_Object *args;
2364{
2365 return arith_driver (Alogxor, nargs, args);
2366}
2367
2368DEFUN ("ash", Fash, Sash, 2, 2, 0,
2369 "Return VALUE with its bits shifted left by COUNT.\n\
2370If COUNT is negative, shifting is actually to the right.\n\
2371In this case, the sign bit is duplicated.")
3b9f7964
RS
2372 (value, count)
2373 register Lisp_Object value, count;
7921925c
JB
2374{
2375 register Lisp_Object val;
2376
3d9652eb
RS
2377 CHECK_NUMBER (value, 0);
2378 CHECK_NUMBER (count, 1);
7921925c 2379
3d9652eb
RS
2380 if (XINT (count) > 0)
2381 XSETINT (val, XINT (value) << XFASTINT (count));
7921925c 2382 else
3d9652eb 2383 XSETINT (val, XINT (value) >> -XINT (count));
7921925c
JB
2384 return val;
2385}
2386
2387DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
2388 "Return VALUE with its bits shifted left by COUNT.\n\
2389If COUNT is negative, shifting is actually to the right.\n\
2390In this case, zeros are shifted in on the left.")
3d9652eb
RS
2391 (value, count)
2392 register Lisp_Object value, count;
7921925c
JB
2393{
2394 register Lisp_Object val;
2395
3d9652eb
RS
2396 CHECK_NUMBER (value, 0);
2397 CHECK_NUMBER (count, 1);
7921925c 2398
3d9652eb
RS
2399 if (XINT (count) > 0)
2400 XSETINT (val, (EMACS_UINT) XUINT (value) << XFASTINT (count));
7921925c 2401 else
3d9652eb 2402 XSETINT (val, (EMACS_UINT) XUINT (value) >> -XINT (count));
7921925c
JB
2403 return val;
2404}
2405
2406DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
2407 "Return NUMBER plus one. NUMBER may be a number or a marker.\n\
2408Markers are converted to integers.")
d9c2a0f2
EN
2409 (number)
2410 register Lisp_Object number;
7921925c
JB
2411{
2412#ifdef LISP_FLOAT_TYPE
d9c2a0f2 2413 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number, 0);
7921925c 2414
d9c2a0f2
EN
2415 if (FLOATP (number))
2416 return (make_float (1.0 + XFLOAT (number)->data));
7921925c 2417#else
d9c2a0f2 2418 CHECK_NUMBER_COERCE_MARKER (number, 0);
7921925c
JB
2419#endif /* LISP_FLOAT_TYPE */
2420
d9c2a0f2
EN
2421 XSETINT (number, XINT (number) + 1);
2422 return number;
7921925c
JB
2423}
2424
2425DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
2426 "Return NUMBER minus one. NUMBER may be a number or a marker.\n\
2427Markers are converted to integers.")
d9c2a0f2
EN
2428 (number)
2429 register Lisp_Object number;
7921925c
JB
2430{
2431#ifdef LISP_FLOAT_TYPE
d9c2a0f2 2432 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number, 0);
7921925c 2433
d9c2a0f2
EN
2434 if (FLOATP (number))
2435 return (make_float (-1.0 + XFLOAT (number)->data));
7921925c 2436#else
d9c2a0f2 2437 CHECK_NUMBER_COERCE_MARKER (number, 0);
7921925c
JB
2438#endif /* LISP_FLOAT_TYPE */
2439
d9c2a0f2
EN
2440 XSETINT (number, XINT (number) - 1);
2441 return number;
7921925c
JB
2442}
2443
2444DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
d9c2a0f2
EN
2445 "Return the bitwise complement of NUMBER. NUMBER must be an integer.")
2446 (number)
2447 register Lisp_Object number;
7921925c 2448{
d9c2a0f2 2449 CHECK_NUMBER (number, 0);
53924017 2450 XSETINT (number, ~XINT (number));
d9c2a0f2 2451 return number;
7921925c
JB
2452}
2453\f
2454void
2455syms_of_data ()
2456{
6315e761
RS
2457 Lisp_Object error_tail, arith_tail;
2458
7921925c
JB
2459 Qquote = intern ("quote");
2460 Qlambda = intern ("lambda");
2461 Qsubr = intern ("subr");
2462 Qerror_conditions = intern ("error-conditions");
2463 Qerror_message = intern ("error-message");
2464 Qtop_level = intern ("top-level");
2465
2466 Qerror = intern ("error");
2467 Qquit = intern ("quit");
2468 Qwrong_type_argument = intern ("wrong-type-argument");
2469 Qargs_out_of_range = intern ("args-out-of-range");
2470 Qvoid_function = intern ("void-function");
ffd56f97 2471 Qcyclic_function_indirection = intern ("cyclic-function-indirection");
7921925c
JB
2472 Qvoid_variable = intern ("void-variable");
2473 Qsetting_constant = intern ("setting-constant");
2474 Qinvalid_read_syntax = intern ("invalid-read-syntax");
2475
2476 Qinvalid_function = intern ("invalid-function");
2477 Qwrong_number_of_arguments = intern ("wrong-number-of-arguments");
2478 Qno_catch = intern ("no-catch");
2479 Qend_of_file = intern ("end-of-file");
2480 Qarith_error = intern ("arith-error");
2481 Qbeginning_of_buffer = intern ("beginning-of-buffer");
2482 Qend_of_buffer = intern ("end-of-buffer");
2483 Qbuffer_read_only = intern ("buffer-read-only");
3b8819d6 2484 Qmark_inactive = intern ("mark-inactive");
7921925c
JB
2485
2486 Qlistp = intern ("listp");
2487 Qconsp = intern ("consp");
2488 Qsymbolp = intern ("symbolp");
2489 Qintegerp = intern ("integerp");
2490 Qnatnump = intern ("natnump");
8e86942b 2491 Qwholenump = intern ("wholenump");
7921925c
JB
2492 Qstringp = intern ("stringp");
2493 Qarrayp = intern ("arrayp");
2494 Qsequencep = intern ("sequencep");
2495 Qbufferp = intern ("bufferp");
2496 Qvectorp = intern ("vectorp");
2497 Qchar_or_string_p = intern ("char-or-string-p");
2498 Qmarkerp = intern ("markerp");
07bd8472 2499 Qbuffer_or_string_p = intern ("buffer-or-string-p");
7921925c
JB
2500 Qinteger_or_marker_p = intern ("integer-or-marker-p");
2501 Qboundp = intern ("boundp");
2502 Qfboundp = intern ("fboundp");
2503
2504#ifdef LISP_FLOAT_TYPE
2505 Qfloatp = intern ("floatp");
2506 Qnumberp = intern ("numberp");
2507 Qnumber_or_marker_p = intern ("number-or-marker-p");
2508#endif /* LISP_FLOAT_TYPE */
2509
4d276982 2510 Qchar_table_p = intern ("char-table-p");
7f0edce7 2511 Qvector_or_char_table_p = intern ("vector-or-char-table-p");
4d276982 2512
7921925c
JB
2513 Qcdr = intern ("cdr");
2514
f845f2c9 2515 /* Handle automatic advice activation */
ab297811
RS
2516 Qad_advice_info = intern ("ad-advice-info");
2517 Qad_activate = intern ("ad-activate");
f845f2c9 2518
6315e761
RS
2519 error_tail = Fcons (Qerror, Qnil);
2520
7921925c
JB
2521 /* ERROR is used as a signaler for random errors for which nothing else is right */
2522
2523 Fput (Qerror, Qerror_conditions,
6315e761 2524 error_tail);
7921925c
JB
2525 Fput (Qerror, Qerror_message,
2526 build_string ("error"));
2527
2528 Fput (Qquit, Qerror_conditions,
2529 Fcons (Qquit, Qnil));
2530 Fput (Qquit, Qerror_message,
2531 build_string ("Quit"));
2532
2533 Fput (Qwrong_type_argument, Qerror_conditions,
6315e761 2534 Fcons (Qwrong_type_argument, error_tail));
7921925c
JB
2535 Fput (Qwrong_type_argument, Qerror_message,
2536 build_string ("Wrong type argument"));
2537
2538 Fput (Qargs_out_of_range, Qerror_conditions,
6315e761 2539 Fcons (Qargs_out_of_range, error_tail));
7921925c
JB
2540 Fput (Qargs_out_of_range, Qerror_message,
2541 build_string ("Args out of range"));
2542
2543 Fput (Qvoid_function, Qerror_conditions,
6315e761 2544 Fcons (Qvoid_function, error_tail));
7921925c
JB
2545 Fput (Qvoid_function, Qerror_message,
2546 build_string ("Symbol's function definition is void"));
2547
ffd56f97 2548 Fput (Qcyclic_function_indirection, Qerror_conditions,
6315e761 2549 Fcons (Qcyclic_function_indirection, error_tail));
ffd56f97
JB
2550 Fput (Qcyclic_function_indirection, Qerror_message,
2551 build_string ("Symbol's chain of function indirections contains a loop"));
2552
7921925c 2553 Fput (Qvoid_variable, Qerror_conditions,
6315e761 2554 Fcons (Qvoid_variable, error_tail));
7921925c
JB
2555 Fput (Qvoid_variable, Qerror_message,
2556 build_string ("Symbol's value as variable is void"));
2557
2558 Fput (Qsetting_constant, Qerror_conditions,
6315e761 2559 Fcons (Qsetting_constant, error_tail));
7921925c
JB
2560 Fput (Qsetting_constant, Qerror_message,
2561 build_string ("Attempt to set a constant symbol"));
2562
2563 Fput (Qinvalid_read_syntax, Qerror_conditions,
6315e761 2564 Fcons (Qinvalid_read_syntax, error_tail));
7921925c
JB
2565 Fput (Qinvalid_read_syntax, Qerror_message,
2566 build_string ("Invalid read syntax"));
2567
2568 Fput (Qinvalid_function, Qerror_conditions,
6315e761 2569 Fcons (Qinvalid_function, error_tail));
7921925c
JB
2570 Fput (Qinvalid_function, Qerror_message,
2571 build_string ("Invalid function"));
2572
2573 Fput (Qwrong_number_of_arguments, Qerror_conditions,
6315e761 2574 Fcons (Qwrong_number_of_arguments, error_tail));
7921925c
JB
2575 Fput (Qwrong_number_of_arguments, Qerror_message,
2576 build_string ("Wrong number of arguments"));
2577
2578 Fput (Qno_catch, Qerror_conditions,
6315e761 2579 Fcons (Qno_catch, error_tail));
7921925c
JB
2580 Fput (Qno_catch, Qerror_message,
2581 build_string ("No catch for tag"));
2582
2583 Fput (Qend_of_file, Qerror_conditions,
6315e761 2584 Fcons (Qend_of_file, error_tail));
7921925c
JB
2585 Fput (Qend_of_file, Qerror_message,
2586 build_string ("End of file during parsing"));
2587
6315e761 2588 arith_tail = Fcons (Qarith_error, error_tail);
7921925c 2589 Fput (Qarith_error, Qerror_conditions,
6315e761 2590 arith_tail);
7921925c
JB
2591 Fput (Qarith_error, Qerror_message,
2592 build_string ("Arithmetic error"));
2593
2594 Fput (Qbeginning_of_buffer, Qerror_conditions,
6315e761 2595 Fcons (Qbeginning_of_buffer, error_tail));
7921925c
JB
2596 Fput (Qbeginning_of_buffer, Qerror_message,
2597 build_string ("Beginning of buffer"));
2598
2599 Fput (Qend_of_buffer, Qerror_conditions,
6315e761 2600 Fcons (Qend_of_buffer, error_tail));
7921925c
JB
2601 Fput (Qend_of_buffer, Qerror_message,
2602 build_string ("End of buffer"));
2603
2604 Fput (Qbuffer_read_only, Qerror_conditions,
6315e761 2605 Fcons (Qbuffer_read_only, error_tail));
7921925c
JB
2606 Fput (Qbuffer_read_only, Qerror_message,
2607 build_string ("Buffer is read-only"));
2608
6315e761
RS
2609#ifdef LISP_FLOAT_TYPE
2610 Qrange_error = intern ("range-error");
2611 Qdomain_error = intern ("domain-error");
2612 Qsingularity_error = intern ("singularity-error");
2613 Qoverflow_error = intern ("overflow-error");
2614 Qunderflow_error = intern ("underflow-error");
2615
2616 Fput (Qdomain_error, Qerror_conditions,
2617 Fcons (Qdomain_error, arith_tail));
2618 Fput (Qdomain_error, Qerror_message,
2619 build_string ("Arithmetic domain error"));
2620
2621 Fput (Qrange_error, Qerror_conditions,
2622 Fcons (Qrange_error, arith_tail));
2623 Fput (Qrange_error, Qerror_message,
2624 build_string ("Arithmetic range error"));
2625
2626 Fput (Qsingularity_error, Qerror_conditions,
2627 Fcons (Qsingularity_error, Fcons (Qdomain_error, arith_tail)));
2628 Fput (Qsingularity_error, Qerror_message,
2629 build_string ("Arithmetic singularity error"));
2630
2631 Fput (Qoverflow_error, Qerror_conditions,
2632 Fcons (Qoverflow_error, Fcons (Qdomain_error, arith_tail)));
2633 Fput (Qoverflow_error, Qerror_message,
2634 build_string ("Arithmetic overflow error"));
2635
2636 Fput (Qunderflow_error, Qerror_conditions,
2637 Fcons (Qunderflow_error, Fcons (Qdomain_error, arith_tail)));
2638 Fput (Qunderflow_error, Qerror_message,
2639 build_string ("Arithmetic underflow error"));
2640
2641 staticpro (&Qrange_error);
2642 staticpro (&Qdomain_error);
2643 staticpro (&Qsingularity_error);
2644 staticpro (&Qoverflow_error);
2645 staticpro (&Qunderflow_error);
2646#endif /* LISP_FLOAT_TYPE */
2647
7921925c
JB
2648 staticpro (&Qnil);
2649 staticpro (&Qt);
2650 staticpro (&Qquote);
2651 staticpro (&Qlambda);
2652 staticpro (&Qsubr);
2653 staticpro (&Qunbound);
2654 staticpro (&Qerror_conditions);
2655 staticpro (&Qerror_message);
2656 staticpro (&Qtop_level);
2657
2658 staticpro (&Qerror);
2659 staticpro (&Qquit);
2660 staticpro (&Qwrong_type_argument);
2661 staticpro (&Qargs_out_of_range);
2662 staticpro (&Qvoid_function);
ffd56f97 2663 staticpro (&Qcyclic_function_indirection);
7921925c
JB
2664 staticpro (&Qvoid_variable);
2665 staticpro (&Qsetting_constant);
2666 staticpro (&Qinvalid_read_syntax);
2667 staticpro (&Qwrong_number_of_arguments);
2668 staticpro (&Qinvalid_function);
2669 staticpro (&Qno_catch);
2670 staticpro (&Qend_of_file);
2671 staticpro (&Qarith_error);
2672 staticpro (&Qbeginning_of_buffer);
2673 staticpro (&Qend_of_buffer);
2674 staticpro (&Qbuffer_read_only);
638b77e6 2675 staticpro (&Qmark_inactive);
7921925c
JB
2676
2677 staticpro (&Qlistp);
2678 staticpro (&Qconsp);
2679 staticpro (&Qsymbolp);
2680 staticpro (&Qintegerp);
2681 staticpro (&Qnatnump);
8e86942b 2682 staticpro (&Qwholenump);
7921925c
JB
2683 staticpro (&Qstringp);
2684 staticpro (&Qarrayp);
2685 staticpro (&Qsequencep);
2686 staticpro (&Qbufferp);
2687 staticpro (&Qvectorp);
2688 staticpro (&Qchar_or_string_p);
2689 staticpro (&Qmarkerp);
07bd8472 2690 staticpro (&Qbuffer_or_string_p);
7921925c
JB
2691 staticpro (&Qinteger_or_marker_p);
2692#ifdef LISP_FLOAT_TYPE
2693 staticpro (&Qfloatp);
464f8898
RS
2694 staticpro (&Qnumberp);
2695 staticpro (&Qnumber_or_marker_p);
7921925c 2696#endif /* LISP_FLOAT_TYPE */
4d276982 2697 staticpro (&Qchar_table_p);
7f0edce7 2698 staticpro (&Qvector_or_char_table_p);
7921925c
JB
2699
2700 staticpro (&Qboundp);
2701 staticpro (&Qfboundp);
2702 staticpro (&Qcdr);
ab297811
RS
2703 staticpro (&Qad_advice_info);
2704 staticpro (&Qad_activate);
7921925c 2705
39bcc759
RS
2706 /* Types that type-of returns. */
2707 Qinteger = intern ("integer");
2708 Qsymbol = intern ("symbol");
2709 Qstring = intern ("string");
2710 Qcons = intern ("cons");
2711 Qmarker = intern ("marker");
2712 Qoverlay = intern ("overlay");
2713 Qfloat = intern ("float");
2714 Qwindow_configuration = intern ("window-configuration");
2715 Qprocess = intern ("process");
2716 Qwindow = intern ("window");
2717 /* Qsubr = intern ("subr"); */
2718 Qcompiled_function = intern ("compiled-function");
2719 Qbuffer = intern ("buffer");
2720 Qframe = intern ("frame");
2721 Qvector = intern ("vector");
fc67d5be
KH
2722 Qchar_table = intern ("char-table");
2723 Qbool_vector = intern ("bool-vector");
39bcc759
RS
2724
2725 staticpro (&Qinteger);
2726 staticpro (&Qsymbol);
2727 staticpro (&Qstring);
2728 staticpro (&Qcons);
2729 staticpro (&Qmarker);
2730 staticpro (&Qoverlay);
2731 staticpro (&Qfloat);
2732 staticpro (&Qwindow_configuration);
2733 staticpro (&Qprocess);
2734 staticpro (&Qwindow);
2735 /* staticpro (&Qsubr); */
2736 staticpro (&Qcompiled_function);
2737 staticpro (&Qbuffer);
2738 staticpro (&Qframe);
2739 staticpro (&Qvector);
fc67d5be
KH
2740 staticpro (&Qchar_table);
2741 staticpro (&Qbool_vector);
39bcc759 2742
7921925c
JB
2743 defsubr (&Seq);
2744 defsubr (&Snull);
39bcc759 2745 defsubr (&Stype_of);
7921925c
JB
2746 defsubr (&Slistp);
2747 defsubr (&Snlistp);
2748 defsubr (&Sconsp);
2749 defsubr (&Satom);
2750 defsubr (&Sintegerp);
464f8898 2751 defsubr (&Sinteger_or_marker_p);
7921925c
JB
2752 defsubr (&Snumberp);
2753 defsubr (&Snumber_or_marker_p);
464f8898
RS
2754#ifdef LISP_FLOAT_TYPE
2755 defsubr (&Sfloatp);
7921925c
JB
2756#endif /* LISP_FLOAT_TYPE */
2757 defsubr (&Snatnump);
2758 defsubr (&Ssymbolp);
2759 defsubr (&Sstringp);
2760 defsubr (&Svectorp);
4d276982 2761 defsubr (&Schar_table_p);
7f0edce7 2762 defsubr (&Svector_or_char_table_p);
4d276982 2763 defsubr (&Sbool_vector_p);
7921925c
JB
2764 defsubr (&Sarrayp);
2765 defsubr (&Ssequencep);
2766 defsubr (&Sbufferp);
2767 defsubr (&Smarkerp);
7921925c 2768 defsubr (&Ssubrp);
dbc4e1c1 2769 defsubr (&Sbyte_code_function_p);
7921925c
JB
2770 defsubr (&Schar_or_string_p);
2771 defsubr (&Scar);
2772 defsubr (&Scdr);
2773 defsubr (&Scar_safe);
2774 defsubr (&Scdr_safe);
2775 defsubr (&Ssetcar);
2776 defsubr (&Ssetcdr);
2777 defsubr (&Ssymbol_function);
ffd56f97 2778 defsubr (&Sindirect_function);
7921925c
JB
2779 defsubr (&Ssymbol_plist);
2780 defsubr (&Ssymbol_name);
2781 defsubr (&Smakunbound);
2782 defsubr (&Sfmakunbound);
2783 defsubr (&Sboundp);
2784 defsubr (&Sfboundp);
2785 defsubr (&Sfset);
80df38a2 2786 defsubr (&Sdefalias);
7921925c
JB
2787 defsubr (&Ssetplist);
2788 defsubr (&Ssymbol_value);
2789 defsubr (&Sset);
2790 defsubr (&Sdefault_boundp);
2791 defsubr (&Sdefault_value);
2792 defsubr (&Sset_default);
2793 defsubr (&Ssetq_default);
2794 defsubr (&Smake_variable_buffer_local);
2795 defsubr (&Smake_local_variable);
2796 defsubr (&Skill_local_variable);
62476adc 2797 defsubr (&Slocal_variable_p);
f4f04cee 2798 defsubr (&Slocal_variable_if_set_p);
7921925c
JB
2799 defsubr (&Saref);
2800 defsubr (&Saset);
f2980264 2801 defsubr (&Snumber_to_string);
25e40a4b 2802 defsubr (&Sstring_to_number);
7921925c
JB
2803 defsubr (&Seqlsign);
2804 defsubr (&Slss);
2805 defsubr (&Sgtr);
2806 defsubr (&Sleq);
2807 defsubr (&Sgeq);
2808 defsubr (&Sneq);
2809 defsubr (&Szerop);
2810 defsubr (&Splus);
2811 defsubr (&Sminus);
2812 defsubr (&Stimes);
2813 defsubr (&Squo);
2814 defsubr (&Srem);
44fa9da5 2815 defsubr (&Smod);
7921925c
JB
2816 defsubr (&Smax);
2817 defsubr (&Smin);
2818 defsubr (&Slogand);
2819 defsubr (&Slogior);
2820 defsubr (&Slogxor);
2821 defsubr (&Slsh);
2822 defsubr (&Sash);
2823 defsubr (&Sadd1);
2824 defsubr (&Ssub1);
2825 defsubr (&Slognot);
8e86942b 2826
c80bd143 2827 XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function;
7921925c
JB
2828}
2829
a33ef3ab 2830SIGTYPE
7921925c
JB
2831arith_error (signo)
2832 int signo;
2833{
fe42a920 2834#if defined(USG) && !defined(POSIX_SIGNALS)
7921925c
JB
2835 /* USG systems forget handlers when they are used;
2836 must reestablish each time */
2837 signal (signo, arith_error);
2838#endif /* USG */
2839#ifdef VMS
2840 /* VMS systems are like USG. */
2841 signal (signo, arith_error);
2842#endif /* VMS */
2843#ifdef BSD4_1
2844 sigrelse (SIGFPE);
2845#else /* not BSD4_1 */
e065a56e 2846 sigsetmask (SIGEMPTYMASK);
7921925c
JB
2847#endif /* not BSD4_1 */
2848
2849 Fsignal (Qarith_error, Qnil);
2850}
2851
2852init_data ()
2853{
2854 /* Don't do this if just dumping out.
2855 We don't want to call `signal' in this case
2856 so that we don't have trouble with dumping
2857 signal-delivering routines in an inconsistent state. */
2858#ifndef CANNOT_DUMP
2859 if (!initialized)
2860 return;
2861#endif /* CANNOT_DUMP */
2862 signal (SIGFPE, arith_error);
7403b5c8 2863
7921925c
JB
2864#ifdef uts
2865 signal (SIGEMT, arith_error);
2866#endif /* uts */
2867}