X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/d8a05828fd9f78c6cadddd8b47b53d83833c3917..e7c1b6ef850e7b4d021fabf4a922010781ed05bd:/src/lisp.h diff --git a/src/lisp.h b/src/lisp.h index 2928f92df3..c3cabe0af2 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -20,14 +20,22 @@ along with GNU Emacs. If not, see . */ #ifndef EMACS_LISP_H #define EMACS_LISP_H +#include #include #include +#include #include +#include #include #include #include +INLINE_HEADER_BEGIN +#ifndef LISP_INLINE +# define LISP_INLINE INLINE +#endif + /* The ubiquitous max and min macros. */ #undef min #undef max @@ -118,7 +126,7 @@ extern _Noreturn void die (const char *, const char *, int); eassert macro altogether, e.g., if XSTRING (x) uses eassert to test STRINGP (x), but a particular use of XSTRING is invoked only after testing that STRINGP (x) is true, making the test redundant. */ -extern int suppress_checking EXTERNALLY_VISIBLE; +extern bool suppress_checking EXTERNALLY_VISIBLE; # define eassert(cond) \ ((cond) || suppress_checking \ @@ -295,14 +303,14 @@ enum Lisp_Fwd_Type typedef struct { EMACS_INT i; } Lisp_Object; #define XLI(o) (o).i -static inline Lisp_Object +LISP_INLINE Lisp_Object XIL (EMACS_INT i) { Lisp_Object o = { i }; return o; } -static inline Lisp_Object +LISP_INLINE Lisp_Object LISP_MAKE_RVALUE (Lisp_Object o) { return o; @@ -319,18 +327,22 @@ enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 1 }; typedef EMACS_INT Lisp_Object; #define XLI(o) (o) #define XIL(i) (i) -#define LISP_MAKE_RVALUE(o) (0+(o)) +#define LISP_MAKE_RVALUE(o) (0 + (o)) #define LISP_INITIALLY_ZERO 0 enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = 0 }; #endif /* CHECK_LISP_OBJECT_TYPE */ /* In the size word of a vector, this bit means the vector has been marked. */ -static ptrdiff_t const ARRAY_MARK_FLAG = PTRDIFF_MIN; +static ptrdiff_t const ARRAY_MARK_FLAG +#define ARRAY_MARK_FLAG PTRDIFF_MIN + = ARRAY_MARK_FLAG; /* In the size word of a struct Lisp_Vector, this bit means it's really some other vector-like object. */ -static ptrdiff_t const PSEUDOVECTOR_FLAG = PTRDIFF_MAX - PTRDIFF_MAX / 2; +static ptrdiff_t const PSEUDOVECTOR_FLAG +#define PSEUDOVECTOR_FLAG (PTRDIFF_MAX - PTRDIFF_MAX / 2) + = PSEUDOVECTOR_FLAG; /* In a pseudovector, the size field actually contains a word with one PSEUDOVECTOR_FLAG bit set, and exactly one of the following bits to @@ -407,16 +419,18 @@ enum lsb_bits #define XINT(a) (XLI (a) >> INTTYPEBITS) #define XUINT(a) ((EMACS_UINT) XLI (a) >> INTTYPEBITS) #define make_number(N) XIL ((EMACS_INT) (N) << INTTYPEBITS) -#define XSET(var, type, ptr) \ +#define make_lisp_ptr(ptr, type) \ (eassert (XTYPE (XIL ((intptr_t) (ptr))) == 0), /* Check alignment. */ \ - (var) = XIL ((type) | (intptr_t) (ptr))) + XIL ((type) | (intptr_t) (ptr))) #define XPNTR(a) ((intptr_t) (XLI (a) & ~TYPEMASK)) #define XUNTAG(a, type) ((intptr_t) (XLI (a) - (type))) #else /* not USE_LSB_TAG */ -static EMACS_INT const VALMASK = VAL_MAX; +static EMACS_INT const VALMASK +#define VALMASK VAL_MAX + = VALMASK; #define XTYPE(a) ((enum Lisp_Type) ((EMACS_UINT) XLI (a) >> VALBITS)) @@ -432,13 +446,13 @@ static EMACS_INT const VALMASK = VAL_MAX; #define XUINT(a) ((EMACS_UINT) (XLI (a) & INTMASK)) #define make_number(N) XIL ((EMACS_INT) (N) & INTMASK) -#define XSET(var, type, ptr) \ - ((var) = XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ - + ((intptr_t) (ptr) & VALMASK))) +#define make_lisp_ptr(ptr, type) \ + (XIL ((EMACS_INT) ((EMACS_UINT) (type) << VALBITS) \ + + ((intptr_t) (ptr) & VALMASK))) #if DATA_SEG_BITS /* DATA_SEG_BITS forces extra bits to be or'd in with any pointers - which were stored in a Lisp_Object */ + which were stored in a Lisp_Object. */ #define XPNTR(a) ((uintptr_t) ((XLI (a) & VALMASK)) | DATA_SEG_BITS)) #else #define XPNTR(a) ((uintptr_t) (XLI (a) & VALMASK)) @@ -480,7 +494,7 @@ static EMACS_INT const MOST_NEGATIVE_FIXNUM = #define FIXNUM_OVERFLOW_P(i) \ (! ((0 <= (i) || MOST_NEGATIVE_FIXNUM <= (i)) && (i) <= MOST_POSITIVE_FIXNUM)) -static inline ptrdiff_t +LISP_INLINE ptrdiff_t clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) { return num < lower ? lower : num <= upper ? num : upper; @@ -542,16 +556,16 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) /* Construct a Lisp_Object from a value or address. */ -#define XSETINT(a, b) (a) = make_number (b) -#define XSETCONS(a, b) XSET (a, Lisp_Cons, b) -#define XSETVECTOR(a, b) XSET (a, Lisp_Vectorlike, b) -#define XSETSTRING(a, b) XSET (a, Lisp_String, b) -#define XSETSYMBOL(a, b) XSET (a, Lisp_Symbol, b) -#define XSETFLOAT(a, b) XSET (a, Lisp_Float, b) +#define XSETINT(a, b) ((a) = make_number (b)) +#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons)) +#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike)) +#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String)) +#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol)) +#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float)) /* Misc types. */ -#define XSETMISC(a, b) XSET (a, Lisp_Misc, b) +#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc)) #define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker) /* Pseudovector types. */ @@ -594,11 +608,9 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX] #define ASIZE(ARRAY) XVECTOR ((ARRAY))->header.size -/* The IDX==IDX tries to detect when the macro argument is side-effecting. */ #define ASET(ARRAY, IDX, VAL) \ - (eassert ((IDX) == (IDX)), \ - eassert ((IDX) >= 0 && (IDX) < ASIZE (ARRAY)), \ - AREF ((ARRAY), (IDX)) = (VAL)) + (eassert (0 <= (IDX) && (IDX) < ASIZE (ARRAY)), \ + XVECTOR (ARRAY)->contents[IDX] = (VAL)) /* Convenience macros for dealing with Lisp strings. */ @@ -622,10 +634,7 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) #define CHECK_TYPE(ok, Qxxxp, x) \ do { if (!(ok)) wrong_type_argument (Qxxxp, (x)); } while (0) -/* Lisp fields are usually hidden from most code and accessed - via special macros. Only select pieces of code, like the GC, - are allowed to use INTERNAL_FIELD directly. Objects which - aren't using this convention should be fixed. */ +/* Deprecated and will be removed soon. */ #define INTERNAL_FIELD(field) field ## _ @@ -633,24 +642,19 @@ clip_to_bounds (ptrdiff_t lower, EMACS_INT num, ptrdiff_t upper) typedef struct interval *INTERVAL; -/* Complain if object is not string or buffer type */ +/* Complain if object is not string or buffer type. */ #define CHECK_STRING_OR_BUFFER(x) \ CHECK_TYPE (STRINGP (x) || BUFFERP (x), Qbuffer_or_string_p, x) -/* Most code should use this macro to - access Lisp fields in struct Lisp_Cons. */ - -#define CVAR(cons, field) ((cons)->INTERNAL_FIELD (field)) - struct Lisp_Cons { /* Car of this cons cell. */ - Lisp_Object INTERNAL_FIELD (car); + Lisp_Object car; union { /* Cdr of this cons cell. */ - Lisp_Object INTERNAL_FIELD (cdr); + Lisp_Object cdr; /* Used to chain conses on a free list. */ struct Lisp_Cons *chain; @@ -664,8 +668,8 @@ struct Lisp_Cons 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.) */ -#define XCAR_AS_LVALUE(c) (CVAR (XCONS (c), car)) -#define XCDR_AS_LVALUE(c) (CVAR (XCONS (c), u.cdr)) +#define XCAR_AS_LVALUE(c) (XCONS (c)->car) +#define XCDR_AS_LVALUE(c) (XCONS (c)->u.cdr) /* Use these from normal code. */ #define XCAR(c) LISP_MAKE_RVALUE (XCAR_AS_LVALUE (c)) @@ -698,7 +702,7 @@ struct Lisp_Cons #define CDR_SAFE(c) \ (CONSP ((c)) ? XCDR ((c)) : Qnil) -/* Nonzero if STR is a multibyte string. */ +/* True if STR is a multibyte string. */ #define STRING_MULTIBYTE(STR) \ (XSTRING (STR)->size_byte >= 0) @@ -749,12 +753,6 @@ static ptrdiff_t const STRING_BYTES_BOUND = (STR) = empty_multibyte_string; \ else XSTRING (STR)->size_byte = XSTRING (STR)->size; } while (0) -/* Get text properties. */ -#define STRING_INTERVALS(STR) (XSTRING (STR)->intervals + 0) - -/* Set text properties. */ -#define STRING_SET_INTERVALS(STR, INT) (XSTRING (STR)->intervals = (INT)) - /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ struct Lisp_String @@ -813,25 +811,49 @@ struct vectorlike_header } next; }; +/* Regular vector is just a header plus array of Lisp_Objects. */ + struct Lisp_Vector { struct vectorlike_header header; Lisp_Object contents[1]; }; +/* A boolvector is a kind of vectorlike, with contents are like a string. */ + +struct Lisp_Bool_Vector + { + /* HEADER.SIZE is the vector's size field. It doesn't have the real size, + just the subtype information. */ + struct vectorlike_header header; + /* This is the size in bits. */ + EMACS_INT size; + /* This contains the actual bits, packed into bytes. */ + unsigned char data[1]; + }; + +/* Some handy constants for calculating sizes + and offsets, mostly of vectorlike objects. */ + +enum + { + header_size = offsetof (struct Lisp_Vector, contents), + bool_header_size = offsetof (struct Lisp_Bool_Vector, data), + word_size = sizeof (Lisp_Object) + }; + /* If a struct is made to look like a vector, this macro returns the length of the shortest vector that would hold that struct. */ -#define VECSIZE(type) ((sizeof (type) \ - - offsetof (struct Lisp_Vector, contents[0]) \ - + sizeof (Lisp_Object) - 1) /* Round up. */ \ - / sizeof (Lisp_Object)) + +#define VECSIZE(type) \ + ((sizeof (type) - header_size + word_size - 1) / word_size) /* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields at the end and we need to compute the number of Lisp_Object fields (the ones that the GC needs to trace). */ -#define PSEUDOVECSIZE(type, nonlispfield) \ - ((offsetof (type, nonlispfield) - offsetof (struct Lisp_Vector, contents[0])) \ - / sizeof (Lisp_Object)) + +#define PSEUDOVECSIZE(type, nonlispfield) \ + ((offsetof (type, nonlispfield) - header_size) / word_size) /* A char-table is a kind of vectorlike, with contents are like a vector but with a few other slots. For some purposes, it makes @@ -889,19 +911,11 @@ struct Lisp_Vector (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \ : char_table_ref ((CT), (IDX))) -/* Almost equivalent to Faref (CT, IDX). However, if the result is - not a character, return IDX. - - For these characters, do not check validity of CT - and do not follow parent. */ -#define CHAR_TABLE_TRANSLATE(CT, IDX) \ - char_table_translate (CT, IDX) - /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 8-bit European characters. Do not check validity of CT. */ #define CHAR_TABLE_SET(CT, IDX, VAL) \ (ASCII_CHAR_P (IDX) && SUB_CHAR_TABLE_P (XCHAR_TABLE (CT)->ascii) \ - ? XSUB_CHAR_TABLE (XCHAR_TABLE (CT)->ascii)->contents[IDX] = VAL \ + ? set_sub_char_table_contents (XCHAR_TABLE (CT)->ascii, IDX, VAL) \ : char_table_set (CT, IDX, VAL)) enum CHARTAB_SIZE_BITS @@ -914,8 +928,6 @@ enum CHARTAB_SIZE_BITS extern const int chartab_size[4]; -struct Lisp_Sub_Char_Table; - struct Lisp_Char_Table { /* HEADER.SIZE is the vector's size field, which also holds the @@ -964,21 +976,10 @@ struct Lisp_Sub_Char_Table /* Minimum character covered by the sub char-table. */ Lisp_Object min_char; + /* Use set_sub_char_table_contents to set this. */ Lisp_Object contents[1]; }; -/* A boolvector is a kind of vectorlike, with contents are like a string. */ -struct Lisp_Bool_Vector - { - /* HEADER.SIZE is the vector's size field. It doesn't have the real size, - just the subtype information. */ - struct vectorlike_header header; - /* This is the size in bits. */ - EMACS_INT size; - /* This contains the actual bits, packed into bytes. */ - unsigned char data[1]; - }; - /* This structure describes a built-in function. It is generated by the DEFUN macro only. defsubr makes it into a Lisp object. @@ -1044,11 +1045,6 @@ enum symbol_redirect SYMBOL_FORWARDED = 3 }; -/* Most code should use this macro to access - Lisp fields in struct Lisp_Symbol. */ - -#define SVAR(sym, field) ((sym)->INTERNAL_FIELD (field)) - struct Lisp_Symbol { unsigned gcmarkbit : 1; @@ -1073,25 +1069,23 @@ struct Lisp_Symbol special (with `defvar' etc), and shouldn't be lexically bound. */ unsigned declared_special : 1; - /* The symbol's name, as a Lisp string. - The name "xname" is used to intentionally break code referring to - the old field "name" of type pointer to struct Lisp_String. */ - Lisp_Object INTERNAL_FIELD (xname); + /* The symbol's name, as a Lisp string. */ + Lisp_Object name; /* Value of the symbol or Qunbound if unbound. Which alternative of the union is used depends on the `redirect' field above. */ union { - Lisp_Object INTERNAL_FIELD (value); + Lisp_Object value; struct Lisp_Symbol *alias; struct Lisp_Buffer_Local_Value *blv; union Lisp_Fwd *fwd; } val; /* Function value of the symbol or Qunbound if not fboundp. */ - Lisp_Object INTERNAL_FIELD (function); + Lisp_Object function; /* The symbol's property list. */ - Lisp_Object INTERNAL_FIELD (plist); + Lisp_Object plist; /* Next symbol in obarray bucket, if the symbol is interned. */ struct Lisp_Symbol *next; @@ -1099,43 +1093,42 @@ struct Lisp_Symbol /* Value is name of symbol. */ -#define SYMBOL_VAL(sym) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), SVAR (sym, val.value)) -#define SYMBOL_ALIAS(sym) \ +#define SYMBOL_VAL(sym) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), sym->val.value) +#define SYMBOL_ALIAS(sym) \ (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias) -#define SYMBOL_BLV(sym) \ +#define SYMBOL_BLV(sym) \ (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv) -#define SYMBOL_FWD(sym) \ +#define SYMBOL_FWD(sym) \ (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd) -#define SET_SYMBOL_VAL(sym, v) \ - (eassert ((sym)->redirect == SYMBOL_PLAINVAL), SVAR (sym, val.value) = (v)) -#define SET_SYMBOL_ALIAS(sym, v) \ +#define SET_SYMBOL_VAL(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) +#define SET_SYMBOL_ALIAS(sym, v) \ (eassert ((sym)->redirect == SYMBOL_VARALIAS), (sym)->val.alias = (v)) -#define SET_SYMBOL_BLV(sym, v) \ +#define SET_SYMBOL_BLV(sym, v) \ (eassert ((sym)->redirect == SYMBOL_LOCALIZED), (sym)->val.blv = (v)) -#define SET_SYMBOL_FWD(sym, v) \ +#define SET_SYMBOL_FWD(sym, v) \ (eassert ((sym)->redirect == SYMBOL_FORWARDED), (sym)->val.fwd = (v)) -#define SYMBOL_NAME(sym) \ - LISP_MAKE_RVALUE (SVAR (XSYMBOL (sym), xname)) +#define SYMBOL_NAME(sym) XSYMBOL (sym)->name /* Value is non-zero if SYM is an interned symbol. */ -#define SYMBOL_INTERNED_P(sym) \ - (XSYMBOL (sym)->interned != SYMBOL_UNINTERNED) +#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) +#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 +#define SYMBOL_CONSTANT_P(sym) XSYMBOL (sym)->constant -#define DEFSYM(sym, name) \ +#define DEFSYM(sym, name) \ do { (sym) = intern_c_string ((name)); staticpro (&(sym)); } while (0) @@ -1206,9 +1199,9 @@ struct Lisp_Hash_Table struct Lisp_Hash_Table *next_weak; /* C function to compare two keys. */ - int (*cmpfn) (struct Lisp_Hash_Table *, - Lisp_Object, EMACS_UINT, - Lisp_Object, EMACS_UINT); + bool (*cmpfn) (struct Lisp_Hash_Table *, + Lisp_Object, EMACS_UINT, + Lisp_Object, EMACS_UINT); /* C function to compute hash code. */ EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object); @@ -1260,16 +1253,11 @@ enum DEFAULT_HASH_SIZE { DEFAULT_HASH_SIZE = 65 }; value gives the ratio of current entries in the hash table and the size of the hash table. */ -#define DEFAULT_REHASH_THRESHOLD 0.8 +static double const DEFAULT_REHASH_THRESHOLD = 0.8; /* Default factor by which to increase the size of a hash table. */ -#define DEFAULT_REHASH_SIZE 1.5 - -/* Most code should use this macro to access - Lisp fields in a different misc objects. */ - -#define MVAR(misc, field) ((misc)->INTERNAL_FIELD (field)) +static double const DEFAULT_REHASH_SIZE = 1.5; /* These structures are used for various misc types. */ @@ -1340,9 +1328,9 @@ struct Lisp_Overlay unsigned gcmarkbit : 1; int spacer : 15; struct Lisp_Overlay *next; - Lisp_Object INTERNAL_FIELD (start); - Lisp_Object INTERNAL_FIELD (end); - Lisp_Object INTERNAL_FIELD (plist); + Lisp_Object start; + Lisp_Object end; + Lisp_Object plist; }; /* Hold a C pointer for later use. @@ -1398,7 +1386,7 @@ struct Lisp_Intfwd struct Lisp_Boolfwd { enum Lisp_Fwd_Type type; /* = Lisp_Fwd_Bool */ - int *boolvar; + bool *boolvar; }; /* Forwarding pointer to a Lisp_Object variable. @@ -1470,14 +1458,6 @@ struct Lisp_Buffer_Local_Value Lisp_Object valcell; }; -#define BLV_FOUND(blv) \ - (eassert ((blv)->found == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found) -#define SET_BLV_FOUND(blv, v) \ - (eassert ((v) == !EQ ((blv)->defcell, (blv)->valcell)), (blv)->found = (v)) - -#define BLV_VALUE(blv) (XCDR ((blv)->valcell)) -#define SET_BLV_VALUE(blv, v) (XSETCDR ((blv)->valcell, v)) - /* Like Lisp_Objfwd except that value lives in a slot in the current kboard. */ struct Lisp_Kboard_Objfwd @@ -1508,6 +1488,16 @@ struct Lisp_Float #define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data) #define XFLOAT_INIT(f, n) (XFLOAT (f)->u.data = (n)) +/* Most hosts nowadays use IEEE floating point, so they use IEC 60559 + representations, have infinities and NaNs, and do not trap on + exceptions. Define IEEE_FLOATING_POINT if this host is one of the + typical ones. The C11 macro __STDC_IEC_559__ is close to what is + wanted here, but is not quite right because Emacs does not require + all the features of C11 Annex F (and does not require C11 at all, + for that matter). */ +#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \ + && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128) + /* A character, declared with the following typedef, is a member of some character set associated with the current buffer. */ #ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */ @@ -1641,7 +1631,7 @@ typedef struct { int mouse_face_image_state; } Mouse_HLInfo; -/* Data type checking */ +/* Data type checking. */ #define NILP(x) EQ (x, Qnil) @@ -1756,15 +1746,18 @@ typedef struct { #define CHECK_WINDOW_CONFIGURATION(x) \ CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x) -/* This macro rejects windows on the interior of the window tree as - "dead", which is what we want; this is an argument-checking macro, and - the user should never get access to interior windows. - - A window of any sort, leaf or interior, is dead if the buffer, - vchild, and hchild members are all nil. */ - -#define CHECK_LIVE_WINDOW(x) \ - CHECK_TYPE (WINDOWP (x) && !NILP (WVAR (XWINDOW (x), buffer)), \ +/* A window of any sort, leaf or interior, is "valid" if one of its + buffer, vchild, or hchild members is non-nil. */ +#define CHECK_VALID_WINDOW(x) \ + CHECK_TYPE (WINDOWP (x) \ + && (!NILP (XWINDOW (x)->buffer) \ + || !NILP (XWINDOW (x)->vchild) \ + || !NILP (XWINDOW (x)->hchild)), \ + Qwindow_valid_p, x) + +/* A window is "live" if and only if it shows a buffer. */ +#define CHECK_LIVE_WINDOW(x) \ + CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), \ Qwindow_live_p, x) #define CHECK_PROCESS(x) \ @@ -1915,11 +1908,7 @@ typedef struct { Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) /* 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)) +#define FUNCTIONP(OBJ) functionp(OBJ) /* defsubr (Sname); is how we define the symbol for function `name' at start-up time. */ @@ -1933,7 +1922,7 @@ enum maxargs extern void defvar_lisp (struct Lisp_Objfwd *, const char *, Lisp_Object *); extern void defvar_lisp_nopro (struct Lisp_Objfwd *, const char *, Lisp_Object *); -extern void defvar_bool (struct Lisp_Boolfwd *, const char *, int *); +extern void defvar_bool (struct Lisp_Boolfwd *, const char *, bool *); extern void defvar_int (struct Lisp_Intfwd *, const char *, EMACS_INT *); extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int); @@ -1986,7 +1975,25 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int); static struct Lisp_Kboard_Objfwd ko_fwd; \ defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \ } while (0) - + +/* Save and restore the instruction and environment pointers, + without affecting the signal mask. */ + +#ifdef HAVE__SETJMP +typedef jmp_buf sys_jmp_buf; +# define sys_setjmp(j) _setjmp (j) +# define sys_longjmp(j, v) _longjmp (j, v) +#elif defined HAVE_SIGSETJMP +typedef sigjmp_buf sys_jmp_buf; +# define sys_setjmp(j) sigsetjmp (j, 0) +# define sys_longjmp(j, v) siglongjmp (j, v) +#else +/* A platform that uses neither _longjmp nor siglongjmp; assume + longjmp does not affect the sigmask. */ +typedef jmp_buf sys_jmp_buf; +# define sys_setjmp(j) setjmp (j) +# define sys_longjmp(j, v) longjmp (j, v) +#endif /* Structure for recording Lisp call stack for backtrace purposes. */ @@ -2015,7 +2022,7 @@ struct specbinding { Lisp_Object symbol, old_value; specbinding_func func; - Lisp_Object unused; /* Dividing by 16 is faster than by 12 */ + Lisp_Object unused; /* Dividing by 16 is faster than by 12. */ }; extern struct specbinding *specpdl; @@ -2024,7 +2031,22 @@ extern ptrdiff_t specpdl_size; #define SPECPDL_INDEX() (specpdl_ptr - specpdl) -/* Everything needed to describe an active condition case. */ +struct backtrace +{ + struct backtrace *next; + Lisp_Object function; + Lisp_Object *args; /* Points to vector of args. */ + ptrdiff_t nargs; /* Length of vector. */ + /* Nonzero means call value of debugger when done with this operation. */ + unsigned int debug_on_exit : 1; +}; + +extern struct backtrace *backtrace_list; + +/* Everything needed to describe an active condition case. + + Members are volatile if their values need to survive _longjmp when + a 'struct handler' is a local variable. */ struct handler { /* The handler clauses and variable from the condition-case form. */ @@ -2035,10 +2057,12 @@ struct handler error: handle all conditions, and errors can run the debugger or display a backtrace. */ Lisp_Object handler; - Lisp_Object var; + + Lisp_Object volatile var; + /* Fsignal stores here the condition-case clause that applies, and Fcondition_case thus knows which clause to run. */ - Lisp_Object chosen_clause; + Lisp_Object volatile chosen_clause; /* Used to effect the longjump out to the handler. */ struct catchtag *tag; @@ -2064,19 +2088,21 @@ struct handler of the catch form. All the other members are concerned with restoring the interpreter - state. */ + state. + Members are volatile if their values need to survive _longjmp when + a 'struct catchtag' is a local variable. */ struct catchtag { Lisp_Object tag; - Lisp_Object val; - struct catchtag *next; + Lisp_Object volatile val; + struct catchtag *volatile next; struct gcpro *gcpro; - jmp_buf jmp; + sys_jmp_buf jmp; struct backtrace *backlist; struct handler *handlerlist; EMACS_INT lisp_eval_depth; - ptrdiff_t pdlcount; + ptrdiff_t volatile pdlcount; int poll_suppress_count; int interrupt_input_blocked; struct byte_stack *byte_stack; @@ -2104,22 +2130,16 @@ extern char *stack_bottom; If quit-flag is set to `kill-emacs' the SIGINT handler has received a request to exit Emacs when it is safe to do. */ -#ifdef SYNC_INPUT extern void process_pending_signals (void); -extern int pending_signals; -#define ELSE_PENDING_SIGNALS \ - else if (pending_signals) \ - process_pending_signals (); -#else /* not SYNC_INPUT */ -#define ELSE_PENDING_SIGNALS -#endif /* not SYNC_INPUT */ +extern int volatile pending_signals; extern void process_quit_flag (void); #define QUIT \ do { \ if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \ process_quit_flag (); \ - ELSE_PENDING_SIGNALS \ + else if (pending_signals) \ + process_pending_signals (); \ } while (0) @@ -2303,7 +2323,7 @@ extern int gcpro_level; #define UNGCPRO \ ((--gcpro_level != gcpro1.level) \ - ? (abort (), 0) \ + ? (emacs_abort (), 0) \ : ((gcprolist = gcpro1.next), 0)) #endif /* DEBUG_GCPRO */ @@ -2336,6 +2356,231 @@ void staticpro (Lisp_Object *); struct window; struct frame; +/* Simple access functions. */ + +LISP_INLINE Lisp_Object * +aref_addr (Lisp_Object array, ptrdiff_t idx) +{ + return & XVECTOR (array)->contents[idx]; +} + +LISP_INLINE void +gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val) +{ + /* Like ASET, but also can be used in the garbage collector: + sweep_weak_table calls set_hash_key etc. while the table is marked. */ + eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG)); + XVECTOR (array)->contents[idx] = val; +} + +/* Copy COUNT Lisp_Objects from ARGS to contents of V starting from OFFSET. */ + +LISP_INLINE void +vcopy (Lisp_Object v, ptrdiff_t offset, Lisp_Object *args, ptrdiff_t count) +{ + eassert (0 <= offset && 0 <= count && offset + count <= ASIZE (v)); + memcpy (XVECTOR (v)->contents + offset, args, count * sizeof *args); +} + +/* Functions to modify hash tables. */ + +LISP_INLINE void +set_hash_key_and_value (struct Lisp_Hash_Table *h, Lisp_Object key_and_value) +{ + h->key_and_value = key_and_value; +} + +LISP_INLINE void +set_hash_key_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->key_and_value, 2 * idx, val); +} + +LISP_INLINE void +set_hash_value_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->key_and_value, 2 * idx + 1, val); +} + +LISP_INLINE void +set_hash_next (struct Lisp_Hash_Table *h, Lisp_Object next) +{ + h->next = next; +} + +LISP_INLINE void +set_hash_next_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->next, idx, val); +} + +LISP_INLINE void +set_hash_hash (struct Lisp_Hash_Table *h, Lisp_Object hash) +{ + h->hash = hash; +} + +LISP_INLINE void +set_hash_hash_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->hash, idx, val); +} + +LISP_INLINE void +set_hash_index (struct Lisp_Hash_Table *h, Lisp_Object index) +{ + h->index = index; +} + +LISP_INLINE void +set_hash_index_slot (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val) +{ + gc_aset (h->index, idx, val); +} + +/* Use these functions to set Lisp_Object + or pointer slots of struct Lisp_Symbol. */ + +LISP_INLINE void +set_symbol_name (Lisp_Object sym, Lisp_Object name) +{ + XSYMBOL (sym)->name = name; +} + +LISP_INLINE void +set_symbol_function (Lisp_Object sym, Lisp_Object function) +{ + XSYMBOL (sym)->function = function; +} + +LISP_INLINE void +set_symbol_plist (Lisp_Object sym, Lisp_Object plist) +{ + XSYMBOL (sym)->plist = plist; +} + +LISP_INLINE void +set_symbol_next (Lisp_Object sym, struct Lisp_Symbol *next) +{ + XSYMBOL (sym)->next = next; +} + +/* Buffer-local (also frame-local) variable access functions. */ + +LISP_INLINE int +blv_found (struct Lisp_Buffer_Local_Value *blv) +{ + eassert (blv->found == !EQ (blv->defcell, blv->valcell)); + return blv->found; +} + +LISP_INLINE void +set_blv_found (struct Lisp_Buffer_Local_Value *blv, int found) +{ + eassert (found == !EQ (blv->defcell, blv->valcell)); + blv->found = found; +} + +LISP_INLINE Lisp_Object +blv_value (struct Lisp_Buffer_Local_Value *blv) +{ + return XCDR (blv->valcell); +} + +LISP_INLINE void +set_blv_value (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + XSETCDR (blv->valcell, val); +} + +LISP_INLINE void +set_blv_where (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->where = val; +} + +LISP_INLINE void +set_blv_defcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->defcell = val; +} + +LISP_INLINE void +set_blv_valcell (struct Lisp_Buffer_Local_Value *blv, Lisp_Object val) +{ + blv->valcell = val; +} + +/* Set overlay's property list. */ + +LISP_INLINE void +set_overlay_plist (Lisp_Object overlay, Lisp_Object plist) +{ + XOVERLAY (overlay)->plist = plist; +} + +/* Get text properties of S. */ + +LISP_INLINE INTERVAL +string_intervals (Lisp_Object s) +{ + return XSTRING (s)->intervals; +} + +/* Set text properties of S to I. */ + +LISP_INLINE void +set_string_intervals (Lisp_Object s, INTERVAL i) +{ + XSTRING (s)->intervals = i; +} + +/* Set a Lisp slot in TABLE to VAL. Most code should use this instead + of setting slots directly. */ + +LISP_INLINE void +set_char_table_ascii (Lisp_Object table, Lisp_Object val) +{ + XCHAR_TABLE (table)->ascii = val; +} +LISP_INLINE void +set_char_table_defalt (Lisp_Object table, Lisp_Object val) +{ + XCHAR_TABLE (table)->defalt = val; +} +LISP_INLINE void +set_char_table_parent (Lisp_Object table, Lisp_Object val) +{ + XCHAR_TABLE (table)->parent = val; +} +LISP_INLINE void +set_char_table_purpose (Lisp_Object table, Lisp_Object val) +{ + XCHAR_TABLE (table)->purpose = val; +} + +/* Set different slots in (sub)character tables. */ + +LISP_INLINE void +set_char_table_extras (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) +{ + eassert (0 <= idx && idx < CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (table))); + XCHAR_TABLE (table)->extras[idx] = val; +} + +LISP_INLINE void +set_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) +{ + eassert (0 <= idx && idx < (1 << CHARTAB_SIZE_BITS_0)); + XCHAR_TABLE (table)->contents[idx] = val; +} + +LISP_INLINE void +set_sub_char_table_contents (Lisp_Object table, ptrdiff_t idx, Lisp_Object val) +{ + XSUB_CHAR_TABLE (table)->contents[idx] = val; +} + /* Defined in data.c. */ extern Lisp_Object Qnil, Qt, Qquote, Qlambda, Qunbound; extern Lisp_Object Qerror_conditions, Qerror_message, Qtop_level; @@ -2357,23 +2602,21 @@ extern Lisp_Object Qchar_table_p, Qvector_or_char_table_p; extern Lisp_Object Qcdr; -extern Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error; -extern Lisp_Object Qoverflow_error, Qunderflow_error; +extern Lisp_Object Qrange_error, Qoverflow_error; extern Lisp_Object Qfloatp; extern Lisp_Object Qnumberp, Qnumber_or_marker_p; -extern Lisp_Object Qinteger, Qinterval, Qsymbol, Qstring; -extern Lisp_Object Qmisc, Qvector, Qfloat, Qcons, Qbuffer; +extern Lisp_Object Qbuffer, Qinteger, Qsymbol; extern Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; EXFUN (Fbyteorder, 0) ATTRIBUTE_CONST; -/* Defined in frame.c */ +/* Defined in frame.c. */ extern Lisp_Object Qframep; -/* Defined in data.c */ +/* Defined in data.c. */ extern Lisp_Object indirect_function (Lisp_Object); extern Lisp_Object find_symbol_value (Lisp_Object); @@ -2411,24 +2654,23 @@ extern _Noreturn void args_out_of_range_3 (Lisp_Object, Lisp_Object, Lisp_Object); extern _Noreturn Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object); extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *); -extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, int); +extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool); extern void syms_of_data (void); -extern void init_data (void); extern void swap_in_global_binding (struct Lisp_Symbol *); /* Defined in cmds.c */ extern void syms_of_cmds (void); extern void keys_of_cmds (void); -/* Defined in coding.c */ +/* Defined in coding.c. */ extern Lisp_Object Qcharset; extern Lisp_Object detect_coding_system (const unsigned char *, ptrdiff_t, - ptrdiff_t, int, int, Lisp_Object); + ptrdiff_t, bool, bool, Lisp_Object); extern void init_coding (void); extern void init_coding_once (void); extern void syms_of_coding (void); -/* Defined in character.c */ +/* Defined in character.c. */ EXFUN (Fmax_char, 0) ATTRIBUTE_CONST; extern ptrdiff_t chars_in_text (const unsigned char *, ptrdiff_t); extern ptrdiff_t multibyte_chars_in_text (const unsigned char *, ptrdiff_t); @@ -2436,21 +2678,21 @@ extern int multibyte_char_to_unibyte (int) ATTRIBUTE_CONST; extern int multibyte_char_to_unibyte_safe (int) ATTRIBUTE_CONST; extern void syms_of_character (void); -/* Defined in charset.c */ +/* Defined in charset.c. */ extern void init_charset (void); extern void init_charset_once (void); extern void syms_of_charset (void); /* Structure forward declarations. */ struct charset; -/* Defined in composite.c */ +/* Defined in composite.c. */ extern void syms_of_composite (void); -/* Defined in syntax.c */ +/* Defined in syntax.c. */ extern void init_syntax_once (void); extern void syms_of_syntax (void); -/* Defined in fns.c */ +/* Defined in fns.c. */ extern Lisp_Object QCrehash_size, QCrehash_threshold; enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; EXFUN (Fidentity, 1) ATTRIBUTE_CONST; @@ -2484,13 +2726,12 @@ extern Lisp_Object string_to_multibyte (Lisp_Object); extern Lisp_Object string_make_unibyte (Lisp_Object); extern void syms_of_fns (void); -/* Defined in floatfns.c */ +/* Defined in floatfns.c. */ extern double extract_float (Lisp_Object); -extern void init_floatfns (void); extern void syms_of_floatfns (void); extern Lisp_Object fmod_float (Lisp_Object x, Lisp_Object y); -/* Defined in fringe.c */ +/* Defined in fringe.c. */ extern void syms_of_fringe (void); extern void init_fringe (void); #ifdef HAVE_WINDOW_SYSTEM @@ -2498,71 +2739,71 @@ extern void mark_fringe_data (void); extern void init_fringe_once (void); #endif /* HAVE_WINDOW_SYSTEM */ -/* Defined in image.c */ +/* Defined in image.c. */ extern Lisp_Object QCascent, QCmargin, QCrelief; extern Lisp_Object QCconversion; extern int x_bitmap_mask (struct frame *, ptrdiff_t); +extern void reset_image_types (void); extern void syms_of_image (void); -/* Defined in insdel.c */ +/* Defined in insdel.c. */ extern Lisp_Object Qinhibit_modification_hooks; extern void move_gap (ptrdiff_t); extern void move_gap_both (ptrdiff_t, ptrdiff_t); extern _Noreturn void buffer_overflow (void); extern void make_gap (ptrdiff_t); extern ptrdiff_t copy_text (const unsigned char *, unsigned char *, - ptrdiff_t, int, int); + ptrdiff_t, bool, bool); extern int count_combining_before (const unsigned char *, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern int count_combining_after (const unsigned char *, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void insert (const char *, ptrdiff_t); extern void insert_and_inherit (const char *, ptrdiff_t); -extern void insert_1 (const char *, ptrdiff_t, int, int, int); +extern void insert_1 (const char *, ptrdiff_t, bool, bool, bool); extern void insert_1_both (const char *, ptrdiff_t, ptrdiff_t, - int, int, int); + bool, bool, bool); extern void insert_from_gap (ptrdiff_t, ptrdiff_t); extern void insert_from_string (Lisp_Object, ptrdiff_t, ptrdiff_t, - ptrdiff_t, ptrdiff_t, int); -extern void insert_from_buffer (struct buffer *, ptrdiff_t, ptrdiff_t, int); + ptrdiff_t, ptrdiff_t, bool); +extern void insert_from_buffer (struct buffer *, ptrdiff_t, ptrdiff_t, bool); extern void insert_char (int); extern void insert_string (const char *); extern void insert_before_markers (const char *, ptrdiff_t); extern void insert_before_markers_and_inherit (const char *, ptrdiff_t); extern void insert_from_string_before_markers (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t, - ptrdiff_t, int); + ptrdiff_t, bool); extern void del_range (ptrdiff_t, ptrdiff_t); -extern Lisp_Object del_range_1 (ptrdiff_t, ptrdiff_t, int, int); -extern void del_range_byte (ptrdiff_t, ptrdiff_t, int); -extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, int); +extern Lisp_Object del_range_1 (ptrdiff_t, ptrdiff_t, bool, bool); +extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool); +extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, - ptrdiff_t, ptrdiff_t, int); -extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, int); + ptrdiff_t, ptrdiff_t, bool); +extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); extern void adjust_markers_for_delete (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t); -extern void replace_range (ptrdiff_t, ptrdiff_t, Lisp_Object, int, int, int); +extern void replace_range (ptrdiff_t, ptrdiff_t, Lisp_Object, bool, bool, bool); extern void replace_range_2 (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, - const char *, ptrdiff_t, ptrdiff_t, int); + const char *, ptrdiff_t, ptrdiff_t, bool); extern void syms_of_insdel (void); -/* Defined in dispnew.c */ +/* Defined in dispnew.c. */ #if (defined PROFILING \ && (defined __FreeBSD__ || defined GNU_LINUX || defined __MINGW32__)) _Noreturn void __executable_start (void); #endif extern Lisp_Object selected_frame; extern Lisp_Object Vwindow_system; -void duration_to_sec_usec (double, int *, int *); -extern Lisp_Object sit_for (Lisp_Object, int, int); +extern Lisp_Object sit_for (Lisp_Object, bool, int); extern void init_display (void); extern void syms_of_display (void); -/* Defined in xdisp.c */ +/* Defined in xdisp.c. */ extern Lisp_Object Qinhibit_point_motion_hooks; extern Lisp_Object Qinhibit_redisplay, Qdisplay; extern Lisp_Object Qmenu_bar_update_hook; @@ -2584,7 +2825,7 @@ extern Lisp_Object echo_area_buffer[2]; extern void add_to_log (const char *, Lisp_Object, Lisp_Object); extern void check_message_stack (void); extern void setup_echo_area_for_printing (int); -extern int push_message (void); +extern bool push_message (void); extern Lisp_Object pop_message_unwind (Lisp_Object); extern Lisp_Object restore_message_unwind (Lisp_Object); extern void restore_message (void); @@ -2613,21 +2854,19 @@ extern Lisp_Object safe_eval (Lisp_Object); extern int pos_visible_p (struct window *, ptrdiff_t, int *, int *, int *, int *, int *, int *); -/* Defined in xsettings.c */ +/* Defined in xsettings.c. */ extern void syms_of_xsettings (void); /* Defined in vm-limit.c. */ extern void memory_warnings (void *, void (*warnfun) (const char *)); -/* Defined in alloc.c */ +/* Defined in alloc.c. */ extern void check_pure_size (void); extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT); -extern void reset_malloc_hooks (void); -extern void uninterrupt_malloc (void); extern void malloc_warning (const char *); extern _Noreturn void memory_full (size_t); extern _Noreturn void buffer_memory_full (ptrdiff_t); -extern int survives_gc_p (Lisp_Object); +extern bool survives_gc_p (Lisp_Object); extern void mark_object (Lisp_Object); #if defined REL_ALLOC && !defined SYSTEM_MALLOC extern void refill_memory_reserve (void); @@ -2654,7 +2893,7 @@ extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t); /* Make unibyte string from C string when the length isn't known. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_unibyte_string (const char *str) { return make_unibyte_string (str, strlen (str)); @@ -2666,13 +2905,13 @@ extern Lisp_Object make_uninit_string (EMACS_INT); extern Lisp_Object make_uninit_multibyte_string (EMACS_INT, EMACS_INT); extern Lisp_Object make_string_from_bytes (const char *, ptrdiff_t, ptrdiff_t); extern Lisp_Object make_specified_string (const char *, - ptrdiff_t, ptrdiff_t, int); -extern Lisp_Object make_pure_string (const char *, ptrdiff_t, ptrdiff_t, int); + ptrdiff_t, ptrdiff_t, bool); +extern Lisp_Object make_pure_string (const char *, ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_pure_c_string (const char *, ptrdiff_t); /* Make a string allocated in pure space, use STR as string data. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_pure_c_string (const char *str) { return make_pure_c_string (str, strlen (str)); @@ -2681,7 +2920,7 @@ build_pure_c_string (const char *str) /* Make a string from the data at STR, treating it as multibyte if the data warrants. */ -static inline Lisp_Object +LISP_INLINE Lisp_Object build_string (const char *str) { return make_string (str, strlen (str)); @@ -2689,6 +2928,7 @@ build_string (const char *str) extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); extern void make_byte_code (struct Lisp_Vector *); +extern Lisp_Object Qautomatic_gc; extern Lisp_Object Qchar_table_extra_slots; extern struct Lisp_Vector *allocate_vector (EMACS_INT); extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); @@ -2701,8 +2941,8 @@ extern struct window *allocate_window (void); extern struct frame *allocate_frame (void); extern struct Lisp_Process *allocate_process (void); extern struct terminal *allocate_terminal (void); -extern int gc_in_progress; -extern int abort_on_gc; +extern bool gc_in_progress; +extern bool abort_on_gc; extern Lisp_Object make_float (double); extern void display_malloc_warning (void); extern ptrdiff_t inhibit_garbage_collection (void); @@ -2722,7 +2962,7 @@ extern void check_cons_list (void); #endif #ifdef REL_ALLOC -/* Defined in ralloc.c */ +/* Defined in ralloc.c. */ extern void *r_alloc (void **, size_t); extern void r_alloc_free (void **); extern void *r_re_alloc (void **, size_t); @@ -2730,14 +2970,13 @@ extern void r_alloc_reset_variable (void **, void **); extern void r_alloc_inhibit_buffer_relocation (int); #endif -/* Defined in chartab.c */ +/* Defined in chartab.c. */ extern Lisp_Object copy_char_table (Lisp_Object); extern Lisp_Object char_table_ref (Lisp_Object, int); extern Lisp_Object char_table_ref_and_range (Lisp_Object, int, int *, int *); -extern Lisp_Object char_table_set (Lisp_Object, int, Lisp_Object); -extern Lisp_Object char_table_set_range (Lisp_Object, int, int, - Lisp_Object); +extern void char_table_set (Lisp_Object, int, Lisp_Object); +extern void char_table_set_range (Lisp_Object, int, int, Lisp_Object); extern int char_table_translate (Lisp_Object, int); extern void map_char_table (void (*) (Lisp_Object, Lisp_Object, Lisp_Object), @@ -2749,7 +2988,7 @@ extern void map_char_table_for_charset (void (*c_function) (Lisp_Object, Lisp_Ob extern Lisp_Object uniprop_table (Lisp_Object); extern void syms_of_chartab (void); -/* Defined in print.c */ +/* Defined in print.c. */ extern Lisp_Object Vprin1_to_string_buffer; extern void debug_print (Lisp_Object) EXTERNALLY_VISIBLE; extern Lisp_Object Qstandard_output; @@ -2766,7 +3005,7 @@ enum FLOAT_TO_STRING_BUFSIZE { FLOAT_TO_STRING_BUFSIZE = 350 }; extern int float_to_string (char *, double); extern void syms_of_print (void); -/* Defined in doprnt.c */ +/* Defined in doprnt.c. */ extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *, va_list); extern ptrdiff_t esprintf (char *, char const *, ...) @@ -2781,6 +3020,7 @@ extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t, /* Defined in lread.c. */ extern Lisp_Object Qvariable_documentation, Qstandard_input; extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction; +extern Lisp_Object Qlexical_binding; extern Lisp_Object check_obarray (Lisp_Object); extern Lisp_Object intern_1 (const char *, ptrdiff_t); extern Lisp_Object intern_c_string_1 (const char *, ptrdiff_t); @@ -2800,13 +3040,13 @@ extern void init_obarray (void); extern void init_lread (void); extern void syms_of_lread (void); -static inline Lisp_Object +LISP_INLINE Lisp_Object intern (const char *str) { return intern_1 (str, strlen (str)); } -static inline Lisp_Object +LISP_INLINE Lisp_Object intern_c_string (const char *str) { return intern_c_string_1 (str, strlen (str)); @@ -2814,12 +3054,11 @@ intern_c_string (const char *str) /* Defined in eval.c. */ extern Lisp_Object Qautoload, Qexit, Qinteractive, Qcommandp, Qmacro; -extern Lisp_Object Qinhibit_quit, Qclosure; +extern Lisp_Object Qinhibit_quit, Qinternal_interpreter_environment, Qclosure; extern Lisp_Object Qand_rest; extern Lisp_Object Vautoload_queue; extern Lisp_Object Vsignaling_function; extern Lisp_Object inhibit_lisp_code; -extern int handling_signal; #if BYTE_MARK_STACK extern struct catchtag *catchlist; extern struct handler *handlerlist; @@ -2858,7 +3097,9 @@ extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_ extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_1 (Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)); -extern Lisp_Object internal_condition_case_n (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object)); +extern Lisp_Object internal_condition_case_n + (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, + Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); extern void specbind (Lisp_Object, Lisp_Object); extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object); extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object); @@ -2866,6 +3107,7 @@ extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); extern _Noreturn void verror (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0); extern Lisp_Object un_autoload (Lisp_Object); +extern Lisp_Object call_debugger (Lisp_Object arg); extern void init_eval_once (void); extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...); extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object); @@ -2885,23 +3127,23 @@ extern Lisp_Object save_restriction_save (void); extern Lisp_Object save_excursion_restore (Lisp_Object); extern Lisp_Object save_restriction_restore (Lisp_Object); extern _Noreturn void time_overflow (void); -extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, int); +extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool); extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, - ptrdiff_t, int); + ptrdiff_t, bool); extern void init_editfns (void); const char *get_system_name (void); extern void syms_of_editfns (void); extern void set_time_zone_rule (const char *); /* Defined in buffer.c. */ -extern int mouse_face_overlay_overlaps (Lisp_Object); +extern bool mouse_face_overlay_overlaps (Lisp_Object); extern _Noreturn void nsberror (Lisp_Object); extern void adjust_overlays_for_insert (ptrdiff_t, ptrdiff_t); extern void adjust_overlays_for_delete (ptrdiff_t, ptrdiff_t); extern void fix_start_end_in_overlays (ptrdiff_t, ptrdiff_t); -extern void report_overlay_modification (Lisp_Object, Lisp_Object, int, +extern void report_overlay_modification (Lisp_Object, Lisp_Object, bool, Lisp_Object, Lisp_Object, Lisp_Object); -extern int overlay_touches_p (ptrdiff_t); +extern bool overlay_touches_p (ptrdiff_t); extern Lisp_Object Vbuffer_alist; extern Lisp_Object set_buffer_if_live (Lisp_Object); extern Lisp_Object other_buffer_safely (Lisp_Object); @@ -2928,7 +3170,7 @@ extern Lisp_Object set_marker_restricted_both (Lisp_Object, Lisp_Object, extern Lisp_Object build_marker (struct buffer *, ptrdiff_t, ptrdiff_t); extern void syms_of_marker (void); -/* Defined in fileio.c */ +/* Defined in fileio.c. */ extern Lisp_Object Qfile_error; extern Lisp_Object Qfile_exists_p; @@ -2936,16 +3178,16 @@ extern Lisp_Object Qfile_directory_p; extern Lisp_Object Qinsert_file_contents; extern Lisp_Object Qfile_name_history; extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object); -EXFUN (Fread_file_name, 6); /* not a normal DEFUN */ +EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */ extern Lisp_Object close_file_unwind (Lisp_Object); extern Lisp_Object restore_point_unwind (Lisp_Object); extern _Noreturn void report_file_error (const char *, Lisp_Object); -extern int internal_delete_file (Lisp_Object); +extern void internal_delete_file (Lisp_Object); extern void syms_of_fileio (void); -extern Lisp_Object make_temp_name (Lisp_Object, int); +extern Lisp_Object make_temp_name (Lisp_Object, bool); extern Lisp_Object Qdelete_file; -/* Defined in search.c */ +/* Defined in search.c. */ extern void shrink_regexp_cache (void); extern void restore_search_regs (void); extern void record_unwind_save_match_data (void); @@ -3009,6 +3251,9 @@ extern int input_pending; extern Lisp_Object menu_bar_items (Lisp_Object); extern Lisp_Object tool_bar_items (Lisp_Object, int *); extern void discard_mouse_events (void); +#ifdef USABLE_SIGIO +void handle_input_available_signal (int); +#endif extern Lisp_Object pending_funcalls; extern int detect_input_pending (void); extern int detect_input_pending_ignore_squeezables (void); @@ -3018,9 +3263,7 @@ extern void cmd_error_internal (Lisp_Object, const char *); extern Lisp_Object command_loop_1 (void); extern Lisp_Object recursive_edit_1 (void); extern void record_auto_save (void); -#ifdef SIGDANGER extern void force_auto_save_soon (void); -#endif extern void init_keyboard (void); extern void syms_of_keyboard (void); extern void keys_of_keyboard (void); @@ -3028,11 +3271,11 @@ extern void keys_of_keyboard (void); /* Defined in indent.c. */ extern ptrdiff_t current_column (void); extern void invalidate_current_column (void); -extern int indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT); +extern bool indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT); extern void syms_of_indent (void); /* Defined in frame.c. */ -extern Lisp_Object Qonly; +extern Lisp_Object Qonly, Qnone; extern Lisp_Object Qvisible; extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object); extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object); @@ -3048,15 +3291,16 @@ extern void syms_of_frame (void); extern char **initial_argv; extern int initial_argc; #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) -extern int display_arg; +extern bool display_arg; #endif extern Lisp_Object decode_env_path (const char *, const char *); extern Lisp_Object empty_unibyte_string, empty_multibyte_string; extern Lisp_Object Qfile_name_handler_alist; -#ifdef FLOAT_CATCH_SIGILL -extern void fatal_error_signal (int); -#endif +extern _Noreturn void terminate_due_to_signal (int, int); extern Lisp_Object Qkill_emacs; +#ifdef WINDOWSNT +extern Lisp_Object Vlibrary_cache; +#endif #if HAVE_SETLOCALE void fixup_locale (void); void synchronize_system_messages_locale (void); @@ -3067,22 +3311,26 @@ void synchronize_system_time_locale (void); #define synchronize_system_messages_locale() #define synchronize_system_time_locale() #endif -void shut_down_emacs (int, int, Lisp_Object); -/* Nonzero means don't do interactive redisplay and don't change tty modes. */ -extern int noninteractive; +extern void shut_down_emacs (int, Lisp_Object); -/* Nonzero means remove site-lisp directories from load-path. */ -extern int no_site_lisp; +/* True means don't do interactive redisplay and don't change tty modes. */ +extern bool noninteractive; + +/* True means remove site-lisp directories from load-path. */ +extern bool no_site_lisp; /* Pipe used to send exit notification to the daemon parent at startup. */ extern int daemon_pipe[2]; #define IS_DAEMON (daemon_pipe[1] != 0) -/* Nonzero means don't do use window-system-specific display code. */ -extern int inhibit_window_system; -/* Nonzero means that a filter or a sentinel is running. */ -extern int running_asynch_code; +/* True if handling a fatal error already. */ +extern bool fatal_error_in_progress; + +/* True means don't do use window-system-specific display code. */ +extern bool inhibit_window_system; +/* True means that a filter or a sentinel is running. */ +extern bool running_asynch_code; /* Defined in process.c. */ extern Lisp_Object QCtype, Qlocal; @@ -3114,20 +3362,20 @@ extern void setup_process_coding_systems (Lisp_Object); #ifndef DOS_NT _Noreturn #endif -extern int child_setup (int, int, int, char **, int, Lisp_Object); +extern int child_setup (int, int, int, char **, bool, Lisp_Object); extern void init_callproc_1 (void); extern void init_callproc (void); extern void set_initial_environment (void); extern void syms_of_callproc (void); -/* Defined in doc.c */ +/* Defined in doc.c. */ extern Lisp_Object Qfunction_documentation; extern Lisp_Object read_doc_string (Lisp_Object); -extern Lisp_Object get_doc_string (Lisp_Object, int, int); +extern Lisp_Object get_doc_string (Lisp_Object, bool, bool); extern void syms_of_doc (void); -extern int read_bytecode_char (int); +extern int read_bytecode_char (bool); -/* Defined in bytecode.c */ +/* Defined in bytecode.c. */ extern Lisp_Object Qbytecode; extern void syms_of_bytecode (void); extern struct byte_stack *byte_stack_list; @@ -3138,12 +3386,12 @@ extern void unmark_byte_stack (void); extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, ptrdiff_t, Lisp_Object *); -/* Defined in macros.c */ +/* Defined in macros.c. */ extern Lisp_Object Qexecute_kbd_macro; extern void init_macros (void); extern void syms_of_macros (void); -/* Defined in undo.c */ +/* Defined in undo.c. */ extern Lisp_Object Qapply; extern Lisp_Object Qinhibit_read_only; extern void truncate_undo_list (struct buffer *); @@ -3156,7 +3404,7 @@ extern void record_property_change (ptrdiff_t, ptrdiff_t, Lisp_Object, Lisp_Object, Lisp_Object); extern void syms_of_undo (void); -/* Defined in textprop.c */ +/* Defined in textprop.c. */ extern Lisp_Object Qfont, Qmouse_face; extern Lisp_Object Qinsert_in_front_hooks, Qinsert_behind_hooks; extern Lisp_Object Qfront_sticky, Qrear_nonsticky; @@ -3164,19 +3412,19 @@ extern Lisp_Object Qminibuffer_prompt; extern void report_interval_modification (Lisp_Object, Lisp_Object); -/* Defined in menu.c */ +/* Defined in menu.c. */ extern void syms_of_menu (void); -/* Defined in xmenu.c */ +/* Defined in xmenu.c. */ extern void syms_of_xmenu (void); -/* Defined in termchar.h */ +/* Defined in termchar.h. */ struct tty_display_info; -/* Defined in termhooks.h */ +/* Defined in termhooks.h. */ struct terminal; -/* Defined in sysdep.c */ +/* Defined in sysdep.c. */ #ifndef HAVE_GET_CURRENT_DIR_NAME extern char *get_current_dir_name (void); #endif @@ -3189,14 +3437,15 @@ extern void init_sys_modes (struct tty_display_info *); extern void reset_sys_modes (struct tty_display_info *); extern void init_all_sys_modes (void); extern void reset_all_sys_modes (void); -extern void wait_for_termination (pid_t); -extern void interruptible_wait_for_termination (pid_t); extern void flush_pending_output (int) ATTRIBUTE_CONST; extern void child_setup_tty (int); extern void setup_pty (int); extern int set_window_size (int, int, int); extern EMACS_INT get_random (void); -extern void seed_random (long); +extern void seed_random (void *, ptrdiff_t); +extern void init_random (void); +extern void emacs_backtrace (int); +extern _Noreturn void emacs_abort (void) NO_INLINE; extern int emacs_open (const char *, int, int); extern int emacs_close (int); extern ptrdiff_t emacs_read (int, char *, ptrdiff_t); @@ -3210,46 +3459,45 @@ extern void unlock_file (Lisp_Object); extern void unlock_buffer (struct buffer *); extern void syms_of_filelock (void); -/* Defined in sound.c */ +/* Defined in sound.c. */ extern void syms_of_sound (void); -/* Defined in category.c */ +/* Defined in category.c. */ extern void init_category_once (void); extern Lisp_Object char_category_set (int); extern void syms_of_category (void); -/* Defined in ccl.c */ +/* Defined in ccl.c. */ extern void syms_of_ccl (void); -/* Defined in dired.c */ +/* Defined in dired.c. */ extern void syms_of_dired (void); extern Lisp_Object directory_files_internal (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, - int, Lisp_Object); + bool, Lisp_Object); -/* Defined in term.c */ +/* Defined in term.c. */ extern int *char_ins_del_vector; -extern void mark_ttys (void); extern void syms_of_term (void); extern _Noreturn void fatal (const char *msgid, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); -/* Defined in terminal.c */ +/* Defined in terminal.c. */ extern void syms_of_terminal (void); -/* Defined in font.c */ +/* Defined in font.c. */ extern void syms_of_font (void); extern void init_font (void); #ifdef HAVE_WINDOW_SYSTEM -/* Defined in fontset.c */ +/* Defined in fontset.c. */ extern void syms_of_fontset (void); -/* Defined in xfns.c, w32fns.c, or macfns.c */ +/* Defined in xfns.c, w32fns.c, or macfns.c. */ extern Lisp_Object Qfont_param; #endif -/* Defined in xfaces.c */ +/* Defined in xfaces.c. */ extern Lisp_Object Qdefault, Qtool_bar, Qfringe; extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor; extern Lisp_Object Qmode_line_inactive; @@ -3257,31 +3505,34 @@ extern Lisp_Object Qface; extern Lisp_Object Qnormal; extern Lisp_Object QCfamily, QCweight, QCslant; extern Lisp_Object QCheight, QCname, QCwidth, QCforeground, QCbackground; +extern Lisp_Object Qextra_light, Qlight, Qsemi_light, Qsemi_bold; +extern Lisp_Object Qbold, Qextra_bold, Qultra_bold; +extern Lisp_Object Qoblique, Qitalic; extern Lisp_Object Vface_alternative_font_family_alist; extern Lisp_Object Vface_alternative_font_registry_alist; extern void syms_of_xfaces (void); #ifdef HAVE_X_WINDOWS -/* Defined in xfns.c */ +/* Defined in xfns.c. */ extern void syms_of_xfns (void); -/* Defined in xsmfns.c */ +/* Defined in xsmfns.c. */ extern void syms_of_xsmfns (void); -/* Defined in xselect.c */ +/* Defined in xselect.c. */ extern void syms_of_xselect (void); -/* Defined in xterm.c */ +/* Defined in xterm.c. */ extern void syms_of_xterm (void); #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_WINDOW_SYSTEM -/* Defined in xterm.c, nsterm.m, w32term.c */ +/* Defined in xterm.c, nsterm.m, w32term.c. */ extern char *x_get_keysym_name (int); #endif /* HAVE_WINDOW_SYSTEM */ #ifdef HAVE_LIBXML2 -/* Defined in xml.c */ +/* Defined in xml.c. */ extern void syms_of_xml (void); extern void xml_cleanup_parser (void); #endif @@ -3292,20 +3543,27 @@ extern int have_menus_p (void); #endif #ifdef HAVE_DBUS -/* Defined in dbusbind.c */ +/* Defined in dbusbind.c. */ void syms_of_dbusbind (void); #endif + +/* Defined in profiler.c. */ +extern bool profiler_memory_running; +extern void malloc_probe (size_t); +extern void syms_of_profiler (void); + + #ifdef DOS_NT -/* Defined in msdos.c, w32.c */ +/* Defined in msdos.c, w32.c. */ extern char *emacs_root_dir (void); #endif /* DOS_NT */ -/* Nonzero means Emacs has already been initialized. +/* True means Emacs has already been initialized. Used during startup to detect startup of dumped Emacs. */ -extern int initialized; +extern bool initialized; -extern int immediate_quit; /* Nonzero means ^G can quit instantly */ +extern int immediate_quit; /* Nonzero means ^G can quit instantly. */ extern void *xmalloc (size_t); extern void *xzalloc (size_t); @@ -3322,23 +3580,6 @@ extern char *egetenv (const char *); /* Set up the name of the machine we're running on. */ extern void init_system_name (void); -static char const DIRECTORY_SEP = '/'; - -/* Use this to suppress gcc's warnings. */ -#ifdef lint - -/* Use CODE only if lint checking is in effect. */ -# define IF_LINT(Code) Code - -/* Assume that the expression COND is true. This differs in intent - from 'assert', as it is a message from the programmer to the compiler. */ -# define lint_assume(cond) ((cond) ? (void) 0 : abort ()) - -#else -# define IF_LINT(Code) /* empty */ -# define lint_assume(cond) ((void) (0 && (cond))) -#endif - /* We used to use `abs', but that clashes with system headers on some platforms, and using a name reserved by Standard C is a bad idea anyway. */ @@ -3352,56 +3593,22 @@ static char const DIRECTORY_SEP = '/'; #define make_fixnum_or_float(val) \ (FIXNUM_OVERFLOW_P (val) ? make_float (val) : make_number (val)) - -/* Checks the `cycle check' variable CHECK to see if it indicates that - EL is part of a cycle; CHECK must be either Qnil or a value returned - by an earlier use of CYCLE_CHECK. SUSPICIOUS is the number of - elements after which a cycle might be suspected; after that many - elements, this macro begins consing in order to keep more precise - track of elements. - - Returns nil if a cycle was detected, otherwise a new value for CHECK - that includes EL. - - CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so - the caller should make sure that's ok. */ - -#define CYCLE_CHECK(check, el, suspicious) \ - (NILP (check) \ - ? make_number (0) \ - : (INTEGERP (check) \ - ? (XFASTINT (check) < (suspicious) \ - ? make_number (XFASTINT (check) + 1) \ - : Fcons (el, Qnil)) \ - : (!NILP (Fmemq ((el), (check))) \ - ? Qnil \ - : Fcons ((el), (check))))) - - /* SAFE_ALLOCA normally allocates memory on the stack, but if size is larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */ -enum MAX_ALLOCA { MAX_ALLOCA = 16*1024 }; +enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 }; extern Lisp_Object safe_alloca_unwind (Lisp_Object); +extern void *record_xmalloc (size_t); #define USE_SAFE_ALLOCA \ - ptrdiff_t sa_count = SPECPDL_INDEX (); int sa_must_free = 0 + ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = 0 /* SAFE_ALLOCA allocates a simple buffer. */ -#define SAFE_ALLOCA(buf, type, size) \ - do { \ - if ((size) < MAX_ALLOCA) \ - buf = (type) alloca (size); \ - else \ - { \ - buf = xmalloc (size); \ - sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, \ - make_save_value (buf, 0)); \ - } \ - } while (0) +#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \ + ? alloca (size) \ + : (sa_must_free = 1, record_xmalloc (size))) /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * NITEMS items, each of the same type as *BUF. MULTIPLIER must @@ -3433,21 +3640,21 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object); /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ -#define SAFE_ALLOCA_LISP(buf, nelt) \ - do { \ - if ((nelt) < MAX_ALLOCA / sizeof (Lisp_Object)) \ - buf = (Lisp_Object *) alloca ((nelt) * sizeof (Lisp_Object)); \ - else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)) \ - { \ - Lisp_Object arg_; \ - buf = xmalloc ((nelt) * sizeof (Lisp_Object)); \ - arg_ = make_save_value (buf, nelt); \ - XSAVE_VALUE (arg_)->dogc = 1; \ - sa_must_free = 1; \ - record_unwind_protect (safe_alloca_unwind, arg_); \ - } \ - else \ - memory_full (SIZE_MAX); \ +#define SAFE_ALLOCA_LISP(buf, nelt) \ + do { \ + if ((nelt) < MAX_ALLOCA / word_size) \ + buf = alloca ((nelt) * word_size); \ + else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ + { \ + Lisp_Object arg_; \ + buf = xmalloc ((nelt) * word_size); \ + arg_ = make_save_value (buf, nelt); \ + XSAVE_VALUE (arg_)->dogc = 1; \ + sa_must_free = 1; \ + record_unwind_protect (safe_alloca_unwind, arg_); \ + } \ + else \ + memory_full (SIZE_MAX); \ } while (0) @@ -3455,7 +3662,7 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object); /* Check whether it's time for GC, and run it if so. */ -static inline void +LISP_INLINE void maybe_gc (void) { if ((consing_since_gc > gc_cons_threshold @@ -3465,4 +3672,38 @@ maybe_gc (void) Fgarbage_collect (); } +LISP_INLINE int +functionp (Lisp_Object object) +{ + if (SYMBOLP (object) && !NILP (Ffboundp (object))) + { + object = Findirect_function (object, Qt); + + if (CONSP (object) && EQ (XCAR (object), Qautoload)) + { + /* Autoloaded symbols are functions, except if they load + macros or keymaps. */ + int i; + for (i = 0; i < 4 && CONSP (object); i++) + object = XCDR (object); + + return ! (CONSP (object) && !NILP (XCAR (object))); + } + } + + if (SUBRP (object)) + return XSUBR (object)->max_args != UNEVALLED; + else if (COMPILEDP (object)) + return 1; + else if (CONSP (object)) + { + Lisp_Object car = XCAR (object); + return EQ (car, Qlambda) || EQ (car, Qclosure); + } + else + return 0; +} + +INLINE_HEADER_END + #endif /* EMACS_LISP_H */