* lisp.h (XCONS, XSTRING, XSYMBOL, XFLOAT, XPROCESS, XWINDOW, XSUBR, XBUFFER):
[bpt/emacs.git] / src / lisp.h
index d40a129..13e734a 100644 (file)
@@ -1,5 +1,6 @@
 /* Fundamental definitions for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985,86,87,93,94,95,97,1998 Free Software Foundation, Inc.
+   Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000
+     Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -19,7 +20,7 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 /* Declare the prototype for a general external function.  */
-#if defined (__STDC__) || defined (WINDOWSNT)
+#if defined (PROTOTYPES) || defined (WINDOWSNT)
 #define P_(proto) proto
 #else
 #define P_(proto) ()
@@ -27,6 +28,15 @@ Boston, MA 02111-1307, USA.  */
 
 
 /* These are default choices for the types to use.  */
+#ifdef _LP64
+#ifndef EMACS_INT
+#define EMACS_INT long
+#define BITS_PER_EMACS_INT BITS_PER_LONG
+#endif
+#ifndef EMACS_UINT
+#define EMACS_UINT unsigned long
+#endif
+#else /* not _LP64 */
 #ifndef EMACS_INT
 #define EMACS_INT int
 #define BITS_PER_EMACS_INT BITS_PER_INT
@@ -34,6 +44,24 @@ Boston, MA 02111-1307, USA.  */
 #ifndef EMACS_UINT
 #define EMACS_UINT unsigned int
 #endif
+#endif
+
+/* Extra internal type checking?  */
+extern int suppress_checking;
+#ifdef ENABLE_CHECKING
+extern void die P_((const char *, const char *, int));
+#define CHECK(check,msg) ((check || suppress_checking ? 0 : die (msg, __FILE__, __LINE__)), 0)
+#else
+/* Produce same side effects and result, but don't complain.  */
+#define CHECK(check,msg) ((check),0)
+#endif
+/* Define an Emacs version of "assert", since some system ones are
+   flaky.  */
+#if defined (__GNUC__) && __GNUC__ >= 2 && defined (__STDC__)
+#define eassert(cond) CHECK(cond,"assertion failed: " #cond)
+#else
+#define eassert(cond) CHECK(cond,"assertion failed")
+#endif
 
 /* Define the fundamental Lisp data structures.  */
 
@@ -64,9 +92,7 @@ enum Lisp_Type
     /* Cons.  XCONS (object) points to a struct Lisp_Cons.  */
     Lisp_Cons,
 
-#ifdef LISP_FLOAT_TYPE
     Lisp_Float,
-#endif /* LISP_FLOAT_TYPE */
 
     /* This is not a type code.  It is for range checking.  */
     Lisp_Type_Limit
@@ -98,13 +124,17 @@ enum Lisp_Misc_Type
 
 /* These values are overridden by the m- file on some machines.  */
 #ifndef VALBITS
-#define VALBITS 28
+#define VALBITS (BITS_PER_EMACS_INT - 4)
 #endif
 
 #ifndef GCTYPEBITS
 #define GCTYPEBITS 3
 #endif
 
+#if 0  /* This doesn't work on some systems that don't allow enumerators
+         > INT_MAX, and it won't work for long long EMACS_INT.  These
+         values are now found in emacs.c as EMACS_INT variables.  */
+
 /* Make these values available in GDB, which sees enums but not macros.  */
 
 enum gdb_lisp_params
@@ -119,6 +149,8 @@ enum gdb_lisp_params
 #endif
 };
 
+#endif /* 0 */
+
 #ifndef NO_UNION_TYPE
 
 #ifndef WORDS_BIG_ENDIAN
@@ -212,7 +244,7 @@ Lisp_Object;
    rather than being part of a string block.  */
 
 #ifndef MARKBIT
-#define MARKBIT ((int) ((unsigned int) 1 << (VALBITS + GCTYPEBITS)))
+#define MARKBIT ((EMACS_INT) ((EMACS_UINT) 1 << (VALBITS + GCTYPEBITS)))
 #endif /*MARKBIT */
 
 /* In the size word of a vector, this bit means the vector has been marked.
@@ -244,8 +276,13 @@ enum pvec_type
   PVEC_BOOL_VECTOR = 0x10000,
   PVEC_BUFFER = 0x20000,
   PVEC_HASH_TABLE = 0x40000,
-  PVEC_TYPE_MASK = 0x7fe00,
+  PVEC_TYPE_MASK = 0x7fe00
+  
+#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
+        emacs.c.  */
   PVEC_FLAG = PSEUDOVECTOR_FLAG
+#endif
 };
 
 /* For convenience, we also store the number of elements in these bits.  */
@@ -278,7 +315,7 @@ enum pvec_type
 /* Extract the value of a Lisp_Object as a signed integer.  */
 
 #ifndef XINT   /* Some machines need to do this differently.  */
-#define XINT(a) (((a) << (BITS_PER_INT-VALBITS)) >> (BITS_PER_INT-VALBITS))
+#define XINT(a) (((a) << (BITS_PER_EMACS_INT-VALBITS)) >> (BITS_PER_EMACS_INT-VALBITS))
 #endif
 
 /* Extract the value as an unsigned integer.  This is a basis
@@ -395,11 +432,11 @@ extern Lisp_Object make_number ();
 
 /* Extract a value or address from a Lisp_Object.  */
 
