Update years in copyright notice; nfc.
[bpt/emacs.git] / src / lisp.h
index bcd0663..09f6f38 100644 (file)
@@ -1,6 +1,6 @@
 /* Fundamental definitions for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985,86,87,93,94,95,97,98,1999,2000,01,02,03,2004
-     Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
+                 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #ifndef EMACS_LISP_H
 #define EMACS_LISP_H
@@ -35,8 +35,29 @@ Boston, MA 02111-1307, USA.  */
    be compared to the sizes recorded in Lisp strings.  */
 
 #define GC_CHECK_STRING_BYTES 1
+
+/* Define this to check for short string overrun.  */
+
+#define GC_CHECK_STRING_OVERRUN 1
+
+/* Define this to check the string free list.  */
+
+#define GC_CHECK_STRING_FREE_LIST 1
+
+/* Define this to check for malloc buffer overrun.  */
+
+#define XMALLOC_OVERRUN_CHECK 1
+
+/* Define this to check for errors in cons list.  */
+/* #define GC_CHECK_CONS_LIST 1 */
+
 #endif /* 0 */
 
+#ifdef GC_CHECK_CONS_LIST
+#define CHECK_CONS_LIST() check_cons_list()
+#else
+#define CHECK_CONS_LIST() 0
+#endif
 
 /* These are default choices for the types to use.  */
 #ifdef _LP64
@@ -232,7 +253,7 @@ LISP_MAKE_RVALUE (Lisp_Object o)
 /* If union type is not wanted, define Lisp_Object as just a number.  */
 
 #ifdef NO_UNION_TYPE
-#define Lisp_Object EMACS_INT
+typedef EMACS_INT Lisp_Object;
 #define LISP_MAKE_RVALUE(o) (0+(o))
 #endif /* NO_UNION_TYPE */
 
@@ -304,11 +325,13 @@ enum pvec_type
 /* 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 DECL_ALIGN
+#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
+#  if defined (__GNUC__)
+#   define DECL_ALIGN(type, var) \
+     type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
+#  endif
 # endif
 #endif
 
@@ -323,7 +346,7 @@ enum pvec_type
 # endif
 #endif
 
-/* Just remove the alignment annotation if we don't use it.  */
+/* 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"
@@ -428,10 +451,10 @@ enum pvec_type
 #define make_number(N) \
   (__extension__ ({ Lisp_Object _l; _l.s.val = (N); _l.s.type = Lisp_Int; _l; }))
 #else
-extern Lisp_Object make_number ();
+extern Lisp_Object make_number P_ ((EMACS_INT));
 #endif
 
-#define EQ(x, y) ((x).s.val == (y).s.val && (x).s.type == (y).s.type)
+#define EQ(x, y) ((x).i == (y).i)
 
 #endif /* NO_UNION_TYPE */
 
@@ -461,7 +484,11 @@ extern size_t pure_size;
    in a Lisp object whose data type says it points to something.  */
 #define XPNTR(a) (XUINT (a) | DATA_SEG_BITS)
 #else
-#define XPNTR(a) XUINT (a)
+/* Some versions of gcc seem to consider the bitfield width when
+   issuing the "cast to pointer from integer of different size"
+   warning, so the cast is here to widen the value back to its natural
+   size.  */
+#define XPNTR(a) ((EMACS_INT) XUINT (a))
 #endif
 #endif /* not HAVE_SHM */
 #endif /* no XPNTR */
@@ -577,9 +604,19 @@ struct Lisp_Cons
     /* Please do not use the names of these elements in code other
        than the core lisp implementation.  Use XCAR and XCDR below.  */
 #ifdef HIDE_LISP_IMPLEMENTATION
-    Lisp_Object car_, cdr_;
+    Lisp_Object car_;
+    union
+    {
+      Lisp_Object cdr_;
+      struct Lisp_Cons *chain;
+    } u;
 #else
