comparison src/data.c @ 428:3ecd8885ac67 r21-2-22

Import from CVS: tag r21-2-22
author cvs
date Mon, 13 Aug 2007 11:28:15 +0200
parents
children 080151679be2
comparison
equal deleted inserted replaced
427:0a0253eac470 428:3ecd8885ac67
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
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
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
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
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
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
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
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 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
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
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
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
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
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
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
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 }