X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/3694b4abbb7febb69622c940bb2599e56362ea06..015a8883e056cd23d926a45304b63880b7a99063:/src/lisp.h diff --git a/src/lisp.h b/src/lisp.h index 8c78ba7edb..cba2349b58 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1,5 +1,5 @@ /* Fundamental definitions for GNU Emacs Lisp interpreter. - Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000 + Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000, 2001 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -26,6 +26,14 @@ Boston, MA 02111-1307, USA. */ #define P_(proto) () #endif +#if 0 +/* Define this temporarily to hunt a bug. If defined, the size of + strings is redundantly recorded in sdata structures so that it can + be compared to the sizes recorded in Lisp strings. */ + +#define GC_CHECK_STRING_BYTES 1 +#endif /* 0*/ + /* These are default choices for the types to use. */ #ifdef _LP64 @@ -53,7 +61,7 @@ extern void die P_((const char *, const char *, int)); #ifdef ENABLE_CHECKING #define CHECK(check,msg) ((check || suppress_checking \ - ? 0 \ + ? (void) 0 \ : die (msg, __FILE__, __LINE__)), \ 0) @@ -67,6 +75,13 @@ extern void die P_((const char *, const char *, int)); #endif +/* Used for making sure that Emacs is compilable in all + configurations. */ + +#ifdef USE_LISP_UNION_TYPE +#undef NO_UNION_TYPE +#endif + /* Define an Emacs version of "assert", since some system ones are flaky. */ #ifndef ENABLE_CHECKING @@ -114,7 +129,7 @@ enum Lisp_Type Lisp_Type_Limit }; -/* This is the set of datatypes that share a common structure. +/* This is the set of data types that share a common structure. The first member of the structure is a type code from this set. The enum values are arbitrary, but we'll use large numbers to make it more likely that we'll spot the error if a random word in memory is @@ -178,25 +193,25 @@ union Lisp_Object { /* Used for comparing two Lisp_Objects; also, positive integers can be accessed fast this way. */ - int i; + EMACS_INT i; struct { - int val: VALBITS; - int type: GCTYPEBITS+1; + EMACS_INT val : VALBITS; + EMACS_INT type : GCTYPEBITS + 1; } s; struct { - unsigned int val: VALBITS; - int type: GCTYPEBITS+1; + EMACS_UINT val : VALBITS; + EMACS_INT type : GCTYPEBITS + 1; } u; struct { - unsigned int val: VALBITS; - enum Lisp_Type type: GCTYPEBITS; + EMACS_UINT val : VALBITS; + enum Lisp_Type type : GCTYPEBITS; /* The markbit is not really part of the value of a Lisp_Object, and is always zero except during garbage collection. */ - unsigned int markbit: 1; + EMACS_UINT markbit : 1; } gu; } Lisp_Object; @@ -208,31 +223,41 @@ union Lisp_Object { /* Used for comparing two Lisp_Objects; also, positive integers can be accessed fast this way. */ - int i; + EMACS_INT i; struct { - int type: GCTYPEBITS+1; - int val: VALBITS; + EMACS_INT type : GCTYPEBITS+1; + EMACS_INT val : VALBITS; } s; struct { - int type: GCTYPEBITS+1; - unsigned int val: VALBITS; + EMACS_INT type : GCTYPEBITS+1; + EMACS_UINT val : VALBITS; } u; struct { /* The markbit is not really part of the value of a Lisp_Object, and is always zero except during garbage collection. */ - unsigned int markbit: 1; - enum Lisp_Type type: GCTYPEBITS; - unsigned int val: VALBITS; + EMACS_UINT markbit : 1; + enum Lisp_Type type : GCTYPEBITS; + EMACS_UINT val : VALBITS; } gu; } Lisp_Object; #endif /* WORDS_BIG_ENDIAN */ +#ifdef __GNUC__ +static __inline__ Lisp_Object +LISP_MAKE_RVALUE (Lisp_Object o) +{ + return o; +} +#else +#define LISP_MAKE_RVALUE(o) (o) /* XXX - keeps arg as rvalue. */ +#endif + #endif /* NO_UNION_TYPE */ @@ -240,6 +265,7 @@ Lisp_Object; #ifdef NO_UNION_TYPE #define Lisp_Object EMACS_INT +#define LISP_MAKE_RVALUE(o) (0+(o)) #endif /* NO_UNION_TYPE */ #ifndef VALMASK @@ -312,7 +338,7 @@ enum pvec_type /* One need to override this if there must be high bits set in data space (doing the result of the below & ((1 << (GCTYPE + 1)) - 1) would work - on all machines, but would penalise machines which don't need it) + on all machines, but would penalize machines which don't need it) */ #ifndef XTYPE #define XTYPE(a) ((enum Lisp_Type) ((a) >> VALBITS)) @@ -331,20 +357,21 @@ enum pvec_type /* Extract the value of a Lisp_Object as a signed integer. */ #ifndef XINT /* Some machines need to do this differently. */ -#define XINT(a) (((a) << (BITS_PER_EMACS_INT-VALBITS)) >> (BITS_PER_EMACS_INT-VALBITS)) +#define XINT(a) ((EMACS_INT) (((a) << (BITS_PER_EMACS_INT - VALBITS)) \ + >> (BITS_PER_EMACS_INT - VALBITS))) #endif /* Extract the value as an unsigned integer. This is a basis for extracting it as a pointer to a structure in storage. */ #ifndef XUINT -#define XUINT(a) ((a) & VALMASK) +#define XUINT(a) ((EMACS_UINT) ((a) & VALMASK)) #endif #ifndef XPNTR #ifdef HAVE_SHM /* In this representation, data is found in two widely separated segments. */ -extern int pure_size; +extern size_t pure_size; #define XPNTR(a) \ (XUINT (a) | (XUINT (a) > pure_size ? DATA_SEG_BITS : PURE_SEG_BITS)) #else /* not HAVE_SHM */ @@ -419,7 +446,8 @@ extern int pure_size; #ifdef EXPLICIT_SIGN_EXTEND /* Make sure we sign-extend; compilers have been known to fail to do so. */ -#define XINT(a) (((a).i << (BITS_PER_INT-VALBITS)) >> (BITS_PER_INT-VALBITS)) +#define XINT(a) (((a).i << (BITS_PER_EMACS_INT - VALBITS)) \ + >> (BITS_PER_EMACS_INT - VALBITS)) #else #define XINT(a) ((a).s.val) #endif /* EXPLICIT_SIGN_EXTEND */ @@ -428,7 +456,7 @@ extern int pure_size; #define XPNTR(a) ((a).u.val) #define XSET(var, vartype, ptr) \ - (((var).s.val = ((int) (ptr))), ((var).s.type = ((char) (vartype)))) + (((var).s.val = ((EMACS_INT) (ptr))), ((var).s.type = ((char) (vartype)))) #if __GNUC__ >= 2 && defined (__OPTIMIZE__) #define make_number(N) \ @@ -451,15 +479,28 @@ extern Lisp_Object make_number (); #endif /* NO_UNION_TYPE */ +/* Largest and smallest representable fixnum values. These are the C + values. */ + +#define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1)) +#define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1) + +/* Value is non-zero if C integer I doesn't fit into a Lisp fixnum. */ + +#define FIXNUM_OVERFLOW_P(i) \ + ((EMACS_INT)(i) > MOST_POSITIVE_FIXNUM \ + || (EMACS_INT) (i) < MOST_NEGATIVE_FIXNUM) + /* Extract a value or address from a Lisp_Object. */ #define XCONS(a) (eassert (GC_CONSP(a)),(struct Lisp_Cons *) XPNTR(a)) -#define XVECTOR(a) ((struct Lisp_Vector *) XPNTR(a)) +#define XVECTOR(a) (eassert (GC_VECTORLIKEP(a)),(struct Lisp_Vector *) XPNTR(a)) #define XSTRING(a) (eassert (GC_STRINGP(a)),(struct Lisp_String *) XPNTR(a)) #define XSYMBOL(a) (eassert (GC_SYMBOLP(a)),(struct Lisp_Symbol *) XPNTR(a)) #define XFLOAT(a) (eassert (GC_FLOATP(a)),(struct Lisp_Float *) XPNTR(a)) /* Misc types. */ + #define XMISC(a) ((union Lisp_Misc *) XPNTR(a)) #define XMISCTYPE(a) (XMARKER (a)->type) #define XMARKER(a) (&(XMISC(a)->u_marker)) @@ -472,6 +513,7 @@ extern Lisp_Object make_number (); #define XKBOARD_OBJFWD(a) (&(XMISC(a)->u_kboard_objfwd)) /* Pseudovector types. */ + #define XPROCESS(a) (eassert (GC_PROCESSP(a)),(struct Lisp_Process *) XPNTR(a)) #define XWINDOW(a) (eassert (GC_WINDOWP(a)),(struct window *) XPNTR(a)) #define XSUBR(a) (eassert (GC_SUBRP(a)),(struct Lisp_Subr *) XPNTR(a)) @@ -479,7 +521,6 @@ extern Lisp_Object make_number (); #define XCHAR_TABLE(a) ((struct Lisp_Char_Table *) XPNTR(a)) #define XBOOL_VECTOR(a) ((struct Lisp_Bool_Vector *) XPNTR(a)) - /* Construct a Lisp_Object from a value or address. */ #define XSETINT(a, b) XSET (a, Lisp_Int, b) @@ -490,10 +531,12 @@ extern Lisp_Object make_number (); #define XSETFLOAT(a, b) XSET (a, Lisp_Float, b) /* Misc types. */ + #define XSETMISC(a, b) XSET (a, Lisp_Misc, b) #define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker) /* Pseudovector types. */ + #define XSETPSEUDOVECTOR(a, b, code) \ (XSETVECTOR (a, b), XVECTOR (a)->size |= PSEUDOVECTOR_FLAG | (code)) #define XSETWINDOW_CONFIGURATION(a, b) \ @@ -505,6 +548,13 @@ extern Lisp_Object make_number (); #define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER)) #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE)) #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR)) + +/* Convenience macros for dealing with Lisp arrays. */ + +#define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX] +#define ASET(ARRAY, IDX, VAL) (AREF ((ARRAY), (IDX)) = (VAL)) +#define ASIZE(ARRAY) XVECTOR ((ARRAY))->size + /* Basic data type for use of intervals. See the macros in intervals.h. */ @@ -516,7 +566,7 @@ struct interval unsigned int position; /* Cache of interval's character position. */ /* This field is usually updated simultaneously with an interval - traversal, there is no guaranty + traversal, there is no guarantee that it is valid for a random interval. */ struct interval *left; /* Intervals which precede me. */ @@ -562,15 +612,6 @@ typedef struct interval *INTERVAL; #define CHECK_STRING_OR_BUFFER(x, i) \ { if (!STRINGP ((x)) && !BUFFERP ((x))) \ x = wrong_type_argument (Qbuffer_or_string_p, (x)); } - -/* Macro used to conditionally compile intervals into certain data - structures. See, e.g., struct Lisp_String below. */ -#define DECLARE_INTERVALS INTERVAL intervals; - -/* Macro used to conditionally compile interval initialization into - certain code. See, e.g., alloc.c. */ -#define INITIALIZE_INTERVAL(ptr,val) ptr->intervals = val - /* In a cons, the markbit of the car is the gc mark bit */ @@ -586,14 +627,43 @@ struct Lisp_Cons }; /* Take the car or cdr of something known to be a cons cell. */ +/* The _AS_LVALUE macros shouldn't be used outside of the minimal set + of code that has to know what a cons cell looks like. Other code not + part of the basic lisp implementation should assume that the car and cdr + fields are not accessible as lvalues. (What if we want to switch to + a copying collector someday? Cached cons cell field addresses may be + invalidated at arbitrary points.) */ #ifdef HIDE_LISP_IMPLEMENTATION -#define XCAR(c) (XCONS ((c))->car_) -#define XCDR(c) (XCONS ((c))->cdr_) +#define XCAR_AS_LVALUE(c) (XCONS ((c))->car_) +#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr_) #else -#define XCAR(c) (XCONS ((c))->car) -#define XCDR(c) (XCONS ((c))->cdr) +#define XCAR_AS_LVALUE(c) (XCONS ((c))->car) +#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr) #endif +/* Okay, we're not quite ready to turn this on yet. A few files still + need to be updated and tested. */ +#undef LISP_MAKE_RVALUE +#define LISP_MAKE_RVALUE(x) (x) + +/* Use these from normal code. */ +#define XCAR(c) LISP_MAKE_RVALUE(XCAR_AS_LVALUE(c)) +#define XCDR(c) LISP_MAKE_RVALUE(XCDR_AS_LVALUE(c)) + +/* Use these to set the fields of a cons cell. + + Note that both arguments may refer to the same object, so 'n' + should not be read after 'c' is first modified. Also, neither + argument should be evaluated more than once; side effects are + especially common in the second argument. */ +#define XSETCAR(c,n) (XCAR_AS_LVALUE(c) = (n)) +#define XSETCDR(c,n) (XCDR_AS_LVALUE(c) = (n)) + +/* For performance: Fast storage of positive integers into the + fields of a cons cell. See above caveats. */ +#define XSETCARFASTINT(c,n) XSETFASTINT(XCAR_AS_LVALUE(c),(n)) +#define XSETCDRFASTINT(c,n) XSETFASTINT(XCDR_AS_LVALUE(c),(n)) + /* Take the car or cdr of something whose type is not known. */ #define CAR(c) \ (CONSP ((c)) ? XCAR ((c)) \ @@ -610,9 +680,20 @@ struct Lisp_Cons (XSTRING (STR)->size_byte >= 0) /* Return the length in bytes of STR. */ + +#ifdef GC_CHECK_STRING_BYTES + +struct Lisp_String; +extern int string_bytes P_ ((struct Lisp_String *)); +#define STRING_BYTES(S) string_bytes ((S)) + +#else /* not GC_CHECK_STRING_BYTES */ + #define STRING_BYTES(STR) \ ((STR)->size_byte < 0 ? (STR)->size : (STR)->size_byte) +#endif /* not GC_CHECK_STRING_BYTES */ + /* Set the length in bytes of STR. */ #define SET_STRING_BYTES(STR, SIZE) ((STR)->size_byte = (SIZE)) @@ -622,7 +703,7 @@ struct Lisp_String { EMACS_INT size; EMACS_INT size_byte; - DECLARE_INTERVALS /* `data' field must be last. */ + INTERVAL intervals; /* text properties in this string */ unsigned char *data; }; @@ -759,18 +840,6 @@ struct Lisp_Bool_Vector unsigned char data[1]; }; -/* In a symbol, the markbit of the plist is used as the gc mark bit */ - -struct Lisp_Symbol - { - struct Lisp_String *name; - Lisp_Object value; - Lisp_Object function; - Lisp_Object plist; - Lisp_Object obarray; - struct Lisp_Symbol *next; /* -> next symbol in this obarray bucket */ - }; - /* This structure describes a built-in function. It is generated by the DEFUN macro only. defsubr makes it into a Lisp object. @@ -789,6 +858,90 @@ struct Lisp_Subr char *doc; }; + +/*********************************************************************** + Symbols + ***********************************************************************/ + +/* Interned state of a symbol. */ + +enum symbol_interned +{ + SYMBOL_UNINTERNED = 0, + SYMBOL_INTERNED = 1, + SYMBOL_INTERNED_IN_INITIAL_OBARRAY = 2 +}; + +/* In a symbol, the markbit of the plist is used as the gc mark bit */ + +struct Lisp_Symbol +{ + /* Non-zero means symbol serves as a variable alias. The symbol + holding the real value is found in the value slot. */ + unsigned indirect_variable : 1; + + /* Non-zero means symbol is constant, i.e. changing its value + should signal an error. */ + unsigned constant : 1; + + /* Interned state of the symbol. This is an enumerator from + enum symbol_interned. */ + unsigned interned : 2; + + /* The symbol's name. This should become a Lisp_Object + some day; there's no need for the Lisp_String pointer nowadays. */ + struct Lisp_String *name; + + /* Value of the symbol or Qunbound if unbound. If this symbol is a + defvaralias, `value' contains the symbol for which it is an + alias. Use the SYMBOL_VALUE and SET_SYMBOL_VALUE macros to get + and set a symbol's value, to take defvaralias into account. */ + Lisp_Object value; + + /* Function value of the symbol or Qunbound if not fcoundp. */ + Lisp_Object function; + + /* The symbol's property list. */ + Lisp_Object plist; + + /* Next symbol in obarray bucket, if the symbol is interned. */ + struct Lisp_Symbol *next; +}; + +/* Value is non-zero if SYM is an interned symbol. */ + +#define SYMBOL_INTERNED_P(sym) \ + (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) + +/* Value is non-zero if SYM is interned in initial_obarray. */ + +#define SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P(sym) \ + (XSYMBOL (sym)->interned == SYMBOL_INTERNED_IN_INITIAL_OBARRAY) + +/* Value is non-zero if symbol is considered a constant, i.e. its + value cannot be changed (there is an exception for keyword symbols, + whose value can be set to the keyword symbol itself). */ + +#define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant + +/* Value is the value of SYM, with defvaralias taken into + account. */ + +#define SYMBOL_VALUE(sym) \ + (XSYMBOL (sym)->indirect_variable \ + ? XSYMBOL (indirect_variable (sym))->value \ + : XSYMBOL (sym)->value) + +/* Set SYM's value to VAL, taking defvaralias into account. */ + +#define SET_SYMBOL_VALUE(sym, val) \ + do { \ + if (XSYMBOL (sym)->indirect_variable) \ + XSYMBOL (indirect_variable ((sym)))->value = (val); \ + else \ + XSYMBOL (sym)->value = (val); \ + } while (0) + /*********************************************************************** Hash Tables @@ -1172,20 +1325,20 @@ typedef unsigned char UCHAR; #define GLYPH int /* Mask bits for face. */ -#define GLYPH_MASK_FACE 0x7FFFFF00 +#define GLYPH_MASK_FACE 0x7FF80000 /* Mask bits for character code. */ -#define GLYPH_MASK_CHAR 0x000000FF /* The lowest 8 bits */ +#define GLYPH_MASK_CHAR 0x0007FFFF /* The lowest 19 bits */ /* The FAST macros assume that we already know we're in an X window. */ /* Set a character code and a face ID in a glyph G. */ -#define FAST_MAKE_GLYPH(char, face) ((char) | ((face) << 8)) +#define FAST_MAKE_GLYPH(char, face) ((char) | ((face) << CHARACTERBITS)) /* Return a glyph's character code. */ #define FAST_GLYPH_CHAR(glyph) ((glyph) & GLYPH_MASK_CHAR) /* Return a glyph's face ID. */ -#define FAST_GLYPH_FACE(glyph) (((glyph) & GLYPH_MASK_FACE) >> 8) +#define FAST_GLYPH_FACE(glyph) (((glyph) & GLYPH_MASK_FACE) >> CHARACTERBITS) /* Slower versions that test the frame type first. */ #define MAKE_GLYPH(f, char, face) (FAST_MAKE_GLYPH (char, face)) @@ -1193,8 +1346,7 @@ typedef unsigned char UCHAR; #define GLYPH_FACE(f, g) (FAST_GLYPH_FACE (g)) /* Return 1 iff GLYPH contains valid character code. */ -#define GLYPH_CHAR_VALID_P(glyph) \ - ((GLYPH) (FAST_GLYPH_CHAR (glyph)) <= MAX_CHAR) +#define GLYPH_CHAR_VALID_P(glyph) CHAR_VALID_P (FAST_GLYPH_CHAR (glyph), 1) /* The ID of the mode line highlighting face. */ #define GLYPH_MODE_LINE_FACE 1 @@ -1362,6 +1514,22 @@ typedef unsigned char UCHAR; #define CHECK_OVERLAY(x, i) \ do { if (!OVERLAYP ((x))) x = wrong_type_argument (Qoverlayp, (x));} while (0) +/* Since we can't assign directly to the CAR or CDR fields of a cons + cell, use these when checking that those fields contain numbers. */ +#define CHECK_NUMBER_CAR(x, i) \ + do { \ + Lisp_Object tmp = XCAR (x); \ + CHECK_NUMBER (tmp, (i)); \ + XSETCAR ((x), tmp); \ + } while (0) + +#define CHECK_NUMBER_CDR(x, i) \ + do { \ + Lisp_Object tmp = XCDR (x); \ + CHECK_NUMBER (tmp, (i)); \ + XSETCDR ((x), tmp); \ + } while (0) + /* Cast pointers to this type to compare them. Some machines want int. */ #ifndef PNTR_COMPARISON_TYPE #define PNTR_COMPARISON_TYPE EMACS_UINT @@ -1389,13 +1557,15 @@ typedef unsigned char UCHAR; A null string means call interactively with no arguments. `doc' is documentation for the user. */ -#if !defined (__STDC__) || defined (USE_NONANSI_DEFUN) -#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc) \ +#if (!defined (__STDC__) && !defined (PROTOTYPES)) \ + || defined (USE_NONANSI_DEFUN) + +#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, args) \ Lisp_Object fnname (); \ struct Lisp_Subr sname = \ { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \ fnname, minargs, maxargs, lname, prompt, 0}; \ - Lisp_Object fnname + Lisp_Object fnname args #else @@ -1427,6 +1597,14 @@ typedef unsigned char UCHAR; Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) #endif +/* Non-zero if OBJ is a Lisp function. */ + +#define FUNCTIONP(OBJ) \ + ((CONSP (OBJ) && EQ (XCAR (OBJ), Qlambda)) \ + || (SYMBOLP (OBJ) && !NILP (Ffboundp (OBJ))) \ + || COMPILEDP (OBJ) \ + || SUBRP (OBJ)) + /* defsubr (Sname); is how we define the symbol for function `name' at start-up time. */ extern void defsubr P_ ((struct Lisp_Subr *)); @@ -1444,6 +1622,21 @@ extern void defvar_kboard P_ ((char *, int)); /* Macros we use to define forwarded Lisp variables. These are used in the syms_of_FILENAME functions. */ +#ifdef DOC_STRINGS_IN_COMMENTS + +#define DEFVAR_LISP(lname, vname) defvar_lisp (lname, vname) +#define DEFVAR_LISP_NOPRO(lname, vname) defvar_lisp_nopro (lname, vname) +#define DEFVAR_BOOL(lname, vname) defvar_bool (lname, vname) +#define DEFVAR_INT(lname, vname) defvar_int (lname, vname) +#define DEFVAR_PER_BUFFER(lname, vname, type) \ + defvar_per_buffer (lname, vname, type, 0) +#define DEFVAR_KBOARD(lname, vname) \ + defvar_kboard (lname, \ + (int)((char *)(¤t_kboard->vname) \ + - (char *)current_kboard)) + +#else /* not DOC_STRINGS_IN_COMMENTS */ + #define DEFVAR_LISP(lname, vname, doc) defvar_lisp (lname, vname) #define DEFVAR_LISP_NOPRO(lname, vname, doc) defvar_lisp_nopro (lname, vname) #define DEFVAR_BOOL(lname, vname, doc) defvar_bool (lname, vname) @@ -1454,6 +1647,10 @@ extern void defvar_kboard P_ ((char *, int)); defvar_kboard (lname, \ (int)((char *)(¤t_kboard->vname) \ - (char *)current_kboard)) + +#endif /* not DOC_STRINGS_IN_COMMENTS */ + + /* Structure for recording Lisp call stack for backtrace purposes. */ @@ -1469,12 +1666,15 @@ extern void defvar_kboard P_ ((char *, int)); form. Otherwise, the element is a variable binding. + If the symbol field is a symbol, it is an ordinary variable binding. - Otherwise, it should be a structure (SYMBOL BUFFER . BUFFER), - which represents having bound BUFFER's local value, - or (SYMBOL nil . BUFFER), which represents having bound the default - value when BUFFER was current (buffer not having any local binding - for SYMBOL). */ + + Otherwise, it should be a structure (SYMBOL WHERE + . CURRENT-BUFFER), which means having bound a local value while + CURRENT-BUFFER was active. If WHERE is nil this means we saw the + default value when binding SYMBOL. WHERE being a buffer or frame + means we saw a buffer-local or frame-local value. Other values of + WHERE mean an internal error. */ struct specbinding { @@ -1487,6 +1687,8 @@ extern struct specbinding *specpdl; extern struct specbinding *specpdl_ptr; extern int specpdl_size; +#define BINDING_STACK_SIZE() (specpdl_ptr - specpdl) + /* Everything needed to describe an active condition case. */ struct handler { @@ -1611,14 +1813,19 @@ extern int gc_cons_threshold; extern struct gcpro *gcprolist; struct gcpro - { - struct gcpro *next; - Lisp_Object *var; /* Address of first protected variable */ - int nvars; /* Number of consecutive protected variables */ +{ + struct gcpro *next; + + /* Address of first protected variable. */ + volatile Lisp_Object *var; + + /* Number of consecutive protected variables. */ + int nvars; + #ifdef DEBUG_GCPRO - int level; + int level; #endif - }; +}; /* Values of GC_MARK_STACK during compilation: @@ -1753,7 +1960,8 @@ void staticpro P_ ((Lisp_Object *)); /* Declare a Lisp-callable function. The MAXARGS parameter has the same meaning as in the DEFUN macro, and is used to construct a prototype. */ -#if !defined (__STDC__) || defined (USE_NONANSI_DEFUN) +#if (!defined (__STDC__) && !defined (PROTOTYPES)) \ + || defined (USE_NONANSI_DEFUN) #define EXFUN(fnname, maxargs) \ extern Lisp_Object fnname () #else @@ -1795,6 +2003,8 @@ extern Lisp_Object Qfloatp, Qinteger_or_floatp, Qinteger_or_float_or_marker_p; extern Lisp_Object Qframep; +extern void circular_list_error P_ ((Lisp_Object)); + EXFUN (Feq, 2); EXFUN (Fnull, 1); EXFUN (Flistp, 1); @@ -1873,17 +2083,21 @@ EXFUN (Fash, 2); EXFUN (Fadd1, 1); EXFUN (Fsub1, 1); +EXFUN (Fmake_variable_buffer_local, 1); +extern Lisp_Object indirect_variable P_ ((Lisp_Object)); extern Lisp_Object long_to_cons P_ ((unsigned long)); extern unsigned long cons_to_long P_ ((Lisp_Object)); extern void args_out_of_range P_ ((Lisp_Object, Lisp_Object)); extern void args_out_of_range_3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); extern Lisp_Object wrong_type_argument P_ ((Lisp_Object, Lisp_Object)); -extern void store_symval_forwarding P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); +extern void store_symval_forwarding P_ ((Lisp_Object, Lisp_Object, + Lisp_Object, struct buffer *)); extern Lisp_Object do_symval_forwarding P_ ((Lisp_Object)); extern Lisp_Object set_internal P_ ((Lisp_Object, Lisp_Object, struct buffer *, int)); extern void syms_of_data P_ ((void)); extern void init_data P_ ((void)); +extern void swap_in_global_binding P_ ((Lisp_Object)); /* Defined in cmds.c */ EXFUN (Fend_of_line, 1); @@ -1902,7 +2116,7 @@ EXFUN (Fread_non_nil_coding_system, 1); EXFUN (Ffind_operation_coding_system, MANY); EXFUN (Fencode_coding_string, 3); EXFUN (Fdecode_coding_string, 3); -extern Lisp_Object detect_coding_system P_ ((unsigned char *, int, int)); +extern Lisp_Object detect_coding_system P_ ((unsigned char *, int, int, int)); Lisp_Object code_convert_string_norecord P_ ((Lisp_Object, Lisp_Object, int)); extern void init_coding P_ ((void)); extern void init_coding_once P_ ((void)); @@ -1935,9 +2149,12 @@ extern void init_syntax_once P_ ((void)); extern void syms_of_syntax P_ ((void)); /* Defined in fns.c */ +extern int use_dialog_box; +extern int next_almost_prime P_ ((int)); extern Lisp_Object larger_vector P_ ((Lisp_Object, int, Lisp_Object)); extern void sweep_weak_hash_tables P_ ((void)); extern Lisp_Object Qstring_lessp; +EXFUN (Foptimize_char_table, 1); extern Lisp_Object Vfeatures; extern Lisp_Object QCtest, QCweakness, Qequal; unsigned sxhash P_ ((Lisp_Object, int)); @@ -2004,9 +2221,8 @@ EXFUN (Fmapcar, 2); EXFUN (Fmapconcat, 3); EXFUN (Fy_or_n_p, 1); extern Lisp_Object do_yes_or_no_p P_ ((Lisp_Object)); -EXFUN (Ffeaturep, 1); EXFUN (Frequire, 3); -EXFUN (Fprovide, 1); +EXFUN (Fprovide, 2); extern Lisp_Object concat2 P_ ((Lisp_Object, Lisp_Object)); extern Lisp_Object concat3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); extern Lisp_Object nconc2 P_ ((Lisp_Object, Lisp_Object)); @@ -2030,6 +2246,7 @@ extern int char_table_translate P_ ((Lisp_Object, int)); extern void map_char_table P_ ((void (*) (Lisp_Object, Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, int, Lisp_Object *)); +extern Lisp_Object char_table_ref_and_index P_ ((Lisp_Object, int, int *)); extern void syms_of_fns P_ ((void)); /* Defined in floatfns.c */ @@ -2040,6 +2257,7 @@ extern void init_floatfns P_ ((void)); extern void syms_of_floatfns P_ ((void)); /* Defined in insdel.c */ +extern Lisp_Object Qinhibit_modification_hooks; extern void move_gap P_ ((int)); extern void move_gap_both P_ ((int, int)); extern void make_gap P_ ((int)); @@ -2085,13 +2303,17 @@ extern void syms_of_display P_ ((void)); extern void safe_bcopy P_ ((char *, char *, int)); /* Defined in xdisp.c */ -extern Lisp_Object Qinhibit_redisplay; +extern Lisp_Object Qinhibit_point_motion_hooks; +extern Lisp_Object Qinhibit_redisplay, Qdisplay; +extern Lisp_Object Qinhibit_eval_during_redisplay; +extern Lisp_Object Qmessage_truncate_lines; extern Lisp_Object Vmessage_log_max; extern int message_enable_multibyte; extern Lisp_Object echo_area_buffer[2]; extern void check_message_stack P_ ((void)); extern void setup_echo_area_for_printing P_ ((int)); extern int push_message P_ ((void)); +extern Lisp_Object push_message_unwind P_ ((Lisp_Object)); extern void pop_message P_ ((void)); extern void restore_message P_ ((void)); extern Lisp_Object current_message P_ ((void)); @@ -2113,17 +2335,19 @@ extern void truncate_echo_area P_ ((int)); extern void redisplay P_ ((void)); extern int check_point_in_composition P_ ((struct buffer *, int, struct buffer *, int)); -extern void redisplay_preserve_echo_area P_ ((void)); +extern void redisplay_preserve_echo_area P_ ((int)); extern void mark_window_display_accurate P_ ((Lisp_Object, int)); -extern int invisible_p P_ ((Lisp_Object, Lisp_Object)); extern void prepare_menu_bars P_ ((void)); extern void syms_of_xdisp P_ ((void)); extern void init_xdisp P_ ((void)); +extern Lisp_Object safe_eval P_ ((Lisp_Object)); +extern int pos_visible_p P_ ((struct window *, int, int *, int)); /* Defined in vm-limit.c. */ extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ())); /* Defined in alloc.c */ +extern void check_pure_size P_ ((void)); extern void allocate_string_data P_ ((struct Lisp_String *, int, int)); extern void uninterrupt_malloc P_ ((void)); extern void malloc_warning P_ ((char *)); @@ -2164,7 +2388,12 @@ EXFUN (Fmake_bool_vector, 2); EXFUN (Fmake_char_table, 2); extern Lisp_Object make_sub_char_table P_ ((Lisp_Object)); extern Lisp_Object Qchar_table_extra_slots; -extern struct Lisp_Vector *allocate_vectorlike P_ ((EMACS_INT)); +extern struct Lisp_Vector *allocate_vector P_ ((EMACS_INT)); +extern struct Lisp_Vector *allocate_other_vector P_ ((EMACS_INT)); +extern struct Lisp_Hash_Table *allocate_hash_table P_ ((void)); +extern struct window *allocate_window P_ ((void)); +extern struct frame *allocate_frame P_ ((void)); +extern struct Lisp_Process *allocate_process P_ ((void)); extern int gc_in_progress; extern Lisp_Object make_float P_ ((double)); extern void display_malloc_warning P_ ((void)); @@ -2221,8 +2450,9 @@ extern Lisp_Object oblookup P_ ((Lisp_Object, char *, int, int)); #define LOADHIST_ATTACH(x) \ if (initialized) Vcurrent_load_list = Fcons (x, Vcurrent_load_list) extern Lisp_Object Vcurrent_load_list; -extern Lisp_Object Vload_history; -extern int openp P_ ((Lisp_Object, Lisp_Object, char *, Lisp_Object *, int)); +extern Lisp_Object Vload_history, Vload_suffixes; +extern int openp P_ ((Lisp_Object, Lisp_Object, Lisp_Object, + Lisp_Object *, int)); extern int isfloat_string P_ ((char *)); extern void map_obarray P_ ((Lisp_Object, void (*) (Lisp_Object, Lisp_Object), Lisp_Object)); @@ -2238,6 +2468,10 @@ extern Lisp_Object Vinhibit_quit, Qinhibit_quit, Vquit_flag; extern Lisp_Object Vmocklisp_arguments, Qmocklisp, Qmocklisp_arguments; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vdebug_on_error; +extern Lisp_Object Vsignaling_function; +extern int handling_signal; +extern int interactive_p P_ ((int)); + /* To run a normal hook, use the appropriate function from the list below. The calling convention: @@ -2267,7 +2501,7 @@ EXFUN (Flet, UNEVALLED); EXFUN (FletX, UNEVALLED); EXFUN (Fwhile, UNEVALLED); EXFUN (Fcatch, UNEVALLED); -EXFUN (Fthrow, 2); +EXFUN (Fthrow, 2) NO_RETURN; EXFUN (Funwind_protect, UNEVALLED); EXFUN (Fcondition_case, UNEVALLED); EXFUN (Fsignal, 2); @@ -2290,14 +2524,17 @@ extern Lisp_Object apply_lambda P_ ((Lisp_Object, Lisp_Object, int)); extern Lisp_Object internal_catch P_ ((Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object)); extern Lisp_Object internal_condition_case P_ ((Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object))); extern Lisp_Object internal_condition_case_1 P_ ((Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object))); +extern Lisp_Object internal_condition_case_2 P_ ((Lisp_Object (*) (int, Lisp_Object *), int, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object))); extern void specbind P_ ((Lisp_Object, Lisp_Object)); extern void record_unwind_protect P_ ((Lisp_Object (*) (Lisp_Object), Lisp_Object)); extern Lisp_Object unbind_to P_ ((int, Lisp_Object)); -extern void error P_ ((/* char *, ... */)); +extern void error P_ ((/* char *, ... */)) NO_RETURN; extern void do_autoload P_ ((Lisp_Object, Lisp_Object)); extern Lisp_Object un_autoload P_ ((Lisp_Object)); EXFUN (Ffetch_bytecode, 1); extern void init_eval_once P_ ((void)); +extern Lisp_Object safe_call P_ ((int, Lisp_Object *)); +extern Lisp_Object safe_call1 P_ ((Lisp_Object, Lisp_Object)); extern void init_eval P_ ((void)); extern void syms_of_eval P_ ((void)); @@ -2350,13 +2587,16 @@ extern void init_editfns P_ ((void)); extern void syms_of_editfns P_ ((void)); EXFUN (Fcurrent_message, 0); extern Lisp_Object Vinhibit_field_text_motion; -EXFUN (Fconstrain_to_field, 4); +EXFUN (Fconstrain_to_field, 5); EXFUN (Ffield_string, 1); EXFUN (Fdelete_field, 1); EXFUN (Ffield_beginning, 2); +EXFUN (Ffield_end, 2); EXFUN (Ffield_string_no_properties, 1); +extern void set_time_zone_rule P_ ((char *)); /* defined in buffer.c */ +extern int mouse_face_overlay_overlaps P_ ((Lisp_Object)); extern void nsberror P_ ((Lisp_Object)); extern char *no_switch_window P_ ((Lisp_Object window)); EXFUN (Fset_buffer_multibyte, 1); @@ -2390,6 +2630,7 @@ extern Lisp_Object Qoverlayp; extern Lisp_Object get_truename_buffer P_ ((Lisp_Object)); extern struct buffer *all_buffers; EXFUN (Fprevious_overlay_change, 1); +EXFUN (Fbuffer_file_name, 1); extern void init_buffer_once P_ ((void)); extern void init_buffer P_ ((void)); extern void syms_of_buffer P_ ((void)); @@ -2443,6 +2684,7 @@ extern int internal_delete_file P_ ((Lisp_Object)); extern void syms_of_fileio P_ ((void)); EXFUN (Fmake_temp_name, 1); extern void init_fileio_once P_ ((void)); +extern Lisp_Object make_temp_name P_ ((Lisp_Object, int)); /* Defined in abbrev.c */ @@ -2457,6 +2699,7 @@ EXFUN (Fmatch_data, 2); EXFUN (Fset_match_data, 1); EXFUN (Fmatch_beginning, 1); EXFUN (Fmatch_end, 1); +EXFUN (Flooking_at, 1); extern int fast_string_match P_ ((Lisp_Object, Lisp_Object)); extern int fast_c_string_match_ignore_case P_ ((Lisp_Object, char *)); extern int scan_buffer P_ ((int, int, int, int, int *, int)); @@ -2514,10 +2757,16 @@ extern void syms_of_casetab P_ ((void)); /* defined in keyboard.c */ -extern Lisp_Object Qdisabled; +extern int echoing; +extern Lisp_Object echo_message_buffer; +extern struct kboard *echo_kboard; +extern void cancel_echoing P_ ((void)); +extern Lisp_Object Qdisabled, QCfilter; extern Lisp_Object Vtty_erase_char, Vhelp_form, Vtop_level; +extern int input_pending; EXFUN (Fdiscard_input, 0); EXFUN (Frecursive_edit, 0); +EXFUN (Ftop_level, 0); EXFUN (Fcommand_execute, 4); EXFUN (Finput_pending_p, 0); extern Lisp_Object menu_bar_items P_ ((Lisp_Object)); @@ -2537,35 +2786,8 @@ extern void record_auto_save P_ ((void)); extern void init_keyboard P_ ((void)); extern void syms_of_keyboard P_ ((void)); extern void keys_of_keyboard P_ ((void)); +extern char *push_key_description P_ ((unsigned int, char *, int)); -/* defined in keymap.c */ - -extern Lisp_Object Qkeymap, Qmenu_bar; -extern Lisp_Object current_global_map; -EXFUN (Fmake_sparse_keymap, 1); -EXFUN (Fcopy_keymap, 1); -EXFUN (Fdefine_key, 3); -EXFUN (Flookup_key, 3); -EXFUN (Fkey_binding, 2); -EXFUN (Fkey_description, 1); -EXFUN (Fsingle_key_description, 1); -EXFUN (Fwhere_is_internal, 4); -extern Lisp_Object access_keymap P_ ((Lisp_Object, Lisp_Object, int, int)); -extern Lisp_Object store_in_keymap P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); -extern Lisp_Object get_keyelt P_ ((Lisp_Object, int)); -extern Lisp_Object get_keymap P_ ((Lisp_Object)); -extern Lisp_Object get_keymap_1 P_ ((Lisp_Object, int, int)); -extern void describe_vector P_ ((Lisp_Object, Lisp_Object, - void (*) (Lisp_Object), int, - Lisp_Object, Lisp_Object, int *, int)); -extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object, - char *, int, int, int)); -extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **)); -extern void initial_define_key P_ ((Lisp_Object, int, char *)); -extern void initial_define_lispy_key P_ ((Lisp_Object, char *, char *)); -extern void fix_submap_inheritance P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); -extern void syms_of_keymap P_ ((void)); -extern void keys_of_keymap P_ ((void)); /* defined in indent.c */ EXFUN (Fvertical_motion, 2); @@ -2579,12 +2801,14 @@ extern void syms_of_indent P_ ((void)); /* defined in window.c */ extern Lisp_Object Qwindowp, Qwindow_live_p; +extern Lisp_Object Vwindow_list; EXFUN (Fwindow_end, 2); EXFUN (Fselected_window, 0); EXFUN (Fnext_window, 3); EXFUN (Fdelete_window, 1); EXFUN (Fselect_window, 1); EXFUN (Fset_window_buffer, 2); +EXFUN (Fwindow_buffer, 1); EXFUN (Fget_buffer_window, 2); EXFUN (Fsave_window_excursion, UNEVALLED); EXFUN (Fsplit_window, 3); @@ -2593,7 +2817,7 @@ EXFUN (Fcurrent_window_configuration, 1); extern int compare_window_configurations P_ ((Lisp_Object, Lisp_Object, int)); EXFUN (Fcoordinates_in_window_p, 2); EXFUN (Fwindow_at, 3); -EXFUN (Fpos_visible_in_window_p, 2); +EXFUN (Fpos_visible_in_window_p, 3); extern void mark_window_cursors_off P_ ((struct window *)); extern int window_internal_height P_ ((struct window *)); extern int window_internal_width P_ ((struct window *)); @@ -2603,6 +2827,7 @@ EXFUN (Fset_window_start, 3); extern void temp_output_buffer_show P_ ((Lisp_Object)); extern void replace_buffer_in_all_windows P_ ((Lisp_Object)); extern void init_window_once P_ ((void)); +extern void init_window P_ ((void)); extern void syms_of_window P_ ((void)); extern void keys_of_window P_ ((void)); @@ -2610,7 +2835,7 @@ extern void keys_of_window P_ ((void)); extern Lisp_Object Qvisible; extern void store_frame_param P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void store_in_alist P_ ((Lisp_Object *, Lisp_Object, Lisp_Object)); -extern Lisp_Object do_switch_frame P_ ((Lisp_Object, Lisp_Object, int)); +extern Lisp_Object do_switch_frame P_ ((Lisp_Object, int, int)); extern Lisp_Object get_frame_param P_ ((struct frame *, Lisp_Object)); extern Lisp_Object frame_buffer_predicate P_ ((Lisp_Object)); EXFUN (Fframep, 1); @@ -2629,6 +2854,7 @@ EXFUN (Fmake_frame_invisible, 2); EXFUN (Ficonify_frame, 1); EXFUN (Fframe_visible_p, 1); EXFUN (Fvisible_frame_list, 0); +EXFUN (Fframe_parameter, 2); EXFUN (Fframe_parameters, 1); EXFUN (Fmodify_frame_parameters, 2); EXFUN (Fset_frame_height, 3); @@ -2648,7 +2874,7 @@ extern void keys_of_frame P_ ((void)); /* defined in emacs.c */ extern Lisp_Object decode_env_path P_ ((char *, char *)); extern Lisp_Object Vinvocation_name, Vinvocation_directory; -extern Lisp_Object Vinstallation_directory; +extern Lisp_Object Vinstallation_directory, empty_string; EXFUN (Fkill_emacs, 1); #if HAVE_SETLOCALE void fixup_locale P_ ((void)); @@ -2689,7 +2915,8 @@ extern void init_process P_ ((void)); extern void syms_of_process P_ ((void)); /* defined in callproc.c */ -extern Lisp_Object Vexec_path, Vexec_directory, Vdata_directory; +extern Lisp_Object Vexec_path, Vexec_suffixes, + Vexec_directory, Vdata_directory; extern Lisp_Object Vdoc_directory; EXFUN (Fcall_process, MANY); extern int child_setup P_ ((int, int, int, char **, int, Lisp_Object)); @@ -2738,10 +2965,11 @@ extern void syms_of_undo P_ ((void)); /* defined in textprop.c */ extern Lisp_Object Qmodification_hooks; -extern Lisp_Object Qrear_nonsticky, Qfont; +extern Lisp_Object Qrear_nonsticky, Qfont, Qmouse_face; extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks; EXFUN (Fnext_property_change, 3); EXFUN (Fnext_single_property_change, 4); +EXFUN (Fnext_single_char_property_change, 4); EXFUN (Fprevious_single_property_change, 4); EXFUN (Fget_text_property, 3); EXFUN (Fput_text_property, 5); @@ -2820,7 +3048,7 @@ extern void syms_of_mocklisp P_ ((void)); /* Defined in term.c */ extern void syms_of_term P_ ((void)); -extern void fatal (); +extern void fatal () NO_RETURN; #ifdef HAVE_X_WINDOWS /* Defined in fontset.c */ @@ -2836,14 +3064,10 @@ extern int getloadavg P_ ((double *, int)); #ifdef HAVE_X_WINDOWS /* Defined in xfns.c */ -extern void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); extern void syms_of_xfns P_ ((void)); extern void init_xfns P_ ((void)); +extern Lisp_Object Vx_resource_name; EXFUN (Fxw_display_color_p, 1); -#ifdef HAVE_X_I18N -extern void free_frame_xic P_ ((struct frame *)); -#endif -/* Fixme: x_defined_color needs declaring, but needs FRAME_PTR and XColor. */ #endif /* HAVE_X_WINDOWS */ /* Defined in xselect.c */ @@ -2854,21 +3078,22 @@ extern void syms_of_xterm P_ ((void)); /* Defined in getloadavg.c */ extern int getloadavg P_ ((double [], int)); - -/* Defined in composite.c */ -extern void compose_text P_ ((int, int, Lisp_Object, Lisp_Object, Lisp_Object)); + /* Nonzero means Emacs has already been initialized. Used during startup to detect startup of dumped Emacs. */ extern int initialized; extern int immediate_quit; /* Nonzero means ^G can quit instantly */ -extern char *getenv (), *ctime (), *getwd (); -extern long *xmalloc (), *xrealloc (); -extern void xfree (); +extern POINTER_TYPE *xmalloc P_ ((size_t)); +extern POINTER_TYPE *xrealloc P_ ((POINTER_TYPE *, size_t)); +extern void xfree P_ ((POINTER_TYPE *)); + extern char *xstrdup P_ ((char *)); +#ifndef USE_CRT_DLL extern char *egetenv P_ ((char *)); +#endif /* Set up the name of the machine we're running on. */ extern void init_system_name P_ ((void)); @@ -2903,3 +3128,46 @@ extern Lisp_Object Vdirectory_sep_char; #else #define SWITCH_ENUM_CAST(x) (x) #endif + +/* Loop over Lisp list LIST. Signal an error if LIST is not a proper + list, or if it contains circles. + + HARE and TORTOISE should be the names of Lisp_Object variables, and + N should be the name of an EMACS_INT variable declared in the + function where the macro is used. Each nested loop should use + its own variables. + + In the loop body, HARE is set to each cons of LIST, and N is the + length of the list processed so far. */ + +#define LIST_END_P(list, obj) \ + (NILP (obj) \ + ? 1 \ + : (CONSP (obj) \ + ? 0 \ + : (wrong_type_argument (Qlistp, (list), 0)), 1)) + +#define FOREACH(hare, list, tortoise, n) \ + for (tortoise = hare = (list), n = 0; \ + !LIST_END_P (list, hare); \ + (hare = XCDR (hare), ++n, \ + ((n & 1) != 0 \ + ? (tortoise = XCDR (tortoise), \ + (EQ (hare, tortoise) \ + && (circular_list_error ((list)), 1))) \ + : 0))) + +/* The ubiquitous min and max macros. */ + +#ifdef max +#undef max +#undef min +#endif +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) + +/* Return a fixnum or float, depending on whether VAL fits in a Lisp + fixnum. */ + +#define make_fixnum_or_float(val) \ + (FIXNUM_OVERFLOW_P (val) ? make_float (val) : make_number (val))