(Fstart_process): GCPRO some things.
[bpt/emacs.git] / src / data.c
CommitLineData
7921925c 1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
c6c5df7f 2 Copyright (C) 1985, 1986, 1988, 1993 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
8the Free Software Foundation; either version 1, or (at your option)
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
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include <signal.h>
22
18160b98 23#include <config.h>
7921925c 24#include "lisp.h"
29eab336 25#include "puresize.h"
7921925c
JB
26
27#ifndef standalone
28#include "buffer.h"
29#endif
30
a44804c2 31#include "syssignal.h"
fb8e9847 32
aaf45c7b
RS
33#if 0 /* That is untrue--XINT is used below, and it uses INTBITS.
34 What in the world is values.h, anyway? */
35#ifdef MSDOS
36/* These are redefined in values.h and not used here */
37#undef INTBITS
38#undef LONGBITS
39#undef SHORTBITS
40#endif
41#endif
42
7921925c 43#ifdef LISP_FLOAT_TYPE
defa77b5 44
93b91208
JB
45#ifdef STDC_HEADERS
46#include <stdlib.h>
47#endif
defa77b5
RS
48
49/* Work around a problem that happens because math.h on hpux 7
50 defines two static variables--which, in Emacs, are not really static,
51 because `static' is defined as nothing. The problem is that they are
52 here, in floatfns.c, and in lread.c.
53 These macros prevent the name conflict. */
54#if defined (HPUX) && !defined (HPUX8)
55#define _MAXLDBL data_c_maxldbl
56#define _NMAXLDBL data_c_nmaxldbl
57#endif
58
7921925c
JB
59#include <math.h>
60#endif /* LISP_FLOAT_TYPE */
61
024ec58f
BF
62#if !defined (atof)
63extern double atof ();
64#endif /* !atof */
65
7921925c
JB
66Lisp_Object Qnil, Qt, Qquote, Qlambda, Qsubr, Qunbound;
67Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
68Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
ffd56f97 69Lisp_Object Qvoid_variable, Qvoid_function, Qcyclic_function_indirection;
7921925c
JB
70Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
71Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
3b8819d6 72Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
7921925c
JB
73Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
74Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qlistp, Qconsp;
75Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
76Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
07bd8472 77Lisp_Object Qbuffer_or_string_p;
7921925c
JB
78Lisp_Object Qboundp, Qfboundp;
79Lisp_Object Qcdr;
80
6315e761
RS
81Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
82Lisp_Object Qoverflow_error, Qunderflow_error;
83
7921925c 84#ifdef LISP_FLOAT_TYPE
464f8898 85Lisp_Object Qfloatp;
7921925c
JB
86Lisp_Object Qnumberp, Qnumber_or_marker_p;
87#endif
88
89static Lisp_Object swap_in_symval_forwarding ();
90
91Lisp_Object
92wrong_type_argument (predicate, value)
93 register Lisp_Object predicate, value;
94{
95 register Lisp_Object tem;
96 do
97 {
98 if (!EQ (Vmocklisp_arguments, Qt))
99 {
100 if (XTYPE (value) == Lisp_String &&
101 (EQ (predicate, Qintegerp) || EQ (predicate, Qinteger_or_marker_p)))
25e40a4b 102 return Fstring_to_number (value);
7921925c 103 if (XTYPE (value) == Lisp_Int && EQ (predicate, Qstringp))
f2980264 104 return Fnumber_to_string (value);
7921925c
JB
105 }
106 value = Fsignal (Qwrong_type_argument, Fcons (predicate, Fcons (value, Qnil)));
107 tem = call1 (predicate, value);
108 }
a33ef3ab 109 while (NILP (tem));
7921925c
JB
110 return value;
111}
112
113pure_write_error ()
114{
115 error ("Attempt to modify read-only object");
116}
117
118void
119args_out_of_range (a1, a2)
120 Lisp_Object a1, a2;
121{
122 while (1)
123 Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Qnil)));
124}
125
126void
127args_out_of_range_3 (a1, a2, a3)
128 Lisp_Object a1, a2, a3;
129{
130 while (1)
131 Fsignal (Qargs_out_of_range, Fcons (a1, Fcons (a2, Fcons (a3, Qnil))));
132}
133
134Lisp_Object
135make_number (num)
136 int num;
137{
138 register Lisp_Object val;
139 XSET (val, Lisp_Int, num);
140 return val;
141}
142
143/* On some machines, XINT needs a temporary location.
144 Here it is, in case it is needed. */
145
146int sign_extend_temp;
147
148/* On a few machines, XINT can only be done by calling this. */
149
150int
151sign_extend_lisp_int (num)
152 int num;
153{
154 if (num & (1 << (VALBITS - 1)))
155 return num | ((-1) << VALBITS);
156 else
157 return num & ((1 << VALBITS) - 1);
158}
159\f
160/* Data type predicates */
161
162DEFUN ("eq", Feq, Seq, 2, 2, 0,
163 "T if the two args are the same Lisp object.")
164 (obj1, obj2)
165 Lisp_Object obj1, obj2;
166{
167 if (EQ (obj1, obj2))
168 return Qt;
169 return Qnil;
170}
171
172DEFUN ("null", Fnull, Snull, 1, 1, 0, "T if OBJECT is nil.")
173 (obj)
174 Lisp_Object obj;
175{
a33ef3ab 176 if (NILP (obj))
7921925c
JB
177 return Qt;
178 return Qnil;
179}
180
181DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0, "T if OBJECT is a cons cell.")
182 (obj)
183 Lisp_Object obj;
184{
185 if (XTYPE (obj) == Lisp_Cons)
186 return Qt;
187 return Qnil;
188}
189
190DEFUN ("atom", Fatom, Satom, 1, 1, 0, "T if OBJECT is not a cons cell. This includes nil.")
191 (obj)
192 Lisp_Object obj;
193{
194 if (XTYPE (obj) == Lisp_Cons)
195 return Qnil;
196 return Qt;
197}
198
199DEFUN ("listp", Flistp, Slistp, 1, 1, 0, "T if OBJECT is a list. This includes nil.")
200 (obj)
201 Lisp_Object obj;
202{
a33ef3ab 203 if (XTYPE (obj) == Lisp_Cons || NILP (obj))
7921925c
JB
204 return Qt;
205 return Qnil;
206}
207
208DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0, "T if OBJECT is not a list. Lists include nil.")
209 (obj)
210 Lisp_Object obj;
211{
a33ef3ab 212 if (XTYPE (obj) == Lisp_Cons || NILP (obj))
7921925c
JB
213 return Qnil;
214 return Qt;
215}
216\f
217DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0, "T if OBJECT is a symbol.")
218 (obj)
219 Lisp_Object obj;
220{
221 if (XTYPE (obj) == Lisp_Symbol)
222 return Qt;
223 return Qnil;
224}
225
226DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0, "T if OBJECT is a vector.")
227 (obj)
228 Lisp_Object obj;
229{
230 if (XTYPE (obj) == Lisp_Vector)
231 return Qt;
232 return Qnil;
233}
234
235DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0, "T if OBJECT is a string.")
236 (obj)
237 Lisp_Object obj;
238{
239 if (XTYPE (obj) == Lisp_String)
240 return Qt;
241 return Qnil;
242}
243
244DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0, "T if OBJECT is an array (string or vector).")
245 (obj)
246 Lisp_Object obj;
247{
248 if (XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
249 return Qt;
250 return Qnil;
251}
252
253DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0,
254 "T if OBJECT is a sequence (list or array).")
255 (obj)
256 register Lisp_Object obj;
257{
a33ef3ab 258 if (CONSP (obj) || NILP (obj) ||
7921925c
JB
259 XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
260 return Qt;
261 return Qnil;
262}
263
264DEFUN ("bufferp", Fbufferp, Sbufferp, 1, 1, 0, "T if OBJECT is an editor buffer.")
265 (obj)
266 Lisp_Object obj;
267{
268 if (XTYPE (obj) == Lisp_Buffer)
269 return Qt;
270 return Qnil;
271}
272
273DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0, "T if OBJECT is a marker (editor pointer).")
274 (obj)
275 Lisp_Object obj;
276{
277 if (XTYPE (obj) == Lisp_Marker)
278 return Qt;
279 return Qnil;
280}
281
7921925c
JB
282DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0, "T if OBJECT is a built-in function.")
283 (obj)
284 Lisp_Object obj;
285{
286 if (XTYPE (obj) == Lisp_Subr)
287 return Qt;
288 return Qnil;
289}
290
dbc4e1c1
JB
291DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
292 1, 1, 0, "T if OBJECT is a byte-compiled function object.")
7921925c
JB
293 (obj)
294 Lisp_Object obj;
295{
296 if (XTYPE (obj) == Lisp_Compiled)
297 return Qt;
298 return Qnil;
299}
300
0321d75c
KH
301DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0,
302 "T if OBJECT is a character (an integer) or a string.")
7921925c
JB
303 (obj)
304 register Lisp_Object obj;
305{
306 if (XTYPE (obj) == Lisp_Int || XTYPE (obj) == Lisp_String)
307 return Qt;
308 return Qnil;
309}
310\f
0321d75c 311DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0, "T if OBJECT is an integer.")
7921925c
JB
312 (obj)
313 Lisp_Object obj;
314{
315 if (XTYPE (obj) == Lisp_Int)
316 return Qt;
317 return Qnil;
318}
319
464f8898
RS
320DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0,
321 "T if OBJECT is an integer or a marker (editor pointer).")
7921925c 322 (obj)
464f8898 323 register Lisp_Object obj;
7921925c 324{
464f8898 325 if (XTYPE (obj) == Lisp_Marker || XTYPE (obj) == Lisp_Int)
7921925c
JB
326 return Qt;
327 return Qnil;
328}
329
0321d75c
KH
330DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0,
331 "T if OBJECT is a nonnegative integer.")
7921925c
JB
332 (obj)
333 Lisp_Object obj;
334{
464f8898 335 if (XTYPE (obj) == Lisp_Int && XINT (obj) >= 0)
7921925c
JB
336 return Qt;
337 return Qnil;
338}
339
340DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
341 "T if OBJECT is a number (floating point or integer).")
342 (obj)
343 Lisp_Object obj;
344{
dbc4e1c1 345 if (NUMBERP (obj))
7921925c 346 return Qt;
dbc4e1c1
JB
347 else
348 return Qnil;
7921925c
JB
349}
350
351DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
352 Snumber_or_marker_p, 1, 1, 0,
353 "T if OBJECT is a number or a marker.")
354 (obj)
355 Lisp_Object obj;
356{
dbc4e1c1 357 if (NUMBERP (obj)
7921925c
JB
358 || XTYPE (obj) == Lisp_Marker)
359 return Qt;
360 return Qnil;
361}
464f8898
RS
362
363#ifdef LISP_FLOAT_TYPE
364DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
365 "T if OBJECT is a floating point number.")
366 (obj)
367 Lisp_Object obj;
368{
369 if (XTYPE (obj) == Lisp_Float)
370 return Qt;
371 return Qnil;
372}
7921925c
JB
373#endif /* LISP_FLOAT_TYPE */
374\f
375/* Extract and set components of lists */
376
377DEFUN ("car", Fcar, Scar, 1, 1, 0,
378 "Return the car of CONSCELL. If arg is nil, return nil.\n\
379Error if arg is not nil and not a cons cell. See also `car-safe'.")
380 (list)
381 register Lisp_Object list;
382{
383 while (1)
384 {
385 if (XTYPE (list) == Lisp_Cons)
386 return XCONS (list)->car;
387 else if (EQ (list, Qnil))
388 return Qnil;
389 else
390 list = wrong_type_argument (Qlistp, list);
391 }
392}
393
394DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
395 "Return the car of OBJECT if it is a cons cell, or else nil.")
396 (object)
397 Lisp_Object object;
398{
399 if (XTYPE (object) == Lisp_Cons)
400 return XCONS (object)->car;
401 else
402 return Qnil;
403}
404
405DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
406 "Return the cdr of CONSCELL. If arg is nil, return nil.\n\
407Error if arg is not nil and not a cons cell. See also `cdr-safe'.")
408
409 (list)
410 register Lisp_Object list;
411{
412 while (1)
413 {
414 if (XTYPE (list) == Lisp_Cons)
415 return XCONS (list)->cdr;
416 else if (EQ (list, Qnil))
417 return Qnil;
418 else
419 list = wrong_type_argument (Qlistp, list);
420 }
421}
422
423DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
424 "Return the cdr of OBJECT if it is a cons cell, or else nil.")
425 (object)
426 Lisp_Object object;
427{
428 if (XTYPE (object) == Lisp_Cons)
429 return XCONS (object)->cdr;
430 else
431 return Qnil;
432}
433
434DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
435 "Set the car of CONSCELL to be NEWCAR. Returns NEWCAR.")
436 (cell, newcar)
437 register Lisp_Object cell, newcar;
438{
439 if (XTYPE (cell) != Lisp_Cons)
440 cell = wrong_type_argument (Qconsp, cell);
441
442 CHECK_IMPURE (cell);
443 XCONS (cell)->car = newcar;
444 return newcar;
445}
446
447DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
448 "Set the cdr of CONSCELL to be NEWCDR. Returns NEWCDR.")
449 (cell, newcdr)
450 register Lisp_Object cell, newcdr;
451{
452 if (XTYPE (cell) != Lisp_Cons)
453 cell = wrong_type_argument (Qconsp, cell);
454
455 CHECK_IMPURE (cell);
456 XCONS (cell)->cdr = newcdr;
457 return newcdr;
458}
459\f
460/* Extract and set components of symbols */
461
462DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, "T if SYMBOL's value is not void.")
463 (sym)
464 register Lisp_Object sym;
465{
466 Lisp_Object valcontents;
467 CHECK_SYMBOL (sym, 0);
468
469 valcontents = XSYMBOL (sym)->value;
470
471#ifdef SWITCH_ENUM_BUG
472 switch ((int) XTYPE (valcontents))
473#else
474 switch (XTYPE (valcontents))
475#endif
476 {
477 case Lisp_Buffer_Local_Value:
478 case Lisp_Some_Buffer_Local_Value:
479 valcontents = swap_in_symval_forwarding (sym, valcontents);
480 }
481
482 return (XTYPE (valcontents) == Lisp_Void || EQ (valcontents, Qunbound)
483 ? Qnil : Qt);
484}
485
486DEFUN ("fboundp", Ffboundp, Sfboundp, 1, 1, 0, "T if SYMBOL's function definition is not void.")
487 (sym)
488 register Lisp_Object sym;
489{
490 CHECK_SYMBOL (sym, 0);
491 return (XTYPE (XSYMBOL (sym)->function) == Lisp_Void
492 || EQ (XSYMBOL (sym)->function, Qunbound))
493 ? Qnil : Qt;
494}
495
496DEFUN ("makunbound", Fmakunbound, Smakunbound, 1, 1, 0, "Make SYMBOL's value be void.")
497 (sym)
498 register Lisp_Object sym;
499{
500 CHECK_SYMBOL (sym, 0);
a33ef3ab 501 if (NILP (sym) || EQ (sym, Qt))
7921925c
JB
502 return Fsignal (Qsetting_constant, Fcons (sym, Qnil));
503 Fset (sym, Qunbound);
504 return sym;
505}
506
507DEFUN ("fmakunbound", Ffmakunbound, Sfmakunbound, 1, 1, 0, "Make SYMBOL's function definition be void.")
508 (sym)
509 register Lisp_Object sym;
510{
511 CHECK_SYMBOL (sym, 0);
512 XSYMBOL (sym)->function = Qunbound;
513 return sym;
514}
515
516DEFUN ("symbol-function", Fsymbol_function, Ssymbol_function, 1, 1, 0,
517 "Return SYMBOL's function definition. Error if that is void.")
ffd56f97
JB
518 (symbol)
519 register Lisp_Object symbol;
7921925c 520{
ffd56f97
JB
521 CHECK_SYMBOL (symbol, 0);
522 if (EQ (XSYMBOL (symbol)->function, Qunbound))
523 return Fsignal (Qvoid_function, Fcons (symbol, Qnil));
524 return XSYMBOL (symbol)->function;
7921925c
JB
525}
526
527DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, "Return SYMBOL's property list.")
528 (sym)
529 register Lisp_Object sym;
530{
531 CHECK_SYMBOL (sym, 0);
532 return XSYMBOL (sym)->plist;
533}
534
535DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, "Return SYMBOL's name, a string.")
536 (sym)
537 register Lisp_Object sym;
538{
539 register Lisp_Object name;
540
541 CHECK_SYMBOL (sym, 0);
542 XSET (name, Lisp_String, XSYMBOL (sym)->name);
543 return name;
544}
545
546DEFUN ("fset", Ffset, Sfset, 2, 2, 0,
547 "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.")
548 (sym, newdef)
549 register Lisp_Object sym, newdef;
550{
551 CHECK_SYMBOL (sym, 0);
e3fa7dfc 552
a33ef3ab 553 if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound))
7921925c
JB
554 Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function),
555 Vautoload_queue);
556 XSYMBOL (sym)->function = newdef;
557 return newdef;
558}
559
d9bcdb34
RS
560/* This name should be removed once it is eliminated from elsewhere. */
561
80df38a2 562DEFUN ("defalias", Fdefalias, Sdefalias, 2, 2, 0,
fc08c367
RS
563 "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.\n\
564Associates the function with the current load file, if any.")
565 (sym, newdef)
566 register Lisp_Object sym, newdef;
567{
568 CHECK_SYMBOL (sym, 0);
569 if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound))
570 Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function),
571 Vautoload_queue);
572 XSYMBOL (sym)->function = newdef;
573 LOADHIST_ATTACH (sym);
574 return newdef;
575}
576
d9bcdb34
RS
577DEFUN ("define-function", Fdefine_function, Sdefine_function, 2, 2, 0,
578 "Set SYMBOL's function definition to NEWVAL, and return NEWVAL.\n\
579Associates the function with the current load file, if any.")
580 (sym, newdef)
581 register Lisp_Object sym, newdef;
582{
583 CHECK_SYMBOL (sym, 0);
584 if (!NILP (Vautoload_queue) && !EQ (XSYMBOL (sym)->function, Qunbound))
585 Vautoload_queue = Fcons (Fcons (sym, XSYMBOL (sym)->function),
586 Vautoload_queue);
587 XSYMBOL (sym)->function = newdef;
588 LOADHIST_ATTACH (sym);
589 return newdef;
590}
591
7921925c
JB
592DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0,
593 "Set SYMBOL's property list to NEWVAL, and return NEWVAL.")
594 (sym, newplist)
595 register Lisp_Object sym, newplist;
596{
597 CHECK_SYMBOL (sym, 0);
598 XSYMBOL (sym)->plist = newplist;
599 return newplist;
600}
ffd56f97 601
7921925c
JB
602\f
603/* Getting and setting values of symbols */
604
605/* Given the raw contents of a symbol value cell,
606 return the Lisp value of the symbol.
607 This does not handle buffer-local variables; use
608 swap_in_symval_forwarding for that. */
609
610Lisp_Object
611do_symval_forwarding (valcontents)
612 register Lisp_Object valcontents;
613{
614 register Lisp_Object val;
615#ifdef SWITCH_ENUM_BUG
616 switch ((int) XTYPE (valcontents))
617#else
618 switch (XTYPE (valcontents))
619#endif
620 {
621 case Lisp_Intfwd:
622 XSET (val, Lisp_Int, *XINTPTR (valcontents));
623 return val;
624
625 case Lisp_Boolfwd:
626 if (*XINTPTR (valcontents))
627 return Qt;
628 return Qnil;
629
630 case Lisp_Objfwd:
631 return *XOBJFWD (valcontents);
632
633 case Lisp_Buffer_Objfwd:
634 return *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer);
635 }
636 return valcontents;
637}
638
639/* Store NEWVAL into SYM, where VALCONTENTS is found in the value cell
640 of SYM. If SYM is buffer-local, VALCONTENTS should be the
641 buffer-independent contents of the value cell: forwarded just one
642 step past the buffer-localness. */
643
644void
645store_symval_forwarding (sym, valcontents, newval)
646 Lisp_Object sym;
647 register Lisp_Object valcontents, newval;
648{
649#ifdef SWITCH_ENUM_BUG
650 switch ((int) XTYPE (valcontents))
651#else
652 switch (XTYPE (valcontents))
653#endif
654 {
655 case Lisp_Intfwd:
656 CHECK_NUMBER (newval, 1);
657 *XINTPTR (valcontents) = XINT (newval);
658 break;
659
660 case Lisp_Boolfwd:
a33ef3ab 661 *XINTPTR (valcontents) = NILP(newval) ? 0 : 1;
7921925c
JB
662 break;
663
664 case Lisp_Objfwd:
665 *XOBJFWD (valcontents) = newval;
666 break;
667
668 case Lisp_Buffer_Objfwd:
bc540f9f
JB
669 {
670 unsigned int offset = XUINT (valcontents);
671 Lisp_Object type =
672 *(Lisp_Object *)(offset + (char *)&buffer_local_types);
673
674 if (! NILP (type) && ! NILP (newval)
675 && XTYPE (newval) != XINT (type))
676 buffer_slot_type_mismatch (valcontents, newval);
677
678 *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer)
679 = newval;
680 break;
681 }
7921925c
JB
682
683 default:
684 valcontents = XSYMBOL (sym)->value;
685 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
686 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
687 XCONS (XSYMBOL (sym)->value)->car = newval;
688 else
689 XSYMBOL (sym)->value = newval;
690 }
691}
692
693/* Set up the buffer-local symbol SYM for validity in the current
694 buffer. VALCONTENTS is the contents of its value cell.
695 Return the value forwarded one step past the buffer-local indicator. */
696
697static Lisp_Object
698swap_in_symval_forwarding (sym, valcontents)
699 Lisp_Object sym, valcontents;
700{
701 /* valcontents is a list
702 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE)).
703
704 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
533984a8
JB
705 local_var_alist, that being the element whose car is this
706 variable. Or it can be a pointer to the
707 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not have
708 an element in its alist for this variable.
709
710 If the current buffer is not BUFFER, we store the current
711 REALVALUE value into CURRENT-ALIST-ELEMENT, then find the
712 appropriate alist element for the buffer now current and set up
713 CURRENT-ALIST-ELEMENT. Then we set REALVALUE out of that
714 element, and store into BUFFER.
715
7921925c
JB
716 Note that REALVALUE can be a forwarding pointer. */
717
718 register Lisp_Object tem1;
719 tem1 = XCONS (XCONS (valcontents)->cdr)->car;
720
a33ef3ab 721 if (NILP (tem1) || current_buffer != XBUFFER (tem1))
7921925c
JB
722 {
723 tem1 = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
724 Fsetcdr (tem1, do_symval_forwarding (XCONS (valcontents)->car));
725 tem1 = assq_no_quit (sym, current_buffer->local_var_alist);
a33ef3ab 726 if (NILP (tem1))
7921925c
JB
727 tem1 = XCONS (XCONS (valcontents)->cdr)->cdr;
728 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car = tem1;
729 XSET (XCONS (XCONS (valcontents)->cdr)->car, Lisp_Buffer, current_buffer);
730 store_symval_forwarding (sym, XCONS (valcontents)->car, Fcdr (tem1));
731 }
732 return XCONS (valcontents)->car;
733}
734\f
14e76af9
JB
735/* Find the value of a symbol, returning Qunbound if it's not bound.
736 This is helpful for code which just wants to get a variable's value
737 if it has one, without signalling an error.
738 Note that it must not be possible to quit
739 within this function. Great care is required for this. */
7921925c 740
14e76af9
JB
741Lisp_Object
742find_symbol_value (sym)
7921925c
JB
743 Lisp_Object sym;
744{
745 register Lisp_Object valcontents, tem1;
746 register Lisp_Object val;
747 CHECK_SYMBOL (sym, 0);
748 valcontents = XSYMBOL (sym)->value;
749
750 retry:
751#ifdef SWITCH_ENUM_BUG
752 switch ((int) XTYPE (valcontents))
753#else
754 switch (XTYPE (valcontents))
755#endif
756 {
757 case Lisp_Buffer_Local_Value:
758 case Lisp_Some_Buffer_Local_Value:
759 valcontents = swap_in_symval_forwarding (sym, valcontents);
760 goto retry;
761
762 case Lisp_Intfwd:
763 XSET (val, Lisp_Int, *XINTPTR (valcontents));
764 return val;
765
766 case Lisp_Boolfwd:
767 if (*XINTPTR (valcontents))
768 return Qt;
769 return Qnil;
770
771 case Lisp_Objfwd:
772 return *XOBJFWD (valcontents);
773
774 case Lisp_Buffer_Objfwd:
775 return *(Lisp_Object *)(XUINT (valcontents) + (char *)current_buffer);
776
7921925c 777 case Lisp_Void:
14e76af9 778 return Qunbound;
7921925c
JB
779 }
780
781 return valcontents;
782}
783
14e76af9
JB
784DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
785 "Return SYMBOL's value. Error if that is void.")
786 (sym)
787 Lisp_Object sym;
788{
789 Lisp_Object val = find_symbol_value (sym);
790
791 if (EQ (val, Qunbound))
792 return Fsignal (Qvoid_variable, Fcons (sym, Qnil));
793 else
794 return val;
795}
796
7921925c
JB
797DEFUN ("set", Fset, Sset, 2, 2, 0,
798 "Set SYMBOL's value to NEWVAL, and return NEWVAL.")
799 (sym, newval)
800 register Lisp_Object sym, newval;
801{
802 int voide = (XTYPE (newval) == Lisp_Void || EQ (newval, Qunbound));
803
804#ifndef RTPC_REGISTER_BUG
805 register Lisp_Object valcontents, tem1, current_alist_element;
806#else /* RTPC_REGISTER_BUG */
807 register Lisp_Object tem1;
808 Lisp_Object valcontents, current_alist_element;
809#endif /* RTPC_REGISTER_BUG */
810
811 CHECK_SYMBOL (sym, 0);
a33ef3ab 812 if (NILP (sym) || EQ (sym, Qt))
7921925c
JB
813 return Fsignal (Qsetting_constant, Fcons (sym, Qnil));
814 valcontents = XSYMBOL (sym)->value;
815
816 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
817 {
818 register int idx = XUINT (valcontents);
819 register int mask = *(int *)(idx + (char *) &buffer_local_flags);
820 if (mask > 0)
821 current_buffer->local_var_flags |= mask;
822 }
823
d8cafeb5
JB
824 else if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
825 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
7921925c 826 {
d8cafeb5
JB
827 /* valcontents is actually a pointer to a cons heading something like:
828 (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE).
829
830 BUFFER is the last buffer for which this symbol's value was
831 made up to date.
832
833 CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
834 local_var_alist, that being the element whose car is this
835 variable. Or it can be a pointer to the
836 (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE), if BUFFER does not
837 have an element in its alist for this variable (that is, if
838 BUFFER sees the default value of this variable).
839
840 If we want to examine or set the value and BUFFER is current,
841 we just examine or set REALVALUE. If BUFFER is not current, we
842 store the current REALVALUE value into CURRENT-ALIST-ELEMENT,
843 then find the appropriate alist element for the buffer now
844 current and set up CURRENT-ALIST-ELEMENT. Then we set
845 REALVALUE out of that element, and store into BUFFER.
846
847 If we are setting the variable and the current buffer does
848 not have an alist entry for this variable, an alist entry is
849 created.
850
851 Note that REALVALUE can be a forwarding pointer. Each time
852 it is examined or set, forwarding must be done. */
853
854 /* What value are we caching right now? */
855 current_alist_element =
856 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
857
858 /* If the current buffer is not the buffer whose binding is
859 currently cached, or if it's a Lisp_Buffer_Local_Value and
860 we're looking at the default value, the cache is invalid; we
861 need to write it out, and find the new CURRENT-ALIST-ELEMENT. */
862 if ((current_buffer
863 != XBUFFER (XCONS (XCONS (valcontents)->cdr)->car))
864 || (XTYPE (valcontents) == Lisp_Buffer_Local_Value
b06faa91
JB
865 && EQ (XCONS (current_alist_element)->car,
866 current_alist_element)))
7921925c 867 {
d8cafeb5
JB
868 /* Write out the cached value for the old buffer; copy it
869 back to its alist element. This works if the current
870 buffer only sees the default value, too. */
871 Fsetcdr (current_alist_element,
872 do_symval_forwarding (XCONS (valcontents)->car));
7921925c 873
d8cafeb5 874 /* Find the new value for CURRENT-ALIST-ELEMENT. */
7921925c 875 tem1 = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 876 if (NILP (tem1))
d8cafeb5
JB
877 {
878 /* This buffer still sees the default value. */
879
880 /* If the variable is a Lisp_Some_Buffer_Local_Value,
881 make CURRENT-ALIST-ELEMENT point to itself,
882 indicating that we're seeing the default value. */
883 if (XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
884 tem1 = XCONS (XCONS (valcontents)->cdr)->cdr;
885
886 /* If it's a Lisp_Buffer_Local_Value, give this buffer a
887 new assoc for a local value and set
888 CURRENT-ALIST-ELEMENT to point to that. */
889 else
890 {
891 tem1 = Fcons (sym, Fcdr (current_alist_element));
892 current_buffer->local_var_alist =
893 Fcons (tem1, current_buffer->local_var_alist);
894 }
895 }
896 /* Cache the new buffer's assoc in CURRENT-ALIST-ELEMENT. */
7921925c 897 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car = tem1;
d8cafeb5
JB
898
899 /* Set BUFFER, now that CURRENT-ALIST-ELEMENT is accurate. */
900 XSET (XCONS (XCONS (valcontents)->cdr)->car,
901 Lisp_Buffer, current_buffer);
7921925c
JB
902 }
903 valcontents = XCONS (valcontents)->car;
904 }
d8cafeb5 905
7921925c
JB
906 /* If storing void (making the symbol void), forward only through
907 buffer-local indicator, not through Lisp_Objfwd, etc. */
908 if (voide)
909 store_symval_forwarding (sym, Qnil, newval);
910 else
911 store_symval_forwarding (sym, valcontents, newval);
d8cafeb5 912
7921925c
JB
913 return newval;
914}
915\f
916/* Access or set a buffer-local symbol's default value. */
917
918/* Return the default value of SYM, but don't check for voidness.
919 Return Qunbound or a Lisp_Void object if it is void. */
920
921Lisp_Object
922default_value (sym)
923 Lisp_Object sym;
924{
925 register Lisp_Object valcontents;
926
927 CHECK_SYMBOL (sym, 0);
928 valcontents = XSYMBOL (sym)->value;
929
930 /* For a built-in buffer-local variable, get the default value
931 rather than letting do_symval_forwarding get the current value. */
932 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
933 {
934 register int idx = XUINT (valcontents);
935
936 if (*(int *) (idx + (char *) &buffer_local_flags) != 0)
937 return *(Lisp_Object *)(idx + (char *) &buffer_defaults);
938 }
939
940 /* Handle user-created local variables. */
941 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
942 || XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
943 {
944 /* If var is set up for a buffer that lacks a local value for it,
945 the current value is nominally the default value.
946 But the current value slot may be more up to date, since
947 ordinary setq stores just that slot. So use that. */
948 Lisp_Object current_alist_element, alist_element_car;
949 current_alist_element
950 = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
951 alist_element_car = XCONS (current_alist_element)->car;
952 if (EQ (alist_element_car, current_alist_element))
953 return do_symval_forwarding (XCONS (valcontents)->car);
954 else
955 return XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->cdr;
956 }
957 /* For other variables, get the current value. */
958 return do_symval_forwarding (valcontents);
959}
960
961DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
962 "Return T if SYMBOL has a non-void default value.\n\
963This is the value that is seen in buffers that do not have their own values\n\
964for this variable.")
965 (sym)
966 Lisp_Object sym;
967{
968 register Lisp_Object value;
969
970 value = default_value (sym);
971 return (XTYPE (value) == Lisp_Void || EQ (value, Qunbound)
972 ? Qnil : Qt);
973}
974
975DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0,
976 "Return SYMBOL's default value.\n\
977This is the value that is seen in buffers that do not have their own values\n\
978for this variable. The default value is meaningful for variables with\n\
979local bindings in certain buffers.")
980 (sym)
981 Lisp_Object sym;
982{
983 register Lisp_Object value;
984
985 value = default_value (sym);
986 if (XTYPE (value) == Lisp_Void || EQ (value, Qunbound))
987 return Fsignal (Qvoid_variable, Fcons (sym, Qnil));
988 return value;
989}
990
991DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
992 "Set SYMBOL's default value to VAL. SYMBOL and VAL are evaluated.\n\
993The default value is seen in buffers that do not have their own values\n\
994for this variable.")
995 (sym, value)
996 Lisp_Object sym, value;
997{
998 register Lisp_Object valcontents, current_alist_element, alist_element_buffer;
999
1000 CHECK_SYMBOL (sym, 0);
1001 valcontents = XSYMBOL (sym)->value;
1002
1003 /* Handle variables like case-fold-search that have special slots
1004 in the buffer. Make them work apparently like Lisp_Buffer_Local_Value
1005 variables. */
1006 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
1007 {
1008 register int idx = XUINT (valcontents);
1009#ifndef RTPC_REGISTER_BUG
1010 register struct buffer *b;
1011#else
1012 struct buffer *b;
1013#endif
1014 register int mask = *(int *) (idx + (char *) &buffer_local_flags);
1015
1016 if (mask > 0)
1017 {
1018 *(Lisp_Object *)(idx + (char *) &buffer_defaults) = value;
1019 for (b = all_buffers; b; b = b->next)
1020 if (!(b->local_var_flags & mask))
1021 *(Lisp_Object *)(idx + (char *) b) = value;
1022 }
1023 return value;
1024 }
1025
1026 if (XTYPE (valcontents) != Lisp_Buffer_Local_Value &&
1027 XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
1028 return Fset (sym, value);
1029
1030 /* Store new value into the DEFAULT-VALUE slot */
1031 XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->cdr = value;
1032
1033 /* If that slot is current, we must set the REALVALUE slot too */
1034 current_alist_element = XCONS (XCONS (XCONS (valcontents)->cdr)->cdr)->car;
1035 alist_element_buffer = Fcar (current_alist_element);
1036 if (EQ (alist_element_buffer, current_alist_element))
1037 store_symval_forwarding (sym, XCONS (valcontents)->car, value);
1038
1039 return value;
1040}
1041
1042DEFUN ("setq-default", Fsetq_default, Ssetq_default, 2, UNEVALLED, 0,
1043 "\
1044(setq-default SYM VAL SYM VAL ...): set each SYM's default value to its VAL.\n\
1045VAL is evaluated; SYM is not. The default value is seen in buffers that do\n\
1046not have their own values for this variable.")
1047 (args)
1048 Lisp_Object args;
1049{
1050 register Lisp_Object args_left;
1051 register Lisp_Object val, sym;
1052 struct gcpro gcpro1;
1053
a33ef3ab 1054 if (NILP (args))
7921925c
JB
1055 return Qnil;
1056
1057 args_left = args;
1058 GCPRO1 (args);
1059
1060 do
1061 {
1062 val = Feval (Fcar (Fcdr (args_left)));
1063 sym = Fcar (args_left);
1064 Fset_default (sym, val);
1065 args_left = Fcdr (Fcdr (args_left));
1066 }
a33ef3ab 1067 while (!NILP (args_left));
7921925c
JB
1068
1069 UNGCPRO;
1070 return val;
1071}
1072\f
a5ca2b75
JB
1073/* Lisp functions for creating and removing buffer-local variables. */
1074
7921925c
JB
1075DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local, Smake_variable_buffer_local,
1076 1, 1, "vMake Variable Buffer Local: ",
1077 "Make VARIABLE have a separate value for each buffer.\n\
1078At any time, the value for the current buffer is in effect.\n\
1079There is also a default value which is seen in any buffer which has not yet\n\
1080set its own value.\n\
1081Using `set' or `setq' to set the variable causes it to have a separate value\n\
1082for the current buffer if it was previously using the default value.\n\
1083The function `default-value' gets the default value and `set-default' sets it.")
1084 (sym)
1085 register Lisp_Object sym;
1086{
1087 register Lisp_Object tem, valcontents;
1088
1089 CHECK_SYMBOL (sym, 0);
1090
1091 if (EQ (sym, Qnil) || EQ (sym, Qt))
1092 error ("Symbol %s may not be buffer-local", XSYMBOL (sym)->name->data);
1093
1094 valcontents = XSYMBOL (sym)->value;
1095 if ((XTYPE (valcontents) == Lisp_Buffer_Local_Value) ||
1096 (XTYPE (valcontents) == Lisp_Buffer_Objfwd))
1097 return sym;
1098 if (XTYPE (valcontents) == Lisp_Some_Buffer_Local_Value)
1099 {
1100 XSETTYPE (XSYMBOL (sym)->value, Lisp_Buffer_Local_Value);
1101 return sym;
1102 }
1103 if (EQ (valcontents, Qunbound))
1104 XSYMBOL (sym)->value = Qnil;
1105 tem = Fcons (Qnil, Fsymbol_value (sym));
1106 XCONS (tem)->car = tem;
1107 XSYMBOL (sym)->value = Fcons (XSYMBOL (sym)->value, Fcons (Fcurrent_buffer (), tem));
1108 XSETTYPE (XSYMBOL (sym)->value, Lisp_Buffer_Local_Value);
1109 return sym;
1110}
1111
1112DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable,
1113 1, 1, "vMake Local Variable: ",
1114 "Make VARIABLE have a separate value in the current buffer.\n\
1115Other buffers will continue to share a common default value.\n\
1116See also `make-variable-buffer-local'.\n\n\
1117If the variable is already arranged to become local when set,\n\
1118this function causes a local value to exist for this buffer,\n\
1119just as if the variable were set.")
1120 (sym)
1121 register Lisp_Object sym;
1122{
1123 register Lisp_Object tem, valcontents;
1124
1125 CHECK_SYMBOL (sym, 0);
1126
1127 if (EQ (sym, Qnil) || EQ (sym, Qt))
1128 error ("Symbol %s may not be buffer-local", XSYMBOL (sym)->name->data);
1129
1130 valcontents = XSYMBOL (sym)->value;
1131 if (XTYPE (valcontents) == Lisp_Buffer_Local_Value
1132 || XTYPE (valcontents) == Lisp_Buffer_Objfwd)
1133 {
1134 tem = Fboundp (sym);
1135
1136 /* Make sure the symbol has a local value in this particular buffer,
1137 by setting it to the same value it already has. */
1138 Fset (sym, (EQ (tem, Qt) ? Fsymbol_value (sym) : Qunbound));
1139 return sym;
1140 }
1141 /* Make sure sym is set up to hold per-buffer values */
1142 if (XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
1143 {
1144 if (EQ (valcontents, Qunbound))
1145 XSYMBOL (sym)->value = Qnil;
1146 tem = Fcons (Qnil, do_symval_forwarding (valcontents));
1147 XCONS (tem)->car = tem;
1148 XSYMBOL (sym)->value = Fcons (XSYMBOL (sym)->value, Fcons (Qnil, tem));
1149 XSETTYPE (XSYMBOL (sym)->value, Lisp_Some_Buffer_Local_Value);
1150 }
1151 /* Make sure this buffer has its own value of sym */
1152 tem = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 1153 if (NILP (tem))
7921925c
JB
1154 {
1155 current_buffer->local_var_alist
1156 = Fcons (Fcons (sym, XCONS (XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->cdr)->cdr),
1157 current_buffer->local_var_alist);
1158
1159 /* Make sure symbol does not think it is set up for this buffer;
1160 force it to look once again for this buffer's value */
1161 {
1162 /* This local variable avoids "expression too complex" on IBM RT. */
1163 Lisp_Object xs;
1164
1165 xs = XSYMBOL (sym)->value;
1166 if (current_buffer == XBUFFER (XCONS (XCONS (xs)->cdr)->car))
1167 XCONS (XCONS (XSYMBOL (sym)->value)->cdr)->car = Qnil;
1168 }
7921925c 1169 }
a5ca2b75
JB
1170
1171 /* If the symbol forwards into a C variable, then swap in the
1172 variable for this buffer immediately. If C code modifies the
1173 variable before we swap in, then that new value will clobber the
1174 default value the next time we swap. */
1175 valcontents = XCONS (XSYMBOL (sym)->value)->car;
1176 if (XTYPE (valcontents) == Lisp_Intfwd
1177 || XTYPE (valcontents) == Lisp_Boolfwd
1178 || XTYPE (valcontents) == Lisp_Objfwd)
1179 swap_in_symval_forwarding (sym, XSYMBOL (sym)->value);
1180
7921925c
JB
1181 return sym;
1182}
1183
1184DEFUN ("kill-local-variable", Fkill_local_variable, Skill_local_variable,
1185 1, 1, "vKill Local Variable: ",
1186 "Make VARIABLE no longer have a separate value in the current buffer.\n\
1187From now on the default value will apply in this buffer.")
1188 (sym)
1189 register Lisp_Object sym;
1190{
1191 register Lisp_Object tem, valcontents;
1192
1193 CHECK_SYMBOL (sym, 0);
1194
1195 valcontents = XSYMBOL (sym)->value;
1196
1197 if (XTYPE (valcontents) == Lisp_Buffer_Objfwd)
1198 {
1199 register int idx = XUINT (valcontents);
1200 register int mask = *(int *) (idx + (char *) &buffer_local_flags);
1201
1202 if (mask > 0)
1203 {
1204 *(Lisp_Object *)(idx + (char *) current_buffer)
1205 = *(Lisp_Object *)(idx + (char *) &buffer_defaults);
1206 current_buffer->local_var_flags &= ~mask;
1207 }
1208 return sym;
1209 }
1210
1211 if (XTYPE (valcontents) != Lisp_Buffer_Local_Value &&
1212 XTYPE (valcontents) != Lisp_Some_Buffer_Local_Value)
1213 return sym;
1214
1215 /* Get rid of this buffer's alist element, if any */
1216
1217 tem = Fassq (sym, current_buffer->local_var_alist);
a33ef3ab 1218 if (!NILP (tem))
7921925c
JB
1219 current_buffer->local_var_alist = Fdelq (tem, current_buffer->local_var_alist);
1220
1221 /* Make sure symbol does not think it is set up for this buffer;
1222 force it to look once again for this buffer's value */
1223 {
1224 Lisp_Object sv;
1225 sv = XSYMBOL (sym)->value;
1226 if (current_buffer == XBUFFER (XCONS (XCONS (sv)->cdr)->car))
1227 XCONS (XCONS (sv)->cdr)->car = Qnil;
1228 }
1229
1230 return sym;
1231}
1232\f
ffd56f97
JB
1233/* Find the function at the end of a chain of symbol function indirections. */
1234
1235/* If OBJECT is a symbol, find the end of its function chain and
1236 return the value found there. If OBJECT is not a symbol, just
1237 return it. If there is a cycle in the function chain, signal a
1238 cyclic-function-indirection error.
1239
1240 This is like Findirect_function, except that it doesn't signal an
1241 error if the chain ends up unbound. */
1242Lisp_Object
a2932990 1243indirect_function (object)
ffd56f97
JB
1244 register Lisp_Object object;
1245{
eb8c3be9 1246 Lisp_Object tortoise, hare;
ffd56f97 1247
eb8c3be9 1248 hare = tortoise = object;
ffd56f97
JB
1249
1250 for (;;)
1251 {
1252 if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound))
1253 break;
1254 hare = XSYMBOL (hare)->function;
1255 if (XTYPE (hare) != Lisp_Symbol || EQ (hare, Qunbound))
1256 break;
1257 hare = XSYMBOL (hare)->function;
1258
eb8c3be9 1259 tortoise = XSYMBOL (tortoise)->function;
ffd56f97 1260
eb8c3be9 1261 if (EQ (hare, tortoise))
ffd56f97
JB
1262 Fsignal (Qcyclic_function_indirection, Fcons (object, Qnil));
1263 }
1264
1265 return hare;
1266}
1267
1268DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 1, 0,
1269 "Return the function at the end of OBJECT's function chain.\n\
1270If OBJECT is a symbol, follow all function indirections and return the final\n\
1271function binding.\n\
1272If OBJECT is not a symbol, just return it.\n\
1273Signal a void-function error if the final symbol is unbound.\n\
1274Signal a cyclic-function-indirection error if there is a loop in the\n\
1275function chain of symbols.")
1276 (object)
1277 register Lisp_Object object;
1278{
1279 Lisp_Object result;
1280
1281 result = indirect_function (object);
1282
1283 if (EQ (result, Qunbound))
1284 return Fsignal (Qvoid_function, Fcons (object, Qnil));
1285 return result;
1286}
1287\f
7921925c
JB
1288/* Extract and set vector and string elements */
1289
1290DEFUN ("aref", Faref, Saref, 2, 2, 0,
1291 "Return the element of ARRAY at index INDEX.\n\
1292ARRAY may be a vector or a string, or a byte-code object. INDEX starts at 0.")
1293 (array, idx)
1294 register Lisp_Object array;
1295 Lisp_Object idx;
1296{
1297 register int idxval;
1298
1299 CHECK_NUMBER (idx, 1);
1300 idxval = XINT (idx);
1301 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String
1302 && XTYPE (array) != Lisp_Compiled)
1303 array = wrong_type_argument (Qarrayp, array);
1304 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1305 args_out_of_range (array, idx);
1306 if (XTYPE (array) == Lisp_String)
1307 {
1308 Lisp_Object val;
1309 XFASTINT (val) = (unsigned char) XSTRING (array)->data[idxval];
1310 return val;
1311 }
1312 else
1313 return XVECTOR (array)->contents[idxval];
1314}
1315
1316DEFUN ("aset", Faset, Saset, 3, 3, 0,
73d40355
RS
1317 "Store into the element of ARRAY at index IDX the value NEWELT.\n\
1318ARRAY may be a vector or a string. IDX starts at 0.")
7921925c
JB
1319 (array, idx, newelt)
1320 register Lisp_Object array;
1321 Lisp_Object idx, newelt;
1322{
1323 register int idxval;
1324
1325 CHECK_NUMBER (idx, 1);
1326 idxval = XINT (idx);
1327 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String)
1328 array = wrong_type_argument (Qarrayp, array);
1329 if (idxval < 0 || idxval >= XVECTOR (array)->size)
1330 args_out_of_range (array, idx);
1331 CHECK_IMPURE (array);
1332
1333 if (XTYPE (array) == Lisp_Vector)
1334 XVECTOR (array)->contents[idxval] = newelt;
1335 else
1336 {
1337 CHECK_NUMBER (newelt, 2);
1338 XSTRING (array)->data[idxval] = XINT (newelt);
1339 }
1340
1341 return newelt;
1342}
1343
1344Lisp_Object
1345Farray_length (array)
1346 register Lisp_Object array;
1347{
1348 register Lisp_Object size;
1349 if (XTYPE (array) != Lisp_Vector && XTYPE (array) != Lisp_String
1350 && XTYPE (array) != Lisp_Compiled)
1351 array = wrong_type_argument (Qarrayp, array);
1352 XFASTINT (size) = XVECTOR (array)->size;
1353 return size;
1354}
1355\f
1356/* Arithmetic functions */
1357
1358enum comparison { equal, notequal, less, grtr, less_or_equal, grtr_or_equal };
1359
1360Lisp_Object
1361arithcompare (num1, num2, comparison)
1362 Lisp_Object num1, num2;
1363 enum comparison comparison;
1364{
1365 double f1, f2;
1366 int floatp = 0;
1367
1368#ifdef LISP_FLOAT_TYPE
1369 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1370 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 0);
1371
1372 if (XTYPE (num1) == Lisp_Float || XTYPE (num2) == Lisp_Float)
1373 {
1374 floatp = 1;
1375 f1 = (XTYPE (num1) == Lisp_Float) ? XFLOAT (num1)->data : XINT (num1);
1376 f2 = (XTYPE (num2) == Lisp_Float) ? XFLOAT (num2)->data : XINT (num2);
1377 }
1378#else
1379 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1380 CHECK_NUMBER_COERCE_MARKER (num2, 0);
1381#endif /* LISP_FLOAT_TYPE */
1382
1383 switch (comparison)
1384 {
1385 case equal:
1386 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
1387 return Qt;
1388 return Qnil;
1389
1390 case notequal:
1391 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
1392 return Qt;
1393 return Qnil;
1394
1395 case less:
1396 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
1397 return Qt;
1398 return Qnil;
1399
1400 case less_or_equal:
1401 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
1402 return Qt;
1403 return Qnil;
1404
1405 case grtr:
1406 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
1407 return Qt;
1408 return Qnil;
1409
1410 case grtr_or_equal:
1411 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
1412 return Qt;
1413 return Qnil;
25e40a4b
JB
1414
1415 default:
1416 abort ();
7921925c
JB
1417 }
1418}
1419
1420DEFUN ("=", Feqlsign, Seqlsign, 2, 2, 0,
1421 "T if two args, both numbers or markers, are equal.")
1422 (num1, num2)
1423 register Lisp_Object num1, num2;
1424{
1425 return arithcompare (num1, num2, equal);
1426}
1427
1428DEFUN ("<", Flss, Slss, 2, 2, 0,
1429 "T if first arg is less than second arg. Both must be numbers or markers.")
1430 (num1, num2)
1431 register Lisp_Object num1, num2;
1432{
1433 return arithcompare (num1, num2, less);
1434}
1435
1436DEFUN (">", Fgtr, Sgtr, 2, 2, 0,
1437 "T if first arg is greater than second arg. Both must be numbers or markers.")
1438 (num1, num2)
1439 register Lisp_Object num1, num2;
1440{
1441 return arithcompare (num1, num2, grtr);
1442}
1443
1444DEFUN ("<=", Fleq, Sleq, 2, 2, 0,
1445 "T if first arg is less than or equal to second arg.\n\
1446Both must be numbers or markers.")
1447 (num1, num2)
1448 register Lisp_Object num1, num2;
1449{
1450 return arithcompare (num1, num2, less_or_equal);
1451}
1452
1453DEFUN (">=", Fgeq, Sgeq, 2, 2, 0,
1454 "T if first arg is greater than or equal to second arg.\n\
1455Both must be numbers or markers.")
1456 (num1, num2)
1457 register Lisp_Object num1, num2;
1458{
1459 return arithcompare (num1, num2, grtr_or_equal);
1460}
1461
1462DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
1463 "T if first arg is not equal to second arg. Both must be numbers or markers.")
1464 (num1, num2)
1465 register Lisp_Object num1, num2;
1466{
1467 return arithcompare (num1, num2, notequal);
1468}
1469
1470DEFUN ("zerop", Fzerop, Szerop, 1, 1, 0, "T if NUMBER is zero.")
1471 (num)
1472 register Lisp_Object num;
1473{
1474#ifdef LISP_FLOAT_TYPE
1475 CHECK_NUMBER_OR_FLOAT (num, 0);
1476
1477 if (XTYPE(num) == Lisp_Float)
1478 {
1479 if (XFLOAT(num)->data == 0.0)
1480 return Qt;
1481 return Qnil;
1482 }
1483#else
1484 CHECK_NUMBER (num, 0);
1485#endif /* LISP_FLOAT_TYPE */
1486
1487 if (!XINT (num))
1488 return Qt;
1489 return Qnil;
1490}
1491\f
51cf3e31
JB
1492/* Convert between 32-bit values and pairs of lispy 24-bit values. */
1493
1494Lisp_Object
1495long_to_cons (i)
1496 unsigned long i;
1497{
1498 unsigned int top = i >> 16;
1499 unsigned int bot = i & 0xFFFF;
1500 if (top == 0)
1501 return make_number (bot);
1502 if (top == 0xFFFF)
1503 return Fcons (make_number (-1), make_number (bot));
1504 return Fcons (make_number (top), make_number (bot));
1505}
1506
1507unsigned long
1508cons_to_long (c)
1509 Lisp_Object c;
1510{
878a80cc 1511 Lisp_Object top, bot;
51cf3e31
JB
1512 if (INTEGERP (c))
1513 return XINT (c);
1514 top = XCONS (c)->car;
1515 bot = XCONS (c)->cdr;
1516 if (CONSP (bot))
1517 bot = XCONS (bot)->car;
1518 return ((XINT (top) << 16) | XINT (bot));
1519}
1520\f
f2980264 1521DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
25e40a4b
JB
1522 "Convert NUM to a string by printing it in decimal.\n\
1523Uses a minus sign if negative.\n\
1524NUM may be an integer or a floating point number.")
7921925c
JB
1525 (num)
1526 Lisp_Object num;
1527{
1528 char buffer[20];
1529
1530#ifndef LISP_FLOAT_TYPE
1531 CHECK_NUMBER (num, 0);
1532#else
1533 CHECK_NUMBER_OR_FLOAT (num, 0);
1534
1535 if (XTYPE(num) == Lisp_Float)
1536 {
1537 char pigbuf[350]; /* see comments in float_to_string */
1538
1539 float_to_string (pigbuf, XFLOAT(num)->data);
1540 return build_string (pigbuf);
1541 }
1542#endif /* LISP_FLOAT_TYPE */
1543
1544 sprintf (buffer, "%d", XINT (num));
1545 return build_string (buffer);
1546}
1547
25e40a4b
JB
1548DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 1, 0,
1549 "Convert STRING to a number by parsing it as a decimal number.\n\
1550This parses both integers and floating point numbers.")
7921925c
JB
1551 (str)
1552 register Lisp_Object str;
1553{
0a3e4d65 1554 unsigned char *p;
25e40a4b 1555
7921925c
JB
1556 CHECK_STRING (str, 0);
1557
25e40a4b
JB
1558 p = XSTRING (str)->data;
1559
1560 /* Skip any whitespace at the front of the number. Some versions of
1561 atoi do this anyway, so we might as well make Emacs lisp consistent. */
0a3e4d65 1562 while (*p == ' ' || *p == '\t')
25e40a4b
JB
1563 p++;
1564
7921925c 1565#ifdef LISP_FLOAT_TYPE
25e40a4b
JB
1566 if (isfloat_string (p))
1567 return make_float (atof (p));
7921925c
JB
1568#endif /* LISP_FLOAT_TYPE */
1569
25e40a4b 1570 return make_number (atoi (p));
7921925c
JB
1571}
1572\f
1573enum arithop
1574 { Aadd, Asub, Amult, Adiv, Alogand, Alogior, Alogxor, Amax, Amin };
1575
b06faa91
JB
1576extern Lisp_Object float_arith_driver ();
1577
7921925c 1578Lisp_Object
87fbf902 1579arith_driver (code, nargs, args)
7921925c
JB
1580 enum arithop code;
1581 int nargs;
1582 register Lisp_Object *args;
1583{
1584 register Lisp_Object val;
1585 register int argnum;
1586 register int accum;
1587 register int next;
1588
1589#ifdef SWITCH_ENUM_BUG
1590 switch ((int) code)
1591#else
1592 switch (code)
1593#endif
1594 {
1595 case Alogior:
1596 case Alogxor:
1597 case Aadd:
1598 case Asub:
1599 accum = 0; break;
1600 case Amult:
1601 accum = 1; break;
1602 case Alogand:
1603 accum = -1; break;
1604 }
1605
1606 for (argnum = 0; argnum < nargs; argnum++)
1607 {
1608 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
1609#ifdef LISP_FLOAT_TYPE
1610 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
1611
1612 if (XTYPE (val) == Lisp_Float) /* time to do serious math */
1613 return (float_arith_driver ((double) accum, argnum, code,
1614 nargs, args));
1615#else
1616 CHECK_NUMBER_COERCE_MARKER (val, argnum);
1617#endif /* LISP_FLOAT_TYPE */
1618 args[argnum] = val; /* runs into a compiler bug. */
1619 next = XINT (args[argnum]);
1620#ifdef SWITCH_ENUM_BUG
1621 switch ((int) code)
1622#else
1623 switch (code)
1624#endif
1625 {
1626 case Aadd: accum += next; break;
1627 case Asub:
1628 if (!argnum && nargs != 1)
1629 next = - next;
1630 accum -= next;
1631 break;
1632 case Amult: accum *= next; break;
1633 case Adiv:
1634 if (!argnum) accum = next;
87fbf902
RS
1635 else
1636 {
1637 if (next == 0)
1638 Fsignal (Qarith_error, Qnil);
1639 accum /= next;
1640 }
7921925c
JB
1641 break;
1642 case Alogand: accum &= next; break;
1643 case Alogior: accum |= next; break;
1644 case Alogxor: accum ^= next; break;
1645 case Amax: if (!argnum || next > accum) accum = next; break;
1646 case Amin: if (!argnum || next < accum) accum = next; break;
1647 }
1648 }
1649
1650 XSET (val, Lisp_Int, accum);
1651 return val;
1652}
1653
1654#ifdef LISP_FLOAT_TYPE
1a2f2d33
KH
1655
1656#undef isnan
1657#define isnan(x) ((x) != (x))
1658
7921925c
JB
1659Lisp_Object
1660float_arith_driver (accum, argnum, code, nargs, args)
1661 double accum;
1662 register int argnum;
1663 enum arithop code;
1664 int nargs;
1665 register Lisp_Object *args;
1666{
1667 register Lisp_Object val;
1668 double next;
1669
1670 for (; argnum < nargs; argnum++)
1671 {
1672 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
1673 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val, argnum);
1674
1675 if (XTYPE (val) == Lisp_Float)
1676 {
1677 next = XFLOAT (val)->data;
1678 }
1679 else
1680 {
1681 args[argnum] = val; /* runs into a compiler bug. */
1682 next = XINT (args[argnum]);
1683 }
1684#ifdef SWITCH_ENUM_BUG
1685 switch ((int) code)
1686#else
1687 switch (code)
1688#endif
1689 {
1690 case Aadd:
1691 accum += next;
1692 break;
1693 case Asub:
1694 if (!argnum && nargs != 1)
1695 next = - next;
1696 accum -= next;
1697 break;
1698 case Amult:
1699 accum *= next;
1700 break;
1701 case Adiv:
1702 if (!argnum)
1703 accum = next;
1704 else
87fbf902
RS
1705 {
1706 if (next == 0)
1707 Fsignal (Qarith_error, Qnil);
1708 accum /= next;
1709 }
7921925c
JB
1710 break;
1711 case Alogand:
1712 case Alogior:
1713 case Alogxor:
1714 return wrong_type_argument (Qinteger_or_marker_p, val);
1715 case Amax:
1a2f2d33 1716 if (!argnum || isnan (next) || next > accum)
7921925c
JB
1717 accum = next;
1718 break;
1719 case Amin:
1a2f2d33 1720 if (!argnum || isnan (next) || next < accum)
7921925c
JB
1721 accum = next;
1722 break;
1723 }
1724 }
1725
1726 return make_float (accum);
1727}
1728#endif /* LISP_FLOAT_TYPE */
1729
1730DEFUN ("+", Fplus, Splus, 0, MANY, 0,
1731 "Return sum of any number of arguments, which are numbers or markers.")
1732 (nargs, args)
1733 int nargs;
1734 Lisp_Object *args;
1735{
1736 return arith_driver (Aadd, nargs, args);
1737}
1738
1739DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
1740 "Negate number or subtract numbers or markers.\n\
1741With one arg, negates it. With more than one arg,\n\
1742subtracts all but the first from the first.")
1743 (nargs, args)
1744 int nargs;
1745 Lisp_Object *args;
1746{
1747 return arith_driver (Asub, nargs, args);
1748}
1749
1750DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
1751 "Returns product of any number of arguments, which are numbers or markers.")
1752 (nargs, args)
1753 int nargs;
1754 Lisp_Object *args;
1755{
1756 return arith_driver (Amult, nargs, args);
1757}
1758
1759DEFUN ("/", Fquo, Squo, 2, MANY, 0,
1760 "Returns first argument divided by all the remaining arguments.\n\
1761The arguments must be numbers or markers.")
1762 (nargs, args)
1763 int nargs;
1764 Lisp_Object *args;
1765{
1766 return arith_driver (Adiv, nargs, args);
1767}
1768
1769DEFUN ("%", Frem, Srem, 2, 2, 0,
1770 "Returns remainder of first arg divided by second.\n\
aa29f9b9 1771Both must be integers or markers.")
7921925c
JB
1772 (num1, num2)
1773 register Lisp_Object num1, num2;
1774{
1775 Lisp_Object val;
1776
7921925c
JB
1777 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1778 CHECK_NUMBER_COERCE_MARKER (num2, 1);
7921925c 1779
87fbf902
RS
1780 if (XFASTINT (num2) == 0)
1781 Fsignal (Qarith_error, Qnil);
1782
7921925c
JB
1783 XSET (val, Lisp_Int, XINT (num1) % XINT (num2));
1784 return val;
1785}
1786
1d66a5fa
KH
1787#ifndef HAVE_FMOD
1788double
1789fmod (f1, f2)
1790 double f1, f2;
1791{
1792#ifdef HAVE_DREM /* Some systems use this non-standard name. */
1793 return (drem (f1, f2));
1794#else /* Other systems don't seem to have it at all. */
1795 return (f1 - f2 * floor (f1/f2));
1796#endif
1797}
1798#endif /* ! HAVE_FMOD */
1799
44fa9da5
PE
1800DEFUN ("mod", Fmod, Smod, 2, 2, 0,
1801 "Returns X modulo Y.\n\
1802The result falls between zero (inclusive) and Y (exclusive).\n\
1803Both X and Y must be numbers or markers.")
1804 (num1, num2)
1805 register Lisp_Object num1, num2;
1806{
1807 Lisp_Object val;
1808 int i1, i2;
1809
1810#ifdef LISP_FLOAT_TYPE
1811 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1, 0);
1812 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2, 1);
1813
1814 if (XTYPE (num1) == Lisp_Float || XTYPE (num2) == Lisp_Float)
1815 {
1816 double f1, f2;
1817
1818 f1 = XTYPE (num1) == Lisp_Float ? XFLOAT (num1)->data : XINT (num1);
1819 f2 = XTYPE (num2) == Lisp_Float ? XFLOAT (num2)->data : XINT (num2);
1820 if (f2 == 0)
1821 Fsignal (Qarith_error, Qnil);
1822
44fa9da5 1823 f1 = fmod (f1, f2);
44fa9da5
PE
1824 /* If the "remainder" comes out with the wrong sign, fix it. */
1825 if ((f1 < 0) != (f2 < 0))
1826 f1 += f2;
1827 return (make_float (f1));
1828 }
1829#else /* not LISP_FLOAT_TYPE */
1830 CHECK_NUMBER_COERCE_MARKER (num1, 0);
1831 CHECK_NUMBER_COERCE_MARKER (num2, 1);
1832#endif /* not LISP_FLOAT_TYPE */
1833
1834 i1 = XINT (num1);
1835 i2 = XINT (num2);
1836
1837 if (i2 == 0)
1838 Fsignal (Qarith_error, Qnil);
1839
1840 i1 %= i2;
1841
1842 /* If the "remainder" comes out with the wrong sign, fix it. */
1843 if ((i1 < 0) != (i2 < 0))
1844 i1 += i2;
1845
1846 XSET (val, Lisp_Int, i1);
1847 return val;
1848}
1849
7921925c
JB
1850DEFUN ("max", Fmax, Smax, 1, MANY, 0,
1851 "Return largest of all the arguments (which must be numbers or markers).\n\
1852The value is always a number; markers are converted to numbers.")
1853 (nargs, args)
1854 int nargs;
1855 Lisp_Object *args;
1856{
1857 return arith_driver (Amax, nargs, args);
1858}
1859
1860DEFUN ("min", Fmin, Smin, 1, MANY, 0,
1861 "Return smallest of all the arguments (which must be numbers or markers).\n\
1862The value is always a number; markers are converted to numbers.")
1863 (nargs, args)
1864 int nargs;
1865 Lisp_Object *args;
1866{
1867 return arith_driver (Amin, nargs, args);
1868}
1869
1870DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
1871 "Return bitwise-and of all the arguments.\n\
1872Arguments may be integers, or markers converted to integers.")
1873 (nargs, args)
1874 int nargs;
1875 Lisp_Object *args;
1876{
1877 return arith_driver (Alogand, nargs, args);
1878}
1879
1880DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
1881 "Return bitwise-or of all the arguments.\n\
1882Arguments may be integers, or markers converted to integers.")
1883 (nargs, args)
1884 int nargs;
1885 Lisp_Object *args;
1886{
1887 return arith_driver (Alogior, nargs, args);
1888}
1889
1890DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
1891 "Return bitwise-exclusive-or of all the arguments.\n\
1892Arguments may be integers, or markers converted to integers.")
1893 (nargs, args)
1894 int nargs;
1895 Lisp_Object *args;
1896{
1897 return arith_driver (Alogxor, nargs, args);
1898}
1899
1900DEFUN ("ash", Fash, Sash, 2, 2, 0,
1901 "Return VALUE with its bits shifted left by COUNT.\n\
1902If COUNT is negative, shifting is actually to the right.\n\
1903In this case, the sign bit is duplicated.")
1904 (num1, num2)
1905 register Lisp_Object num1, num2;
1906{
1907 register Lisp_Object val;
1908
1909 CHECK_NUMBER (num1, 0);
1910 CHECK_NUMBER (num2, 1);
1911
1912 if (XINT (num2) > 0)
1913 XSET (val, Lisp_Int, XINT (num1) << XFASTINT (num2));
1914 else
1915 XSET (val, Lisp_Int, XINT (num1) >> -XINT (num2));
1916 return val;
1917}
1918
1919DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
1920 "Return VALUE with its bits shifted left by COUNT.\n\
1921If COUNT is negative, shifting is actually to the right.\n\
1922In this case, zeros are shifted in on the left.")
1923 (num1, num2)
1924 register Lisp_Object num1, num2;
1925{
1926 register Lisp_Object val;
1927
1928 CHECK_NUMBER (num1, 0);
1929 CHECK_NUMBER (num2, 1);
1930
1931 if (XINT (num2) > 0)
1932 XSET (val, Lisp_Int, (unsigned) XFASTINT (num1) << XFASTINT (num2));
1933 else
1934 XSET (val, Lisp_Int, (unsigned) XFASTINT (num1) >> -XINT (num2));
1935 return val;
1936}
1937
1938DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
1939 "Return NUMBER plus one. NUMBER may be a number or a marker.\n\
1940Markers are converted to integers.")
1941 (num)
1942 register Lisp_Object num;
1943{
1944#ifdef LISP_FLOAT_TYPE
1945 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num, 0);
1946
1947 if (XTYPE (num) == Lisp_Float)
1948 return (make_float (1.0 + XFLOAT (num)->data));
1949#else
1950 CHECK_NUMBER_COERCE_MARKER (num, 0);
1951#endif /* LISP_FLOAT_TYPE */
1952
1953 XSETINT (num, XFASTINT (num) + 1);
1954 return num;
1955}
1956
1957DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
1958 "Return NUMBER minus one. NUMBER may be a number or a marker.\n\
1959Markers are converted to integers.")
1960 (num)
1961 register Lisp_Object num;
1962{
1963#ifdef LISP_FLOAT_TYPE
1964 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num, 0);
1965
1966 if (XTYPE (num) == Lisp_Float)
1967 return (make_float (-1.0 + XFLOAT (num)->data));
1968#else
1969 CHECK_NUMBER_COERCE_MARKER (num, 0);
1970#endif /* LISP_FLOAT_TYPE */
1971
1972 XSETINT (num, XFASTINT (num) - 1);
1973 return num;
1974}
1975
1976DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
1977 "Return the bitwise complement of ARG. ARG must be an integer.")
1978 (num)
1979 register Lisp_Object num;
1980{
1981 CHECK_NUMBER (num, 0);
1982 XSETINT (num, ~XFASTINT (num));
1983 return num;
1984}
1985\f
1986void
1987syms_of_data ()
1988{
6315e761
RS
1989 Lisp_Object error_tail, arith_tail;
1990
7921925c
JB
1991 Qquote = intern ("quote");
1992 Qlambda = intern ("lambda");
1993 Qsubr = intern ("subr");
1994 Qerror_conditions = intern ("error-conditions");
1995 Qerror_message = intern ("error-message");
1996 Qtop_level = intern ("top-level");
1997
1998 Qerror = intern ("error");
1999 Qquit = intern ("quit");
2000 Qwrong_type_argument = intern ("wrong-type-argument");
2001 Qargs_out_of_range = intern ("args-out-of-range");
2002 Qvoid_function = intern ("void-function");
ffd56f97 2003 Qcyclic_function_indirection = intern ("cyclic-function-indirection");
7921925c
JB
2004 Qvoid_variable = intern ("void-variable");
2005 Qsetting_constant = intern ("setting-constant");
2006 Qinvalid_read_syntax = intern ("invalid-read-syntax");
2007
2008 Qinvalid_function = intern ("invalid-function");
2009 Qwrong_number_of_arguments = intern ("wrong-number-of-arguments");
2010 Qno_catch = intern ("no-catch");
2011 Qend_of_file = intern ("end-of-file");
2012 Qarith_error = intern ("arith-error");
2013 Qbeginning_of_buffer = intern ("beginning-of-buffer");
2014 Qend_of_buffer = intern ("end-of-buffer");
2015 Qbuffer_read_only = intern ("buffer-read-only");
3b8819d6 2016 Qmark_inactive = intern ("mark-inactive");
7921925c
JB
2017
2018 Qlistp = intern ("listp");
2019 Qconsp = intern ("consp");
2020 Qsymbolp = intern ("symbolp");
2021 Qintegerp = intern ("integerp");
2022 Qnatnump = intern ("natnump");
2023 Qstringp = intern ("stringp");
2024 Qarrayp = intern ("arrayp");
2025 Qsequencep = intern ("sequencep");
2026 Qbufferp = intern ("bufferp");
2027 Qvectorp = intern ("vectorp");
2028 Qchar_or_string_p = intern ("char-or-string-p");
2029 Qmarkerp = intern ("markerp");
07bd8472 2030 Qbuffer_or_string_p = intern ("buffer-or-string-p");
7921925c
JB
2031 Qinteger_or_marker_p = intern ("integer-or-marker-p");
2032 Qboundp = intern ("boundp");
2033 Qfboundp = intern ("fboundp");
2034
2035#ifdef LISP_FLOAT_TYPE
2036 Qfloatp = intern ("floatp");
2037 Qnumberp = intern ("numberp");
2038 Qnumber_or_marker_p = intern ("number-or-marker-p");
2039#endif /* LISP_FLOAT_TYPE */
2040
2041 Qcdr = intern ("cdr");
2042
6315e761
RS
2043 error_tail = Fcons (Qerror, Qnil);
2044
7921925c
JB
2045 /* ERROR is used as a signaler for random errors for which nothing else is right */
2046
2047 Fput (Qerror, Qerror_conditions,
6315e761 2048 error_tail);
7921925c
JB
2049 Fput (Qerror, Qerror_message,
2050 build_string ("error"));
2051
2052 Fput (Qquit, Qerror_conditions,
2053 Fcons (Qquit, Qnil));
2054 Fput (Qquit, Qerror_message,
2055 build_string ("Quit"));
2056
2057 Fput (Qwrong_type_argument, Qerror_conditions,
6315e761 2058 Fcons (Qwrong_type_argument, error_tail));
7921925c
JB
2059 Fput (Qwrong_type_argument, Qerror_message,
2060 build_string ("Wrong type argument"));
2061
2062 Fput (Qargs_out_of_range, Qerror_conditions,
6315e761 2063 Fcons (Qargs_out_of_range, error_tail));
7921925c
JB
2064 Fput (Qargs_out_of_range, Qerror_message,
2065 build_string ("Args out of range"));
2066
2067 Fput (Qvoid_function, Qerror_conditions,
6315e761 2068 Fcons (Qvoid_function, error_tail));
7921925c
JB
2069 Fput (Qvoid_function, Qerror_message,
2070 build_string ("Symbol's function definition is void"));
2071
ffd56f97 2072 Fput (Qcyclic_function_indirection, Qerror_conditions,
6315e761 2073 Fcons (Qcyclic_function_indirection, error_tail));
ffd56f97
JB
2074 Fput (Qcyclic_function_indirection, Qerror_message,
2075 build_string ("Symbol's chain of function indirections contains a loop"));
2076
7921925c 2077 Fput (Qvoid_variable, Qerror_conditions,
6315e761 2078 Fcons (Qvoid_variable, error_tail));
7921925c
JB
2079 Fput (Qvoid_variable, Qerror_message,
2080 build_string ("Symbol's value as variable is void"));
2081
2082 Fput (Qsetting_constant, Qerror_conditions,
6315e761 2083 Fcons (Qsetting_constant, error_tail));
7921925c
JB
2084 Fput (Qsetting_constant, Qerror_message,
2085 build_string ("Attempt to set a constant symbol"));
2086
2087 Fput (Qinvalid_read_syntax, Qerror_conditions,
6315e761 2088 Fcons (Qinvalid_read_syntax, error_tail));
7921925c
JB
2089 Fput (Qinvalid_read_syntax, Qerror_message,
2090 build_string ("Invalid read syntax"));
2091
2092 Fput (Qinvalid_function, Qerror_conditions,
6315e761 2093 Fcons (Qinvalid_function, error_tail));
7921925c
JB
2094 Fput (Qinvalid_function, Qerror_message,
2095 build_string ("Invalid function"));
2096
2097 Fput (Qwrong_number_of_arguments, Qerror_conditions,
6315e761 2098 Fcons (Qwrong_number_of_arguments, error_tail));
7921925c
JB
2099 Fput (Qwrong_number_of_arguments, Qerror_message,
2100 build_string ("Wrong number of arguments"));
2101
2102 Fput (Qno_catch, Qerror_conditions,
6315e761 2103 Fcons (Qno_catch, error_tail));
7921925c
JB
2104 Fput (Qno_catch, Qerror_message,
2105 build_string ("No catch for tag"));
2106
2107 Fput (Qend_of_file, Qerror_conditions,
6315e761 2108 Fcons (Qend_of_file, error_tail));
7921925c
JB
2109 Fput (Qend_of_file, Qerror_message,
2110 build_string ("End of file during parsing"));
2111
6315e761 2112 arith_tail = Fcons (Qarith_error, error_tail);
7921925c 2113 Fput (Qarith_error, Qerror_conditions,
6315e761 2114 arith_tail);
7921925c
JB
2115 Fput (Qarith_error, Qerror_message,
2116 build_string ("Arithmetic error"));
2117
2118 Fput (Qbeginning_of_buffer, Qerror_conditions,
6315e761 2119 Fcons (Qbeginning_of_buffer, error_tail));
7921925c
JB
2120 Fput (Qbeginning_of_buffer, Qerror_message,
2121 build_string ("Beginning of buffer"));
2122
2123 Fput (Qend_of_buffer, Qerror_conditions,
6315e761 2124 Fcons (Qend_of_buffer, error_tail));
7921925c
JB
2125 Fput (Qend_of_buffer, Qerror_message,
2126 build_string ("End of buffer"));
2127
2128 Fput (Qbuffer_read_only, Qerror_conditions,
6315e761 2129 Fcons (Qbuffer_read_only, error_tail));
7921925c
JB
2130 Fput (Qbuffer_read_only, Qerror_message,
2131 build_string ("Buffer is read-only"));
2132
6315e761
RS
2133#ifdef LISP_FLOAT_TYPE
2134 Qrange_error = intern ("range-error");
2135 Qdomain_error = intern ("domain-error");
2136 Qsingularity_error = intern ("singularity-error");
2137 Qoverflow_error = intern ("overflow-error");
2138 Qunderflow_error = intern ("underflow-error");
2139
2140 Fput (Qdomain_error, Qerror_conditions,
2141 Fcons (Qdomain_error, arith_tail));
2142 Fput (Qdomain_error, Qerror_message,
2143 build_string ("Arithmetic domain error"));
2144
2145 Fput (Qrange_error, Qerror_conditions,
2146 Fcons (Qrange_error, arith_tail));
2147 Fput (Qrange_error, Qerror_message,
2148 build_string ("Arithmetic range error"));
2149
2150 Fput (Qsingularity_error, Qerror_conditions,
2151 Fcons (Qsingularity_error, Fcons (Qdomain_error, arith_tail)));
2152 Fput (Qsingularity_error, Qerror_message,
2153 build_string ("Arithmetic singularity error"));
2154
2155 Fput (Qoverflow_error, Qerror_conditions,
2156 Fcons (Qoverflow_error, Fcons (Qdomain_error, arith_tail)));
2157 Fput (Qoverflow_error, Qerror_message,
2158 build_string ("Arithmetic overflow error"));
2159
2160 Fput (Qunderflow_error, Qerror_conditions,
2161 Fcons (Qunderflow_error, Fcons (Qdomain_error, arith_tail)));
2162 Fput (Qunderflow_error, Qerror_message,
2163 build_string ("Arithmetic underflow error"));
2164
2165 staticpro (&Qrange_error);
2166 staticpro (&Qdomain_error);
2167 staticpro (&Qsingularity_error);
2168 staticpro (&Qoverflow_error);
2169 staticpro (&Qunderflow_error);
2170#endif /* LISP_FLOAT_TYPE */
2171
7921925c
JB
2172 staticpro (&Qnil);
2173 staticpro (&Qt);
2174 staticpro (&Qquote);
2175 staticpro (&Qlambda);
2176 staticpro (&Qsubr);
2177 staticpro (&Qunbound);
2178 staticpro (&Qerror_conditions);
2179 staticpro (&Qerror_message);
2180 staticpro (&Qtop_level);
2181
2182 staticpro (&Qerror);
2183 staticpro (&Qquit);
2184 staticpro (&Qwrong_type_argument);
2185 staticpro (&Qargs_out_of_range);
2186 staticpro (&Qvoid_function);
ffd56f97 2187 staticpro (&Qcyclic_function_indirection);
7921925c
JB
2188 staticpro (&Qvoid_variable);
2189 staticpro (&Qsetting_constant);
2190 staticpro (&Qinvalid_read_syntax);
2191 staticpro (&Qwrong_number_of_arguments);
2192 staticpro (&Qinvalid_function);
2193 staticpro (&Qno_catch);
2194 staticpro (&Qend_of_file);
2195 staticpro (&Qarith_error);
2196 staticpro (&Qbeginning_of_buffer);
2197 staticpro (&Qend_of_buffer);
2198 staticpro (&Qbuffer_read_only);
638b77e6 2199 staticpro (&Qmark_inactive);
7921925c
JB
2200
2201 staticpro (&Qlistp);
2202 staticpro (&Qconsp);
2203 staticpro (&Qsymbolp);
2204 staticpro (&Qintegerp);
2205 staticpro (&Qnatnump);
2206 staticpro (&Qstringp);
2207 staticpro (&Qarrayp);
2208 staticpro (&Qsequencep);
2209 staticpro (&Qbufferp);
2210 staticpro (&Qvectorp);
2211 staticpro (&Qchar_or_string_p);
2212 staticpro (&Qmarkerp);
07bd8472 2213 staticpro (&Qbuffer_or_string_p);
7921925c
JB
2214 staticpro (&Qinteger_or_marker_p);
2215#ifdef LISP_FLOAT_TYPE
2216 staticpro (&Qfloatp);
464f8898
RS
2217 staticpro (&Qnumberp);
2218 staticpro (&Qnumber_or_marker_p);
7921925c
JB
2219#endif /* LISP_FLOAT_TYPE */
2220
2221 staticpro (&Qboundp);
2222 staticpro (&Qfboundp);
2223 staticpro (&Qcdr);
2224
2225 defsubr (&Seq);
2226 defsubr (&Snull);
2227 defsubr (&Slistp);
2228 defsubr (&Snlistp);
2229 defsubr (&Sconsp);
2230 defsubr (&Satom);
2231 defsubr (&Sintegerp);
464f8898 2232 defsubr (&Sinteger_or_marker_p);
7921925c
JB
2233 defsubr (&Snumberp);
2234 defsubr (&Snumber_or_marker_p);
464f8898
RS
2235#ifdef LISP_FLOAT_TYPE
2236 defsubr (&Sfloatp);
7921925c
JB
2237#endif /* LISP_FLOAT_TYPE */
2238 defsubr (&Snatnump);
2239 defsubr (&Ssymbolp);
2240 defsubr (&Sstringp);
2241 defsubr (&Svectorp);
2242 defsubr (&Sarrayp);
2243 defsubr (&Ssequencep);
2244 defsubr (&Sbufferp);
2245 defsubr (&Smarkerp);
7921925c 2246 defsubr (&Ssubrp);
dbc4e1c1 2247 defsubr (&Sbyte_code_function_p);
7921925c
JB
2248 defsubr (&Schar_or_string_p);
2249 defsubr (&Scar);
2250 defsubr (&Scdr);
2251 defsubr (&Scar_safe);
2252 defsubr (&Scdr_safe);
2253 defsubr (&Ssetcar);
2254 defsubr (&Ssetcdr);
2255 defsubr (&Ssymbol_function);
ffd56f97 2256 defsubr (&Sindirect_function);
7921925c
JB
2257 defsubr (&Ssymbol_plist);
2258 defsubr (&Ssymbol_name);
2259 defsubr (&Smakunbound);
2260 defsubr (&Sfmakunbound);
2261 defsubr (&Sboundp);
2262 defsubr (&Sfboundp);
2263 defsubr (&Sfset);
80df38a2 2264 defsubr (&Sdefalias);
d9bcdb34 2265 defsubr (&Sdefine_function);
7921925c
JB
2266 defsubr (&Ssetplist);
2267 defsubr (&Ssymbol_value);
2268 defsubr (&Sset);
2269 defsubr (&Sdefault_boundp);
2270 defsubr (&Sdefault_value);
2271 defsubr (&Sset_default);
2272 defsubr (&Ssetq_default);
2273 defsubr (&Smake_variable_buffer_local);
2274 defsubr (&Smake_local_variable);
2275 defsubr (&Skill_local_variable);
2276 defsubr (&Saref);
2277 defsubr (&Saset);
f2980264 2278 defsubr (&Snumber_to_string);
25e40a4b 2279 defsubr (&Sstring_to_number);
7921925c
JB
2280 defsubr (&Seqlsign);
2281 defsubr (&Slss);
2282 defsubr (&Sgtr);
2283 defsubr (&Sleq);
2284 defsubr (&Sgeq);
2285 defsubr (&Sneq);
2286 defsubr (&Szerop);
2287 defsubr (&Splus);
2288 defsubr (&Sminus);
2289 defsubr (&Stimes);
2290 defsubr (&Squo);
2291 defsubr (&Srem);
44fa9da5 2292 defsubr (&Smod);
7921925c
JB
2293 defsubr (&Smax);
2294 defsubr (&Smin);
2295 defsubr (&Slogand);
2296 defsubr (&Slogior);
2297 defsubr (&Slogxor);
2298 defsubr (&Slsh);
2299 defsubr (&Sash);
2300 defsubr (&Sadd1);
2301 defsubr (&Ssub1);
2302 defsubr (&Slognot);
2303}
2304
a33ef3ab 2305SIGTYPE
7921925c
JB
2306arith_error (signo)
2307 int signo;
2308{
2309#ifdef USG
2310 /* USG systems forget handlers when they are used;
2311 must reestablish each time */
2312 signal (signo, arith_error);
2313#endif /* USG */
2314#ifdef VMS
2315 /* VMS systems are like USG. */
2316 signal (signo, arith_error);
2317#endif /* VMS */
2318#ifdef BSD4_1
2319 sigrelse (SIGFPE);
2320#else /* not BSD4_1 */
e065a56e 2321 sigsetmask (SIGEMPTYMASK);
7921925c
JB
2322#endif /* not BSD4_1 */
2323
2324 Fsignal (Qarith_error, Qnil);
2325}
2326
2327init_data ()
2328{
2329 /* Don't do this if just dumping out.
2330 We don't want to call `signal' in this case
2331 so that we don't have trouble with dumping
2332 signal-delivering routines in an inconsistent state. */
2333#ifndef CANNOT_DUMP
2334 if (!initialized)
2335 return;
2336#endif /* CANNOT_DUMP */
2337 signal (SIGFPE, arith_error);
f58b3686 2338
7921925c
JB
2339#ifdef uts
2340 signal (SIGEMT, arith_error);
2341#endif /* uts */
2342}