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