-    Lisp_Object car, cdr;
+    Lisp_Object car;
+    union
+    {
+      Lisp_Object cdr;
+      struct Lisp_Cons *chain;
+    } u;
 #endif
   };
 
@@ -592,10 +629,10 @@ struct Lisp_Cons
    invalidated at arbitrary points.)  */
 #ifdef HIDE_LISP_IMPLEMENTATION
 #define XCAR_AS_LVALUE(c) (XCONS ((c))->car_)
-#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr_)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->u.cdr_)
 #else
 #define XCAR_AS_LVALUE(c) (XCONS ((c))->car)
-#define XCDR_AS_LVALUE(c) (XCONS ((c))->cdr)
+#define XCDR_AS_LVALUE(c) (XCONS ((c))->u.cdr)
 #endif
 
 /* Use these from normal code.  */
@@ -697,6 +734,14 @@ struct Lisp_Vector
    indexed by (charset-id + 128).  */
 #define CHAR_TABLE_ORDINARY_SLOTS 384
 
+/* These are the slot of the default values for single byte
+   characters.  As 0x9A is never be a charset-id, it is safe to use
+   that slot for ASCII.  0x9E and 0x80 are charset-ids of
+   eight-bit-control and eight-bit-graphic respectively.  */
+#define CHAR_TABLE_DEFAULT_SLOT_ASCII (0x9A + 128)
+#define CHAR_TABLE_DEFAULT_SLOT_8_BIT_CONTROL (0x9E + 128)
+#define CHAR_TABLE_DEFAULT_SLOT_8_BIT_GRAPHIC (0x80 + 128)
+
 /* This is the number of slots that apply to characters of ASCII and
    8-bit Europeans only.  */
 #define CHAR_TABLE_SINGLE_BYTE_SLOTS 256
@@ -1199,7 +1244,10 @@ struct Lisp_Save_Value
   {
     int type : 16;     /* = Lisp_Misc_Save_Value */
     unsigned gcmarkbit : 1;
-    int spacer : 15;
+    int spacer : 14;
+    /* If DOGC is set, POINTER is the address of a memory
+       area containing INTEGER potential Lisp_Objects.  */
+    unsigned int dogc : 1;
     void *pointer;
     int integer;
   };
@@ -1241,17 +1289,21 @@ union Lisp_Misc
 /* Lisp floating point type */
 struct Lisp_Float
   {
+    union
+    {
 #ifdef HIDE_LISP_IMPLEMENTATION
-    double data_;
+      double data_;
 #else
-    double data;
+      double data;
 #endif
+      struct Lisp_Float *chain;
+    } u;
   };
 
 #ifdef HIDE_LISP_IMPLEMENTATION
-#define XFLOAT_DATA(f) (XFLOAT (f)->data_)
+#define XFLOAT_DATA(f) (XFLOAT (f)->u.data_)
 #else
-#define XFLOAT_DATA(f) (XFLOAT (f)->data)
+#define XFLOAT_DATA(f) (XFLOAT (f)->u.data)
 #endif
 
 /* A character, declared with the following typedef, is a member
@@ -1371,7 +1423,7 @@ typedef unsigned char UCHAR;
 \f
 /* Data type checking */
 
-#define NILP(x)  (XFASTINT (x) == XFASTINT (Qnil))
+#define NILP(x)  EQ (x, Qnil)
 #define GC_NILP(x) GC_EQ (x, Qnil)
 
 #define NUMBERP(x) (INTEGERP (x) || FLOATP (x))
@@ -1650,8 +1702,16 @@ extern void defvar_kboard P_ ((char *, int));
 #define DEFVAR_LISP_NOPRO(lname, vname, doc) defvar_lisp_nopro (lname, vname)
 #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 *)(&current_kboard->vname) \
@@ -1747,11 +1807,15 @@ extern char *stack_bottom;
 #ifdef SYNC_INPUT
 extern void handle_async_input P_ ((void));
 extern int interrupt_input_pending;
