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