/* Fundamental definitions for GNU Emacs Lisp interpreter.
Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#ifdef ENABLE_CHECKING
+/* The suppress_checking variable is initialized to 0 in alloc.c. Set
+ it to 1 using a debugger to temporarily disable aborting on
+ detected internal inconsistencies or error conditions.
+
+ Testing suppress_checking after the supplied condition ensures that
+ the side effects produced by CHECK will be consistent, independent
+ of whether ENABLE_CHECKING is defined, or whether the checks are
+ suppressed at run time.
+
+ In some cases, a good compiler may be able to optimize away the
+ CHECK macro altogether, e.g., if XSTRING (x) uses CHECK to test
+ STRINGP (x), but a particular use of XSTRING is invoked only after
+ testing that STRINGP (x) is true, making the test redundant. */
+
#define CHECK(check,msg) (((check) || suppress_checking \
? (void) 0 \
: die ((msg), __FILE__, __LINE__)), \
#define eassert(cond) CHECK(cond,"assertion failed")
#endif
#endif /* ENABLE_CHECKING */
+\f
+/***** Select the tagging scheme. *****/
+/* There are basically two options that control the tagging scheme:
+ - NO_UNION_TYPE says that Lisp_Object should be an integer instead
+ of a union.
+ - USE_LSB_TAG means that we can assume the least 3 bits of pointers are
+ always 0, and we can thus use them to hold tag bits, without
+ restricting our addressing space.
+
+ If USE_LSB_TAG is not set, then we use the top 3 bits for tagging, thus
+ restricting our possible address range. Currently USE_LSB_TAG is not
+ allowed together with a union. This is not due to any fundamental
+ technical (or political ;-) problem: nobody wrote the code to do it yet.
+
+ USE_LSB_TAG not only requires the least 3 bits of pointers returned by
+ malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
+ on the few static Lisp_Objects used: all the defsubr as well
+ as the two special buffers buffer_defaults and buffer_local_symbols. */
+
+/* First, try and define DECL_ALIGN(type,var) which declares a static
+ variable VAR of type TYPE with the added requirement that it be
+ TYPEBITS-aligned. */
+#ifndef NO_DECL_ALIGN
+# ifndef DECL_ALIGN
+/* What compiler directive should we use for non-gcc compilers? -stef */
+# if defined (__GNUC__)
+# define DECL_ALIGN(type, var) \
+ type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
+# endif
+# endif
+#endif
+
+/* Let's USE_LSB_TAG on systems where we know malloc returns mult-of-8. */
+#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined MAC_OSX
+/* We also need to be able to specify mult-of-8 alignment on static vars. */
+# if defined DECL_ALIGN
+/* We currently do not support USE_LSB_TAG with a union Lisp_Object. */
+# if defined NO_UNION_TYPE
+# define USE_LSB_TAG
+# endif
+# endif
+#endif
+
+/* If we cannot use 8-byte alignment, make DECL_ALIGN a no-op. */
+#ifndef DECL_ALIGN
+# ifdef USE_LSB_TAG
+# error "USE_LSB_TAG used without defining DECL_ALIGN"
+# endif
+# define DECL_ALIGN(type, var) type var
+#endif
+
/* Define the fundamental Lisp data structures. */
Lisp_Misc_Objfwd,
Lisp_Misc_Buffer_Objfwd,
Lisp_Misc_Buffer_Local_Value,
- Lisp_Misc_Some_Buffer_Local_Value,
Lisp_Misc_Overlay,
Lisp_Misc_Kboard_Objfwd,
Lisp_Misc_Save_Value,
{
/* Used for comparing two Lisp_Objects;
also, positive integers can be accessed fast this way. */
- EMACS_INT i;
+ EMACS_UINT i;
struct
{
{
/* Used for comparing two Lisp_Objects;
also, positive integers can be accessed fast this way. */
- EMACS_INT i;
+ EMACS_UINT i;
struct
{
#define LISP_MAKE_RVALUE(o) (o)
#endif
-#endif /* NO_UNION_TYPE */
-
+#else /* NO_UNION_TYPE */
/* If union type is not wanted, define Lisp_Object as just a number. */
-#ifdef NO_UNION_TYPE
typedef EMACS_INT Lisp_Object;
#define LISP_MAKE_RVALUE(o) (0+(o))
#endif /* NO_UNION_TYPE */
-/* Two flags that are set during GC. On some machines, these flags
- are defined differently by the m- file. */
-
/* In the size word of a vector, this bit means the vector has been marked. */
-#ifndef ARRAY_MARK_FLAG
-#define ARRAY_MARK_FLAG ((EMACS_INT) ((EMACS_UINT) 1 << (VALBITS + GCTYPEBITS - 1)))
-#endif /* no ARRAY_MARK_FLAG */
+#define ARRAY_MARK_FLAG ((EMACS_UINT) 1 << (BITS_PER_EMACS_INT - 1))
/* In the size word of a struct Lisp_Vector, this bit means it's really
some other vector-like object. */
-#ifndef PSEUDOVECTOR_FLAG
-#define PSEUDOVECTOR_FLAG ((ARRAY_MARK_FLAG >> 1) & ~ARRAY_MARK_FLAG)
-#endif
+#define PSEUDOVECTOR_FLAG ((ARRAY_MARK_FLAG >> 1))
/* In a pseudovector, the size field actually contains a word with one
PSEUDOVECTOR_FLAG bit set, and exactly one of the following bits to
- indicate the actual type. */
+ indicate the actual type.
+ We use a bitset, even tho only one of the bits can be set at any
+ particular time just so as to be able to use micro-optimizations such as
+ testing membership of a particular subset of pseudovectors in Fequal.
+ It is not crucial, but there are plenty of bits here, so why not do it? */
enum pvec_type
{
PVEC_NORMAL_VECTOR = 0,
PVEC_BOOL_VECTOR = 0x10000,
PVEC_BUFFER = 0x20000,
PVEC_HASH_TABLE = 0x40000,
- PVEC_SUB_CHAR_TABLE = 0x80000,
- PVEC_TYPE_MASK = 0x0ffe00
+ PVEC_TERMINAL = 0x80000,
+ PVEC_SUB_CHAR_TABLE = 0x100000,
+ PVEC_OTHER = 0x200000,
+ PVEC_TYPE_MASK = 0x2ffe00
#if 0 /* This is used to make the value of PSEUDOVECTOR_FLAG available to
GDB. It doesn't work on OS Alpha. Moved to a variable in
of bool vectors. This should not vary across implementations. */
#define BOOL_VECTOR_BITS_PER_CHAR 8
\f
-/***** Select the tagging scheme. *****/
-/* There are basically two options that control the tagging scheme:
- - NO_UNION_TYPE says that Lisp_Object should be an integer instead
- of a union.
- - USE_LSB_TAG means that we can assume the least 3 bits of pointers are
- always 0, and we can thus use them to hold tag bits, without
- restricting our addressing space.
-
- If USE_LSB_TAG is not set, then we use the top 3 bits for tagging, thus
- restricting our possible address range. Currently USE_LSB_TAG is not
- allowed together with a union. This is not due to any fundamental
- technical (or political ;-) problem: nobody wrote the code to do it yet.
-
- USE_LSB_TAG not only requires the least 3 bits of pointers returned by
- malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
- on the few static Lisp_Objects used: all the defsubr as well
- as the two special buffers buffer_defaults and buffer_local_symbols. */
-
-/* First, try and define DECL_ALIGN(type,var) which declares a static
- variable VAR of type TYPE with the added requirement that it be
- TYPEBITS-aligned. */
-#ifndef NO_DECL_ALIGN
-# ifndef DECL_ALIGN
-/* What compiler directive should we use for non-gcc compilers? -stef */
-# if defined (__GNUC__)
-# define DECL_ALIGN(type, var) \
- type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
-# endif
-# endif
-#endif
-
-/* Let's USE_LSB_TAG on systems where we know malloc returns mult-of-8. */
-#if defined GNU_MALLOC || defined DOUG_LEA_MALLOC || defined __GLIBC__ || defined MAC_OSX
-/* We also need to be able to specify mult-of-8 alignment on static vars. */
-# if defined DECL_ALIGN
-/* We currently do not support USE_LSB_TAG with a union Lisp_Object. */
-# if defined NO_UNION_TYPE
-# define USE_LSB_TAG
-# endif
-# endif
-#endif
-
-/* If we cannot use 8-byte alignment, make DECL_ALIGN a no-op. */
-#ifndef DECL_ALIGN
-# ifdef USE_LSB_TAG
-# error "USE_LSB_TAG used without defining DECL_ALIGN"
-# endif
-# define DECL_ALIGN(type, var) type var
-#endif
-
-\f
/* These macros extract various sorts of values from a Lisp_Object.
For example, if tem is a Lisp_Object whose type is Lisp_Cons,
XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */
#ifdef NO_UNION_TYPE
+/* Return a perfect hash of the Lisp_Object representation. */
+#define XHASH(a) (a)
+
#ifdef USE_LSB_TAG
#define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1)
#endif /* not USE_LSB_TAG */
-#define EQ(x, y) ((x) == (y))
-
#else /* not NO_UNION_TYPE */
+#define XHASH(a) ((a).i)
+
#define XTYPE(a) ((enum Lisp_Type) (a).u.type)
/* For integers known to be positive, XFASTINT provides fast retrieval
extern Lisp_Object make_number P_ ((EMACS_INT));
#endif
-#define EQ(x, y) ((x).i == (y).i)
-
#endif /* NO_UNION_TYPE */
+#define EQ(x, y) (XHASH (x) == XHASH (y))
+
#ifndef XPNTR
#ifdef HAVE_SHM
/* In this representation, data is found in two widely separated segments. */
/* Misc types. */
#define XMISC(a) ((union Lisp_Misc *) XPNTR(a))
-#define XMISCTYPE(a) (XMARKER (a)->type)
-#define XMARKER(a) (&(XMISC(a)->u_marker))
-#define XINTFWD(a) (&(XMISC(a)->u_intfwd))
-#define XBOOLFWD(a) (&(XMISC(a)->u_boolfwd))
-#define XOBJFWD(a) (&(XMISC(a)->u_objfwd))
-#define XBUFFER_OBJFWD(a) (&(XMISC(a)->u_buffer_objfwd))
-#define XBUFFER_LOCAL_VALUE(a) (&(XMISC(a)->u_buffer_local_value))
-#define XOVERLAY(a) (&(XMISC(a)->u_overlay))
-#define XKBOARD_OBJFWD(a) (&(XMISC(a)->u_kboard_objfwd))
-#define XSAVE_VALUE(a) (&(XMISC(a)->u_save_value))
+#define XMISCANY(a) (eassert (MISCP (a)), &(XMISC(a)->u_any))
+#define XMISCTYPE(a) (XMISCANY (a)->type)
+#define XMARKER(a) (eassert (MARKERP (a)), &(XMISC(a)->u_marker))
+#define XINTFWD(a) (eassert (INTFWDP (a)), &(XMISC(a)->u_intfwd))
+#define XBOOLFWD(a) (eassert (BOOLFWDP (a)), &(XMISC(a)->u_boolfwd))
+#define XOBJFWD(a) (eassert (OBJFWDP (a)), &(XMISC(a)->u_objfwd))
+#define XOVERLAY(a) (eassert (OVERLAYP (a)), &(XMISC(a)->u_overlay))
+#define XSAVE_VALUE(a) (eassert (SAVE_VALUEP (a)), &(XMISC(a)->u_save_value))
+#define XBUFFER_OBJFWD(a) \
+ (eassert (BUFFER_OBJFWDP (a)), &(XMISC(a)->u_buffer_objfwd))
+#define XBUFFER_LOCAL_VALUE(a) \
+ (eassert (BUFFER_LOCAL_VALUEP (a)), &(XMISC(a)->u_buffer_local_value))
+#define XKBOARD_OBJFWD(a) \
+ (eassert (KBOARD_OBJFWDP (a)), &(XMISC(a)->u_kboard_objfwd))
/* Pseudovector types. */
#define XPROCESS(a) (eassert (PROCESSP(a)),(struct Lisp_Process *) XPNTR(a))
#define XWINDOW(a) (eassert (WINDOWP(a)),(struct window *) XPNTR(a))
+#define XTERMINAL(a) (eassert (TERMINALP(a)),(struct terminal *) XPNTR(a))
#define XSUBR(a) (eassert (SUBRP(a)),(struct Lisp_Subr *) XPNTR(a))
#define XBUFFER(a) (eassert (BUFFERP(a)),(struct buffer *) XPNTR(a))
-#define XCHAR_TABLE(a) ((struct Lisp_Char_Table *) XPNTR(a))
-#define XSUB_CHAR_TABLE(a) ((struct Lisp_Sub_Char_Table *) XPNTR(a))
-#define XBOOL_VECTOR(a) ((struct Lisp_Bool_Vector *) XPNTR(a))
+#define XCHAR_TABLE(a) (eassert (CHAR_TABLE_P (a)), (struct Lisp_Char_Table *) XPNTR(a))
+#define XSUB_CHAR_TABLE(a) (eassert (SUB_CHAR_TABLE_P (a)), (struct Lisp_Sub_Char_Table *) XPNTR(a))
+#define XBOOL_VECTOR(a) (eassert (BOOL_VECTOR_P (a)), (struct Lisp_Bool_Vector *) XPNTR(a))
/* Construct a Lisp_Object from a value or address. */
/* Pseudovector types. */
+#define XSETPVECTYPE(v,code) ((v)->size |= PSEUDOVECTOR_FLAG | (code))
#define XSETPSEUDOVECTOR(a, b, code) \
- (XSETVECTOR (a, b), XVECTOR (a)->size |= PSEUDOVECTOR_FLAG | (code))
+ (XSETVECTOR (a, b), \
+ eassert ((XVECTOR (a)->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 XSETCOMPILED(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_COMPILED))
#define XSETBUFFER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BUFFER))
/* 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
+/* 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))
/* Convenience macros for dealing with Lisp strings. */
-#define SREF(string, index) (XSTRING (string)->data[index] + 0)
-#define SSET(string, index, new) (XSTRING (string)->data[index] = (new))
#define SDATA(string) (XSTRING (string)->data + 0)
+#define SREF(string, index) (SDATA (string)[index] + 0)
+#define SSET(string, index, new) (SDATA (string)[index] = (new))
#define SCHARS(string) (XSTRING (string)->size + 0)
#define SBYTES(string) (STRING_BYTES (XSTRING (string)) + 0)
(XSTRING (string)->size = (newsize))
#define STRING_COPYIN(string, index, new, count) \
- bcopy (new, XSTRING (string)->data + index, count)
+ bcopy (new, SDATA (string) + index, count)
/* Type checking. */
struct Lisp_Vector
{
- EMACS_INT size;
+ EMACS_UINT size;
struct Lisp_Vector *next;
Lisp_Object contents[1];
};
struct Lisp_Char_Table
{
/* This 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_INT size;
+ 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;
/* This holds a default value,
{
/* This is the vector's size field. It doesn't have the real size,
just the subtype information. */
- EMACS_INT vector_size;
+ EMACS_UINT vector_size;
struct Lisp_Vector *next;
/* This is the size in bits. */
- EMACS_INT size;
+ EMACS_UINT size;
/* This contains the actual bits, packed into bytes. */
unsigned char data[1];
};
struct Lisp_Subr
{
- EMACS_INT size;
+ EMACS_UINT size;
Lisp_Object (*function) ();
short min_args, max_args;
char *symbol_name;
- char *prompt;
+ char *intspec;
char *doc;
};
struct Lisp_Hash_Table
{
/* Vector fields. The hash table code doesn't refer to these. */
- EMACS_INT size;
+ EMACS_UINT size;
struct Lisp_Vector *vec_next;
/* Function used to compare keys. */
ratio, a float. */
Lisp_Object rehash_threshold;
- /* Number of key/value entries in the table. */
- Lisp_Object count;
-
- /* Vector of keys and values. The key of item I is found at index
- 2 * I, the value is found at index 2 * I + 1. */
- Lisp_Object key_and_value;
-
/* Vector of hash codes.. If hash[I] is nil, this means that that
entry I is unused. */
Lisp_Object hash;
/* User-supplied key comparison function, or nil. */
Lisp_Object user_cmp_function;
+ /* Only the fields above are traced normally by the GC. The ones below
+ `count'. are special and are either ignored by the GC or traced in
+ a special way (e.g. because of weakness). */
+
+ /* Number of key/value entries in the table. */
+ unsigned int count;
+
+ /* Vector of keys and values. The key of item I is found at index
+ 2 * I, the value is found at index 2 * I + 1.
+ This is gc_marked specially if the table is weak. */
+ Lisp_Object key_and_value;
+
/* Next weak hash table if this is a weak hash table. The head
of the list is in weak_hash_tables. */
struct Lisp_Hash_Table *next_weak;
\f
/* These structures are used for various misc types. */
+struct Lisp_Misc_Any /* Supertype of all Misc types. */
+{
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Marker */
+ unsigned gcmarkbit : 1;
+ int spacer : 15;
+};
+
struct Lisp_Marker
{
- int type : 16; /* = Lisp_Misc_Marker */
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Marker */
unsigned gcmarkbit : 1;
- int spacer : 14;
+ int spacer : 13;
+ /* This flag is temporarily used in the functions
+ decode/encode_coding_object to record that the marker position
+ must be adjusted after the conversion. */
+ unsigned int need_adjustment : 1;
/* 1 means normal insertion at the marker's position
leaves the marker after the inserted text. */
unsigned int insertion_type : 1;
- /* This is the buffer that the marker points into,
- or 0 if it points nowhere. */
+ /* This is the buffer that the marker points into, or 0 if it points nowhere.
+ Note: a chain of markers can contain markers pointing into different
+ buffers (the chain is per buffer_text rather than per buffer, so it's
+ shared between indirect buffers). */
+ /* This is used for (other than NULL-checking):
+ - Fmarker_buffer
+ - Fset_marker: check eq(oldbuf, newbuf) to avoid unchain+rechain.
+ - unchain_marker: to find the list from which to unchain.
+ - Fkill_buffer: to unchain the markers of current indirect buffer.
+ */
struct buffer *buffer;
/* The remaining fields are meaningless in a marker that
/* For markers that point somewhere,
this is used to chain of all the markers in a given buffer. */
+ /* We could remove it and use an array in buffer_text instead.
+ That would also allow to preserve it ordered. */
struct Lisp_Marker *next;
/* This is the char position where the marker points. */
EMACS_INT charpos;
int type : 16; /* = Lisp_Misc_Buffer_Objfwd */
unsigned gcmarkbit : 1;
int spacer : 15;
+ Lisp_Object slottype; /* Qnil, Lisp_Int, Lisp_Symbol, or Lisp_String. */
int offset;
};
binding into `realvalue' (or through it). Also update
LOADED-BINDING to point to the newly loaded binding.
- Lisp_Misc_Buffer_Local_Value and Lisp_Misc_Some_Buffer_Local_Value
- both use this kind of structure. With the former, merely setting
- the variable creates a local binding for the current buffer. With
- the latter, setting the variable does not do that; only
- make-local-variable does that. */
+ `local_if_set' indicates that merely setting the variable creates a local
+ binding for the current buffer. Otherwise the latter, setting the
+ variable does not do that; only make-local-variable does that. */
struct Lisp_Buffer_Local_Value
{
- int type : 16; /* = Lisp_Misc_Buffer_Local_Value
- or Lisp_Misc_Some_Buffer_Local_Value */
+ int type : 16; /* = Lisp_Misc_Buffer_Local_Value */
unsigned gcmarkbit : 1;
- int spacer : 12;
+ int spacer : 11;
+ /* 1 means that merely setting the variable creates a local
+ binding for the current buffer */
+ unsigned int local_if_set : 1;
/* 1 means this variable is allowed to have frame-local bindings,
so check for them when looking for the proper binding. */
unsigned int check_frame : 1;
unsigned int found_for_frame : 1;
Lisp_Object realvalue;
/* The buffer and frame for which the loaded binding was found. */
+ /* Having both is only needed if we want to allow variables that are
+ both buffer local and frame local (in which case, we currently give
+ precedence to the buffer-local binding). I don't think such
+ a combination is desirable. --Stef */
Lisp_Object buffer, frame;
/* A cons cell, (LOADED-BINDING . DEFAULT-VALUE).
PLIST is the overlay's property list. */
struct Lisp_Overlay
{
- int type : 16; /* = Lisp_Misc_Overlay */
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Overlay */
unsigned gcmarkbit : 1;
int spacer : 15;
struct Lisp_Overlay *next;
current kboard. */
struct Lisp_Kboard_Objfwd
{
- int type : 16; /* = Lisp_Misc_Kboard_Objfwd */
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Kboard_Objfwd */
unsigned gcmarkbit : 1;
int spacer : 15;
int offset;
This type of object is used in the arg to record_unwind_protect. */
struct Lisp_Save_Value
{
- int type : 16; /* = Lisp_Misc_Save_Value */
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Save_Value */
unsigned gcmarkbit : 1;
int spacer : 14;
/* If DOGC is set, POINTER is the address of a memory
/* A miscellaneous object, when it's on the free list. */
struct Lisp_Free
{
- int type : 16; /* = Lisp_Misc_Free */
+ enum Lisp_Misc_Type type : 16; /* = Lisp_Misc_Free */
unsigned gcmarkbit : 1;
int spacer : 15;
union Lisp_Misc *chain;
union Lisp_Misc
{
- struct Lisp_Free u_free;
+ struct Lisp_Misc_Any u_any; /* Supertype of all Misc types. */
+ struct Lisp_Free u_free; /* Includes padding to force alignment. */
struct Lisp_Marker u_marker;
struct Lisp_Intfwd u_intfwd;
struct Lisp_Boolfwd u_boolfwd;
All callers should assure that at least this size of memory is
allocated at the place pointed by the second argument.
- Thers are 6 modifiers, each consumes 2 chars.
+ There are 6 modifiers, each consumes 2 chars.
The octal form of a character code consumes
(1 + CHARACTERBITS / 3 + 1) chars (including backslash at the head).
We need one more byte for string terminator `\0'. */
#define KEY_DESCRIPTION_SIZE ((2 * 6) + 1 + (CHARACTERBITS / 3) + 1 + 1)
-#ifdef USE_X_TOOLKIT
-#ifdef NO_UNION_TYPE
-/* Use this for turning a (void *) into a Lisp_Object, as when the
- Lisp_Object is passed into a toolkit callback function. */
-#define VOID_TO_LISP(larg,varg) \
- do { ((larg) = ((Lisp_Object) (varg))); } while (0)
-#define CVOID_TO_LISP VOID_TO_LISP
-
-/* Use this for turning a Lisp_Object into a (void *), as when the
- Lisp_Object is passed into a toolkit callback function. */
-#define LISP_TO_VOID(larg) ((void *) (larg))
-#define LISP_TO_CVOID(varg) ((const void *) (larg))
-
-#else /* not NO_UNION_TYPE */
-/* Use this for turning a (void *) into a Lisp_Object, as when the
- Lisp_Object is passed into a toolkit callback function. */
-#define VOID_TO_LISP(larg,varg) \
- do { ((larg).v = (void *) (varg)); } while (0)
-#define CVOID_TO_LISP(larg,varg) \
- do { ((larg).cv = (const void *) (varg)); } while (0)
-
-/* Use this for turning a Lisp_Object into a (void *), as when the
- Lisp_Object is passed into a toolkit callback function. */
-#define LISP_TO_VOID(larg) ((larg).v)
-#define LISP_TO_CVOID(larg) ((larg).cv)
-#endif /* not NO_UNION_TYPE */
-#endif /* USE_X_TOOLKIT */
-
\f
-/* The glyph datatype, used to represent characters on the display. */
-
-/* Glyph code to use as an index to the glyph table. If it is out of
- range for the glyph table, or the corresonding element in the table
- is nil, the low 8 bits are the single byte character code, and the
- bits above are the numeric face ID. If FID is the face ID of a
- glyph on a frame F, then F->display.x->faces[FID] contains the
- description of that face. This is an int instead of a short, so we
- can support a good bunch of face ID's (2^(31 - 8)); given that we
- have no mechanism for tossing unused frame face ID's yet, we'll
- probably run out of 255 pretty quickly.
- This is always -1 for a multibyte character. */
-#define GLYPH int
-
-/* Mask bits for face. */
-#define GLYPH_MASK_FACE 0x7FC00000
- /* Mask bits for character code. */
-#define GLYPH_MASK_CHAR 0x003FFFFF /* The lowest 22 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) << CHARACTERBITS))
+/* The glyph datatype, used to represent characters on the display.
+ It consists of a char code and a face id. */
+
+typedef struct {
+ int ch;
+ int face_id;
+} GLYPH;
/* Return a glyph's character code. */
-#define FAST_GLYPH_CHAR(glyph) ((glyph) & GLYPH_MASK_CHAR)
+#define GLYPH_CHAR(glyph) ((glyph).ch)
/* Return a glyph's face ID. */
-#define FAST_GLYPH_FACE(glyph) (((glyph) & GLYPH_MASK_FACE) >> CHARACTERBITS)
+#define GLYPH_FACE(glyph) ((glyph).face_id)
-/* Slower versions that test the frame type first. */
-#define MAKE_GLYPH(f, char, face) (FAST_MAKE_GLYPH (char, face))
-#define GLYPH_CHAR(f, g) (FAST_GLYPH_CHAR (g))
-#define GLYPH_FACE(f, g) (FAST_GLYPH_FACE (g))
+#define SET_GLYPH_CHAR(glyph, char) ((glyph).ch = (char))
+#define SET_GLYPH_FACE(glyph, face) ((glyph).face_id = (face))
+#define SET_GLYPH(glyph, char, face) ((glyph).ch = (char), (glyph).face_id = (face))
/* Return 1 if GLYPH contains valid character code. */
-#define GLYPH_CHAR_VALID_P(glyph) CHAR_VALID_P (FAST_GLYPH_CHAR (glyph), 1)
+#define GLYPH_CHAR_VALID_P(glyph) CHAR_VALID_P (GLYPH_CHAR (glyph), 1)
+
+
+/* Glyph Code from a display vector may either be an integer which
+ encodes a char code in the lower CHARACTERBITS bits and a (very small)
+ face-id in the upper bits, or it may be a cons (CHAR . FACE-ID). */
+
+#define GLYPH_CODE_CHAR(gc) \
+ (CONSP (gc) ? XINT (XCAR (gc)) : INTEGERP (gc) ? (XINT (gc) & ((1 << CHARACTERBITS)-1)) : 0)
+
+#define GLYPH_CODE_FACE(gc) \
+ (CONSP (gc) ? XINT (XCDR (gc)) : INTEGERP (gc) ? (XINT (gc) >> CHARACTERBITS) : DEFAULT_FACE_ID)
+
+/* Return 1 if glyph code from display vector contains valid character code. */
+#define GLYPH_CODE_CHAR_VALID_P(gc) CHAR_VALID_P (GLYPH_CODE_CHAR (gc), 1)
+
+#define GLYPH_CODE_P(gc) ((CONSP (gc) && INTEGERP (XCAR (gc)) && INTEGERP (XCDR (gc))) || INTEGERP (gc))
+
+/* Only called when GLYPH_CODE_P (gc) is true. */
+#define SET_GLYPH_FROM_GLYPH_CODE(glyph, gc) \
+ do \
+ { \
+ if (CONSP (gc)) \
+ SET_GLYPH (glyph, XINT (XCAR (gc)), XINT (XCDR (gc))); \
+ else \
+ SET_GLYPH (glyph, (XINT (gc) & ((1 << CHARACTERBITS)-1)), \
+ (XINT (gc) >> CHARACTERBITS)); \
+ } \
+ while (0)
/* The ID of the mode line highlighting face. */
#define GLYPH_MODE_LINE_FACE 1
#define BUFFER_LOCAL_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Buffer_Local_Value)
#define SOME_BUFFER_LOCAL_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Some_Buffer_Local_Value)
#define KBOARD_OBJFWDP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Kboard_Objfwd)
+#define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value)
/* True if object X is a pseudovector whose code is CODE. */
#define WINDOW_CONFIGURATIONP(x) PSEUDOVECTORP (x, PVEC_WINDOW_CONFIGURATION)
#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 COMPILEDP(x) PSEUDOVECTORP (x, PVEC_COMPILED)
#define BUFFERP(x) PSEUDOVECTORP (x, PVEC_BUFFER)
followed by the address of a vector of Lisp_Objects
which contains the argument values.
UNEVALLED means pass the list of unevaluated arguments
- `prompt' says how to read arguments for an interactive call.
- See the doc string for `interactive'.
+ `intspec' says how interactive arguments are to be fetched.
+ If the string starts with a `(', `intspec' is evaluated and the resulting
+ list is the list of arguments.
+ If it's a string that doesn't start with `(', the value should follow
+ the one of the doc string for `interactive'.
A null string means call interactively with no arguments.
`doc' is documentation for the user. */
-#if (!defined (__STDC__) && !defined (PROTOTYPES)) \
- || defined (USE_NONANSI_DEFUN)
+#if (!defined (__STDC__) && !defined (PROTOTYPES))
-#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc) \
+#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
Lisp_Object fnname (); \
DECL_ALIGN (struct Lisp_Subr, sname) = \
{ PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \
- fnname, minargs, maxargs, lname, prompt, 0}; \
+ fnname, minargs, maxargs, lname, intspec, 0}; \
Lisp_Object fnname
#else
/* This version of DEFUN declares a function prototype with the right
arguments, so we can catch errors with maxargs at compile-time. */
-#define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc) \
+#define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \
Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \
DECL_ALIGN (struct Lisp_Subr, sname) = \
{ PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)), \
- fnname, minargs, maxargs, lname, prompt, 0}; \
+ fnname, minargs, maxargs, lname, intspec, 0}; \
Lisp_Object fnname
/* Note that the weird token-substitution semantics of ANSI C makes
extern void defvar_lisp_nopro P_ ((char *, Lisp_Object *));
extern void defvar_bool P_ ((char *, int *));
extern void defvar_int P_ ((char *, EMACS_INT *));
-extern void defvar_per_buffer P_ ((char *, Lisp_Object *, Lisp_Object, char *));
extern void defvar_kboard P_ ((char *, int));
/* Macros we use to define forwarded Lisp variables.
#define DEFVAR_BOOL(lname, vname, doc) defvar_bool (lname, vname)
#define DEFVAR_INT(lname, vname, doc) defvar_int (lname, vname)
-/* TYPE is nil for a general Lisp variable.
- An integer specifies a type; then only LIsp values
- with that type code are allowed (except that nil is allowed too).
- LNAME is the LIsp-level variable name.
- VNAME is the name of the buffer slot.
- DOC is a dummy where you write the doc string as a comment. */
-#define DEFVAR_PER_BUFFER(lname, vname, type, doc) \
- defvar_per_buffer (lname, vname, type, 0)
-
#define DEFVAR_KBOARD(lname, vname, doc) \
defvar_kboard (lname, \
(int)((char *)(¤t_kboard->vname) \
\f
/* 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 (PROTOTYPES)) \
- || defined (USE_NONANSI_DEFUN)
+#if (!defined (__STDC__) && !defined (PROTOTYPES))
#define EXFUN(fnname, maxargs) \
extern Lisp_Object fnname ()
#else
EXFUN (Fupdate_coding_systems_internal, 0);
EXFUN (Fencode_coding_string, 4);
EXFUN (Fdecode_coding_string, 4);
-extern Lisp_Object detect_coding_system P_ ((const unsigned char *, int,
- int, int, int, Lisp_Object));
+extern Lisp_Object detect_coding_system P_ ((const unsigned char *, EMACS_INT,
+ EMACS_INT, int, int, Lisp_Object));
extern void init_coding P_ ((void));
extern void init_coding_once P_ ((void));
extern void syms_of_coding P_ ((void));
EXFUN (Fchar_bytes, 1);
EXFUN (Fchar_width, 1);
EXFUN (Fstring, MANY);
-extern int chars_in_text P_ ((const unsigned char *, int));
-extern int multibyte_chars_in_text P_ ((const unsigned char *, int));
+extern EMACS_INT chars_in_text P_ ((const unsigned char *, EMACS_INT));
+extern EMACS_INT multibyte_chars_in_text P_ ((const unsigned char *, EMACS_INT));
extern int multibyte_char_to_unibyte P_ ((int, Lisp_Object));
extern int multibyte_char_to_unibyte_safe P_ ((int));
extern Lisp_Object Qcharset;
extern Lisp_Object assq_no_quit P_ ((Lisp_Object, Lisp_Object));
extern Lisp_Object assoc_no_quit P_ ((Lisp_Object, Lisp_Object));
extern void clear_string_char_byte_cache P_ ((void));
-extern int string_char_to_byte P_ ((Lisp_Object, int));
-extern int string_byte_to_char P_ ((Lisp_Object, int));
+extern EMACS_INT string_char_to_byte P_ ((Lisp_Object, EMACS_INT));
+extern EMACS_INT string_byte_to_char P_ ((Lisp_Object, EMACS_INT));
extern Lisp_Object string_make_multibyte P_ ((Lisp_Object));
extern Lisp_Object string_to_multibyte P_ ((Lisp_Object));
extern Lisp_Object string_make_unibyte P_ ((Lisp_Object));
extern void insert_and_inherit P_ ((const unsigned char *, int));
extern void insert_1 P_ ((const unsigned char *, int, int, int, int));
extern void insert_1_both P_ ((const unsigned char *, int, int, int, int, int));
-extern void insert_from_gap P_ ((int, int));
+extern void insert_from_gap P_ ((EMACS_INT, EMACS_INT));
extern void insert_from_string P_ ((Lisp_Object, int, int, int, int, int));
extern void insert_from_buffer P_ ((struct buffer *, int, int, int));
extern void insert_char P_ ((int));
EXFUN (Fmake_bool_vector, 2);
extern Lisp_Object Qchar_table_extra_slots;
extern struct Lisp_Vector *allocate_vector P_ ((EMACS_INT));
-extern struct Lisp_Vector *allocate_other_vector P_ ((EMACS_INT));
+extern struct Lisp_Vector *allocate_pseudovector P_ ((int memlen, int lisplen, EMACS_INT tag));
+#define ALLOCATE_PSEUDOVECTOR(typ,field,tag) \
+ ((typ*) \
+ allocate_pseudovector \
+ (VECSIZE (typ), PSEUDOVECSIZE (typ, field), tag))
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 struct terminal *allocate_terminal P_ ((void));
extern int gc_in_progress;
extern int abort_on_gc;
extern Lisp_Object make_float P_ ((double));
Lisp_Object, Lisp_Object, Lisp_Object));
extern int overlay_touches_p P_ ((int));
extern Lisp_Object Vbuffer_alist, Vinhibit_read_only;
+EXFUN (Fbuffer_list, 1);
EXFUN (Fget_buffer, 1);
EXFUN (Fget_buffer_create, 1);
EXFUN (Fgenerate_new_buffer_name, 2);
extern void discard_mouse_events P_ ((void));
EXFUN (Fevent_convert_list, 1);
EXFUN (Fread_key_sequence, 5);
+EXFUN (Fset_input_interrupt_mode, 1);
+EXFUN (Fset_output_flow_control, 2);
+EXFUN (Fset_input_meta_mode, 2);
+EXFUN (Fset_quit_char, 1);
EXFUN (Fset_input_mode, 4);
extern int detect_input_pending P_ ((void));
extern int detect_input_pending_ignore_squeezables 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));
+extern void add_user_signal P_ ((int sig, const char *name));
/* defined in indent.c */
extern int child_setup P_ ((int, int, int, char **, int, Lisp_Object));
extern void init_callproc_1 P_ ((void));
extern void init_callproc P_ ((void));
-extern void set_process_environment P_ ((void));
+extern void set_initial_environment P_ ((void));
extern void syms_of_callproc P_ ((void));
/* defined in doc.c */
EXFUN (Fprevious_single_property_change, 4);
EXFUN (Fget_text_property, 3);
EXFUN (Fput_text_property, 5);
+EXFUN (Fget_text_property, 3);
EXFUN (Fprevious_char_property_change, 2);
EXFUN (Fnext_char_property_change, 2);
extern void report_interval_modification P_ ((Lisp_Object, Lisp_Object));
EXFUN (Fx_popup_dialog, 3);
extern void syms_of_xmenu P_ ((void));
+/* defined in termchar.h */
+struct tty_display_info;
+
+/* defined in termhooks.h */
+struct terminal;
+
/* defined in sysdep.c */
#ifndef HAVE_GET_CURRENT_DIR_NAME
extern char *get_current_dir_name P_ ((void));
#endif
extern void stuff_char P_ ((char c));
extern void init_sigio P_ ((int));
-extern void request_sigio P_ ((void));
-extern void unrequest_sigio P_ ((void));
-extern void reset_sys_modes P_ ((void));
extern void sys_subshell P_ ((void));
extern void sys_suspend P_ ((void));
extern void discard_tty_input P_ ((void));
-extern void init_sys_modes P_ ((void));
-extern void get_frame_size P_ ((int *, int *));
+extern void init_sys_modes P_ ((struct tty_display_info *));
+extern void reset_sys_modes P_ ((struct tty_display_info *));
+extern void init_all_sys_modes P_ ((void));
+extern void reset_all_sys_modes P_ ((void));
extern void wait_for_termination P_ ((int));
extern void flush_pending_output P_ ((int));
extern void child_setup_tty P_ ((int));
extern void setup_pty P_ ((int));
extern int set_window_size P_ ((int, int, int));
extern void create_process P_ ((Lisp_Object, char **, Lisp_Object));
-extern int tabs_safe_p P_ ((void));
-extern void init_baud_rate P_ ((void));
extern int emacs_open P_ ((const char *, int, int));
extern int emacs_close P_ ((int));
extern int emacs_read P_ ((int, char *, unsigned int));
/* Defined in term.c */
extern void syms_of_term P_ ((void));
-extern void fatal () NO_RETURN;
+extern void fatal P_ ((const char *msgid, ...)) NO_RETURN;
+
+/* Defined in terminal.c */
+EXFUN (Fdelete_terminal, 2);
+extern void syms_of_terminal P_ ((void));
#ifdef HAVE_WINDOW_SYSTEM
/* Defined in fontset.c */
extern void init_mac_osx_environment P_ ((void));
#endif /* MAC_OSX */
#endif /* MAC_OS */
+
+#ifdef HAVE_MENUS
+/* Defined in (x|mac|w32)fns.c... */
+extern int have_menus_p P_ ((void));
+#endif
\f
/* Nonzero means Emacs has already been initialized.
Used during startup to detect startup of dumped Emacs. */
#define IS_ANY_SEP(_c_) (IS_DIRECTORY_SEP (_c_))
#endif
-#ifdef SWITCH_ENUM_BUG
-#define SWITCH_ENUM_CAST(x) ((int)(x))
-#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.
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
+/* 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. */
+#if !defined(eabs)
+#define eabs(x) ((x) < 0 ? -(x) : (x))
+#endif
+
/* Return a fixnum or float, depending on whether VAL fits in a Lisp
fixnum. */