-#define XCONS(a) ((struct Lisp_Cons *) XPNTR(a))
+#define XCONS(a) (eassert (GC_CONSP(a)),(struct Lisp_Cons *) XPNTR(a))
 #define XVECTOR(a) ((struct Lisp_Vector *) XPNTR(a))
-#define XSTRING(a) ((struct Lisp_String *) XPNTR(a))
-#define XSYMBOL(a) ((struct Lisp_Symbol *) XPNTR(a))
-#define XFLOAT(a) ((struct Lisp_Float *) XPNTR(a))
+#define XSTRING(a) (eassert (GC_STRINGP(a)),(struct Lisp_String *) XPNTR(a))
+#define XSYMBOL(a) (eassert (GC_SYMBOLP(a)),(struct Lisp_Symbol *) XPNTR(a))
+#define XFLOAT(a) (eassert (GC_FLOATP(a)),(struct Lisp_Float *) XPNTR(a))
 
 /* Misc types.  */
 #define XMISC(a)   ((union Lisp_Misc *) XPNTR(a))
@@ -414,10 +451,10 @@ extern Lisp_Object make_number ();
 #define XKBOARD_OBJFWD(a) (&(XMISC(a)->u_kboard_objfwd))
 
 /* Pseudovector types.  */
-#define XPROCESS(a) ((struct Lisp_Process *) XPNTR(a))
-#define XWINDOW(a) ((struct window *) XPNTR(a))
-#define XSUBR(a) ((struct Lisp_Subr *) XPNTR(a))
-#define XBUFFER(a) ((struct buffer *) XPNTR(a))
+#define XPROCESS(a) (eassert (GC_PROCESSP(a)),(struct Lisp_Process *) XPNTR(a))
+#define XWINDOW(a) (eassert (GC_WINDOWP(a)),(struct window *) XPNTR(a))
+#define XSUBR(a) (eassert (GC_SUBRP(a)),(struct Lisp_Subr *) XPNTR(a))
+#define XBUFFER(a) (eassert (GC_BUFFERP(a)),(struct buffer *) XPNTR(a))
 #define XCHAR_TABLE(a) ((struct Lisp_Char_Table *) XPNTR(a))
 #define XBOOL_VECTOR(a) ((struct Lisp_Bool_Vector *) XPNTR(a))
 
@@ -448,7 +485,6 @@ extern Lisp_Object make_number ();
 #define XSETCHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CHAR_TABLE))
 #define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
 \f
-#ifdef USE_TEXT_PROPERTIES
 /* Basic data type for use of intervals.  See the macros in intervals.h.  */
 
 struct interval
@@ -475,17 +511,22 @@ struct interval
      You'd think we could store this information in the parent object
      somewhere (after all, that should be visited once and then
      ignored too, right?), but strings are GC'd strangely.  */
-  struct interval *parent;
+  union
+  {
+    struct interval *interval;
+    Lisp_Object obj;
+  } up;
+  unsigned int up_obj : 1;
 
   /* The remaining components are `properties' of the interval.
      The first four are duplicates for things which can be on the list,
      for purposes of speed.  */
 
-  unsigned char write_protect;     /* Non-zero means can't modify.  */
-  unsigned char visible;           /* Zero means don't display.  */
-  unsigned char front_sticky;      /* Non-zero means text inserted just
+  unsigned int write_protect : 1;    /* Non-zero means can't modify.  */
+  unsigned int visible : 1;        /* Zero means don't display.  */
+  unsigned int front_sticky : 1;    /* Non-zero means text inserted just
                                       before this interval goes into it.  */
-  unsigned char rear_sticky;       /* Likewise for just after it.  */
+  unsigned int rear_sticky : 1;            /* Likewise for just after it.  */
 
   /* Properties of this interval.
      The mark bit on this field says whether this particular interval
@@ -509,17 +550,6 @@ typedef struct interval *INTERVAL;
    certain code.  See, e.g., alloc.c.  */
 #define INITIALIZE_INTERVAL(ptr,val) ptr->intervals = val
 
-#else  /* No text properties */
-
-/* If no intervals are used, make the above definitions go away.  */
-
-#define CHECK_STRING_OR_BUFFER(x, i)
-
-#define INTERVAL
-#define DECLARE_INTERVALS
-#define INITIALIZE_INTERVAL(ptr,val)
-
-#endif /* USE_TEXT_PROPERTIES */
 \f
 /* In a cons, the markbit of the car is the gc mark bit */
 
@@ -582,7 +612,7 @@ struct Lisp_String
     EMACS_INT size;
     EMACS_INT size_byte;
     DECLARE_INTERVALS          /* `data' field must be last.  */