+
 #define QUIT                                           \
   do {                                                 \
     if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))    \
       {                                                        \
+        Lisp_Object flag = Vquit_flag;                 \
        Vquit_flag = Qnil;                              \
+       if (EQ (Vthrow_on_input, flag))                 \
+         Fthrow (Vthrow_on_input, Qt);                 \
        Fsignal (Qquit, Qnil);                          \
       }                                                        \
     else if (interrupt_input_pending)                  \
@@ -1764,7 +1828,10 @@ extern int interrupt_input_pending;
   do {                                                 \
     if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))    \
       {                                                        \
+        Lisp_Object flag = Vquit_flag;                 \
        Vquit_flag = Qnil;                              \
+       if (EQ (Vthrow_on_input, flag))                 \
+         Fthrow (Vthrow_on_input, Qt);                 \
        Fsignal (Qquit, Qnil);                          \
       }                                                        \
   } while (0)
@@ -1820,16 +1887,21 @@ extern Lisp_Object case_temp2;
     NATNUMP (case_temp2))                                      \
    ? XFASTINT (case_temp2) : case_temp1)
 
-extern Lisp_Object Vascii_downcase_table;
+extern Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
+extern Lisp_Object Vascii_canon_table, Vascii_eqv_table;
 \f
 /* Number of bytes of structure consed since last GC.  */
 
 extern int consing_since_gc;
 
-/* Threshold for doing another gc.  */
+/* Thresholds for doing another gc.  */
 
 extern EMACS_INT gc_cons_threshold;
 
+extern EMACS_INT gc_relative_threshold;
+
+extern EMACS_INT memory_full_cons_threshold;
+
 /* Structure for recording stack slots that need marking.  */
 
 /* This is a chain of structures, each of which points at a Lisp_Object variable
@@ -2275,6 +2347,7 @@ EXFUN (Felt, 2);
 EXFUN (Fmember, 2);
 EXFUN (Frassq, 2);
 EXFUN (Fdelq, 2);
+EXFUN (Fdelete, 2);
 EXFUN (Fsort, 2);
 EXFUN (Freverse, 1);
 EXFUN (Fnreverse, 1);
@@ -2297,6 +2370,7 @@ 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));
+extern Lisp_Object string_to_multibyte P_ ((Lisp_Object));
 extern Lisp_Object string_make_unibyte P_ ((Lisp_Object));
 EXFUN (Fcopy_alist, 1);
 EXFUN (Fplist_get, 2);
@@ -2329,6 +2403,7 @@ extern void init_fringe P_ ((void));
 extern void init_fringe_once P_ ((void));
 
 /* Defined in image.c */
+EXFUN (Finit_image_library, 2);
 extern void syms_of_image P_ ((void));
 extern void init_image P_ ((void));
 
@@ -2365,6 +2440,7 @@ extern void adjust_after_replace P_ ((int, int, Lisp_Object, int, int));
 extern void adjust_after_replace_noundo P_ ((int, int, int, int, int, int));
 extern void adjust_after_insert P_ ((int, int, int, int, int));
 extern void replace_range P_ ((int, int, Lisp_Object, int, int, int));
+extern void replace_range_2 P_ ((int, int, int, int, char *, int, int, int));
 extern void syms_of_insdel P_ ((void));
 
 /* Defined in dispnew.c */
@@ -2423,7 +2499,7 @@ extern void syms_of_xdisp P_ ((void));
 extern void init_xdisp P_ ((void));
 extern Lisp_Object safe_eval P_ ((Lisp_Object));
 extern int pos_visible_p P_ ((struct window *, int, int *,
-                             int *, int *, int));
+                             int *, int *, int *, int));
 
 /* Defined in vm-limit.c.  */
 extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
@@ -2431,6 +2507,7 @@ extern void memory_warnings P_ ((POINTER_TYPE *, void (*warnfun) ()));
 /* Defined in alloc.c */
 extern void check_pure_size P_ ((void));
 extern void allocate_string_data P_ ((struct Lisp_String *, int, int));
