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 Copyright (C) 2000 Ben Wing.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: Mule 2.0, FSF 19.30. Some of FSF's data.c is in
26 /* This file has been Mule-ized. */
33 #include "syssignal.h"
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 */
41 Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
43 Lisp_Object Qunloaded;
45 Lisp_Object Qerror_conditions, Qerror_message;
46 Lisp_Object Qerror, Qquit, Qsyntax_error, Qinvalid_read_syntax;
47 Lisp_Object Qlist_formation_error;
48 Lisp_Object Qmalformed_list, Qmalformed_property_list;
49 Lisp_Object Qcircular_list, Qcircular_property_list;
50 Lisp_Object Qinvalid_argument, Qwrong_type_argument, Qargs_out_of_range;
51 Lisp_Object Qwrong_number_of_arguments, Qinvalid_function, Qno_catch;
52 Lisp_Object Qinternal_error, Qinvalid_state;
53 Lisp_Object Qvoid_variable, Qcyclic_variable_indirection;
54 Lisp_Object Qvoid_function, Qcyclic_function_indirection;
55 Lisp_Object Qinvalid_operation, Qinvalid_change;
56 Lisp_Object Qsetting_constant;
57 Lisp_Object Qediting_error;
58 Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
59 Lisp_Object Qio_error, Qend_of_file;
60 Lisp_Object Qarith_error, Qrange_error, Qdomain_error;
61 Lisp_Object Qsingularity_error, Qoverflow_error, Qunderflow_error;
62 Lisp_Object Qintegerp, Qnatnump, Qsymbolp;
63 Lisp_Object Qlistp, Qtrue_list_p, Qweak_listp;
64 Lisp_Object Qconsp, Qsubrp;
65 Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qvectorp;
66 Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qbufferp;
67 Lisp_Object Qinteger_or_char_p, Qinteger_char_or_marker_p;
68 Lisp_Object Qnumberp, Qnumber_char_or_marker_p;
69 Lisp_Object Qbit_vectorp, Qbitp, Qcdr;
75 int debug_issue_ebola_notices;
77 Fixnum debug_ebola_backtrace_length;
80 eq_with_ebola_notice (Lisp_Object obj1, Lisp_Object obj2)
82 if (debug_issue_ebola_notices
83 && ((CHARP (obj1) && INTP (obj2)) || (CHARP (obj2) && INTP (obj1))))
85 /* #### It would be really nice if this were a proper warning
86 instead of brain-dead print to Qexternal_debugging_output. */
87 write_c_string ("Comparison between integer and character is constant nil (",
88 Qexternal_debugging_output);
89 Fprinc (obj1, Qexternal_debugging_output);
90 write_c_string (" and ", Qexternal_debugging_output);
91 Fprinc (obj2, Qexternal_debugging_output);
92 write_c_string (")\n", Qexternal_debugging_output);
93 debug_short_backtrace (debug_ebola_backtrace_length);
95 return EQ (obj1, obj2);
98 #endif /* DEBUG_XEMACS */
103 wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
105 /* This function can GC */
106 REGISTER Lisp_Object tem;
109 value = Fsignal (Qwrong_type_argument, list2 (predicate, value));
110 tem = call1 (predicate, value);
117 dead_wrong_type_argument (Lisp_Object predicate, Lisp_Object value)
119 signal_error (Qwrong_type_argument, list2 (predicate, value));
122 DEFUN ("wrong-type-argument", Fwrong_type_argument, 2, 2, 0, /*
123 Signal an error until the correct type value is given by the user.
124 This function loops, signalling a continuable `wrong-type-argument' error
125 with PREDICATE and VALUE as the data associated with the error and then
126 calling PREDICATE on the returned value, until the value gotten satisfies
127 PREDICATE. At that point, the gotten value is returned.
131 return wrong_type_argument (predicate, value);
135 c_write_error (Lisp_Object obj)
137 signal_simple_error ("Attempt to modify read-only object (c)", obj);
141 lisp_write_error (Lisp_Object obj)
143 signal_simple_error ("Attempt to modify read-only object (lisp)", obj);
147 args_out_of_range (Lisp_Object a1, Lisp_Object a2)
149 signal_error (Qargs_out_of_range, list2 (a1, a2));
153 args_out_of_range_3 (Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
155 signal_error (Qargs_out_of_range, list3 (a1, a2, a3));
159 check_int_range (EMACS_INT val, EMACS_INT min, EMACS_INT max)
161 if (val < min || val > max)
162 args_out_of_range_3 (make_int (val), make_int (min), make_int (max));
165 /* On some machines, XINT needs a temporary location.
166 Here it is, in case it is needed. */
168 EMACS_INT sign_extend_temp;
170 /* On a few machines, XINT can only be done by calling this. */
171 /* XEmacs: only used by m/convex.h */
172 EMACS_INT sign_extend_lisp_int (EMACS_INT num);
174 sign_extend_lisp_int (EMACS_INT num)
176 if (num & (1L << (INT_VALBITS - 1)))
177 return num | ((-1L) << INT_VALBITS);
179 return num & (EMACS_INT) ((1UL << INT_VALBITS) - 1);
183 /* Data type predicates */
185 DEFUN ("eq", Feq, 2, 2, 0, /*
186 Return t if the two args are the same Lisp object.
190 return EQ_WITH_EBOLA_NOTICE (object1, object2) ? Qt : Qnil;
193 DEFUN ("old-eq", Fold_eq, 2, 2, 0, /*
194 Return t if the two args are (in most cases) the same Lisp object.
196 Special kludge: A character is considered `old-eq' to its equivalent integer
197 even though they are not the same object and are in fact of different
198 types. This is ABSOLUTELY AND UTTERLY HORRENDOUS but is necessary to
199 preserve byte-code compatibility with v19. This kludge is known as the
200 \"char-int confoundance disease\" and appears in a number of other
201 functions with `old-foo' equivalents.
203 Do not use this function!
208 return HACKEQ_UNSAFE (object1, object2) ? Qt : Qnil;
211 DEFUN ("null", Fnull, 1, 1, 0, /*
212 Return t if OBJECT is nil.
216 return NILP (object) ? Qt : Qnil;
219 DEFUN ("consp", Fconsp, 1, 1, 0, /*
220 Return t if OBJECT is a cons cell. `nil' is not a cons cell.
224 return CONSP (object) ? Qt : Qnil;
227 DEFUN ("atom", Fatom, 1, 1, 0, /*
228 Return t if OBJECT is not a cons cell. `nil' is not a cons cell.
232 return CONSP (object) ? Qnil : Qt;
235 DEFUN ("listp", Flistp, 1, 1, 0, /*
236 Return t if OBJECT is a list. `nil' is a list.
240 return LISTP (object) ? Qt : Qnil;
243 DEFUN ("nlistp", Fnlistp, 1, 1, 0, /*
244 Return t if OBJECT is not a list. `nil' is a list.
248 return LISTP (object) ? Qnil : Qt;
251 DEFUN ("true-list-p", Ftrue_list_p, 1, 1, 0, /*
252 Return t if OBJECT is an acyclic, nil-terminated (ie, not dotted), list.
256 return TRUE_LIST_P (object) ? Qt : Qnil;
259 DEFUN ("symbolp", Fsymbolp, 1, 1, 0, /*
260 Return t if OBJECT is a symbol.
264 return SYMBOLP (object) ? Qt : Qnil;
267 DEFUN ("keywordp", Fkeywordp, 1, 1, 0, /*
268 Return t if OBJECT is a keyword.
272 return KEYWORDP (object) ? Qt : Qnil;
275 DEFUN ("vectorp", Fvectorp, 1, 1, 0, /*
276 Return t if OBJECT is a vector.
280 return VECTORP (object) ? Qt : Qnil;
283 DEFUN ("bit-vector-p", Fbit_vector_p, 1, 1, 0, /*
284 Return t if OBJECT is a bit vector.
288 return BIT_VECTORP (object) ? Qt : Qnil;
291 DEFUN ("stringp", Fstringp, 1, 1, 0, /*
292 Return t if OBJECT is a string.
296 return STRINGP (object) ? Qt : Qnil;
299 DEFUN ("arrayp", Farrayp, 1, 1, 0, /*
300 Return t if OBJECT is an array (string, vector, or bit vector).
304 return (VECTORP (object) ||
306 BIT_VECTORP (object))
310 DEFUN ("sequencep", Fsequencep, 1, 1, 0, /*
311 Return t if OBJECT is a sequence (list or array).
315 return (LISTP (object) ||
318 BIT_VECTORP (object))
322 DEFUN ("markerp", Fmarkerp, 1, 1, 0, /*
323 Return t if OBJECT is a marker (editor pointer).
327 return MARKERP (object) ? Qt : Qnil;
330 DEFUN ("subrp", Fsubrp, 1, 1, 0, /*
331 Return t if OBJECT is a built-in function.
335 return SUBRP (object) ? Qt : Qnil;
338 DEFUN ("subr-min-args", Fsubr_min_args, 1, 1, 0, /*
339 Return minimum number of args built-in function SUBR may be called with.
344 return make_int (XSUBR (subr)->min_args);
347 DEFUN ("subr-max-args", Fsubr_max_args, 1, 1, 0, /*
348 Return maximum number of args built-in function SUBR may be called with,
349 or nil if it takes an arbitrary number of arguments or is a special form.
355 nargs = XSUBR (subr)->max_args;
356 if (nargs == MANY || nargs == UNEVALLED)
359 return make_int (nargs);
362 DEFUN ("subr-interactive", Fsubr_interactive, 1, 1, 0, /*
363 Return the interactive spec of the subr object SUBR, or nil.
364 If non-nil, the return value will be a list whose first element is
365 `interactive' and whose second element is the interactive spec.
371 prompt = XSUBR (subr)->prompt;
372 return prompt ? list2 (Qinteractive, build_string (prompt)) : Qnil;
376 DEFUN ("characterp", Fcharacterp, 1, 1, 0, /*
377 Return t if OBJECT is a character.
378 Unlike in XEmacs v19 and FSF Emacs, a character is its own primitive type.
379 Any character can be converted into an equivalent integer using
380 `char-int'. To convert the other way, use `int-char'; however,
381 only some integers can be converted into characters. Such an integer
382 is called a `char-int'; see `char-int-p'.
384 Some functions that work on integers (e.g. the comparison functions
385 <, <=, =, /=, etc. and the arithmetic functions +, -, *, etc.)
386 accept characters and implicitly convert them into integers. In
387 general, functions that work on characters also accept char-ints and
388 implicitly convert them into characters. WARNING: Neither of these
389 behaviors is very desirable, and they are maintained for backward
390 compatibility with old E-Lisp programs that confounded characters and
391 integers willy-nilly. These behaviors may change in the future; therefore,
392 do not rely on them. Instead, use the character-specific functions such
397 return CHARP (object) ? Qt : Qnil;
400 DEFUN ("char-to-int", Fchar_to_int, 1, 1, 0, /*
401 Convert CHARACTER into an equivalent integer.
402 The resulting integer will always be non-negative. The integers in
403 the range 0 - 255 map to characters as follows:
407 128 - 159 Control set 1
408 160 - 255 Right half of ISO-8859-1
410 If support for Mule does not exist, these are the only valid character
411 values. When Mule support exists, the values assigned to other characters
412 may vary depending on the particular version of XEmacs, the order in which
413 character sets were loaded, etc., and you should not depend on them.
417 CHECK_CHAR (character);
418 return make_int (XCHAR (character));
421 DEFUN ("int-to-char", Fint_to_char, 1, 1, 0, /*
422 Convert integer INTEGER into the equivalent character.
423 Not all integers correspond to valid characters; use `char-int-p' to
424 determine whether this is the case. If the integer cannot be converted,
430 if (CHAR_INTP (integer))
431 return make_char (XINT (integer));
436 DEFUN ("char-int-p", Fchar_int_p, 1, 1, 0, /*
437 Return t if OBJECT is an integer that can be converted into a character.
442 return CHAR_INTP (object) ? Qt : Qnil;
445 DEFUN ("char-or-char-int-p", Fchar_or_char_int_p, 1, 1, 0, /*
446 Return t if OBJECT is a character or an integer that can be converted into one.
450 return CHAR_OR_CHAR_INTP (object) ? Qt : Qnil;
453 DEFUN ("char-or-string-p", Fchar_or_string_p, 1, 1, 0, /*
454 Return t if OBJECT is a character (or a char-int) or a string.
455 It is semi-hateful that we allow a char-int here, as it goes against
456 the name of this function, but it makes the most sense considering the
457 other steps we take to maintain compatibility with the old character/integer
458 confoundedness in older versions of E-Lisp.
462 return CHAR_OR_CHAR_INTP (object) || STRINGP (object) ? Qt : Qnil;
465 DEFUN ("char-ref-p", Fchar_ref_p, 1, 1, 0, /*
466 Return t if OBJECT is a character-reference.
470 return CONSP (object) && KEYWORDP (XCAR (object)) ? Qt : Qnil;
473 DEFUN ("integerp", Fintegerp, 1, 1, 0, /*
474 Return t if OBJECT is an integer.
478 return INTP (object) ? Qt : Qnil;
481 DEFUN ("integer-or-marker-p", Finteger_or_marker_p, 1, 1, 0, /*
482 Return t if OBJECT is an integer or a marker (editor pointer).
486 return INTP (object) || MARKERP (object) ? Qt : Qnil;
489 DEFUN ("integer-or-char-p", Finteger_or_char_p, 1, 1, 0, /*
490 Return t if OBJECT is an integer or a character.
494 return INTP (object) || CHARP (object) ? Qt : Qnil;
497 DEFUN ("integer-char-or-marker-p", Finteger_char_or_marker_p, 1, 1, 0, /*
498 Return t if OBJECT is an integer, character or a marker (editor pointer).
502 return INTP (object) || CHARP (object) || MARKERP (object) ? Qt : Qnil;
505 DEFUN ("natnump", Fnatnump, 1, 1, 0, /*
506 Return t if OBJECT is a nonnegative integer.
510 return NATNUMP (object) ? Qt : Qnil;
513 DEFUN ("bitp", Fbitp, 1, 1, 0, /*
514 Return t if OBJECT is a bit (0 or 1).
518 return BITP (object) ? Qt : Qnil;
521 DEFUN ("numberp", Fnumberp, 1, 1, 0, /*
522 Return t if OBJECT is a number (floating point or integer).
526 return INT_OR_FLOATP (object) ? Qt : Qnil;
529 DEFUN ("number-or-marker-p", Fnumber_or_marker_p, 1, 1, 0, /*
530 Return t if OBJECT is a number or a marker.
534 return INT_OR_FLOATP (object) || MARKERP (object) ? Qt : Qnil;
537 DEFUN ("number-char-or-marker-p", Fnumber_char_or_marker_p, 1, 1, 0, /*
538 Return t if OBJECT is a number, character or a marker.
542 return (INT_OR_FLOATP (object) ||
548 #ifdef LISP_FLOAT_TYPE
549 DEFUN ("floatp", Ffloatp, 1, 1, 0, /*
550 Return t if OBJECT is a floating point number.
554 return FLOATP (object) ? Qt : Qnil;
556 #endif /* LISP_FLOAT_TYPE */
558 DEFUN ("type-of", Ftype_of, 1, 1, 0, /*
559 Return a symbol representing the type of OBJECT.
563 switch (XTYPE (object))
565 case Lisp_Type_Record:
566 return intern (XRECORD_LHEADER_IMPLEMENTATION (object)->name);
568 case Lisp_Type_Char: return Qcharacter;
570 default: return Qinteger;
575 /* Extract and set components of lists */
577 DEFUN ("car", Fcar, 1, 1, 0, /*
578 Return the car of LIST. If arg is nil, return nil.
579 Error if arg is not nil and not a cons cell. See also `car-safe'.
587 else if (NILP (list))
590 list = wrong_type_argument (Qlistp, list);
594 DEFUN ("car-safe", Fcar_safe, 1, 1, 0, /*
595 Return the car of OBJECT if it is a cons cell, or else nil.
599 return CONSP (object) ? XCAR (object) : Qnil;
602 DEFUN ("cdr", Fcdr, 1, 1, 0, /*
603 Return the cdr of LIST. If arg is nil, return nil.
604 Error if arg is not nil and not a cons cell. See also `cdr-safe'.
612 else if (NILP (list))
615 list = wrong_type_argument (Qlistp, list);
619 DEFUN ("cdr-safe", Fcdr_safe, 1, 1, 0, /*
620 Return the cdr of OBJECT if it is a cons cell, else nil.
624 return CONSP (object) ? XCDR (object) : Qnil;
627 DEFUN ("setcar", Fsetcar, 2, 2, 0, /*
628 Set the car of CONS-CELL to be NEWCAR. Return NEWCAR.
632 if (!CONSP (cons_cell))
633 cons_cell = wrong_type_argument (Qconsp, cons_cell);
635 XCAR (cons_cell) = newcar;
639 DEFUN ("setcdr", Fsetcdr, 2, 2, 0, /*
640 Set the cdr of CONS-CELL to be NEWCDR. Return NEWCDR.
644 if (!CONSP (cons_cell))
645 cons_cell = wrong_type_argument (Qconsp, cons_cell);
647 XCDR (cons_cell) = newcdr;
651 /* Find the function at the end of a chain of symbol function indirections.
653 If OBJECT is a symbol, find the end of its function chain and
654 return the value found there. If OBJECT is not a symbol, just
655 return it. If there is a cycle in the function chain, signal a
656 cyclic-function-indirection error.
658 This is like Findirect_function when VOID_FUNCTION_ERRORP is true.
659 When VOID_FUNCTION_ERRORP is false, no error is signaled if the end
660 of the chain ends up being Qunbound. */
662 indirect_function (Lisp_Object object, int void_function_errorp)
664 #define FUNCTION_INDIRECTION_SUSPICION_LENGTH 16
665 Lisp_Object tortoise, hare;
668 for (hare = tortoise = object, count = 0;
670 hare = XSYMBOL (hare)->function, count++)
672 if (count < FUNCTION_INDIRECTION_SUSPICION_LENGTH) continue;
675 tortoise = XSYMBOL (tortoise)->function;
676 if (EQ (hare, tortoise))
677 return Fsignal (Qcyclic_function_indirection, list1 (object));
680 if (void_function_errorp && UNBOUNDP (hare))
681 return signal_void_function_error (object);
686 DEFUN ("indirect-function", Findirect_function, 1, 1, 0, /*
687 Return the function at the end of OBJECT's function chain.
688 If OBJECT is a symbol, follow all function indirections and return
689 the final function binding.
690 If OBJECT is not a symbol, just return it.
691 Signal a void-function error if the final symbol is unbound.
692 Signal a cyclic-function-indirection error if there is a loop in the
693 function chain of symbols.
697 return indirect_function (object, 1);
700 /* Extract and set vector and string elements */
702 DEFUN ("aref", Faref, 2, 2, 0, /*
703 Return the element of ARRAY at index INDEX.
704 ARRAY may be a vector, bit vector, or string. INDEX starts at 0.
712 if (INTP (index_)) idx = XINT (index_);
713 else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
716 index_ = wrong_type_argument (Qinteger_or_char_p, index_);
720 if (idx < 0) goto range_error;
724 if (idx >= XVECTOR_LENGTH (array)) goto range_error;
725 return XVECTOR_DATA (array)[idx];
727 else if (BIT_VECTORP (array))
729 if (idx >= bit_vector_length (XBIT_VECTOR (array))) goto range_error;
730 return make_int (bit_vector_bit (XBIT_VECTOR (array), idx));
732 else if (STRINGP (array))
734 if (idx >= XSTRING_CHAR_LENGTH (array)) goto range_error;
735 return make_char (string_char (XSTRING (array), idx));
737 #ifdef LOSING_BYTECODE
738 else if (COMPILED_FUNCTIONP (array))
740 /* Weird, gross compatibility kludge */
741 return Felt (array, index_);
746 check_losing_bytecode ("aref", array);
747 array = wrong_type_argument (Qarrayp, array);
752 args_out_of_range (array, index_);
753 return Qnil; /* not reached */
756 DEFUN ("aset", Faset, 3, 3, 0, /*
757 Store into the element of ARRAY at index INDEX the value NEWVAL.
758 ARRAY may be a vector, bit vector, or string. INDEX starts at 0.
760 (array, index_, newval))
766 if (INTP (index_)) idx = XINT (index_);
767 else if (CHARP (index_)) idx = XCHAR (index_); /* yuck! */
770 index_ = wrong_type_argument (Qinteger_or_char_p, index_);
774 if (idx < 0) goto range_error;
778 if (idx >= XVECTOR_LENGTH (array)) goto range_error;
779 XVECTOR_DATA (array)[idx] = newval;
781 else if (BIT_VECTORP (array))
783 if (idx >= bit_vector_length (XBIT_VECTOR (array))) goto range_error;
785 set_bit_vector_bit (XBIT_VECTOR (array), idx, !ZEROP (newval));
787 else if (STRINGP (array))
789 CHECK_CHAR_COERCE_INT (newval);
790 if (idx >= XSTRING_CHAR_LENGTH (array)) goto range_error;
791 set_string_char (XSTRING (array), idx, XCHAR (newval));
792 bump_string_modiff (array);
796 array = wrong_type_argument (Qarrayp, array);
803 args_out_of_range (array, index_);
804 return Qnil; /* not reached */
808 /**********************************************************************/
809 /* Arithmetic functions */
810 /**********************************************************************/
822 number_char_or_marker_to_int_or_double (Lisp_Object obj, int_or_double *p)
826 if (INTP (obj)) p->c.ival = XINT (obj);
827 else if (CHARP (obj)) p->c.ival = XCHAR (obj);
828 else if (MARKERP (obj)) p->c.ival = marker_position (obj);
829 #ifdef LISP_FLOAT_TYPE
830 else if (FLOATP (obj)) p->c.dval = XFLOAT_DATA (obj), p->int_p = 0;
834 obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
840 number_char_or_marker_to_double (Lisp_Object obj)
843 if (INTP (obj)) return (double) XINT (obj);
844 else if (CHARP (obj)) return (double) XCHAR (obj);
845 else if (MARKERP (obj)) return (double) marker_position (obj);
846 #ifdef LISP_FLOAT_TYPE
847 else if (FLOATP (obj)) return XFLOAT_DATA (obj);
851 obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
857 integer_char_or_marker_to_int (Lisp_Object obj)
860 if (INTP (obj)) return XINT (obj);
861 else if (CHARP (obj)) return XCHAR (obj);
862 else if (MARKERP (obj)) return marker_position (obj);
865 obj = wrong_type_argument (Qinteger_char_or_marker_p, obj);
870 #define ARITHCOMPARE_MANY(op) \
872 int_or_double iod1, iod2, *p = &iod1, *q = &iod2; \
873 Lisp_Object *args_end = args + nargs; \
875 number_char_or_marker_to_int_or_double (*args++, p); \
877 while (args < args_end) \
879 number_char_or_marker_to_int_or_double (*args++, q); \
881 if (!((p->int_p && q->int_p) ? \
882 (p->c.ival op q->c.ival) : \
883 ((p->int_p ? (double) p->c.ival : p->c.dval) op \
884 (q->int_p ? (double) q->c.ival : q->c.dval)))) \
887 { /* swap */ int_or_double *r = p; p = q; q = r; } \
892 DEFUN ("=", Feqlsign, 1, MANY, 0, /*
893 Return t if all the arguments are numerically equal.
894 The arguments may be numbers, characters or markers.
896 (int nargs, Lisp_Object *args))
898 ARITHCOMPARE_MANY (==)
901 DEFUN ("<", Flss, 1, MANY, 0, /*
902 Return t if the sequence of arguments is monotonically increasing.
903 The arguments may be numbers, characters or markers.
905 (int nargs, Lisp_Object *args))
907 ARITHCOMPARE_MANY (<)
910 DEFUN (">", Fgtr, 1, MANY, 0, /*
911 Return t if the sequence of arguments is monotonically decreasing.
912 The arguments may be numbers, characters or markers.
914 (int nargs, Lisp_Object *args))
916 ARITHCOMPARE_MANY (>)
919 DEFUN ("<=", Fleq, 1, MANY, 0, /*
920 Return t if the sequence of arguments is monotonically nondecreasing.
921 The arguments may be numbers, characters or markers.
923 (int nargs, Lisp_Object *args))
925 ARITHCOMPARE_MANY (<=)
928 DEFUN (">=", Fgeq, 1, MANY, 0, /*
929 Return t if the sequence of arguments is monotonically nonincreasing.
930 The arguments may be numbers, characters or markers.
932 (int nargs, Lisp_Object *args))
934 ARITHCOMPARE_MANY (>=)
937 DEFUN ("/=", Fneq, 1, MANY, 0, /*
938 Return t if no two arguments are numerically equal.
939 The arguments may be numbers, characters or markers.
941 (int nargs, Lisp_Object *args))
943 Lisp_Object *args_end = args + nargs;
946 /* Unlike all the other comparisons, this is an N*N algorithm.
947 We could use a hash table for nargs > 50 to make this linear. */
948 for (p = args; p < args_end; p++)
950 int_or_double iod1, iod2;
951 number_char_or_marker_to_int_or_double (*p, &iod1);
953 for (q = p + 1; q < args_end; q++)
955 number_char_or_marker_to_int_or_double (*q, &iod2);
957 if (!((iod1.int_p && iod2.int_p) ?
958 (iod1.c.ival != iod2.c.ival) :
959 ((iod1.int_p ? (double) iod1.c.ival : iod1.c.dval) !=
960 (iod2.int_p ? (double) iod2.c.ival : iod2.c.dval))))
967 DEFUN ("zerop", Fzerop, 1, 1, 0, /*
968 Return t if NUMBER is zero.
974 return EQ (number, Qzero) ? Qt : Qnil;
975 #ifdef LISP_FLOAT_TYPE
976 else if (FLOATP (number))
977 return XFLOAT_DATA (number) == 0.0 ? Qt : Qnil;
978 #endif /* LISP_FLOAT_TYPE */
981 number = wrong_type_argument (Qnumberp, number);
986 /* Convert between a 32-bit value and a cons of two 16-bit values.
987 This is used to pass 32-bit integers to and from the user.
988 Use time_to_lisp() and lisp_to_time() for time values.
990 If you're thinking of using this to store a pointer into a Lisp Object
991 for internal purposes (such as when calling record_unwind_protect()),
992 try using make_opaque_ptr()/get_opaque_ptr() instead. */
994 word_to_lisp (unsigned int item)
996 return Fcons (make_int (item >> 16), make_int (item & 0xffff));
1000 lisp_to_word (Lisp_Object item)
1006 Lisp_Object top = Fcar (item);
1007 Lisp_Object bot = Fcdr (item);
1010 return (XINT (top) << 16) | (XINT (bot) & 0xffff);
1015 DEFUN ("number-to-string", Fnumber_to_string, 1, 1, 0, /*
1016 Convert NUMBER to a string by printing it in decimal.
1017 Uses a minus sign if negative.
1018 NUMBER may be an integer or a floating point number.
1022 char buffer[VALBITS];
1024 CHECK_INT_OR_FLOAT (number);
1026 #ifdef LISP_FLOAT_TYPE
1027 if (FLOATP (number))
1029 char pigbuf[350]; /* see comments in float_to_string */
1031 float_to_string (pigbuf, XFLOAT_DATA (number));
1032 return build_string (pigbuf);
1034 #endif /* LISP_FLOAT_TYPE */
1036 long_to_string (buffer, XINT (number));
1037 return build_string (buffer);
1041 digit_to_number (int character, int base)
1044 int digit = ((character >= '0' && character <= '9') ? character - '0' :
1045 (character >= 'a' && character <= 'z') ? character - 'a' + 10 :
1046 (character >= 'A' && character <= 'Z') ? character - 'A' + 10 :
1049 return digit >= base ? -1 : digit;
1052 DEFUN ("string-to-number", Fstring_to_number, 1, 2, 0, /*
1053 Convert STRING to a number by parsing it as a number in base BASE.
1054 This parses both integers and floating point numbers.
1055 It ignores leading spaces and tabs.
1057 If BASE is nil or omitted, base 10 is used.
1058 BASE must be an integer between 2 and 16 (inclusive).
1059 Floating point numbers always use base 10.
1066 CHECK_STRING (string);
1074 check_int_range (b, 2, 16);
1077 p = (char *) XSTRING_DATA (string);
1079 /* Skip any whitespace at the front of the number. Some versions of
1080 atoi do this anyway, so we might as well make Emacs lisp consistent. */
1081 while (*p == ' ' || *p == '\t')
1084 #ifdef LISP_FLOAT_TYPE
1085 if (isfloat_string (p) && b == 10)
1086 return make_float (atof (p));
1087 #endif /* LISP_FLOAT_TYPE */
1091 /* Use the system-provided functions for base 10. */
1092 #if SIZEOF_EMACS_INT == SIZEOF_INT
1093 return make_int (atoi (p));
1094 #elif SIZEOF_EMACS_INT == SIZEOF_LONG
1095 return make_int (atol (p));
1096 #elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
1097 return make_int (atoll (p));
1114 int digit = digit_to_number (*p++, b);
1119 return make_int (negative * v);
1124 DEFUN ("+", Fplus, 0, MANY, 0, /*
1125 Return sum of any number of arguments.
1126 The arguments should all be numbers, characters or markers.
1128 (int nargs, Lisp_Object *args))
1130 EMACS_INT iaccum = 0;
1131 Lisp_Object *args_end = args + nargs;
1133 while (args < args_end)
1136 number_char_or_marker_to_int_or_double (*args++, &iod);
1138 iaccum += iod.c.ival;
1141 double daccum = (double) iaccum + iod.c.dval;
1142 while (args < args_end)
1143 daccum += number_char_or_marker_to_double (*args++);
1144 return make_float (daccum);
1148 return make_int (iaccum);
1151 DEFUN ("-", Fminus, 1, MANY, 0, /*
1152 Negate number or subtract numbers, characters or markers.
1153 With one arg, negates it. With more than one arg,
1154 subtracts all but the first from the first.
1156 (int nargs, Lisp_Object *args))
1160 Lisp_Object *args_end = args + nargs;
1163 number_char_or_marker_to_int_or_double (*args++, &iod);
1165 iaccum = nargs > 1 ? iod.c.ival : - iod.c.ival;
1168 daccum = nargs > 1 ? iod.c.dval : - iod.c.dval;
1172 while (args < args_end)
1174 number_char_or_marker_to_int_or_double (*args++, &iod);
1176 iaccum -= iod.c.ival;
1179 daccum = (double) iaccum - iod.c.dval;
1184 return make_int (iaccum);
1187 for (; args < args_end; args++)
1188 daccum -= number_char_or_marker_to_double (*args);
1189 return make_float (daccum);
1192 DEFUN ("*", Ftimes, 0, MANY, 0, /*
1193 Return product of any number of arguments.
1194 The arguments should all be numbers, characters or markers.
1196 (int nargs, Lisp_Object *args))
1198 EMACS_INT iaccum = 1;
1199 Lisp_Object *args_end = args + nargs;
1201 while (args < args_end)
1204 number_char_or_marker_to_int_or_double (*args++, &iod);
1206 iaccum *= iod.c.ival;
1209 double daccum = (double) iaccum * iod.c.dval;
1210 while (args < args_end)
1211 daccum *= number_char_or_marker_to_double (*args++);
1212 return make_float (daccum);
1216 return make_int (iaccum);
1219 DEFUN ("/", Fquo, 1, MANY, 0, /*
1220 Return first argument divided by all the remaining arguments.
1221 The arguments must be numbers, characters or markers.
1222 With one argument, reciprocates the argument.
1224 (int nargs, Lisp_Object *args))
1228 Lisp_Object *args_end = args + nargs;
1235 number_char_or_marker_to_int_or_double (*args++, &iod);
1237 iaccum = iod.c.ival;
1240 daccum = iod.c.dval;
1245 while (args < args_end)
1247 number_char_or_marker_to_int_or_double (*args++, &iod);
1250 if (iod.c.ival == 0) goto divide_by_zero;
1251 iaccum /= iod.c.ival;
1255 if (iod.c.dval == 0) goto divide_by_zero;
1256 daccum = (double) iaccum / iod.c.dval;
1261 return make_int (iaccum);
1264 for (; args < args_end; args++)
1266 double dval = number_char_or_marker_to_double (*args);
1267 if (dval == 0) goto divide_by_zero;
1270 return make_float (daccum);
1273 Fsignal (Qarith_error, Qnil);
1274 return Qnil; /* not reached */
1277 DEFUN ("max", Fmax, 1, MANY, 0, /*
1278 Return largest of all the arguments.
1279 All arguments must be numbers, characters or markers.
1280 The value is always a number; markers and characters are converted
1283 (int nargs, Lisp_Object *args))
1287 Lisp_Object *args_end = args + nargs;
1290 number_char_or_marker_to_int_or_double (*args++, &iod);
1299 while (args < args_end)
1301 number_char_or_marker_to_int_or_double (*args++, &iod);
1304 if (imax < iod.c.ival) imax = iod.c.ival;
1308 dmax = (double) imax;
1309 if (dmax < iod.c.dval) dmax = iod.c.dval;
1314 return make_int (imax);
1317 while (args < args_end)
1319 double dval = number_char_or_marker_to_double (*args++);
1320 if (dmax < dval) dmax = dval;
1322 return make_float (dmax);
1325 DEFUN ("min", Fmin, 1, MANY, 0, /*
1326 Return smallest of all the arguments.
1327 All arguments must be numbers, characters or markers.
1328 The value is always a number; markers and characters are converted
1331 (int nargs, Lisp_Object *args))
1335 Lisp_Object *args_end = args + nargs;
1338 number_char_or_marker_to_int_or_double (*args++, &iod);
1347 while (args < args_end)
1349 number_char_or_marker_to_int_or_double (*args++, &iod);
1352 if (imin > iod.c.ival) imin = iod.c.ival;
1356 dmin = (double) imin;
1357 if (dmin > iod.c.dval) dmin = iod.c.dval;
1362 return make_int (imin);
1365 while (args < args_end)
1367 double dval = number_char_or_marker_to_double (*args++);
1368 if (dmin > dval) dmin = dval;
1370 return make_float (dmin);
1373 DEFUN ("logand", Flogand, 0, MANY, 0, /*
1374 Return bitwise-and of all the arguments.
1375 Arguments may be integers, or markers or characters converted to integers.
1377 (int nargs, Lisp_Object *args))
1379 EMACS_INT bits = ~0;
1380 Lisp_Object *args_end = args + nargs;
1382 while (args < args_end)
1383 bits &= integer_char_or_marker_to_int (*args++);
1385 return make_int (bits);
1388 DEFUN ("logior", Flogior, 0, MANY, 0, /*
1389 Return bitwise-or of all the arguments.
1390 Arguments may be integers, or markers or characters converted to integers.
1392 (int nargs, Lisp_Object *args))
1395 Lisp_Object *args_end = args + nargs;
1397 while (args < args_end)
1398 bits |= integer_char_or_marker_to_int (*args++);
1400 return make_int (bits);
1403 DEFUN ("logxor", Flogxor, 0, MANY, 0, /*
1404 Return bitwise-exclusive-or of all the arguments.
1405 Arguments may be integers, or markers or characters converted to integers.
1407 (int nargs, Lisp_Object *args))
1410 Lisp_Object *args_end = args + nargs;
1412 while (args < args_end)
1413 bits ^= integer_char_or_marker_to_int (*args++);
1415 return make_int (bits);
1418 DEFUN ("lognot", Flognot, 1, 1, 0, /*
1419 Return the bitwise complement of NUMBER.
1420 NUMBER may be an integer, marker or character converted to integer.
1424 return make_int (~ integer_char_or_marker_to_int (number));
1427 DEFUN ("%", Frem, 2, 2, 0, /*
1428 Return remainder of first arg divided by second.
1429 Both must be integers, characters or markers.
1433 EMACS_INT ival1 = integer_char_or_marker_to_int (number1);
1434 EMACS_INT ival2 = integer_char_or_marker_to_int (number2);
1437 Fsignal (Qarith_error, Qnil);
1439 return make_int (ival1 % ival2);
1442 /* Note, ANSI *requires* the presence of the fmod() library routine.
1443 If your system doesn't have it, complain to your vendor, because
1448 fmod (double f1, double f2)
1452 return f1 - f2 * floor (f1/f2);
1454 #endif /* ! HAVE_FMOD */
1457 DEFUN ("mod", Fmod, 2, 2, 0, /*
1459 The result falls between zero (inclusive) and Y (exclusive).
1460 Both X and Y must be numbers, characters or markers.
1461 If either argument is a float, a float will be returned.
1465 int_or_double iod1, iod2;
1466 number_char_or_marker_to_int_or_double (x, &iod1);
1467 number_char_or_marker_to_int_or_double (y, &iod2);
1469 #ifdef LISP_FLOAT_TYPE
1470 if (!iod1.int_p || !iod2.int_p)
1472 double dval1 = iod1.int_p ? (double) iod1.c.ival : iod1.c.dval;
1473 double dval2 = iod2.int_p ? (double) iod2.c.ival : iod2.c.dval;
1474 if (dval2 == 0) goto divide_by_zero;
1475 dval1 = fmod (dval1, dval2);
1477 /* If the "remainder" comes out with the wrong sign, fix it. */
1478 if (dval2 < 0 ? dval1 > 0 : dval1 < 0)
1481 return make_float (dval1);
1483 #endif /* LISP_FLOAT_TYPE */
1486 if (iod2.c.ival == 0) goto divide_by_zero;
1488 ival = iod1.c.ival % iod2.c.ival;
1490 /* If the "remainder" comes out with the wrong sign, fix it. */
1491 if (iod2.c.ival < 0 ? ival > 0 : ival < 0)
1492 ival += iod2.c.ival;
1494 return make_int (ival);
1498 Fsignal (Qarith_error, Qnil);
1499 return Qnil; /* not reached */
1502 DEFUN ("ash", Fash, 2, 2, 0, /*
1503 Return VALUE with its bits shifted left by COUNT.
1504 If COUNT is negative, shifting is actually to the right.
1505 In this case, the sign bit is duplicated.
1509 CHECK_INT_COERCE_CHAR (value);
1510 CONCHECK_INT (count);
1512 return make_int (XINT (count) > 0 ?
1513 XINT (value) << XINT (count) :
1514 XINT (value) >> -XINT (count));
1517 DEFUN ("lsh", Flsh, 2, 2, 0, /*
1518 Return VALUE with its bits shifted left by COUNT.
1519 If COUNT is negative, shifting is actually to the right.
1520 In this case, zeros are shifted in on the left.
1524 CHECK_INT_COERCE_CHAR (value);
1525 CONCHECK_INT (count);
1527 return make_int (XINT (count) > 0 ?
1528 XUINT (value) << XINT (count) :
1529 XUINT (value) >> -XINT (count));
1532 DEFUN ("1+", Fadd1, 1, 1, 0, /*
1533 Return NUMBER plus one. NUMBER may be a number, character or marker.
1534 Markers and characters are converted to integers.
1540 if (INTP (number)) return make_int (XINT (number) + 1);
1541 if (CHARP (number)) return make_int (XCHAR (number) + 1);
1542 if (MARKERP (number)) return make_int (marker_position (number) + 1);
1543 #ifdef LISP_FLOAT_TYPE
1544 if (FLOATP (number)) return make_float (XFLOAT_DATA (number) + 1.0);
1545 #endif /* LISP_FLOAT_TYPE */
1547 number = wrong_type_argument (Qnumber_char_or_marker_p, number);
1551 DEFUN ("1-", Fsub1, 1, 1, 0, /*
1552 Return NUMBER minus one. NUMBER may be a number, character or marker.
1553 Markers and characters are converted to integers.
1559 if (INTP (number)) return make_int (XINT (number) - 1);
1560 if (CHARP (number)) return make_int (XCHAR (number) - 1);
1561 if (MARKERP (number)) return make_int (marker_position (number) - 1);
1562 #ifdef LISP_FLOAT_TYPE
1563 if (FLOATP (number)) return make_float (XFLOAT_DATA (number) - 1.0);
1564 #endif /* LISP_FLOAT_TYPE */
1566 number = wrong_type_argument (Qnumber_char_or_marker_p, number);
1571 /************************************************************************/
1573 /************************************************************************/
1575 /* A weak list is like a normal list except that elements automatically
1576 disappear when no longer in use, i.e. when no longer GC-protected.
1577 The basic idea is that we don't mark the elements during GC, but
1578 wait for them to be marked elsewhere. If they're not marked, we
1579 remove them. This is analogous to weak hash tables; see the explanation
1580 there for more info. */
1582 static Lisp_Object Vall_weak_lists; /* Gemarke es nicht!!! */
1584 static Lisp_Object encode_weak_list_type (enum weak_list_type type);
1587 mark_weak_list (Lisp_Object obj)
1589 return Qnil; /* nichts ist gemarkt */
1593 print_weak_list (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
1596 error ("printing unreadable object #<weak-list>");
1598 write_c_string ("#<weak-list ", printcharfun);
1599 print_internal (encode_weak_list_type (XWEAK_LIST (obj)->type),
1601 write_c_string (" ", printcharfun);
1602 print_internal (XWEAK_LIST (obj)->list, printcharfun, escapeflag);
1603 write_c_string (">", printcharfun);
1607 weak_list_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
1609 struct weak_list *w1 = XWEAK_LIST (obj1);
1610 struct weak_list *w2 = XWEAK_LIST (obj2);
1612 return ((w1->type == w2->type) &&
1613 internal_equal (w1->list, w2->list, depth + 1));
1616 static unsigned long
1617 weak_list_hash (Lisp_Object obj, int depth)
1619 struct weak_list *w = XWEAK_LIST (obj);
1621 return HASH2 ((unsigned long) w->type,
1622 internal_hash (w->list, depth + 1));
1626 make_weak_list (enum weak_list_type type)
1629 struct weak_list *wl =
1630 alloc_lcrecord_type (struct weak_list, &lrecord_weak_list);
1634 XSETWEAK_LIST (result, wl);
1635 wl->next_weak = Vall_weak_lists;
1636 Vall_weak_lists = result;
1640 static const struct lrecord_description weak_list_description[] = {
1641 { XD_LISP_OBJECT, offsetof (struct weak_list, list) },
1642 { XD_LO_LINK, offsetof (struct weak_list, next_weak) },
1646 DEFINE_LRECORD_IMPLEMENTATION ("weak-list", weak_list,
1647 mark_weak_list, print_weak_list,
1648 0, weak_list_equal, weak_list_hash,
1649 weak_list_description,
1652 -- we do not mark the list elements (either the elements themselves
1653 or the cons cells that hold them) in the normal marking phase.
1654 -- at the end of marking, we go through all weak lists that are
1655 marked, and mark the cons cells that hold all marked
1656 objects, and possibly parts of the objects themselves.
1657 (See alloc.c, "after-mark".)
1658 -- after that, we prune away all the cons cells that are not marked.
1660 WARNING WARNING WARNING WARNING WARNING:
1662 The code in the following two functions is *unbelievably* tricky.
1663 Don't mess with it. You'll be sorry.
1665 Linked lists just majorly suck, d'ya know?
1669 finish_marking_weak_lists (void)
1674 for (rest = Vall_weak_lists;
1676 rest = XWEAK_LIST (rest)->next_weak)
1679 enum weak_list_type type = XWEAK_LIST (rest)->type;
1681 if (! marked_p (rest))
1682 /* The weak list is probably garbage. Ignore it. */
1685 for (rest2 = XWEAK_LIST (rest)->list;
1686 /* We need to be trickier since we're inside of GC;
1687 use CONSP instead of !NILP in case of user-visible
1690 rest2 = XCDR (rest2))
1693 /* If the element is "marked" (meaning depends on the type
1694 of weak list), we need to mark the cons containing the
1695 element, and maybe the element itself (if only some part
1696 was already marked). */
1697 int need_to_mark_cons = 0;
1698 int need_to_mark_elem = 0;
1700 /* If a cons is already marked, then its car is already marked
1701 (either because of an external pointer or because of
1702 a previous call to this function), and likewise for all
1703 the rest of the elements in the list, so we can stop now. */
1704 if (marked_p (rest2))
1707 elem = XCAR (rest2);
1711 case WEAK_LIST_SIMPLE:
1712 if (marked_p (elem))
1713 need_to_mark_cons = 1;
1716 case WEAK_LIST_ASSOC:
1719 /* just leave bogus elements there */
1720 need_to_mark_cons = 1;
1721 need_to_mark_elem = 1;
1723 else if (marked_p (XCAR (elem)) &&
1724 marked_p (XCDR (elem)))
1726 need_to_mark_cons = 1;
1727 /* We still need to mark elem, because it's
1728 probably not marked. */
1729 need_to_mark_elem = 1;
1733 case WEAK_LIST_KEY_ASSOC:
1736 /* just leave bogus elements there */
1737 need_to_mark_cons = 1;
1738 need_to_mark_elem = 1;
1740 else if (marked_p (XCAR (elem)))
1742 need_to_mark_cons = 1;
1743 /* We still need to mark elem and XCDR (elem);
1744 marking elem does both */
1745 need_to_mark_elem = 1;
1749 case WEAK_LIST_VALUE_ASSOC:
1752 /* just leave bogus elements there */
1753 need_to_mark_cons = 1;
1754 need_to_mark_elem = 1;
1756 else if (marked_p (XCDR (elem)))
1758 need_to_mark_cons = 1;
1759 /* We still need to mark elem and XCAR (elem);
1760 marking elem does both */
1761 need_to_mark_elem = 1;
1765 case WEAK_LIST_FULL_ASSOC:
1768 /* just leave bogus elements there */
1769 need_to_mark_cons = 1;
1770 need_to_mark_elem = 1;
1772 else if (marked_p (XCAR (elem)) ||
1773 marked_p (XCDR (elem)))
1775 need_to_mark_cons = 1;
1776 /* We still need to mark elem and XCAR (elem);
1777 marking elem does both */
1778 need_to_mark_elem = 1;
1786 if (need_to_mark_elem && ! marked_p (elem))
1792 /* We also need to mark the cons that holds the elem or
1793 assoc-pair. We do *not* want to call (mark_object) here
1794 because that will mark the entire list; we just want to
1795 mark the cons itself.
1797 if (need_to_mark_cons)
1799 Lisp_Cons *c = XCONS (rest2);
1800 if (!CONS_MARKED_P (c))
1808 /* In case of imperfect list, need to mark the final cons
1809 because we're not removing it */
1810 if (!NILP (rest2) && ! marked_p (rest2))
1812 mark_object (rest2);
1821 prune_weak_lists (void)
1823 Lisp_Object rest, prev = Qnil;
1825 for (rest = Vall_weak_lists;
1827 rest = XWEAK_LIST (rest)->next_weak)
1829 if (! (marked_p (rest)))
1831 /* This weak list itself is garbage. Remove it from the list. */
1833 Vall_weak_lists = XWEAK_LIST (rest)->next_weak;
1835 XWEAK_LIST (prev)->next_weak =
1836 XWEAK_LIST (rest)->next_weak;
1840 Lisp_Object rest2, prev2 = Qnil;
1841 Lisp_Object tortoise;
1842 int go_tortoise = 0;
1844 for (rest2 = XWEAK_LIST (rest)->list, tortoise = rest2;
1845 /* We need to be trickier since we're inside of GC;
1846 use CONSP instead of !NILP in case of user-visible
1850 /* It suffices to check the cons for marking,
1851 regardless of the type of weak list:
1853 -- if the cons is pointed to somewhere else,
1854 then it should stay around and will be marked.
1855 -- otherwise, if it should stay around, it will
1856 have been marked in finish_marking_weak_lists().
1857 -- otherwise, it's not marked and should disappear.
1859 if (! marked_p (rest2))
1863 XWEAK_LIST (rest)->list = XCDR (rest2);
1865 XCDR (prev2) = XCDR (rest2);
1866 rest2 = XCDR (rest2);
1867 /* Ouch. Circularity checking is even trickier
1868 than I thought. When we cut out a link
1869 like this, we can't advance the turtle or
1870 it'll catch up to us. Imagine that we're
1871 standing on floor tiles and moving forward --
1872 what we just did here is as if the floor
1873 tile under us just disappeared and all the
1874 ones ahead of us slid one tile towards us.
1875 In other words, we didn't move at all;
1876 if the tortoise was one step behind us
1877 previously, it still is, and therefore
1878 it must not move. */
1884 /* Implementing circularity checking is trickier here
1885 than in other places because we have to guarantee
1886 that we've processed all elements before exiting
1887 due to a circularity. (In most places, an error
1888 is issued upon encountering a circularity, so it
1889 doesn't really matter if all elements are processed.)
1890 The idea is that we process along with the hare
1891 rather than the tortoise. If at any point in
1892 our forward process we encounter the tortoise,
1893 we must have already visited the spot, so we exit.
1894 (If we process with the tortoise, we can fail to
1895 process cases where a cons points to itself, or
1896 where cons A points to cons B, which points to
1899 rest2 = XCDR (rest2);
1901 tortoise = XCDR (tortoise);
1902 go_tortoise = !go_tortoise;
1903 if (EQ (rest2, tortoise))
1913 static enum weak_list_type
1914 decode_weak_list_type (Lisp_Object symbol)
1916 CHECK_SYMBOL (symbol);
1917 if (EQ (symbol, Qsimple)) return WEAK_LIST_SIMPLE;
1918 if (EQ (symbol, Qassoc)) return WEAK_LIST_ASSOC;
1919 if (EQ (symbol, Qold_assoc)) return WEAK_LIST_ASSOC; /* EBOLA ALERT! */
1920 if (EQ (symbol, Qkey_assoc)) return WEAK_LIST_KEY_ASSOC;
1921 if (EQ (symbol, Qvalue_assoc)) return WEAK_LIST_VALUE_ASSOC;
1922 if (EQ (symbol, Qfull_assoc)) return WEAK_LIST_FULL_ASSOC;
1924 signal_simple_error ("Invalid weak list type", symbol);
1925 return WEAK_LIST_SIMPLE; /* not reached */
1929 encode_weak_list_type (enum weak_list_type type)
1933 case WEAK_LIST_SIMPLE: return Qsimple;
1934 case WEAK_LIST_ASSOC: return Qassoc;
1935 case WEAK_LIST_KEY_ASSOC: return Qkey_assoc;
1936 case WEAK_LIST_VALUE_ASSOC: return Qvalue_assoc;
1937 case WEAK_LIST_FULL_ASSOC: return Qfull_assoc;
1942 return Qnil; /* not reached */
1945 DEFUN ("weak-list-p", Fweak_list_p, 1, 1, 0, /*
1946 Return non-nil if OBJECT is a weak list.
1950 return WEAK_LISTP (object) ? Qt : Qnil;
1953 DEFUN ("make-weak-list", Fmake_weak_list, 0, 1, 0, /*
1954 Return a new weak list object of type TYPE.
1955 A weak list object is an object that contains a list. This list behaves
1956 like any other list except that its elements do not count towards
1957 garbage collection -- if the only pointer to an object is inside a weak
1958 list (other than pointers in similar objects such as weak hash tables),
1959 the object is garbage collected and automatically removed from the list.
1960 This is used internally, for example, to manage the list holding the
1961 children of an extent -- an extent that is unused but has a parent will
1962 still be reclaimed, and will automatically be removed from its parent's
1965 Optional argument TYPE specifies the type of the weak list, and defaults
1966 to `simple'. Recognized types are
1968 `simple' Objects in the list disappear if not pointed to.
1969 `assoc' Objects in the list disappear if they are conses
1970 and either the car or the cdr of the cons is not
1972 `key-assoc' Objects in the list disappear if they are conses
1973 and the car is not pointed to.
1974 `value-assoc' Objects in the list disappear if they are conses
1975 and the cdr is not pointed to.
1976 `full-assoc' Objects in the list disappear if they are conses
1977 and neither the car nor the cdr is pointed to.
1984 return make_weak_list (decode_weak_list_type (type));
1987 DEFUN ("weak-list-type", Fweak_list_type, 1, 1, 0, /*
1988 Return the type of the given weak-list object.
1992 CHECK_WEAK_LIST (weak);
1993 return encode_weak_list_type (XWEAK_LIST (weak)->type);
1996 DEFUN ("weak-list-list", Fweak_list_list, 1, 1, 0, /*
1997 Return the list contained in a weak-list object.
2001 CHECK_WEAK_LIST (weak);
2002 return XWEAK_LIST_LIST (weak);
2005 DEFUN ("set-weak-list-list", Fset_weak_list_list, 2, 2, 0, /*
2006 Change the list contained in a weak-list object.
2010 CHECK_WEAK_LIST (weak);
2011 XWEAK_LIST_LIST (weak) = new_list;
2016 /************************************************************************/
2017 /* initialization */
2018 /************************************************************************/
2021 arith_error (int signo)
2023 EMACS_REESTABLISH_SIGNAL (signo, arith_error);
2024 EMACS_UNBLOCK_SIGNAL (signo);
2025 signal_error (Qarith_error, Qnil);
2029 init_data_very_early (void)
2031 /* Don't do this if just dumping out.
2032 We don't want to call `signal' in this case
2033 so that we don't have trouble with dumping
2034 signal-delivering routines in an inconsistent state. */
2038 #endif /* CANNOT_DUMP */
2039 signal (SIGFPE, arith_error);
2041 signal (SIGEMT, arith_error);
2046 init_errors_once_early (void)
2048 DEFSYMBOL (Qerror_conditions);
2049 DEFSYMBOL (Qerror_message);
2051 /* We declare the errors here because some other deferrors depend
2052 on some of the errors below. */
2054 /* ERROR is used as a signaler for random errors for which nothing
2057 DEFERROR (Qerror, "error", Qnil);
2058 DEFERROR_STANDARD (Qquit, Qnil);
2060 DEFERROR (Qunimplemented, "Feature not yet implemented", Qerror);
2061 DEFERROR_STANDARD (Qsyntax_error, Qerror);
2062 DEFERROR_STANDARD (Qinvalid_read_syntax, Qsyntax_error);
2063 DEFERROR_STANDARD (Qlist_formation_error, Qsyntax_error);
2065 /* Generated by list traversal macros */
2066 DEFERROR_STANDARD (Qmalformed_list, Qlist_formation_error);
2067 DEFERROR_STANDARD (Qmalformed_property_list, Qmalformed_list);
2068 DEFERROR_STANDARD (Qcircular_list, Qlist_formation_error);
2069 DEFERROR_STANDARD (Qcircular_property_list, Qcircular_list);
2071 DEFERROR_STANDARD (Qinvalid_argument, Qerror);
2072 DEFERROR_STANDARD (Qwrong_type_argument, Qinvalid_argument);
2073 DEFERROR_STANDARD (Qargs_out_of_range, Qinvalid_argument);
2074 DEFERROR_STANDARD (Qwrong_number_of_arguments, Qinvalid_argument);
2075 DEFERROR_STANDARD (Qinvalid_function, Qinvalid_argument);
2076 DEFERROR (Qno_catch, "No catch for tag", Qinvalid_argument);
2078 DEFERROR_STANDARD (Qinternal_error, Qerror);
2080 DEFERROR (Qinvalid_state, "Properties or values have been set incorrectly",
2082 DEFERROR (Qvoid_function, "Symbol's function definition is void",
2084 DEFERROR (Qcyclic_function_indirection,
2085 "Symbol's chain of function indirections contains a loop",
2087 DEFERROR (Qvoid_variable, "Symbol's value as variable is void",
2089 DEFERROR (Qcyclic_variable_indirection,
2090 "Symbol's chain of variable indirections contains a loop",
2093 DEFERROR (Qinvalid_operation,
2094 "Operation not allowed or error during operation", Qerror);
2095 DEFERROR (Qinvalid_change, "Attempt to set properties or values incorrectly",
2096 Qinvalid_operation);
2097 DEFERROR (Qsetting_constant, "Attempt to set a constant symbol",
2100 DEFERROR (Qediting_error, "Invalid operation during editing",
2101 Qinvalid_operation);
2102 DEFERROR_STANDARD (Qbeginning_of_buffer, Qediting_error);
2103 DEFERROR_STANDARD (Qend_of_buffer, Qediting_error);
2104 DEFERROR (Qbuffer_read_only, "Buffer is read-only", Qediting_error);
2106 DEFERROR (Qio_error, "IO Error", Qinvalid_operation);
2107 DEFERROR (Qend_of_file, "End of file or stream", Qio_error);
2109 DEFERROR (Qarith_error, "Arithmetic error", Qinvalid_operation);
2110 DEFERROR (Qrange_error, "Arithmetic range error", Qarith_error);
2111 DEFERROR (Qdomain_error, "Arithmetic domain error", Qarith_error);
2112 DEFERROR (Qsingularity_error, "Arithmetic singularity error", Qdomain_error);
2113 DEFERROR (Qoverflow_error, "Arithmetic overflow error", Qdomain_error);
2114 DEFERROR (Qunderflow_error, "Arithmetic underflow error", Qdomain_error);
2120 INIT_LRECORD_IMPLEMENTATION (weak_list);
2123 DEFSYMBOL (Qlambda);
2125 DEFSYMBOL (Qtrue_list_p);
2128 DEFSYMBOL (Qsymbolp);
2129 DEFSYMBOL (Qintegerp);
2130 DEFSYMBOL (Qcharacterp);
2131 DEFSYMBOL (Qnatnump);
2132 DEFSYMBOL (Qstringp);
2133 DEFSYMBOL (Qarrayp);
2134 DEFSYMBOL (Qsequencep);
2135 DEFSYMBOL (Qbufferp);
2137 DEFSYMBOL_MULTIWORD_PREDICATE (Qbit_vectorp);
2138 DEFSYMBOL (Qvectorp);
2139 DEFSYMBOL (Qchar_or_string_p);
2140 DEFSYMBOL (Qmarkerp);
2141 DEFSYMBOL (Qinteger_or_marker_p);
2142 DEFSYMBOL (Qinteger_or_char_p);
2143 DEFSYMBOL (Qinteger_char_or_marker_p);
2144 DEFSYMBOL (Qnumberp);
2145 DEFSYMBOL (Qnumber_char_or_marker_p);
2147 DEFSYMBOL_MULTIWORD_PREDICATE (Qweak_listp);
2149 #ifdef LISP_FLOAT_TYPE
2150 DEFSYMBOL (Qfloatp);
2151 #endif /* LISP_FLOAT_TYPE */
2153 DEFSUBR (Fwrong_type_argument);
2158 Ffset (intern ("not"), intern ("null"));
2161 DEFSUBR (Ftrue_list_p);
2164 DEFSUBR (Fchar_or_string_p);
2165 DEFSUBR (Fcharacterp);
2166 DEFSUBR (Fchar_int_p);
2167 DEFSUBR (Fchar_to_int);
2168 DEFSUBR (Fint_to_char);
2169 DEFSUBR (Fchar_or_char_int_p);
2170 DEFSUBR (Fchar_ref_p);
2171 DEFSUBR (Fintegerp);
2172 DEFSUBR (Finteger_or_marker_p);
2173 DEFSUBR (Finteger_or_char_p);
2174 DEFSUBR (Finteger_char_or_marker_p);
2176 DEFSUBR (Fnumber_or_marker_p);
2177 DEFSUBR (Fnumber_char_or_marker_p);
2178 #ifdef LISP_FLOAT_TYPE
2180 #endif /* LISP_FLOAT_TYPE */
2183 DEFSUBR (Fkeywordp);
2187 DEFSUBR (Fbit_vector_p);
2189 DEFSUBR (Fsequencep);
2192 DEFSUBR (Fsubr_min_args);
2193 DEFSUBR (Fsubr_max_args);
2194 DEFSUBR (Fsubr_interactive);
2198 DEFSUBR (Fcar_safe);
2199 DEFSUBR (Fcdr_safe);
2202 DEFSUBR (Findirect_function);
2206 DEFSUBR (Fnumber_to_string);
2207 DEFSUBR (Fstring_to_number);
2232 DEFSUBR (Fweak_list_p);
2233 DEFSUBR (Fmake_weak_list);
2234 DEFSUBR (Fweak_list_type);
2235 DEFSUBR (Fweak_list_list);
2236 DEFSUBR (Fset_weak_list_list);
2242 /* This must not be staticpro'd */
2243 Vall_weak_lists = Qnil;
2244 dump_add_weak_object_chain (&Vall_weak_lists);
2247 DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /*
2248 If non-zero, note when your code may be suffering from char-int confoundance.
2249 That is to say, if XEmacs encounters a usage of `eq', `memq', `equal',
2250 etc. where an int and a char with the same value are being compared,
2251 it will issue a notice on stderr to this effect, along with a backtrace.
2252 In such situations, the result would be different in XEmacs 19 versus
2253 XEmacs 20, and you probably don't want this.
2255 Note that in order to see these notices, you have to byte compile your
2256 code under XEmacs 20 -- any code byte-compiled under XEmacs 19 will
2257 have its chars and ints all confounded in the byte code, making it
2258 impossible to accurately determine Ebola infection.
2261 debug_issue_ebola_notices = 0;
2263 DEFVAR_INT ("debug-ebola-backtrace-length",
2264 &debug_ebola_backtrace_length /*
2265 Length (in stack frames) of short backtrace printed out in Ebola notices.
2266 See `debug-issue-ebola-notices'.
2268 debug_ebola_backtrace_length = 32;
2270 #endif /* DEBUG_XEMACS */