-    unsigned char data[1];
+    unsigned char *data;
   };
 
 /* If a struct is made to look like a vector, this macro returns the length
@@ -928,56 +958,63 @@ struct Lisp_Buffer_Objfwd
     int offset;
   };
 
-/* Used in a symbol value cell when the symbol's value is per-buffer.
-   The actual contents resemble a cons cell which starts a list like this:
-   (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE).
-
-   The cons-like structure is for historical reasons; it might be better
-   to just put these elements into the struct, now.
-
-   BUFFER is the last buffer for which this symbol's value was
-   made up to date.
-
-   CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's
-   local_var_alist, that being the element whose car is this
-   variable.  Or it can be a pointer to the
-   (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE),
-   if BUFFER does not have an element in its alist for this
-   variable (that is, if BUFFER sees the default value of this
-   variable).
-
-   If we want to examine or set the value and BUFFER is current,
-   we just examine or set REALVALUE.  If BUFFER is not current, we
-   store the current REALVALUE value into CURRENT-ALIST-ELEMENT,
-   then find the appropriate alist element for the buffer now
-   current and set up CURRENT-ALIST-ELEMENT.  Then we set
-   REALVALUE out of that element, and store into BUFFER.
-
-   If we are setting the variable and the current buffer does not
-   have an alist entry for this variable, an alist entry is
-   created.
-
-   Note that REALVALUE can be a forwarding pointer.  Each time it
-   is examined or set, forwarding must be done.  Each time we
-   switch buffers, buffer-local variables which forward into C
-   variables are swapped immediately, so the C code can assume
-   that they are always up to date.
+/* struct Lisp_Buffer_Local_Value is used in a symbol value cell when
+   the symbol has buffer-local or frame-local bindings.  (Exception:
+   some buffer-local variables are built-in, with their values stored
+   in the buffer structure itself.  They are handled differently,
+   using struct Lisp_Buffer_Objfwd.)
+
+   The `realvalue' slot holds the variable's current value, or a
+   forwarding pointer to where that value is kept.  This value is the
+   one that corresponds to the loaded binding.  To read or set the
+   variable, you must first make sure the right binding is loaded;
+   then you can access the value in (or through) `realvalue'.
+   
+   `buffer' and `frame' are the buffer and frame for which the loaded
+   binding was found.  If those have changed, to make sure the right
+   binding is loaded it is necessary to find which binding goes with
+   the current buffer and selected frame, then load it.  To load it,
+   first unload the previous binding, then copy the value of the new
+   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
-   use the same substructure.  The difference is that with the latter,
-   merely setting the variable while some buffer is current
-   does not cause that buffer to have its own local value of this variable.
-   Only make-local-variable does that.  */
+   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.  */
+
 struct Lisp_Buffer_Local_Value
   {
     int type : 16;      /* = Lisp_Misc_Buffer_Local_Value
                           or Lisp_Misc_Some_Buffer_Local_Value */
     int spacer : 13;
+
+    /* 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;
+    /* 1 means that the binding now loaded was found
+       as a local binding for the buffer in the `buffer' slot.  */
     unsigned int found_for_buffer : 1;
+    /* 1 means that the binding now loaded was found
+       as a local binding for the frame in the `frame' slot.  */
     unsigned int found_for_frame : 1;
     Lisp_Object realvalue;
+    /* The buffer and frame for which the loaded binding was found.  */
     Lisp_Object buffer, frame;
+
+    /* A cons cell, (LOADED-BINDING . DEFAULT-VALUE).
+
+       LOADED-BINDING is the binding now loaded.  It is a cons cell
+       whose cdr is the binding's value.  The cons cell may be an
+       element of a buffer's local-variable alist, or an element of a
+       frame's parameter alist, or it may be this cons cell.
+
+       DEFAULT-VALUE is the variable's default value, seen when the
+       current buffer and selected frame do not have their own
+       bindings for the variable.  When the default binding is loaded,
+       LOADED-BINDING is actually this very cons cell; thus, its car
+       points to itself.  */
     Lisp_Object cdr;
   };
 
@@ -1017,8 +1054,7 @@ union Lisp_Misc
     struct Lisp_Kboard_Objfwd u_kboard_objfwd;
   };
 \f