+extern void reset_malloc_hooks P_ ((void));
 extern void uninterrupt_malloc P_ ((void));
 extern void malloc_warning P_ ((char *));
 extern void memory_full P_ ((void));
@@ -2483,12 +2560,14 @@ extern Lisp_Object make_float P_ ((double));
 extern void display_malloc_warning P_ ((void));
 extern int inhibit_garbage_collection P_ ((void));
 extern Lisp_Object make_save_value P_ ((void *, int));
+extern void free_misc P_ ((Lisp_Object));
 extern void free_marker P_ ((Lisp_Object));
 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));
+extern int valid_lisp_object_p P_ ((Lisp_Object));
 
 /* Defined in print.c */
 extern Lisp_Object Vprin1_to_string_buffer;
@@ -2606,6 +2685,7 @@ extern Lisp_Object call6 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object
 EXFUN (Fdo_auto_save, 2);
 extern Lisp_Object apply_lambda P_ ((Lisp_Object, Lisp_Object, int));
 extern Lisp_Object internal_catch P_ ((Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object));
+extern Lisp_Object internal_lisp_condition_case P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object internal_condition_case P_ ((Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)));
 extern Lisp_Object internal_condition_case_1 P_ ((Lisp_Object (*) (Lisp_Object), Lisp_Object, Lisp_Object, Lisp_Object (*) (Lisp_Object)));
 extern Lisp_Object internal_condition_case_2 P_ ((Lisp_Object (*) (int, Lisp_Object *), int, Lisp_Object *, Lisp_Object, Lisp_Object (*) (Lisp_Object)));
@@ -2712,6 +2792,7 @@ EXFUN (Fbuffer_disable_undo, 1);
 EXFUN (Fbuffer_enable_undo, 1);
 EXFUN (Ferase_buffer, 0);
 extern Lisp_Object Qoverlayp;
+extern Lisp_Object Qevaporate;
 extern Lisp_Object get_truename_buffer P_ ((Lisp_Object));
 extern struct buffer *all_buffers;
 EXFUN (Fprevious_overlay_change, 1);
@@ -2779,14 +2860,16 @@ extern void syms_of_abbrev P_ ((void));
 /* defined in search.c */
 extern void shrink_regexp_cache P_ ((void));
 EXFUN (Fstring_match, 3);
-extern void restore_match_data P_ ((void));
-EXFUN (Fmatch_data, 2);
-EXFUN (Fset_match_data, 1);
+extern void restore_search_regs P_ ((void));
+EXFUN (Fmatch_data, 3);
+EXFUN (Fset_match_data, 2);
 EXFUN (Fmatch_beginning, 1);
 EXFUN (Fmatch_end, 1);
+extern void record_unwind_save_match_data P_ ((void));
 EXFUN (Flooking_at, 1);
 extern int fast_string_match P_ ((Lisp_Object, Lisp_Object));
 extern int fast_c_string_match_ignore_case P_ ((Lisp_Object, const char *));
+extern int fast_string_match_ignore_case P_ ((Lisp_Object, Lisp_Object));
 extern int scan_buffer P_ ((int, int, int, int, int *, int));
 extern int scan_newline P_ ((int, int, int, int, int, int));
 extern int find_next_newline P_ ((int, int));
@@ -2799,7 +2882,7 @@ extern void syms_of_search P_ ((void));
 extern Lisp_Object last_minibuf_string;
 extern void choose_minibuf_frame P_ ((void));
 EXFUN (Fcompleting_read, 8);
-EXFUN (Fread_from_minibuffer, 7);
+EXFUN (Fread_from_minibuffer, 8);
 EXFUN (Fread_variable, 2);
 EXFUN (Fread_buffer, 3);
 EXFUN (Fread_minibuffer, 2);
@@ -2847,6 +2930,7 @@ extern struct kboard *echo_kboard;
 extern void cancel_echoing P_ ((void));
 extern Lisp_Object Qdisabled, QCfilter;
 extern Lisp_Object Vtty_erase_char, Vhelp_form, Vtop_level;
