XEmacs 21.2.26 "Millenium".
[chise/xemacs-chise.git.1] / src / data.c
1 /* Primitive operations on Lisp data types for XEmacs Lisp interpreter.
2    Copyright (C) 1985, 1986, 1988, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING.  If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* Synched up with: Mule 2.0, FSF 19.30.  Some of FSF's data.c is in
23    XEmacs' symbols.c. */
24
25 /* This file has been Mule-ized. */
26
27 #include <config.h>
28 #include "lisp.h"
29
30 #include "buffer.h"
31 #include "bytecode.h"
32 #include "syssignal.h"
33
34 #ifdef LISP_FLOAT_TYPE
35 /* Need to define a differentiating symbol -- see sysfloat.h */
36 # define THIS_FILENAME data_c
37 # include "sysfloat.h"
38 #endif /* LISP_FLOAT_TYPE */
39
40 Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
41 Lisp_Object Qerror_conditions, Qerror_message;
42 Lisp_Object Qerror, Qquit, Qwrong_type_argument, Qargs_out_of_range;
43 Lisp_Object Qvoid_variable, Qcyclic_variable_indirection;
44 Lisp_Object Qvoid_function, Qcyclic_function_indirection;
45 Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
46 Lisp_Object Qmalformed_list, Qmalformed_property_list;
47 Lisp_Object Qcircular_list, Qcircular_property_list;
48 Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
49 Lisp_Object Qio_error, Qend_of_file;
50 Lisp_Object Qarith_error, Qrange_error, Qdomain_error;
51 Lisp_Object Qsingularity_error, Qoverflow_error, Qunderflow_error;
52 Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
53 Lisp_Object Qintegerp, Qnatnump, Qsymbolp;
54 Lisp_Object Qlistp, Qtrue_list_p, Qweak_listp;
55 Lisp_Object Qconsp, Qsubrp;
56 Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qvectorp;
57 Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qbufferp;
58 Lisp_Object Qinteger_or_char_p, Qinteger_char_or_marker_p;
59 Lisp_Object Qnumberp, Qnumber_char_or_marker_p;
60 Lisp_Object Qbit_vectorp, Qbitp, Qcdr;
61
62 Lisp_Object Qfloatp;
63
64 #ifdef DEBUG_XEMACS
65
66 int debug_issue_ebola_notices;
67
68 int debug_ebola_backtrace_length;
69
70 int
71 eq_with_ebola_notice (Lisp_Object obj1, Lisp_Object obj2)
72 {
73   if (debug_issue_ebola_notices
74       && ((CHARP (obj1) && INTP (obj2)) || (CHARP (obj2) && INTP (obj1))))
75     {
76       /* #### It would be really nice if this were a proper warning
77          instead of brain-dead print ro Qexternal_debugging_output.  */
78       write_c_string ("Comparison between integer and character is constant nil (",
79                       Qexternal_debugging_output);
80       Fprinc (obj1, Qexternal_debugging_output);
81       write_c_string (" and ", Qexternal_debugging_output);
82       Fprinc (obj2, Qexternal_debugging_output);
83       write_c_string (")\n", Qexternal_debugging_output);
84       debug_short_backtrace (debug_ebola_backtrace_length);
85     }
86   return EQ (obj1, obj2);
87 }
88
89 #endif /* DEBUG_XEMACS */
90
91
92 \f
93 Lisp_Object
94 wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
95 {
96   /* This function can GC */
97   REGISTER Lisp_Object tem;
98   do
99     {
100       value = Fsignal (Qwrong_type_argument, list2 (predicate, value));
101       tem = call1 (predicate, value);
102     }
103   while (NILP (tem));
104   return value;
105 }
106
107 DOESNT_RETURN
108 dead_wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
109 {
110   signal_error (Qwrong_type_argument, list2 (predicate, value));
111 }
112
113 DEFUN ("wrong-type-argument", Fwrong_type_argument, 2, 2, 0, /*
114 Signal an error until the correct type value is given by the user.
115 This function loops, signalling a continuable `wrong-type-argument' error
116 with PREDICATE and VALUE as the data associated with the error and then
117 calling PREDICATE on the returned value, until the value gotten satisfies
118 PREDICATE.  At that point, the gotten value is returned.
119 */
120        (predicate, value))
121 {
122   return wrong_type_argument (predicate, value);
123 }
124
125 DOESNT_RETURN
126 c_write_error (Lisp_Object obj)
127 {
128   signal_simple_error ("Attempt to modify read-only object (c)", obj);
129 }
130
131 DOESNT_RETURN
132 lisp_write_error (Lisp_Object obj)
133 {
134   signal_simple_error ("Attempt to modify read-only object (lisp)", obj);
135 }
136
137 DOESNT_RETURN
138 args_out_of_range (Lisp_Object a1, Lisp_Object a2)
139 {
140   signal_error (Qargs_out_of_range, list2 (a1, a2));
141 }
142
143 DOESNT_RETURN
144 args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
145 {
146   signal_error (Qargs_out_of_range, list3 (a1, a2, a3));
147 }
148
149 void
150 check_int_range (EMACS_INT val, EMACS_INT min, EMACS_INT max)
151 {
152   if (val < min || val > max)
153     args_out_of_range_3 (make_int (val), make_int (min), make_int (max));
154 }
155
156 /* On some machines, XINT needs a temporary location.
157    Here it is, in case it is needed.  */
158
159 EMACS_INT sign_extend_temp;
160
161 /* On a few machines, XINT can only be done by calling this.  */
162 /* XEmacs:  only used by m/convex.h */
163 EMACS_INT sign_extend_lisp_int (EMACS_INT num);
164 EMACS_INT
165 sign_extend_lisp_int (EMACS_INT num)
166 {
167   if (num & (1L << (VALBITS - 1)))
168     return num | ((-1L) << VALBITS);
169   else
170     return num & ((1L << VALBITS) - 1);
171 }
172
173 \f
174 /* Data type predicates */
175
176 DEFUN ("eq", Feq, 2, 2, 0, /*
177 Return t if the two args are the same Lisp object.
178 */
179        (obj1, obj2))
180 {
181   return EQ_WITH_EBOLA_NOTICE (obj1, obj2) ? Qt : Qnil;
182 }
183
184 DEFUN ("old-eq", Fold_eq, 2, 2, 0, /*
185 Return t if the two args are (in most cases) the same Lisp object.
186
187 Special kludge: A character is considered `old-eq' to its equivalent integer
188 even though they are not the same object and are in fact of different
189 types.  This is ABSOLUTELY AND UTTERLY HORRENDOUS but is necessary to
190 preserve byte-code compatibility with v19.  This kludge is known as the
191 \"char-int confoundance disease\" and appears in a number of other
192 functions with `old-foo' equivalents.
193
194 Do not use this function!
195 */
196        (obj1, obj2))
197 {
198   /* #### blasphemy */
199   return HACKEQ_UNSAFE (obj1, obj2) ? Qt : Qnil;
200 }
201
202 DEFUN ("null", Fnull, 1, 1, 0, /*
203 Return t if OBJECT is nil.
204 */
205        (object))
206 {
207   return NILP (object) ? Qt : Qnil;
208 }
209
210 DEFUN ("consp", Fconsp, 1, 1, 0, /*
211 Return t if OBJECT is a cons cell.  `nil' is not a cons cell.
212 */
213        (object))
214 {
215   return CONSP (object) ? Qt : Qnil;
216 }
217
218 DEFUN ("atom", Fatom, 1, 1, 0, /*
219 Return t if OBJECT is not a cons cell.  `nil' is not a cons cell.
220 */
221        (object))
222 {
223   return CONSP (object) ? Qnil : Qt;
224 }
225
226 DEFUN ("listp", Flistp, 1, 1, 0, /*
227 Return t if OBJECT is a list.  `nil' is a list.
228 */
229        (object))
230 {
231   return LISTP (object) ? Qt : Qnil;
232 }
233
234 DEFUN ("nlistp", Fnlistp, 1, 1, 0, /*
235 Return t if OBJECT is not a list.  `nil' is a list.
236 */
237        (object))
238 {
239   return LISTP (object) ? Qnil : Qt;
240 }
241
242 DEFUN ("true-list-p", Ftrue_list_p, 1, 1, 0, /*
243 Return t if OBJECT is a non-dotted, i.e. nil-terminated, list.
244 */
245        (object))
246 {
247   return TRUE_LIST_P (object) ? Qt : Qnil;
248 }
249 \f
250 DEFUN ("symbolp", Fsymbolp, 1, 1, 0, /*
251 Return t if OBJECT is a symbol.
252 */
253        (object))
254 {
255   return SYMBOLP (object) ? Qt : Qnil;
256 }
257
258 DEFUN ("keywordp", Fkeywordp, 1, 1, 0, /*
259 Return t if OBJECT is a keyword.
260 */
261        (object))
262 {
263   return KEYWORDP (object) ? Qt : Qnil;
264 }
265
266 DEFUN ("vectorp", Fvectorp, 1, 1, 0, /*
267 Return t if OBJECT is a vector.
268 */
269        (object))
270 {
271   return VECTORP (object) ? Qt : Qnil;
272 }
273
274 DEFUN ("bit-vector-p", Fbit_vector_p, 1, 1, 0, /*
275 Return t if OBJECT is a bit vector.
276 */
277        (object))
278 {
279   return BIT_VECTORP (object) ? Qt : Qnil;
280 }
281
282 DEFUN ("stringp", Fstringp, 1, 1, 0, /*
283 Return t if OBJECT is a string.
284 */
285        (object))
286 {
287   return STRINGP (object) ? Qt : Qnil;
288 }
289
290 DEFUN ("arrayp", Farrayp, 1, 1, 0, /*
291 Return t if OBJECT is an array (string, vector, or bit vector).
292 */
293        (object))
294 {
295   return (VECTORP       (object) ||
296           STRINGP       (object) ||
297           BIT_VECTORP   (object))
298     ? Qt : Qnil;
299 }
300
301 DEFUN ("sequencep", Fsequencep, 1, 1, 0, /*
302 Return t if OBJECT is a sequence (list or array).
303 */
304        (object))
305 {
306   return (LISTP         (object) ||
307           VECTORP       (object) ||
308           STRINGP       (object) ||
309           BIT_VECTORP   (object))
310     ? Qt : Qnil;
311 }
312
313 DEFUN ("markerp", Fmarkerp, 1, 1, 0, /*
314 Return t if OBJECT is a marker (editor pointer).
315 */
316        (object))
317 {
318   return MARKERP (object) ? Qt : Qnil;
319 }
320
321 DEFUN ("subrp", Fsubrp, 1, 1, 0, /*
322 Return t if OBJECT is a built-in function.
323 */
324        (object))
325 {
326   return SUBRP (object) ? Qt : Qnil;
327 }
328
329 DEFUN ("subr-min-args", Fsubr_min_args, 1, 1, 0, /*
330 Return minimum number of args built-in function SUBR may be called with.
331 */
332        (subr))
333 {
334   CHECK_SUBR (subr);
335   return make_int (XSUBR (subr)->min_args);
336 }
337
338 DEFUN ("subr-max-args", Fsubr_max_args, 1, 1, 0, /*
339 Return maximum number of args built-in function SUBR may be called with,
340 or nil if it takes an arbitrary number of arguments or is a special form.
341 */
342        (subr))
343 {
344   int nargs;
345   CHECK_SUBR (subr);
346   nargs = XSUBR (subr)->max_args;
347   if (nargs == MANY || nargs == UNEVALLED)
348     return Qnil;
349   else
350     return make_int (nargs);
351 }
352
353 DEFUN ("subr-interactive", Fsubr_interactive, 1, 1, 0, /*
354 Return the interactive spec of the subr object, or nil.
355 If non-nil, the return value will be a list whose first element is
356 `interactive' and whose second element is the interactive spec.
357 */
358        (subr))
359 {
360   CONST char *prompt;
361   CHECK_SUBR (subr);
362   prompt = XSUBR (subr)->prompt;
363   return prompt ? list2 (Qinteractive, build_string (prompt)) : Qnil;
364 }
365
366 \f
367 DEFUN ("characterp", Fcharacterp, 1, 1, 0, /*
368 Return t if OBJECT is a character.
369 Unlike in XEmacs v19 and FSF Emacs, a character is its own primitive type.
370 Any character can be converted into an equivalent integer using
371 `char-int'.  To convert the other way, use `int-char'; however,
372 only some integers can be converted into characters.  Such an integer
373 is called a `char-int'; see `char-int-p'.
374
375 Some functions that work on integers (e.g. the comparison functions
376 <, <=, =, /=, etc. and the arithmetic functions +, -, *, etc.)
377 accept characters and implicitly convert them into integers.  In
378 general, functions that work on characters also accept char-ints and
379 implicitly convert them into characters.  WARNING: Neither of these
380 behaviors is very desirable, and they are maintained for backward
381 compatibility with old E-Lisp programs that confounded characters and
382 integers willy-nilly.  These behaviors may change in the future; therefore,
383 do not rely on them.  Instead, use the character-specific functions such
384 as `char='.
385 */
386        (object))
387 {
388   return CHARP (object) ? Qt : Qnil;
389 }
390
391 DEFUN ("char-to-int", Fchar_to_int, 1, 1, 0, /*
392 Convert a character into an equivalent integer.
393 The resulting integer will always be non-negative.  The integers in
394 the range 0 - 255 map to characters as follows:
395
396 0 - 31          Control set 0
397 32 - 127        ASCII
398 128 - 159       Control set 1
399 160 - 255       Right half of ISO-8859-1
400
401 If support for Mule does not exist, these are the only valid character
402 values.  When Mule support exists, the values assigned to other characters
403 may vary depending on the particular version of XEmacs, the order in which
404 character sets were loaded, etc., and you should not depend on them.
405 */
406        (ch))
407 {
408   CHECK_CHAR (ch);
409   return make_int (XCHAR (ch));
410 }
411
412 DEFUN ("int-to-char", Fint_to_char, 1, 1, 0, /*
413 Convert an integer into the equivalent character.
414 Not all integers correspond to valid characters; use `char-int-p' to
415 determine whether this is the case.  If the integer cannot be converted,
416 nil is returned.
417 */
418        (integer))
419 {
420   CHECK_INT (integer);
421   if (CHAR_INTP (integer))
422     return make_char (XINT (integer));
423   else
424     return Qnil;
425 }
426
427 DEFUN ("char-int-p", Fchar_int_p, 1, 1, 0, /*
428 Return t if OBJECT is an integer that can be converted into a character.
429 See `char-int'.
430 */
431        (object))
432 {
433   return CHAR_INTP (object) ? Qt : Qnil;
434 }
435
436 DEFUN ("char-or-char-int-p", Fchar_or_char_int_p, 1, 1, 0, /*
437 Return t if OBJECT is a character or an integer that can be converted into one.
438 */
439        (object))
440 {
441   return CHAR_OR_CHAR_INTP (object) ? Qt : Qnil;
442 }
443
444 DEFUN ("char-or-string-p", Fchar_or_string_p, 1, 1, 0, /*
445 Return t if OBJECT is a character (or a char-int) or a string.
446 It is semi-hateful that we allow a char-int here, as it goes against
447 the name of this function, but it makes the most sense considering the
448 other steps we take to maintain compatibility with the old character/integer
449 confoundedness in older versions of E-Lisp.
450 */
451        (object))
452 {
453   return CHAR_OR_CHAR_INTP (object) || STRINGP (object) ? Qt : Qnil;
454 }
455 \f
456 DEFUN ("integerp", Fintegerp, 1, 1, 0, /*
457 Return t if OBJECT is an integer.
458 */
459        (object))
460 {
461   return INTP (object) ? Qt : Qnil;
462 }
463
464 DEFUN ("integer-or-marker-p", Finteger_or_marker_p, 1, 1, 0, /*
465 Return t if OBJECT is an integer or a marker (editor pointer).
466 */
467        (object))
468 {
469   return INTP (object) || MARKERP (object) ? Qt : Qnil;
470 }
471
472 DEFUN ("integer-or-char-p", Finteger_or_char_p, 1, 1, 0, /*
473 Return t if OBJECT is an integer or a character.
474 */
475        (object))
476 {
477   return INTP (object) || CHARP (object) ? Qt : Qnil;
478 }
479
480 DEFUN ("integer-char-or-marker-p", Finteger_char_or_marker_p, 1, 1, 0, /*
481 Return t if OBJECT is an integer, character or a marker (editor pointer).
482 */
483        (object))
484 {
485   return INTP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil;
486 }
487
488 DEFUN ("natnump", Fnatnump, 1, 1, 0, /*
489 Return t if OBJECT is a nonnegative integer.
490 */
491        (object))
492 {
493   return NATNUMP (object) ? Qt : Qnil;
494 }
495
496 DEFUN ("bitp", Fbitp, 1, 1, 0, /*
497 Return t if OBJECT is a bit (0 or 1).
498 */
499        (object))
500 {
501   return BITP (object) ? Qt : Qnil;
502 }
503
504 DEFUN ("numberp", Fnumberp, 1, 1, 0, /*
505 Return t if OBJECT is a number (floating point or integer).
506 */
507        (object))
508 {
509   return INT_OR_FLOATP (object) ? Qt : Qnil;
510 }
511
512 DEFUN ("number-or-marker-p", Fnumber_or_marker_p, 1, 1, 0, /*
513 Return t if OBJECT is a number or a marker.
514 */
515        (object))
516 {
517   return INT_OR_FLOATP (object) || MARKERP (object) ? Qt : Qnil;
518 }
519
520 DEFUN ("number-char-or-marker-p", Fnumber_char_or_marker_p, 1, 1, 0, /*
521 Return t if OBJECT is a number, character or a marker.
522 */
523        (object))
524 {
525   return (INT_OR_FLOATP (object) ||
526           CHARP         (object) ||
527           MARKERP       (object))
528     ? Qt : Qnil;
529 }
530
531 #ifdef LISP_FLOAT_TYPE
532 DEFUN ("floatp", Ffloatp, 1, 1, 0, /*
533 Return t if OBJECT is a floating point number.
534 */
535        (object))
536 {
537   return FLOATP (object) ? Qt : Qnil;
538 }
539 #endif /* LISP_FLOAT_TYPE */
540
541 DEFUN ("type-of", Ftype_of, 1, 1, 0, /*
542 Return a symbol representing the type of OBJECT.
543 */
544        (object))
545 {
546   switch (XTYPE (object))
547     {
548     case Lisp_Type_Record:
549       return intern (XRECORD_LHEADER_IMPLEMENTATION (object)->name);
550
551     case Lisp_Type_Char: return Qcharacter;
552
553     default: return Qinteger;
554     }
555 }
556
557 \f
558 /* Extract and set components of lists */
559
560 DEFUN ("car", Fcar, 1, 1, 0, /*
561 Return the car of LIST.  If arg is nil, return nil.
562 Error if arg is not nil and not a cons cell.  See also `car-safe'.
563 */
564        (list))
565 {
566   while (1)
567     {
568       if (CONSP (list))
569         return XCAR (list);
570       else if (NILP (list))
571         return Qnil;
572       else
573         list = wrong_type_argument (Qlistp, list);
574     }
575 }
576
577 DEFUN ("car-safe", Fcar_safe, 1, 1, 0, /*
578 Return the car of OBJECT if it is a cons cell, or else nil.
579 */
580        (object))
581 {
582   return CONSP (object) ? XCAR (object) : Qnil;
583 }
584
585 DEFUN ("cdr", Fcdr, 1, 1, 0, /*
586 Return the cdr of LIST.  If arg is nil, return nil.
587 Error if arg is not nil and not a cons cell.  See also `cdr-safe'.
588 */
589        (list))
590 {
591   while (1)
592     {
593       if (CONSP (list))
594         return XCDR (list);
595       else if (NILP (list))
596         return Qnil;
597       else
598         list = wrong_type_argument (Qlistp, list);
599     }
600 }
601
602 DEFUN ("cdr-safe", Fcdr_safe, 1, 1, 0, /*
603 Return the cdr of OBJECT if it is a cons cell, else nil.
604 */
605        (object))
606 {
607   return CONSP (object) ? XCDR (object) : Qnil;
608 }
609
610 DEFUN ("setcar", Fsetcar, 2, 2, 0, /*
611 Set the car of CONSCELL to be NEWCAR.  Return NEWCAR.
612 */
613        (conscell, newcar))
614 {
615   if (!CONSP (conscell))
616     conscell = wrong_type_argument (Qconsp, conscell);
617
618   XCAR (conscell) = newcar;
619   return newcar;
620 }
621
622 DEFUN ("setcdr", Fsetcdr, 2, 2, 0, /*
623 Set the cdr of CONSCELL to be NEWCDR.  Return NEWCDR.
624 */
625        (conscell, newcdr))
626 {
627   if (!CONSP (conscell))
628     conscell = wrong_type_argument (Qconsp, conscell);
629
630   XCDR (conscell) = newcdr;
631   return newcdr;
632 }
633 \f
634 /* Find the function at the end of a chain of symbol function indirections.
635
636    If OBJECT is a symbol, find the end of its function chain and
637    return the value found there.  If OBJECT is not a symbol, just
638    return it.  If there is a cycle in the function chain, signal a
639    cyclic-function-indirection error.
640
641    This is like Findirect_function, except that it doesn't signal an
642    error if the chain ends up unbound.  */
643 Lisp_Object
644 indirect_function (Lisp_Object object, int errorp)
645 {
646 #define FUNCTION_INDIRECTION_SUSPICION_LENGTH 16
647   Lisp_Object tortoise, hare;
648   int count;
649
650   for (hare = tortoise = object, count = 0;
651        SYMBOLP (hare);
652        hare = XSYMBOL (hare)->function, count++)
653     {
654       if (count < FUNCTION_INDIRECTION_SUSPICION_LENGTH) continue;
655
656       if (count & 1)
657         tortoise = XSYMBOL (tortoise)->function;
658       if (EQ (hare, tortoise))
659         return Fsignal (Qcyclic_function_indirection, list1 (object));
660     }
661
662   if (errorp && UNBOUNDP (hare))
663     return signal_void_function_error (object);
664
665   return hare;
666 }
667
668 DEFUN ("indirect-function", Findirect_function, 1, 1, 0, /*
669 Return the function at the end of OBJECT's function chain.
670 If OBJECT is a symbol, follow all function indirections and return
671 the final function binding.
672 If OBJECT is not a symbol, just return it.
673 Signal a void-function error if the final symbol is unbound.
674 Signal a cyclic-function-indirection error if there is a loop in the
675 function chain of symbols.
676 */
677        (object))
678 {
679   return indirect_function (object, 1);
680 }
681 \f
682 /* Extract and set vector and string elements */
683
684 DEFUN ("aref", Faref, 2, 2, 0, /*
685 Return the element of ARRAY at index INDEX.
686 ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
687 */
688        (array, index_))
689 {
690   EMACS_INT idx;
691
692  retry:
693
694   if      (INTP  (index_)) idx = XINT  (index_);
695   else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
696   else
697     {
698       index_ = wrong_type_argument (Qinteger_or_char_p, index_);
699       goto retry;
700     }
701
702   if (idx < 0) goto range_error;
703
704   if (VECTORP (array))
705     {
706       if (idx >= XVECTOR_LENGTH (array)) goto range_error;
707       return XVECTOR_DATA (array)[idx];
708     }
709   else if (BIT_VECTORP (array))
710     {
711       if (idx >= bit_vector_length (XBIT_VECTOR (array))) goto range_error;
712       return make_int (bit_vector_bit (XBIT_VECTOR (array), idx));
713     }
714   else if (STRINGP (array))
715     {
716       if (idx >= XSTRING_CHAR_LENGTH (array)) goto range_error;
717       return make_char (string_char (XSTRING (array), idx));
718     }
719 #ifdef LOSING_BYTECODE
720   else if (COMPILED_FUNCTIONP (array))
721     {
722       /* Weird, gross compatibility kludge */
723       return Felt (array, index_);
724     }
725 #endif
726   else
727     {
728       check_losing_bytecode ("aref", array);
729       array = wrong_type_argument (Qarrayp, array);
730       goto retry;
731     }
732
733  range_error:
734   args_out_of_range (array, index_);
735   return Qnil; /* not reached */
736 }
737
738 DEFUN ("aset", Faset, 3, 3, 0, /*
739 Store into the element of ARRAY at index INDEX the value NEWVAL.
740 ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
741 */
742        (array, index_, newval))
743 {
744   EMACS_INT idx;
745
746  retry:
747
748   if      (INTP  (index_)) idx = XINT (index_);
749   else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
750   else
751     {
752       index_ = wrong_type_argument (Qinteger_or_char_p, index_);
753       goto retry;
754     }
755
756   if (idx < 0) goto range_error;
757
758   if (VECTORP (array))
759     {
760       if (idx >= XVECTOR_LENGTH (array)) goto range_error;
761       XVECTOR_DATA (array)[idx] = newval;
762     }
763   else if (BIT_VECTORP (array))
764     {
765       if (idx >= bit_vector_length (XBIT_VECTOR (array))) goto range_error;
766       CHECK_BIT (newval);
767       set_bit_vector_bit (XBIT_VECTOR (array), idx, !ZEROP (newval));
768     }
769   else if (STRINGP (array))
770     {
771       CHECK_CHAR_COERCE_INT (newval);
772       if (idx >= XSTRING_CHAR_LENGTH (array)) goto range_error;
773       set_string_char (XSTRING (array), idx, XCHAR (newval));
774       bump_string_modiff (array);
775     }
776   else
777     {
778       array = wrong_type_argument (Qarrayp, array);
779       goto retry;
780     }
781
782   return newval;
783
784  range_error:
785   args_out_of_range (array, index_);
786   return Qnil; /* not reached */
787 }
788
789 \f
790 /**********************************************************************/
791 /*                       Arithmetic functions                         */
792 /**********************************************************************/
793 typedef struct
794 {
795   int int_p;
796   union
797   {
798     EMACS_INT ival;
799     double dval;
800   } c;
801 } int_or_double;
802
803 static void
804 number_char_or_marker_to_int_or_double (Lisp_Object obj, int_or_double *p)
805 {
806  retry:
807   p->int_p = 1;
808   if      (INTP    (obj)) p->c.ival = XINT  (obj);
809   else if (CHARP   (obj)) p->c.ival = XCHAR (obj);
810   else if (MARKERP (obj)) p->c.ival = marker_position (obj);
811 #ifdef LISP_FLOAT_TYPE
812   else if (FLOATP  (obj)) p->c.dval = XFLOAT_DATA (obj), p->int_p = 0;
813 #endif
814   else
815     {
816       obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
817       goto retry;
818     }
819 }
820
821 static double
822 number_char_or_marker_to_double (Lisp_Object obj)
823 {
824  retry:
825   if      (INTP    (obj)) return (double) XINT  (obj);
826   else if (CHARP   (obj)) return (double) XCHAR (obj);
827   else if (MARKERP (obj)) return (double) marker_position (obj);
828 #ifdef LISP_FLOAT_TYPE
829   else if (FLOATP  (obj)) return XFLOAT_DATA (obj);
830 #endif
831   else
832     {
833       obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
834       goto retry;
835     }
836 }
837
838 static EMACS_INT
839 integer_char_or_marker_to_int (Lisp_Object obj)
840 {
841  retry:
842   if      (INTP    (obj)) return XINT  (obj);
843   else if (CHARP   (obj)) return XCHAR (obj);
844   else if (MARKERP (obj)) return marker_position (obj);
845   else
846     {
847       obj = wrong_type_argument (Qinteger_char_or_marker_p, obj);
848       goto retry;
849     }
850 }
851
852 #define ARITHCOMPARE_MANY(op)                                   \
853 {                                                               \
854   int_or_double iod1, iod2, *p = &iod1, *q = &iod2;             \
855   Lisp_Object *args_end = args + nargs;                         \
856                                                                 \
857   number_char_or_marker_to_int_or_double (*args++, p);          \
858                                                                 \
859   while (args < args_end)                                       \
860     {                                                           \
861       number_char_or_marker_to_int_or_double (*args++, q);      \
862                                                                 \
863       if (!((p->int_p && q->int_p) ?                            \
864             (p->c.ival op q->c.ival) :                          \
865             ((p->int_p ? (double) p->c.ival : p->c.dval) op     \
866              (q->int_p ? (double) q->c.ival : q->c.dval))))     \
867         return Qnil;                                            \
868                                                                 \
869       { /* swap */ int_or_double *r = p; p = q; q = r; }        \
870     }                                                           \
871   return Qt;                                                    \
872 }
873
874 DEFUN ("=", Feqlsign, 1, MANY, 0, /*
875 Return t if all the arguments are numerically equal.
876 The arguments may be numbers, characters or markers.
877 */
878        (int nargs, Lisp_Object *args))
879 {
880   ARITHCOMPARE_MANY (==)
881 }
882
883 DEFUN ("<", Flss, 1, MANY, 0, /*
884 Return t if the sequence of arguments is monotonically increasing.
885 The arguments may be numbers, characters or markers.
886 */
887        (int nargs, Lisp_Object *args))
888 {
889   ARITHCOMPARE_MANY (<)
890 }
891
892 DEFUN (">", Fgtr, 1, MANY, 0, /*
893 Return t if the sequence of arguments is monotonically decreasing.
894 The arguments may be numbers, characters or markers.
895 */
896        (int nargs, Lisp_Object *args))
897 {
898   ARITHCOMPARE_MANY (>)
899 }
900
901 DEFUN ("<=", Fleq, 1, MANY, 0, /*
902 Return t if the sequence of arguments is monotonically nondecreasing.
903 The arguments may be numbers, characters or markers.
904 */
905        (int nargs, Lisp_Object *args))
906 {
907   ARITHCOMPARE_MANY (<=)
908 }
909
910 DEFUN (">=", Fgeq, 1, MANY, 0, /*
911 Return t if the sequence of arguments is monotonically nonincreasing.
912 The arguments may be numbers, characters or markers.
913 */
914        (int nargs, Lisp_Object *args))
915 {
916   ARITHCOMPARE_MANY (>=)
917 }
918
919 DEFUN ("/=", Fneq, 1, MANY, 0, /*
920 Return t if no two arguments are numerically equal.
921 The arguments may be numbers, characters or markers.
922 */
923        (int nargs, Lisp_Object *args))
924 {
925   Lisp_Object *args_end = args + nargs;
926   Lisp_Object *p, *q;
927
928   /* Unlike all the other comparisons, this is an N*N algorithm.
929      We could use a hash table for nargs > 50 to make this linear. */
930   for (p = args; p < args_end; p++)
931     {
932       int_or_double iod1, iod2;
933       number_char_or_marker_to_int_or_double (*p, &iod1);
934
935       for (q = p + 1; q < args_end; q++)
936         {
937           number_char_or_marker_to_int_or_double (*q, &iod2);
938
939           if (!((iod1.int_p && iod2.int_p) ?
940                 (iod1.c.ival != iod2.c.ival) :
941                 ((iod1.int_p ? (double) iod1.c.ival : iod1.c.dval) !=
942                  (iod2.int_p ? (double) iod2.c.ival : iod2.c.dval))))
943             return Qnil;
944         }
945     }
946   return Qt;
947 }
948
949 DEFUN ("zerop", Fzerop, 1, 1, 0, /*
950 Return t if NUMBER is zero.
951 */
952        (number))
953 {
954  retry:
955   if (INTP (number))
956     return EQ (number, Qzero) ? Qt : Qnil;
957 #ifdef LISP_FLOAT_TYPE
958   else if (FLOATP (number))
959     return XFLOAT_DATA (number) == 0.0 ? Qt : Qnil;
960 #endif /* LISP_FLOAT_TYPE */
961   else
962     {
963       number = wrong_type_argument (Qnumberp, number);
964       goto retry;
965     }
966 }
967 \f
968 /* Convert between a 32-bit value and a cons of two 16-bit values.
969    This is used to pass 32-bit integers to and from the user.
970    Use time_to_lisp() and lisp_to_time() for time values.
971
972    If you're thinking of using this to store a pointer into a Lisp Object
973    for internal purposes (such as when calling record_unwind_protect()),
974    try using make_opaque_ptr()/get_opaque_ptr() instead. */
975 Lisp_Object
976 word_to_lisp (unsigned int item)
977 {
978   return Fcons (make_int (item >> 16), make_int (item & 0xffff));
979 }
980
981 unsigned int
982 lisp_to_word (Lisp_Object item)
983 {
984   if (INTP (item))
985     return XINT (item);
986   else
987     {
988       Lisp_Object top = Fcar (item);
989       Lisp_Object bot = Fcdr (item);
990       CHECK_INT (top);
991       CHECK_INT (bot);
992       return (XINT (top) << 16) | (XINT (bot) & 0xffff);
993     }
994 }
995
996 \f
997 DEFUN ("number-to-string", Fnumber_to_string, 1, 1, 0, /*
998 Convert NUM to a string by printing it in decimal.
999 Uses a minus sign if negative.
1000 NUM may be an integer or a floating point number.
1001 */
1002        (num))
1003 {
1004   char buffer[VALBITS];
1005
1006   CHECK_INT_OR_FLOAT (num);
1007
1008 #ifdef LISP_FLOAT_TYPE
1009   if (FLOATP (num))
1010     {
1011       char pigbuf[350]; /* see comments in float_to_string */
1012
1013       float_to_string (pigbuf, XFLOAT_DATA (num));
1014       return build_string (pigbuf);
1015     }
1016 #endif /* LISP_FLOAT_TYPE */
1017
1018   long_to_string (buffer, XINT (num));
1019   return build_string (buffer);
1020 }
1021
1022 static int
1023 digit_to_number (int character, int base)
1024 {
1025   /* Assumes ASCII */
1026   int digit = ((character >= '0' && character <= '9') ? character - '0'      :
1027                (character >= 'a' && character <= 'z') ? character - 'a' + 10 :
1028                (character >= 'A' && character <= 'Z') ? character - 'A' + 10 :
1029                -1);
1030
1031   return digit >= base ? -1 : digit;
1032 }
1033
1034 DEFUN ("string-to-number", Fstring_to_number, 1, 2, 0, /*
1035 Convert STRING to a number by parsing it as a decimal number.
1036 This parses both integers and floating point numbers.
1037 It ignores leading spaces and tabs.
1038
1039 If BASE, interpret STRING as a number in that base.  If BASE isn't
1040 present, base 10 is used.  BASE must be between 2 and 16 (inclusive).
1041 Floating point numbers always use base 10.
1042 */
1043        (string, base))
1044 {
1045   char *p;
1046   int b;
1047
1048   CHECK_STRING (string);
1049
1050   if (NILP (base))
1051     b = 10;
1052   else
1053     {
1054       CHECK_INT (base);
1055       b = XINT (base);
1056       check_int_range (b, 2, 16);
1057     }
1058
1059   p = (char *) XSTRING_DATA (string);
1060
1061   /* Skip any whitespace at the front of the number.  Some versions of
1062      atoi do this anyway, so we might as well make Emacs lisp consistent.  */
1063   while (*p == ' ' || *p == '\t')
1064     p++;
1065
1066 #ifdef LISP_FLOAT_TYPE
1067   if (isfloat_string (p))
1068     return make_float (atof (p));
1069 #endif /* LISP_FLOAT_TYPE */
1070
1071   if (b == 10)
1072     {
1073       /* Use the system-provided functions for base 10. */
1074 #if   SIZEOF_EMACS_INT == SIZEOF_INT
1075       return make_int (atoi (p));
1076 #elif SIZEOF_EMACS_INT == SIZEOF_LONG
1077       return make_int (atol (p));
1078 #elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
1079       return make_int (atoll (p));
1080 #endif
1081     }
1082   else
1083     {
1084       int digit, negative = 1;
1085       EMACS_INT v = 0;
1086
1087       if (*p == '-')
1088         {
1089           negative = -1;
1090           p++;
1091         }
1092       else if (*p == '+')
1093         p++;
1094       while (1)
1095         {
1096           digit = digit_to_number (*p++, b);
1097           if (digit < 0)
1098             break;
1099           v = v * b + digit;
1100         }
1101       return make_int (negative * v);
1102     }
1103 }
1104 \f
1105
1106 DEFUN ("+", Fplus, 0, MANY, 0, /*
1107 Return sum of any number of arguments.
1108 The arguments should all be numbers, characters or markers.
1109 */
1110        (int nargs, Lisp_Object *args))
1111 {
1112   EMACS_INT iaccum = 0;
1113   Lisp_Object *args_end = args + nargs;
1114
1115   while (args < args_end)
1116     {
1117       int_or_double iod;
1118       number_char_or_marker_to_int_or_double (*args++, &iod);
1119       if (iod.int_p)
1120         iaccum += iod.c.ival;
1121       else
1122         {
1123           double daccum = (double) iaccum + iod.c.dval;
1124           while (args < args_end)
1125             daccum += number_char_or_marker_to_double (*args++);
1126           return make_float (daccum);
1127         }
1128     }
1129
1130   return make_int (iaccum);
1131 }
1132
1133 DEFUN ("-", Fminus, 1, MANY, 0, /*
1134 Negate number or subtract numbers, characters or markers.
1135 With one arg, negates it.  With more than one arg,
1136 subtracts all but the first from the first.
1137 */
1138        (int nargs, Lisp_Object *args))
1139 {
1140   EMACS_INT iaccum;
1141   double daccum;
1142   Lisp_Object *args_end = args + nargs;
1143   int_or_double iod;
1144
1145   number_char_or_marker_to_int_or_double (*args++, &iod);
1146   if (iod.int_p)
1147     iaccum = nargs > 1 ? iod.c.ival : - iod.c.ival;
1148   else
1149     {
1150       daccum = nargs > 1 ? iod.c.dval : - iod.c.dval;
1151       goto do_float;
1152     }
1153
1154   while (args < args_end)
1155     {
1156       number_char_or_marker_to_int_or_double (*args++, &iod);
1157       if (iod.int_p)
1158         iaccum -= iod.c.ival;
1159       else
1160         {
1161           daccum = (double) iaccum - iod.c.dval;
1162           goto do_float;
1163         }
1164     }
1165
1166   return make_int (iaccum);
1167
1168  do_float:
1169   for (; args < args_end; args++)
1170     daccum -= number_char_or_marker_to_double (*args);
1171   return make_float (daccum);
1172 }
1173
1174 DEFUN ("*", Ftimes, 0, MANY, 0, /*
1175 Return product of any number of arguments.
1176 The arguments should all be numbers, characters or markers.
1177 */
1178        (int nargs, Lisp_Object *args))
1179 {
1180   EMACS_INT iaccum = 1;
1181   Lisp_Object *args_end = args + nargs;
1182
1183   while (args < args_end)
1184     {
1185       int_or_double iod;
1186       number_char_or_marker_to_int_or_double (*args++, &iod);
1187       if (iod.int_p)
1188         iaccum *= iod.c.ival;
1189       else
1190         {
1191           double daccum = (double) iaccum * iod.c.dval;
1192           while (args < args_end)
1193             daccum *= number_char_or_marker_to_double (*args++);
1194           return make_float (daccum);
1195         }
1196     }
1197
1198   return make_int (iaccum);
1199 }
1200
1201 DEFUN ("/", Fquo, 1, MANY, 0, /*
1202 Return first argument divided by all the remaining arguments.
1203 The arguments must be numbers, characters or markers.
1204 With one argument, reciprocates the argument.
1205 */
1206        (int nargs, Lisp_Object *args))
1207 {
1208   EMACS_INT iaccum;
1209   double daccum;
1210   Lisp_Object *args_end = args + nargs;
1211   int_or_double iod;
1212
1213   if (nargs == 1)
1214     iaccum = 1;
1215   else
1216     {
1217       number_char_or_marker_to_int_or_double (*args++, &iod);
1218       if (iod.int_p)
1219         iaccum = iod.c.ival;
1220       else
1221         {
1222           daccum = iod.c.dval;
1223           goto divide_floats;
1224         }
1225     }
1226
1227   while (args < args_end)
1228     {
1229       number_char_or_marker_to_int_or_double (*args++, &iod);
1230       if (iod.int_p)
1231         {
1232           if (iod.c.ival == 0) goto divide_by_zero;
1233           iaccum /= iod.c.ival;
1234         }
1235       else
1236         {
1237           if (iod.c.dval == 0) goto divide_by_zero;
1238           daccum = (double) iaccum / iod.c.dval;
1239           goto divide_floats;
1240         }
1241     }
1242
1243   return make_int (iaccum);
1244
1245  divide_floats:
1246   for (; args < args_end; args++)
1247     {
1248       double dval = number_char_or_marker_to_double (*args);
1249       if (dval == 0) goto divide_by_zero;
1250       daccum /= dval;
1251     }
1252   return make_float (daccum);
1253
1254  divide_by_zero:
1255   Fsignal (Qarith_error, Qnil);
1256   return Qnil; /* not reached */
1257 }
1258
1259 DEFUN ("max", Fmax, 1, MANY, 0, /*
1260 Return largest of all the arguments.
1261 All arguments must be numbers, characters or markers.
1262 The value is always a number; markers and characters are converted
1263 to numbers.
1264 */
1265        (int nargs, Lisp_Object *args))
1266 {
1267   EMACS_INT imax;
1268   double dmax;
1269   Lisp_Object *args_end = args + nargs;
1270   int_or_double iod;
1271
1272   number_char_or_marker_to_int_or_double (*args++, &iod);
1273   if (iod.int_p)
1274     imax = iod.c.ival;
1275   else
1276     {
1277       dmax = iod.c.dval;
1278       goto max_floats;
1279     }
1280
1281   while (args < args_end)
1282     {
1283       number_char_or_marker_to_int_or_double (*args++, &iod);
1284       if (iod.int_p)
1285         {
1286           if (imax < iod.c.ival) imax = iod.c.ival;
1287         }
1288       else
1289         {
1290           dmax = (double) imax;
1291           if (dmax < iod.c.dval) dmax = iod.c.dval;
1292           goto max_floats;
1293         }
1294     }
1295
1296   return make_int (imax);
1297
1298  max_floats:
1299   while (args < args_end)
1300     {
1301       double dval = number_char_or_marker_to_double (*args++);
1302       if (dmax < dval) dmax = dval;
1303     }
1304   return make_float (dmax);
1305 }
1306
1307 DEFUN ("min", Fmin, 1, MANY, 0, /*
1308 Return smallest of all the arguments.
1309 All arguments must be numbers, characters or markers.
1310 The value is always a number; markers and characters are converted
1311 to numbers.
1312 */
1313        (int nargs, Lisp_Object *args))
1314 {
1315   EMACS_INT imin;
1316   double dmin;
1317   Lisp_Object *args_end = args + nargs;
1318   int_or_double iod;
1319
1320   number_char_or_marker_to_int_or_double (*args++, &iod);
1321   if (iod.int_p)
1322     imin = iod.c.ival;
1323   else
1324     {
1325       dmin = iod.c.dval;
1326       goto min_floats;
1327     }
1328
1329   while (args < args_end)
1330     {
1331       number_char_or_marker_to_int_or_double (*args++, &iod);
1332       if (iod.int_p)
1333         {
1334           if (imin > iod.c.ival) imin = iod.c.ival;
1335         }
1336       else
1337         {
1338           dmin = (double) imin;
1339           if (dmin > iod.c.dval) dmin = iod.c.dval;
1340           goto min_floats;
1341         }
1342     }
1343
1344   return make_int (imin);
1345
1346  min_floats:
1347   while (args < args_end)
1348     {
1349       double dval = number_char_or_marker_to_double (*args++);
1350       if (dmin > dval) dmin = dval;
1351     }
1352   return make_float (dmin);
1353 }
1354
1355 DEFUN ("logand", Flogand, 0, MANY, 0, /*
1356 Return bitwise-and of all the arguments.
1357 Arguments may be integers, or markers or characters converted to integers.
1358 */
1359        (int nargs, Lisp_Object *args))
1360 {
1361   EMACS_INT bits = ~0;
1362   Lisp_Object *args_end = args + nargs;
1363
1364   while (args < args_end)
1365     bits &= integer_char_or_marker_to_int (*args++);
1366
1367   return make_int (bits);
1368 }
1369
1370 DEFUN ("logior", Flogior, 0, MANY, 0, /*
1371 Return bitwise-or of all the arguments.
1372 Arguments may be integers, or markers or characters converted to integers.
1373 */
1374        (int nargs, Lisp_Object *args))
1375 {
1376   EMACS_INT bits = 0;
1377   Lisp_Object *args_end = args + nargs;
1378
1379   while (args < args_end)
1380     bits |= integer_char_or_marker_to_int (*args++);
1381
1382   return make_int (bits);
1383 }
1384
1385 DEFUN ("logxor", Flogxor, 0, MANY, 0, /*
1386 Return bitwise-exclusive-or of all the arguments.
1387 Arguments may be integers, or markers or characters converted to integers.
1388 */
1389        (int nargs, Lisp_Object *args))
1390 {
1391   EMACS_INT bits = 0;
1392   Lisp_Object *args_end = args + nargs;
1393
1394   while (args < args_end)
1395     bits ^= integer_char_or_marker_to_int (*args++);
1396
1397   return make_int (bits);
1398 }
1399
1400 DEFUN ("lognot", Flognot, 1, 1, 0, /*
1401 Return the bitwise complement of NUMBER.
1402 NUMBER may be an integer, marker or character converted to integer.
1403 */
1404        (number))
1405 {
1406   return make_int (~ integer_char_or_marker_to_int (number));
1407 }
1408
1409 DEFUN ("%", Frem, 2, 2, 0, /*
1410 Return remainder of first arg divided by second.
1411 Both must be integers, characters or markers.
1412 */
1413        (num1, num2))
1414 {
1415   EMACS_INT ival1 = integer_char_or_marker_to_int (num1);
1416   EMACS_INT ival2 = integer_char_or_marker_to_int (num2);
1417
1418   if (ival2 == 0)
1419     Fsignal (Qarith_error, Qnil);
1420
1421   return make_int (ival1 % ival2);
1422 }
1423
1424 /* Note, ANSI *requires* the presence of the fmod() library routine.
1425    If your system doesn't have it, complain to your vendor, because
1426    that is a bug. */
1427
1428 #ifndef HAVE_FMOD
1429 double
1430 fmod (double f1, double f2)
1431 {
1432   if (f2 < 0.0)
1433     f2 = -f2;
1434   return f1 - f2 * floor (f1/f2);
1435 }
1436 #endif /* ! HAVE_FMOD */
1437
1438
1439 DEFUN ("mod", Fmod, 2, 2, 0, /*
1440 Return X modulo Y.
1441 The result falls between zero (inclusive) and Y (exclusive).
1442 Both X and Y must be numbers, characters or markers.
1443 If either argument is a float, a float will be returned.
1444 */
1445        (x, y))
1446 {
1447   int_or_double iod1, iod2;
1448   number_char_or_marker_to_int_or_double (x, &iod1);
1449   number_char_or_marker_to_int_or_double (y, &iod2);
1450
1451 #ifdef LISP_FLOAT_TYPE
1452   if (!iod1.int_p || !iod2.int_p)
1453     {
1454       double dval1 = iod1.int_p ? (double) iod1.c.ival : iod1.c.dval;
1455       double dval2 = iod2.int_p ? (double) iod2.c.ival : iod2.c.dval;
1456       if (dval2 == 0) goto divide_by_zero;
1457       dval1 = fmod (dval1, dval2);
1458
1459       /* If the "remainder" comes out with the wrong sign, fix it.  */
1460       if (dval2 < 0 ? dval1 > 0 : dval1 < 0)
1461         dval1 += dval2;
1462
1463       return make_float (dval1);
1464     }
1465 #endif /* LISP_FLOAT_TYPE */
1466   {
1467     EMACS_INT ival;
1468     if (iod2.c.ival == 0) goto divide_by_zero;
1469
1470     ival = iod1.c.ival % iod2.c.ival;
1471
1472     /* If the "remainder" comes out with the wrong sign, fix it.  */
1473     if (iod2.c.ival < 0 ? ival > 0 : ival < 0)
1474       ival += iod2.c.ival;
1475
1476     return make_int (ival);
1477   }
1478
1479  divide_by_zero:
1480   Fsignal (Qarith_error, Qnil);
1481   return Qnil; /* not reached */
1482 }
1483
1484 DEFUN ("ash", Fash, 2, 2, 0, /*
1485 Return VALUE with its bits shifted left by COUNT.
1486 If COUNT is negative, shifting is actually to the right.
1487 In this case, the sign bit is duplicated.
1488 */
1489        (value, count))
1490 {
1491   CHECK_INT_COERCE_CHAR (value);
1492   CONCHECK_INT (count);
1493
1494   return make_int (XINT (count) > 0 ?
1495                    XINT (value) <<  XINT (count) :
1496                    XINT (value) >> -XINT (count));
1497 }
1498
1499 DEFUN ("lsh", Flsh, 2, 2, 0, /*
1500 Return VALUE with its bits shifted left by COUNT.
1501 If COUNT is negative, shifting is actually to the right.
1502 In this case, zeros are shifted in on the left.
1503 */
1504        (value, count))
1505 {
1506   CHECK_INT_COERCE_CHAR (value);
1507   CONCHECK_INT (count);
1508
1509   return make_int (XINT (count) > 0 ?
1510                    XUINT (value) <<  XINT (count) :
1511                    XUINT (value) >> -XINT (count));
1512 }
1513
1514 DEFUN ("1+", Fadd1, 1, 1, 0, /*
1515 Return NUMBER plus one.  NUMBER may be a number, character or marker.
1516 Markers and characters are converted to integers.
1517 */
1518        (number))
1519 {
1520  retry:
1521
1522   if (INTP    (number)) return make_int (XINT  (number) + 1);
1523   if (CHARP   (number)) return make_int (XCHAR (number) + 1);
1524   if (MARKERP (number)) return make_int (marker_position (number) + 1);
1525 #ifdef LISP_FLOAT_TYPE
1526   if (FLOATP  (number)) return make_float (XFLOAT_DATA (number) + 1.0);
1527 #endif /* LISP_FLOAT_TYPE */
1528
1529   number = wrong_type_argument (Qnumber_char_or_marker_p, number);
1530   goto retry;
1531 }
1532
1533 DEFUN ("1-", Fsub1, 1, 1, 0, /*
1534 Return NUMBER minus one.  NUMBER may be a number, character or marker.
1535 Markers and characters are converted to integers.
1536 */
1537        (number))
1538 {
1539  retry:
1540
1541   if (INTP    (number)) return make_int (XINT  (number) - 1);
1542   if (CHARP   (number)) return make_int (XCHAR (number) - 1);
1543   if (MARKERP (number)) return make_int (marker_position (number) - 1);
1544 #ifdef LISP_FLOAT_TYPE
1545   if (FLOATP  (number)) return make_float (XFLOAT_DATA (number) - 1.0);
1546 #endif /* LISP_FLOAT_TYPE */
1547
1548   number = wrong_type_argument (Qnumber_char_or_marker_p, number);
1549   goto retry;
1550 }
1551
1552 \f
1553 /************************************************************************/
1554 /*                              weak lists                              */
1555 /************************************************************************/
1556
1557 /* A weak list is like a normal list except that elements automatically
1558    disappear when no longer in use, i.e. when no longer GC-protected.
1559    The basic idea is that we don't mark the elements during GC, but
1560    wait for them to be marked elsewhere.  If they're not marked, we
1561    remove them.  This is analogous to weak hash tables; see the explanation
1562    there for more info. */
1563
1564 static Lisp_Object Vall_weak_lists; /* Gemarke es nicht!!! */
1565
1566 static Lisp_Object encode_weak_list_type (enum weak_list_type type);
1567
1568 static Lisp_Object
1569 mark_weak_list (Lisp_Object obj)
1570 {
1571   return Qnil; /* nichts ist gemarkt */
1572 }
1573
1574 static void
1575 print_weak_list (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1576 {
1577   if (print_readably)
1578     error ("printing unreadable object #<weak-list>");
1579
1580   write_c_string ("#<weak-list ", printcharfun);
1581   print_internal (encode_weak_list_type (XWEAK_LIST (obj)->type),
1582                   printcharfun, 0);
1583   write_c_string (" ", printcharfun);
1584   print_internal (XWEAK_LIST (obj)->list, printcharfun, escapeflag);
1585   write_c_string (">", printcharfun);
1586 }
1587
1588 static int
1589 weak_list_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1590 {
1591   struct weak_list *w1 = XWEAK_LIST (obj1);
1592   struct weak_list *w2 = XWEAK_LIST (obj2);
1593
1594   return ((w1->type == w2->type) &&
1595           internal_equal (w1->list, w2->list, depth + 1));
1596 }
1597
1598 static unsigned long
1599 weak_list_hash (Lisp_Object obj, int depth)
1600 {
1601   struct weak_list *w = XWEAK_LIST (obj);
1602
1603   return HASH2 ((unsigned long) w->type,
1604                 internal_hash (w->list, depth + 1));
1605 }
1606
1607 Lisp_Object
1608 make_weak_list (enum weak_list_type type)
1609 {
1610   Lisp_Object result;
1611   struct weak_list *wl =
1612     alloc_lcrecord_type (struct weak_list, &lrecord_weak_list);
1613
1614   wl->list = Qnil;
1615   wl->type = type;
1616   XSETWEAK_LIST (result, wl);
1617   wl->next_weak = Vall_weak_lists;
1618   Vall_weak_lists = result;
1619   return result;
1620 }
1621
1622 static const struct lrecord_description weak_list_description[] = {
1623   { XD_LISP_OBJECT, offsetof(struct weak_list, list), 1 },
1624   { XD_LO_LINK,     offsetof(struct weak_list, next_weak) },
1625   { XD_END }
1626 };
1627
1628 DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
1629                                mark_weak_list, print_weak_list,
1630                                0, weak_list_equal, weak_list_hash,
1631                                weak_list_description,
1632                                struct weak_list);
1633 /*
1634    -- we do not mark the list elements (either the elements themselves
1635       or the cons cells that hold them) in the normal marking phase.
1636    -- at the end of marking, we go through all weak lists that are
1637       marked, and mark the cons cells that hold all marked
1638       objects, and possibly parts of the objects themselves.
1639       (See alloc.c, "after-mark".)
1640    -- after that, we prune away all the cons cells that are not marked.
1641
1642    WARNING WARNING WARNING WARNING WARNING:
1643
1644    The code in the following two functions is *unbelievably* tricky.
1645    Don't mess with it.  You'll be sorry.
1646
1647    Linked lists just majorly suck, d'ya know?
1648 */
1649
1650 int
1651 finish_marking_weak_lists (void)
1652 {
1653   Lisp_Object rest;
1654   int did_mark = 0;
1655
1656   for (rest = Vall_weak_lists;
1657        !NILP (rest);
1658        rest = XWEAK_LIST (rest)->next_weak)
1659     {
1660       Lisp_Object rest2;
1661       enum weak_list_type type = XWEAK_LIST (rest)->type;
1662
1663       if (! marked_p (rest))
1664         /* The weak list is probably garbage.  Ignore it. */
1665         continue;
1666
1667       for (rest2 = XWEAK_LIST (rest)->list;
1668            /* We need to be trickier since we're inside of GC;
1669               use CONSP instead of !NILP in case of user-visible
1670               imperfect lists */
1671            CONSP (rest2);
1672            rest2 = XCDR (rest2))
1673         {
1674           Lisp_Object elem;
1675           /* If the element is "marked" (meaning depends on the type
1676              of weak list), we need to mark the cons containing the
1677              element, and maybe the element itself (if only some part
1678              was already marked). */
1679           int need_to_mark_cons = 0;
1680           int need_to_mark_elem = 0;
1681
1682           /* If a cons is already marked, then its car is already marked
1683              (either because of an external pointer or because of
1684              a previous call to this function), and likewise for all
1685              the rest of the elements in the list, so we can stop now. */
1686           if (marked_p (rest2))
1687             break;
1688
1689           elem = XCAR (rest2);
1690
1691           switch (type)
1692             {
1693             case WEAK_LIST_SIMPLE:
1694               if (marked_p (elem))
1695                 need_to_mark_cons = 1;
1696               break;
1697
1698             case WEAK_LIST_ASSOC:
1699               if (!CONSP (elem))
1700                 {
1701                   /* just leave bogus elements there */
1702                   need_to_mark_cons = 1;
1703                   need_to_mark_elem = 1;
1704                 }
1705               else if (marked_p (XCAR (elem)) &&
1706                        marked_p (XCDR (elem)))
1707                 {
1708                   need_to_mark_cons = 1;
1709                   /* We still need to mark elem, because it's
1710                      probably not marked. */
1711                   need_to_mark_elem = 1;
1712                 }
1713               break;
1714
1715             case WEAK_LIST_KEY_ASSOC:
1716               if (!CONSP (elem))
1717                 {
1718                   /* just leave bogus elements there */
1719                   need_to_mark_cons = 1;
1720                   need_to_mark_elem = 1;
1721                 }
1722               else if (marked_p (XCAR (elem)))
1723                 {
1724                   need_to_mark_cons = 1;
1725                   /* We still need to mark elem and XCDR (elem);
1726                      marking elem does both */
1727                   need_to_mark_elem = 1;
1728                 }
1729               break;
1730
1731             case WEAK_LIST_VALUE_ASSOC:
1732               if (!CONSP (elem))
1733                 {
1734                   /* just leave bogus elements there */
1735                   need_to_mark_cons = 1;
1736                   need_to_mark_elem = 1;
1737                 }
1738               else if (marked_p (XCDR (elem)))
1739                 {
1740                   need_to_mark_cons = 1;
1741                   /* We still need to mark elem and XCAR (elem);
1742                      marking elem does both */
1743                   need_to_mark_elem = 1;
1744                 }
1745               break;
1746
1747             default:
1748               abort ();
1749             }
1750
1751           if (need_to_mark_elem && ! marked_p (elem))
1752             {
1753               mark_object (elem);
1754               did_mark = 1;
1755             }
1756
1757           /* We also need to mark the cons that holds the elem or
1758              assoc-pair.  We do *not* want to call (mark_object) here
1759              because that will mark the entire list; we just want to
1760              mark the cons itself.
1761              */
1762           if (need_to_mark_cons)
1763             {
1764               Lisp_Cons *c = XCONS (rest2);
1765               if (!CONS_MARKED_P (c))
1766                 {
1767                   MARK_CONS (c);
1768                   did_mark = 1;
1769                 }
1770             }
1771         }
1772
1773       /* In case of imperfect list, need to mark the final cons
1774          because we're not removing it */
1775       if (!NILP (rest2) && ! marked_p (rest2))
1776         {
1777           mark_object (rest2);
1778           did_mark = 1;
1779         }
1780     }
1781
1782   return did_mark;
1783 }
1784
1785 void
1786 prune_weak_lists (void)
1787 {
1788   Lisp_Object rest, prev = Qnil;
1789
1790   for (rest = Vall_weak_lists;
1791        !NILP (rest);
1792        rest = XWEAK_LIST (rest)->next_weak)
1793     {
1794       if (! (marked_p (rest)))
1795         {
1796           /* This weak list itself is garbage.  Remove it from the list. */
1797           if (NILP (prev))
1798             Vall_weak_lists = XWEAK_LIST (rest)->next_weak;
1799           else
1800             XWEAK_LIST (prev)->next_weak =
1801               XWEAK_LIST (rest)->next_weak;
1802         }
1803       else
1804         {
1805           Lisp_Object rest2, prev2 = Qnil;
1806           Lisp_Object tortoise;
1807           int go_tortoise = 0;
1808
1809           for (rest2 = XWEAK_LIST (rest)->list, tortoise = rest2;
1810                /* We need to be trickier since we're inside of GC;
1811                   use CONSP instead of !NILP in case of user-visible
1812                   imperfect lists */
1813                CONSP (rest2);)
1814             {
1815               /* It suffices to check the cons for marking,
1816                  regardless of the type of weak list:
1817
1818                  -- if the cons is pointed to somewhere else,
1819                     then it should stay around and will be marked.
1820                  -- otherwise, if it should stay around, it will
1821                     have been marked in finish_marking_weak_lists().
1822                  -- otherwise, it's not marked and should disappear.
1823                  */
1824               if (! marked_p (rest2))
1825                 {
1826                   /* bye bye :-( */
1827                   if (NILP (prev2))
1828                     XWEAK_LIST (rest)->list = XCDR (rest2);
1829                   else
1830                     XCDR (prev2) = XCDR (rest2);
1831                   rest2 = XCDR (rest2);
1832                   /* Ouch.  Circularity checking is even trickier
1833                      than I thought.  When we cut out a link
1834                      like this, we can't advance the turtle or
1835                      it'll catch up to us.  Imagine that we're
1836                      standing on floor tiles and moving forward --
1837                      what we just did here is as if the floor
1838                      tile under us just disappeared and all the
1839                      ones ahead of us slid one tile towards us.
1840                      In other words, we didn't move at all;
1841                      if the tortoise was one step behind us
1842                      previously, it still is, and therefore
1843                      it must not move. */
1844                 }
1845               else
1846                 {
1847                   prev2 = rest2;
1848
1849                   /* Implementing circularity checking is trickier here
1850                      than in other places because we have to guarantee
1851                      that we've processed all elements before exiting
1852                      due to a circularity. (In most places, an error
1853                      is issued upon encountering a circularity, so it
1854                      doesn't really matter if all elements are processed.)
1855                      The idea is that we process along with the hare
1856                      rather than the tortoise.  If at any point in
1857                      our forward process we encounter the tortoise,
1858                      we must have already visited the spot, so we exit.
1859                      (If we process with the tortoise, we can fail to
1860                      process cases where a cons points to itself, or
1861                      where cons A points to cons B, which points to
1862                      cons A.) */
1863
1864                   rest2 = XCDR (rest2);
1865                   if (go_tortoise)
1866                     tortoise = XCDR (tortoise);
1867                   go_tortoise = !go_tortoise;
1868                   if (EQ (rest2, tortoise))
1869                     break;
1870                 }
1871             }
1872
1873           prev = rest;
1874         }
1875     }
1876 }
1877
1878 static enum weak_list_type
1879 decode_weak_list_type (Lisp_Object symbol)
1880 {
1881   CHECK_SYMBOL (symbol);
1882   if (EQ (symbol, Qsimple))      return WEAK_LIST_SIMPLE;
1883   if (EQ (symbol, Qassoc))       return WEAK_LIST_ASSOC;
1884   if (EQ (symbol, Qold_assoc))   return WEAK_LIST_ASSOC;  /* EBOLA ALERT! */
1885   if (EQ (symbol, Qkey_assoc))   return WEAK_LIST_KEY_ASSOC;
1886   if (EQ (symbol, Qvalue_assoc)) return WEAK_LIST_VALUE_ASSOC;
1887
1888   signal_simple_error ("Invalid weak list type", symbol);
1889   return WEAK_LIST_SIMPLE; /* not reached */
1890 }
1891
1892 static Lisp_Object
1893 encode_weak_list_type (enum weak_list_type type)
1894 {
1895   switch (type)
1896     {
1897     case WEAK_LIST_SIMPLE:      return Qsimple;
1898     case WEAK_LIST_ASSOC:       return Qassoc;
1899     case WEAK_LIST_KEY_ASSOC:   return Qkey_assoc;
1900     case WEAK_LIST_VALUE_ASSOC: return Qvalue_assoc;
1901     default:
1902       abort ();
1903     }
1904
1905   return Qnil; /* not reached */
1906 }
1907
1908 DEFUN ("weak-list-p", Fweak_list_p, 1, 1, 0, /*
1909 Return non-nil if OBJECT is a weak list.
1910 */
1911        (object))
1912 {
1913   return WEAK_LISTP (object) ? Qt : Qnil;
1914 }
1915
1916 DEFUN ("make-weak-list", Fmake_weak_list, 0, 1, 0, /*
1917 Return a new weak list object of type TYPE.
1918 A weak list object is an object that contains a list.  This list behaves
1919 like any other list except that its elements do not count towards
1920 garbage collection -- if the only pointer to an object in inside a weak
1921 list (other than pointers in similar objects such as weak hash tables),
1922 the object is garbage collected and automatically removed from the list.
1923 This is used internally, for example, to manage the list holding the
1924 children of an extent -- an extent that is unused but has a parent will
1925 still be reclaimed, and will automatically be removed from its parent's
1926 list of children.
1927
1928 Optional argument TYPE specifies the type of the weak list, and defaults
1929 to `simple'.  Recognized types are
1930
1931 `simple'        Objects in the list disappear if not pointed to.
1932 `assoc'         Objects in the list disappear if they are conses
1933                 and either the car or the cdr of the cons is not
1934                 pointed to.
1935 `key-assoc'     Objects in the list disappear if they are conses
1936                 and the car is not pointed to.
1937 `value-assoc'   Objects in the list disappear if they are conses
1938                 and the cdr is not pointed to.
1939 */
1940        (type))
1941 {
1942   if (NILP (type))
1943     type = Qsimple;
1944
1945   return make_weak_list (decode_weak_list_type (type));
1946 }
1947
1948 DEFUN ("weak-list-type", Fweak_list_type, 1, 1, 0, /*
1949 Return the type of the given weak-list object.
1950 */
1951        (weak))
1952 {
1953   CHECK_WEAK_LIST (weak);
1954   return encode_weak_list_type (XWEAK_LIST (weak)->type);
1955 }
1956
1957 DEFUN ("weak-list-list", Fweak_list_list, 1, 1, 0, /*
1958 Return the list contained in a weak-list object.
1959 */
1960        (weak))
1961 {
1962   CHECK_WEAK_LIST (weak);
1963   return XWEAK_LIST_LIST (weak);
1964 }
1965
1966 DEFUN ("set-weak-list-list", Fset_weak_list_list, 2, 2, 0, /*
1967 Change the list contained in a weak-list object.
1968 */
1969        (weak, new_list))
1970 {
1971   CHECK_WEAK_LIST (weak);
1972   XWEAK_LIST_LIST (weak) = new_list;
1973   return new_list;
1974 }
1975
1976 \f
1977 /************************************************************************/
1978 /*                            initialization                            */
1979 /************************************************************************/
1980
1981 static SIGTYPE
1982 arith_error (int signo)
1983 {
1984   EMACS_REESTABLISH_SIGNAL (signo, arith_error);
1985   EMACS_UNBLOCK_SIGNAL (signo);
1986   signal_error (Qarith_error, Qnil);
1987 }
1988
1989 void
1990 init_data_very_early (void)
1991 {
1992   /* Don't do this if just dumping out.
1993      We don't want to call `signal' in this case
1994      so that we don't have trouble with dumping
1995      signal-delivering routines in an inconsistent state.  */
1996 #ifndef CANNOT_DUMP
1997   if (!initialized)
1998     return;
1999 #endif /* CANNOT_DUMP */
2000   signal (SIGFPE, arith_error);
2001 #ifdef uts
2002   signal (SIGEMT, arith_error);
2003 #endif /* uts */
2004 }
2005
2006 void
2007 init_errors_once_early (void)
2008 {
2009   defsymbol (&Qerror_conditions, "error-conditions");
2010   defsymbol (&Qerror_message, "error-message");
2011
2012   /* We declare the errors here because some other deferrors depend
2013      on some of the errors below. */
2014
2015   /* ERROR is used as a signaler for random errors for which nothing
2016      else is right */
2017
2018   deferror (&Qerror, "error", "error", Qnil);
2019   deferror (&Qquit, "quit", "Quit", Qnil);
2020
2021   deferror (&Qwrong_type_argument, "wrong-type-argument",
2022             "Wrong type argument", Qerror);
2023   deferror (&Qargs_out_of_range, "args-out-of-range", "Args out of range",
2024             Qerror);
2025   deferror (&Qvoid_function, "void-function",
2026             "Symbol's function definition is void", Qerror);
2027   deferror (&Qcyclic_function_indirection, "cyclic-function-indirection",
2028             "Symbol's chain of function indirections contains a loop", Qerror);
2029   deferror (&Qvoid_variable, "void-variable",
2030             "Symbol's value as variable is void", Qerror);
2031   deferror (&Qcyclic_variable_indirection, "cyclic-variable-indirection",
2032             "Symbol's chain of variable indirections contains a loop", Qerror);
2033   deferror (&Qsetting_constant, "setting-constant",
2034             "Attempt to set a constant symbol", Qerror);
2035   deferror (&Qinvalid_read_syntax, "invalid-read-syntax",
2036             "Invalid read syntax", Qerror);
2037
2038   /* Generated by list traversal macros */
2039   deferror (&Qmalformed_list, "malformed-list",
2040             "Malformed list", Qerror);
2041   deferror (&Qmalformed_property_list, "malformed-property-list",
2042             "Malformed property list", Qmalformed_list);
2043   deferror (&Qcircular_list, "circular-list",
2044             "Circular list", Qerror);
2045   deferror (&Qcircular_property_list, "circular-property-list",
2046             "Circular property list", Qcircular_list);
2047
2048   deferror (&Qinvalid_function, "invalid-function", "Invalid function",
2049             Qerror);
2050   deferror (&Qwrong_number_of_arguments, "wrong-number-of-arguments",
2051             "Wrong number of arguments", Qerror);
2052   deferror (&Qno_catch, "no-catch", "No catch for tag",
2053             Qerror);
2054   deferror (&Qbeginning_of_buffer, "beginning-of-buffer",
2055             "Beginning of buffer", Qerror);
2056   deferror (&Qend_of_buffer, "end-of-buffer", "End of buffer", Qerror);
2057   deferror (&Qbuffer_read_only, "buffer-read-only", "Buffer is read-only",
2058             Qerror);
2059
2060   deferror (&Qio_error, "io-error", "IO Error", Qerror);
2061   deferror (&Qend_of_file, "end-of-file", "End of stream", Qio_error);
2062
2063   deferror (&Qarith_error, "arith-error", "Arithmetic error", Qerror);
2064   deferror (&Qrange_error, "range-error", "Arithmetic range error",
2065             Qarith_error);
2066   deferror (&Qdomain_error, "domain-error", "Arithmetic domain error",
2067             Qarith_error);
2068   deferror (&Qsingularity_error, "singularity-error",
2069             "Arithmetic singularity error", Qdomain_error);
2070   deferror (&Qoverflow_error, "overflow-error",
2071             "Arithmetic overflow error", Qdomain_error);
2072   deferror (&Qunderflow_error, "underflow-error",
2073             "Arithmetic underflow error", Qdomain_error);
2074 }
2075
2076 void
2077 syms_of_data (void)
2078 {
2079   defsymbol (&Qquote, "quote");
2080   defsymbol (&Qlambda, "lambda");
2081   defsymbol (&Qlistp, "listp");
2082   defsymbol (&Qtrue_list_p, "true-list-p");
2083   defsymbol (&Qconsp, "consp");
2084   defsymbol (&Qsubrp, "subrp");
2085   defsymbol (&Qsymbolp, "symbolp");
2086   defsymbol (&Qintegerp, "integerp");
2087   defsymbol (&Qcharacterp, "characterp");
2088   defsymbol (&Qnatnump, "natnump");
2089   defsymbol (&Qstringp, "stringp");
2090   defsymbol (&Qarrayp, "arrayp");
2091   defsymbol (&Qsequencep, "sequencep");
2092   defsymbol (&Qbufferp, "bufferp");
2093   defsymbol (&Qbitp, "bitp");
2094   defsymbol (&Qbit_vectorp, "bit-vector-p");
2095   defsymbol (&Qvectorp, "vectorp");
2096   defsymbol (&Qchar_or_string_p, "char-or-string-p");
2097   defsymbol (&Qmarkerp, "markerp");
2098   defsymbol (&Qinteger_or_marker_p, "integer-or-marker-p");
2099   defsymbol (&Qinteger_or_char_p, "integer-or-char-p");
2100   defsymbol (&Qinteger_char_or_marker_p, "integer-char-or-marker-p");
2101   defsymbol (&Qnumberp, "numberp");
2102   defsymbol (&Qnumber_char_or_marker_p, "number-char-or-marker-p");
2103   defsymbol (&Qcdr, "cdr");
2104   defsymbol (&Qweak_listp, "weak-list-p");
2105
2106 #ifdef LISP_FLOAT_TYPE
2107   defsymbol (&Qfloatp, "floatp");
2108 #endif /* LISP_FLOAT_TYPE */
2109
2110   DEFSUBR (Fwrong_type_argument);
2111
2112   DEFSUBR (Feq);
2113   DEFSUBR (Fold_eq);
2114   DEFSUBR (Fnull);
2115   Ffset (intern ("not"), intern ("null"));
2116   DEFSUBR (Flistp);
2117   DEFSUBR (Fnlistp);
2118   DEFSUBR (Ftrue_list_p);
2119   DEFSUBR (Fconsp);
2120   DEFSUBR (Fatom);
2121   DEFSUBR (Fchar_or_string_p);
2122   DEFSUBR (Fcharacterp);
2123   DEFSUBR (Fchar_int_p);
2124   DEFSUBR (Fchar_to_int);
2125   DEFSUBR (Fint_to_char);
2126   DEFSUBR (Fchar_or_char_int_p);
2127   DEFSUBR (Fintegerp);
2128   DEFSUBR (Finteger_or_marker_p);
2129   DEFSUBR (Finteger_or_char_p);
2130   DEFSUBR (Finteger_char_or_marker_p);
2131   DEFSUBR (Fnumberp);
2132   DEFSUBR (Fnumber_or_marker_p);
2133   DEFSUBR (Fnumber_char_or_marker_p);
2134 #ifdef LISP_FLOAT_TYPE
2135   DEFSUBR (Ffloatp);
2136 #endif /* LISP_FLOAT_TYPE */
2137   DEFSUBR (Fnatnump);
2138   DEFSUBR (Fsymbolp);
2139   DEFSUBR (Fkeywordp);
2140   DEFSUBR (Fstringp);
2141   DEFSUBR (Fvectorp);
2142   DEFSUBR (Fbitp);
2143   DEFSUBR (Fbit_vector_p);
2144   DEFSUBR (Farrayp);
2145   DEFSUBR (Fsequencep);
2146   DEFSUBR (Fmarkerp);
2147   DEFSUBR (Fsubrp);
2148   DEFSUBR (Fsubr_min_args);
2149   DEFSUBR (Fsubr_max_args);
2150   DEFSUBR (Fsubr_interactive);
2151   DEFSUBR (Ftype_of);
2152   DEFSUBR (Fcar);
2153   DEFSUBR (Fcdr);
2154   DEFSUBR (Fcar_safe);
2155   DEFSUBR (Fcdr_safe);
2156   DEFSUBR (Fsetcar);
2157   DEFSUBR (Fsetcdr);
2158   DEFSUBR (Findirect_function);
2159   DEFSUBR (Faref);
2160   DEFSUBR (Faset);
2161
2162   DEFSUBR (Fnumber_to_string);
2163   DEFSUBR (Fstring_to_number);
2164   DEFSUBR (Feqlsign);
2165   DEFSUBR (Flss);
2166   DEFSUBR (Fgtr);
2167   DEFSUBR (Fleq);
2168   DEFSUBR (Fgeq);
2169   DEFSUBR (Fneq);
2170   DEFSUBR (Fzerop);
2171   DEFSUBR (Fplus);
2172   DEFSUBR (Fminus);
2173   DEFSUBR (Ftimes);
2174   DEFSUBR (Fquo);
2175   DEFSUBR (Frem);
2176   DEFSUBR (Fmod);
2177   DEFSUBR (Fmax);
2178   DEFSUBR (Fmin);
2179   DEFSUBR (Flogand);
2180   DEFSUBR (Flogior);
2181   DEFSUBR (Flogxor);
2182   DEFSUBR (Flsh);
2183   DEFSUBR (Fash);
2184   DEFSUBR (Fadd1);
2185   DEFSUBR (Fsub1);
2186   DEFSUBR (Flognot);
2187
2188   DEFSUBR (Fweak_list_p);
2189   DEFSUBR (Fmake_weak_list);
2190   DEFSUBR (Fweak_list_type);
2191   DEFSUBR (Fweak_list_list);
2192   DEFSUBR (Fset_weak_list_list);
2193 }
2194
2195 void
2196 vars_of_data (void)
2197 {
2198   /* This must not be staticpro'd */
2199   Vall_weak_lists = Qnil;
2200   pdump_wire_list (&Vall_weak_lists);
2201
2202 #ifdef DEBUG_XEMACS
2203   DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /*
2204 If non-zero, note when your code may be suffering from char-int confoundance.
2205 That is to say, if XEmacs encounters a usage of `eq', `memq', `equal',
2206 etc. where an int and a char with the same value are being compared,
2207 it will issue a notice on stderr to this effect, along with a backtrace.
2208 In such situations, the result would be different in XEmacs 19 versus
2209 XEmacs 20, and you probably don't want this.
2210
2211 Note that in order to see these notices, you have to byte compile your
2212 code under XEmacs 20 -- any code byte-compiled under XEmacs 19 will
2213 have its chars and ints all confounded in the byte code, making it
2214 impossible to accurately determine Ebola infection.
2215 */ );
2216
2217   debug_issue_ebola_notices = 0;
2218
2219   DEFVAR_INT ("debug-ebola-backtrace-length",
2220               &debug_ebola_backtrace_length /*
2221 Length (in stack frames) of short backtrace printed out in Ebola notices.
2222 See `debug-issue-ebola-notices'.
2223 */ );
2224   debug_ebola_backtrace_length = 32;
2225
2226 #endif /* DEBUG_XEMACS */
2227 }