-#ifdef LISP_FLOAT_TYPE
-/* Optional Lisp floating point type */
+/* Lisp floating point type */
 struct Lisp_Float
   {
     Lisp_Object type;          /* essentially used for mark-bit
@@ -1035,7 +1071,6 @@ struct Lisp_Float
 #else
 #define XFLOAT_DATA(f) (XFLOAT (f)->data)
 #endif
-#endif /* LISP_FLOAT_TYPE */
 
 /* A character, declared with the following typedef, is a member
    of some character set associated with the current buffer.  */
@@ -1072,6 +1107,16 @@ typedef unsigned char UCHAR;
    itself.  */
 #define CHARACTERBITS 19
 
+/* The maximum byte size consumed by push_key_description.
+   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.
+   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
@@ -1103,36 +1148,33 @@ typedef unsigned char UCHAR;
 \f
 /* The glyph datatype, used to represent characters on the display.  */
 
-/* The low 19 bits (CHARACTERBITS) are the character code, and the
-   bits above them except for the topmost two bits 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 (i.e. 2^(32 - 19 - 2) = 2048 ID's) ; given that we
+/* 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.  */
-#define GLYPH unsigned int
-
-/* Mask bit for a glyph of a character which should be written from
-   right to left.  */
-#define GLYPH_MASK_REV_DIR 0x80000000
-/* Mask bit for a padding glyph of a multi-column character.  */
-#define GLYPH_MASK_PADDING 0x40000000
+   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    0x3FF80000
-/* Mask bits for character code.  */
-#define GLYPH_MASK_CHAR    0x0007FFFF /* The lowest 19 bits */
+#define GLYPH_MASK_FACE    0x7FFFFF00
+ /* Mask bits for character code.  */
+#define GLYPH_MASK_CHAR    0x000000FF /* The lowest 8 bits */
 
 /* The FAST macros assume that we already know we're in an X window.  */
 
-/* Given a character code and a face ID, return the appropriate glyph.  */
-#define FAST_MAKE_GLYPH(char, face) ((char) | ((face) << CHARACTERBITS))
+/* Set a character code and a face ID in a glyph G.  */
+#define FAST_MAKE_GLYPH(char, face) ((char) | ((face) << 8))
 
 /* Return a glyph's character code.  */
 #define FAST_GLYPH_CHAR(glyph) ((glyph) & GLYPH_MASK_CHAR)
 
 /* Return a glyph's face ID.  */
-#define FAST_GLYPH_FACE(glyph) (((glyph) & GLYPH_MASK_FACE) >> CHARACTERBITS)
+#define FAST_GLYPH_FACE(glyph) (((glyph) & GLYPH_MASK_FACE) >> 8)
 
 /* Slower versions that test the frame type first.  */
 #define MAKE_GLYPH(f, char, face) (FAST_MAKE_GLYPH (char, face))
@@ -1151,13 +1193,8 @@ typedef unsigned char UCHAR;
 #define NILP(x)  (XFASTINT (x) == XFASTINT (Qnil))
 #define GC_NILP(x) GC_EQ (x, Qnil)
 
-#ifdef LISP_FLOAT_TYPE
 #define NUMBERP(x) (INTEGERP (x) || FLOATP (x))
 #define GC_NUMBERP(x) (GC_INTEGERP (x) || GC_FLOATP (x))
-#else
-#define NUMBERP(x) (INTEGERP (x))
-#define GC_NUMBERP(x) (GC_INTEGERP (x))
-#endif
 #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0)
 #define GC_NATNUMP(x) (GC_INTEGERP (x) && XINT (x) >= 0)
 
@@ -1174,13 +1211,8 @@ typedef unsigned char UCHAR;
 #define CONSP(x) (XTYPE ((x)) == Lisp_Cons)
 #define GC_CONSP(x) (XGCTYPE ((x)) == Lisp_Cons)
 
-#ifdef LISP_FLOAT_TYPE
 #define FLOATP(x) (XTYPE ((x)) == Lisp_Float)
 #define GC_FLOATP(x) (XGCTYPE ((x)) == Lisp_Float)
-#else
-#define FLOATP(x) (0)
-#define GC_FLOATP(x) (0)
-#endif
 #define VECTORP(x) (VECTORLIKEP (x) && !(XVECTOR (x)->size & PSEUDOVECTOR_FLAG))
 #define GC_VECTORP(x) (GC_VECTORLIKEP (x) && !(XVECTOR (x)->size & PSEUDOVECTOR_FLAG))
 #define OVERLAYP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay)
@@ -1301,8 +1333,6 @@ typedef unsigned char UCHAR;
   do { if (MARKERP ((x))) XSETFASTINT (x, marker_position (x)); \
     else if (!INTEGERP ((x))) x = wrong_type_argument (Qinteger_or_marker_p, (x)); } while (0)
 
-#ifdef LISP_FLOAT_TYPE
-
 #define XFLOATINT(n) extract_float((n))
 
 #define CHECK_FLOAT(x, i)              \
@@ -1318,21 +1348,12 @@ typedef unsigned char UCHAR;
   else if (!INTEGERP (x) && !FLOATP (x))               \
     x = wrong_type_argument (Qnumber_or_marker_p, (x)); } while (0)
 
-#else  /* Not LISP_FLOAT_TYPE */
-
-#define CHECK_NUMBER_OR_FLOAT CHECK_NUMBER
-
-#define CHECK_NUMBER_OR_FLOAT_COERCE_MARKER CHECK_NUMBER_COERCE_MARKER
-
-#define XFLOATINT(n) XINT((n))
-#endif /* LISP_FLOAT_TYPE */
-
 #define CHECK_OVERLAY(x, i) \
   do { if (!OVERLAYP ((x))) x = wrong_type_argument (Qoverlayp, (x));} while (0)
 
 /* Cast pointers to this type to compare them.  Some machines want int.  */
 #ifndef PNTR_COMPARISON_TYPE