+extern Lisp_Object Vthrow_on_input;
 extern int input_pending;
 EXFUN (Fdiscard_input, 0);
 EXFUN (Frecursive_edit, 0);
@@ -2861,6 +2945,7 @@ EXFUN (Fevent_convert_list, 1);
 EXFUN (Fread_key_sequence, 5);
 EXFUN (Fset_input_mode, 4);
 extern int detect_input_pending P_ ((void));
+extern int detect_input_pending_ignore_squeezables P_ ((void));
 extern int detect_input_pending_run_timers P_ ((int));
 extern void safe_run_hooks P_ ((Lisp_Object));
 extern void cmd_error_internal P_ ((Lisp_Object, char *));
@@ -2884,6 +2969,10 @@ extern int indented_beyond_p P_ ((int, int, double));
 extern void syms_of_indent P_ ((void));
 
 /* defined in frame.c */
+#ifdef HAVE_WINDOW_SYSTEM
+extern Lisp_Object Vx_resource_name;
+extern Lisp_Object Vx_resource_class;
+#endif /* HAVE_WINDOW_SYSTEM */
 extern Lisp_Object Qvisible;
 extern void store_frame_param P_ ((struct frame *, Lisp_Object, Lisp_Object));
 extern void store_in_alist P_ ((Lisp_Object *, Lisp_Object, Lisp_Object));
@@ -2891,7 +2980,7 @@ extern Lisp_Object do_switch_frame P_ ((Lisp_Object, int, int));
 extern Lisp_Object get_frame_param P_ ((struct frame *, Lisp_Object));
 extern Lisp_Object frame_buffer_predicate P_ ((Lisp_Object));
 EXFUN (Fframep, 1);
-EXFUN (Fselect_frame, 2);
+EXFUN (Fselect_frame, 1);
 EXFUN (Fselected_frame, 0);
 EXFUN (Fwindow_frame, 1);
 EXFUN (Fframe_root_window, 1);
@@ -2955,13 +3044,13 @@ EXFUN (Fprocess_send_eof, 1);
 EXFUN (Fwaiting_for_user_input_p, 0);
 extern Lisp_Object Qprocessp;
 extern void kill_buffer_processes P_ ((Lisp_Object));
-extern int wait_reading_process_input P_ ((int, int, Lisp_Object, int));
-extern void deactivate_process P_ ((Lisp_Object));
+extern int wait_reading_process_output P_ ((int, int, int, int,
+                                           Lisp_Object,
+                                           struct Lisp_Process *,
+                                           int));
 extern void add_keyboard_wait_descriptor P_ ((int));
 extern void delete_keyboard_wait_descriptor P_ ((int));
 extern void close_process_descs P_ ((void));
-extern void status_notify P_ ((void));
-extern int read_process_output P_ ((Lisp_Object, int));
 extern void init_process P_ ((void));
 extern void syms_of_process P_ ((void));
 extern void setup_process_coding_systems P_ ((Lisp_Object));
@@ -3005,7 +3094,7 @@ extern void syms_of_macros P_ ((void));
 /* defined in undo.c */
 extern Lisp_Object Qinhibit_read_only;
 EXFUN (Fundo_boundary, 0);
-extern Lisp_Object truncate_undo_list P_ ((Lisp_Object, int, int));
+extern void truncate_undo_list P_ ((struct buffer *));
 extern void record_marker_adjustment P_ ((Lisp_Object, int));
 extern void record_insert P_ ((int, int));
 extern void record_delete P_ ((int, Lisp_Object));
@@ -3014,6 +3103,7 @@ extern void record_change P_ ((int, int));
 extern void record_property_change P_ ((int, int, Lisp_Object, Lisp_Object,
                                        Lisp_Object));
 extern void syms_of_undo P_ ((void));
+extern Lisp_Object Vundo_outer_limit;
 
 /* defined in textprop.c */
 extern Lisp_Object Qfont, Qmouse_face;
