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