#define XSYMBOL(a) (eassert (SYMBOLP(a)),(struct Lisp_Symbol *) XPNTR(a))
#define XFLOAT(a) (eassert (FLOATP(a)),(struct Lisp_Float *) XPNTR(a))
+/* Extract the size field of a vector-like object. */
+
+#define XVECTORLIKE_HEADER_SIZE(a) \
+ (((struct vectorlike_header *) XPNTR (a))->size + 0)
+
/* Misc types. */
#define XMISC(a) ((union Lisp_Misc *) XPNTR(a))
/* Pseudovector types. */
-#define XSETPVECTYPE(v,code) ((v)->size |= PSEUDOVECTOR_FLAG | (code))
+#define XSETPVECTYPE(v, code) XSETTYPED_PVECTYPE(v, header.size, code)
+#define XSETTYPED_PVECTYPE(v, size_member, code) \
+ ((v)->size_member |= PSEUDOVECTOR_FLAG | (code))
+#define XSETPVECTYPESIZE(v, code, sizeval) \
+ ((v)->header.size = PSEUDOVECTOR_FLAG | (code) | (sizeval))
#define XSETPSEUDOVECTOR(a, b, code) \
+ XSETTYPED_PSEUDOVECTOR(a, b, XVECTORLIKE_HEADER_SIZE (a), code)
+#define XSETTYPED_PSEUDOVECTOR(a, b, size, code) \
(XSETVECTOR (a, b), \
- eassert ((XVECTOR (a)->size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
+ eassert ((size & (PSEUDOVECTOR_FLAG | PVEC_TYPE_MASK)) \
== (PSEUDOVECTOR_FLAG | (code))))
#define XSETWINDOW_CONFIGURATION(a, b) \
(XSETPSEUDOVECTOR (a, b, PVEC_WINDOW_CONFIGURATION))
#define XSETPROCESS(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_PROCESS))
#define XSETWINDOW(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_WINDOW))
#define XSETTERMINAL(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TERMINAL))
-#define XSETSUBR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUBR))
+#define XSETSUBR(a, b) \
+ XSETTYPED_PSEUDOVECTOR (a, b, XSUBR (a)->size, PVEC_SUBR)
#define XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
#define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
/* Convenience macros for dealing with Lisp arrays. */
#define AREF(ARRAY, IDX) XVECTOR ((ARRAY))->contents[IDX]
-#define ASIZE(ARRAY) XVECTOR ((ARRAY))->size
+#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)), \
unsigned char *data;
};
-struct Lisp_Vector
+/* Header of vector-like objects. This type documents the constraints on
+ layout of vectors and pseudovectors, and helps optimizing compilers not get
+ fooled by Emacs's type punning. */
+struct vectorlike_header
{
EMACS_UINT size;
- struct Lisp_Vector *next;
+ union {
+ struct buffer *buffer;
+ struct Lisp_Vector *vector;
+ } next;
+ };
+
+struct Lisp_Vector
+ {
+ struct vectorlike_header header;
Lisp_Object contents[1];
};
/* Return the number of "extra" slots in the char table CT. */
#define CHAR_TABLE_EXTRA_SLOTS(CT) \
- (((CT)->size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
+ (((CT)->header.size & PSEUDOVECTOR_SIZE_MASK) - CHAR_TABLE_STANDARD_SLOTS)
#ifdef __GNUC__
struct Lisp_Char_Table
{
- /* This is the vector's size field, which also holds the
+ /* HEADER.SIZE is the vector's size field, which also holds the
pseudovector type information. It holds the size, too.
The size counts the defalt, parent, purpose, ascii,
contents, and extras slots. */
- EMACS_UINT size;
- struct Lisp_Vector *next;
+ struct vectorlike_header header;
/* This holds a default value,
which is used whenever the value for a specific character is nil. */
struct Lisp_Sub_Char_Table
{
- /* This is the vector's size field, which also holds the
+ /* HEADER.SIZE is the vector's size field, which also holds the
pseudovector type information. It holds the size, too. */
- EMACS_INT size;
- struct Lisp_Vector *next;
+ struct vectorlike_header header;
/* Depth of this sub char-table. It should be 1, 2, or 3. A sub
char-table of depth 1 contains 16 elements, and each element
/* A boolvector is a kind of vectorlike, with contents are like a string. */
struct Lisp_Bool_Vector
{
- /* This is the vector's size field. It doesn't have the real size,
+ /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
just the subtype information. */
- EMACS_UINT vector_size;
- struct Lisp_Vector *next;
+ struct vectorlike_header header;
/* This is the size in bits. */
EMACS_UINT size;
/* This contains the actual bits, packed into bytes. */
This type is treated in most respects as a pseudovector,
but since we never dynamically allocate or free them,
- we don't need a next-vector field. */
+ we don't need a struct vectorlike_header and its 'next' field. */
struct Lisp_Subr
{
struct Lisp_Hash_Table
{
- /* Vector fields. The hash table code doesn't refer to these. */
- EMACS_UINT size;
- struct Lisp_Vector *vec_next;
+ /* This is for Lisp; the hash table code does not refer to it. */
+ struct vectorlike_header header;
/* Function used to compare keys. */
Lisp_Object test;
/* Value is the size of hash table H. */
-#define HASH_TABLE_SIZE(H) XVECTOR ((H)->next)->size
+#define HASH_TABLE_SIZE(H) ASIZE ((H)->next)
/* Default size for hash tables if not specified. */
#define CONSP(x) (XTYPE ((x)) == Lisp_Cons)
#define FLOATP(x) (XTYPE ((x)) == Lisp_Float)
-#define VECTORP(x) (VECTORLIKEP (x) && !(XVECTOR (x)->size & PSEUDOVECTOR_FLAG))
+#define VECTORP(x) (VECTORLIKEP (x) && !(ASIZE (x) & PSEUDOVECTOR_FLAG))
#define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
#define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker)
#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
/* True if object X is a pseudovector whose code is CODE. */
#define PSEUDOVECTORP(x, code) \
+ TYPED_PSEUDOVECTORP(x, vectorlike_header, code)
+
+/* True if object X, with internal type struct T *, is a pseudovector whose
+ code is CODE. */
+#define TYPED_PSEUDOVECTORP(x, t, code) \
(VECTORLIKEP (x) \
- && (((XVECTOR (x)->size & (PSEUDOVECTOR_FLAG | (code)))) \
+ && (((((struct t *) XPNTR (x))->size \
+ & (PSEUDOVECTOR_FLAG | (code)))) \
== (PSEUDOVECTOR_FLAG | (code))))
/* Test for specific pseudovector types. */
#define PROCESSP(x) PSEUDOVECTORP (x, PVEC_PROCESS)
#define WINDOWP(x) PSEUDOVECTORP (x, PVEC_WINDOW)
#define TERMINALP(x) PSEUDOVECTORP (x, PVEC_TERMINAL)
-#define SUBRP(x) PSEUDOVECTORP (x, PVEC_SUBR)
+#define SUBRP(x) TYPED_PSEUDOVECTORP (x, Lisp_Subr, PVEC_SUBR)
#define COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
#define CHAR_TABLE_P(x) PSEUDOVECTORP (x, PVEC_CHAR_TABLE)
} while (0)
extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object *, Lisp_Object);
-extern int isfloat_string (const char *, int);
+Lisp_Object string_to_number (char const *, int, int);
extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
Lisp_Object);
extern void dir_warning (const char *, Lisp_Object);