guile-elisp bootstrap part (C)
[bpt/emacs.git] / src / data.c
CommitLineData
7921925c 1/* Primitive operations on Lisp data types for GNU Emacs Lisp interpreter.
ba318903 2 Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2014 Free Software
ab422c4d 3 Foundation, Inc.
7921925c
JB
4
5This file is part of GNU Emacs.
6
9ec0b715 7GNU Emacs is free software: you can redistribute it and/or modify
7921925c 8it under the terms of the GNU General Public License as published by
9ec0b715
GM
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
7921925c
JB
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
9ec0b715 18along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
7921925c
JB
19
20
18160b98 21#include <config.h>
dd8daec5 22#include <stdio.h>
0ae6bdee 23
4eed3157 24#include <byteswap.h>
595e113b
PE
25#include <count-one-bits.h>
26#include <count-trailing-zeros.h>
0ae6bdee
PE
27#include <intprops.h>
28
7921925c 29#include "lisp.h"
29eab336 30#include "puresize.h"
e6e1f521 31#include "character.h"
7921925c 32#include "buffer.h"
077d751f 33#include "keyboard.h"
b0c2d1c6 34#include "frame.h"
a44804c2 35#include "syssignal.h"
620c53a6 36#include "termhooks.h" /* For FRAME_KBOARD reference in y-or-n-p. */
4e6f2626 37#include "font.h"
61b108cc 38#include "keymap.h"
fb8e9847 39
955cbe7b 40Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
73880000 41Lisp_Object Qnil_, Qt_;
955cbe7b 42static Lisp_Object Qsubr;
7921925c 43Lisp_Object Qerror_conditions, Qerror_message, Qtop_level;
71873e2b 44Lisp_Object Qerror, Quser_error, Qquit, Qargs_out_of_range;
454e2fb9 45static Lisp_Object Qwrong_length_argument;
955cbe7b
PE
46static Lisp_Object Qwrong_type_argument;
47Lisp_Object Qvoid_variable, Qvoid_function;
48static Lisp_Object Qcyclic_function_indirection;
49static Lisp_Object Qcyclic_variable_indirection;
50Lisp_Object Qcircular_list;
51static Lisp_Object Qsetting_constant;
52Lisp_Object Qinvalid_read_syntax;
7921925c 53Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
3b8819d6 54Lisp_Object Qend_of_file, Qarith_error, Qmark_inactive;
7921925c 55Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
8f9f49d7 56Lisp_Object Qtext_read_only;
6b61353c 57
2f1205e0 58Lisp_Object Qintegerp, Qwholenump, Qsymbolp, Qlistp, Qconsp;
955cbe7b 59static Lisp_Object Qnatnump;
7921925c
JB
60Lisp_Object Qstringp, Qarrayp, Qsequencep, Qbufferp;
61Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qvectorp;
3e0b94e7 62Lisp_Object Qbool_vector_p;
955cbe7b
PE
63Lisp_Object Qbuffer_or_string_p;
64static Lisp_Object Qkeywordp, Qboundp;
65Lisp_Object Qfboundp;
7f0edce7 66Lisp_Object Qchar_table_p, Qvector_or_char_table_p;
39bcc759 67
7921925c 68Lisp_Object Qcdr;
955cbe7b 69static Lisp_Object Qad_advice_info, Qad_activate_internal;
7921925c 70
c990426a
PE
71static Lisp_Object Qdomain_error, Qsingularity_error, Qunderflow_error;
72Lisp_Object Qrange_error, Qoverflow_error;
6315e761 73
464f8898 74Lisp_Object Qfloatp;
7921925c 75Lisp_Object Qnumberp, Qnumber_or_marker_p;
7921925c 76
b52d6985
PE
77Lisp_Object Qinteger, Qsymbol;
78static Lisp_Object Qcons, Qfloat, Qmisc, Qstring, Qvector;
e6cba650 79Lisp_Object Qwindow;
3ab6e069
DA
80static Lisp_Object Qoverlay, Qwindow_configuration;
81static Lisp_Object Qprocess, Qmarker;
82static Lisp_Object Qcompiled_function, Qframe;
4b66faf3 83Lisp_Object Qbuffer;
81dc5de5 84static Lisp_Object Qchar_table, Qbool_vector, Qhash_table;
84575e67
PE
85static Lisp_Object Qsubrp;
86static Lisp_Object Qmany, Qunevalled;
4e6f2626 87Lisp_Object Qfont_spec, Qfont_entity, Qfont_object;
61b108cc 88static Lisp_Object Qdefun;
39bcc759 89
62947569 90Lisp_Object Qspecial_operator;
12cc4337
PE
91Lisp_Object Qinteractive_form;
92static Lisp_Object Qdefalias_fset_function;
3860280a 93
844e0de1 94static void swap_in_symval_forwarding (sym_t, struct Lisp_Buffer_Local_Value *);
d02eeab3 95
84575e67
PE
96static bool
97BOOLFWDP (union Lisp_Fwd *a)
98{
99 return XFWDTYPE (a) == Lisp_Fwd_Bool;
100}
101static bool
102INTFWDP (union Lisp_Fwd *a)
103{
104 return XFWDTYPE (a) == Lisp_Fwd_Int;
105}
106static bool
107KBOARD_OBJFWDP (union Lisp_Fwd *a)
108{
109 return XFWDTYPE (a) == Lisp_Fwd_Kboard_Obj;
110}
111static bool
112OBJFWDP (union Lisp_Fwd *a)
113{
114 return XFWDTYPE (a) == Lisp_Fwd_Obj;
115}
116
117static struct Lisp_Boolfwd *
118XBOOLFWD (union Lisp_Fwd *a)
119{
120 eassert (BOOLFWDP (a));
121 return &a->u_boolfwd;
122}
123static struct Lisp_Kboard_Objfwd *
124XKBOARD_OBJFWD (union Lisp_Fwd *a)
125{
126 eassert (KBOARD_OBJFWDP (a));
127 return &a->u_kboard_objfwd;
128}
129static struct Lisp_Intfwd *
130XINTFWD (union Lisp_Fwd *a)
131{
132 eassert (INTFWDP (a));
133 return &a->u_intfwd;
134}
135static struct Lisp_Objfwd *
136XOBJFWD (union Lisp_Fwd *a)
137{
138 eassert (OBJFWDP (a));
139 return &a->u_objfwd;
140}
141
142static void
143CHECK_SUBR (Lisp_Object x)
144{
62947569 145 CHECK_TYPE (! NILP (Fsubrp (x)), Qsubrp, x);
84575e67
PE
146}
147
148static void
149set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found)
150{
151 eassert (found == !EQ (blv->defcell, blv->valcell));
152 blv->found = found;
153}
154
155static Lisp_Object
156blv_value (struct Lisp_Buffer_Local_Value *blv)
157{
158 return XCDR (blv->valcell);
159}
160
161static void
162set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
163{
164 XSETCDR (blv->valcell, val);
165}
166
167static void
168set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
169{
170 blv->where = val;
171}
172
173static void
174set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
175{
176 blv->defcell = val;
177}
178
179static void
180set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val)
181{
182 blv->valcell = val;
183}
13d95cc0 184
454e2fb9
PE
185static _Noreturn void
186wrong_length_argument (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
187{
188 Lisp_Object size1 = make_number (bool_vector_size (a1));
189 Lisp_Object size2 = make_number (bool_vector_size (a2));
190 if (NILP (a3))
191 xsignal2 (Qwrong_length_argument, size1, size2);
192 else
193 xsignal3 (Qwrong_length_argument, size1, size2,
194 make_number (bool_vector_size (a3)));
195}
196
7921925c 197Lisp_Object
971de7fb 198wrong_type_argument (register Lisp_Object predicate, register Lisp_Object value)
7921925c 199{
2de9f71c
SM
200 /* If VALUE is not even a valid Lisp object, we'd want to abort here
201 where we can get a backtrace showing where it came from. We used
202 to try and do that by checking the tagbits, but nowadays all
203 tagbits are potentially valid. */
204 /* if ((unsigned int) XTYPE (value) >= Lisp_Type_Limit)
1088b922 205 * emacs_abort (); */
e1351ff7 206
740ef0b5 207 xsignal2 (Qwrong_type_argument, predicate, value);
7921925c
JB
208}
209
7921925c 210void
971de7fb 211args_out_of_range (Lisp_Object a1, Lisp_Object a2)
7921925c 212{
740ef0b5 213 xsignal2 (Qargs_out_of_range, a1, a2);
7921925c
JB
214}
215
216void
971de7fb 217args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
7921925c 218{
740ef0b5 219 xsignal3 (Qargs_out_of_range, a1, a2, a3);
7921925c
JB
220}
221
7921925c 222\f
61b108cc 223/* Data type predicates. */
7921925c
JB
224
225DEFUN ("eq", Feq, Seq, 2, 2, 0,
8c1a1077 226 doc: /* Return t if the two args are the same Lisp object. */)
5842a27b 227 (Lisp_Object obj1, Lisp_Object obj2)
7921925c
JB
228{
229 if (EQ (obj1, obj2))
230 return Qt;
231 return Qnil;
232}
233
8c1a1077
PJ
234DEFUN ("null", Fnull, Snull, 1, 1, 0,
235 doc: /* Return t if OBJECT is nil. */)
5842a27b 236 (Lisp_Object object)
7921925c 237{
39bcc759 238 if (NILP (object))
7921925c
JB
239 return Qt;
240 return Qnil;
241}
242
39bcc759 243DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0,
8c1a1077
PJ
244 doc: /* Return a symbol representing the type of OBJECT.
245The symbol returned names the object's basic type;
246for example, (type-of 1) returns `integer'. */)
5842a27b 247 (Lisp_Object object)
39bcc759 248{
55a1744a
BT
249 if (INTEGERP (object))
250 return Qinteger;
251 else if (SYMBOLP (object))
252 return Qsymbol;
253 else if (STRINGP (object))
254 return Qstring;
255 else if (CONSP (object))
256 return Qcons;
257 else if (MISCP (object))
39bcc759 258 {
324a6eef 259 switch (XMISCTYPE (object))
39bcc759
RS
260 {
261 case Lisp_Misc_Marker:
262 return Qmarker;
263 case Lisp_Misc_Overlay:
264 return Qoverlay;
265 case Lisp_Misc_Float:
266 return Qfloat;
267 }
1088b922 268 emacs_abort ();
55a1744a
BT
269 }
270 else if (VECTORLIKEP (object))
271 {
8e50cc2d 272 if (WINDOW_CONFIGURATIONP (object))
39bcc759 273 return Qwindow_configuration;
8e50cc2d 274 if (PROCESSP (object))
39bcc759 275 return Qprocess;
8e50cc2d 276 if (WINDOWP (object))
39bcc759 277 return Qwindow;
876c194c
SM
278 if (COMPILEDP (object))
279 return Qcompiled_function;
8e50cc2d 280 if (BUFFERP (object))
39bcc759 281 return Qbuffer;
8e50cc2d 282 if (CHAR_TABLE_P (object))
fc67d5be 283 return Qchar_table;
8e50cc2d 284 if (BOOL_VECTOR_P (object))
fc67d5be 285 return Qbool_vector;
8e50cc2d 286 if (FRAMEP (object))
39bcc759 287 return Qframe;
8e50cc2d 288 if (HASH_TABLE_P (object))
81dc5de5 289 return Qhash_table;
4e6f2626
CY
290 if (FONT_SPEC_P (object))
291 return Qfont_spec;
292 if (FONT_ENTITY_P (object))
293 return Qfont_entity;
294 if (FONT_OBJECT_P (object))
295 return Qfont_object;
39bcc759 296 return Qvector;
39bcc759 297 }
55a1744a
BT
298 else if (FLOATP (object))
299 return Qfloat;
62947569
BT
300 else if (! NILP (Fsubrp (object)))
301 return Qsubr;
55a1744a
BT
302 else
303 return Qt;
39bcc759
RS
304}
305
8c1a1077
PJ
306DEFUN ("consp", Fconsp, Sconsp, 1, 1, 0,
307 doc: /* Return t if OBJECT is a cons cell. */)
5842a27b 308 (Lisp_Object object)
7921925c 309{
39bcc759 310 if (CONSP (object))
7921925c
JB
311 return Qt;
312 return Qnil;
313}
314
25638b07 315DEFUN ("atom", Fatom, Satom, 1, 1, 0,
8c1a1077 316 doc: /* Return t if OBJECT is not a cons cell. This includes nil. */)
5842a27b 317 (Lisp_Object object)
7921925c 318{
39bcc759 319 if (CONSP (object))
7921925c
JB
320 return Qnil;
321 return Qt;
322}
323
25638b07 324DEFUN ("listp", Flistp, Slistp, 1, 1, 0,
4cdcdcc9
LT
325 doc: /* Return t if OBJECT is a list, that is, a cons cell or nil.
326Otherwise, return nil. */)
5842a27b 327 (Lisp_Object object)
7921925c 328{
39bcc759 329 if (CONSP (object) || NILP (object))
7921925c
JB
330 return Qt;
331 return Qnil;
332}
333
25638b07 334DEFUN ("nlistp", Fnlistp, Snlistp, 1, 1, 0,
8c1a1077 335 doc: /* Return t if OBJECT is not a list. Lists include nil. */)
5842a27b 336 (Lisp_Object object)
7921925c 337{
39bcc759 338 if (CONSP (object) || NILP (object))
7921925c
JB
339 return Qnil;
340 return Qt;
341}
342\f
25638b07 343DEFUN ("symbolp", Fsymbolp, Ssymbolp, 1, 1, 0,
8c1a1077 344 doc: /* Return t if OBJECT is a symbol. */)
5842a27b 345 (Lisp_Object object)
7921925c 346{
39bcc759 347 if (SYMBOLP (object))
7921925c
JB
348 return Qt;
349 return Qnil;
350}
351
42c30833
BT
352static bool
353SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (Lisp_Object sym)
354{
355 /* Should be initial_obarray */
356 Lisp_Object tem = Ffind_symbol (SYMBOL_NAME (sym), Vobarray);
357 return (! NILP (scm_c_value_ref (tem, 1))
358 && (EQ (sym, scm_c_value_ref (tem, 0))));
359}
360
cda9b832
DL
361/* Define this in C to avoid unnecessarily consing up the symbol
362 name. */
363DEFUN ("keywordp", Fkeywordp, Skeywordp, 1, 1, 0,
8c1a1077
PJ
364 doc: /* Return t if OBJECT is a keyword.
365This means that it is a symbol with a print name beginning with `:'
366interned in the initial obarray. */)
5842a27b 367 (Lisp_Object object)
cda9b832
DL
368{
369 if (SYMBOLP (object)
d5db4077 370 && SREF (SYMBOL_NAME (object), 0) == ':'
f35d5bad 371 && SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (object))
cda9b832
DL
372 return Qt;
373 return Qnil;
374}
375
25638b07 376DEFUN ("vectorp", Fvectorp, Svectorp, 1, 1, 0,
8c1a1077 377 doc: /* Return t if OBJECT is a vector. */)
5842a27b 378 (Lisp_Object object)
7921925c 379{
39bcc759 380 if (VECTORP (object))
7921925c
JB
381 return Qt;
382 return Qnil;
383}
384
25638b07 385DEFUN ("stringp", Fstringp, Sstringp, 1, 1, 0,
8c1a1077 386 doc: /* Return t if OBJECT is a string. */)
5842a27b 387 (Lisp_Object object)
7921925c 388{
39bcc759 389 if (STRINGP (object))
7921925c
JB
390 return Qt;
391 return Qnil;
392}
393
25638b07 394DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p,
8c1a1077 395 1, 1, 0,
3323c263
EZ
396 doc: /* Return t if OBJECT is a multibyte string.
397Return nil if OBJECT is either a unibyte string, or not a string. */)
5842a27b 398 (Lisp_Object object)
25638b07
RS
399{
400 if (STRINGP (object) && STRING_MULTIBYTE (object))
401 return Qt;
402 return Qnil;
403}
404
405DEFUN ("char-table-p", Fchar_table_p, Schar_table_p, 1, 1, 0,
8c1a1077 406 doc: /* Return t if OBJECT is a char-table. */)
5842a27b 407 (Lisp_Object object)
4d276982
RS
408{
409 if (CHAR_TABLE_P (object))
410 return Qt;
411 return Qnil;
412}
413
7f0edce7
RS
414DEFUN ("vector-or-char-table-p", Fvector_or_char_table_p,
415 Svector_or_char_table_p, 1, 1, 0,
8c1a1077 416 doc: /* Return t if OBJECT is a char-table or vector. */)
5842a27b 417 (Lisp_Object object)
7f0edce7
RS
418{
419 if (VECTORP (object) || CHAR_TABLE_P (object))
420 return Qt;
421 return Qnil;
422}
423
8c1a1077
PJ
424DEFUN ("bool-vector-p", Fbool_vector_p, Sbool_vector_p, 1, 1, 0,
425 doc: /* Return t if OBJECT is a bool-vector. */)
5842a27b 426 (Lisp_Object object)
4d276982
RS
427{
428 if (BOOL_VECTOR_P (object))
429 return Qt;
430 return Qnil;
431}
432
8c1a1077
PJ
433DEFUN ("arrayp", Farrayp, Sarrayp, 1, 1, 0,
434 doc: /* Return t if OBJECT is an array (string or vector). */)
5842a27b 435 (Lisp_Object object)
7921925c 436{
0c64a8cd 437 if (ARRAYP (object))
7921925c
JB
438 return Qt;
439 return Qnil;
440}
441
442DEFUN ("sequencep", Fsequencep, Ssequencep, 1, 1, 0,
8c1a1077 443 doc: /* Return t if OBJECT is a sequence (list or array). */)
5842a27b 444 (register Lisp_Object object)
7921925c 445{
0c64a8cd 446 if (CONSP (object) || NILP (object) || ARRAYP (object))
7921925c
JB
447 return Qt;
448 return Qnil;
449}
450
8c1a1077
PJ
451DEFUN ("bufferp", Fbufferp, Sbufferp, 1, 1, 0,
452 doc: /* Return t if OBJECT is an editor buffer. */)
5842a27b 453 (Lisp_Object object)
7921925c 454{
39bcc759 455 if (BUFFERP (object))
7921925c
JB
456 return Qt;
457 return Qnil;
458}
459
8c1a1077
PJ
460DEFUN ("markerp", Fmarkerp, Smarkerp, 1, 1, 0,
461 doc: /* Return t if OBJECT is a marker (editor pointer). */)
5842a27b 462 (Lisp_Object object)
7921925c 463{
39bcc759 464 if (MARKERP (object))
7921925c
JB
465 return Qt;
466 return Qnil;
467}
468
8c1a1077
PJ
469DEFUN ("subrp", Fsubrp, Ssubrp, 1, 1, 0,
470 doc: /* Return t if OBJECT is a built-in function. */)
5842a27b 471 (Lisp_Object object)
7921925c 472{
62947569
BT
473 if (CONSP (object) && EQ (XCAR (object), Qspecial_operator))
474 object = XCDR (object);
475 if (SCM_PRIMITIVE_P (object))
7921925c
JB
476 return Qt;
477 return Qnil;
478}
479
dbc4e1c1 480DEFUN ("byte-code-function-p", Fbyte_code_function_p, Sbyte_code_function_p,
8c1a1077
PJ
481 1, 1, 0,
482 doc: /* Return t if OBJECT is a byte-compiled function object. */)
5842a27b 483 (Lisp_Object object)
7921925c 484{
39bcc759 485 if (COMPILEDP (object))
7921925c
JB
486 return Qt;
487 return Qnil;
488}
489
0321d75c 490DEFUN ("char-or-string-p", Fchar_or_string_p, Schar_or_string_p, 1, 1, 0,
8637f5ee 491 doc: /* Return t if OBJECT is a character or a string. */)
5842a27b 492 (register Lisp_Object object)
7921925c 493{
cfd70f33 494 if (CHARACTERP (object) || STRINGP (object))
7921925c
JB
495 return Qt;
496 return Qnil;
497}
498\f
8c1a1077
PJ
499DEFUN ("integerp", Fintegerp, Sintegerp, 1, 1, 0,
500 doc: /* Return t if OBJECT is an integer. */)
5842a27b 501 (Lisp_Object object)
7921925c 502{
39bcc759 503 if (INTEGERP (object))
7921925c
JB
504 return Qt;
505 return Qnil;
506}
507
464f8898 508DEFUN ("integer-or-marker-p", Finteger_or_marker_p, Sinteger_or_marker_p, 1, 1, 0,
8c1a1077 509 doc: /* Return t if OBJECT is an integer or a marker (editor pointer). */)
5842a27b 510 (register Lisp_Object object)
7921925c 511{
39bcc759 512 if (MARKERP (object) || INTEGERP (object))
7921925c
JB
513 return Qt;
514 return Qnil;
515}
516
0321d75c 517DEFUN ("natnump", Fnatnump, Snatnump, 1, 1, 0,
8c1a1077 518 doc: /* Return t if OBJECT is a nonnegative integer. */)
5842a27b 519 (Lisp_Object object)
7921925c 520{
39bcc759 521 if (NATNUMP (object))
7921925c
JB
522 return Qt;
523 return Qnil;
524}
525
526DEFUN ("numberp", Fnumberp, Snumberp, 1, 1, 0,
8c1a1077 527 doc: /* Return t if OBJECT is a number (floating point or integer). */)
5842a27b 528 (Lisp_Object object)
7921925c 529{
39bcc759 530 if (NUMBERP (object))
7921925c 531 return Qt;
dbc4e1c1
JB
532 else
533 return Qnil;
7921925c
JB
534}
535
536DEFUN ("number-or-marker-p", Fnumber_or_marker_p,
537 Snumber_or_marker_p, 1, 1, 0,
8c1a1077 538 doc: /* Return t if OBJECT is a number or a marker. */)
5842a27b 539 (Lisp_Object object)
7921925c 540{
39bcc759 541 if (NUMBERP (object) || MARKERP (object))
7921925c
JB
542 return Qt;
543 return Qnil;
544}
464f8898 545
464f8898 546DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0,
8c1a1077 547 doc: /* Return t if OBJECT is a floating point number. */)
5842a27b 548 (Lisp_Object object)
464f8898 549{
39bcc759 550 if (FLOATP (object))
464f8898
RS
551 return Qt;
552 return Qnil;
553}
cc94f3b2 554
7921925c 555\f
32e5c58c 556/* Extract and set components of lists. */
7921925c 557
a7ca3326 558DEFUN ("car", Fcar, Scar, 1, 1, 0,
8c1a1077 559 doc: /* Return the car of LIST. If arg is nil, return nil.
9701c742
LT
560Error if arg is not nil and not a cons cell. See also `car-safe'.
561
da46c5be
LT
562See Info node `(elisp)Cons Cells' for a discussion of related basic
563Lisp concepts such as car, cdr, cons cell and list. */)
5842a27b 564 (register Lisp_Object list)
7921925c 565{
0c64a8cd 566 return CAR (list);
7921925c
JB
567}
568
a7ca3326 569DEFUN ("car-safe", Fcar_safe, Scar_safe, 1, 1, 0,
8c1a1077 570 doc: /* Return the car of OBJECT if it is a cons cell, or else nil. */)
5842a27b 571 (Lisp_Object object)
7921925c 572{
0c64a8cd 573 return CAR_SAFE (object);
7921925c
JB
574}
575
a7ca3326 576DEFUN ("cdr", Fcdr, Scdr, 1, 1, 0,
8c1a1077 577 doc: /* Return the cdr of LIST. If arg is nil, return nil.
9701c742
LT
578Error if arg is not nil and not a cons cell. See also `cdr-safe'.
579
da46c5be
LT
580See Info node `(elisp)Cons Cells' for a discussion of related basic
581Lisp concepts such as cdr, car, cons cell and list. */)
5842a27b 582 (register Lisp_Object list)
7921925c 583{
0c64a8cd 584 return CDR (list);
7921925c
JB
585}
586
a7ca3326 587DEFUN ("cdr-safe", Fcdr_safe, Scdr_safe, 1, 1, 0,
8c1a1077 588 doc: /* Return the cdr of OBJECT if it is a cons cell, or else nil. */)
5842a27b 589 (Lisp_Object object)
7921925c 590{
0c64a8cd 591 return CDR_SAFE (object);
7921925c
JB
592}
593
a7ca3326 594DEFUN ("setcar", Fsetcar, Ssetcar, 2, 2, 0,
8c1a1077 595 doc: /* Set the car of CELL to be NEWCAR. Returns NEWCAR. */)
5842a27b 596 (register Lisp_Object cell, Lisp_Object newcar)
7921925c 597{
0c64a8cd 598 CHECK_CONS (cell);
7921925c 599 CHECK_IMPURE (cell);
f3fbd155 600 XSETCAR (cell, newcar);
7921925c
JB
601 return newcar;
602}
603
a7ca3326 604DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
8c1a1077 605 doc: /* Set the cdr of CELL to be NEWCDR. Returns NEWCDR. */)
5842a27b 606 (register Lisp_Object cell, Lisp_Object newcdr)
7921925c 607{
0c64a8cd 608 CHECK_CONS (cell);
7921925c 609 CHECK_IMPURE (cell);
f3fbd155 610 XSETCDR (cell, newcdr);
7921925c
JB
611 return newcdr;
612}
613\f
1ec4b7b2 614/* Extract and set components of symbols. */
7921925c 615
a7ca3326 616DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0,
a9de9f0c
GM
617 doc: /* Return t if SYMBOL's value is not void.
618Note that if `lexical-binding' is in effect, this refers to the
619global value outside of any lexical scope. */)
5842a27b 620 (register Lisp_Object symbol)
7921925c
JB
621{
622 Lisp_Object valcontents;
844e0de1 623 sym_t sym;
b7826503 624 CHECK_SYMBOL (symbol);
ce5b453a 625 sym = XSYMBOL (symbol);
7921925c 626
ce5b453a 627 start:
844e0de1 628 switch (SYMBOL_REDIRECT (sym))
ce5b453a
SM
629 {
630 case SYMBOL_PLAINVAL: valcontents = SYMBOL_VAL (sym); break;
631 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
632 case SYMBOL_LOCALIZED:
633 {
634 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
635 if (blv->fwd)
636 /* In set_internal, we un-forward vars when their value is
7be68de5 637 set to Qunbound. */
ce5b453a
SM
638 return Qt;
639 else
640 {
641 swap_in_symval_forwarding (sym, blv);
a04e2c62 642 valcontents = blv_value (blv);
ce5b453a
SM
643 }
644 break;
645 }
646 case SYMBOL_FORWARDED:
647 /* In set_internal, we un-forward vars when their value is
7be68de5 648 set to Qunbound. */
ce5b453a 649 return Qt;
1088b922 650 default: emacs_abort ();
ce5b453a 651 }
7921925c 652
1bfcade3 653 return (EQ (valcontents, Qunbound) ? Qnil : Qt);
7921925c
JB
654}
655
d1c3da7b
BT
656WRAP1 (Ffboundp, "fboundp")
657WRAP1 (Fmakunbound, "makunbound")
658WRAP1 (Ffmakunbound, "fmakunbound")
659WRAP1 (Fsymbol_function, "symbol-function")
7921925c 660
8c1a1077
PJ
661DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0,
662 doc: /* Return SYMBOL's property list. */)
5842a27b 663 (register Lisp_Object symbol)
7921925c 664{
b7826503 665 CHECK_SYMBOL (symbol);
061cde10 666 return symbol_plist (symbol);
7921925c
JB
667}
668
a7ca3326 669DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0,
8c1a1077 670 doc: /* Return SYMBOL's name, a string. */)
5842a27b 671 (register Lisp_Object symbol)
7921925c
JB
672{
673 register Lisp_Object name;
674
b7826503 675 CHECK_SYMBOL (symbol);
84023177 676 name = SYMBOL_NAME (symbol);
7921925c
JB
677 return name;
678}
679
d1c3da7b 680WRAP2 (Ffset, "fset")
7921925c 681
d2fde41d 682DEFUN ("defalias", Fdefalias, Sdefalias, 2, 3, 0,
1053a871 683 doc: /* Set SYMBOL's function definition to DEFINITION.
96143227
RS
684Associates the function with the current load file, if any.
685The optional third argument DOCSTRING specifies the documentation string
686for SYMBOL; if it is omitted or nil, SYMBOL uses the documentation string
1053a871 687determined by DEFINITION.
189e7007
GM
688
689Internally, this normally uses `fset', but if SYMBOL has a
690`defalias-fset-function' property, the associated value is used instead.
691
1053a871 692The return value is undefined. */)
5842a27b 693 (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring)
fc08c367 694{
8a658a52 695 CHECK_SYMBOL (symbol);
61b108cc
SM
696 if (!NILP (Vpurify_flag)
697 /* If `definition' is a keymap, immutable (and copying) is wrong. */
698 && !KEYMAPP (definition))
699 definition = Fpurecopy (definition);
32e5c58c
SM
700
701 {
702 bool autoload = AUTOLOADP (definition);
703 if (NILP (Vpurify_flag) || !autoload)
704 { /* Only add autoload entries after dumping, because the ones before are
705 not useful and else we get loads of them from the loaddefs.el. */
706
1d59fbe3 707 if (AUTOLOADP (SYMBOL_FUNCTION (symbol)))
32e5c58c
SM
708 /* Remember that the function was already an autoload. */
709 LOADHIST_ATTACH (Fcons (Qt, symbol));
710 LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol));
711 }
712 }
713
714 { /* Handle automatic advice activation. */
715 Lisp_Object hook = Fget (symbol, Qdefalias_fset_function);
716 if (!NILP (hook))
717 call2 (hook, symbol, definition);
718 else
719 Ffset (symbol, definition);
720 }
721
d2fde41d
SM
722 if (!NILP (docstring))
723 Fput (symbol, Qfunction_documentation, docstring);
1053a871
SM
724 /* We used to return `definition', but now that `defun' and `defmacro' expand
725 to a call to `defalias', we return `symbol' for backward compatibility
726 (bug#11686). */
727 return symbol;
fc08c367
RS
728}
729
7921925c 730DEFUN ("setplist", Fsetplist, Ssetplist, 2, 2, 0,
6b61353c 731 doc: /* Set SYMBOL's property list to NEWPLIST, and return NEWPLIST. */)
5842a27b 732 (register Lisp_Object symbol, Lisp_Object newplist)
7921925c 733{
b7826503 734 CHECK_SYMBOL (symbol);
c644523b 735 set_symbol_plist (symbol, newplist);
7921925c
JB
736 return newplist;
737}
ffd56f97 738
6f0e897f 739DEFUN ("subr-arity", Fsubr_arity, Ssubr_arity, 1, 1, 0,
8c1a1077
PJ
740 doc: /* Return minimum and maximum number of args allowed for SUBR.
741SUBR must be a built-in function.
742The returned value is a pair (MIN . MAX). MIN is the minimum number
743of args. MAX is the maximum number or the symbol `many', for a
744function with `&rest' args, or `unevalled' for a special form. */)
5842a27b 745 (Lisp_Object subr)
6f0e897f 746{
62947569
BT
747 Lisp_Object min, max;
748 Lisp_Object arity;
749 bool special = false;
750
0c64a8cd 751 CHECK_SUBR (subr);
62947569
BT
752 if (CONSP (subr) && EQ (XCAR (subr), Qspecial_operator))
753 {
754 subr = XCDR (subr);
755 special = true;
756 }
757 arity = scm_procedure_minimum_arity (subr);
758 if (scm_is_false (arity))
759 return Qnil;
760 min = XCAR (arity);
761 if (special)
762 max = Qunevalled;
763 else if (scm_is_true (XCAR (XCDR (XCDR (arity)))))
764 max = Qmany;
765 else
766 max = scm_sum (min, XCAR (XCDR (arity)));
767 return Fcons (min, max);
6f0e897f
DL
768}
769
0fddae66
SM
770DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
771 doc: /* Return name of subroutine SUBR.
772SUBR must be a built-in function. */)
5842a27b 773 (Lisp_Object subr)
0fddae66 774{
0c64a8cd 775 CHECK_SUBR (subr);
62947569
BT
776 if (CONSP (subr) && EQ (XCAR (subr), Qspecial_operator))
777 subr = XCDR (subr);
778 return Fsymbol_name (SCM_SUBR_NAME (subr));
0fddae66
SM
779}
780
a7ca3326 781DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0,
6b61353c 782 doc: /* Return the interactive form of CMD or nil if none.
df133612
LT
783If CMD is not a command, the return value is nil.
784Value, if non-nil, is a list \(interactive SPEC). */)
5842a27b 785 (Lisp_Object cmd)
cc515226 786{
c4f46926 787 Lisp_Object fun = indirect_function (cmd); /* Check cycles. */
764ea377 788
eadf1faa 789 if (NILP (fun))
c4f46926
SM
790 return Qnil;
791
792 /* Use an `interactive-form' property if present, analogous to the
32e5c58c 793 function-documentation property. */
c4f46926
SM
794 fun = cmd;
795 while (SYMBOLP (fun))
796 {
3860280a 797 Lisp_Object tmp = Fget (fun, Qinteractive_form);
c4f46926
SM
798 if (!NILP (tmp))
799 return tmp;
800 else
801 fun = Fsymbol_function (fun);
802 }
6b61353c 803
b06bf4dc
BT
804 if (COMPILEDP (fun))
805 {
806 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE)
807 return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE));
808 }
809 else if (scm_is_true (scm_procedure_p (fun)))
6b61353c 810 {
69f7f524
BT
811 Lisp_Object tem = scm_assq (Qinteractive_form,
812 scm_procedure_properties (fun));
813 if (scm_is_pair (tem))
814 return list2 (Qinteractive, scm_cdr (tem));
6b61353c 815 }
32e5c58c
SM
816 else if (AUTOLOADP (fun))
817 return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil));
6b61353c
KH
818 else if (CONSP (fun))
819 {
820 Lisp_Object funcar = XCAR (fun);
b38b1ec0 821 if (EQ (funcar, Qclosure))
23aba0ea
SM
822 return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun))));
823 else if (EQ (funcar, Qlambda))
6b61353c 824 return Fassq (Qinteractive, Fcdr (XCDR (fun)));
6b61353c 825 }
cc515226
GM
826 return Qnil;
827}
828
7921925c 829\f
f35d5bad
GM
830/***********************************************************************
831 Getting and Setting Values of Symbols
832 ***********************************************************************/
833
834/* Return the symbol holding SYMBOL's value. Signal
835 `cyclic-variable-indirection' if SYMBOL's chain of variable
836 indirections contains a loop. */
837
844e0de1
BT
838sym_t
839indirect_variable (sym_t symbol)
f35d5bad 840{
844e0de1 841 sym_t tortoise, hare;
f35d5bad
GM
842
843 hare = tortoise = symbol;
844
844e0de1 845 while (SYMBOL_REDIRECT (hare) == SYMBOL_VARALIAS)
f35d5bad 846 {
ce5b453a 847 hare = SYMBOL_ALIAS (hare);
844e0de1 848 if (SYMBOL_REDIRECT (hare) != SYMBOL_VARALIAS)
f35d5bad 849 break;
bfb96cb7 850
ce5b453a
SM
851 hare = SYMBOL_ALIAS (hare);
852 tortoise = SYMBOL_ALIAS (tortoise);
f35d5bad 853
ad97b375
SM
854 if (hare == tortoise)
855 {
856 Lisp_Object tem;
857 XSETSYMBOL (tem, symbol);
858 xsignal1 (Qcyclic_variable_indirection, tem);
859 }
f35d5bad
GM
860 }
861
862 return hare;
863}
864
865
866DEFUN ("indirect-variable", Findirect_variable, Sindirect_variable, 1, 1, 0,
8c1a1077 867 doc: /* Return the variable at the end of OBJECT's variable chain.
4abcdac8
CY
868If OBJECT is a symbol, follow its variable indirections (if any), and
869return the variable at the end of the chain of aliases. See Info node
870`(elisp)Variable Aliases'.
871
872If OBJECT is not a symbol, just return it. If there is a loop in the
873chain of aliases, signal a `cyclic-variable-indirection' error. */)
5842a27b 874 (Lisp_Object object)
f35d5bad
GM
875{
876 if (SYMBOLP (object))
946f9a5b 877 {
844e0de1 878 sym_t sym = indirect_variable (XSYMBOL (object));
946f9a5b
PE
879 XSETSYMBOL (object, sym);
880 }
f35d5bad
GM
881 return object;
882}
883
7921925c
JB
884
885/* Given the raw contents of a symbol value cell,
886 return the Lisp value of the symbol.
887 This does not handle buffer-local variables; use
888 swap_in_symval_forwarding for that. */
889
890Lisp_Object
971de7fb 891do_symval_forwarding (register union Lisp_Fwd *valcontents)
7921925c
JB
892{
893 register Lisp_Object val;
ce5b453a
SM
894 switch (XFWDTYPE (valcontents))
895 {
896 case Lisp_Fwd_Int:
897 XSETINT (val, *XINTFWD (valcontents)->intvar);
898 return val;
899
900 case Lisp_Fwd_Bool:
901 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
902
903 case Lisp_Fwd_Obj:
904 return *XOBJFWD (valcontents)->objvar;
905
906 case Lisp_Fwd_Buffer_Obj:
4ce60d2e 907 return per_buffer_value (current_buffer,
ce5b453a
SM
908 XBUFFER_OBJFWD (valcontents)->offset);
909
910 case Lisp_Fwd_Kboard_Obj:
911 /* We used to simply use current_kboard here, but from Lisp
a98edce9 912 code, its value is often unexpected. It seems nicer to
ce5b453a
SM
913 allow constructions like this to work as intuitively expected:
914
915 (with-selected-frame frame
916 (define-key local-function-map "\eOP" [f1]))
917
918 On the other hand, this affects the semantics of
919 last-command and real-last-command, and people may rely on
920 that. I took a quick look at the Lisp codebase, and I
921 don't think anything will break. --lorentey */
922 return *(Lisp_Object *)(XKBOARD_OBJFWD (valcontents)->offset
923 + (char *)FRAME_KBOARD (SELECTED_FRAME ()));
1088b922 924 default: emacs_abort ();
ce5b453a 925 }
7921925c
JB
926}
927
d9c2a0f2
EN
928/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
929 of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the
7921925c 930 buffer-independent contents of the value cell: forwarded just one
7a283f36
GM
931 step past the buffer-localness.
932
933 BUF non-zero means set the value in buffer BUF instead of the
934 current buffer. This only plays a role for per-buffer variables. */
7921925c 935
ce5b453a 936static void
971de7fb 937store_symval_forwarding (union Lisp_Fwd *valcontents, register Lisp_Object newval, struct buffer *buf)
7921925c 938{
ce5b453a 939 switch (XFWDTYPE (valcontents))
7921925c 940 {
ce5b453a
SM
941 case Lisp_Fwd_Int:
942 CHECK_NUMBER (newval);
943 *XINTFWD (valcontents)->intvar = XINT (newval);
944 break;
aa3830c4 945
ce5b453a
SM
946 case Lisp_Fwd_Bool:
947 *XBOOLFWD (valcontents)->boolvar = !NILP (newval);
948 break;
aa3830c4 949
ce5b453a
SM
950 case Lisp_Fwd_Obj:
951 *XOBJFWD (valcontents)->objvar = newval;
aa3830c4 952
ce5b453a
SM
953 /* If this variable is a default for something stored
954 in the buffer itself, such as default-fill-column,
955 find the buffers that don't have local values for it
956 and update them. */
957 if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults
958 && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1))
46b2ac21 959 {
ce5b453a
SM
960 int offset = ((char *) XOBJFWD (valcontents)->objvar
961 - (char *) &buffer_defaults);
962 int idx = PER_BUFFER_IDX (offset);
aa3830c4 963
8f3a2c26 964 Lisp_Object tail, buf;
aa3830c4 965
ce5b453a
SM
966 if (idx <= 0)
967 break;
aa3830c4 968
8f3a2c26 969 FOR_EACH_LIVE_BUFFER (tail, buf)
6b61353c 970 {
8f3a2c26 971 struct buffer *b = XBUFFER (buf);
6b61353c 972
ce5b453a 973 if (! PER_BUFFER_VALUE_P (b, idx))
4ce60d2e 974 set_per_buffer_value (b, offset, newval);
6b61353c 975 }
ce5b453a
SM
976 }
977 break;
7403b5c8 978
ce5b453a
SM
979 case Lisp_Fwd_Buffer_Obj:
980 {
981 int offset = XBUFFER_OBJFWD (valcontents)->offset;
58cc0a01 982 Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate;
ce5b453a 983
58cc0a01
DA
984 if (!NILP (predicate) && !NILP (newval)
985 && NILP (call1 (predicate, newval)))
986 wrong_type_argument (predicate, newval);
ce5b453a
SM
987
988 if (buf == NULL)
989 buf = current_buffer;
4ce60d2e 990 set_per_buffer_value (buf, offset, newval);
ce5b453a
SM
991 }
992 break;
7403b5c8 993
ce5b453a
SM
994 case Lisp_Fwd_Kboard_Obj:
995 {
996 char *base = (char *) FRAME_KBOARD (SELECTED_FRAME ());
997 char *p = base + XKBOARD_OBJFWD (valcontents)->offset;
998 *(Lisp_Object *) p = newval;
999 }
7921925c
JB
1000 break;
1001
7921925c 1002 default:
1088b922 1003 emacs_abort (); /* goto def; */
7921925c
JB
1004 }
1005}
1006
d73e321c
DA
1007/* Set up SYMBOL to refer to its global binding. This makes it safe
1008 to alter the status of other bindings. BEWARE: this may be called
1009 during the mark phase of GC, where we assume that Lisp_Object slots
1010 of BLV are marked after this function has changed them. */
b0d53add
GM
1011
1012void
844e0de1 1013swap_in_global_binding (sym_t symbol)
b0d53add 1014{
ce5b453a 1015 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (symbol);
b0d53add
GM
1016
1017 /* Unload the previously loaded binding. */
ce5b453a 1018 if (blv->fwd)
a04e2c62 1019 set_blv_value (blv, do_symval_forwarding (blv->fwd));
bfb96cb7 1020
b0d53add 1021 /* Select the global binding in the symbol. */
a04e2c62 1022 set_blv_valcell (blv, blv->defcell);
ce5b453a
SM
1023 if (blv->fwd)
1024 store_symval_forwarding (blv->fwd, XCDR (blv->defcell), NULL);
b0d53add
GM
1025
1026 /* Indicate that the global binding is set up now. */
a04e2c62
DA
1027 set_blv_where (blv, Qnil);
1028 set_blv_found (blv, 0);
b0d53add
GM
1029}
1030
2829d05f 1031/* Set up the buffer-local symbol SYMBOL for validity in the current buffer.
42e975f0
RS
1032 VALCONTENTS is the contents of its value cell,
1033 which points to a struct Lisp_Buffer_Local_Value.
1034
1035 Return the value forwarded one step past the buffer-local stage.
1036 This could be another forwarding pointer. */
7921925c 1037
ce5b453a 1038static void
844e0de1 1039swap_in_symval_forwarding (sym_t symbol, struct Lisp_Buffer_Local_Value *blv)
7921925c 1040{
7921925c 1041 register Lisp_Object tem1;
bfb96cb7 1042
ce5b453a
SM
1043 eassert (blv == SYMBOL_BLV (symbol));
1044
1045 tem1 = blv->where;
7921925c 1046
42e975f0 1047 if (NILP (tem1)
ce5b453a
SM
1048 || (blv->frame_local
1049 ? !EQ (selected_frame, tem1)
1050 : current_buffer != XBUFFER (tem1)))
7921925c 1051 {
bfb96cb7 1052
42e975f0 1053 /* Unload the previously loaded binding. */
ce5b453a
SM
1054 tem1 = blv->valcell;
1055 if (blv->fwd)
a04e2c62 1056 set_blv_value (blv, do_symval_forwarding (blv->fwd));
42e975f0 1057 /* Choose the new binding. */
ce5b453a
SM
1058 {
1059 Lisp_Object var;
1060 XSETSYMBOL (var, symbol);
1061 if (blv->frame_local)
1062 {
e69b0960 1063 tem1 = assq_no_quit (var, XFRAME (selected_frame)->param_alist);
a04e2c62 1064 set_blv_where (blv, selected_frame);
ce5b453a
SM
1065 }
1066 else
1067 {
4b4deea2 1068 tem1 = assq_no_quit (var, BVAR (current_buffer, local_var_alist));
d73e321c 1069 set_blv_where (blv, Fcurrent_buffer ());
ce5b453a
SM
1070 }
1071 }
1072 if (!(blv->found = !NILP (tem1)))
1073 tem1 = blv->defcell;
b0c2d1c6 1074
42e975f0 1075 /* Load the new binding. */
a04e2c62 1076 set_blv_valcell (blv, tem1);
ce5b453a 1077 if (blv->fwd)
a04e2c62 1078 store_symval_forwarding (blv->fwd, blv_value (blv), NULL);
7921925c 1079 }
7921925c
JB
1080}
1081\f
14e76af9
JB
1082/* Find the value of a symbol, returning Qunbound if it's not bound.
1083 This is helpful for code which just wants to get a variable's value
8e6208c5 1084 if it has one, without signaling an error.
14e76af9
JB
1085 Note that it must not be possible to quit
1086 within this function. Great care is required for this. */
7921925c 1087
14e76af9 1088Lisp_Object
971de7fb 1089find_symbol_value (Lisp_Object symbol)
7921925c 1090{
844e0de1 1091 sym_t sym;
bfb96cb7 1092
b7826503 1093 CHECK_SYMBOL (symbol);
ce5b453a 1094 sym = XSYMBOL (symbol);
7921925c 1095
ce5b453a 1096 start:
844e0de1 1097 switch (SYMBOL_REDIRECT (sym))
ce5b453a
SM
1098 {
1099 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1100 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
1101 case SYMBOL_LOCALIZED:
1102 {
1103 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1104 swap_in_symval_forwarding (sym, blv);
a04e2c62 1105 return blv->fwd ? do_symval_forwarding (blv->fwd) : blv_value (blv);
ce5b453a
SM
1106 }
1107 /* FALLTHROUGH */
1108 case SYMBOL_FORWARDED:
1109 return do_symval_forwarding (SYMBOL_FWD (sym));
1088b922 1110 default: emacs_abort ();
ce5b453a 1111 }
7921925c
JB
1112}
1113
a7ca3326 1114DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
14d27346
GM
1115 doc: /* Return SYMBOL's value. Error if that is void.
1116Note that if `lexical-binding' is in effect, this returns the
1117global value outside of any lexical scope. */)
5842a27b 1118 (Lisp_Object symbol)
14e76af9 1119{
0671d7c0 1120 Lisp_Object val;
14e76af9 1121
d9c2a0f2 1122 val = find_symbol_value (symbol);
740ef0b5 1123 if (!EQ (val, Qunbound))
14e76af9 1124 return val;
740ef0b5
KS
1125
1126 xsignal1 (Qvoid_variable, symbol);
14e76af9
JB
1127}
1128
a7ca3326 1129DEFUN ("set", Fset, Sset, 2, 2, 0,
8c1a1077 1130 doc: /* Set SYMBOL's value to NEWVAL, and return NEWVAL. */)
5842a27b 1131 (register Lisp_Object symbol, Lisp_Object newval)
05ef7169 1132{
94b612ad 1133 set_internal (symbol, newval, Qnil, 0);
ce5b453a 1134 return newval;
05ef7169
RS
1135}
1136
25638b07 1137/* Store the value NEWVAL into SYMBOL.
94b612ad
SM
1138 If buffer/frame-locality is an issue, WHERE specifies which context to use.
1139 (nil stands for the current buffer/frame).
2829d05f 1140
de1339b0 1141 If BINDFLAG is false, then if this symbol is supposed to become
05ef7169 1142 local in every buffer where it is set, then we make it local.
de1339b0 1143 If BINDFLAG is true, we don't do that. */
05ef7169 1144
ce5b453a 1145void
de1339b0
PE
1146set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
1147 bool bindflag)
7921925c 1148{
de1339b0 1149 bool voide = EQ (newval, Qunbound);
844e0de1 1150 sym_t sym;
ce5b453a 1151 Lisp_Object tem1;
7921925c 1152
2829d05f 1153 /* If restoring in a dead buffer, do nothing. */
94b612ad
SM
1154 /* if (BUFFERP (where) && NILP (XBUFFER (where)->name))
1155 return; */
2829d05f 1156
b7826503 1157 CHECK_SYMBOL (symbol);
ce5b453a 1158 if (SYMBOL_CONSTANT_P (symbol))
7921925c 1159 {
ce5b453a
SM
1160 if (NILP (Fkeywordp (symbol))
1161 || !EQ (newval, Fsymbol_value (symbol)))
1162 xsignal1 (Qsetting_constant, symbol);
1163 else
1164 /* Allow setting keywords to their own value. */
1165 return;
7921925c 1166 }
42e975f0 1167
ce5b453a 1168 sym = XSYMBOL (symbol);
7921925c 1169
ce5b453a 1170 start:
844e0de1 1171 switch (SYMBOL_REDIRECT (sym))
ce5b453a
SM
1172 {
1173 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1174 case SYMBOL_PLAINVAL: SET_SYMBOL_VAL (sym , newval); return;
1175 case SYMBOL_LOCALIZED:
1176 {
1177 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
94b612ad
SM
1178 if (NILP (where))
1179 {
1180 if (blv->frame_local)
1181 where = selected_frame;
1182 else
1183 XSETBUFFER (where, current_buffer);
1184 }
ce5b453a
SM
1185 /* If the current buffer is not the buffer whose binding is
1186 loaded, or if there may be frame-local bindings and the frame
1187 isn't the right one, or if it's a Lisp_Buffer_Local_Value and
1188 the default binding is loaded, the loaded binding may be the
1189 wrong one. */
94b612ad 1190 if (!EQ (blv->where, where)
bfeae2cf 1191 /* Also unload a global binding (if the var is local_if_set). */
ce5b453a
SM
1192 || (EQ (blv->valcell, blv->defcell)))
1193 {
1194 /* The currently loaded binding is not necessarily valid.
1195 We need to unload it, and choose a new binding. */
1196
1197 /* Write out `realvalue' to the old loaded binding. */
1198 if (blv->fwd)
a04e2c62 1199 set_blv_value (blv, do_symval_forwarding (blv->fwd));
b0c2d1c6 1200
ce5b453a 1201 /* Find the new binding. */
94b612ad
SM
1202 XSETSYMBOL (symbol, sym); /* May have changed via aliasing. */
1203 tem1 = Fassq (symbol,
1204 (blv->frame_local
e69b0960 1205 ? XFRAME (where)->param_alist
4b4deea2 1206 : BVAR (XBUFFER (where), local_var_alist)));
a04e2c62 1207 set_blv_where (blv, where);
9e677988 1208 blv->found = 1;
ce5b453a
SM
1209
1210 if (NILP (tem1))
1211 {
1212 /* This buffer still sees the default value. */
1213
1214 /* If the variable is a Lisp_Some_Buffer_Local_Value,
1215 or if this is `let' rather than `set',
1216 make CURRENT-ALIST-ELEMENT point to itself,
1217 indicating that we're seeing the default value.
1218 Likewise if the variable has been let-bound
1219 in the current buffer. */
1220 if (bindflag || !blv->local_if_set
1221 || let_shadows_buffer_binding_p (sym))
1222 {
9e677988 1223 blv->found = 0;
ce5b453a
SM
1224 tem1 = blv->defcell;
1225 }
1226 /* If it's a local_if_set, being set not bound,
1227 and we're not within a let that was made for this buffer,
1228 create a new buffer-local binding for the variable.
1229 That means, give this buffer a new assoc for a local value
1230 and load that binding. */
1231 else
1232 {
1233 /* local_if_set is only supported for buffer-local
1234 bindings, not for frame-local bindings. */
1235 eassert (!blv->frame_local);
1236 tem1 = Fcons (symbol, XCDR (blv->defcell));
39eb03f1
PE
1237 bset_local_var_alist
1238 (XBUFFER (where),
1239 Fcons (tem1, BVAR (XBUFFER (where), local_var_alist)));
ce5b453a
SM
1240 }
1241 }
1242
1243 /* Record which binding is now loaded. */
a04e2c62 1244 set_blv_valcell (blv, tem1);
ce5b453a 1245 }
b0c2d1c6 1246
ce5b453a 1247 /* Store the new value in the cons cell. */
a04e2c62 1248 set_blv_value (blv, newval);
d8cafeb5 1249
ce5b453a
SM
1250 if (blv->fwd)
1251 {
1252 if (voide)
1253 /* If storing void (making the symbol void), forward only through
1254 buffer-local indicator, not through Lisp_Objfwd, etc. */
1255 blv->fwd = NULL;
1256 else
94b612ad
SM
1257 store_symval_forwarding (blv->fwd, newval,
1258 BUFFERP (where)
1259 ? XBUFFER (where) : current_buffer);
ce5b453a
SM
1260 }
1261 break;
1262 }
1263 case SYMBOL_FORWARDED:
1264 {
94b612ad
SM
1265 struct buffer *buf
1266 = BUFFERP (where) ? XBUFFER (where) : current_buffer;
ce5b453a
SM
1267 union Lisp_Fwd *innercontents = SYMBOL_FWD (sym);
1268 if (BUFFER_OBJFWDP (innercontents))
1269 {
1270 int offset = XBUFFER_OBJFWD (innercontents)->offset;
1271 int idx = PER_BUFFER_IDX (offset);
1272 if (idx > 0
1273 && !bindflag
1274 && !let_shadows_buffer_binding_p (sym))
1275 SET_PER_BUFFER_VALUE_P (buf, idx, 1);
1276 }
569c11e3 1277
ce5b453a
SM
1278 if (voide)
1279 { /* If storing void (making the symbol void), forward only through
1280 buffer-local indicator, not through Lisp_Objfwd, etc. */
844e0de1 1281 SET_SYMBOL_REDIRECT (sym, SYMBOL_PLAINVAL);
ce5b453a
SM
1282 SET_SYMBOL_VAL (sym, newval);
1283 }
1284 else
1285 store_symval_forwarding (/* sym, */ innercontents, newval, buf);
1286 break;
1287 }
1088b922 1288 default: emacs_abort ();
7921925c 1289 }
ce5b453a 1290 return;
7921925c
JB
1291}
1292\f
1293/* Access or set a buffer-local symbol's default value. */
1294
d9c2a0f2 1295/* Return the default value of SYMBOL, but don't check for voidness.
1bfcade3 1296 Return Qunbound if it is void. */
7921925c 1297
112396d6 1298static Lisp_Object
971de7fb 1299default_value (Lisp_Object symbol)
7921925c 1300{
844e0de1 1301 sym_t sym;
7921925c 1302
b7826503 1303 CHECK_SYMBOL (symbol);
ce5b453a 1304 sym = XSYMBOL (symbol);
7921925c 1305
ce5b453a 1306 start:
844e0de1 1307 switch (SYMBOL_REDIRECT (sym))
7921925c 1308 {
ce5b453a
SM
1309 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1310 case SYMBOL_PLAINVAL: return SYMBOL_VAL (sym);
1311 case SYMBOL_LOCALIZED:
1312 {
1313 /* If var is set up for a buffer that lacks a local value for it,
1314 the current value is nominally the default value.
1315 But the `realvalue' slot may be more up to date, since
1316 ordinary setq stores just that slot. So use that. */
1317 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1318 if (blv->fwd && EQ (blv->valcell, blv->defcell))
1319 return do_symval_forwarding (blv->fwd);
1320 else
1321 return XCDR (blv->defcell);
1322 }
1323 case SYMBOL_FORWARDED:
1324 {
1325 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
7921925c 1326
ce5b453a
SM
1327 /* For a built-in buffer-local variable, get the default value
1328 rather than letting do_symval_forwarding get the current value. */
1329 if (BUFFER_OBJFWDP (valcontents))
1330 {
1331 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1332 if (PER_BUFFER_IDX (offset) != 0)
4ce60d2e 1333 return per_buffer_default (offset);
ce5b453a
SM
1334 }
1335
1336 /* For other variables, get the current value. */
1337 return do_symval_forwarding (valcontents);
1338 }
1088b922 1339 default: emacs_abort ();
7921925c 1340 }
7921925c
JB
1341}
1342
a7ca3326 1343DEFUN ("default-boundp", Fdefault_boundp, Sdefault_boundp, 1, 1, 0,
8c1a1077
PJ
1344 doc: /* Return t if SYMBOL has a non-void default value.
1345This is the value that is seen in buffers that do not have their own values
1346for this variable. */)
5842a27b 1347 (Lisp_Object symbol)
7921925c
JB
1348{
1349 register Lisp_Object value;
1350
d9c2a0f2 1351 value = default_value (symbol);
1bfcade3 1352 return (EQ (value, Qunbound) ? Qnil : Qt);
7921925c
JB
1353}
1354
a7ca3326 1355DEFUN ("default-value", Fdefault_value, Sdefault_value, 1, 1, 0,
8c1a1077
PJ
1356 doc: /* Return SYMBOL's default value.
1357This is the value that is seen in buffers that do not have their own values
1358for this variable. The default value is meaningful for variables with
1359local bindings in certain buffers. */)
5842a27b 1360 (Lisp_Object symbol)
7921925c 1361{
a104f656 1362 Lisp_Object value = default_value (symbol);
740ef0b5
KS
1363 if (!EQ (value, Qunbound))
1364 return value;
1365
1366 xsignal1 (Qvoid_variable, symbol);
7921925c
JB
1367}
1368
a7ca3326 1369DEFUN ("set-default", Fset_default, Sset_default, 2, 2, 0,
6e86a75d 1370 doc: /* Set SYMBOL's default value to VALUE. SYMBOL and VALUE are evaluated.
8c1a1077
PJ
1371The default value is seen in buffers that do not have their own values
1372for this variable. */)
5842a27b 1373 (Lisp_Object symbol, Lisp_Object value)
7921925c 1374{
844e0de1 1375 sym_t sym;
7921925c 1376
b7826503 1377 CHECK_SYMBOL (symbol);
ce5b453a 1378 if (SYMBOL_CONSTANT_P (symbol))
7921925c 1379 {
ce5b453a
SM
1380 if (NILP (Fkeywordp (symbol))
1381 || !EQ (value, Fdefault_value (symbol)))
1382 xsignal1 (Qsetting_constant, symbol);
1383 else
1384 /* Allow setting keywords to their own value. */
1385 return value;
1386 }
1387 sym = XSYMBOL (symbol);
7921925c 1388
ce5b453a 1389 start:
844e0de1 1390 switch (SYMBOL_REDIRECT (sym))
ce5b453a
SM
1391 {
1392 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1393 case SYMBOL_PLAINVAL: return Fset (symbol, value);
1394 case SYMBOL_LOCALIZED:
1395 {
1396 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
984ef137 1397
ce5b453a
SM
1398 /* Store new value into the DEFAULT-VALUE slot. */
1399 XSETCDR (blv->defcell, value);
bfb96cb7 1400
ce5b453a
SM
1401 /* If the default binding is now loaded, set the REALVALUE slot too. */
1402 if (blv->fwd && EQ (blv->defcell, blv->valcell))
1403 store_symval_forwarding (blv->fwd, value, NULL);
1404 return value;
1405 }
1406 case SYMBOL_FORWARDED:
1407 {
1408 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
7921925c 1409
ce5b453a
SM
1410 /* Handle variables like case-fold-search that have special slots
1411 in the buffer.
1412 Make them work apparently like Lisp_Buffer_Local_Value variables. */
1413 if (BUFFER_OBJFWDP (valcontents))
1414 {
1415 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1416 int idx = PER_BUFFER_IDX (offset);
7921925c 1417
4ce60d2e 1418 set_per_buffer_default (offset, value);
7921925c 1419
ce5b453a
SM
1420 /* If this variable is not always local in all buffers,
1421 set it in the buffers that don't nominally have a local value. */
1422 if (idx > 0)
1423 {
1424 struct buffer *b;
7921925c 1425
52b852c7 1426 FOR_EACH_BUFFER (b)
ce5b453a 1427 if (!PER_BUFFER_VALUE_P (b, idx))
4ce60d2e 1428 set_per_buffer_value (b, offset, value);
ce5b453a
SM
1429 }
1430 return value;
1431 }
1432 else
1433 return Fset (symbol, value);
1434 }
1088b922 1435 default: emacs_abort ();
ce5b453a 1436 }
7921925c 1437}
7921925c 1438\f
a5ca2b75
JB
1439/* Lisp functions for creating and removing buffer-local variables. */
1440
ce5b453a
SM
1441union Lisp_Val_Fwd
1442 {
1443 Lisp_Object value;
1444 union Lisp_Fwd *fwd;
1445 };
1446
1447static struct Lisp_Buffer_Local_Value *
844e0de1 1448make_blv (sym_t sym, bool forwarded,
de1339b0 1449 union Lisp_Val_Fwd valcontents)
ce5b453a 1450{
38182d90 1451 struct Lisp_Buffer_Local_Value *blv = xmalloc (sizeof *blv);
c632dfda
JD
1452 Lisp_Object symbol;
1453 Lisp_Object tem;
1454
1455 XSETSYMBOL (symbol, sym);
1456 tem = Fcons (symbol, (forwarded
1457 ? do_symval_forwarding (valcontents.fwd)
1458 : valcontents.value));
1459
ce5b453a
SM
1460 /* Buffer_Local_Values cannot have as realval a buffer-local
1461 or keyboard-local forwarding. */
1462 eassert (!(forwarded && BUFFER_OBJFWDP (valcontents.fwd)));
1463 eassert (!(forwarded && KBOARD_OBJFWDP (valcontents.fwd)));
1464 blv->fwd = forwarded ? valcontents.fwd : NULL;
a04e2c62 1465 set_blv_where (blv, Qnil);
ce5b453a
SM
1466 blv->frame_local = 0;
1467 blv->local_if_set = 0;
a04e2c62
DA
1468 set_blv_defcell (blv, tem);
1469 set_blv_valcell (blv, tem);
1470 set_blv_found (blv, 0);
ce5b453a
SM
1471 return blv;
1472}
1473
a7ca3326 1474DEFUN ("make-variable-buffer-local", Fmake_variable_buffer_local,
16a97296 1475 Smake_variable_buffer_local, 1, 1, "vMake Variable Buffer Local: ",
8c1a1077
PJ
1476 doc: /* Make VARIABLE become buffer-local whenever it is set.
1477At any time, the value for the current buffer is in effect,
1478unless the variable has never been set in this buffer,
1479in which case the default value is in effect.
1480Note that binding the variable with `let', or setting it while
1481a `let'-style binding made in this buffer is in effect,
bfb96cb7 1482does not make the variable buffer-local. Return VARIABLE.
8c1a1077 1483
450533b0
SM
1484This globally affects all uses of this variable, so it belongs together with
1485the variable declaration, rather than with its uses (if you just want to make
1486a variable local to the current buffer for one particular use, use
1487`make-local-variable'). Buffer-local bindings are normally cleared
1488while setting up a new major mode, unless they have a `permanent-local'
1489property.
a9908653 1490
8c1a1077 1491The function `default-value' gets the default value and `set-default' sets it. */)
5842a27b 1492 (register Lisp_Object variable)
7921925c 1493{
844e0de1 1494 sym_t sym;
ce5b453a 1495 struct Lisp_Buffer_Local_Value *blv = NULL;
bfe3e0a2 1496 union Lisp_Val_Fwd valcontents IF_LINT (= {LISP_INITIALLY_ZERO});
de1339b0 1497 bool forwarded IF_LINT (= 0);
7921925c 1498
b7826503 1499 CHECK_SYMBOL (variable);
ce5b453a 1500 sym = XSYMBOL (variable);
7921925c 1501
ce5b453a 1502 start:
844e0de1 1503 switch (SYMBOL_REDIRECT (sym))
fd9440c5 1504 {
ce5b453a
SM
1505 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1506 case SYMBOL_PLAINVAL:
1507 forwarded = 0; valcontents.value = SYMBOL_VAL (sym);
1508 if (EQ (valcontents.value, Qunbound))
1509 valcontents.value = Qnil;
1510 break;
1511 case SYMBOL_LOCALIZED:
1512 blv = SYMBOL_BLV (sym);
1513 if (blv->frame_local)
1514 error ("Symbol %s may not be buffer-local",
1515 SDATA (SYMBOL_NAME (variable)));
1516 break;
1517 case SYMBOL_FORWARDED:
1518 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1519 if (KBOARD_OBJFWDP (valcontents.fwd))
1520 error ("Symbol %s may not be buffer-local",
1521 SDATA (SYMBOL_NAME (variable)));
1522 else if (BUFFER_OBJFWDP (valcontents.fwd))
1523 return variable;
1524 break;
1088b922 1525 default: emacs_abort ();
fd9440c5 1526 }
ce5b453a 1527
844e0de1 1528 if (SYMBOL_CONSTANT (sym))
ce5b453a
SM
1529 error ("Symbol %s may not be buffer-local", SDATA (SYMBOL_NAME (variable)));
1530
1531 if (!blv)
7921925c 1532 {
ce5b453a 1533 blv = make_blv (sym, forwarded, valcontents);
844e0de1 1534 SET_SYMBOL_REDIRECT (sym, SYMBOL_LOCALIZED);
ce5b453a
SM
1535 SET_SYMBOL_BLV (sym, blv);
1536 {
1537 Lisp_Object symbol;
1538 XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
1539 if (let_shadows_global_binding_p (symbol))
8b1e1112
SM
1540 message ("Making %s buffer-local while let-bound!",
1541 SDATA (SYMBOL_NAME (variable)));
ce5b453a 1542 }
7921925c 1543 }
ce5b453a
SM
1544
1545 blv->local_if_set = 1;
d9c2a0f2 1546 return variable;
7921925c
JB
1547}
1548
a7ca3326 1549DEFUN ("make-local-variable", Fmake_local_variable, Smake_local_variable,
8c1a1077
PJ
1550 1, 1, "vMake Local Variable: ",
1551 doc: /* Make VARIABLE have a separate value in the current buffer.
1552Other buffers will continue to share a common default value.
1553\(The buffer-local value of VARIABLE starts out as the same value
1554VARIABLE previously had. If VARIABLE was void, it remains void.\)
a9908653 1555Return VARIABLE.
8c1a1077
PJ
1556
1557If the variable is already arranged to become local when set,
1558this function causes a local value to exist for this buffer,
1559just as setting the variable would do.
1560
1561This function returns VARIABLE, and therefore
1562 (set (make-local-variable 'VARIABLE) VALUE-EXP)
1563works.
1564
a9908653
RS
1565See also `make-variable-buffer-local'.
1566
8c1a1077 1567Do not use `make-local-variable' to make a hook variable buffer-local.
515f3f25 1568Instead, use `add-hook' and specify t for the LOCAL argument. */)
de1339b0 1569 (Lisp_Object variable)
7921925c 1570{
de1339b0
PE
1571 Lisp_Object tem;
1572 bool forwarded IF_LINT (= 0);
bfe3e0a2 1573 union Lisp_Val_Fwd valcontents IF_LINT (= {LISP_INITIALLY_ZERO});
844e0de1 1574 sym_t sym;
ce5b453a 1575 struct Lisp_Buffer_Local_Value *blv = NULL;
7921925c 1576
b7826503 1577 CHECK_SYMBOL (variable);
ce5b453a 1578 sym = XSYMBOL (variable);
7921925c 1579
ce5b453a 1580 start:
844e0de1 1581 switch (SYMBOL_REDIRECT (sym))
ce5b453a
SM
1582 {
1583 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1584 case SYMBOL_PLAINVAL:
1585 forwarded = 0; valcontents.value = SYMBOL_VAL (sym); break;
1586 case SYMBOL_LOCALIZED:
1587 blv = SYMBOL_BLV (sym);
1588 if (blv->frame_local)
1589 error ("Symbol %s may not be buffer-local",
1590 SDATA (SYMBOL_NAME (variable)));
1591 break;
1592 case SYMBOL_FORWARDED:
1593 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1594 if (KBOARD_OBJFWDP (valcontents.fwd))
1595 error ("Symbol %s may not be buffer-local",
1596 SDATA (SYMBOL_NAME (variable)));
1597 break;
1088b922 1598 default: emacs_abort ();
ce5b453a
SM
1599 }
1600
844e0de1 1601 if (SYMBOL_CONSTANT (sym))
8b1e1112
SM
1602 error ("Symbol %s may not be buffer-local",
1603 SDATA (SYMBOL_NAME (variable)));
7921925c 1604
ce5b453a
SM
1605 if (blv ? blv->local_if_set
1606 : (forwarded && BUFFER_OBJFWDP (valcontents.fwd)))
7921925c 1607 {
d9c2a0f2 1608 tem = Fboundp (variable);
7921925c
JB
1609 /* Make sure the symbol has a local value in this particular buffer,
1610 by setting it to the same value it already has. */
d9c2a0f2
EN
1611 Fset (variable, (EQ (tem, Qt) ? Fsymbol_value (variable) : Qunbound));
1612 return variable;
7921925c 1613 }
ce5b453a 1614 if (!blv)
7921925c 1615 {
ce5b453a 1616 blv = make_blv (sym, forwarded, valcontents);
844e0de1 1617 SET_SYMBOL_REDIRECT (sym, SYMBOL_LOCALIZED);
ce5b453a
SM
1618 SET_SYMBOL_BLV (sym, blv);
1619 {
1620 Lisp_Object symbol;
1621 XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
1622 if (let_shadows_global_binding_p (symbol))
8b1e1112
SM
1623 message ("Making %s local to %s while let-bound!",
1624 SDATA (SYMBOL_NAME (variable)),
4b4deea2 1625 SDATA (BVAR (current_buffer, name)));
ce5b453a 1626 }
7921925c 1627 }
ce5b453a 1628
42e975f0 1629 /* Make sure this buffer has its own value of symbol. */
ce5b453a 1630 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
4b4deea2 1631 tem = Fassq (variable, BVAR (current_buffer, local_var_alist));
a33ef3ab 1632 if (NILP (tem))
7921925c 1633 {
ce5b453a
SM
1634 if (let_shadows_buffer_binding_p (sym))
1635 message ("Making %s buffer-local while locally let-bound!",
1636 SDATA (SYMBOL_NAME (variable)));
1637
a5d004a1
RS
1638 /* Swap out any local binding for some other buffer, and make
1639 sure the current value is permanently recorded, if it's the
1640 default value. */
d9c2a0f2 1641 find_symbol_value (variable);
a5d004a1 1642
39eb03f1
PE
1643 bset_local_var_alist
1644 (current_buffer,
1645 Fcons (Fcons (variable, XCDR (blv->defcell)),
1646 BVAR (current_buffer, local_var_alist)));
7921925c
JB
1647
1648 /* Make sure symbol does not think it is set up for this buffer;
42e975f0 1649 force it to look once again for this buffer's value. */
ce5b453a 1650 if (current_buffer == XBUFFER (blv->where))
a04e2c62
DA
1651 set_blv_where (blv, Qnil);
1652 set_blv_found (blv, 0);
7921925c 1653 }
a5ca2b75 1654
42e975f0
RS
1655 /* If the symbol forwards into a C variable, then load the binding
1656 for this buffer now. If C code modifies the variable before we
1657 load the binding in, then that new value will clobber the default
1658 binding the next time we unload it. */
ce5b453a
SM
1659 if (blv->fwd)
1660 swap_in_symval_forwarding (sym, blv);
a5ca2b75 1661
d9c2a0f2 1662 return variable;
7921925c
JB
1663}
1664
1665DEFUN ("kill-local-variable", Fkill_local_variable, Skill_local_variable,
8c1a1077
PJ
1666 1, 1, "vKill Local Variable: ",
1667 doc: /* Make VARIABLE no longer have a separate value in the current buffer.
bfb96cb7 1668From now on the default value will apply in this buffer. Return VARIABLE. */)
5842a27b 1669 (register Lisp_Object variable)
7921925c 1670{
ce5b453a
SM
1671 register Lisp_Object tem;
1672 struct Lisp_Buffer_Local_Value *blv;
844e0de1 1673 sym_t sym;
7921925c 1674
b7826503 1675 CHECK_SYMBOL (variable);
ce5b453a 1676 sym = XSYMBOL (variable);
7921925c 1677
ce5b453a 1678 start:
844e0de1 1679 switch (SYMBOL_REDIRECT (sym))
7921925c 1680 {
ce5b453a
SM
1681 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1682 case SYMBOL_PLAINVAL: return variable;
1683 case SYMBOL_FORWARDED:
1684 {
1685 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1686 if (BUFFER_OBJFWDP (valcontents))
1687 {
1688 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1689 int idx = PER_BUFFER_IDX (offset);
1690
1691 if (idx > 0)
1692 {
1693 SET_PER_BUFFER_VALUE_P (current_buffer, idx, 0);
4ce60d2e
DA
1694 set_per_buffer_value (current_buffer, offset,
1695 per_buffer_default (offset));
ce5b453a
SM
1696 }
1697 }
1698 return variable;
1699 }
1700 case SYMBOL_LOCALIZED:
1701 blv = SYMBOL_BLV (sym);
1702 if (blv->frame_local)
1703 return variable;
1704 break;
1088b922 1705 default: emacs_abort ();
7921925c
JB
1706 }
1707
42e975f0 1708 /* Get rid of this buffer's alist element, if any. */
ad97b375 1709 XSETSYMBOL (variable, sym); /* Propagate variable indirection. */
4b4deea2 1710 tem = Fassq (variable, BVAR (current_buffer, local_var_alist));
a33ef3ab 1711 if (!NILP (tem))
39eb03f1
PE
1712 bset_local_var_alist
1713 (current_buffer,
1714 Fdelq (tem, BVAR (current_buffer, local_var_alist)));
7921925c 1715
42e975f0
RS
1716 /* If the symbol is set up with the current buffer's binding
1717 loaded, recompute its value. We have to do it now, or else
1718 forwarded objects won't work right. */
7921925c 1719 {
ce5b453a
SM
1720 Lisp_Object buf; XSETBUFFER (buf, current_buffer);
1721 if (EQ (buf, blv->where))
79c83e03 1722 {
a04e2c62 1723 set_blv_where (blv, Qnil);
9e677988 1724 blv->found = 0;
978dd578 1725 find_symbol_value (variable);
79c83e03 1726 }
7921925c
JB
1727 }
1728
d9c2a0f2 1729 return variable;
7921925c 1730}
62476adc 1731
b0c2d1c6
RS
1732/* Lisp functions for creating and removing buffer-local variables. */
1733
ab795c65
GM
1734/* Obsolete since 22.2. NB adjust doc of modify-frame-parameters
1735 when/if this is removed. */
1736
b0c2d1c6 1737DEFUN ("make-variable-frame-local", Fmake_variable_frame_local, Smake_variable_frame_local,
8c1a1077
PJ
1738 1, 1, "vMake Variable Frame Local: ",
1739 doc: /* Enable VARIABLE to have frame-local bindings.
4d4d36b1
RS
1740This does not create any frame-local bindings for VARIABLE,
1741it just makes them possible.
1742
1743A frame-local binding is actually a frame parameter value.
1744If a frame F has a value for the frame parameter named VARIABLE,
1745that also acts as a frame-local binding for VARIABLE in F--
1746provided this function has been called to enable VARIABLE
1747to have frame-local bindings at all.
1748
1749The only way to create a frame-local binding for VARIABLE in a frame
1750is to set the VARIABLE frame parameter of that frame. See
1751`modify-frame-parameters' for how to set frame parameters.
1752
a02a1384
GM
1753Note that since Emacs 23.1, variables cannot be both buffer-local and
1754frame-local any more (buffer-local bindings used to take precedence over
1755frame-local bindings). */)
de1339b0 1756 (Lisp_Object variable)
b0c2d1c6 1757{
de1339b0 1758 bool forwarded;
ce5b453a 1759 union Lisp_Val_Fwd valcontents;
844e0de1 1760 sym_t sym;
ce5b453a 1761 struct Lisp_Buffer_Local_Value *blv = NULL;
b0c2d1c6 1762
b7826503 1763 CHECK_SYMBOL (variable);
ce5b453a 1764 sym = XSYMBOL (variable);
b0c2d1c6 1765
ce5b453a 1766 start:
844e0de1 1767 switch (SYMBOL_REDIRECT (sym))
42e975f0 1768 {
ce5b453a
SM
1769 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1770 case SYMBOL_PLAINVAL:
1771 forwarded = 0; valcontents.value = SYMBOL_VAL (sym);
1772 if (EQ (valcontents.value, Qunbound))
1773 valcontents.value = Qnil;
1774 break;
1775 case SYMBOL_LOCALIZED:
1776 if (SYMBOL_BLV (sym)->frame_local)
1777 return variable;
1778 else
1779 error ("Symbol %s may not be frame-local",
1780 SDATA (SYMBOL_NAME (variable)));
1781 case SYMBOL_FORWARDED:
1782 forwarded = 1; valcontents.fwd = SYMBOL_FWD (sym);
1783 if (KBOARD_OBJFWDP (valcontents.fwd) || BUFFER_OBJFWDP (valcontents.fwd))
1784 error ("Symbol %s may not be frame-local",
1785 SDATA (SYMBOL_NAME (variable)));
1786 break;
1088b922 1787 default: emacs_abort ();
42e975f0 1788 }
b0c2d1c6 1789
844e0de1 1790 if (SYMBOL_CONSTANT (sym))
ce5b453a
SM
1791 error ("Symbol %s may not be frame-local", SDATA (SYMBOL_NAME (variable)));
1792
1793 blv = make_blv (sym, forwarded, valcontents);
1794 blv->frame_local = 1;
844e0de1 1795 SET_SYMBOL_REDIRECT (sym, SYMBOL_LOCALIZED);
ce5b453a 1796 SET_SYMBOL_BLV (sym, blv);
8b1e1112
SM
1797 {
1798 Lisp_Object symbol;
1799 XSETSYMBOL (symbol, sym); /* In case `variable' is aliased. */
1800 if (let_shadows_global_binding_p (symbol))
1801 message ("Making %s frame-local while let-bound!",
1802 SDATA (SYMBOL_NAME (variable)));
1803 }
b0c2d1c6
RS
1804 return variable;
1805}
1806
a7ca3326 1807DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p,
8c1a1077
PJ
1808 1, 2, 0,
1809 doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER.
1810BUFFER defaults to the current buffer. */)
5842a27b 1811 (register Lisp_Object variable, Lisp_Object buffer)
62476adc 1812{
c48ead86 1813 register struct buffer *buf;
844e0de1 1814 sym_t sym;
c48ead86
KH
1815
1816 if (NILP (buffer))
1817 buf = current_buffer;
1818 else
1819 {
b7826503 1820 CHECK_BUFFER (buffer);
c48ead86
KH
1821 buf = XBUFFER (buffer);
1822 }
62476adc 1823
b7826503 1824 CHECK_SYMBOL (variable);
ce5b453a 1825 sym = XSYMBOL (variable);
be95bee9 1826
ce5b453a 1827 start:
844e0de1 1828 switch (SYMBOL_REDIRECT (sym))
c48ead86 1829 {
ce5b453a
SM
1830 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1831 case SYMBOL_PLAINVAL: return Qnil;
1832 case SYMBOL_LOCALIZED:
1833 {
1834 Lisp_Object tail, elt, tmp;
1835 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1836 XSETBUFFER (tmp, buf);
8d1d9587 1837 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
aa3830c4 1838
2f592f95
SM
1839 if (EQ (blv->where, tmp)) /* The binding is already loaded. */
1840 return blv_found (blv) ? Qt : Qnil;
1841 else
1842 for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
1843 {
1844 elt = XCAR (tail);
1845 if (EQ (variable, XCAR (elt)))
1846 {
1847 eassert (!blv->frame_local);
1848 return Qt;
1849 }
1850 }
ce5b453a
SM
1851 return Qnil;
1852 }
1853 case SYMBOL_FORWARDED:
1854 {
1855 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1856 if (BUFFER_OBJFWDP (valcontents))
1857 {
1858 int offset = XBUFFER_OBJFWD (valcontents)->offset;
1859 int idx = PER_BUFFER_IDX (offset);
1860 if (idx == -1 || PER_BUFFER_VALUE_P (buf, idx))
1861 return Qt;
1862 }
1863 return Qnil;
1864 }
1088b922 1865 default: emacs_abort ();
c48ead86 1866 }
62476adc 1867}
f4f04cee
RS
1868
1869DEFUN ("local-variable-if-set-p", Flocal_variable_if_set_p, Slocal_variable_if_set_p,
8c1a1077 1870 1, 2, 0,
1a5432bc
CY
1871 doc: /* Non-nil if VARIABLE is local in buffer BUFFER when set there.
1872BUFFER defaults to the current buffer.
1873
1874More precisely, return non-nil if either VARIABLE already has a local
1875value in BUFFER, or if VARIABLE is automatically buffer-local (see
1876`make-variable-buffer-local'). */)
5842a27b 1877 (register Lisp_Object variable, Lisp_Object buffer)
f4f04cee 1878{
844e0de1 1879 sym_t sym;
f4f04cee 1880
b7826503 1881 CHECK_SYMBOL (variable);
ce5b453a 1882 sym = XSYMBOL (variable);
f4f04cee 1883
ce5b453a 1884 start:
844e0de1 1885 switch (SYMBOL_REDIRECT (sym))
f4f04cee 1886 {
ce5b453a
SM
1887 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1888 case SYMBOL_PLAINVAL: return Qnil;
1889 case SYMBOL_LOCALIZED:
1890 {
1891 struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
1892 if (blv->local_if_set)
1893 return Qt;
1894 XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
1895 return Flocal_variable_p (variable, buffer);
1896 }
1897 case SYMBOL_FORWARDED:
1898 /* All BUFFER_OBJFWD slots become local if they are set. */
1899 return (BUFFER_OBJFWDP (SYMBOL_FWD (sym)) ? Qt : Qnil);
1088b922 1900 default: emacs_abort ();
f4f04cee 1901 }
f4f04cee 1902}
6b61353c
KH
1903
1904DEFUN ("variable-binding-locus", Fvariable_binding_locus, Svariable_binding_locus,
1905 1, 1, 0,
1906 doc: /* Return a value indicating where VARIABLE's current binding comes from.
1907If the current binding is buffer-local, the value is the current buffer.
1908If the current binding is frame-local, the value is the selected frame.
1909If the current binding is global (the default), the value is nil. */)
5842a27b 1910 (register Lisp_Object variable)
6b61353c 1911{
844e0de1 1912 sym_t sym;
6b61353c
KH
1913
1914 CHECK_SYMBOL (variable);
ce5b453a 1915 sym = XSYMBOL (variable);
6b61353c
KH
1916
1917 /* Make sure the current binding is actually swapped in. */
1918 find_symbol_value (variable);
1919
ce5b453a 1920 start:
844e0de1 1921 switch (SYMBOL_REDIRECT (sym))
6b61353c 1922 {
ce5b453a
SM
1923 case SYMBOL_VARALIAS: sym = indirect_variable (sym); goto start;
1924 case SYMBOL_PLAINVAL: return Qnil;
1925 case SYMBOL_FORWARDED:
1926 {
1927 union Lisp_Fwd *valcontents = SYMBOL_FWD (sym);
1928 if (KBOARD_OBJFWDP (valcontents))
d2a95ffb 1929 return Fframe_terminal (selected_frame);
ce5b453a
SM
1930 else if (!BUFFER_OBJFWDP (valcontents))
1931 return Qnil;
1932 }
1933 /* FALLTHROUGH */
1934 case SYMBOL_LOCALIZED:
6b61353c
KH
1935 /* For a local variable, record both the symbol and which
1936 buffer's or frame's value we are saving. */
1937 if (!NILP (Flocal_variable_p (variable, Qnil)))
1938 return Fcurrent_buffer ();
844e0de1 1939 else if (SYMBOL_REDIRECT (sym) == SYMBOL_LOCALIZED
a04e2c62 1940 && blv_found (SYMBOL_BLV (sym)))
ce5b453a
SM
1941 return SYMBOL_BLV (sym)->where;
1942 else
1943 return Qnil;
1088b922 1944 default: emacs_abort ();
6b61353c 1945 }
6b61353c 1946}
2a42d440 1947
c40bb1ba 1948/* This code is disabled now that we use the selected frame to return
7be68de5 1949 keyboard-local-values. */
c40bb1ba 1950#if 0
f57e2426 1951extern struct terminal *get_terminal (Lisp_Object display, int);
2a42d440 1952
a7ca3326 1953DEFUN ("terminal-local-value", Fterminal_local_value,
16a97296 1954 Sterminal_local_value, 2, 2, 0,
6ed8eeff 1955 doc: /* Return the terminal-local value of SYMBOL on TERMINAL.
2a42d440
KL
1956If SYMBOL is not a terminal-local variable, then return its normal
1957value, like `symbol-value'.
1958
708e05dc 1959TERMINAL may be a terminal object, a frame, or nil (meaning the
6ed8eeff 1960selected frame's terminal device). */)
5842a27b 1961 (Lisp_Object symbol, Lisp_Object terminal)
2a42d440
KL
1962{
1963 Lisp_Object result;
6ed8eeff
KL
1964 struct terminal *t = get_terminal (terminal, 1);
1965 push_kboard (t->kboard);
2a42d440 1966 result = Fsymbol_value (symbol);
256c9c3a 1967 pop_kboard ();
2a42d440
KL
1968 return result;
1969}
1970
a7ca3326 1971DEFUN ("set-terminal-local-value", Fset_terminal_local_value,
16a97296 1972 Sset_terminal_local_value, 3, 3, 0,
6ed8eeff 1973 doc: /* Set the terminal-local binding of SYMBOL on TERMINAL to VALUE.
2a42d440 1974If VARIABLE is not a terminal-local variable, then set its normal
7e59217d
KL
1975binding, like `set'.
1976
708e05dc 1977TERMINAL may be a terminal object, a frame, or nil (meaning the
6ed8eeff 1978selected frame's terminal device). */)
5842a27b 1979 (Lisp_Object symbol, Lisp_Object terminal, Lisp_Object value)
2a42d440
KL
1980{
1981 Lisp_Object result;
6ed8eeff 1982 struct terminal *t = get_terminal (terminal, 1);
256c9c3a 1983 push_kboard (d->kboard);
2a42d440 1984 result = Fset (symbol, value);
256c9c3a 1985 pop_kboard ();
2a42d440
KL
1986 return result;
1987}
c40bb1ba 1988#endif
7921925c 1989\f
ffd56f97
JB
1990/* Find the function at the end of a chain of symbol function indirections. */
1991
1992/* If OBJECT is a symbol, find the end of its function chain and
1993 return the value found there. If OBJECT is not a symbol, just
1994 return it. If there is a cycle in the function chain, signal a
1995 cyclic-function-indirection error.
1996
1997 This is like Findirect_function, except that it doesn't signal an
1998 error if the chain ends up unbound. */
1999Lisp_Object
971de7fb 2000indirect_function (register Lisp_Object object)
ffd56f97 2001{
eb8c3be9 2002 Lisp_Object tortoise, hare;
ffd56f97 2003
eb8c3be9 2004 hare = tortoise = object;
ffd56f97
JB
2005
2006 for (;;)
2007 {
eadf1faa 2008 if (!SYMBOLP (hare) || NILP (hare))
ffd56f97 2009 break;
1d59fbe3 2010 hare = SYMBOL_FUNCTION (hare);
eadf1faa 2011 if (!SYMBOLP (hare) || NILP (hare))
ffd56f97 2012 break;
1d59fbe3 2013 hare = SYMBOL_FUNCTION (hare);
ffd56f97 2014
1d59fbe3 2015 tortoise = SYMBOL_FUNCTION (tortoise);
ffd56f97 2016
eb8c3be9 2017 if (EQ (hare, tortoise))
740ef0b5 2018 xsignal1 (Qcyclic_function_indirection, object);
ffd56f97
JB
2019 }
2020
2021 return hare;
2022}
2023
a7ca3326 2024DEFUN ("indirect-function", Findirect_function, Sindirect_function, 1, 2, 0,
8c1a1077 2025 doc: /* Return the function at the end of OBJECT's function chain.
0ddb0ae8
TTN
2026If OBJECT is not a symbol, just return it. Otherwise, follow all
2027function indirections to find the final function binding and return it.
2028If the final symbol in the chain is unbound, signal a void-function error.
8350f087 2029Optional arg NOERROR non-nil means to return nil instead of signaling.
8c1a1077
PJ
2030Signal a cyclic-function-indirection error if there is a loop in the
2031function chain of symbols. */)
5842a27b 2032 (register Lisp_Object object, Lisp_Object noerror)
ffd56f97
JB
2033{
2034 Lisp_Object result;
2035
64de53d8
KS
2036 /* Optimize for no indirection. */
2037 result = object;
eadf1faa 2038 if (SYMBOLP (result) && !NILP (result)
1d59fbe3 2039 && (result = SYMBOL_FUNCTION (result), SYMBOLP (result)))
64de53d8 2040 result = indirect_function (result);
eadf1faa 2041 if (!NILP (result))
64de53d8 2042 return result;
ffd56f97 2043
64de53d8 2044 if (NILP (noerror))
740ef0b5 2045 xsignal1 (Qvoid_function, object);
ffd56f97 2046
64de53d8 2047 return Qnil;
ffd56f97
JB
2048}
2049\f
7abaf5cc 2050/* Extract and set vector and string elements. */
7921925c 2051
a7ca3326 2052DEFUN ("aref", Faref, Saref, 2, 2, 0,
8c1a1077
PJ
2053 doc: /* Return the element of ARRAY at index IDX.
2054ARRAY may be a vector, a string, a char-table, a bool-vector,
2055or a byte-code object. IDX starts at 0. */)
5842a27b 2056 (register Lisp_Object array, Lisp_Object idx)
7921925c 2057{
ace1712c 2058 register EMACS_INT idxval;
7921925c 2059
b7826503 2060 CHECK_NUMBER (idx);
7921925c 2061 idxval = XINT (idx);
e9ebc175 2062 if (STRINGP (array))
7921925c 2063 {
ace1712c 2064 int c;
d311d28c 2065 ptrdiff_t idxval_byte;
25638b07 2066
d5db4077 2067 if (idxval < 0 || idxval >= SCHARS (array))
c24e4efe 2068 args_out_of_range (array, idx);
25638b07 2069 if (! STRING_MULTIBYTE (array))
d5db4077 2070 return make_number ((unsigned char) SREF (array, idxval));
25638b07
RS
2071 idxval_byte = string_char_to_byte (array, idxval);
2072
62a6e103 2073 c = STRING_CHAR (SDATA (array) + idxval_byte);
25638b07 2074 return make_number (c);
7921925c 2075 }
4d276982
RS
2076 else if (BOOL_VECTOR_P (array))
2077 {
1c0a7493 2078 if (idxval < 0 || idxval >= bool_vector_size (array))
4d276982 2079 args_out_of_range (array, idx);
df5b4930 2080 return bool_vector_ref (array, idxval);
4d276982
RS
2081 }
2082 else if (CHAR_TABLE_P (array))
2083 {
e6e1f521
KH
2084 CHECK_CHARACTER (idx);
2085 return CHAR_TABLE_REF (array, idxval);
4d276982 2086 }
7921925c 2087 else
c24e4efe 2088 {
90d8445b 2089 ptrdiff_t size = 0;
7f358972 2090 if (VECTORP (array))
77b37c05 2091 size = ASIZE (array);
876c194c 2092 else if (COMPILEDP (array))
77b37c05 2093 size = ASIZE (array) & PSEUDOVECTOR_SIZE_MASK;
7f358972
RS
2094 else
2095 wrong_type_argument (Qarrayp, array);
2096
2097 if (idxval < 0 || idxval >= size)
c24e4efe 2098 args_out_of_range (array, idx);
b9598260 2099 return AREF (array, idxval);
c24e4efe 2100 }
7921925c
JB
2101}
2102
a7ca3326 2103DEFUN ("aset", Faset, Saset, 3, 3, 0,
8c1a1077 2104 doc: /* Store into the element of ARRAY at index IDX the value NEWELT.
bfb96cb7
FP
2105Return NEWELT. ARRAY may be a vector, a string, a char-table or a
2106bool-vector. IDX starts at 0. */)
5842a27b 2107 (register Lisp_Object array, Lisp_Object idx, Lisp_Object newelt)
7921925c 2108{
ace1712c 2109 register EMACS_INT idxval;
7921925c 2110
b7826503 2111 CHECK_NUMBER (idx);
7921925c 2112 idxval = XINT (idx);
0c64a8cd 2113 CHECK_ARRAY (array, Qarrayp);
7921925c
JB
2114 CHECK_IMPURE (array);
2115
e9ebc175 2116 if (VECTORP (array))
c24e4efe 2117 {
77b37c05 2118 if (idxval < 0 || idxval >= ASIZE (array))
c24e4efe 2119 args_out_of_range (array, idx);
28be1ada 2120 ASET (array, idxval, newelt);
c24e4efe 2121 }
4d276982
RS
2122 else if (BOOL_VECTOR_P (array))
2123 {
1c0a7493 2124 if (idxval < 0 || idxval >= bool_vector_size (array))
4d276982 2125 args_out_of_range (array, idx);
df5b4930 2126 bool_vector_set (array, idxval, !NILP (newelt));
4d276982
RS
2127 }
2128 else if (CHAR_TABLE_P (array))
2129 {
e6e1f521
KH
2130 CHECK_CHARACTER (idx);
2131 CHAR_TABLE_SET (array, idxval, newelt);
4d276982 2132 }
0fed43f3 2133 else
25638b07 2134 {
13bdea59 2135 int c;
25638b07 2136
d5db4077 2137 if (idxval < 0 || idxval >= SCHARS (array))
25638b07 2138 args_out_of_range (array, idx);
d9130605 2139 CHECK_CHARACTER (newelt);
13bdea59 2140 c = XFASTINT (newelt);
25638b07 2141
0fed43f3 2142 if (STRING_MULTIBYTE (array))
3c9de1af 2143 {
d311d28c
PE
2144 ptrdiff_t idxval_byte, nbytes;
2145 int prev_bytes, new_bytes;
0fed43f3
PE
2146 unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;
2147
2148 nbytes = SBYTES (array);
2149 idxval_byte = string_char_to_byte (array, idxval);
d5db4077 2150 p1 = SDATA (array) + idxval_byte;
0fed43f3
PE
2151 prev_bytes = BYTES_BY_CHAR_HEAD (*p1);
2152 new_bytes = CHAR_STRING (c, p0);
2153 if (prev_bytes != new_bytes)
2154 {
2155 /* We must relocate the string data. */
d311d28c 2156 ptrdiff_t nchars = SCHARS (array);
0fed43f3 2157 USE_SAFE_ALLOCA;
98c6f1e3 2158 unsigned char *str = SAFE_ALLOCA (nbytes);
0fed43f3 2159
0fed43f3 2160 memcpy (str, SDATA (array), nbytes);
69f7f524 2161 allocate_string_data (array, nchars,
0fed43f3
PE
2162 nbytes + new_bytes - prev_bytes);
2163 memcpy (SDATA (array), str, idxval_byte);
2164 p1 = SDATA (array) + idxval_byte;
2165 memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes,
2166 nbytes - (idxval_byte + prev_bytes));
2167 SAFE_FREE ();
2168 clear_string_char_byte_cache ();
2169 }
2170 while (new_bytes--)
2171 *p1++ = *p0++;
3c9de1af 2172 }
0fed43f3 2173 else
5dff5999 2174 {
0fed43f3
PE
2175 if (! SINGLE_BYTE_CHAR_P (c))
2176 {
2177 int i;
2178
2179 for (i = SBYTES (array) - 1; i >= 0; i--)
2180 if (SREF (array, i) >= 0x80)
2181 args_out_of_range (array, newelt);
2182 /* ARRAY is an ASCII string. Convert it to a multibyte
2183 string, and try `aset' again. */
2184 STRING_SET_MULTIBYTE (array);
2185 return Faset (array, idx, newelt);
2186 }
2187 SSET (array, idxval, c);
5dff5999 2188 }
7921925c
JB
2189 }
2190
2191 return newelt;
2192}
7921925c
JB
2193\f
2194/* Arithmetic functions */
2195
ebb99847
BR
2196Lisp_Object
2197arithcompare (Lisp_Object num1, Lisp_Object num2, enum Arith_Comparison comparison)
7921925c 2198{
6bbd7a29 2199 double f1 = 0, f2 = 0;
de1339b0 2200 bool floatp = 0;
7921925c 2201
b7826503
PJ
2202 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num1);
2203 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (num2);
7921925c 2204
e9ebc175 2205 if (FLOATP (num1) || FLOATP (num2))
7921925c
JB
2206 {
2207 floatp = 1;
7539e11f
KR
2208 f1 = (FLOATP (num1)) ? XFLOAT_DATA (num1) : XINT (num1);
2209 f2 = (FLOATP (num2)) ? XFLOAT_DATA (num2) : XINT (num2);
7921925c 2210 }
7921925c
JB
2211
2212 switch (comparison)
2213 {
ebb99847 2214 case ARITH_EQUAL:
7921925c
JB
2215 if (floatp ? f1 == f2 : XINT (num1) == XINT (num2))
2216 return Qt;
2217 return Qnil;
2218
ebb99847 2219 case ARITH_NOTEQUAL:
7921925c
JB
2220 if (floatp ? f1 != f2 : XINT (num1) != XINT (num2))
2221 return Qt;
2222 return Qnil;
2223
ebb99847 2224 case ARITH_LESS:
7921925c
JB
2225 if (floatp ? f1 < f2 : XINT (num1) < XINT (num2))
2226 return Qt;
2227 return Qnil;
2228
ebb99847 2229 case ARITH_LESS_OR_EQUAL:
7921925c
JB
2230 if (floatp ? f1 <= f2 : XINT (num1) <= XINT (num2))
2231 return Qt;
2232 return Qnil;
2233
ebb99847 2234 case ARITH_GRTR:
7921925c
JB
2235 if (floatp ? f1 > f2 : XINT (num1) > XINT (num2))
2236 return Qt;
2237 return Qnil;
2238
ebb99847 2239 case ARITH_GRTR_OR_EQUAL:
7921925c
JB
2240 if (floatp ? f1 >= f2 : XINT (num1) >= XINT (num2))
2241 return Qt;
2242 return Qnil;
25e40a4b
JB
2243
2244 default:
1088b922 2245 emacs_abort ();
7921925c
JB
2246 }
2247}
2248
ebb99847
BR
2249static Lisp_Object
2250arithcompare_driver (ptrdiff_t nargs, Lisp_Object *args,
2251 enum Arith_Comparison comparison)
7921925c 2252{
56a0e352
PE
2253 ptrdiff_t argnum;
2254 for (argnum = 1; argnum < nargs; ++argnum)
ebb99847 2255 {
4c539a7b 2256 if (EQ (Qnil, arithcompare (args[argnum - 1], args[argnum], comparison)))
ebb99847
BR
2257 return Qnil;
2258 }
2259 return Qt;
7921925c
JB
2260}
2261
ebb99847 2262DEFUN ("=", Feqlsign, Seqlsign, 1, MANY, 0,
53482f41
DA
2263 doc: /* Return t if args, all numbers or markers, are equal.
2264usage: (= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
ebb99847 2265 (ptrdiff_t nargs, Lisp_Object *args)
7921925c 2266{
ebb99847 2267 return arithcompare_driver (nargs, args, ARITH_EQUAL);
7921925c
JB
2268}
2269
ebb99847 2270DEFUN ("<", Flss, Slss, 1, MANY, 0,
7b385b02 2271 doc: /* Return t if each arg (a number or marker), is less than the next arg.
53482f41 2272usage: (< NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
ebb99847 2273 (ptrdiff_t nargs, Lisp_Object *args)
7921925c 2274{
ebb99847 2275 return arithcompare_driver (nargs, args, ARITH_LESS);
7921925c
JB
2276}
2277
ebb99847 2278DEFUN (">", Fgtr, Sgtr, 1, MANY, 0,
7b385b02 2279 doc: /* Return t if each arg (a number or marker) is greater than the next arg.
53482f41 2280usage: (> NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
ebb99847 2281 (ptrdiff_t nargs, Lisp_Object *args)
7921925c 2282{
ebb99847 2283 return arithcompare_driver (nargs, args, ARITH_GRTR);
7921925c
JB
2284}
2285
ebb99847 2286DEFUN ("<=", Fleq, Sleq, 1, MANY, 0,
7b385b02 2287 doc: /* Return t if each arg (a number or marker) is less than or equal to the next.
53482f41 2288usage: (<= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
ebb99847
BR
2289 (ptrdiff_t nargs, Lisp_Object *args)
2290{
2291 return arithcompare_driver (nargs, args, ARITH_LESS_OR_EQUAL);
2292}
2293
2294DEFUN (">=", Fgeq, Sgeq, 1, MANY, 0,
7b385b02 2295 doc: /* Return t if each arg (a number or marker) is greater than or equal to the next.
bd21bf41 2296usage: (>= NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
ebb99847 2297 (ptrdiff_t nargs, Lisp_Object *args)
7921925c 2298{
ebb99847 2299 return arithcompare_driver (nargs, args, ARITH_GRTR_OR_EQUAL);
7921925c
JB
2300}
2301
2302DEFUN ("/=", Fneq, Sneq, 2, 2, 0,
8c1a1077 2303 doc: /* Return t if first arg is not equal to second arg. Both must be numbers or markers. */)
5842a27b 2304 (register Lisp_Object num1, Lisp_Object num2)
7921925c 2305{
ebb99847 2306 return arithcompare (num1, num2, ARITH_NOTEQUAL);
7921925c 2307}
7921925c 2308\f
be44ca6c
PE
2309/* Convert the cons-of-integers, integer, or float value C to an
2310 unsigned value with maximum value MAX. Signal an error if C does not
2311 have a valid format or is out of range. */
2312uintmax_t
2313cons_to_unsigned (Lisp_Object c, uintmax_t max)
2314{
de1339b0 2315 bool valid = 0;
be44ca6c
PE
2316 uintmax_t val IF_LINT (= 0);
2317 if (INTEGERP (c))
2318 {
2319 valid = 0 <= XINT (c);
2320 val = XINT (c);
2321 }
2322 else if (FLOATP (c))
2323 {
2324 double d = XFLOAT_DATA (c);
2325 if (0 <= d
2326 && d < (max == UINTMAX_MAX ? (double) UINTMAX_MAX + 1 : max + 1))
2327 {
2328 val = d;
2329 valid = 1;
2330 }
2331 }
2332 else if (CONSP (c) && NATNUMP (XCAR (c)))
2333 {
2334 uintmax_t top = XFASTINT (XCAR (c));
2335 Lisp_Object rest = XCDR (c);
2336 if (top <= UINTMAX_MAX >> 24 >> 16
2337 && CONSP (rest)
2338 && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
2339 && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
2340 {
2341 uintmax_t mid = XFASTINT (XCAR (rest));
2342 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
2343 valid = 1;
2344 }
2345 else if (top <= UINTMAX_MAX >> 16)
2346 {
2347 if (CONSP (rest))
2348 rest = XCAR (rest);
2349 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
2350 {
2351 val = top << 16 | XFASTINT (rest);
2352 valid = 1;
2353 }
2354 }
2355 }
51cf3e31 2356
be44ca6c
PE
2357 if (! (valid && val <= max))
2358 error ("Not an in-range integer, float, or cons of integers");
2359 return val;
51cf3e31
JB
2360}
2361
be44ca6c
PE
2362/* Convert the cons-of-integers, integer, or float value C to a signed
2363 value with extrema MIN and MAX. Signal an error if C does not have
2364 a valid format or is out of range. */
2365intmax_t
2366cons_to_signed (Lisp_Object c, intmax_t min, intmax_t max)
51cf3e31 2367{
de1339b0 2368 bool valid = 0;
be44ca6c 2369 intmax_t val IF_LINT (= 0);
51cf3e31 2370 if (INTEGERP (c))
be44ca6c
PE
2371 {
2372 val = XINT (c);
2373 valid = 1;
2374 }
2375 else if (FLOATP (c))
2376 {
2377 double d = XFLOAT_DATA (c);
2378 if (min <= d
2379 && d < (max == INTMAX_MAX ? (double) INTMAX_MAX + 1 : max + 1))
2380 {
2381 val = d;
2382 valid = 1;
2383 }
2384 }
2385 else if (CONSP (c) && INTEGERP (XCAR (c)))
2386 {
2387 intmax_t top = XINT (XCAR (c));
2388 Lisp_Object rest = XCDR (c);
2389 if (INTMAX_MIN >> 24 >> 16 <= top && top <= INTMAX_MAX >> 24 >> 16
2390 && CONSP (rest)
2391 && NATNUMP (XCAR (rest)) && XFASTINT (XCAR (rest)) < 1 << 24
2392 && NATNUMP (XCDR (rest)) && XFASTINT (XCDR (rest)) < 1 << 16)
2393 {
2394 intmax_t mid = XFASTINT (XCAR (rest));
2395 val = top << 24 << 16 | mid << 16 | XFASTINT (XCDR (rest));
2396 valid = 1;
2397 }
2398 else if (INTMAX_MIN >> 16 <= top && top <= INTMAX_MAX >> 16)
2399 {
2400 if (CONSP (rest))
2401 rest = XCAR (rest);
2402 if (NATNUMP (rest) && XFASTINT (rest) < 1 << 16)
2403 {
2404 val = top << 16 | XFASTINT (rest);
2405 valid = 1;
2406 }
2407 }
2408 }
2409
2410 if (! (valid && min <= val && val <= max))
2411 error ("Not an in-range integer, float, or cons of integers");
2412 return val;
51cf3e31
JB
2413}
2414\f
a7ca3326 2415DEFUN ("number-to-string", Fnumber_to_string, Snumber_to_string, 1, 1, 0,
bfb96cb7 2416 doc: /* Return the decimal representation of NUMBER as a string.
8c1a1077
PJ
2417Uses a minus sign if negative.
2418NUMBER may be an integer or a floating point number. */)
5842a27b 2419 (Lisp_Object number)
7921925c 2420{
99027bdd
PE
2421 char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))];
2422 int len;
7921925c 2423
b7826503 2424 CHECK_NUMBER_OR_FLOAT (number);
7921925c 2425
d9c2a0f2 2426 if (FLOATP (number))
99027bdd
PE
2427 len = float_to_string (buffer, XFLOAT_DATA (number));
2428 else
2429 len = sprintf (buffer, "%"pI"d", XINT (number));
7921925c 2430
99027bdd 2431 return make_unibyte_string (buffer, len);
7921925c
JB
2432}
2433
a7ca3326 2434DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0,
558ee900 2435 doc: /* Parse STRING as a decimal number and return the number.
12cb2b06
PE
2436Ignore leading spaces and tabs, and all trailing chars. Return 0 if
2437STRING cannot be parsed as an integer or floating point number.
8c1a1077
PJ
2438
2439If BASE, interpret STRING as a number in that base. If BASE isn't
2440present, base 10 is used. BASE must be between 2 and 16 (inclusive).
12cb2b06 2441If the base used is not 10, STRING is always parsed as an integer. */)
5842a27b 2442 (register Lisp_Object string, Lisp_Object base)
7921925c 2443{
57ace6d0 2444 register char *p;
342858a5 2445 register int b;
452f4150 2446 Lisp_Object val;
25e40a4b 2447
b7826503 2448 CHECK_STRING (string);
7921925c 2449
3883fbeb
RS
2450 if (NILP (base))
2451 b = 10;
2452 else
2453 {
b7826503 2454 CHECK_NUMBER (base);
d311d28c 2455 if (! (2 <= XINT (base) && XINT (base) <= 16))
740ef0b5 2456 xsignal1 (Qargs_out_of_range, base);
d311d28c 2457 b = XINT (base);
3883fbeb
RS
2458 }
2459
57ace6d0 2460 p = SSDATA (string);
0a3e4d65 2461 while (*p == ' ' || *p == '\t')
25e40a4b
JB
2462 p++;
2463
452f4150
PE
2464 val = string_to_number (p, b, 1);
2465 return NILP (val) ? make_number (0) : val;
7921925c 2466}
7403b5c8 2467\f
7921925c 2468enum arithop
7a283f36
GM
2469 {
2470 Aadd,
2471 Asub,
2472 Amult,
2473 Adiv,
2474 Alogand,
2475 Alogior,
2476 Alogxor,
2477 Amax,
2478 Amin
2479 };
2480
f66c7cf8
PE
2481static Lisp_Object float_arith_driver (double, ptrdiff_t, enum arithop,
2482 ptrdiff_t, Lisp_Object *);
112396d6 2483static Lisp_Object
f66c7cf8 2484arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args)
7921925c 2485{
de1339b0
PE
2486 Lisp_Object val;
2487 ptrdiff_t argnum, ok_args;
2488 EMACS_INT accum = 0;
2489 EMACS_INT next, ok_accum;
2490 bool overflow = 0;
0ae6bdee 2491
7393bcbb 2492 switch (code)
7921925c
JB
2493 {
2494 case Alogior:
2495 case Alogxor:
2496 case Aadd:
2497 case Asub:
7a283f36
GM
2498 accum = 0;
2499 break;
7921925c 2500 case Amult:
7a283f36
GM
2501 accum = 1;
2502 break;
7921925c 2503 case Alogand:
7a283f36
GM
2504 accum = -1;
2505 break;
2506 default:
2507 break;
7921925c
JB
2508 }
2509
2510 for (argnum = 0; argnum < nargs; argnum++)
2511 {
0ae6bdee
PE
2512 if (! overflow)
2513 {
2514 ok_args = argnum;
2515 ok_accum = accum;
2516 }
2517
7a283f36
GM
2518 /* Using args[argnum] as argument to CHECK_NUMBER_... */
2519 val = args[argnum];
b7826503 2520 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
7921925c 2521
7a283f36 2522 if (FLOATP (val))
0ae6bdee 2523 return float_arith_driver (ok_accum, ok_args, code,
7a283f36
GM
2524 nargs, args);
2525 args[argnum] = val;
7921925c 2526 next = XINT (args[argnum]);
7393bcbb 2527 switch (code)
7921925c 2528 {
7a283f36 2529 case Aadd:
0ae6bdee
PE
2530 if (INT_ADD_OVERFLOW (accum, next))
2531 {
2532 overflow = 1;
2533 accum &= INTMASK;
2534 }
7a283f36
GM
2535 accum += next;
2536 break;
7921925c 2537 case Asub:
0ae6bdee
PE
2538 if (INT_SUBTRACT_OVERFLOW (accum, next))
2539 {
2540 overflow = 1;
2541 accum &= INTMASK;
2542 }
e64981da 2543 accum = argnum ? accum - next : nargs == 1 ? - next : next;
7921925c 2544 break;
7a283f36 2545 case Amult:
0ae6bdee
PE
2546 if (INT_MULTIPLY_OVERFLOW (accum, next))
2547 {
c8a9ca5a 2548 EMACS_UINT a = accum, b = next, ab = a * b;
0ae6bdee 2549 overflow = 1;
c8a9ca5a 2550 accum = ab & INTMASK;
0ae6bdee
PE
2551 }
2552 else
2553 accum *= next;
7a283f36 2554 break;
7921925c 2555 case Adiv:
7a283f36
GM
2556 if (!argnum)
2557 accum = next;
87fbf902
RS
2558 else
2559 {
2560 if (next == 0)
740ef0b5 2561 xsignal0 (Qarith_error);
87fbf902
RS
2562 accum /= next;
2563 }
7921925c 2564 break;
7a283f36
GM
2565 case Alogand:
2566 accum &= next;
2567 break;
2568 case Alogior:
2569 accum |= next;
2570 break;
2571 case Alogxor:
2572 accum ^= next;
2573 break;
2574 case Amax:
2575 if (!argnum || next > accum)
2576 accum = next;
2577 break;
2578 case Amin:
2579 if (!argnum || next < accum)
2580 accum = next;
2581 break;
7921925c
JB
2582 }
2583 }
2584
f187f1f7 2585 XSETINT (val, accum);
7921925c
JB
2586 return val;
2587}
2588
1a2f2d33
KH
2589#undef isnan
2590#define isnan(x) ((x) != (x))
2591
7a283f36 2592static Lisp_Object
f66c7cf8
PE
2593float_arith_driver (double accum, ptrdiff_t argnum, enum arithop code,
2594 ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2595{
2596 register Lisp_Object val;
2597 double next;
7403b5c8 2598
7921925c
JB
2599 for (; argnum < nargs; argnum++)
2600 {
2601 val = args[argnum]; /* using args[argnum] as argument to CHECK_NUMBER_... */
b7826503 2602 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (val);
7921925c 2603
e9ebc175 2604 if (FLOATP (val))
7921925c 2605 {
7539e11f 2606 next = XFLOAT_DATA (val);
7921925c
JB
2607 }
2608 else
2609 {
2610 args[argnum] = val; /* runs into a compiler bug. */
2611 next = XINT (args[argnum]);
2612 }
7393bcbb 2613 switch (code)
7921925c
JB
2614 {
2615 case Aadd:
2616 accum += next;
2617 break;
2618 case Asub:
e64981da 2619 accum = argnum ? accum - next : nargs == 1 ? - next : next;
7921925c
JB
2620 break;
2621 case Amult:
2622 accum *= next;
2623 break;
2624 case Adiv:
2625 if (!argnum)
2626 accum = next;
2627 else
87fbf902 2628 {
ad8d56b9 2629 if (! IEEE_FLOATING_POINT && next == 0)
740ef0b5 2630 xsignal0 (Qarith_error);
87fbf902
RS
2631 accum /= next;
2632 }
7921925c
JB
2633 break;
2634 case Alogand:
2635 case Alogior:
2636 case Alogxor:
2637 return wrong_type_argument (Qinteger_or_marker_p, val);
2638 case Amax:
1a2f2d33 2639 if (!argnum || isnan (next) || next > accum)
7921925c
JB
2640 accum = next;
2641 break;
2642 case Amin:
1a2f2d33 2643 if (!argnum || isnan (next) || next < accum)
7921925c
JB
2644 accum = next;
2645 break;
2646 }
2647 }
2648
2649 return make_float (accum);
2650}
cc94f3b2 2651
7921925c 2652
a7ca3326 2653DEFUN ("+", Fplus, Splus, 0, MANY, 0,
8c1a1077
PJ
2654 doc: /* Return sum of any number of arguments, which are numbers or markers.
2655usage: (+ &rest NUMBERS-OR-MARKERS) */)
f66c7cf8 2656 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2657{
2658 return arith_driver (Aadd, nargs, args);
2659}
2660
a7ca3326 2661DEFUN ("-", Fminus, Sminus, 0, MANY, 0,
558ee900 2662 doc: /* Negate number or subtract numbers or markers and return the result.
8c1a1077 2663With one arg, negates it. With more than one arg,
f44fba9e 2664subtracts all but the first from the first.
8c1a1077 2665usage: (- &optional NUMBER-OR-MARKER &rest MORE-NUMBERS-OR-MARKERS) */)
f66c7cf8 2666 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2667{
2668 return arith_driver (Asub, nargs, args);
2669}
2670
a7ca3326 2671DEFUN ("*", Ftimes, Stimes, 0, MANY, 0,
be24eadf 2672 doc: /* Return product of any number of arguments, which are numbers or markers.
8c1a1077 2673usage: (* &rest NUMBERS-OR-MARKERS) */)
f66c7cf8 2674 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2675{
2676 return arith_driver (Amult, nargs, args);
2677}
2678
32e5c58c 2679DEFUN ("/", Fquo, Squo, 1, MANY, 0,
be24eadf 2680 doc: /* Return first argument divided by all the remaining arguments.
f44fba9e 2681The arguments must be numbers or markers.
32e5c58c 2682usage: (/ DIVIDEND &rest DIVISORS) */)
f66c7cf8 2683 (ptrdiff_t nargs, Lisp_Object *args)
7921925c 2684{
f66c7cf8 2685 ptrdiff_t argnum;
7ef98053 2686 for (argnum = 2; argnum < nargs; argnum++)
28712a21
JB
2687 if (FLOATP (args[argnum]))
2688 return float_arith_driver (0, 0, Adiv, nargs, args);
7921925c
JB
2689 return arith_driver (Adiv, nargs, args);
2690}
2691
a7ca3326 2692DEFUN ("%", Frem, Srem, 2, 2, 0,
be24eadf 2693 doc: /* Return remainder of X divided by Y.
8c1a1077 2694Both must be integers or markers. */)
5842a27b 2695 (register Lisp_Object x, Lisp_Object y)
7921925c
JB
2696{
2697 Lisp_Object val;
2698
b7826503
PJ
2699 CHECK_NUMBER_COERCE_MARKER (x);
2700 CHECK_NUMBER_COERCE_MARKER (y);
7921925c 2701
d311d28c 2702 if (XINT (y) == 0)
740ef0b5 2703 xsignal0 (Qarith_error);
87fbf902 2704
d9c2a0f2 2705 XSETINT (val, XINT (x) % XINT (y));
7921925c
JB
2706 return val;
2707}
2708
44fa9da5 2709DEFUN ("mod", Fmod, Smod, 2, 2, 0,
be24eadf 2710 doc: /* Return X modulo Y.
8c1a1077
PJ
2711The result falls between zero (inclusive) and Y (exclusive).
2712Both X and Y must be numbers or markers. */)
5842a27b 2713 (register Lisp_Object x, Lisp_Object y)
44fa9da5
PE
2714{
2715 Lisp_Object val;
5260234d 2716 EMACS_INT i1, i2;
44fa9da5 2717
b7826503
PJ
2718 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (x);
2719 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (y);
44fa9da5 2720
d9c2a0f2 2721 if (FLOATP (x) || FLOATP (y))
ad8d56b9
PE
2722 return fmod_float (x, y);
2723
d9c2a0f2
EN
2724 i1 = XINT (x);
2725 i2 = XINT (y);
44fa9da5
PE
2726
2727 if (i2 == 0)
740ef0b5 2728 xsignal0 (Qarith_error);
7403b5c8 2729
44fa9da5
PE
2730 i1 %= i2;
2731
2732 /* If the "remainder" comes out with the wrong sign, fix it. */
04f7ec69 2733 if (i2 < 0 ? i1 > 0 : i1 < 0)
44fa9da5
PE
2734 i1 += i2;
2735
f187f1f7 2736 XSETINT (val, i1);
44fa9da5
PE
2737 return val;
2738}
2739
a7ca3326 2740DEFUN ("max", Fmax, Smax, 1, MANY, 0,
8c1a1077 2741 doc: /* Return largest of all the arguments (which must be numbers or markers).
f44fba9e 2742The value is always a number; markers are converted to numbers.
8c1a1077 2743usage: (max NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
f66c7cf8 2744 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2745{
2746 return arith_driver (Amax, nargs, args);
2747}
2748
a7ca3326 2749DEFUN ("min", Fmin, Smin, 1, MANY, 0,
8c1a1077 2750 doc: /* Return smallest of all the arguments (which must be numbers or markers).
f44fba9e 2751The value is always a number; markers are converted to numbers.
8c1a1077 2752usage: (min NUMBER-OR-MARKER &rest NUMBERS-OR-MARKERS) */)
f66c7cf8 2753 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2754{
2755 return arith_driver (Amin, nargs, args);
2756}
2757
2758DEFUN ("logand", Flogand, Slogand, 0, MANY, 0,
8c1a1077 2759 doc: /* Return bitwise-and of all the arguments.
f44fba9e 2760Arguments may be integers, or markers converted to integers.
8c1a1077 2761usage: (logand &rest INTS-OR-MARKERS) */)
f66c7cf8 2762 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2763{
2764 return arith_driver (Alogand, nargs, args);
2765}
2766
2767DEFUN ("logior", Flogior, Slogior, 0, MANY, 0,
8c1a1077 2768 doc: /* Return bitwise-or of all the arguments.
f44fba9e 2769Arguments may be integers, or markers converted to integers.
8c1a1077 2770usage: (logior &rest INTS-OR-MARKERS) */)
f66c7cf8 2771 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2772{
2773 return arith_driver (Alogior, nargs, args);
2774}
2775
2776DEFUN ("logxor", Flogxor, Slogxor, 0, MANY, 0,
8c1a1077 2777 doc: /* Return bitwise-exclusive-or of all the arguments.
f44fba9e 2778Arguments may be integers, or markers converted to integers.
31fb1b2c 2779usage: (logxor &rest INTS-OR-MARKERS) */)
f66c7cf8 2780 (ptrdiff_t nargs, Lisp_Object *args)
7921925c
JB
2781{
2782 return arith_driver (Alogxor, nargs, args);
2783}
2784
2785DEFUN ("ash", Fash, Sash, 2, 2, 0,
8c1a1077
PJ
2786 doc: /* Return VALUE with its bits shifted left by COUNT.
2787If COUNT is negative, shifting is actually to the right.
2788In this case, the sign bit is duplicated. */)
5842a27b 2789 (register Lisp_Object value, Lisp_Object count)
7921925c
JB
2790{
2791 register Lisp_Object val;
2792
b7826503
PJ
2793 CHECK_NUMBER (value);
2794 CHECK_NUMBER (count);
7921925c 2795
81d70626
RS
2796 if (XINT (count) >= BITS_PER_EMACS_INT)
2797 XSETINT (val, 0);
2798 else if (XINT (count) > 0)
6ab1b16c 2799 XSETINT (val, XUINT (value) << XFASTINT (count));
81d70626
RS
2800 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2801 XSETINT (val, XINT (value) < 0 ? -1 : 0);
7921925c 2802 else
3d9652eb 2803 XSETINT (val, XINT (value) >> -XINT (count));
7921925c
JB
2804 return val;
2805}
2806
2807DEFUN ("lsh", Flsh, Slsh, 2, 2, 0,
8c1a1077
PJ
2808 doc: /* Return VALUE with its bits shifted left by COUNT.
2809If COUNT is negative, shifting is actually to the right.
3a9b1297 2810In this case, zeros are shifted in on the left. */)
5842a27b 2811 (register Lisp_Object value, Lisp_Object count)
7921925c
JB
2812{
2813 register Lisp_Object val;
2814
b7826503
PJ
2815 CHECK_NUMBER (value);
2816 CHECK_NUMBER (count);
7921925c 2817
81d70626
RS
2818 if (XINT (count) >= BITS_PER_EMACS_INT)
2819 XSETINT (val, 0);
2820 else if (XINT (count) > 0)
c8a9ca5a 2821 XSETINT (val, XUINT (value) << XFASTINT (count));
81d70626
RS
2822 else if (XINT (count) <= -BITS_PER_EMACS_INT)
2823 XSETINT (val, 0);
7921925c 2824 else
c8a9ca5a 2825 XSETINT (val, XUINT (value) >> -XINT (count));
7921925c
JB
2826 return val;
2827}
2828
a7ca3326 2829DEFUN ("1+", Fadd1, Sadd1, 1, 1, 0,
8c1a1077
PJ
2830 doc: /* Return NUMBER plus one. NUMBER may be a number or a marker.
2831Markers are converted to integers. */)
5842a27b 2832 (register Lisp_Object number)
7921925c 2833{
b7826503 2834 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number);
7921925c 2835
d9c2a0f2 2836 if (FLOATP (number))
7539e11f 2837 return (make_float (1.0 + XFLOAT_DATA (number)));
7921925c 2838
d9c2a0f2
EN
2839 XSETINT (number, XINT (number) + 1);
2840 return number;
7921925c
JB
2841}
2842
a7ca3326 2843DEFUN ("1-", Fsub1, Ssub1, 1, 1, 0,
8c1a1077
PJ
2844 doc: /* Return NUMBER minus one. NUMBER may be a number or a marker.
2845Markers are converted to integers. */)
5842a27b 2846 (register Lisp_Object number)
7921925c 2847{
b7826503 2848 CHECK_NUMBER_OR_FLOAT_COERCE_MARKER (number);
7921925c 2849
d9c2a0f2 2850 if (FLOATP (number))
7539e11f 2851 return (make_float (-1.0 + XFLOAT_DATA (number)));
7921925c 2852
d9c2a0f2
EN
2853 XSETINT (number, XINT (number) - 1);
2854 return number;
7921925c
JB
2855}
2856
2857DEFUN ("lognot", Flognot, Slognot, 1, 1, 0,
8c1a1077 2858 doc: /* Return the bitwise complement of NUMBER. NUMBER must be an integer. */)
5842a27b 2859 (register Lisp_Object number)
7921925c 2860{
b7826503 2861 CHECK_NUMBER (number);
53924017 2862 XSETINT (number, ~XINT (number));
d9c2a0f2 2863 return number;
7921925c 2864}
6b61353c 2865
a7ca3326 2866DEFUN ("byteorder", Fbyteorder, Sbyteorder, 0, 0, 0,
6b61353c
KH
2867 doc: /* Return the byteorder for the machine.
2868Returns 66 (ASCII uppercase B) for big endian machines or 108 (ASCII
2869lowercase l) for small endian machines. */)
5842a27b 2870 (void)
6b61353c
KH
2871{
2872 unsigned i = 0x04030201;
2873 int order = *(char *)&i == 1 ? 108 : 66;
2874
2875 return make_number (order);
2876}
2877
3e0b94e7
DC
2878/* Because we round up the bool vector allocate size to word_size
2879 units, we can safely read past the "end" of the vector in the
2cf00efc 2880 operations below. These extra bits are always zero. */
3e0b94e7 2881
87c4314d 2882static bits_word
f2752e01 2883bool_vector_spare_mask (EMACS_INT nr_bits)
3e0b94e7 2884{
87c4314d 2885 return (((bits_word) 1) << (nr_bits % BITS_PER_BITS_WORD)) - 1;
3e0b94e7
DC
2886}
2887
2cf00efc
PE
2888/* Info about unsigned long long, falling back on unsigned long
2889 if unsigned long long is not available. */
2890
13a5993b 2891#if HAVE_UNSIGNED_LONG_LONG_INT && defined ULLONG_MAX
2cf00efc 2892enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long long) };
56a0e352 2893# define ULL_MAX ULLONG_MAX
3e0b94e7 2894#else
2cf00efc 2895enum { BITS_PER_ULL = CHAR_BIT * sizeof (unsigned long) };
56a0e352 2896# define ULL_MAX ULONG_MAX
2cf00efc 2897# define count_one_bits_ll count_one_bits_l
56a0e352 2898# define count_trailing_zeros_ll count_trailing_zeros_l
3e0b94e7
DC
2899#endif
2900
2cf00efc
PE
2901/* Shift VAL right by the width of an unsigned long long.
2902 BITS_PER_ULL must be less than BITS_PER_BITS_WORD. */
2903
2904static bits_word
2905shift_right_ull (bits_word w)
2906{
2907 /* Pacify bogus GCC warning about shift count exceeding type width. */
2908 int shift = BITS_PER_ULL - BITS_PER_BITS_WORD < 0 ? BITS_PER_ULL : 0;
2909 return w >> shift;
2910}
2911
2912/* Return the number of 1 bits in W. */
2913
2914static int
2915count_one_bits_word (bits_word w)
2916{
2917 if (BITS_WORD_MAX <= UINT_MAX)
2918 return count_one_bits (w);
2919 else if (BITS_WORD_MAX <= ULONG_MAX)
2920 return count_one_bits_l (w);
2921 else
2922 {
2923 int i = 0, count = 0;
2924 while (count += count_one_bits_ll (w),
0fadc0b0 2925 (i += BITS_PER_ULL) < BITS_PER_BITS_WORD)
2cf00efc
PE
2926 w = shift_right_ull (w);
2927 return count;
2928 }
2929}
2930
3e0b94e7
DC
2931enum bool_vector_op { bool_vector_exclusive_or,
2932 bool_vector_union,
2933 bool_vector_intersection,
2934 bool_vector_set_difference,
2935 bool_vector_subsetp };
2936
7be68de5 2937static Lisp_Object
23e79746
PE
2938bool_vector_binop_driver (Lisp_Object a,
2939 Lisp_Object b,
3e0b94e7
DC
2940 Lisp_Object dest,
2941 enum bool_vector_op op)
2942{
2943 EMACS_INT nr_bits;
23e79746 2944 bits_word *adata, *bdata, *destdata;
87d86601 2945 ptrdiff_t i = 0;
3e0b94e7
DC
2946 ptrdiff_t nr_words;
2947
23e79746
PE
2948 CHECK_BOOL_VECTOR (a);
2949 CHECK_BOOL_VECTOR (b);
3e0b94e7 2950
23e79746
PE
2951 nr_bits = bool_vector_size (a);
2952 if (bool_vector_size (b) != nr_bits)
2953 wrong_length_argument (a, b, dest);
3e0b94e7 2954
87d86601 2955 nr_words = bool_vector_words (nr_bits);
23e79746
PE
2956 adata = bool_vector_data (a);
2957 bdata = bool_vector_data (b);
87d86601 2958
3e0b94e7
DC
2959 if (NILP (dest))
2960 {
2cf00efc 2961 dest = make_uninit_bool_vector (nr_bits);
23e79746 2962 destdata = bool_vector_data (dest);
3e0b94e7
DC
2963 }
2964 else
2965 {
2966 CHECK_BOOL_VECTOR (dest);
23e79746 2967 destdata = bool_vector_data (dest);
454e2fb9 2968 if (bool_vector_size (dest) != nr_bits)
23e79746 2969 wrong_length_argument (a, b, dest);
3e0b94e7 2970
87d86601
PE
2971 switch (op)
2972 {
2973 case bool_vector_exclusive_or:
75360f19
PE
2974 for (; i < nr_words; i++)
2975 if (destdata[i] != (adata[i] ^ bdata[i]))
2976 goto set_dest;
87d86601 2977 break;
7be68de5 2978
87d86601 2979 case bool_vector_subsetp:
75360f19
PE
2980 for (; i < nr_words; i++)
2981 if (adata[i] &~ bdata[i])
87d86601 2982 return Qnil;
75360f19
PE
2983 return Qt;
2984
2985 case bool_vector_union:
2986 for (; i < nr_words; i++)
2987 if (destdata[i] != (adata[i] | bdata[i]))
2988 goto set_dest;
87d86601
PE
2989 break;
2990
2991 case bool_vector_intersection:
75360f19
PE
2992 for (; i < nr_words; i++)
2993 if (destdata[i] != (adata[i] & bdata[i]))
2994 goto set_dest;
87d86601 2995 break;
2cf00efc 2996
87d86601 2997 case bool_vector_set_difference:
75360f19
PE
2998 for (; i < nr_words; i++)
2999 if (destdata[i] != (adata[i] &~ bdata[i]))
3000 goto set_dest;
87d86601
PE
3001 break;
3002 }
75360f19
PE
3003
3004 return Qnil;
87d86601
PE
3005 }
3006
75360f19 3007 set_dest:
87d86601 3008 switch (op)
3e0b94e7 3009 {
87d86601 3010 case bool_vector_exclusive_or:
75360f19 3011 for (; i < nr_words; i++)
23e79746 3012 destdata[i] = adata[i] ^ bdata[i];
87d86601
PE
3013 break;
3014
3015 case bool_vector_union:
75360f19 3016 for (; i < nr_words; i++)
23e79746 3017 destdata[i] = adata[i] | bdata[i];
87d86601 3018 break;
3e0b94e7 3019
87d86601 3020 case bool_vector_intersection:
75360f19 3021 for (; i < nr_words; i++)
23e79746 3022 destdata[i] = adata[i] & bdata[i];
87d86601 3023 break;
3e0b94e7 3024
87d86601 3025 case bool_vector_set_difference:
75360f19 3026 for (; i < nr_words; i++)
23e79746 3027 destdata[i] = adata[i] &~ bdata[i];
87d86601 3028 break;
75360f19
PE
3029
3030 default:
3031 eassume (0);
3e0b94e7 3032 }
7be68de5 3033
87d86601 3034 return dest;
3e0b94e7
DC
3035}
3036
2fcc742f
PE
3037/* PRECONDITION must be true. Return VALUE. This odd construction
3038 works around a bogus GCC diagnostic "shift count >= width of type". */
3039
3040static int
3041pre_value (bool precondition, int value)
3042{
3043 eassume (precondition);
3044 return precondition ? value : 0;
3045}
3046
3e0b94e7
DC
3047/* Compute the number of trailing zero bits in val. If val is zero,
3048 return the number of bits in val. */
595e113b 3049static int
87c4314d 3050count_trailing_zero_bits (bits_word val)
3e0b94e7 3051{
87c4314d 3052 if (BITS_WORD_MAX == UINT_MAX)
595e113b 3053 return count_trailing_zeros (val);
87c4314d 3054 if (BITS_WORD_MAX == ULONG_MAX)
595e113b 3055 return count_trailing_zeros_l (val);
56a0e352 3056 if (BITS_WORD_MAX == ULL_MAX)
595e113b 3057 return count_trailing_zeros_ll (val);
595e113b 3058
87c4314d 3059 /* The rest of this code is for the unlikely platform where bits_word differs
595e113b 3060 in width from unsigned int, unsigned long, and unsigned long long. */
2cf00efc 3061 val |= ~ BITS_WORD_MAX;
87c4314d 3062 if (BITS_WORD_MAX <= UINT_MAX)
595e113b 3063 return count_trailing_zeros (val);
87c4314d 3064 if (BITS_WORD_MAX <= ULONG_MAX)
595e113b 3065 return count_trailing_zeros_l (val);
2cf00efc
PE
3066 else
3067 {
3068 int count;
3069 for (count = 0;
3070 count < BITS_PER_BITS_WORD - BITS_PER_ULL;
3071 count += BITS_PER_ULL)
3072 {
56a0e352 3073 if (val & ULL_MAX)
2cf00efc
PE
3074 return count + count_trailing_zeros_ll (val);
3075 val = shift_right_ull (val);
3076 }
3077
3078 if (BITS_PER_BITS_WORD % BITS_PER_ULL != 0
3079 && BITS_WORD_MAX == (bits_word) -1)
2fcc742f
PE
3080 val |= (bits_word) 1 << pre_value (ULONG_MAX < BITS_WORD_MAX,
3081 BITS_PER_BITS_WORD % BITS_PER_ULL);
2cf00efc
PE
3082 return count + count_trailing_zeros_ll (val);
3083 }
3e0b94e7
DC
3084}
3085
87c4314d
PE
3086static bits_word
3087bits_word_to_host_endian (bits_word val)
3e0b94e7 3088{
595e113b
PE
3089#ifndef WORDS_BIGENDIAN
3090 return val;
3e0b94e7 3091#else
2cf00efc
PE
3092 if (BITS_WORD_MAX >> 31 == 1)
3093 return bswap_32 (val);
3094# if HAVE_UNSIGNED_LONG_LONG
3095 if (BITS_WORD_MAX >> 31 >> 31 >> 1 == 1)
3096 return bswap_64 (val);
3097# endif
3098 {
3099 int i;
3100 bits_word r = 0;
3101 for (i = 0; i < sizeof val; i++)
3102 {
3103 r = ((r << 1 << (CHAR_BIT - 1))
3104 | (val & ((1u << 1 << (CHAR_BIT - 1)) - 1)));
3105 val = val >> 1 >> (CHAR_BIT - 1);
3106 }
3107 return r;
3108 }
3e0b94e7
DC
3109#endif
3110}
3111
3112DEFUN ("bool-vector-exclusive-or", Fbool_vector_exclusive_or,
3113 Sbool_vector_exclusive_or, 2, 3, 0,
454e2fb9
PE
3114 doc: /* Return A ^ B, bitwise exclusive or.
3115If optional third argument C is given, store result into C.
3116A, B, and C must be bool vectors of the same length.
3117Return the destination vector if it changed or nil otherwise. */)
3e0b94e7
DC
3118 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3119{
3120 return bool_vector_binop_driver (a, b, c, bool_vector_exclusive_or);
3121}
3122
3123DEFUN ("bool-vector-union", Fbool_vector_union,
3124 Sbool_vector_union, 2, 3, 0,
454e2fb9
PE
3125 doc: /* Return A | B, bitwise or.
3126If optional third argument C is given, store result into C.
3127A, B, and C must be bool vectors of the same length.
3128Return the destination vector if it changed or nil otherwise. */)
3e0b94e7
DC
3129 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3130{
3131 return bool_vector_binop_driver (a, b, c, bool_vector_union);
3132}
3133
3134DEFUN ("bool-vector-intersection", Fbool_vector_intersection,
3135 Sbool_vector_intersection, 2, 3, 0,
454e2fb9
PE
3136 doc: /* Return A & B, bitwise and.
3137If optional third argument C is given, store result into C.
3138A, B, and C must be bool vectors of the same length.
3139Return the destination vector if it changed or nil otherwise. */)
3e0b94e7
DC
3140 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3141{
3142 return bool_vector_binop_driver (a, b, c, bool_vector_intersection);
3143}
3144
3145DEFUN ("bool-vector-set-difference", Fbool_vector_set_difference,
3146 Sbool_vector_set_difference, 2, 3, 0,
454e2fb9
PE
3147 doc: /* Return A &~ B, set difference.
3148If optional third argument C is given, store result into C.
3149A, B, and C must be bool vectors of the same length.
3150Return the destination vector if it changed or nil otherwise. */)
3e0b94e7
DC
3151 (Lisp_Object a, Lisp_Object b, Lisp_Object c)
3152{
3153 return bool_vector_binop_driver (a, b, c, bool_vector_set_difference);
3154}
3155
3156DEFUN ("bool-vector-subsetp", Fbool_vector_subsetp,
3157 Sbool_vector_subsetp, 2, 2, 0,
3f73284a
PE
3158 doc: /* Return t if every t value in A is also t in B, nil otherwise.
3159A and B must be bool vectors of the same length. */)
3e0b94e7
DC
3160 (Lisp_Object a, Lisp_Object b)
3161{
3f73284a 3162 return bool_vector_binop_driver (a, b, b, bool_vector_subsetp);
3e0b94e7
DC
3163}
3164
3165DEFUN ("bool-vector-not", Fbool_vector_not,
3166 Sbool_vector_not, 1, 2, 0,
454e2fb9
PE
3167 doc: /* Compute ~A, set complement.
3168If optional second argument B is given, store result into B.
3169A and B must be bool vectors of the same length.
3e0b94e7
DC
3170Return the destination vector. */)
3171 (Lisp_Object a, Lisp_Object b)
3172{
3173 EMACS_INT nr_bits;
87c4314d 3174 bits_word *bdata, *adata;
3e0b94e7 3175 ptrdiff_t i;
3e0b94e7
DC
3176
3177 CHECK_BOOL_VECTOR (a);
1c0a7493 3178 nr_bits = bool_vector_size (a);
3e0b94e7
DC
3179
3180 if (NILP (b))
2cf00efc 3181 b = make_uninit_bool_vector (nr_bits);
3e0b94e7
DC
3182 else
3183 {
3184 CHECK_BOOL_VECTOR (b);
454e2fb9
PE
3185 if (bool_vector_size (b) != nr_bits)
3186 wrong_length_argument (a, b, Qnil);
3e0b94e7
DC
3187 }
3188
df5b4930
PE
3189 bdata = bool_vector_data (b);
3190 adata = bool_vector_data (a);
3e0b94e7 3191
87c4314d 3192 for (i = 0; i < nr_bits / BITS_PER_BITS_WORD; i++)
df5b4930 3193 bdata[i] = BITS_WORD_MAX & ~adata[i];
3e0b94e7 3194
87c4314d 3195 if (nr_bits % BITS_PER_BITS_WORD)
3e0b94e7 3196 {
df5b4930 3197 bits_word mword = bits_word_to_host_endian (adata[i]);
3e0b94e7
DC
3198 mword = ~mword;
3199 mword &= bool_vector_spare_mask (nr_bits);
87c4314d 3200 bdata[i] = bits_word_to_host_endian (mword);
3e0b94e7
DC
3201 }
3202
3203 return b;
3204}
3205
ec2c4ee6
PE
3206DEFUN ("bool-vector-count-population", Fbool_vector_count_population,
3207 Sbool_vector_count_population, 1, 1, 0,
3208 doc: /* Count how many elements in A are t.
3209A is a bool vector. To count A's nil elements, subtract the return
3210value from A's length. */)
3211 (Lisp_Object a)
3e0b94e7 3212{
f2752e01 3213 EMACS_INT count;
3e0b94e7 3214 EMACS_INT nr_bits;
87c4314d 3215 bits_word *adata;
2cf00efc 3216 ptrdiff_t i, nwords;
3e0b94e7
DC
3217
3218 CHECK_BOOL_VECTOR (a);
3219
1c0a7493 3220 nr_bits = bool_vector_size (a);
2cf00efc 3221 nwords = bool_vector_words (nr_bits);
3e0b94e7 3222 count = 0;
df5b4930 3223 adata = bool_vector_data (a);
3e0b94e7 3224
2cf00efc
PE
3225 for (i = 0; i < nwords; i++)
3226 count += count_one_bits_word (adata[i]);
3e0b94e7
DC
3227
3228 return make_number (count);
3229}
3230
ec2c4ee6
PE
3231DEFUN ("bool-vector-count-consecutive", Fbool_vector_count_consecutive,
3232 Sbool_vector_count_consecutive, 3, 3, 0,
3233 doc: /* Count how many consecutive elements in A equal B starting at I.
3234A is a bool vector, B is t or nil, and I is an index into A. */)
3e0b94e7
DC
3235 (Lisp_Object a, Lisp_Object b, Lisp_Object i)
3236{
f2752e01 3237 EMACS_INT count;
3e0b94e7 3238 EMACS_INT nr_bits;
f2752e01 3239 int offset;
87c4314d
PE
3240 bits_word *adata;
3241 bits_word twiddle;
3242 bits_word mword; /* Machine word. */
2cf00efc 3243 ptrdiff_t pos, pos0;
3e0b94e7
DC
3244 ptrdiff_t nr_words;
3245
3246 CHECK_BOOL_VECTOR (a);
3247 CHECK_NATNUM (i);
3248
1c0a7493 3249 nr_bits = bool_vector_size (a);
3e0b94e7
DC
3250 if (XFASTINT (i) > nr_bits) /* Allow one past the end for convenience */
3251 args_out_of_range (a, i);
3252
df5b4930
PE
3253 adata = bool_vector_data (a);
3254 nr_words = bool_vector_words (nr_bits);
87c4314d
PE
3255 pos = XFASTINT (i) / BITS_PER_BITS_WORD;
3256 offset = XFASTINT (i) % BITS_PER_BITS_WORD;
3e0b94e7
DC
3257 count = 0;
3258
3259 /* By XORing with twiddle, we transform the problem of "count
3260 consecutive equal values" into "count the zero bits". The latter
3261 operation usually has hardware support. */
df5b4930 3262 twiddle = NILP (b) ? 0 : BITS_WORD_MAX;
3e0b94e7
DC
3263
3264 /* Scan the remainder of the mword at the current offset. */
3265 if (pos < nr_words && offset != 0)
3266 {
87c4314d 3267 mword = bits_word_to_host_endian (adata[pos]);
3e0b94e7
DC
3268 mword ^= twiddle;
3269 mword >>= offset;
87d86601
PE
3270
3271 /* Do not count the pad bits. */
2cf00efc 3272 mword |= (bits_word) 1 << (BITS_PER_BITS_WORD - offset);
87d86601 3273
3e0b94e7 3274 count = count_trailing_zero_bits (mword);
7be68de5 3275 pos++;
87c4314d 3276 if (count + offset < BITS_PER_BITS_WORD)
3e0b94e7
DC
3277 return make_number (count);
3278 }
3279
3280 /* Scan whole words until we either reach the end of the vector or
3281 find an mword that doesn't completely match. twiddle is
3282 endian-independent. */
2cf00efc 3283 pos0 = pos;
3e0b94e7 3284 while (pos < nr_words && adata[pos] == twiddle)
2cf00efc
PE
3285 pos++;
3286 count += (pos - pos0) * BITS_PER_BITS_WORD;
3e0b94e7
DC
3287
3288 if (pos < nr_words)
3289 {
3290 /* If we stopped because of a mismatch, see how many bits match
3291 in the current mword. */
87c4314d 3292 mword = bits_word_to_host_endian (adata[pos]);
3e0b94e7
DC
3293 mword ^= twiddle;
3294 count += count_trailing_zero_bits (mword);
3295 }
87c4314d 3296 else if (nr_bits % BITS_PER_BITS_WORD != 0)
3e0b94e7
DC
3297 {
3298 /* If we hit the end, we might have overshot our count. Reduce
3299 the total by the number of spare bits at the end of the
3300 vector. */
87c4314d 3301 count -= BITS_PER_BITS_WORD - nr_bits % BITS_PER_BITS_WORD;
3e0b94e7
DC
3302 }
3303
3304 return make_number (count);
3305}
6b61353c 3306
7921925c 3307\f
d1c3da7b
BT
3308DEFUN ("bind-symbol", Fbind_symbol, Sbind_symbol, 3, 3, 0,
3309 doc: /* Bind symbol. */)
3310 (Lisp_Object symbol, Lisp_Object value, Lisp_Object thunk)
3311{
3312 Lisp_Object val;
3313 dynwind_begin ();
3314 specbind (symbol, value);
3315 val = call0 (thunk);
3316 dynwind_end ();
3317 return val;
3318}
3319\f
7921925c 3320void
971de7fb 3321syms_of_data (void)
7921925c 3322{
6315e761
RS
3323 Lisp_Object error_tail, arith_tail;
3324
62947569
BT
3325 /* Used by defsubr. */
3326 DEFSYM (Qspecial_operator, "special-operator");
3327 DEFSYM (Qinteractive_form, "interactive-form");
3328
fe6aa7a1
BT
3329#include "data.x"
3330
620c53a6
SM
3331 DEFSYM (Qquote, "quote");
3332 DEFSYM (Qlambda, "lambda");
3333 DEFSYM (Qsubr, "subr");
3334 DEFSYM (Qerror_conditions, "error-conditions");
3335 DEFSYM (Qerror_message, "error-message");
3336 DEFSYM (Qtop_level, "top-level");
3337
3338 DEFSYM (Qerror, "error");
71873e2b 3339 DEFSYM (Quser_error, "user-error");
620c53a6 3340 DEFSYM (Qquit, "quit");
454e2fb9 3341 DEFSYM (Qwrong_length_argument, "wrong-length-argument");
620c53a6
SM
3342 DEFSYM (Qwrong_type_argument, "wrong-type-argument");
3343 DEFSYM (Qargs_out_of_range, "args-out-of-range");
3344 DEFSYM (Qvoid_function, "void-function");
3345 DEFSYM (Qcyclic_function_indirection, "cyclic-function-indirection");
3346 DEFSYM (Qcyclic_variable_indirection, "cyclic-variable-indirection");
3347 DEFSYM (Qvoid_variable, "void-variable");
3348 DEFSYM (Qsetting_constant, "setting-constant");
3349 DEFSYM (Qinvalid_read_syntax, "invalid-read-syntax");
3350
3351 DEFSYM (Qinvalid_function, "invalid-function");
3352 DEFSYM (Qwrong_number_of_arguments, "wrong-number-of-arguments");
3353 DEFSYM (Qno_catch, "no-catch");
3354 DEFSYM (Qend_of_file, "end-of-file");
3355 DEFSYM (Qarith_error, "arith-error");
3356 DEFSYM (Qbeginning_of_buffer, "beginning-of-buffer");
3357 DEFSYM (Qend_of_buffer, "end-of-buffer");
3358 DEFSYM (Qbuffer_read_only, "buffer-read-only");
3359 DEFSYM (Qtext_read_only, "text-read-only");
3360 DEFSYM (Qmark_inactive, "mark-inactive");
3361
3362 DEFSYM (Qlistp, "listp");
3363 DEFSYM (Qconsp, "consp");
3364 DEFSYM (Qsymbolp, "symbolp");
3365 DEFSYM (Qkeywordp, "keywordp");
3366 DEFSYM (Qintegerp, "integerp");
3367 DEFSYM (Qnatnump, "natnump");
3368 DEFSYM (Qwholenump, "wholenump");
3369 DEFSYM (Qstringp, "stringp");
3370 DEFSYM (Qarrayp, "arrayp");
3371 DEFSYM (Qsequencep, "sequencep");
3372 DEFSYM (Qbufferp, "bufferp");
3373 DEFSYM (Qvectorp, "vectorp");
3e0b94e7 3374 DEFSYM (Qbool_vector_p, "bool-vector-p");
620c53a6
SM
3375 DEFSYM (Qchar_or_string_p, "char-or-string-p");
3376 DEFSYM (Qmarkerp, "markerp");
3377 DEFSYM (Qbuffer_or_string_p, "buffer-or-string-p");
3378 DEFSYM (Qinteger_or_marker_p, "integer-or-marker-p");
3379 DEFSYM (Qboundp, "boundp");
3380 DEFSYM (Qfboundp, "fboundp");
3381
3382 DEFSYM (Qfloatp, "floatp");
3383 DEFSYM (Qnumberp, "numberp");
3384 DEFSYM (Qnumber_or_marker_p, "number-or-marker-p");
3385
3386 DEFSYM (Qchar_table_p, "char-table-p");
3387 DEFSYM (Qvector_or_char_table_p, "vector-or-char-table-p");
3388
3389 DEFSYM (Qsubrp, "subrp");
3390 DEFSYM (Qunevalled, "unevalled");
3391 DEFSYM (Qmany, "many");
3392
3393 DEFSYM (Qcdr, "cdr");
3394
3395 /* Handle automatic advice activation. */
3396 DEFSYM (Qad_advice_info, "ad-advice-info");
3397 DEFSYM (Qad_activate_internal, "ad-activate-internal");
f845f2c9 3398
d67b4f80 3399 error_tail = pure_cons (Qerror, Qnil);
6315e761 3400
620c53a6
SM
3401 /* ERROR is used as a signaler for random errors for which nothing else is
3402 right. */
7921925c
JB
3403
3404 Fput (Qerror, Qerror_conditions,
6315e761 3405 error_tail);
7921925c 3406 Fput (Qerror, Qerror_message,
2a0213a6 3407 build_pure_c_string ("error"));
7921925c 3408
71873e2b
SM
3409#define PUT_ERROR(sym, tail, msg) \
3410 Fput (sym, Qerror_conditions, pure_cons (sym, tail)); \
2a0213a6 3411 Fput (sym, Qerror_message, build_pure_c_string (msg))
71873e2b
SM
3412
3413 PUT_ERROR (Qquit, Qnil, "Quit");
3414
3415 PUT_ERROR (Quser_error, error_tail, "");
454e2fb9 3416 PUT_ERROR (Qwrong_length_argument, error_tail, "Wrong length argument");
71873e2b
SM
3417 PUT_ERROR (Qwrong_type_argument, error_tail, "Wrong type argument");
3418 PUT_ERROR (Qargs_out_of_range, error_tail, "Args out of range");
3419 PUT_ERROR (Qvoid_function, error_tail,
3420 "Symbol's function definition is void");
3421 PUT_ERROR (Qcyclic_function_indirection, error_tail,
3422 "Symbol's chain of function indirections contains a loop");
3423 PUT_ERROR (Qcyclic_variable_indirection, error_tail,
3424 "Symbol's chain of variable indirections contains a loop");
620c53a6 3425 DEFSYM (Qcircular_list, "circular-list");
71873e2b
SM
3426 PUT_ERROR (Qcircular_list, error_tail, "List contains a loop");
3427 PUT_ERROR (Qvoid_variable, error_tail, "Symbol's value as variable is void");
3428 PUT_ERROR (Qsetting_constant, error_tail,
3429 "Attempt to set a constant symbol");
3430 PUT_ERROR (Qinvalid_read_syntax, error_tail, "Invalid read syntax");
3431 PUT_ERROR (Qinvalid_function, error_tail, "Invalid function");
3432 PUT_ERROR (Qwrong_number_of_arguments, error_tail,
3433 "Wrong number of arguments");
3434 PUT_ERROR (Qno_catch, error_tail, "No catch for tag");
3435 PUT_ERROR (Qend_of_file, error_tail, "End of file during parsing");
7921925c 3436
d67b4f80 3437 arith_tail = pure_cons (Qarith_error, error_tail);
71873e2b 3438 Fput (Qarith_error, Qerror_conditions, arith_tail);
2a0213a6 3439 Fput (Qarith_error, Qerror_message, build_pure_c_string ("Arithmetic error"));
71873e2b
SM
3440
3441 PUT_ERROR (Qbeginning_of_buffer, error_tail, "Beginning of buffer");
3442 PUT_ERROR (Qend_of_buffer, error_tail, "End of buffer");
3443 PUT_ERROR (Qbuffer_read_only, error_tail, "Buffer is read-only");
3444 PUT_ERROR (Qtext_read_only, pure_cons (Qbuffer_read_only, error_tail),
3445 "Text is read-only");
8f9f49d7 3446
620c53a6
SM
3447 DEFSYM (Qrange_error, "range-error");
3448 DEFSYM (Qdomain_error, "domain-error");
3449 DEFSYM (Qsingularity_error, "singularity-error");
3450 DEFSYM (Qoverflow_error, "overflow-error");
3451 DEFSYM (Qunderflow_error, "underflow-error");
6315e761 3452
71873e2b
SM
3453 PUT_ERROR (Qdomain_error, arith_tail, "Arithmetic domain error");
3454
3455 PUT_ERROR (Qrange_error, arith_tail, "Arithmetic range error");
3456
3457 PUT_ERROR (Qsingularity_error, Fcons (Qdomain_error, arith_tail),
3458 "Arithmetic singularity error");
3459
3460 PUT_ERROR (Qoverflow_error, Fcons (Qdomain_error, arith_tail),
3461 "Arithmetic overflow error");
3462 PUT_ERROR (Qunderflow_error, Fcons (Qdomain_error, arith_tail),
3463 "Arithmetic underflow error");
6315e761 3464
7921925c
JB
3465 staticpro (&Qnil);
3466 staticpro (&Qt);
7921925c 3467 staticpro (&Qunbound);
7921925c 3468
39bcc759 3469 /* Types that type-of returns. */
620c53a6
SM
3470 DEFSYM (Qinteger, "integer");
3471 DEFSYM (Qsymbol, "symbol");
3472 DEFSYM (Qstring, "string");
3473 DEFSYM (Qcons, "cons");
3474 DEFSYM (Qmarker, "marker");
3475 DEFSYM (Qoverlay, "overlay");
3476 DEFSYM (Qfloat, "float");
3477 DEFSYM (Qwindow_configuration, "window-configuration");
3478 DEFSYM (Qprocess, "process");
3479 DEFSYM (Qwindow, "window");
620c53a6
SM
3480 DEFSYM (Qcompiled_function, "compiled-function");
3481 DEFSYM (Qbuffer, "buffer");
3482 DEFSYM (Qframe, "frame");
3483 DEFSYM (Qvector, "vector");
3484 DEFSYM (Qchar_table, "char-table");
3485 DEFSYM (Qbool_vector, "bool-vector");
3486 DEFSYM (Qhash_table, "hash-table");
3ab6e069 3487 DEFSYM (Qmisc, "misc");
39bcc759 3488
61b108cc
SM
3489 DEFSYM (Qdefun, "defun");
3490
4e6f2626
CY
3491 DEFSYM (Qfont_spec, "font-spec");
3492 DEFSYM (Qfont_entity, "font-entity");
3493 DEFSYM (Qfont_object, "font-object");
3494
32e5c58c 3495 DEFSYM (Qdefalias_fset_function, "defalias-fset-function");
3860280a 3496
1d59fbe3 3497 set_symbol_function (Qwholenump, SYMBOL_FUNCTION (Qnatnump));
e6190b11 3498
29208e82 3499 DEFVAR_LISP ("most-positive-fixnum", Vmost_positive_fixnum,
9d113d9d
AS
3500 doc: /* The largest value that is representable in a Lisp integer. */);
3501 Vmost_positive_fixnum = make_number (MOST_POSITIVE_FIXNUM);
844e0de1 3502 SET_SYMBOL_CONSTANT (XSYMBOL (intern_c_string ("most-positive-fixnum")), 1);
bfb96cb7 3503
29208e82 3504 DEFVAR_LISP ("most-negative-fixnum", Vmost_negative_fixnum,
9d113d9d
AS
3505 doc: /* The smallest value that is representable in a Lisp integer. */);
3506 Vmost_negative_fixnum = make_number (MOST_NEGATIVE_FIXNUM);
844e0de1 3507 SET_SYMBOL_CONSTANT (XSYMBOL (intern_c_string ("most-negative-fixnum")), 1);
7921925c 3508}