-#define PNTR_COMPARISON_TYPE unsigned int
+#define PNTR_COMPARISON_TYPE EMACS_UINT
 #endif
 \f
 /* Define a built-in function for calling from Lisp.
@@ -1435,8 +1456,15 @@ extern void defvar_kboard P_ ((char *, int));
    If func is zero and symbol is nil, undoing this binding evaluates
       the list of forms in old_value; this implements Lisp's unwind-protect
       form.
-   Otherwise, undoing this binding stores old_value as symbol's value; this
-      undoes the bindings made by a let form or function call.  */
+
+   Otherwise, the element is a variable binding.
+   If the symbol field is a symbol, it is an ordinary variable binding.
+   Otherwise, it should be a structure (SYMBOL BUFFER . BUFFER),
+   which represents having bound BUFFER's local value,
+   or (SYMBOL nil . BUFFER), which represents having bound the default
+   value when BUFFER was current (buffer not having any local binding
+   for SYMBOL).  */
+
 struct specbinding
   {
     Lisp_Object symbol, old_value;
@@ -1476,11 +1504,27 @@ extern Lisp_Object memory_signal_data;
    Tells GC how to save a copy of the stack.  */
 extern char *stack_bottom;
 
-/* Check quit-flag and quit if it is non-nil.  */
+/* Check quit-flag and quit if it is non-nil.
+   Typing C-g does not directly cause a quit; it only sets Vquit_flag.
+   So the program needs to do QUIT at times when it is safe to quit.
+   Every loop that might run for a long time or might not exit
+   ought to do QUIT at least once, at a safe place.
+   Unless that is impossible, of course.
+   But it is very desirable to avoid creating loops where QUIT is impossible.
 
-#define QUIT \
-  if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
-    { Vquit_flag = Qnil; Fsignal (Qquit, Qnil); }
+   Exception: if you set immediate_quit to nonzero,
+   then the handler that responds to the C-g does the quit itself.
+   This is a good thing to do around a loop that has no side effects
+   and (in particular) cannot call arbitrary Lisp code.  */
+
+#define QUIT                                           \
+  do {                                                 \
+    if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))    \
+      {                                                        \
+       Vquit_flag = Qnil;                              \
+       Fsignal (Qquit, Qnil);                          \
+      }                                                        \
+  } while (0)
 
 /* Nonzero if ought to quit now.  */
 
@@ -1560,8 +1604,43 @@ struct gcpro
     struct gcpro *next;
     Lisp_Object *var;          /* Address of first protected variable */
     int nvars;                 /* Number of consecutive protected variables */
+#ifdef DEBUG_GCPRO
+    int level;
+#endif
   };
 
+/* Values of GC_MARK_STACK during compilation:
+
+   0   Use GCPRO as before
+   1   Do the real thing, make GCPROs and UNGCPRO no-ops.
+   2    Mark the stack, and check that everything GCPRO'd is
+       marked.
+   3   Mark using GCPRO's, mark stack last, and count how many
+       dead objects are kept alive.  */
+
+
+#define GC_USE_GCPROS_AS_BEFORE                0
+#define GC_MAKE_GCPROS_NOOPS           1
+#define GC_MARK_STACK_CHECK_GCPROS     2
+#define GC_USE_GCPROS_CHECK_ZOMBIES    3
+
+#ifndef GC_MARK_STACK
+#define GC_MARK_STACK GC_USE_GCPROS_AS_BEFORE
+#endif
+
+#if GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS
+
+#define GCPRO1(varname) ((void) 0)
+#define GCPRO2(varname1, varname2)((void) 0) 
+#define GCPRO3(varname1, varname2, varname3) ((void) 0) 
+#define GCPRO4(varname1, varname2, varname3, varname4) ((void) 0)
+#define GCPRO5(varname1, varname2, varname3, varname4, varname5) ((void) 0)
+#define UNGCPRO ((void) 0)
+
+#else /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
+
+#ifndef DEBUG_GCPRO
+
 #define GCPRO1(varname) \
  {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \
   gcprolist = &gcpro1; }
@@ -1592,11 +1671,59 @@ struct gcpro
   gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \
   gcprolist = &gcpro5; }
 
-/* Call staticpro (&var) to protect static variable `var'.  */
+#define UNGCPRO (gcprolist = gcpro1.next)
 
-void staticpro P_ ((Lisp_Object *));
+#else
+
+extern int gcpro_level;
+
+#define GCPRO1(varname) \
+ {gcpro1.next = gcprolist; gcpro1.var = &varname; gcpro1.nvars = 1; \
+  gcpro1.level = gcpro_level++; \
+  gcprolist = &gcpro1; }
+
+#define GCPRO2(varname1, varname2) \
+ {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
+  gcpro1.level = gcpro_level; \
+  gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
+  gcpro2.level = gcpro_level++; \
+  gcprolist = &gcpro2; }
+
+#define GCPRO3(varname1, varname2, varname3) \
+ {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
+  gcpro1.level = gcpro_level; \
+  gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
+  gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
+  gcpro3.level = gcpro_level++; \
+  gcprolist = &gcpro3; }
+
+#define GCPRO4(varname1, varname2, varname3, varname4) \
+ {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
+  gcpro1.level = gcpro_level; \
+  gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
+  gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
+  gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \
+  gcpro4.level = gcpro_level++; \
+  gcprolist = &gcpro4; }
+
+#define GCPRO5(varname1, varname2, varname3, varname4, varname5) \
+ {gcpro1.next = gcprolist; gcpro1.var = &varname1; gcpro1.nvars = 1; \
+  gcpro1.level = gcpro_level; \
+  gcpro2.next = &gcpro1; gcpro2.var = &varname2; gcpro2.nvars = 1; \
+  gcpro3.next = &gcpro2; gcpro3.var = &varname3; gcpro3.nvars = 1; \
+  gcpro4.next = &gcpro3; gcpro4.var = &varname4; gcpro4.nvars = 1; \
+  gcpro5.next = &gcpro4; gcpro5.var = &varname5; gcpro5.nvars = 1; \
+  gcpro5.level = gcpro_level++; \
+  gcprolist = &gcpro5; }
+
+#define UNGCPRO                                        \
+ ((--gcpro_level != gcpro1.level)              \
+  ? (abort (), 0)                              \
+  : ((gcprolist = gcpro1.next), 0))
+
+#endif /* DEBUG_GCPRO */
+#endif /* GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS */
 
