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