@@ -3032,10 +3122,13 @@ extern Lisp_Object next_single_char_property_change P_ ((Lisp_Object,
 
 /* defined in xmenu.c */
 EXFUN (Fx_popup_menu, 2);
-EXFUN (Fx_popup_dialog, 2);
+EXFUN (Fx_popup_dialog, 3);
 extern void syms_of_xmenu P_ ((void));
 
 /* 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));
@@ -3104,11 +3197,12 @@ extern int getloadavg P_ ((double *, int));
 #ifdef HAVE_X_WINDOWS
 /* Defined in xfns.c */
 extern void syms_of_xfns P_ ((void));
-extern Lisp_Object Vx_resource_name;
-extern Lisp_Object Vx_resource_class;
-EXFUN (Fxw_display_color_p, 1);
-EXFUN (Fx_file_dialog, 4);
 #endif /* HAVE_X_WINDOWS */
+#ifdef HAVE_WINDOW_SYSTEM
+/* Defined in xfns.c, w32fns.c, or macfns.c */
+EXFUN (Fxw_display_color_p, 1);
+EXFUN (Fx_file_dialog, 5);
+#endif /* HAVE_WINDOW_SYSTEM */
 
 /* Defined in xsmfns.c */
 extern void syms_of_xsmfns P_ ((void));
@@ -3121,6 +3215,11 @@ extern void syms_of_xterm P_ ((void));
 
 /* Defined in getloadavg.c */
 extern int getloadavg P_ ((double [], int));
+
+#ifdef MSDOS
+/* Defined in msdos.c */
+EXFUN (Fmsdos_downcase_filename, 1);
+#endif
 \f
 /* Nonzero means Emacs has already been initialized.
    Used during startup to detect startup of dumped Emacs.  */
@@ -3134,9 +3233,7 @@ extern void xfree P_ ((POINTER_TYPE *));
 
 extern char *xstrdup P_ ((const char *));
 
-#ifndef USE_CRT_DLL
 extern char *egetenv P_ ((char *));
-#endif
 
 /* Set up the name of the machine we're running on.  */
 extern void init_system_name P_ ((void));
@@ -3243,6 +3340,61 @@ extern Lisp_Object Vdirectory_sep_char;
         : 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.  */
+
+#define MAX_ALLOCA 16*1024
+
+extern Lisp_Object safe_alloca_unwind (Lisp_Object);
+
+#define USE_SAFE_ALLOCA                        \
+  int sa_count = SPECPDL_INDEX (), 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 = (type) xmalloc (size);                      \
+       sa_must_free++;                                   \
+       record_unwind_protect (safe_alloca_unwind,        \
+                              make_save_value (buf, 0)); \
+      }                                                          \
+  } while (0)
+
+/* SAFE_FREE frees xmalloced memory and enables GC as needed.  */
+
+#define SAFE_FREE()                    \
+  do {                                 \
+    if (sa_must_free) {                        \
+      sa_must_free = 0;                        \
+      unbind_to (sa_count, Qnil);      \
+    }                                  \
+  } while (0)
+
+
+/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects.  */
+
+#define SAFE_ALLOCA_LISP(buf, nelt)                      \
+  do {                                                   \
+    int size_ = (nelt) * sizeof (Lisp_Object);           \
+    if (size_ < MAX_ALLOCA)                              \
+      buf = (Lisp_Object *) alloca (size_);              \
+    else                                                 \
+      {                                                          \
+       Lisp_Object arg_;                                 \
+       buf = (Lisp_Object *) xmalloc (size_);            \
+       arg_ = make_save_value (buf, nelt);               \
+       XSAVE_VALUE (arg_)->dogc = 1;                     \
+       sa_must_free++;                                   \
+       record_unwind_protect (safe_alloca_unwind, arg_); \
+      }                                                          \
+  } while (0)
+
+
 #endif /* EMACS_LISP_H */
 
 /* arch-tag: 9b2ed020-70eb-47ac-94ee-e1c2a5107d5e