-#define UNGCPRO (gcprolist = gcpro1.next)
 
 /* Evaluate expr, UNGCPRO, and then return the value of expr.  */
 #define RETURN_UNGCPRO(expr)                   \
@@ -1608,6 +1735,10 @@ do                                               \
       return ret_ungc_val;                     \
     }                                          \
 while (0)
+
+/* Call staticpro (&var) to protect static variable `var'.  */
+
+void staticpro P_ ((Lisp_Object *));
 \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.  */
@@ -1634,7 +1765,7 @@ extern Lisp_Object Qsetting_constant, Qinvalid_read_syntax;
 extern Lisp_Object Qinvalid_function, Qwrong_number_of_arguments, Qno_catch;
 extern Lisp_Object Qend_of_file, Qarith_error;
 extern Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
-extern Lisp_Object Qmark_inactive;
+extern Lisp_Object Qmark_inactive, Qtext_read_only;
 
 extern Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
 extern Lisp_Object Qoverflow_error, Qunderflow_error;
@@ -1649,9 +1780,7 @@ extern Lisp_Object Qboundp, Qfboundp;
 extern Lisp_Object Qbuffer_or_string_p;
 extern Lisp_Object Qcdr;
 
-#ifdef LISP_FLOAT_TYPE
 extern Lisp_Object Qfloatp, Qinteger_or_floatp, Qinteger_or_float_or_marker_p;
-#endif /* LISP_FLOAT_TYPE */
 
 extern Lisp_Object Qframep;
 
@@ -1674,11 +1803,9 @@ EXFUN (Fmarkerp, 1);
 EXFUN (Fsubrp, 1);
 EXFUN (Fchar_or_string_p, 1);
 EXFUN (Finteger_or_marker_p, 1);
-#ifdef LISP_FLOAT_TYPE
 EXFUN (Ffloatp, 1);
 EXFUN (Finteger_or_floatp, 1);
 EXFUN (Finteger_or_float_or_marker_p, 1);
-#endif /* LISP_FLOAT_TYPE */
 
 EXFUN (Fcar, 1);
 EXFUN (Fcar_safe, 1);
@@ -1743,7 +1870,7 @@ extern void args_out_of_range_3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object wrong_type_argument P_ ((Lisp_Object, Lisp_Object));
 extern void store_symval_forwarding P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object do_symval_forwarding P_ ((Lisp_Object));
-extern Lisp_Object set_internal P_ ((Lisp_Object, Lisp_Object, int));
+extern Lisp_Object set_internal P_ ((Lisp_Object, Lisp_Object, struct buffer *, int));
 extern void syms_of_data P_ ((void));
 extern void init_data P_ ((void));
 
@@ -1765,6 +1892,7 @@ EXFUN (Ffind_operation_coding_system, MANY);
 EXFUN (Fencode_coding_string, 3);
 EXFUN (Fdecode_coding_string, 3);
 extern Lisp_Object detect_coding_system P_ ((unsigned char *, int, int));
+Lisp_Object code_convert_string_norecord P_ ((Lisp_Object, Lisp_Object, int));
 extern void init_coding P_ ((void));
 extern void init_coding_once P_ ((void));
 extern void syms_of_coding P_ ((void));
@@ -1776,6 +1904,7 @@ extern int nonascii_insert_offset;
 extern Lisp_Object Vnonascii_translation_table;
 EXFUN (Fchar_bytes, 1);
 EXFUN (Fchar_width, 1);
+EXFUN (Fstring, MANY);
 extern int chars_in_text P_ ((unsigned char *, int));
 extern int multibyte_chars_in_text P_ ((unsigned char *, int));
 extern int unibyte_char_to_multibyte P_ ((int));
@@ -1798,14 +1927,15 @@ extern void syms_of_syntax P_ ((void));
 extern void sweep_weak_hash_tables P_ ((void));
 extern Lisp_Object Qstring_lessp;
 extern Lisp_Object Vfeatures;
+extern Lisp_Object QCtest, QCweakness, Qequal;
 unsigned sxhash P_ ((Lisp_Object, int));
 Lisp_Object make_hash_table P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
                                 Lisp_Object, Lisp_Object, Lisp_Object,
                                 Lisp_Object));
 Lisp_Object copy_hash_table P_ ((struct Lisp_Hash_Table *));
 int hash_lookup P_ ((struct Lisp_Hash_Table *, Lisp_Object, unsigned *));
