#ifndef EMACS_LISP_H
#define EMACS_LISP_H
+#include <setjmp.h>
#include <stdalign.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
+#include <float.h>
#include <inttypes.h>
#include <limits.h>
/* Define the fundamental Lisp data structures. */
-/* This is the set of Lisp data types. */
+/* This is the set of Lisp data types. If you want to define a new
+ data type, read the comments after Lisp_Fwd_Type definition
+ below. */
/* Lisp integers use 2 tags, to give them one extra bit, thus
extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */
Lisp_Fwd_Kboard_Obj, /* Fwd to a Lisp_Object field of kboards. */
};
+/* If you want to define a new Lisp data type, here are some
+ instructions. See the thread at
+ http://lists.gnu.org/archive/html/emacs-devel/2012-10/msg00561.html
+ for more info.
+
+ First, there are already a couple of Lisp types that can be used if
+ your new type does not need to be exposed to Lisp programs nor
+ displayed to users. These are Lisp_Save_Value, a Lisp_Misc
+ subtype; and PVEC_OTHER, a kind of vectorlike object. The former
+ is suitable for temporarily stashing away pointers and integers in
+ a Lisp object (see the existing uses of make_save_value and
+ XSAVE_VALUE). The latter is useful for vector-like Lisp objects
+ that need to be used as part of other objects, but which are never
+ shown to users or Lisp code (search for PVEC_OTHER in xterm.c for
+ an example).
+
+ These two types don't look pretty when printed, so they are
+ unsuitable for Lisp objects that can be exposed to users.
+
+ To define a new data type, add one more Lisp_Misc subtype or one
+ more pseudovector subtype. Pseudovectors are more suitable for
+ objects with several slots that need to support fast random access,
+ while Lisp_Misc types are for everything else. A pseudovector object
+ provides one or more slots for Lisp objects, followed by struct
+ members that are accessible only from C. A Lisp_Misc object is a
+ wrapper for a C struct that can contain anything you like.
+
+ To add a new pseudovector type, extend the pvec_type enumeration;
+ to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration.
+
+ For a Lisp_Misc, you will also need to add your entry to union
+ Lisp_Misc (but make sure the first word has the same structure as
+ the others, starting with a 16-bit member of the Lisp_Misc_Type
+ enumeration and a 1-bit GC markbit) and make sure the overall size
+ of the union is not increased by your addition.
+
+ Then you will need to add switch branches in print.c (in
+ print_object, to print your object, and possibly also in
+ print_preprocess) and to alloc.c, to mark your object (in
+ mark_object) and to free it (in gc_sweep). The latter is also the
+ right place to call any code specific to your data type that needs
+ to run when the object is recycled -- e.g., free any additional
+ resources allocated for it that are not Lisp objects. You can even
+ make a pointer to the function that frees the resources a slot in
+ your object -- this way, the same object could be used to represent
+ several disparate C structures. */
+
#ifdef CHECK_LISP_OBJECT_TYPE
typedef struct { EMACS_INT i; } Lisp_Object;
= PSEUDOVECTOR_FLAG;
/* In a pseudovector, the size field actually contains a word with one
- PSEUDOVECTOR_FLAG bit set, and exactly one of the following bits to
- 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? */
+ PSEUDOVECTOR_FLAG bit set, and one of the following values extracted
+ with PVEC_TYPE_MASK to indicate the actual type. */
enum pvec_type
{
- PVEC_NORMAL_VECTOR = 0, /* Unused! */
+ PVEC_NORMAL_VECTOR,
PVEC_FREE,
PVEC_PROCESS,
PVEC_FRAME,
/* Construct a Lisp_Object from a value or address. */
-#define XSETINT(a, b) (a) = make_number (b)
-#define XSETCONS(a, b) (a) = make_lisp_ptr (b, Lisp_Cons)
-#define XSETVECTOR(a, b) (a) = make_lisp_ptr (b, Lisp_Vectorlike)
-#define XSETSTRING(a, b) (a) = make_lisp_ptr (b, Lisp_String)
-#define XSETSYMBOL(a, b) (a) = make_lisp_ptr (b, Lisp_Symbol)
-#define XSETFLOAT(a, b) (a) = make_lisp_ptr (b, Lisp_Float)
+#define XSETINT(a, b) ((a) = make_number (b))
+#define XSETCONS(a, b) ((a) = make_lisp_ptr (b, Lisp_Cons))
+#define XSETVECTOR(a, b) ((a) = make_lisp_ptr (b, Lisp_Vectorlike))
+#define XSETSTRING(a, b) ((a) = make_lisp_ptr (b, Lisp_String))
+#define XSETSYMBOL(a, b) ((a) = make_lisp_ptr (b, Lisp_Symbol))
+#define XSETFLOAT(a, b) ((a) = make_lisp_ptr (b, Lisp_Float))
/* Misc types. */
-#define XSETMISC(a, b) (a) = make_lisp_ptr (b, Lisp_Misc)
+#define XSETMISC(a, b) ((a) = make_lisp_ptr (b, Lisp_Misc))
#define XSETMARKER(a, b) (XSETMISC (a, b), XMISCTYPE (a) = Lisp_Misc_Marker)
/* Pseudovector types. */
#define XFLOAT_DATA(f) (0 ? XFLOAT (f)->u.data : XFLOAT (f)->u.data)
#define XFLOAT_INIT(f, n) (XFLOAT (f)->u.data = (n))
+/* Most hosts nowadays use IEEE floating point, so they use IEC 60559
+ representations, have infinities and NaNs, and do not trap on
+ exceptions. Define IEEE_FLOATING_POINT if this host is one of the
+ typical ones. The C11 macro __STDC_IEC_559__ is close to what is
+ wanted here, but is not quite right because Emacs does not require
+ all the features of C11 Annex F (and does not require C11 at all,
+ for that matter). */
+#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
+ && FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
+
/* A character, declared with the following typedef, is a member
of some character set associated with the current buffer. */
#ifndef _UCHAR_T /* Protect against something in ctab.h on AIX. */
#define CHECK_WINDOW_CONFIGURATION(x) \
CHECK_TYPE (WINDOW_CONFIGURATIONP (x), Qwindow_configuration_p, x)
-/* A window of any sort, leaf or interior, is "valid" if one of its
- buffer, vchild, or hchild members is non-nil. */
-#define CHECK_VALID_WINDOW(x) \
- CHECK_TYPE (WINDOWP (x) \
- && (!NILP (XWINDOW (x)->buffer) \
- || !NILP (XWINDOW (x)->vchild) \
- || !NILP (XWINDOW (x)->hchild)), \
- Qwindow_valid_p, x)
-
-/* A window is "live" if and only if it shows a buffer. */
-#define CHECK_LIVE_WINDOW(x) \
- CHECK_TYPE (WINDOWP (x) && !NILP (XWINDOW (x)->buffer), \
- Qwindow_live_p, x)
-
#define CHECK_PROCESS(x) \
CHECK_TYPE (PROCESSP (x), Qprocessp, x)
static struct Lisp_Kboard_Objfwd ko_fwd; \
defvar_kboard (&ko_fwd, lname, offsetof (KBOARD, vname ## _)); \
} while (0)
-
+\f
+/* Save and restore the instruction and environment pointers,
+ without affecting the signal mask. */
+
+#ifdef HAVE__SETJMP
+typedef jmp_buf sys_jmp_buf;
+# define sys_setjmp(j) _setjmp (j)
+# define sys_longjmp(j, v) _longjmp (j, v)
+#elif defined HAVE_SIGSETJMP
+typedef sigjmp_buf sys_jmp_buf;
+# define sys_setjmp(j) sigsetjmp (j, 0)
+# define sys_longjmp(j, v) siglongjmp (j, v)
+#else
+/* A platform that uses neither _longjmp nor siglongjmp; assume
+ longjmp does not affect the sigmask. */
+typedef jmp_buf sys_jmp_buf;
+# define sys_setjmp(j) setjmp (j)
+# define sys_longjmp(j, v) longjmp (j, v)
+#endif
\f
/* Structure for recording Lisp call stack for backtrace purposes. */
#define SPECPDL_INDEX() (specpdl_ptr - specpdl)
-/* Everything needed to describe an active condition case. */
+struct backtrace
+{
+ struct backtrace *next;
+ Lisp_Object function;
+ Lisp_Object *args; /* Points to vector of args. */
+ ptrdiff_t nargs; /* Length of vector. */
+ /* Nonzero means call value of debugger when done with this operation. */
+ unsigned int debug_on_exit : 1;
+};
+
+extern struct backtrace *backtrace_list;
+
+/* Everything needed to describe an active condition case.
+
+ Members are volatile if their values need to survive _longjmp when
+ a 'struct handler' is a local variable. */
struct handler
{
/* The handler clauses and variable from the condition-case form. */
error: handle all conditions, and errors can run the debugger
or display a backtrace. */
Lisp_Object handler;
- Lisp_Object var;
+
+ Lisp_Object volatile var;
+
/* Fsignal stores here the condition-case clause that applies,
and Fcondition_case thus knows which clause to run. */
- Lisp_Object chosen_clause;
+ Lisp_Object volatile chosen_clause;
/* Used to effect the longjump out to the handler. */
struct catchtag *tag;
of the catch form.
All the other members are concerned with restoring the interpreter
- state. */
+ state.
+ Members are volatile if their values need to survive _longjmp when
+ a 'struct catchtag' is a local variable. */
struct catchtag
{
Lisp_Object tag;
- Lisp_Object val;
- struct catchtag *next;
+ Lisp_Object volatile val;
+ struct catchtag *volatile next;
struct gcpro *gcpro;
- jmp_buf jmp;
+ sys_jmp_buf jmp;
struct backtrace *backlist;
struct handler *handlerlist;
EMACS_INT lisp_eval_depth;
- ptrdiff_t pdlcount;
+ ptrdiff_t volatile pdlcount;
int poll_suppress_count;
int interrupt_input_blocked;
struct byte_stack *byte_stack;
If quit-flag is set to `kill-emacs' the SIGINT handler has received
a request to exit Emacs when it is safe to do. */
-#ifdef SYNC_INPUT
extern void process_pending_signals (void);
-extern int pending_signals;
-#define ELSE_PENDING_SIGNALS \
- else if (pending_signals) \
- process_pending_signals ();
-#else /* not SYNC_INPUT */
-#define ELSE_PENDING_SIGNALS
-#endif /* not SYNC_INPUT */
+extern bool volatile pending_signals;
extern void process_quit_flag (void);
#define QUIT \
do { \
if (!NILP (Vquit_flag) && NILP (Vinhibit_quit)) \
process_quit_flag (); \
- ELSE_PENDING_SIGNALS \
+ else if (pending_signals) \
+ process_pending_signals (); \
} while (0)
extern Lisp_Object Qcdr;
-extern Lisp_Object Qrange_error, Qdomain_error, Qsingularity_error;
-extern Lisp_Object Qoverflow_error, Qunderflow_error;
+extern Lisp_Object Qrange_error, Qoverflow_error;
extern Lisp_Object Qfloatp;
extern Lisp_Object Qnumberp, Qnumber_or_marker_p;
extern Lisp_Object do_symval_forwarding (union Lisp_Fwd *);
extern void set_internal (Lisp_Object, Lisp_Object, Lisp_Object, bool);
extern void syms_of_data (void);
-extern void init_data (void);
extern void swap_in_global_binding (struct Lisp_Symbol *);
/* Defined in cmds.c */
extern Lisp_Object QCascent, QCmargin, QCrelief;
extern Lisp_Object QCconversion;
extern int x_bitmap_mask (struct frame *, ptrdiff_t);
+extern void reset_image_types (void);
extern void syms_of_image (void);
/* Defined in insdel.c. */
/* Defined in alloc.c. */
extern void check_pure_size (void);
extern void allocate_string_data (struct Lisp_String *, EMACS_INT, EMACS_INT);
-extern void reset_malloc_hooks (void);
-extern void uninterrupt_malloc (void);
extern void malloc_warning (const char *);
extern _Noreturn void memory_full (size_t);
extern _Noreturn void buffer_memory_full (ptrdiff_t);
extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object);
extern void make_byte_code (struct Lisp_Vector *);
+extern Lisp_Object Qautomatic_gc;
extern Lisp_Object Qchar_table_extra_slots;
extern struct Lisp_Vector *allocate_vector (EMACS_INT);
extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag);
} while (0)
extern int openp (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object *, Lisp_Object);
-Lisp_Object string_to_number (char const *, int, int);
+extern Lisp_Object string_to_number (char const *, int, bool);
extern void map_obarray (Lisp_Object, void (*) (Lisp_Object, Lisp_Object),
Lisp_Object);
extern void dir_warning (const char *, Lisp_Object);
extern Lisp_Object Vautoload_queue;
extern Lisp_Object Vsignaling_function;
extern Lisp_Object inhibit_lisp_code;
-extern int handling_signal;
#if BYTE_MARK_STACK
extern struct catchtag *catchlist;
extern struct handler *handlerlist;
extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t, bool);
extern void init_editfns (void);
-const char *get_system_name (void);
extern void syms_of_editfns (void);
extern void set_time_zone_rule (const char *);
extern void syms_of_fileio (void);
extern Lisp_Object make_temp_name (Lisp_Object, bool);
extern Lisp_Object Qdelete_file;
+extern bool check_existing (const char *);
/* Defined in search.c. */
extern void shrink_regexp_cache (void);
extern ptrdiff_t fast_looking_at (Lisp_Object, ptrdiff_t, ptrdiff_t,
ptrdiff_t, ptrdiff_t, Lisp_Object);
extern ptrdiff_t scan_buffer (int, ptrdiff_t, ptrdiff_t, ptrdiff_t,
- ptrdiff_t *, int);
+ ptrdiff_t *, bool);
extern EMACS_INT scan_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t,
- EMACS_INT, int);
+ EMACS_INT, bool);
extern ptrdiff_t find_next_newline (ptrdiff_t, int);
extern ptrdiff_t find_next_newline_no_quit (ptrdiff_t, ptrdiff_t);
extern ptrdiff_t find_before_next_newline (ptrdiff_t, ptrdiff_t, ptrdiff_t);
extern Lisp_Object Qup, Qdown, Qbottom;
extern Lisp_Object Qtop;
extern Lisp_Object last_undo_boundary;
-extern int input_pending;
+extern bool input_pending;
extern Lisp_Object menu_bar_items (Lisp_Object);
extern Lisp_Object tool_bar_items (Lisp_Object, int *);
extern void discard_mouse_events (void);
+#ifdef USABLE_SIGIO
+void handle_input_available_signal (int);
+#endif
extern Lisp_Object pending_funcalls;
-extern int detect_input_pending (void);
-extern int detect_input_pending_ignore_squeezables (void);
-extern int detect_input_pending_run_timers (int);
+extern bool detect_input_pending (void);
+extern bool detect_input_pending_ignore_squeezables (void);
+extern bool detect_input_pending_run_timers (bool);
extern void safe_run_hooks (Lisp_Object);
extern void cmd_error_internal (Lisp_Object, const char *);
extern Lisp_Object command_loop_1 (void);
/* Defined in indent.c. */
extern ptrdiff_t current_column (void);
extern void invalidate_current_column (void);
-extern int indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT);
+extern bool indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT);
extern void syms_of_indent (void);
/* Defined in frame.c. */
extern Lisp_Object decode_env_path (const char *, const char *);
extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
extern Lisp_Object Qfile_name_handler_alist;
-extern _Noreturn void fatal_error_backtrace (int, int);
+extern _Noreturn void terminate_due_to_signal (int, int);
extern Lisp_Object Qkill_emacs;
+#ifdef WINDOWSNT
+extern Lisp_Object Vlibrary_cache;
+#endif
#if HAVE_SETLOCALE
void fixup_locale (void);
void synchronize_system_messages_locale (void);
extern Lisp_Object QCtype, Qlocal;
extern Lisp_Object Qprocessp;
extern void kill_buffer_processes (Lisp_Object);
-extern int wait_reading_process_output (intmax_t, int, int, int,
+extern int wait_reading_process_output (intmax_t, int, int, bool,
Lisp_Object,
struct Lisp_Process *,
int);
extern char *get_current_dir_name (void);
#endif
extern void stuff_char (char c);
+extern void init_foreground_group (void);
extern void init_sigio (int);
extern void sys_subshell (void);
extern void sys_suspend (void);
extern void reset_sys_modes (struct tty_display_info *);
extern void init_all_sys_modes (void);
extern void reset_all_sys_modes (void);
-extern void wait_for_termination (pid_t);
-extern void interruptible_wait_for_termination (pid_t);
extern void flush_pending_output (int) ATTRIBUTE_CONST;
extern void child_setup_tty (int);
extern void setup_pty (int);
void syms_of_dbusbind (void);
#endif
+
+/* Defined in profiler.c. */
+extern bool profiler_memory_running;
+extern void malloc_probe (size_t);
+extern void syms_of_profiler (void);
+
+
#ifdef DOS_NT
/* Defined in msdos.c, w32.c. */
extern char *emacs_root_dir (void);
Used during startup to detect startup of dumped Emacs. */
extern bool initialized;
-extern int immediate_quit; /* Nonzero means ^G can quit instantly. */
+/* True means ^G can quit instantly. */
+extern bool immediate_quit;
extern void *xmalloc (size_t);
extern void *xzalloc (size_t);