Coverity inspired security fixes from Nelson
[sxemacs] / src / data.c
1 /* Primitive operations on Lisp data types for SXEmacs Lisp interpreter.
2    Copyright (C) 1985, 1986, 1988, 1992, 1993, 1994, 1995
3    Free Software Foundation, Inc.
4    Copyright (C) 2000 Ben Wing.
5
6 This file is part of SXEmacs
7
8 SXEmacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 SXEmacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
20
21
22 /* Synched up with: Mule 2.0, FSF 19.30.  Some of FSF's data.c is in
23    SXEmacs' 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 #include "dynacat.h"
34
35 Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound;
36 Lisp_Object Qerror_conditions, Qerror_message;
37 Lisp_Object Qerror, Qquit, Qsyntax_error, Qinvalid_read_syntax;
38 Lisp_Object Qlist_formation_error, Qstructure_formation_error;
39 Lisp_Object Qmalformed_list, Qmalformed_property_list;
40 Lisp_Object Qcircular_list, Qcircular_property_list;
41 Lisp_Object Qinvalid_argument, Qwrong_type_argument, Qargs_out_of_range;
42 Lisp_Object Qwrong_number_of_arguments, Qinvalid_function, Qno_catch;
43 Lisp_Object Qinternal_error, Qinvalid_state, Qinvalid_constant;
44 Lisp_Object Qvoid_variable, Qcyclic_variable_indirection;
45 Lisp_Object Qvoid_function, Qcyclic_function_indirection;
46 Lisp_Object Qinvalid_operation, Qinvalid_change, Qout_of_memory;
47 Lisp_Object Qsetting_constant, Qprinting_unreadable_object;
48 Lisp_Object Qediting_error, Qconversion_error, Qtext_conversion_error;
49 Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
50 Lisp_Object Qio_error, Qend_of_file;
51 Lisp_Object Qarith_error, Qrange_error, Qdomain_error, Qstack_overflow;
52 Lisp_Object Qsingularity_error, Qoverflow_error, Qunderflow_error;
53 Lisp_Object Qintegerp, Qnatnump, Qnonnegativep, Qpositivep, Qsymbolp;
54 Lisp_Object Qlistp, Qtrue_list_p, Qweak_listp;
55 Lisp_Object Qconsp, Qsubrp;
56 Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qvectorp, Qdictp;
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_SXEMACS
65
66 int debug_issue_ebola_notices;
67
68 Fixnum debug_ebola_backtrace_length;
69
70 int eq_with_ebola_notice(Lisp_Object obj1, Lisp_Object obj2)
71 {
72         if (debug_issue_ebola_notices
73             && ((CHARP(obj1) && INTP(obj2)) || (CHARP(obj2) && INTP(obj1)))) {
74                 /* #### It would be really nice if this were a proper warning
75                    instead of brain-dead print to Qexternal_debugging_output.  */
76                 write_c_string
77                     ("Comparison between integer and character is constant nil (",
78                      Qexternal_debugging_output);
79                 Fprinc(obj1, Qexternal_debugging_output);
80                 write_c_string(" and ", Qexternal_debugging_output);
81                 Fprinc(obj2, Qexternal_debugging_output);
82                 write_c_string(")\n", Qexternal_debugging_output);
83                 debug_short_backtrace(debug_ebola_backtrace_length);
84         }
85         return EQ(obj1, obj2);
86 }
87
88 #endif                          /* DEBUG_SXEMACS */
89 \f
90 Lisp_Object wrong_type_argument(Lisp_Object predicate, Lisp_Object value)
91 {
92         /* This function can GC */
93         REGISTER Lisp_Object tem;
94         do {
95                 value = Fsignal(Qwrong_type_argument, list2(predicate, value));
96                 tem = call1(predicate, value);
97         }
98         while (NILP(tem));
99         return value;
100 }
101
102 DOESNT_RETURN dead_wrong_type_argument(Lisp_Object predicate, Lisp_Object value)
103 {
104         signal_error(Qwrong_type_argument, list2(predicate, value));
105 }
106
107 DEFUN("wrong-type-argument", Fwrong_type_argument, 2, 2, 0,     /*
108 Signal an error until the correct type value is given by the user.
109 This function loops, signalling a continuable `wrong-type-argument' error
110 with PREDICATE and VALUE as the data associated with the error and then
111 calling PREDICATE on the returned value, until the value gotten satisfies
112 PREDICATE.  At that point, the gotten value is returned.
113 */
114       (predicate, value))
115 {
116         return wrong_type_argument(predicate, value);
117 }
118
119 DOESNT_RETURN c_write_error(Lisp_Object obj)
120 {
121         signal_simple_error("Attempt to modify read-only object (c)", obj);
122 }
123
124 DOESNT_RETURN lisp_write_error(Lisp_Object obj)
125 {
126         signal_simple_error("Attempt to modify read-only object (lisp)", obj);
127 }
128
129 DOESNT_RETURN args_out_of_range(Lisp_Object a1, Lisp_Object a2)
130 {
131         signal_error(Qargs_out_of_range, list2(a1, a2));
132 }
133
134 DOESNT_RETURN
135 args_out_of_range_3(Lisp_Object a1, Lisp_Object a2, Lisp_Object a3)
136 {
137         signal_error(Qargs_out_of_range, list3(a1, a2, a3));
138 }
139
140 void check_int_range(EMACS_INT val, EMACS_INT min, EMACS_INT max)
141 {
142         if (val < min || val > max)
143                 args_out_of_range_3(make_int(val), make_int(min),
144                                     make_int(max));
145 }
146
147 /* On some machines, XINT needs a temporary location.
148    Here it is, in case it is needed.  */
149
150 EMACS_INT sign_extend_temp;
151
152 /* On a few machines, XINT can only be done by calling this.  */
153 /* SXEmacs:  only used by m/convex.h */
154 EMACS_INT sign_extend_lisp_int(EMACS_INT num);
155 EMACS_INT sign_extend_lisp_int(EMACS_INT num)
156 {
157         if (num & (1L << (INT_VALBITS - 1)))
158                 return num | ((-1L) << INT_VALBITS);
159         else
160                 return num & (EMACS_INT) ((1UL << INT_VALBITS) - 1);
161 }
162 \f
163 /* Data type predicates */
164
165 DEFUN("eq", Feq, 2, 2, 0,       /*
166 Return t if the two args are the same Lisp object.
167 */
168       (object1, object2))
169 {
170         return EQ_WITH_EBOLA_NOTICE(object1, object2) ? Qt : Qnil;
171 }
172
173 DEFUN("old-eq", Fold_eq, 2, 2, 0,       /*
174 Return t if the two args are (in most cases) the same Lisp object.
175
176 Special kludge: A character is considered `old-eq' to its equivalent integer
177 even though they are not the same object and are in fact of different
178 types.  This is ABSOLUTELY AND UTTERLY HORRENDOUS but is necessary to
179 preserve byte-code compatibility with v19.  This kludge is known as the
180 \"char-int confoundance disease\" and appears in a number of other
181 functions with `old-foo' equivalents.
182
183 Do not use this function!
184 */
185       (object1, object2))
186 {
187         /* #### blasphemy */
188         return HACKEQ_UNSAFE(object1, object2) ? Qt : Qnil;
189 }
190
191 DEFUN("null", Fnull, 1, 1, 0,   /*
192 Return t if OBJECT is nil.
193 */
194       (object))
195 {
196         return NILP(object) ? Qt : Qnil;
197 }
198
199 DEFUN("consp", Fconsp, 1, 1, 0, /*
200 Return t if OBJECT is a cons cell.  `nil' is not a cons cell.
201
202 A cons cell is a Lisp object (an area in memory) comprising two pointers
203 called the CAR and the CDR.  Each of these pointers can point to any other
204 Lisp object.  The common Lisp data type, the list, is a specially-structured
205 series of cons cells.
206
207 See the documentation for `cons' or the Lisp manual for more details on what
208 a cons cell is.
209 */
210       (object))
211 {
212         return CONSP(object) ? Qt : Qnil;
213 }
214
215 DEFUN("atom", Fatom, 1, 1, 0,   /*
216 Return t if OBJECT is not a cons cell.  `nil' is not a cons cell.
217
218 A cons cell is a Lisp object (an area in memory) comprising two pointers
219 called the CAR and the CDR.  Each of these pointers can point to any other
220 Lisp object.  The common Lisp data type, the list, is a specially-structured
221 series of cons cells.
222
223 See the documentation for `cons' or the Lisp manual for more details on what
224 a cons cell is.
225 */
226       (object))
227 {
228         return CONSP(object) ? Qnil : Qt;
229 }
230
231 DEFUN("listp", Flistp, 1, 1, 0, /*
232 Return t if OBJECT is a list.  `nil' is a list.
233
234 A list is implemented as a series of cons cells structured such that the CDR
235 of each cell either points to another cons cell or to `nil', the special
236 Lisp value for both Boolean false and the empty list.
237 */
238       (object))
239 {
240         return LISTP(object) ? Qt : Qnil;
241 }
242
243 DEFUN("nlistp", Fnlistp, 1, 1, 0,       /*
244 Return t if OBJECT is not a list.  `nil' is a list.
245
246 A list is implemented as a series of cons cells structured such that the CDR
247 of each cell either points to another cons cell or to `nil', the special
248 Lisp value for both Boolean false and the empty list.
249 */
250       (object))
251 {
252         return LISTP(object) ? Qnil : Qt;
253 }
254
255 DEFUN("true-list-p", Ftrue_list_p, 1, 1, 0,     /*
256 Return t if OBJECT is an acyclic, nil-terminated (ie, not dotted), list.
257
258 A list is implemented as a series of cons cells structured such that the CDR
259 of each cell either points to another cons cell or to `nil', the special
260 Lisp value for both Boolean false and the empty list.
261 */
262       (object))
263 {
264         return TRUE_LIST_P(object) ? Qt : Qnil;
265 }
266 \f
267 DEFUN("symbolp", Fsymbolp, 1, 1, 0,     /*
268 Return t if OBJECT is a symbol.
269 */
270       (object))
271 {
272         return SYMBOLP(object) ? Qt : Qnil;
273 }
274
275 DEFUN("keywordp", Fkeywordp, 1, 1, 0,   /*
276 Return t if OBJECT is a keyword.
277
278 A symbol is a Lisp object with a name. It can optionally have any and all of
279 a value, a property list and an associated function. 
280 */
281       (object))
282 {
283         return KEYWORDP(object) ? Qt : Qnil;
284 }
285
286 DEFUN("vectorp", Fvectorp, 1, 1, 0,     /*
287 Return t if OBJECT is a vector.
288 */
289       (object))
290 {
291         return VECTORP(object) ? Qt : Qnil;
292 }
293
294 DEFUN("bit-vector-p", Fbit_vector_p, 1, 1, 0,   /*
295 Return t if OBJECT is a bit vector.
296 */
297       (object))
298 {
299         return BIT_VECTORP(object) ? Qt : Qnil;
300 }
301
302 DEFUN("stringp", Fstringp, 1, 1, 0,     /*
303 Return t if OBJECT is a string.
304 */
305       (object))
306 {
307         return STRINGP(object) ? Qt : Qnil;
308 }
309
310 DEFUN("arrayp", Farrayp, 1, 1, 0,       /*
311 Return t if OBJECT is an array (string, vector, or bit vector).
312 */
313       (object))
314 {
315         return (VECTORP(object) || STRINGP(object) || BIT_VECTORP(object))
316             ? Qt : Qnil;
317 }
318
319 DEFUN("sequencep", Fsequencep, 1, 1, 0, /*
320 Return t if OBJECT is a sequence (list, dllist or array).
321 */
322       (object))
323 {
324         return (LISTP(object) || DLLISTP(object) ||
325                 VECTORP(object) || STRINGP(object) || BIT_VECTORP(object))
326             ? Qt : Qnil;
327 }
328
329 DEFUN("markerp", Fmarkerp, 1, 1, 0,     /*
330 Return t if OBJECT is a marker (editor pointer).
331 */
332       (object))
333 {
334         return MARKERP(object) ? Qt : Qnil;
335 }
336
337 DEFUN("subrp", Fsubrp, 1, 1, 0, /*
338 Return t if OBJECT is a built-in function.
339 */
340       (object))
341 {
342         return SUBRP(object) ? Qt : Qnil;
343 }
344
345 DEFUN("subr-min-args", Fsubr_min_args, 1, 1, 0, /*
346 Return minimum number of args built-in function SUBR may be called with.
347 */
348       (subr))
349 {
350         CHECK_SUBR(subr);
351         return make_int(XSUBR(subr)->min_args);
352 }
353
354 DEFUN("subr-max-args", Fsubr_max_args, 1, 1, 0, /*
355 Return maximum number of args built-in function SUBR may be called with,
356 or nil if it takes an arbitrary number of arguments or is a special form.
357 */
358       (subr))
359 {
360         int nargs;
361         CHECK_SUBR(subr);
362         nargs = XSUBR(subr)->max_args;
363         if (nargs == MANY || nargs == UNEVALLED)
364                 return Qnil;
365         else
366                 return make_int(nargs);
367 }
368
369 DEFUN("subr-interactive", Fsubr_interactive, 1, 1, 0,   /*
370 Return the interactive spec of the subr object SUBR, or nil.
371 If non-nil, the return value will be a list whose first element is
372 `interactive' and whose second element is the interactive spec.
373 */
374       (subr))
375 {
376         const char *prompt;
377         CHECK_SUBR(subr);
378         prompt = XSUBR(subr)->prompt;
379         return prompt ? list2(Qinteractive, build_string(prompt)) : Qnil;
380 }
381 \f
382 DEFUN("characterp", Fcharacterp, 1, 1, 0,       /*
383 Return t if OBJECT is a character.
384 Unlike in XEmacs v19 and FSF Emacs, a character is its own primitive type.
385 Any character can be converted into an equivalent integer using
386 `char-int'.  To convert the other way, use `int-char'; however,
387 only some integers can be converted into characters.  Such an integer
388 is called a `char-int'; see `char-int-p'.
389
390 Some functions that work on integers (e.g. the comparison functions
391 <, <=, =, /=, etc. and the arithmetic functions +, -, *, etc.)
392 accept characters and implicitly convert them into integers.  In
393 general, functions that work on characters also accept char-ints and
394 implicitly convert them into characters.  WARNING: Neither of these
395 behaviors is very desirable, and they are maintained for backward
396 compatibility with old E-Lisp programs that confounded characters and
397 integers willy-nilly.  These behaviors may change in the future; therefore,
398 do not rely on them.  Instead, use the character-specific functions such
399 as `char='.
400 */
401       (object))
402 {
403         return CHARP(object) ? Qt : Qnil;
404 }
405
406 DEFUN("char-to-int", Fchar_to_int, 1, 1, 0,     /*
407 Convert CHARACTER into an equivalent integer.
408 The resulting integer will always be non-negative.  The integers in
409 the range 0 - 255 map to characters as follows:
410
411    0 - 31          Control set 0
412   32 - 127        ASCII
413  128 - 159       Control set 1
414  160 - 255       Right half of ISO-8859-1
415
416 If support for Mule does not exist, these are the only valid character
417 values.  When Mule support exists, the values assigned to other characters
418 may vary depending on the particular version of SXEmacs, the order in which
419 character sets were loaded, etc., and you should not depend on them.
420 */
421       (character))
422 {
423         CHECK_CHAR(character);
424         return make_int(XCHAR(character));
425 }
426
427 DEFUN("int-to-char", Fint_to_char, 1, 1, 0,     /*
428 Convert integer INTEGER into the equivalent character.
429 Not all integers correspond to valid characters; use `char-int-p' to
430 determine whether this is the case.  If the integer cannot be converted,
431 nil is returned.
432 */
433       (integer))
434 {
435         CHECK_INT(integer);
436         if (CHAR_INTP(integer))
437                 return make_char(XINT(integer));
438         else
439                 return Qnil;
440 }
441
442 DEFUN("char-int-p", Fchar_int_p, 1, 1, 0,       /*
443 Return t if OBJECT is an integer that can be converted into a character.
444 See `char-int'.
445 */
446       (object))
447 {
448         return CHAR_INTP(object) ? Qt : Qnil;
449 }
450
451 DEFUN("char-or-char-int-p", Fchar_or_char_int_p, 1, 1, 0,       /*
452 Return t if OBJECT is a character or an integer that can be converted into one.
453 */
454       (object))
455 {
456         return CHAR_OR_CHAR_INTP(object) ? Qt : Qnil;
457 }
458
459 DEFUN("char-or-string-p", Fchar_or_string_p, 1, 1, 0,   /*
460 Return t if OBJECT is a character (or a char-int) or a string.
461 It is semi-hateful that we allow a char-int here, as it goes against
462 the name of this function, but it makes the most sense considering the
463 other steps we take to maintain compatibility with the old character/integer
464 confoundedness in older versions of E-Lisp.
465 */
466       (object))
467 {
468         return CHAR_OR_CHAR_INTP(object) || STRINGP(object) ? Qt : Qnil;
469 }
470 \f
471 #ifdef WITH_NUMBER_TYPES
472 /* In this case, integerp is defined in number.c. */
473 DEFUN("intp", Fintp, 1, 1, 0, /*
474 Return t if OBJECT is an ordinary integer.
475 */
476       (object))
477 {
478         return INTP(object) ? Qt : Qnil;
479 }
480 /* stay compatible to XE 21.5 */
481 DEFUN("fixnump", Ffixnump, 1, 1, 0, /*
482 Return t if OBJECT is an ordinary integer.
483 */
484       (object))
485 {
486         return INTP(object) ? Qt : Qnil;
487 }
488 #else  /* !WITH_NUMBER_TYPES */
489 DEFUN("integerp", Fintegerp, 1, 1, 0,   /*
490 Return t if OBJECT is an integer.
491 */
492       (object))
493 {
494         return INTP(object) ? Qt : Qnil;
495 }
496 #endif  /* WITH_NUMBER_TYPES */
497
498 DEFUN("integer-or-marker-p", Finteger_or_marker_p, 1, 1, 0,     /*
499 Return t if OBJECT is an integer or a marker (editor pointer).
500 */
501       (object))
502 {
503         return INTP(object) || MARKERP(object) ? Qt : Qnil;
504 }
505
506 DEFUN("integer-or-char-p", Finteger_or_char_p, 1, 1, 0, /*
507 Return t if OBJECT is an integer or a character.
508 */
509       (object))
510 {
511         return INTP(object) || CHARP(object) ? Qt : Qnil;
512 }
513
514 DEFUN("integer-char-or-marker-p", Finteger_char_or_marker_p, 1, 1, 0,   /*
515 Return t if OBJECT is an integer, character or a marker (editor pointer).
516 */
517       (object))
518 {
519         return INTP(object) || CHARP(object) || MARKERP(object) ? Qt : Qnil;
520 }
521
522 DEFUN("natnump", Fnatnump, 1, 1, 0,     /*
523 Return t if OBJECT is a nonnegative integer.
524 */
525       (object))
526 {
527         return (NATNUMP(object)
528 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
529                 || (BIGZP(object) &&
530                     bigz_sign(XBIGZ_DATA(object)) >= 0)
531 #endif
532                 ) ? Qt : Qnil;
533 }
534
535 DEFUN ("nonnegativep", Fnonnegativep, 1, 1, 0, /*
536 Return t if OBJECT is a nonnegative number.
537
538 We call a number object non-negative iff it is comparable
539 and its value is not less than 0.
540 */
541        (object))
542 {
543         return NATNUMP(object)
544 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
545                 || (BIGZP(object) &&
546                     bigz_sign(XBIGZ_DATA(object)) >= 0)
547 #endif  /* HAVE_MPZ */
548 #if defined HAVE_MPQ && defined WITH_GMP
549                 || (BIGQP(object) &&
550                     bigq_sign(XBIGQ_DATA(object)) >= 0)
551 #endif  /* HAVE_MPQ */
552 #ifdef HAVE_FPFLOAT
553                 || (FLOATP(object) &&
554                     (double)XFLOAT_DATA(object) >= 0.0)
555 #endif  /* HAVE_FPFLOAT */
556 #if defined HAVE_MPF && defined WITH_GMP
557                 || (BIGFP(object) &&
558                     bigf_sign(XBIGF_DATA(object)) >= 0)
559 #endif  /* HAVE_MPF */
560 #if defined HAVE_MPFR && defined WITH_MPFR
561                 || (BIGFRP(object) &&
562                     bigfr_sign(XBIGFR_DATA(object)) >= 0)
563 #endif  /* HAVE_MPFR */
564                 ? Qt : Qnil;
565 }
566
567 DEFUN("bitp", Fbitp, 1, 1, 0,   /*
568 Return t if OBJECT is a bit (0 or 1).
569 */
570       (object))
571 {
572         return BITP(object) ? Qt : Qnil;
573 }
574
575 DEFUN("numberp", Fnumberp, 1, 1, 0,     /*
576 Return t if OBJECT is a number (floating point or integer).
577 */
578       (object))
579 {
580 #if defined(WITH_NUMBER_TYPES)
581         return NUMBERP(object) ? Qt : Qnil;
582 #else
583         return INT_OR_FLOATP(object) ? Qt : Qnil;
584 #endif
585 }
586
587 DEFUN("number-or-marker-p", Fnumber_or_marker_p, 1, 1, 0,       /*
588 Return t if OBJECT is a number or a marker.
589 */
590       (object))
591 {
592         return INT_OR_FLOATP(object) || MARKERP(object) ? Qt : Qnil;
593 }
594
595 DEFUN("number-char-or-marker-p", Fnumber_char_or_marker_p, 1, 1, 0,     /*
596 Return t if OBJECT is a number, character or a marker.
597 */
598       (object))
599 {
600         return (INT_OR_FLOATP(object) || CHARP(object) || MARKERP(object))
601             ? Qt : Qnil;
602 }
603
604 #ifdef HAVE_FPFLOAT
605 DEFUN("floatp", Ffloatp, 1, 1, 0,       /*
606 Return t if OBJECT is a floating point number.
607 */
608       (object))
609 {
610         return FLOATP(object) ? Qt : Qnil;
611 }
612 #endif                          /* HAVE_FPFLOAT */
613
614 DEFUN("type-of", Ftype_of, 1, 1, 0,     /*
615 Return a symbol representing the type of OBJECT.
616 */
617       (object))
618 {
619         switch (XTYPE(object)) {
620         case Lisp_Type_Record:
621                 if (XRECORD_LHEADER_IMPLEMENTATION(object)->
622                     lrecord_type_index != lrecord_type_dynacat)
623                         return intern(
624                                 XRECORD_LHEADER_IMPLEMENTATION(object)->name);
625                 else if (SYMBOLP(XDYNACAT_TYPE(object)))
626                         return XDYNACAT_TYPE(object);
627                 else
628                         return Qundecided;
629
630         case Lisp_Type_Char:
631                 return Qcharacter;
632
633                 /* list all cases */
634         case Lisp_Type_Int_Even:
635         case Lisp_Type_Int_Odd:
636         default:
637                 return Qinteger;
638         }
639 }
640 \f
641 /* Extract and set components of lists */
642
643 DEFUN("car", Fcar, 1, 1, 0,     /*
644 Return the car of CONS.  If CONS is nil, return nil.
645
646 The car of a list or a dotted pair is its first element.
647 Error if CONS is not nil and not a cons cell.  See also `car-safe'.
648 */
649       (cons))
650 {
651         while (1) {
652                 if (CONSP(cons))
653                         return XCAR(cons);
654                 else if (NILP(cons))
655                         return Qnil;
656                 else
657                         cons = wrong_type_argument(Qlistp, cons);
658         }
659 }
660
661 DEFUN("car-safe", Fcar_safe, 1, 1, 0,   /*
662 Return the car of OBJECT if it is a cons cell, or else nil.
663
664 The car of a list or a dotted pair is its first element.
665 */
666       (object))
667 {
668         return CONSP(object) ? XCAR(object) : Qnil;
669 }
670
671 DEFUN("cdr", Fcdr, 1, 1, 0,     /*
672 Return the cdr of CONS.  If CONS is nil, return nil.
673
674 The cdr of a list is the list without its first element.  The cdr of a
675 dotted pair (A . B) is the second element, B.
676
677 Error if arg is not nil and not a cons cell.  See also `cdr-safe'.
678 */
679       (cons))
680 {
681         while (1) {
682                 if (CONSP(cons))
683                         return XCDR(cons);
684                 else if (NILP(cons))
685                         return Qnil;
686                 else
687                         cons = wrong_type_argument(Qlistp, cons);
688         }
689 }
690
691 DEFUN("cdr-safe", Fcdr_safe, 1, 1, 0,   /*
692 Return the cdr of OBJECT if it is a cons cell, else nil.
693
694 The cdr of a list is the list without its first element.  The cdr of a
695 dotted pair (A . B) is the second element, B.
696 */
697       (object))
698 {
699         return CONSP(object) ? XCDR(object) : Qnil;
700 }
701
702 DEFUN("setcar", Fsetcar, 2, 2, 0,       /*
703 Set the car of CONS-CELL to be NEWCAR.  Return NEWCAR.
704
705 The car of a list or a dotted pair is its first element.
706 */
707       (cons_cell, newcar))
708 {
709         if (!CONSP(cons_cell))
710                 cons_cell = wrong_type_argument(Qconsp, cons_cell);
711
712         XCAR(cons_cell) = newcar;
713         return newcar;
714 }
715
716 DEFUN("setcdr", Fsetcdr, 2, 2, 0,       /*
717 Set the cdr of CONS-CELL to be NEWCDR.  Return NEWCDR.
718
719 The cdr of a list is the list without its first element.  The cdr of a
720 dotted pair (A . B) is the second element, B.
721 */
722       (cons_cell, newcdr))
723 {
724         if (!CONSP(cons_cell))
725                 cons_cell = wrong_type_argument(Qconsp, cons_cell);
726
727         XCDR(cons_cell) = newcdr;
728         return newcdr;
729 }
730 \f
731 /* Find the function at the end of a chain of symbol function indirections.
732
733    If OBJECT is a symbol, find the end of its function chain and
734    return the value found there.  If OBJECT is not a symbol, just
735    return it.  If there is a cycle in the function chain, signal a
736    cyclic-function-indirection error.
737
738    This is like Findirect_function when VOID_FUNCTION_ERRORP is true.
739    When VOID_FUNCTION_ERRORP is false, no error is signaled if the end
740    of the chain ends up being Qunbound. */
741 Lisp_Object indirect_function(Lisp_Object object, int void_function_errorp)
742 {
743 #define FUNCTION_INDIRECTION_SUSPICION_LENGTH 16
744         Lisp_Object tortoise, hare;
745         int count;
746
747         for (hare = tortoise = object, count = 0;
748              SYMBOLP(hare); hare = XSYMBOL(hare)->function, count++) {
749                 if (count < FUNCTION_INDIRECTION_SUSPICION_LENGTH)
750                         continue;
751
752                 if (count & 1)
753                         tortoise = XSYMBOL(tortoise)->function;
754                 if (EQ(hare, tortoise))
755                         return Fsignal(Qcyclic_function_indirection,
756                                        list1(object));
757         }
758
759         if (void_function_errorp && UNBOUNDP(hare))
760                 return signal_void_function_error(object);
761
762         return hare;
763 }
764
765 DEFUN("indirect-function", Findirect_function, 1, 1, 0, /*
766 Return the function at the end of OBJECT's function chain.
767 If OBJECT is a symbol, follow all function indirections and return
768 the final function binding.
769 If OBJECT is not a symbol, just return it.
770 Signal a void-function error if the final symbol is unbound.
771 Signal a cyclic-function-indirection error if there is a loop in the
772 function chain of symbols.
773 */
774       (object))
775 {
776         return indirect_function(object, 1);
777 }
778 \f
779 /* Extract and set vector and string elements */
780
781 DEFUN("aref", Faref, 2, 2, 0,   /*
782 Return the element of ARRAY at index INDEX.
783 ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
784 */
785       (array, index_))
786 {
787         EMACS_INT idx;
788         EMACS_INT alen;
789
790 retry:
791         /* frob the position INDEX */
792         if (INTP(index_))
793                 idx = XINT(index_);
794         else if (CHARP(index_))
795                 idx = XCHAR(index_);    /* yuck! */
796         else {
797                 index_ = wrong_type_argument(Qinteger_or_char_p, index_);
798                 goto retry;
799         }
800
801         /* frob the length of ARRAY */
802         if (VECTORP(array))
803                 alen = XVECTOR_LENGTH(array);
804         else if (BIT_VECTORP(array))
805                 alen = bit_vector_length(XBIT_VECTOR(array));
806         else if (STRINGP(array))
807                 alen = XSTRING_CHAR_LENGTH(array);
808         else
809                 alen = 0;
810
811         if (idx < 0 || idx >= alen)
812                 goto range_error;
813
814         if (VECTORP(array))
815                 return XVECTOR_DATA(array)[idx];
816         else if (BIT_VECTORP(array))
817                 return make_int(bit_vector_bit(XBIT_VECTOR(array), idx));
818         else if (STRINGP(array))
819                 return make_char(string_char(XSTRING(array), idx));
820 #ifdef LOSING_BYTECODE
821         else if (COMPILED_FUNCTIONP(array)) {
822                 /* Weird, gross compatibility kludge */
823                 return Felt(array, index_);
824         }
825 #endif
826         else {
827                 check_losing_bytecode("aref", array);
828                 array = wrong_type_argument(Qarrayp, array);
829                 goto retry;
830         }
831
832 range_error:
833         args_out_of_range(array, index_);
834         return Qnil;            /* not reached */
835 }
836
837 DEFUN("aset", Faset, 3, 3, 0,   /*
838 Store into the element of ARRAY at index INDEX the value NEWVAL.
839 ARRAY may be a vector, bit vector, or string.  INDEX starts at 0.
840 */
841       (array, index_, newval))
842 {
843         EMACS_INT idx;
844         EMACS_INT alen;
845
846 retry:
847         /* frob the INDEX position */
848         if (INTP(index_))
849                 idx = XINT(index_);
850         else if (CHARP(index_))
851                 idx = XCHAR(index_);    /* yuck! */
852         else {
853                 index_ = wrong_type_argument(Qinteger_or_char_p, index_);
854                 goto retry;
855         }
856
857         /* frob the length of ARRAY */
858         if (VECTORP(array))
859                 alen = XVECTOR_LENGTH(array);
860         else if (BIT_VECTORP(array))
861                 alen = bit_vector_length(XBIT_VECTOR(array));
862         else if (STRINGP(array))
863                 alen = XSTRING_CHAR_LENGTH(array);
864         else
865                 alen = 0;
866
867         if (idx < 0 || idx >= alen)
868                 goto range_error;
869
870         if (VECTORP(array)) {
871                 XVECTOR_DATA(array)[idx] = newval;
872         } else if (BIT_VECTORP(array)) {
873                 CHECK_BIT(newval);
874                 set_bit_vector_bit(XBIT_VECTOR(array), idx, !ZEROP(newval));
875         } else if (STRINGP(array)) {
876                 CHECK_CHAR_COERCE_INT(newval);
877                 set_string_char(XSTRING(array), idx, XCHAR(newval));
878                 bump_string_modiff(array);
879         } else {
880                 array = wrong_type_argument(Qarrayp, array);
881                 goto retry;
882         }
883
884         return newval;
885
886 range_error:
887         args_out_of_range(array, index_);
888         return Qnil;            /* not reached */
889 }
890 \f
891 /**********************************************************************/
892 /*                       Arithmetic functions                         */
893 /**********************************************************************/
894 typedef struct {
895         int int_p;
896         union {
897                 EMACS_INT ival;
898                 double dval;
899         } c;
900 } int_or_double;
901
902 #ifndef WITH_NUMBER_TYPES
903 static void
904 number_char_or_marker_to_int_or_double(Lisp_Object obj, int_or_double * p)
905 {
906       retry:
907         p->int_p = 1;
908         if (INTP(obj))
909                 p->c.ival = XINT(obj);
910         else if (CHARP(obj))
911                 p->c.ival = XCHAR(obj);
912         else if (MARKERP(obj))
913                 p->c.ival = marker_position(obj);
914 #ifdef HAVE_FPFLOAT
915         else if (FLOATP(obj))
916                 p->c.dval = XFLOAT_DATA(obj), p->int_p = 0;
917 #endif
918         else {
919                 obj = wrong_type_argument(Qnumber_char_or_marker_p, obj);
920                 goto retry;
921         }
922 }
923
924 static double number_char_or_marker_to_double(Lisp_Object obj)
925 {
926       retry:
927         if (INTP(obj))
928                 return (double)XINT(obj);
929         else if (CHARP(obj))
930                 return (double)XCHAR(obj);
931         else if (MARKERP(obj))
932                 return (double)marker_position(obj);
933 #ifdef HAVE_FPFLOAT
934         else if (FLOATP(obj))
935                 return XFLOAT_DATA(obj);
936 #endif
937         else {
938                 obj = wrong_type_argument(Qnumber_char_or_marker_p, obj);
939                 goto retry;
940         }
941 }
942 #endif
943
944 static EMACS_INT integer_char_or_marker_to_int(Lisp_Object obj)
945 {
946       retry:
947         if (INTP(obj))
948                 return XINT(obj);
949         else if (CHARP(obj))
950                 return XCHAR(obj);
951         else if (MARKERP(obj))
952                 return marker_position(obj);
953         else {
954                 obj = wrong_type_argument(Qinteger_char_or_marker_p, obj);
955                 goto retry;
956         }
957 }
958
959 \f
960 /* Convert between a 32-bit value and a cons of two 16-bit values.
961    This is used to pass 32-bit integers to and from the user.
962    Use time_to_lisp() and lisp_to_time() for time values.
963
964    If you're thinking of using this to store a pointer into a Lisp Object
965    for internal purposes (such as when calling record_unwind_protect()),
966    try using make_opaque_ptr()/get_opaque_ptr() instead. */
967 Lisp_Object word_to_lisp(unsigned int item)
968 {
969         return Fcons(make_int(item >> 16), make_int(item & 0xffff));
970 }
971
972 unsigned int lisp_to_word(Lisp_Object item)
973 {
974         if (INTP(item))
975                 return XINT(item);
976         else {
977                 Lisp_Object top = Fcar(item);
978                 Lisp_Object bot = Fcdr(item);
979                 CHECK_INT(top);
980                 CHECK_INT(bot);
981                 return (XINT(top) << 16) | (XINT(bot) & 0xffff);
982         }
983 }
984 \f
985 DEFUN("number-to-string", Fnumber_to_string, 1, 1, 0,   /*
986 Convert NUMBER to a string by printing it in decimal.
987 Uses a minus sign if negative.
988 NUMBER may be an integer or a floating point number.
989 */
990       (number))
991 {
992         char buffer[VALBITS];
993
994 #ifdef WITH_NUMBER_TYPES
995         CHECK_NUMBER(number);
996 #else
997         CHECK_INT_OR_FLOAT(number);
998 #endif
999
1000 #ifdef HAVE_FPFLOAT
1001         if (FLOATP(number)) {
1002                 char pigbuf[350];       /* see comments in float_to_string */
1003
1004                 float_to_string(pigbuf, XFLOAT_DATA(number), sizeof(pigbuf));
1005                 return build_string(pigbuf);
1006         }
1007 #endif  /* HAVE_FPFLOAT */
1008 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1009         if (BIGZP(number)) {
1010                 char *str = bigz_to_string(XBIGZ_DATA(number), 10);
1011                 Lisp_Object retval = build_string(str);
1012                 xfree(str);
1013                 return retval;
1014         }
1015 #endif  /* HAVE_MPZ */
1016 #if defined HAVE_MPQ && defined WITH_GMP
1017         if (BIGQP(number)) {
1018                 char *str = (char *)bigq_to_string(XBIGQ_DATA(number), 10);
1019                 Lisp_Object retval = build_string(str);
1020                 xfree(str);
1021                 return retval;
1022         }
1023 #endif  /* HAVE_MPQ */
1024 #if defined HAVE_MPF && defined WITH_GMP
1025         if (BIGFP(number)) {
1026                 char *str = (char *)bigf_to_string(XBIGF_DATA(number), 10);
1027                 Lisp_Object retval = build_string(str);
1028                 xfree(str);
1029                 return retval;
1030         }
1031 #endif  /* HAVE_MPF */
1032 #if defined HAVE_MPFR && defined WITH_MPFR
1033         if (BIGFRP(number)) {
1034                 char *str = (char*)bigfr_to_string(XBIGFR_DATA(number), 10);
1035                 Lisp_Object retval = build_string(str);
1036                 xfree(str);
1037                 return retval;
1038         }
1039 #endif  /* HAVE_MPFR */
1040 #if defined HAVE_PSEUG && defined WITH_PSEUG
1041         if (BIGGP(number)) {
1042                 char *str = (char *)bigg_to_string(XBIGG_DATA(number), 10);
1043                 Lisp_Object retval = build_string(str);
1044                 xfree(str);
1045                 return retval;
1046         }
1047 #endif  /* HAVE_PSEUG */
1048 #if defined HAVE_MPC && defined WITH_MPC ||     \
1049         defined HAVE_PSEUC && defined WITH_PSEUC
1050         if (BIGCP(number)) {
1051                 char *str = (char *)bigc_to_string(XBIGC_DATA(number), 10);
1052                 Lisp_Object retval = build_string(str);
1053                 xfree(str);
1054                 return retval;
1055         }
1056 #endif  /* HAVE_MPC */
1057 #if defined HAVE_QUATERN && defined WITH_QUATERN
1058         if (QUATERNP(number)) {
1059                 char *str = (char*)quatern_to_string(XQUATERN_DATA(number), 10);
1060                 Lisp_Object retval = build_string(str);
1061                 xfree(str);
1062                 return retval;
1063         }
1064 #endif  /* HAVE_QUATERN */
1065         if (INDEFP(number)) {
1066                 char *str = (char *)indef_to_string(XINDEF_DATA(number));
1067                 Lisp_Object retval = build_string(str);
1068                 xfree(str);
1069                 return retval;
1070         }
1071
1072         long_to_string(buffer, XINT(number), sizeof(buffer));
1073         return build_string(buffer);
1074 }
1075
1076 #if !defined HAVE_MPZ || !(defined WITH_GMP || defined WITH_MP)
1077 static int digit_to_number(int character, int base)
1078 {
1079         /* Assumes ASCII */
1080         int digit = ((character >= '0' && character <= '9') ? character - '0' :
1081                      (character >= 'a'
1082                       && character <=
1083                       'z') ? character - 'a' + 10 : (character >= 'A'
1084                                                      && character <=
1085                                                      'Z') ? character - 'A' +
1086                      10 : -1);
1087
1088         return digit >= base ? -1 : digit;
1089 }
1090 #endif  /* HAVE_MPZ */
1091
1092 DEFUN("string-to-number", Fstring_to_number, 1, 2, 0,   /*
1093 Convert STRING to a number by parsing it as a number in base BASE.
1094 This parses both integers and floating point numbers.
1095 It ignores leading spaces and tabs.
1096
1097 If BASE is nil or omitted, base 10 is used.
1098 BASE must be an integer between 2 and 16 (inclusive).
1099 Floating point numbers always use base 10.
1100
1101 If STRING is a float, the variable `read-real-as' decides how to
1102 interpret that float.
1103 */
1104       (string, base))
1105 {
1106         char *p;
1107         int b;
1108
1109         CHECK_STRING(string);
1110
1111         if (NILP(base))
1112                 b = 10;
1113         else {
1114                 CHECK_INT(base);
1115                 b = XINT(base);
1116                 check_int_range(b, 2, 16);
1117         }
1118
1119         p = (char *)XSTRING_DATA(string);
1120
1121         /* Skip any whitespace at the front of the number.  Some versions of
1122            atoi do this anyway, so we might as well make Emacs lisp consistent.  */
1123         while (*p == ' ' || *p == '\t')
1124                 p++;
1125
1126 #if defined HAVE_PSEUG && defined WITH_PSEUG
1127         if (isgaussian_string(p))
1128                 return read_bigg_string(p);
1129 #endif  /* HAVE_PSEUG */
1130
1131 #if defined HAVE_MPC && defined WITH_MPC ||     \
1132         defined HAVE_PSEUC && defined WITH_PSEUC
1133         if (isbigc_string(p))
1134                 return read_bigc_string(p);
1135 #endif  /* HAVE_MPC */
1136
1137 #if defined HAVE_MPFR && defined WITH_MPFR
1138         if (isfloat_string(p) && b == 10) {
1139                 if (!(default_real_precision) || Vread_real_as != Qbigfr)
1140                         return make_float(str_to_fpfloat((const char*)p));
1141                 else
1142                         return read_bigfr_string(p);
1143         }
1144 #elif defined HAVE_MPF && defined WITH_GMP
1145         if (isfloat_string(p) && b == 10) {
1146                 if (!(default_real_precision) || Vread_real_as != Qbigf)
1147                         return make_float(str_to_fpfloat((const char*)p));
1148                 else
1149                         return read_bigf_string(p);
1150         }
1151 #elif defined HAVE_FPFLOAT
1152         if (isfloat_string(p) && b == 10)
1153                 return make_float(str_to_fpfloat(p));
1154 #endif  /* HAVE_MPFR || HAVE_MPFR || HAVE_FPFLOAT */
1155
1156         if (ase_resc_elm_pred_f && ase_resc_elm_f &&
1157             ase_resc_elm_pred_f(p))
1158                 return ase_resc_elm_f(p);
1159
1160 #if defined HAVE_QUATERN && defined WITH_QUATERN
1161         if (isquatern_string(p))
1162                 return read_quatern_string(p);
1163 #endif  /* HAVE_QUATERN */
1164
1165 #if defined HAVE_MPQ && defined WITH_GMP
1166         if (strchr (p, '/') != NULL) {
1167 #if 0
1168                 return read_bigq_string(p);
1169 #else
1170                 /* do we even need fractions in different bases? */
1171                 Bufbyte *end, save;
1172                 bigq bq;
1173                 Lisp_Object result;
1174                 
1175                 if (*p == '+')
1176                         p++;
1177                 
1178                 end = (Bufbyte*)p;
1179                 if (*end == '-')
1180                         end++;
1181                 while ((*end >= '0' && *end <= '9') ||
1182                        (b > 10 && *end >= 'a' && *end <= 'a' + b - 11) ||
1183                        (b > 10 && *end >= 'A' && *end <= 'A' + b - 11))
1184                         end++;
1185                 if (*end == '/') {
1186                         end++;
1187                         if (*end == '-')
1188                                 end++;
1189                         while ((*end >= '0' && *end <= '9') ||
1190                                (b > 10 && *end >= 'a' &&
1191                                 *end <= 'a' + b - 11) ||
1192                                (b > 10 && *end >= 'A' &&
1193                                 *end <= 'A' + b - 11))
1194                                 end++;
1195                 }
1196                 save = *end;
1197                 *end = '\0';
1198
1199                 bigq_init(bq);
1200                 
1201                 bigq_set_string(bq, (const char *) p, b);
1202                 *end = save;
1203                 bigq_canonicalize(bq);
1204
1205                 result = make_bigq_bq(bq);
1206
1207                 bigq_fini(bq);
1208                 return result;
1209 #endif  /* 1 */
1210         }
1211 #endif /* HAVE_MPQ */
1212
1213 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1214         {
1215                 Bufbyte *end, save;
1216                 Lisp_Object retval;
1217                 
1218                 if (*p == '+')
1219                         p++;
1220                 end = (Bufbyte*)p;
1221                 if (*end == '-')
1222                         end++;
1223                 while ((*end >= '0' && *end <= '9') ||
1224                        (b > 10 && *end >= 'a' && *end <= 'a' + b - 11) ||
1225                        (b > 10 && *end >= 'A' && *end <= 'A' + b - 11))
1226                         end++;
1227                 save = *end;
1228                 *end = '\0';
1229                 if (*p == '\0')
1230                         retval = make_int(0);
1231                 else {
1232                         bigz bz;
1233                         bigz_init(bz);
1234                         bigz_set_string(bz, (const char *)p, b);
1235                         retval = ent_mpz_downgrade_maybe(bz);
1236                         bigz_fini(bz);
1237                 }
1238                 *end = save;
1239                 return retval;
1240         }
1241
1242 #else  /* !HAVE_MPZ */
1243
1244         if (b == 10) {
1245                 /* Use the system-provided functions for base 10. */
1246 #if   SIZEOF_EMACS_INT == SIZEOF_INT
1247                 return make_int(atoi(p));
1248 #elif SIZEOF_EMACS_INT == SIZEOF_LONG
1249                 return make_int(atol(p));
1250 #elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG_INT
1251                 return make_int(atoll(p));
1252 #endif
1253         } else {
1254                 int negative = 1;
1255                 EMACS_INT v = 0;
1256
1257                 if (*p == '-') {
1258                         negative = -1;
1259                         p++;
1260                 } else if (*p == '+')
1261                         p++;
1262                 while (1) {
1263                         int digit = digit_to_number(*p++, b);
1264                         if (digit < 0)
1265                                 break;
1266                         v = v * b + digit;
1267                 }
1268                 return make_int(negative * v);
1269         }
1270 #endif /* HAVE_MPZ */
1271 }
1272
1273 \f
1274 DEFUN("logand", Flogand, 0, MANY, 0,    /*
1275 Return bitwise-and of all the arguments.
1276 Arguments may be integers, or markers or characters converted to integers.
1277 */
1278       (int nargs, Lisp_Object * args))
1279 {
1280 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1281         REGISTER int i;
1282         Lisp_Object result, other;
1283         ase_object_type_t nt1, nt2;
1284
1285         if (nargs == 0)
1286                 return make_int(~0);
1287
1288         result = args[0];
1289         if (!(INTEGERP(result) || CHARP(result) || MARKERP(result)))
1290                 result = wrong_type_argument(Qintegerp, result);
1291
1292         if (nargs == 1)
1293                 return make_int(ent_int(result));
1294
1295         for (i = 1; i < nargs; i++) {
1296                 other = args[i];
1297                 if (!(INTEGERP(other) || CHARP(other) || MARKERP(other)))
1298                         other = wrong_type_argument(Qintegerp, other);
1299
1300                 nt1 = ase_optable_index(result);
1301                 nt2 = ase_optable_index(other);
1302
1303                 if (nt1 == INT_T && nt2 == INT_T) {
1304                         result = make_int(ent_int(result) & ent_int(other));
1305                 } else if (nt1 == INT_T && nt2 == BIGZ_T) {
1306                         bigz_set_long(ent_scratch_bigz, ent_int(result));
1307                         bigz_and(ent_scratch_bigz,
1308                                  ent_scratch_bigz,
1309                                  XBIGZ_DATA(other));
1310                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1311                 } else if (nt1 == BIGZ_T && nt2 == INT_T) {
1312                         bigz_set_long(ent_scratch_bigz, ent_int(other));
1313                         bigz_and(ent_scratch_bigz,
1314                                  XBIGZ_DATA(result),
1315                                  ent_scratch_bigz);
1316                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1317                 } else if (nt1 == BIGZ_T && nt2 == BIGZ_T) {
1318                         bigz_and(ent_scratch_bigz,
1319                                  XBIGZ_DATA(result),
1320                                  XBIGZ_DATA(other));
1321                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1322                 }
1323         }
1324         return result;
1325
1326 #else /* !HAVE_MPZ */
1327         EMACS_INT bits = ~0;
1328         Lisp_Object *args_end = args + nargs;
1329
1330         while (args < args_end)
1331                 bits &= integer_char_or_marker_to_int(*args++);
1332
1333         return make_int(bits);
1334 #endif  /* HAVE_MPZ */
1335 }
1336
1337 DEFUN("logior", Flogior, 0, MANY, 0,    /*
1338 Return bitwise-or of all the arguments.
1339 Arguments may be integers, or markers or characters converted to integers.
1340 */
1341       (int nargs, Lisp_Object * args))
1342 {
1343 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1344         REGISTER int i;
1345         Lisp_Object result, other;
1346         ase_object_type_t nt1, nt2;
1347
1348         if (nargs == 0)
1349                 return make_int(0);
1350
1351         result = args[0];
1352         if (!(INTEGERP(result) || CHARP(result) || MARKERP(result)))
1353                 result = wrong_type_argument(Qintegerp, result);
1354
1355         if (nargs == 1)
1356                 return make_int(ent_int(result));
1357
1358         for (i = 1; i < nargs; i++) {
1359                 other = args[i];
1360                 if (!(INTEGERP(other) || CHARP(other) || MARKERP(other)))
1361                         other = wrong_type_argument(Qintegerp, other);
1362
1363                 nt1 = ase_optable_index(result);
1364                 nt2 = ase_optable_index(other);
1365
1366                 if (nt1 == INT_T && nt2 == INT_T) {
1367                         result = make_int(ent_int(result) | ent_int(other));
1368                 } else if (nt1 == INT_T && nt2 == BIGZ_T) {
1369                         bigz_set_long(ent_scratch_bigz, ent_int(result));
1370                         bigz_ior(ent_scratch_bigz,
1371                                  ent_scratch_bigz,
1372                                  XBIGZ_DATA(other));
1373                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1374                 } else if (nt1 == BIGZ_T && nt2 == INT_T) {
1375                         bigz_set_long(ent_scratch_bigz, ent_int(other));
1376                         bigz_ior(ent_scratch_bigz,
1377                                  XBIGZ_DATA(result),
1378                                  ent_scratch_bigz);
1379                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1380                 } else if (nt1 == BIGZ_T && nt2 == BIGZ_T) {
1381                         bigz_ior(ent_scratch_bigz,
1382                                  XBIGZ_DATA(result),
1383                                  XBIGZ_DATA(other));
1384                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1385                 }
1386         }
1387         return result;
1388
1389 #else /* !HAVE_MPZ */
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 #endif  /* HAVE_MPZ */
1399 }
1400
1401 DEFUN("logxor", Flogxor, 0, MANY, 0,    /*
1402 Return bitwise-exclusive-or of all the arguments.
1403 Arguments may be integers, or markers or characters converted to integers.
1404 */
1405       (int nargs, Lisp_Object * args))
1406 {
1407 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1408         REGISTER int i;
1409         Lisp_Object result, other;
1410         ase_object_type_t nt1, nt2;
1411
1412         if (nargs == 0)
1413                 return make_int(0);
1414
1415         result = args[0];
1416         if (!(INTEGERP(result) || CHARP(result) || MARKERP(result)))
1417                 result = wrong_type_argument(Qintegerp, result);
1418
1419         if (nargs == 1)
1420                 return make_int(ent_int(result));
1421
1422         for (i = 1; i < nargs; i++) {
1423                 other = args[i];
1424                 if (!(INTEGERP(other) || CHARP(other) || MARKERP(other)))
1425                         other = wrong_type_argument(Qintegerp, other);
1426
1427                 nt1 = ase_optable_index(result);
1428                 nt2 = ase_optable_index(other);
1429
1430                 if (nt1 == INT_T && nt2 == INT_T) {
1431                         result = make_int(ent_int(result) ^ ent_int(other));
1432                 } else if (nt1 == INT_T && nt2 == BIGZ_T) {
1433                         bigz_set_long(ent_scratch_bigz, ent_int(result));
1434                         bigz_xor(ent_scratch_bigz,
1435                                  ent_scratch_bigz,
1436                                  XBIGZ_DATA(other));
1437                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1438                 } else if (nt1 == BIGZ_T && nt2 == INT_T) {
1439                         bigz_set_long(ent_scratch_bigz, ent_int(other));
1440                         bigz_xor(ent_scratch_bigz,
1441                                  XBIGZ_DATA(result),
1442                                  ent_scratch_bigz);
1443                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1444                 } else if (nt1 == BIGZ_T && nt2 == BIGZ_T) {
1445                         bigz_xor(ent_scratch_bigz,
1446                                  XBIGZ_DATA(result),
1447                                  XBIGZ_DATA(other));
1448                         result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1449                 }
1450         }
1451         return result;
1452
1453 #else  /* !HAVE_MPZ */
1454
1455         EMACS_INT bits = 0;
1456         Lisp_Object *args_end = args + nargs;
1457
1458         while (args < args_end)
1459                 bits ^= integer_char_or_marker_to_int(*args++);
1460
1461         return make_int(bits);
1462 #endif  /* HAVE_MPZ */
1463 }
1464
1465 DEFUN("lognot", Flognot, 1, 1, 0,       /*
1466 Return the bitwise complement of NUMBER.
1467 NUMBER may be an integer, marker or character converted to integer.
1468 */
1469       (number))
1470 {
1471 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1472         if (BIGZP(number)) {
1473                 bigz bz;
1474                 Lisp_Object result;
1475
1476                 bigz_init(bz);
1477
1478                 bigz_not(bz, XBIGZ_DATA(number));
1479                 result = make_bigz_bz(bz);
1480
1481                 bigz_fini(bz);
1482                 return result;
1483         } else {
1484                 return make_int(~integer_char_or_marker_to_int(number));
1485         }
1486 #else  /* HAVE_MPZ */
1487         return make_int(~integer_char_or_marker_to_int(number));
1488 #endif  /* HAVE_MPZ */
1489 }
1490
1491 /* Note, ANSI *requires* the presence of the fmod() library routine.
1492    If your system doesn't have it, complain to your vendor, because
1493    that is a bug. */
1494
1495 #ifndef HAVE_FMOD
1496 double fmod(double f1, double f2)
1497 {
1498         if (f2 < 0.0)
1499                 f2 = -f2;
1500         return f1 - f2 * floor(f1 / f2);
1501 }
1502 #endif                          /* ! HAVE_FMOD */
1503
1504 DEFUN("ash", Fash, 2, 2, 0,     /*
1505 Return VALUE with its bits shifted left by COUNT.
1506 If COUNT is negative, shifting is actually to the right.
1507 In this case, the sign bit is duplicated.
1508 */
1509       (value, count))
1510 {
1511         CHECK_INT_COERCE_CHAR(value);
1512         CONCHECK_INT(count);
1513
1514         return make_int(XINT(count) > 0 ?
1515                         XINT(value) << XINT(count) :
1516                         XINT(value) >> -XINT(count));
1517 }
1518
1519 DEFUN("lsh", Flsh, 2, 2, 0,     /*
1520 Return VALUE with its bits shifted left by COUNT.
1521 If COUNT is negative, shifting is actually to the right.
1522 In this case, zeros are shifted in on the left.
1523 */
1524       (value, count))
1525 {
1526 #if defined HAVE_MPZ && (defined WITH_GMP || defined WITH_MP)
1527         Lisp_Object result;
1528
1529         result = Qzero;
1530         value = Fcoerce_number(value, Qinteger, Qnil);
1531         CONCHECK_INT(count);
1532
1533         switch (ase_optable_index(value)) {
1534         case INT_T:
1535                 if (XREALINT(count) <= 0)
1536                         return make_int(XREALINT(value) >> -XREALINT(count));
1537                 /* Use bignums to avoid overflow */
1538                 bigz_set_long(ent_scratch_bigz, XREALINT(value));
1539                 bigz_lshift(ent_scratch_bigz,
1540                             ent_scratch_bigz, XREALINT(count));
1541
1542                 result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1543                 break;
1544         case BIGZ_T:
1545                 if (XREALINT(count) <= 0) {
1546                         bigz_rshift(ent_scratch_bigz,
1547                                     XBIGZ_DATA(value),
1548                                     -XREALINT(count));
1549                 } else {
1550                         bigz_lshift(ent_scratch_bigz,
1551                                     XBIGZ_DATA(value),
1552                                     XREALINT(count));
1553                 }
1554                 result = ent_mpz_downgrade_maybe(ent_scratch_bigz);
1555                 break;
1556         case INDEF_T:
1557                 if (COMPARABLE_INDEF_P(value))
1558                         result = value;
1559                 else if (COMPARABLE_INDEF_P(count) &&
1560                          XINDEF_DATA(count) == POS_INFINITY)
1561                         result = make_indef(POS_INFINITY);
1562                 else if (COMPARABLE_INDEF_P(count) &&
1563                          XINDEF_DATA(count) == NEG_INFINITY)
1564                         result = Qzero;
1565                 break;
1566         default:
1567                 result = Qzero;
1568         }
1569
1570         return result;
1571
1572 #else  /* HAVE_MPZ */
1573         CHECK_INT_COERCE_CHAR(value);
1574         CONCHECK_INT(count);
1575
1576         return make_int(XINT(count) > 0 ?
1577                         XUINT(value) << XINT(count) :
1578                         XUINT(value) >> -XINT(count));
1579 #endif  /* HAVE_MPZ */
1580 }
1581
1582 /* Number theoretic functions */
1583
1584 #if defined WITH_GMP && defined HAVE_MPZ
1585
1586 /* why do we put this cruft here, actually? Is not it better to have a separate
1587  * number-fns.c or the like?
1588  */
1589
1590 DEFUN("primep", Fprimep, 1, 2, 0,       /*
1591 Return `nil' if NUMBER is known to be composite, return `t' if 
1592 NUMBER is definitely prime and return 'probably-prime if 
1593 NUMBER seems to be prime but it is not certain.
1594
1595 If optional argument CERTAINTY-THRESHOLD is non-nil, it should be a
1596 natural number to indicate how many probabilistic primality tests must
1597 be passed in order to have certainty about the primality of NUMBER.
1598 The default is 8.
1599 */
1600       (number, certainty_threshold))
1601 {
1602         Lisp_Object bznumber;
1603         int result;
1604
1605         if (INDEFP(number))
1606                 return Qnil;
1607
1608         bznumber = Fcoerce_number(number, Qbigz, Qnil);
1609         if (NILP(certainty_threshold))
1610                 result = mpz_probab_prime_p(XBIGZ_DATA(bznumber), 8);
1611         else if (NATNUMP(certainty_threshold))
1612                 result = mpz_probab_prime_p(XBIGZ_DATA(bznumber),
1613                                             XINT(certainty_threshold));
1614         else
1615                 result = wrong_type_argument(Qnatnump, certainty_threshold);
1616
1617         if (result == 0)
1618                 return Qnil;
1619         else if (result == 1)
1620                 return intern("probably-prime");
1621         else if (result == 2)
1622                 return Qt;
1623         else
1624                 return intern("unknown-test-result");
1625 }
1626
1627 DEFUN("next-prime", Fnext_prime, 1, 1, 0,       /*
1628 Return the next prime number greater than NUMBER.
1629 */
1630       (number))
1631 {
1632         Lisp_Object bznumber;
1633
1634         if (INDEFP(number)) {
1635                 return number;
1636         }
1637
1638         bznumber = Fcoerce_number(number, Qbigz, Qnil);
1639         mpz_nextprime(ent_scratch_bigz, XBIGZ_DATA(bznumber));
1640         return ent_mpz_downgrade_maybe(ent_scratch_bigz);
1641 }
1642
1643
1644 DEFUN("factorial", Ffactorial, 1, 1, 0, /*
1645 Return the factorial of NUMBER.
1646 */
1647       (number))
1648 {
1649         bigz bz;
1650         Lisp_Object result;
1651
1652         if (INDEFP(number) &&
1653             XINDEF_DATA(number) == POS_INFINITY)
1654                 return number;
1655
1656         if (!INTP(number)) {
1657                 number = wrong_type_argument(Qintegerp, number);
1658                 return Qzero;
1659         }
1660         if (!NATNUMP(number)) {
1661                 number = wrong_type_argument(Qnatnump, number);
1662                 return Qzero;
1663         }
1664
1665         bigz_init(bz);
1666
1667         mpz_fac_ui(bz, XUINT(number));
1668         result = make_bigz_bz(bz);
1669
1670         bigz_fini(bz);
1671         return result;
1672 }
1673
1674 DEFUN("binomial-coefficient", Fbinomial_coefficient, 2, 2, 0, /*
1675 Return the binomial coefficient, N over K.
1676 */
1677       (n, k))
1678 {
1679         bigz bz;
1680         unsigned long kui;
1681         Lisp_Object result;
1682
1683         CHECK_INTEGER(n);
1684         CHECK_INTEGER(k);
1685
1686         if (NILP(Fnonnegativep(k)))
1687                 return wrong_type_argument(Qnonnegativep, k);
1688         else if (INTP(k))
1689                 kui = XINT(k);
1690         else if (BIGZP(k))
1691                 kui = bigz_to_ulong(XBIGZ_DATA(k));
1692         else
1693                 return wrong_type_argument(Qintegerp, k);
1694
1695         n = Fcoerce_number(n, Qbigz, Qnil);
1696
1697         bigz_init(bz);
1698         mpz_bin_ui(bz, XBIGZ_DATA(n), kui);
1699         result = make_bigz_bz(bz);
1700
1701         bigz_fini(bz);
1702         return result;
1703 }
1704
1705 DEFUN("remove-factor", Fremove_factor, 2, 2, 0, /*
1706 Remove all occurences of FACTOR in NUMBER and return a cons cell
1707 with NUMBER divided by a maximal power of FACTOR in the car and
1708 the exponent in the cdr.
1709 FACTOR must be non-negative and greater than 1.
1710 */
1711       (factor, number))
1712 {
1713         Lisp_Object bznumber, bzfactor;
1714         bigz bz;
1715         Lisp_Object result;
1716         unsigned long occur;
1717
1718         if (INDEFP(factor) && INDEFP(number)) {
1719                 if (XINDEF_DATA(factor) == POS_INFINITY)
1720                         return Fcons(factor, factor);
1721                 else
1722                         return wrong_type_argument(Qnonnegativep, factor);
1723         }
1724         if (INDEFP(factor)) {
1725                 if (XINDEF_DATA(factor) == POS_INFINITY)
1726                         return Fcons(number, Qzero);
1727                 else
1728                         return wrong_type_argument(Qnonnegativep, factor);
1729         }
1730         if (INDEFP(number)) {
1731                 if (INFINITYP(number))
1732                         return Fcons(number, make_indef(POS_INFINITY));
1733                 else
1734                         return wrong_type_argument(Qnumberp, number);
1735         }
1736
1737         bigz_init(bz);
1738
1739         bznumber = Fcoerce_number(number, Qbigz, Qnil);
1740         bzfactor = Fcoerce_number(factor, Qbigz, Qnil);
1741
1742         bigz_set_long(bz, 1L);
1743         if (bigz_eql(XBIGZ_DATA(bzfactor), bz)) {
1744                 /* factor is one, which is always in a prime decomposition */
1745                 bigz_fini(bz);
1746                 return Fcons(bznumber, make_indef(POS_INFINITY));
1747         }
1748         bigz_set_long(bz, -1L);
1749         if (bigz_eql(XBIGZ_DATA(bzfactor), bz)) {
1750                 /* factor is -1, which is always in a prime decomposition
1751                  * (it is a unit), but as such it occurs only pairwise, that's
1752                  * why we return 0 as exponent here
1753                  */
1754                 bigz_fini(bz);
1755                 return Fcons(bznumber, Qzero);
1756         }
1757         bigz_set_long(bz, 0L);
1758         if (bigz_eql(XBIGZ_DATA(bzfactor), bz)) {
1759                 /* factor is zero, which is never in a prime decomposition */
1760                 bigz_fini(bz);
1761                 return Fcons(bznumber, Qzero);
1762         }
1763         if (bigz_lt(XBIGZ_DATA(bzfactor), bz)) {
1764                 /* factor is negative, which is bad if number is positive */
1765                 bigz_neg(XBIGZ_DATA(bzfactor), XBIGZ_DATA(bzfactor));
1766                 occur = mpz_remove(bz, XBIGZ_DATA(bznumber),
1767                                    XBIGZ_DATA(bzfactor));
1768                 /* negate the result, iff the exponent is odd */
1769                 if ((occur % 2) != 0)
1770                         bigz_neg(bz, bz);
1771                 result = make_bigz_bz(bz);
1772         } else {
1773                 occur = mpz_remove(bz,
1774                                    XBIGZ_DATA(bznumber),
1775                                    XBIGZ_DATA(bzfactor));
1776                 result = make_bigz_bz(bz);
1777         }
1778
1779         bigz_fini(bz);
1780         return Fcons(result, make_integer((signed long)occur));
1781 }
1782
1783 DEFUN("fibonacci", Ffibonacci, 1, 1, 0, /*
1784 Return the NUMBERth Fibonacci number.
1785 To compute both, the NUMBERth and (NUMBER-1)th Fibonacci
1786 number use `fibonacci2' instead.
1787 */
1788       (number))
1789 {
1790         bigz bz;
1791         unsigned long n;
1792         Lisp_Object result;
1793
1794         CHECK_INTEGER(number);
1795
1796         if (NILP(Fnonnegativep(number)))
1797                 return wrong_type_argument(Qnonnegativep, number);
1798         else if (INTP(number))
1799                 n = XINT(number);
1800         else if (BIGZP(number))
1801                 n = bigz_to_ulong(XBIGZ_DATA(number));
1802         else
1803                 return wrong_type_argument(Qintegerp, number);
1804
1805         bigz_init(bz);
1806         mpz_fib_ui(bz, n);
1807         result = make_bigz_bz(bz);
1808
1809         bigz_fini(bz);
1810         return result;
1811 }
1812
1813 DEFUN("fibonacci2", Ffibonacci2, 1, 1, 0, /*
1814 Return a cons with the NUMBERth and (NUMBER-1)th Fibonacci number.
1815 To compute a series of Fibonacci numbers starting at index
1816 NUMBER, use this function and recursively compute the rest.
1817 */
1818       (number))
1819 {
1820         bigz bzn, bznsub1;
1821         unsigned long n;
1822         Lisp_Object result;
1823
1824         CHECK_INTEGER(number);
1825
1826         if (NILP(Fnonnegativep(number)))
1827                 return wrong_type_argument(Qnonnegativep, number);
1828         else if (INTP(number))
1829                 n = XINT(number);
1830         else if (BIGZP(number))
1831                 n = bigz_to_ulong(XBIGZ_DATA(number));
1832         else
1833                 return wrong_type_argument(Qintegerp, number);
1834
1835         bigz_init(bzn);
1836         bigz_init(bznsub1);
1837         mpz_fib2_ui(bzn, bznsub1, n);
1838         result = Fcons(make_bigz_bz(bzn),
1839                        make_bigz_bz(bznsub1));
1840
1841         bigz_fini(bzn);
1842         bigz_fini(bznsub1);
1843         return result;
1844 }
1845
1846 DEFUN("lucas", Flucas, 1, 1, 0, /*
1847 Return the NUMBERth Lucas number.
1848 To compute both, the NUMBERth and (NUMBER-1)th Lucas
1849 number use `lucas2' instead.
1850 */
1851       (number))
1852 {
1853         bigz bz;
1854         unsigned long n;
1855         Lisp_Object result;
1856
1857         CHECK_INTEGER(number);
1858
1859         if (NILP(Fnonnegativep(number)))
1860                 return wrong_type_argument(Qnonnegativep, number);
1861         else if (INTP(number))
1862                 n = XINT(number);
1863         else if (BIGZP(number))
1864                 n = bigz_to_ulong(XBIGZ_DATA(number));
1865         else
1866                 return wrong_type_argument(Qintegerp, number);
1867
1868         bigz_init(bz);
1869         mpz_lucnum_ui(bz, n);
1870         result = make_bigz_bz(bz);
1871
1872         bigz_fini(bz);
1873         return result;
1874 }
1875
1876 DEFUN("lucas2", Flucas2, 1, 1, 0, /*
1877 Return a cons with the NUMBERth and (NUMBER-1)th Lucas number.
1878 To compute a series of Lucas numbers starting at index
1879 NUMBER, use this function and recursively compute the rest.
1880 */
1881       (number))
1882 {
1883         bigz bzn, bznsub1;
1884         unsigned long n;
1885         Lisp_Object result;
1886
1887         CHECK_INTEGER(number);
1888
1889         if (NILP(Fnonnegativep(number)))
1890                 return wrong_type_argument(Qnonnegativep, number);
1891         else if (INTP(number))
1892                 n = XINT(number);
1893         else if (BIGZP(number))
1894                 n = bigz_to_ulong(XBIGZ_DATA(number));
1895         else
1896                 return wrong_type_argument(Qintegerp, number);
1897
1898         bigz_init(bzn);
1899         bigz_init(bznsub1);
1900         mpz_lucnum2_ui(bzn, bznsub1, n);
1901         result = Fcons(make_bigz_bz(bzn),
1902                        make_bigz_bz(bznsub1));
1903
1904         bigz_fini(bzn);
1905         bigz_fini(bznsub1);
1906         return result;
1907 }
1908
1909 DEFUN("divisiblep", Fdivisiblep, 2, 2, 0, /*
1910 Return t if NUMBER is divisible by D, nil otherwise.
1911 */
1912       (number, d))
1913 {
1914         CHECK_INTEGER(number);
1915         CHECK_INTEGER(d);
1916
1917         number = Fcoerce_number(number, Qbigz, Qnil);
1918         if (INTP(d))
1919                 return mpz_divisible_ui_p(XBIGZ_DATA(number), XINT(d))
1920                         ? Qt : Qnil;
1921         else if (BIGZP(d))
1922                 return mpz_divisible_p(XBIGZ_DATA(number), XBIGZ_DATA(d))
1923                         ? Qt : Qnil;
1924         else
1925                 return wrong_type_argument(Qintegerp, d);
1926 }
1927
1928 DEFUN("congruentp", Fcongruentp, 3, 3, 0, /*
1929 Return t if NUMBER is congruent to C modulo M, nil otherwise.
1930 */
1931       (number, c, m))
1932 {
1933         CHECK_INTEGER(number);
1934         CHECK_INTEGER(c);
1935         CHECK_INTEGER(m);
1936
1937         number = Fcoerce_number(number, Qbigz, Qnil);
1938         if (INTP(c) && INTP(m))
1939                 return mpz_congruent_ui_p(XBIGZ_DATA(number), XINT(c), XINT(m))
1940                         ? Qt : Qnil;
1941         else {
1942                 c = Fcoerce_number(c, Qbigz, Qnil);
1943                 m = Fcoerce_number(m, Qbigz, Qnil);
1944                 return mpz_congruent_p(XBIGZ_DATA(number),
1945                                        XBIGZ_DATA(c), XBIGZ_DATA(m))
1946                         ? Qt : Qnil;
1947         }
1948 }
1949
1950 DEFUN("perfect-power-p", Fperfect_power_p, 1, 1, 0, /*
1951 Return t if NUMBER is a perfect power, nil otherwise.
1952 An integer NUMBER is said to be a perfect power if there 
1953 exist integers, a and b, such that a^b = NUMBER.
1954 */
1955       (number))
1956 {
1957         CHECK_INTEGER(number);
1958
1959         number = Fcoerce_number(number, Qbigz, Qnil);
1960
1961         return mpz_perfect_power_p(XBIGZ_DATA(number)) ? Qt : Qnil;
1962 }
1963
1964 DEFUN("perfect-square-p", Fperfect_square_p, 1, 1, 0, /*
1965 Return t if NUMBER is a perfect square, nil otherwise.
1966 An integer NUMBER is said to be a perfect square if there 
1967 exists an integer b such that b^2 = NUMBER.
1968 */
1969       (number))
1970 {
1971         CHECK_INTEGER(number);
1972
1973         number = Fcoerce_number(number, Qbigz, Qnil);
1974
1975         return mpz_perfect_square_p(XBIGZ_DATA(number)) ? Qt : Qnil;
1976 }
1977
1978 DEFUN("integral-sqrt", Fintegral_sqrt, 1, 1, 0, /*
1979 Return a cons with the integral square root of NUMBER
1980 in the car and the remainder in the cdr.
1981 An integral square root is a number b and a remainder c
1982 such that b*b + c = NUMBER.
1983 */
1984       (number))
1985 {
1986         bigz bzsqrt, bzrem;
1987         Lisp_Object result;
1988
1989         CHECK_INTEGER(number);
1990
1991         number = Fcoerce_number(number, Qbigz, Qnil);
1992
1993         bigz_init(bzsqrt);
1994         bigz_init(bzrem);
1995         mpz_sqrtrem(bzsqrt, bzrem, XBIGZ_DATA(number));
1996
1997         result = Fcons(make_bigz_bz(bzsqrt), make_bigz_bz(bzrem));
1998
1999         bigz_fini(bzsqrt);
2000         bigz_fini(bzrem);
2001         return result;
2002 }
2003
2004 #endif  /* WITH_GMP && HAVE_MPZ */
2005
2006 DEFUN("zero-divisor-p", Fzero_divisor_p, 1, 1, 0, /*
2007 Return t if NUMBER is a zero-divisor, nil otherwise.
2008 That is, if there exists another non-zero number B, such that
2009   NUMBER * B = 0
2010 */
2011       (number))
2012 {
2013         Lisp_Object result;
2014
2015         CHECK_NUMBER(number);
2016
2017         switch (ase_optable_index(number)) {
2018         default:
2019                 result = Qnil;
2020         }
2021         return result;
2022 }
2023
2024 #if defined WITH_ECM && defined HAVE_ECM &&     \
2025         defined HAVE_MPZ && defined WITH_GMP
2026 DEFUN("factorise", Ffactorise, 1, 3, 0, /*
2027 Return the factorisation of NUMBER.
2028 If optional arument B1 is non-nil, it should be a float used as
2029 stage 1 boundary.
2030 Second optional argument method can be 'ecm, 'p-1 'p+1.
2031 */
2032       (number, b1, method))
2033 {
2034         int status;
2035         unsigned long expt;
2036         long factor_l;
2037         bigz bz;
2038         bigz bznumber;
2039         Lisp_Object bzn;
2040         Lisp_Object result = Qnil;
2041         double sb1;
2042         ecm_params p;
2043
2044         bzn = Fcoerce_number(number, Qbigz, Qnil);
2045         bigz_init(bz);
2046
2047         bigz_init(bznumber);
2048         bigz_set(bznumber, XBIGZ_DATA(bzn));
2049
2050         if (NILP(b1))
2051                 sb1 = 200.0;
2052         else
2053                 sb1 = extract_float(b1);
2054
2055         ecm_init(p);
2056         if (0) {
2057         } else if (method == intern("p-1")) {
2058                 p->method = ECM_PM1;
2059         } else if (method == intern("p+1")) {
2060                 p->method = ECM_PP1;
2061         } else {
2062                 p->method = ECM_ECM;
2063         }
2064
2065         status = 1;
2066         while (status > 0) {
2067                 status = ecm_factor(bz, bznumber, sb1, p);
2068
2069                 factor_l = bigz_to_long(bz);
2070                 if (factor_l == 1 || factor_l == -1)
2071                         status = 0;
2072                 if (status > 0 && factor_l != 0) {
2073                         expt = mpz_remove(bznumber, bznumber, bz);
2074                         result = Fcons(Fcons(make_bigz_bz(bz),
2075                                              make_int(expt)),
2076                                        result);
2077                 }
2078         }
2079
2080         ecm_clear(p);
2081         bigz_fini(bznumber);
2082         bigz_fini(bz);
2083
2084         return result;
2085 }
2086 #endif  /* WITH_ECM && HAVE_ECM */
2087
2088 #if defined(WITH_GMP) && (defined(HAVE_MPZ) || defined(HAVE_MPQ))
2089 DEFUN("gcd", Fgcd, 0, MANY, 0,  /*
2090 Return the greatest common divisor of the arguments.
2091 */
2092       (int nargs, Lisp_Object *args))
2093 {
2094         REGISTER int i;
2095
2096         if (nargs == 0)
2097                 return Qzero;
2098         else if (nargs == 1)
2099                 return args[0];
2100         else {
2101                 bigz bz;
2102                 bigz bznum;
2103                 bigz bzden;
2104                 Lisp_Object bzn;
2105                 bigz_init(bz);
2106                 bigz_init(bznum);
2107                 bigz_init(bzden);
2108
2109                 bzn = args[0];
2110                 switch (ase_optable_index(bzn)) {
2111                 case INT_T:
2112                         bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2113                         bigz_set(bz, XBIGZ_DATA(bzn));
2114                         bigz_set_long(bzden, 1L);
2115                         break;
2116                 case BIGZ_T:
2117                         bigz_set(bz, XBIGZ_DATA(bzn));
2118                         bigz_set_long(bzden, 1L);
2119                         break;
2120                 case BIGQ_T:
2121                         bigz_set(bz, XBIGQ_NUMERATOR(bzn));
2122                         bigz_set(bzden, XBIGQ_DENOMINATOR(bzn));
2123                         break;
2124
2125                 /* no gcd defined for the rest */
2126                 default:
2127                         bigz_fini(bz);
2128                         bigz_fini(bznum);
2129                         bigz_fini(bzden);
2130                         return Qzero;
2131                         break;
2132                 }
2133
2134                 for (i = 1; i < nargs; i++) {
2135                         bzn = args[i];
2136
2137                         switch (ase_optable_index(bzn)) {
2138                         case INT_T:
2139                                 bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2140                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2141                                 break;
2142                         case BIGZ_T:
2143                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2144                                 break;
2145                         case BIGQ_T:
2146                                 bigz_mul(bzden, bzden, XBIGQ_DENOMINATOR(bzn));
2147                                 bigz_set(bznum, XBIGQ_NUMERATOR(bzn));
2148                                 break;
2149
2150                                 /* no gcd defined for the rest */
2151                         default:
2152                                 bigz_fini(bz);
2153                                 bigz_fini(bznum);
2154                                 bigz_fini(bzden);
2155                                 return Qzero;
2156                                 break;
2157                         }
2158
2159                         bigz_gcd(bz, bz, bznum);
2160                 }
2161                 if (bigz_fits_long_p(bzden) &&
2162                     bigz_to_long(bzden) == 1L) {
2163                         bzn = make_bigz_bz(bz);
2164                 } else {
2165                         bzn = make_bigq_bz(bz, bzden);
2166                 }
2167                 bigz_fini(bz);
2168                 bigz_fini(bznum);
2169                 bigz_fini(bzden);
2170                 return bzn;
2171         }
2172         /* NOT REACHED */
2173         return Qzero;
2174 }
2175
2176 DEFUN("xgcd", Fxgcd, 0, MANY, 0,        /*
2177 Return the extended gcd of the arguments.
2178 The result is a list of integers, where the car is the actual gcd
2179 and the cdr consists of coefficients, s1, ..., sn, such that
2180 s1*arg1 + s2*arg2 + ... + sn*argn = gcd.
2181 */
2182       (int nargs, Lisp_Object *args))
2183 {
2184         REGISTER int i, j;
2185
2186         if (nargs == 0)
2187                 return list1(Qzero);
2188         else if (nargs == 1)
2189                 return list2(args[0], make_int(1L));
2190         else {
2191                 bigz bz;
2192                 bigz bs;
2193                 bigz bt;
2194                 bigz bznum;
2195                 bigz bzden;
2196                 Lisp_Object bzn;
2197                 Lisp_Object *qargs = alloca_array(Lisp_Object, nargs+1);
2198                 bigz_init(bz);
2199                 bigz_init(bznum);
2200                 bigz_init(bzden);
2201                 bigz_init(bs);
2202                 bigz_init(bt);
2203
2204                 bzn = args[0];
2205                 switch (ase_optable_index(bzn)) {
2206                 case INT_T:
2207                         bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2208                         bigz_set(bz, XBIGZ_DATA(bzn));
2209                         bigz_set_long(bzden, 1L);
2210                         break;
2211                 case BIGZ_T:
2212                         bigz_set(bz, XBIGZ_DATA(bzn));
2213                         bigz_set_long(bzden, 1L);
2214                         break;
2215                 case BIGQ_T:
2216                         bigz_set(bz, XBIGQ_NUMERATOR(bzn));
2217                         bigz_set(bzden, XBIGQ_DENOMINATOR(bzn));
2218                         break;
2219
2220                 /* no gcd defined for the rest */
2221                 default:
2222                         bigz_fini(bz);
2223                         bigz_fini(bznum);
2224                         bigz_fini(bzden);
2225                         bigz_fini(bs);
2226                         bigz_fini(bt);
2227                         return list1(Qzero);
2228                         break;
2229                 }
2230
2231                 qargs[1] = make_bigz(1L);
2232                 for (i = 1; i < nargs; i++) {
2233                         bzn = args[i];
2234
2235                         switch (ase_optable_index(bzn)) {
2236                         case INT_T:
2237                                 bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2238                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2239                                 break;
2240                         case BIGZ_T:
2241                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2242                                 break;
2243                         /* multiply across fractions */
2244                         case BIGQ_T:
2245                                 bigz_set(bznum, XBIGQ_NUMERATOR(bzn));
2246                                 bigz_mul(bznum, bznum, bzden);
2247                                 bigz_mul(bzden, bzden, XBIGQ_DENOMINATOR(bzn));
2248                                 bigz_mul(bz, bz, XBIGQ_DENOMINATOR(bzn));
2249                                 break;
2250
2251                                 /* no gcd defined for the rest */
2252                         default:
2253                                 bigz_fini(bz);
2254                                 bigz_fini(bznum);
2255                                 bigz_fini(bzden);
2256                                 bigz_fini(bs);
2257                                 bigz_fini(bt);
2258                                 return list1(Qzero);
2259                                 break;
2260                         }
2261
2262                         mpz_gcdext(bz, bs, bt, bz, bznum);
2263                         for (j = i; j > 0; j--) {
2264                                 bigz_mul(XBIGZ_DATA(qargs[j]),
2265                                          XBIGZ_DATA(qargs[j]),
2266                                          bs);
2267                         }
2268                         qargs[i+1] = make_bigz_bz(bt);
2269                 }
2270                 if (bigz_fits_long_p(bzden) &&
2271                     bigz_to_long(bzden) == 1L) {
2272                         qargs[0] = make_bigz_bz(bz);
2273                 } else {
2274                         qargs[0] = make_bigq_bz(bz, bzden);
2275                 }
2276                 bigz_fini(bz);
2277                 bigz_fini(bznum);
2278                 bigz_fini(bzden);
2279                 bigz_fini(bs);
2280                 bigz_fini(bt);
2281                 return Flist(nargs+1, qargs);
2282         }
2283         /* NOT REACHED */
2284         return Qzero;
2285 }
2286
2287 DEFUN("lcm", Flcm, 0, MANY, 0,  /*
2288 Return the least common multiple of the arguments.
2289 */
2290       (int nargs, Lisp_Object *args))
2291 {
2292         REGISTER int i;
2293
2294         if (nargs == 0)
2295                 return Qzero;
2296         else if (nargs == 1)
2297                 return args[0];
2298         else {
2299                 bigz bz;
2300                 bigz bznum;
2301                 bigz bzden;
2302                 Lisp_Object bzn;
2303                 bigz_init(bz);
2304                 bigz_init(bznum);
2305                 bigz_init(bzden);
2306
2307                 bzn = args[0];
2308                 switch (ase_optable_index(bzn)) {
2309                 case INT_T:
2310                         bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2311                         bigz_set(bz, XBIGZ_DATA(bzn));
2312                         bigz_set_long(bzden, 1L);
2313                         break;
2314                 case BIGZ_T:
2315                         bigz_set(bz, XBIGZ_DATA(bzn));
2316                         bigz_set_long(bzden, 1L);
2317                         break;
2318                 case BIGQ_T:
2319                         bigz_set(bz, XBIGQ_NUMERATOR(bzn));
2320                         bigz_set(bzden, XBIGQ_DENOMINATOR(bzn));
2321                         break;
2322
2323                 /* no lcm defined for the rest */
2324                 default:
2325                         bigz_fini(bz);
2326                         bigz_fini(bznum);
2327                         bigz_fini(bzden);
2328                         return Qzero;
2329                         break;
2330                 }
2331
2332                 for (i = 1; i < nargs; i++) {
2333                         bzn = args[i];
2334
2335                         switch (ase_optable_index(bzn)) {
2336                         case INT_T:
2337                                 bzn = Fcoerce_number(bzn, Qbigz, Qnil);
2338                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2339                                 break;
2340                         case BIGZ_T:
2341                                 bigz_set(bznum, XBIGZ_DATA(bzn));
2342                                 break;
2343                         /* multiply across fractions */
2344                         case BIGQ_T:
2345                                 bigz_set(bznum, XBIGQ_NUMERATOR(bzn));
2346                                 bigz_mul(bznum, bznum, bzden);
2347                                 bigz_mul(bzden, bzden, XBIGQ_DENOMINATOR(bzn));
2348                                 bigz_mul(bz, bz, XBIGQ_DENOMINATOR(bzn));
2349                                 break;
2350
2351                         /* no gcd defined for the rest */
2352                         default:
2353                                 bigz_fini(bz);
2354                                 bigz_fini(bznum);
2355                                 bigz_fini(bzden);
2356                                 return Qzero;
2357                                 break;
2358                         }
2359                         bigz_lcm(bz, bz, bznum);
2360                 }
2361                 if (bigz_fits_long_p(bzden) &&
2362                     bigz_to_long(bzden) == 1L) {
2363                         bzn = make_bigz_bz(bz);
2364                 } else {
2365                         bzn = make_bigq_bz(bz, bzden);
2366                 }
2367                 bigz_fini(bz);
2368                 bigz_fini(bznum);
2369                 bigz_fini(bzden);
2370                 return bzn;
2371         }
2372         /* NOT REACHED */
2373         return Qzero;
2374 }
2375 #endif  /* WITH_GMP && (HAVE_MPZ || HAVE_MPQ) */
2376
2377 \f
2378 /************************************************************************/
2379 /*                              weak lists                              */
2380 /************************************************************************/
2381
2382 /* A weak list is like a normal list except that elements automatically
2383    disappear when no longer in use, i.e. when no longer GC-protected.
2384    The basic idea is that we don't mark the elements during GC, but
2385    wait for them to be marked elsewhere.  If they're not marked, we
2386    remove them.  This is analogous to weak hash tables; see the explanation
2387    there for more info. */
2388
2389 static Lisp_Object Vall_weak_lists;     /* Gemarke es nicht!!! */
2390
2391 static Lisp_Object encode_weak_list_type(enum weak_list_type type);
2392
2393 static Lisp_Object mark_weak_list(Lisp_Object obj)
2394 {
2395         return Qnil;            /* nichts ist gemarkt */
2396         /* avoid some warning */
2397         return (obj == Qnil);
2398 }
2399
2400 static void
2401 print_weak_list(Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
2402 {
2403         if (print_readably)
2404                 error("printing unreadable object #<weak-list>");
2405
2406         write_c_string("#<weak-list ", printcharfun);
2407         print_internal(encode_weak_list_type(XWEAK_LIST(obj)->type),
2408                        printcharfun, 0);
2409         write_c_string(" ", printcharfun);
2410         print_internal(XWEAK_LIST(obj)->list, printcharfun, escapeflag);
2411         write_c_string(">", printcharfun);
2412 }
2413
2414 static int weak_list_equal(Lisp_Object obj1, Lisp_Object obj2, int depth)
2415 {
2416         struct weak_list *w1 = XWEAK_LIST(obj1);
2417         struct weak_list *w2 = XWEAK_LIST(obj2);
2418
2419         return ((w1->type == w2->type) &&
2420                 internal_equal(w1->list, w2->list, depth + 1));
2421 }
2422
2423 static unsigned long weak_list_hash(Lisp_Object obj, int depth)
2424 {
2425         struct weak_list *w = XWEAK_LIST(obj);
2426
2427         return HASH2((unsigned long)w->type, internal_hash(w->list, depth + 1));
2428 }
2429
2430 Lisp_Object make_weak_list(enum weak_list_type type)
2431 {
2432         Lisp_Object result;
2433         struct weak_list *wl =
2434             alloc_lcrecord_type(struct weak_list, &lrecord_weak_list);
2435
2436         wl->list = Qnil;
2437         wl->type = type;
2438         XSETWEAK_LIST(result, wl);
2439         wl->next_weak = Vall_weak_lists;
2440         Vall_weak_lists = result;
2441         return result;
2442 }
2443
2444 static const struct lrecord_description weak_list_description[] = {
2445         {XD_LISP_OBJECT, offsetof(struct weak_list, list)},
2446         {XD_LO_LINK, offsetof(struct weak_list, next_weak)},
2447         {XD_END}
2448 };
2449
2450 DEFINE_LRECORD_IMPLEMENTATION("weak-list", weak_list,
2451                               mark_weak_list, print_weak_list,
2452                               0, weak_list_equal, weak_list_hash,
2453                               weak_list_description, struct weak_list);
2454 /*
2455    -- we do not mark the list elements (either the elements themselves
2456       or the cons cells that hold them) in the normal marking phase.
2457    -- at the end of marking, we go through all weak lists that are
2458       marked, and mark the cons cells that hold all marked
2459       objects, and possibly parts of the objects themselves.
2460       (See alloc.c, "after-mark".)
2461    -- after that, we prune away all the cons cells that are not marked.
2462
2463    WARNING WARNING WARNING WARNING WARNING:
2464
2465    The code in the following two functions is *unbelievably* tricky.
2466    Don't mess with it.  You'll be sorry.
2467
2468    Linked lists just majorly suck, d'ya know?
2469 */
2470
2471 int finish_marking_weak_lists(void)
2472 {
2473         Lisp_Object rest;
2474         int did_mark = 0;
2475
2476         for (rest = Vall_weak_lists;
2477              !NILP(rest); rest = XWEAK_LIST(rest)->next_weak) {
2478                 Lisp_Object rest2;
2479                 enum weak_list_type type = XWEAK_LIST(rest)->type;
2480
2481                 if (!marked_p(rest))
2482                         /* The weak list is probably garbage.  Ignore it. */
2483                         continue;
2484
2485                 for (rest2 = XWEAK_LIST(rest)->list;
2486                      /* We need to be trickier since we're inside of GC;
2487                         use CONSP instead of !NILP in case of user-visible
2488                         imperfect lists */
2489                      CONSP(rest2); rest2 = XCDR(rest2)) {
2490                         Lisp_Object elem;
2491                         /* If the element is "marked" (meaning depends on the type
2492                            of weak list), we need to mark the cons containing the
2493                            element, and maybe the element itself (if only some part
2494                            was already marked). */
2495                         int need_to_mark_cons = 0;
2496                         int need_to_mark_elem = 0;
2497
2498                         /* If a cons is already marked, then its car is already marked
2499                            (either because of an external pointer or because of
2500                            a previous call to this function), and likewise for all
2501                            the rest of the elements in the list, so we can stop now. */
2502                         if (marked_p(rest2))
2503                                 break;
2504
2505                         elem = XCAR(rest2);
2506
2507                         switch (type) {
2508                         case WEAK_LIST_SIMPLE:
2509                                 if (marked_p(elem))
2510                                         need_to_mark_cons = 1;
2511                                 break;
2512
2513                         case WEAK_LIST_ASSOC:
2514                                 if (!CONSP(elem)) {
2515                                         /* just leave bogus elements there */
2516                                         need_to_mark_cons = 1;
2517                                         need_to_mark_elem = 1;
2518                                 } else if (marked_p(XCAR(elem)) &&
2519                                            marked_p(XCDR(elem))) {
2520                                         need_to_mark_cons = 1;
2521                                         /* We still need to mark elem, because it's
2522                                            probably not marked. */
2523                                         need_to_mark_elem = 1;
2524                                 }
2525                                 break;
2526
2527                         case WEAK_LIST_KEY_ASSOC:
2528                                 if (!CONSP(elem)) {
2529                                         /* just leave bogus elements there */
2530                                         need_to_mark_cons = 1;
2531                                         need_to_mark_elem = 1;
2532                                 } else if (marked_p(XCAR(elem))) {
2533                                         need_to_mark_cons = 1;
2534                                         /* We still need to mark elem and XCDR (elem);
2535                                            marking elem does both */
2536                                         need_to_mark_elem = 1;
2537                                 }
2538                                 break;
2539
2540                         case WEAK_LIST_VALUE_ASSOC:
2541                                 if (!CONSP(elem)) {
2542                                         /* just leave bogus elements there */
2543                                         need_to_mark_cons = 1;
2544                                         need_to_mark_elem = 1;
2545                                 } else if (marked_p(XCDR(elem))) {
2546                                         need_to_mark_cons = 1;
2547                                         /* We still need to mark elem and XCAR (elem);
2548                                            marking elem does both */
2549                                         need_to_mark_elem = 1;
2550                                 }
2551                                 break;
2552
2553                         case WEAK_LIST_FULL_ASSOC:
2554                                 if (!CONSP(elem)) {
2555                                         /* just leave bogus elements there */
2556                                         need_to_mark_cons = 1;
2557                                         need_to_mark_elem = 1;
2558                                 } else if (marked_p(XCAR(elem)) ||
2559                                            marked_p(XCDR(elem))) {
2560                                         need_to_mark_cons = 1;
2561                                         /* We still need to mark elem and XCAR (elem);
2562                                            marking elem does both */
2563                                         need_to_mark_elem = 1;
2564                                 }
2565                                 break;
2566
2567                         default:
2568                                 abort();
2569                         }
2570
2571                         if (need_to_mark_elem && !marked_p(elem)) {
2572                                 mark_object(elem);
2573                                 did_mark = 1;
2574                         }
2575
2576                         /* We also need to mark the cons that holds the elem or
2577                            assoc-pair.  We do *not* want to call (mark_object) here
2578                            because that will mark the entire list; we just want to
2579                            mark the cons itself.
2580                          */
2581                         if (need_to_mark_cons) {
2582                                 Lisp_Cons *c = XCONS(rest2);
2583                                 if (!CONS_MARKED_P(c)) {
2584                                         MARK_CONS(c);
2585                                         did_mark = 1;
2586                                 }
2587                         }
2588                 }
2589
2590                 /* In case of imperfect list, need to mark the final cons
2591                    because we're not removing it */
2592                 if (!NILP(rest2) && !marked_p(rest2)) {
2593                         mark_object(rest2);
2594                         did_mark = 1;
2595                 }
2596         }
2597
2598         return did_mark;
2599 }
2600
2601 void prune_weak_lists(void)
2602 {
2603         Lisp_Object rest, prev = Qnil;
2604
2605         for (rest = Vall_weak_lists;
2606              !NILP(rest); rest = XWEAK_LIST(rest)->next_weak) {
2607                 if (!(marked_p(rest))) {
2608                         /* This weak list itself is garbage.  Remove it from the list. */
2609                         if (NILP(prev))
2610                                 Vall_weak_lists = XWEAK_LIST(rest)->next_weak;
2611                         else
2612                                 XWEAK_LIST(prev)->next_weak =
2613                                     XWEAK_LIST(rest)->next_weak;
2614                 } else {
2615                         Lisp_Object rest2, prev2 = Qnil;
2616                         Lisp_Object tortoise;
2617                         int go_tortoise = 0;
2618
2619                         for (rest2 = XWEAK_LIST(rest)->list, tortoise = rest2;
2620                              /* We need to be trickier since we're inside of GC;
2621                                 use CONSP instead of !NILP in case of user-visible
2622                                 imperfect lists */
2623                              CONSP(rest2);) {
2624                                 /* It suffices to check the cons for marking,
2625                                    regardless of the type of weak list:
2626
2627                                    -- if the cons is pointed to somewhere else,
2628                                    then it should stay around and will be marked.
2629                                    -- otherwise, if it should stay around, it will
2630                                    have been marked in finish_marking_weak_lists().
2631                                    -- otherwise, it's not marked and should disappear.
2632                                  */
2633                                 if (!marked_p(rest2)) {
2634                                         /* bye bye :-( */
2635                                         if (NILP(prev2))
2636                                                 XWEAK_LIST(rest)->list =
2637                                                     XCDR(rest2);
2638                                         else
2639                                                 XCDR(prev2) = XCDR(rest2);
2640                                         rest2 = XCDR(rest2);
2641                                         /* Ouch.  Circularity checking is even trickier
2642                                            than I thought.  When we cut out a link
2643                                            like this, we can't advance the turtle or
2644                                            it'll catch up to us.  Imagine that we're
2645                                            standing on floor tiles and moving forward --
2646                                            what we just did here is as if the floor
2647                                            tile under us just disappeared and all the
2648                                            ones ahead of us slid one tile towards us.
2649                                            In other words, we didn't move at all;
2650                                            if the tortoise was one step behind us
2651                                            previously, it still is, and therefore
2652                                            it must not move. */
2653                                 } else {
2654                                         prev2 = rest2;
2655
2656                                         /* Implementing circularity checking is trickier here
2657                                            than in other places because we have to guarantee
2658                                            that we've processed all elements before exiting
2659                                            due to a circularity. (In most places, an error
2660                                            is issued upon encountering a circularity, so it
2661                                            doesn't really matter if all elements are processed.)
2662                                            The idea is that we process along with the hare
2663                                            rather than the tortoise.  If at any point in
2664                                            our forward process we encounter the tortoise,
2665                                            we must have already visited the spot, so we exit.
2666                                            (If we process with the tortoise, we can fail to
2667                                            process cases where a cons points to itself, or
2668                                            where cons A points to cons B, which points to
2669                                            cons A.) */
2670
2671                                         rest2 = XCDR(rest2);
2672                                         if (go_tortoise)
2673                                                 tortoise = XCDR(tortoise);
2674                                         go_tortoise = !go_tortoise;
2675                                         if (EQ(rest2, tortoise))
2676                                                 break;
2677                                 }
2678                         }
2679
2680                         prev = rest;
2681                 }
2682         }
2683 }
2684
2685 static enum weak_list_type decode_weak_list_type(Lisp_Object symbol)
2686 {
2687         CHECK_SYMBOL(symbol);
2688         if (EQ(symbol, Qsimple))
2689                 return WEAK_LIST_SIMPLE;
2690         if (EQ(symbol, Qassoc))
2691                 return WEAK_LIST_ASSOC;
2692         if (EQ(symbol, Qold_assoc))
2693                 return WEAK_LIST_ASSOC; /* EBOLA ALERT! */
2694         if (EQ(symbol, Qkey_assoc))
2695                 return WEAK_LIST_KEY_ASSOC;
2696         if (EQ(symbol, Qvalue_assoc))
2697                 return WEAK_LIST_VALUE_ASSOC;
2698         if (EQ(symbol, Qfull_assoc))
2699                 return WEAK_LIST_FULL_ASSOC;
2700
2701         signal_simple_error("Invalid weak list type", symbol);
2702         return WEAK_LIST_SIMPLE;        /* not reached */
2703 }
2704
2705 static Lisp_Object encode_weak_list_type(enum weak_list_type type)
2706 {
2707         switch (type) {
2708         case WEAK_LIST_SIMPLE:
2709                 return Qsimple;
2710         case WEAK_LIST_ASSOC:
2711                 return Qassoc;
2712         case WEAK_LIST_KEY_ASSOC:
2713                 return Qkey_assoc;
2714         case WEAK_LIST_VALUE_ASSOC:
2715                 return Qvalue_assoc;
2716         case WEAK_LIST_FULL_ASSOC:
2717                 return Qfull_assoc;
2718         default:
2719                 abort();
2720         }
2721
2722         return Qnil;            /* not reached */
2723 }
2724
2725 DEFUN("weak-list-p", Fweak_list_p, 1, 1, 0,     /*
2726 Return non-nil if OBJECT is a weak list.
2727 */
2728       (object))
2729 {
2730         return WEAK_LISTP(object) ? Qt : Qnil;
2731 }
2732
2733 DEFUN("make-weak-list", Fmake_weak_list, 0, 1, 0,       /*
2734 Return a new weak list object of type TYPE.
2735 A weak list object is an object that contains a list.  This list behaves
2736 like any other list except that its elements do not count towards
2737 garbage collection -- if the only pointer to an object is inside a weak
2738 list (other than pointers in similar objects such as weak hash tables),
2739 the object is garbage collected and automatically removed from the list.
2740 This is used internally, for example, to manage the list holding the
2741 children of an extent -- an extent that is unused but has a parent will
2742 still be reclaimed, and will automatically be removed from its parent's
2743 list of children.
2744
2745 Optional argument TYPE specifies the type of the weak list, and defaults
2746 to `simple'.  Recognized types are
2747
2748   `simple'       Objects in the list disappear if not pointed to.
2749   `assoc'        Objects in the list disappear if they are conses
2750                  and either the car or the cdr of the cons is not
2751                  pointed to.
2752   `key-assoc'    Objects in the list disappear if they are conses
2753                  and the car is not pointed to.
2754   `value-assoc'  Objects in the list disappear if they are conses
2755                  and the cdr is not pointed to.
2756   `full-assoc'   Objects in the list disappear if they are conses
2757                  and neither the car nor the cdr is pointed to.
2758 */
2759       (type))
2760 {
2761         if (NILP(type))
2762                 type = Qsimple;
2763
2764         return make_weak_list(decode_weak_list_type(type));
2765 }
2766
2767 DEFUN("weak-list-type", Fweak_list_type, 1, 1, 0,       /*
2768 Return the type of the given weak-list object.
2769 */
2770       (weak))
2771 {
2772         CHECK_WEAK_LIST(weak);
2773         return encode_weak_list_type(XWEAK_LIST(weak)->type);
2774 }
2775
2776 DEFUN("weak-list-list", Fweak_list_list, 1, 1, 0,       /*
2777 Return the list contained in a weak-list object.
2778 */
2779       (weak))
2780 {
2781         CHECK_WEAK_LIST(weak);
2782         return XWEAK_LIST_LIST(weak);
2783 }
2784
2785 DEFUN("set-weak-list-list", Fset_weak_list_list, 2, 2, 0,       /*
2786 Change the list contained in a weak-list object.
2787 */
2788       (weak, new_list))
2789 {
2790         CHECK_WEAK_LIST(weak);
2791         XWEAK_LIST_LIST(weak) = new_list;
2792         return new_list;
2793 }
2794 \f
2795 /************************************************************************/
2796 /*                            initialization                            */
2797 /************************************************************************/
2798
2799 static SIGTYPE arith_error(int signo)
2800 {
2801         EMACS_REESTABLISH_SIGNAL(signo, arith_error);
2802         EMACS_UNBLOCK_SIGNAL(signo);
2803         signal_error(Qarith_error, Qnil);
2804 }
2805
2806 void init_data_very_early(void)
2807 {
2808         /* Don't do this if just dumping out.
2809            We don't want to call `signal' in this case
2810            so that we don't have trouble with dumping
2811            signal-delivering routines in an inconsistent state.  */
2812 #ifndef CANNOT_DUMP
2813         if (!initialized)
2814                 return;
2815 #endif                          /* CANNOT_DUMP */
2816         signal(SIGFPE, arith_error);
2817 #ifdef uts
2818         signal(SIGEMT, arith_error);
2819 #endif                          /* uts */
2820 }
2821
2822 void
2823 init_errors_once_early (void)
2824 {
2825         DEFSYMBOL (Qerror_conditions);
2826         DEFSYMBOL (Qerror_message);
2827
2828         /* We declare the errors here because some other deferrors depend
2829            on some of the errors below. */
2830
2831         /* ERROR is used as a signaler for random errors for which nothing
2832            else is right */
2833
2834         DEFERROR (Qerror, "error", Qnil);
2835         DEFERROR_STANDARD (Qquit, Qnil);
2836
2837         DEFERROR_STANDARD (Qinvalid_argument, Qerror);
2838
2839         DEFERROR_STANDARD (Qsyntax_error, Qinvalid_argument);
2840         DEFERROR_STANDARD (Qinvalid_read_syntax, Qsyntax_error);
2841         DEFERROR_STANDARD (Qstructure_formation_error, Qsyntax_error);
2842         DEFERROR_STANDARD (Qlist_formation_error, Qstructure_formation_error);
2843         DEFERROR_STANDARD (Qmalformed_list, Qlist_formation_error);
2844         DEFERROR_STANDARD (Qmalformed_property_list, Qmalformed_list);
2845         DEFERROR_STANDARD (Qcircular_list, Qlist_formation_error);
2846         DEFERROR_STANDARD (Qcircular_property_list, Qcircular_list);
2847
2848         DEFERROR_STANDARD (Qwrong_type_argument, Qinvalid_argument);
2849         DEFERROR_STANDARD (Qargs_out_of_range, Qinvalid_argument);
2850         DEFERROR_STANDARD (Qwrong_number_of_arguments, Qinvalid_argument);
2851         DEFERROR_STANDARD (Qinvalid_function, Qinvalid_argument);
2852         DEFERROR_STANDARD (Qinvalid_constant, Qinvalid_argument);
2853         DEFERROR (Qno_catch, "No catch for tag", Qinvalid_argument);
2854
2855         DEFERROR_STANDARD (Qinvalid_state, Qerror);
2856         DEFERROR (Qvoid_function, "Symbol's function definition is void",
2857                   Qinvalid_state);
2858         DEFERROR (Qcyclic_function_indirection,
2859                   "Symbol's chain of function indirections contains a loop",
2860                   Qinvalid_state);
2861         DEFERROR (Qvoid_variable, "Symbol's value as variable is void",
2862                   Qinvalid_state);
2863         DEFERROR (Qcyclic_variable_indirection,
2864                   "Symbol's chain of variable indirections contains a loop",
2865                   Qinvalid_state);
2866         DEFERROR_STANDARD (Qstack_overflow, Qinvalid_state);
2867         DEFERROR_STANDARD (Qinternal_error, Qinvalid_state);
2868         DEFERROR_STANDARD (Qout_of_memory, Qinvalid_state);
2869
2870         DEFERROR_STANDARD (Qinvalid_operation, Qerror);
2871         DEFERROR_STANDARD (Qinvalid_change, Qinvalid_operation);
2872         DEFERROR (Qsetting_constant, "Attempt to set a constant symbol",
2873                   Qinvalid_change);
2874         DEFERROR_STANDARD (Qprinting_unreadable_object, Qinvalid_operation);
2875         DEFERROR (Qunimplemented, "Feature not yet implemented", Qinvalid_operation);
2876
2877         DEFERROR_STANDARD (Qediting_error, Qinvalid_operation);
2878         DEFERROR_STANDARD (Qbeginning_of_buffer, Qediting_error);
2879         DEFERROR_STANDARD (Qend_of_buffer, Qediting_error);
2880         DEFERROR (Qbuffer_read_only, "Buffer is read-only", Qediting_error);
2881
2882         DEFERROR (Qio_error, "IO Error", Qinvalid_operation);
2883         DEFERROR_STANDARD (Qfile_error, Qio_error);
2884         DEFERROR (Qend_of_file, "End of file or stream", Qfile_error);
2885         DEFERROR_STANDARD (Qconversion_error, Qio_error);
2886         DEFERROR_STANDARD (Qtext_conversion_error, Qconversion_error);
2887
2888         DEFERROR (Qarith_error, "Arithmetic error", Qinvalid_operation);
2889         DEFERROR (Qrange_error, "Arithmetic range error", Qarith_error);
2890         DEFERROR (Qdomain_error, "Arithmetic domain error", Qarith_error);
2891         DEFERROR (Qsingularity_error, "Arithmetic singularity error", Qdomain_error);
2892         DEFERROR (Qoverflow_error, "Arithmetic overflow error", Qdomain_error);
2893         DEFERROR (Qunderflow_error, "Arithmetic underflow error", Qdomain_error);
2894 }
2895
2896 void syms_of_data(void)
2897 {
2898         INIT_LRECORD_IMPLEMENTATION(weak_list);
2899
2900         DEFSYMBOL(Qquote);
2901         DEFSYMBOL(Qlambda);
2902         DEFSYMBOL(Qlistp);
2903         DEFSYMBOL(Qtrue_list_p);
2904         DEFSYMBOL(Qconsp);
2905         DEFSYMBOL(Qsubrp);
2906         DEFSYMBOL(Qsymbolp);
2907         DEFSYMBOL(Qintegerp);
2908         DEFSYMBOL(Qcharacterp);
2909         DEFSYMBOL(Qnatnump);
2910         DEFSYMBOL(Qnonnegativep);
2911         DEFSYMBOL(Qpositivep);
2912         DEFSYMBOL(Qstringp);
2913         DEFSYMBOL(Qarrayp);
2914         DEFSYMBOL(Qsequencep);
2915         DEFSYMBOL(Qdictp);
2916         DEFSYMBOL(Qbufferp);
2917         DEFSYMBOL(Qbitp);
2918         DEFSYMBOL_MULTIWORD_PREDICATE(Qbit_vectorp);
2919         DEFSYMBOL(Qvectorp);
2920         DEFSYMBOL(Qchar_or_string_p);
2921         DEFSYMBOL(Qmarkerp);
2922         DEFSYMBOL(Qinteger_or_marker_p);
2923         DEFSYMBOL(Qinteger_or_char_p);
2924         DEFSYMBOL(Qinteger_char_or_marker_p);
2925         DEFSYMBOL(Qnumberp);
2926         DEFSYMBOL(Qnumber_char_or_marker_p);
2927         DEFSYMBOL(Qcdr);
2928         DEFSYMBOL_MULTIWORD_PREDICATE(Qweak_listp);
2929
2930 #ifdef HAVE_FPFLOAT
2931         DEFSYMBOL(Qfloatp);
2932 #endif                          /* HAVE_FPFLOAT */
2933
2934         DEFSUBR(Fwrong_type_argument);
2935
2936         DEFSUBR(Feq);
2937         DEFSUBR(Fold_eq);
2938         DEFSUBR(Fnull);
2939         Ffset(intern("not"), intern("null"));
2940         DEFSUBR(Flistp);
2941         DEFSUBR(Fnlistp);
2942         DEFSUBR(Ftrue_list_p);
2943         DEFSUBR(Fconsp);
2944         DEFSUBR(Fatom);
2945         DEFSUBR(Fchar_or_string_p);
2946         DEFSUBR(Fcharacterp);
2947         DEFSUBR(Fchar_int_p);
2948         DEFSUBR(Fchar_to_int);
2949         DEFSUBR(Fint_to_char);
2950         DEFSUBR(Fchar_or_char_int_p);
2951         DEFSUBR(Fintp);
2952         DEFSUBR(Ffixnump);
2953         DEFSUBR(Finteger_or_marker_p);
2954         DEFSUBR(Finteger_or_char_p);
2955         DEFSUBR(Finteger_char_or_marker_p);
2956         DEFSUBR(Fnumberp);
2957         DEFSUBR(Fnumber_or_marker_p);
2958         DEFSUBR(Fnumber_char_or_marker_p);
2959 #ifdef HAVE_FPFLOAT
2960         DEFSUBR(Ffloatp);
2961 #endif                          /* HAVE_FPFLOAT */
2962         DEFSUBR(Fnatnump);
2963         DEFSUBR(Fnonnegativep);
2964         DEFSUBR(Fsymbolp);
2965         DEFSUBR(Fkeywordp);
2966         DEFSUBR(Fstringp);
2967         DEFSUBR(Fvectorp);
2968         DEFSUBR(Fbitp);
2969         DEFSUBR(Fbit_vector_p);
2970         DEFSUBR(Farrayp);
2971         DEFSUBR(Fsequencep);
2972         DEFSUBR(Fmarkerp);
2973         DEFSUBR(Fsubrp);
2974         DEFSUBR(Fsubr_min_args);
2975         DEFSUBR(Fsubr_max_args);
2976         DEFSUBR(Fsubr_interactive);
2977         DEFSUBR(Ftype_of);
2978         DEFSUBR(Fcar);
2979         DEFSUBR(Fcdr);
2980         DEFSUBR(Fcar_safe);
2981         DEFSUBR(Fcdr_safe);
2982         DEFSUBR(Fsetcar);
2983         DEFSUBR(Fsetcdr);
2984         DEFSUBR(Findirect_function);
2985         DEFSUBR(Faref);
2986         DEFSUBR(Faset);
2987
2988         DEFSUBR(Fnumber_to_string);
2989         DEFSUBR(Fstring_to_number);
2990
2991         DEFSUBR(Flogand);
2992         DEFSUBR(Flogior);
2993         DEFSUBR(Flogxor);
2994         DEFSUBR(Flsh);
2995         DEFSUBR(Fash);
2996         DEFSUBR(Flognot);
2997 #if defined(WITH_GMP) && defined(HAVE_MPZ)
2998         DEFSUBR(Fprimep);
2999         DEFSUBR(Fnext_prime);
3000         DEFSUBR(Fgcd);
3001         DEFSUBR(Fxgcd);
3002         DEFSUBR(Flcm);
3003         DEFSUBR(Ffactorial);
3004         DEFSUBR(Fbinomial_coefficient);
3005         DEFSUBR(Fremove_factor);
3006         DEFSUBR(Ffibonacci);
3007         DEFSUBR(Ffibonacci2);
3008         DEFSUBR(Flucas);
3009         DEFSUBR(Flucas2);
3010         DEFSUBR(Fdivisiblep);
3011         DEFSUBR(Fcongruentp);
3012         DEFSUBR(Fperfect_power_p);
3013         DEFSUBR(Fperfect_square_p);
3014         DEFSUBR(Fintegral_sqrt);
3015 #if defined HAVE_ECM && defined WITH_ECM
3016         DEFSUBR(Ffactorise);    /* some day maybe */
3017 #endif  /* WITH_ECM && HAVE_ECM */
3018 #endif  /* WITH_GMP && HAVE_MPZ */
3019         DEFSUBR(Fzero_divisor_p);
3020         DEFSUBR(Fweak_list_p);
3021         DEFSUBR(Fmake_weak_list);
3022         DEFSUBR(Fweak_list_type);
3023         DEFSUBR(Fweak_list_list);
3024         DEFSUBR(Fset_weak_list_list);
3025 }
3026
3027 void vars_of_data(void)
3028 {
3029         /* This must not be staticpro'd */
3030         Vall_weak_lists = Qnil;
3031         dump_add_weak_object_chain(&Vall_weak_lists);
3032
3033 #ifdef DEBUG_SXEMACS
3034         DEFVAR_BOOL("debug-issue-ebola-notices", &debug_issue_ebola_notices     /*
3035 If non-zero, note when your code may be suffering from char-int confoundance.
3036 That is to say, if SXEmacs encounters a usage of `eq', `memq', `equal',
3037 etc. where an int and a char with the same value are being compared,
3038 it will issue a notice on stderr to this effect, along with a backtrace.
3039 In such situations, the result would be different in XEmacs 19 versus
3040 XEmacs 20, and you probably don't want this.
3041
3042 Note that in order to see these notices, you have to byte compile your
3043 code under XEmacs 20 -- any code byte-compiled under XEmacs 19 will
3044 have its chars and ints all confounded in the byte code, making it
3045 impossible to accurately determine Ebola infection.
3046                                                                                  */ );
3047
3048         debug_issue_ebola_notices = 0;
3049
3050         DEFVAR_INT("debug-ebola-backtrace-length", &debug_ebola_backtrace_length        /*
3051 Length (in stack frames) of short backtrace printed out in Ebola notices.
3052 See `debug-issue-ebola-notices'.
3053                                                                                          */ );
3054         debug_ebola_backtrace_length = 32;
3055
3056 #endif                          /* DEBUG_SXEMACS */
3057 }