-void hash_put P_ ((struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
-                  unsigned));
+int hash_put P_ ((struct Lisp_Hash_Table *, Lisp_Object, Lisp_Object,
+                 unsigned));
 void hash_remove P_ ((struct Lisp_Hash_Table *, Lisp_Object));
 void hash_clear P_ ((struct Lisp_Hash_Table *));
 void remove_hash_entry P_ ((struct Lisp_Hash_Table *, int));
@@ -1869,7 +1999,7 @@ extern Lisp_Object concat2 P_ ((Lisp_Object, Lisp_Object));
 extern Lisp_Object concat3 P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object nconc2 P_ ((Lisp_Object, Lisp_Object));
 extern Lisp_Object assq_no_quit P_ ((Lisp_Object, Lisp_Object));
-extern void clear_string_char_byte_cache P_ (());
+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 Lisp_Object string_make_multibyte P_ ((Lisp_Object));
@@ -1891,10 +2021,8 @@ extern void map_char_table P_ ((void (*) (Lisp_Object, Lisp_Object, Lisp_Object)
 extern void syms_of_fns P_ ((void));
 
 /* Defined in floatfns.c */
-#ifdef LISP_FLOAT_TYPE
 extern double extract_float P_ ((Lisp_Object));
 EXFUN (Ffloat, 1);
-#endif /* LISP_FLOAT_TYPE */
 EXFUN (Ftruncate, 2);
 extern void init_floatfns P_ ((void));
 extern void syms_of_floatfns P_ ((void));
@@ -1919,10 +2047,10 @@ extern void insert_before_markers P_ ((unsigned char *, int));
 extern void insert_before_markers_and_inherit P_ ((unsigned char *, int));
 extern void insert_from_string_before_markers P_ ((Lisp_Object, int, int, int, int, int));
 extern void del_range P_ ((int, int));
-extern void del_range_1 P_ ((int, int, int));
+extern Lisp_Object del_range_1 P_ ((int, int, int, int));
 extern void del_range_byte P_ ((int, int, int));
 extern void del_range_both P_ ((int, int, int, int, int));
-extern void del_range_2 P_ ((int, int, int, int));
+extern Lisp_Object del_range_2 P_ ((int, int, int, int, int));
 extern void modify_region P_ ((struct buffer *, int, int));
 extern void prepare_to_modify_buffer P_ ((int, int, int *));
 extern void signal_before_change P_ ((int, int, int *));
@@ -1971,6 +2099,8 @@ extern void message_log_maybe_newline P_ ((void));
 extern void update_echo_area P_ ((void));
 extern void truncate_echo_area P_ ((int));
 extern void redisplay P_ ((void));
+extern int check_point_in_composition
+       P_ ((struct buffer *, int, struct buffer *, int));
 extern void redisplay_preserve_echo_area P_ ((void));
 extern void mark_window_display_accurate P_ ((Lisp_Object, int));
 extern int invisible_p P_ ((Lisp_Object, Lisp_Object));
@@ -1979,13 +2109,10 @@ extern void syms_of_xdisp P_ ((void));
 extern void init_xdisp P_ ((void));
 
 /* Defined in vm-limit.c.  */
-#ifdef __STDC__
-extern void memory_warnings P_ ((void *, void (*warnfun) ()));
-#else
-extern void memory_warnings P_ ((char *, void (*warnfun) ()));
-#endif
-                               
+extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
+
 /* Defined in alloc.c */
+extern void allocate_string_data P_ ((struct Lisp_String *, int, int));
 extern void uninterrupt_malloc P_ ((void));
 extern void malloc_warning P_ ((char *));
 extern void memory_full P_ ((void));
@@ -2027,9 +2154,7 @@ extern Lisp_Object make_sub_char_table P_ ((Lisp_Object));
 extern Lisp_Object Qchar_table_extra_slots;
 extern struct Lisp_Vector *allocate_vectorlike P_ ((EMACS_INT));
 extern int gc_in_progress;
-#ifdef LISP_FLOAT_TYPE
 extern Lisp_Object make_float P_ ((double));
-#endif /* LISP_FLOAT_TYPE */
 extern void display_malloc_warning P_ ((void));
 extern int inhibit_garbage_collection P_ ((void));
 extern void free_marker P_ ((Lisp_Object));
@@ -2037,6 +2162,7 @@ extern void free_cons P_ ((struct Lisp_Cons *));
 extern void init_alloc_once P_ ((void));
 extern void init_alloc P_ ((void));
 extern void syms_of_alloc P_ ((void));
+extern struct buffer * allocate_buffer P_ ((void));
 
 /* Defined in print.c */
 extern Lisp_Object Vprin1_to_string_buffer;
@@ -2211,6 +2337,12 @@ extern Lisp_Object make_buffer_string_both P_ ((int, int, int, int, int));
 extern void init_editfns P_ ((void));
 extern void syms_of_editfns P_ ((void));
 EXFUN (Fcurrent_message, 0);
+extern Lisp_Object Vinhibit_field_text_motion;
+EXFUN (Fconstrain_to_field, 4);
+EXFUN (Ffield_string, 1);
+EXFUN (Fdelete_field, 1);
+EXFUN (Ffield_beginning, 2);
+EXFUN (Ffield_string_no_properties, 1);
 
 /* defined in buffer.c */
 extern void nsberror P_ ((Lisp_Object));
@@ -2379,7 +2511,7 @@ EXFUN (Finput_pending_p, 0);
 extern Lisp_Object menu_bar_items P_ ((Lisp_Object));
 extern Lisp_Object tool_bar_items P_ ((Lisp_Object, int *));
 extern Lisp_Object Qvertical_scroll_bar;
-extern void discard_mouse_events ();
+extern void discard_mouse_events P_ ((void));
 EXFUN (Fevent_convert_list, 1);
 EXFUN (Fread_key_sequence, 5);
 EXFUN (Fset_input_mode, 4);
@@ -2506,6 +2638,16 @@ extern Lisp_Object decode_env_path P_ ((char *, char *));
 extern Lisp_Object Vinvocation_name, Vinvocation_directory;
 extern Lisp_Object Vinstallation_directory;
 EXFUN (Fkill_emacs, 1);
+#if HAVE_SETLOCALE
+void fixup_locale P_ ((void));
+void synchronize_system_messages_locale P_ ((void));
+void synchronize_system_time_locale P_ ((void));
+#else
+#define setlocale(category, locale)
+#define fixup_locale()
+#define synchronize_system_messages_locale()
+#define synchronize_system_time_locale()
+#endif
 void shut_down_emacs P_ ((int, int, Lisp_Object));
 /* Nonzero means don't do interactive redisplay and don't change tty modes */
 extern int noninteractive;
@@ -2558,6 +2700,9 @@ extern int read_bytecode_char P_ ((int));
 extern Lisp_Object Qbytecode;
 EXFUN (Fbyte_code, 3);
 extern void syms_of_bytecode P_ ((void));
+extern struct byte_stack *byte_stack_list;
+extern void mark_byte_stack P_ ((void));
+extern void unmark_byte_stack P_ ((void));
 
 /* defined in macros.c */
 extern Lisp_Object Qexecute_kbd_macro;
@@ -2598,6 +2743,9 @@ extern Lisp_Object next_single_char_property_change P_ ((Lisp_Object,
                                                         Lisp_Object,
                                                         Lisp_Object,
                                                         Lisp_Object));
+extern Lisp_Object set_text_properties P_ ((Lisp_Object, Lisp_Object,
+                                           Lisp_Object, Lisp_Object,
+                                           Lisp_Object));
 
 /* defined in intervals.c */
 extern Lisp_Object get_local_map P_ ((int, struct buffer *));
@@ -2606,6 +2754,7 @@ extern Lisp_Object get_local_map P_ ((int, struct buffer *));
 EXFUN (Fx_popup_menu, 2);
 EXFUN (Fx_popup_dialog, 2);
 extern void syms_of_xmenu P_ ((void));
+extern int popup_activated_flag;
 
 /* defined in sysdep.c */
 extern void stuff_char P_ ((char c));
@@ -2627,6 +2776,10 @@ 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_ ((char *, int, int));
+extern int emacs_close P_ ((int));
+extern int emacs_read P_ ((int, char *, unsigned int));
+extern int emacs_write P_ ((int, char *, unsigned int));
 
 /* defined in filelock.c */
 EXFUN (Funlock_buffer, 0);
@@ -2676,9 +2829,13 @@ extern int getloadavg P_ ((double *, int));
 /* Defined in xfns.c */
 extern void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object));
 extern void syms_of_xfns P_ ((void));
