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