-EXFUN (Fx_hide_busy_cursor, 1);
 extern void init_xfns P_ ((void));
+EXFUN (Fxw_display_color_p, 1);
+#ifdef HAVE_X_I18N
+extern void free_frame_xic P_ ((struct frame *));
 #endif
+/* Fixme: x_defined_color needs declaring, but needs FRAME_PTR and XColor. */
+#endif /* HAVE_X_WINDOWS */
 
 /* Defined in xselect.c */
 extern void syms_of_xselect P_ ((void));
@@ -2688,7 +2845,9 @@ extern void syms_of_xterm P_ ((void));
 
 /* Defined in getloadavg.c */
 extern int getloadavg P_ ((double [], int));
-\f
+
+/* Defined in composite.c */
+extern void compose_text P_ ((int, int, Lisp_Object, Lisp_Object, Lisp_Object));\f
 /* Nonzero means Emacs has already been initialized.
    Used during startup to detect startup of dumped Emacs.  */
 extern int initialized;
@@ -2698,6 +2857,7 @@ extern int immediate_quit;            /* Nonzero means ^G can quit instantly */
 extern char *getenv (), *ctime (), *getwd ();
 extern long *xmalloc (), *xrealloc ();
 extern void xfree ();
+extern char *xstrdup P_ ((char *));
 
 extern char *egetenv P_ ((char *));