2013-07-16 Paul Eggert <eggert@cs.ucla.edu>
+ New unwind-protect flavors to better type-check C callbacks.
+ This also lessens the need to write wrappers for callbacks,
+ and the need for make_save_pointer.
+ * alloca.c (free_save_value):
+ * atimer.c (run_all_atimers):
+ Now extern.
+ * alloc.c (safe_alloca_unwind):
+ * atimer.c (unwind_stop_other_atimers):
+ * keyboard.c (cancel_hourglass_unwind) [HAVE_WINDOW_SYSTEM]:
+ * menu.c (cleanup_popup_menu) [HAVE_NS]:
+ * minibuf.c (choose_minibuf_frame_1):
+ * process.c (make_serial_process_unwind):
+ * xdisp.h (pop_message_unwind):
+ * xselect.c (queue_selection_requests_unwind):
+ Remove no-longer-needed wrapper. All uses replaced by the wrappee.
+ * alloca.c (record_xmalloc):
+ Prefer record_unwind_protect_ptr to record_unwind_protect with
+ make_save_pointer.
+ * alloca.c (Fgarbage_collect):
+ Prefer record_unwind_protect_void to passing a dummy.
+ * buffer.c (restore_buffer):
+ * window.c (restore_window_configuration):
+ * xfns.c, w32fns.c (do_unwind_create_frame)
+ New wrapper. All record-unwind uses of wrappee changed.
+ * buffer.c (set_buffer_if_live):
+ * callproc.c (call_process_cleanup, delete_temp_file):
+ * coding.c (code_conversion_restore):
+ * dired.c (directory_files_internal_w32_unwind) [WINDOWSNT]:
+ * editfns.c (save_excursion_restore)
+ (subst_char_in_region_unwind, subst_char_in_region_unwind_1)
+ (save_restriction_restore):
+ * eval.c (restore_stack_limits, un_autoload):
+ * fns.c (require_unwind):
+ * keyboard.c (recursive_edit_unwind, tracking_off):
+ * lread.c (record_load_unwind, load_warn_old_style_backquotes):
+ * macros.c (pop_kbd_macro, restore_menu_items):
+ * nsfns.m (unwind_create_frame):
+ * print.c (print_unwind):
+ * process.c (start_process_unwind):
+ * search.c (unwind_set_match_data):
+ * window.c (select_window_norecord, select_frame_norecord):
+ * xdisp.c (unwind_with_echo_area_buffer, unwind_format_mode_line)
+ (fast_set_selected_frame):
+ * xfns.c, w32fns.c (unwind_create_tip_frame):
+ Return void, not a dummy Lisp_Object. All uses changed.
+ * buffer.h (set_buffer_if_live): Move decl here from lisp.h.
+ * callproc.c (call_process_kill):
+ * fileio.c (restore_point_unwind, decide_coding_unwind)
+ (build_annotations_unwind):
+ * insdel.c (Fcombine_after_change_execute_1):
+ * keyboard.c (read_char_help_form_unwind):
+ * menu.c (unuse_menu_items):
+ * minibuf.c (run_exit_minibuf_hook, read_minibuf_unwind):
+ * sound.c (sound_cleanup):
+ * xdisp.c (unwind_redisplay):
+ * xfns.c (clean_up_dialog):
+ * xselect.c (x_selection_request_lisp_error, x_catch_errors_unwind):
+ Accept no args and return void, instead of accepting and returning
+ a dummy Lisp_Object. All uses changed.
+ * cygw32.c (fchdir_unwind):
+ * fileio.c (close_file_unwind):
+ * keyboard.c (restore_kboard_configuration):
+ * lread.c (readevalllop_1):
+ * process.c (wait_reading_process_output_unwind):
+ Accept int and return void, rather than accepting an Emacs integer
+ and returning a dummy object. In some cases this fixes an
+ unlikely bug when the corresponding int is outside Emacs integer
+ range. All uses changed.
+ * dired.c (directory_files_internal_unwind):
+ * fileio.c (do_auto_save_unwind):
+ * gtkutil.c (pop_down_dialog):
+ * insdel.c (reset_var_on_error):
+ * lread.c (load_unwind):
+ * xfns.c (clean_up_file_dialog):
+ * xmenu.c, nsmenu.m (pop_down_menu):
+ * xmenu.c (cleanup_widget_value_tree):
+ * xselect.c (wait_for_property_change_unwind):
+ Accept pointer and return void, rather than accepting an Emacs
+ save value encapsulating the pointer and returning a dummy object.
+ All uses changed.
+ * editfns.c (Fformat): Update the saved pointer directly via
+ set_unwind_protect_ptr rather than indirectly via make_save_pointer.
+ * eval.c (specpdl_func): Remove. All uses replaced by definiens.
+ (unwind_body): New function.
+ (record_unwind_protect): First arg is now a function returning void,
+ not a dummy Lisp_Object.
+ (record_unwind_protect_ptr, record_unwind_protect_int)
+ (record_unwind_protect_void): New functions.
+ (unbind_to): Support SPECPDL_UNWIND_PTR etc.
+ * fileio.c (struct auto_save_unwind): New type.
+ (do_auto_save_unwind): Use it.
+ (do_auto_save_unwind_1): Remove; subsumed by new do_auto_save_unwind.
+ * insdel.c (struct rvoe_arg): New type.
+ (reset_var_on_error): Use it.
+ * lisp.h (SPECPDL_UNWIND_PTR, SPECPDL_UNWIND_INT, SPECPDL_UNWIND_VOID):
+ New constants.
+ (specbinding_func): Remove; there are now several such functions.
+ (union specbinding): New members unwind_ptr, unwind_int, unwind_void.
+ (set_unwind_protect_ptr): New function.
+ * xselect.c: Remove unnecessary forward decls, to simplify maintenance.
+
Be simpler and more consistent about reporting I/O errors.
* fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
Say "Read error" and "Write error", rather than "I/O error", or
static Lisp_Object Qpost_gc_hook;
-static void free_save_value (Lisp_Object);
static void mark_terminals (void);
static void gc_sweep (void);
static Lisp_Object make_pure_vector (ptrdiff_t);
memory_full (0);
}
-/* Unwind for SAFE_ALLOCA */
-
-Lisp_Object
-safe_alloca_unwind (Lisp_Object arg)
-{
- free_save_value (arg);
- return Qnil;
-}
-
/* Return a newly allocated memory block of SIZE bytes, remembering
to free it when unwinding. */
void *
record_xmalloc (size_t size)
{
void *p = xmalloc (size);
- record_unwind_protect (safe_alloca_unwind, make_save_pointer (p));
+ record_unwind_protect_ptr (xfree, p);
return p;
}
return val;
}
-/* The most common task it to save just one C pointer. */
+/* Save just one C pointer. record_unwind_protect_ptr is simpler and
+ faster than combining this with record_unwind_protect, but
+ occasionally this function is useful for other reasons. */
Lisp_Object
make_save_pointer (void *pointer)
/* Free a Lisp_Save_Value object. Do not use this function
if SAVE contains pointer other than returned by xmalloc. */
-static void
+void
free_save_value (Lisp_Object save)
{
xfree (XSAVE_POINTER (save, 0));
/* Save what's currently displayed in the echo area. */
message_p = push_message ();
- record_unwind_protect (pop_message_unwind, Qnil);
+ record_unwind_protect_void (pop_message_unwind);
/* Save a copy of the contents of the stack, for debugging. */
#if MAX_SAVE_STACK > 0
/* Run all timers again, if some have been stopped with a call to
stop_other_atimers. */
-static void
+void
run_all_atimers (void)
{
if (stopped_atimers)
}
-/* A version of run_all_atimers suitable for a record_unwind_protect. */
-
-Lisp_Object
-unwind_stop_other_atimers (Lisp_Object dummy)
-{
- run_all_atimers ();
- return Qnil;
-}
-
-
/* Arrange for a SIGALRM to arrive when the next timer is ripe. */
static void
void init_atimer (void);
void turn_on_atimers (bool);
void stop_other_atimers (struct atimer *);
-Lisp_Object unwind_stop_other_atimers (Lisp_Object);
+void run_all_atimers (void);
#endif /* EMACS_ATIMER_H */
return buffer;
}
+void
+restore_buffer (Lisp_Object buffer_or_name)
+{
+ Fset_buffer (buffer_or_name);
+}
+
/* Set the current buffer to BUFFER provided if it is alive. */
-Lisp_Object
+void
set_buffer_if_live (Lisp_Object buffer)
{
if (BUFFER_LIVE_P (XBUFFER (buffer)))
set_buffer_internal (XBUFFER (buffer));
- return Qnil;
}
\f
DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
extern void record_buffer (Lisp_Object);
extern void fix_overlays_before (struct buffer *, ptrdiff_t, ptrdiff_t);
extern void mmap_set_vars (bool);
+extern void restore_buffer (Lisp_Object);
+extern void set_buffer_if_live (Lisp_Object);
/* Set the current buffer to B.
CASE (Bsave_window_excursion): /* Obsolete since 24.1. */
{
- register ptrdiff_t count1 = SPECPDL_INDEX ();
- record_unwind_protect (Fset_window_configuration,
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ record_unwind_protect (restore_window_configuration,
Fcurrent_window_configuration (Qnil));
BEFORE_POTENTIAL_GC ();
TOP = Fprogn (TOP);
}
CASE (Bunwind_protect): /* FIXME: avoid closure for lexbind. */
- record_unwind_protect (Fprogn, POP);
+ record_unwind_protect (unwind_body, POP);
NEXT;
CASE (Bcondition_case): /* FIXME: ill-suited for lexbind. */
/* Clean up when exiting call_process_cleanup. */
-static Lisp_Object
-call_process_kill (Lisp_Object ignored)
+static void
+call_process_kill (void)
{
if (synch_process_fd >= 0)
emacs_close (synch_process_fd);
proc.pid = synch_process_pid;
record_kill_process (&proc);
}
-
- return Qnil;
}
/* Clean up when exiting Fcall_process.
On MSDOS, delete the temporary file on any kind of termination.
On Unix, kill the process and any children on termination by signal. */
-static Lisp_Object
+static void
call_process_cleanup (Lisp_Object arg)
{
#ifdef MSDOS
{
ptrdiff_t count = SPECPDL_INDEX ();
kill (-synch_process_pid, SIGINT);
- record_unwind_protect (call_process_kill, make_number (0));
+ record_unwind_protect_void (call_process_kill);
message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
immediate_quit = 1;
QUIT;
if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
unlink (SDATA (file));
#endif
-
- return Qnil;
}
#ifdef DOS_NT
return make_number (WEXITSTATUS (status));
}
\f
-static Lisp_Object
+static void
delete_temp_file (Lisp_Object name)
{
/* Suppress jka-compr handling, etc. */
internal_delete_file (name);
#endif
unbind_to (count, Qnil);
- return Qnil;
}
/* Create a temporary file suitable for storing the input data of
}
-static Lisp_Object
+static void
code_conversion_restore (Lisp_Object arg)
{
Lisp_Object current, workbuf;
}
set_buffer_internal (XBUFFER (current));
UNGCPRO;
- return Qnil;
}
Lisp_Object
#include <unistd.h>
#include <fcntl.h>
-static Lisp_Object
-fchdir_unwind (Lisp_Object dir_fd)
+static void
+fchdir_unwind (int dir_fd)
{
- (void) fchdir (XFASTINT (dir_fd));
- (void) close (XFASTINT (dir_fd));
- return Qnil;
+ (void) fchdir (dir_fd);
+ (void) close (dir_fd);
}
static void
if (old_cwd_fd == -1)
error ("could not open current directory: %s", strerror (errno));
- record_unwind_protect (fchdir_unwind, make_number (old_cwd_fd));
+ record_unwind_protect_int (fchdir_unwind, old_cwd_fd);
new_cwd = Funhandled_file_name_directory (
Fexpand_file_name (build_string ("."), Qnil));
}
#ifdef WINDOWSNT
-Lisp_Object
+void
directory_files_internal_w32_unwind (Lisp_Object arg)
{
Vw32_get_true_file_attributes = arg;
- return Qnil;
}
#endif
-static Lisp_Object
-directory_files_internal_unwind (Lisp_Object dh)
+static void
+directory_files_internal_unwind (void *dh)
{
- DIR *d = XSAVE_POINTER (dh, 0);
+ DIR *d = dh;
block_input ();
closedir (d);
unblock_input ();
- return Qnil;
}
/* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
/* Unfortunately, we can now invoke expand-file-name and
file-attributes on filenames, both of which can throw, so we must
do a proper unwind-protect. */
- record_unwind_protect (directory_files_internal_unwind,
- make_save_pointer (d));
+ record_unwind_protect_ptr (directory_files_internal_unwind, d);
#ifdef WINDOWSNT
if (attrs)
if (!d)
report_file_error ("Opening directory", dirname);
- record_unwind_protect (directory_files_internal_unwind,
- make_save_pointer (d));
+ record_unwind_protect_ptr (directory_files_internal_unwind, d);
/* Loop reading blocks */
/* (att3b compiler bug requires do a null comparison this way) */
/* Restore saved buffer before leaving `save-excursion' special form. */
-Lisp_Object
+void
save_excursion_restore (Lisp_Object info)
{
Lisp_Object tem, tem1, omark, nmark;
out:
free_misc (info);
- return Qnil;
}
DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
return make_number (0);
}
\f
-static Lisp_Object
+static void
subst_char_in_region_unwind (Lisp_Object arg)
{
bset_undo_list (current_buffer, arg);
- return arg;
}
-static Lisp_Object
+static void
subst_char_in_region_unwind_1 (Lisp_Object arg)
{
bset_filename (current_buffer, arg);
- return arg;
}
DEFUN ("subst-char-in-region", Fsubst_char_in_region,
}
}
-Lisp_Object
+void
save_restriction_restore (Lisp_Object data)
{
struct buffer *cur = NULL;
if (cur)
set_buffer_internal (cur);
-
- return Qnil;
}
DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
ptrdiff_t bufsize = sizeof initial_buffer;
ptrdiff_t max_bufsize = STRING_BYTES_BOUND + 1;
char *p;
- Lisp_Object buf_save_value IF_LINT (= {0});
+ ptrdiff_t buf_save_value_index IF_LINT (= 0);
char *format, *end, *format_start;
ptrdiff_t formatlen, nchars;
/* True if the format is multibyte. */
{
buf = xmalloc (bufsize);
sa_must_free = 1;
- buf_save_value = make_save_pointer (buf);
- record_unwind_protect (safe_alloca_unwind, buf_save_value);
+ buf_save_value_index = SPECPDL_INDEX ();
+ record_unwind_protect_ptr (xfree, buf);
memcpy (buf, initial_buffer, used);
}
else
{
buf = xrealloc (buf, bufsize);
- set_save_pointer (buf_save_value, 0, buf);
+ set_unwind_protect_ptr (buf_save_value_index, buf);
}
p = buf + used;
return pdl->unwind.arg;
}
-static specbinding_func
-specpdl_func (union specbinding *pdl)
-{
- eassert (pdl->kind == SPECPDL_UNWIND);
- return pdl->unwind.func;
-}
-
Lisp_Object
backtrace_function (union specbinding *pdl)
{
/* Unwind-protect function used by call_debugger. */
-static Lisp_Object
+static void
restore_stack_limits (Lisp_Object data)
{
max_specpdl_size = XINT (XCAR (data));
max_lisp_eval_depth = XINT (XCDR (data));
- return Qnil;
}
/* Call the Lisp debugger, giving it argument ARG. */
DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0,
doc: /* Eval BODY forms sequentially and return value of last one.
usage: (progn BODY...) */)
- (Lisp_Object args)
+ (Lisp_Object body)
{
- register Lisp_Object val = Qnil;
+ Lisp_Object val = Qnil;
struct gcpro gcpro1;
- GCPRO1 (args);
+ GCPRO1 (body);
- while (CONSP (args))
+ while (CONSP (body))
{
- val = eval_sub (XCAR (args));
- args = XCDR (args);
+ val = eval_sub (XCAR (body));
+ body = XCDR (body);
}
UNGCPRO;
return val;
}
+/* Evaluate BODY sequentually, discarding its value. Suitable for
+ record_unwind_protect. */
+
+void
+unwind_body (Lisp_Object body)
+{
+ Fprogn (body);
+}
+
DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0,
doc: /* Eval FIRST and BODY sequentially; return value from FIRST.
The value of FIRST is saved during the evaluation of the remaining args,
Lisp_Object val;
ptrdiff_t count = SPECPDL_INDEX ();
- record_unwind_protect (Fprogn, Fcdr (args));
+ record_unwind_protect (unwind_body, Fcdr (args));
val = eval_sub (Fcar (args));
return unbind_to (count, val);
}
Qnil);
}
-Lisp_Object
+void
un_autoload (Lisp_Object oldqueue)
{
- register Lisp_Object queue, first, second;
+ Lisp_Object queue, first, second;
/* Queue to unwind is current value of Vautoload_queue.
oldqueue is the shadowed value to leave in Vautoload_queue. */
Ffset (first, second);
queue = XCDR (queue);
}
- return Qnil;
}
/* Load an autoloaded function.
}
void
-record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg)
+record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg)
{
specpdl_ptr->unwind.kind = SPECPDL_UNWIND;
specpdl_ptr->unwind.func = function;
grow_specpdl ();
}
+void
+record_unwind_protect_ptr (void (*function) (void *), void *arg)
+{
+ specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR;
+ specpdl_ptr->unwind_ptr.func = function;
+ specpdl_ptr->unwind_ptr.arg = arg;
+ grow_specpdl ();
+}
+
+void
+record_unwind_protect_int (void (*function) (int), int arg)
+{
+ specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT;
+ specpdl_ptr->unwind_int.func = function;
+ specpdl_ptr->unwind_int.arg = arg;
+ grow_specpdl ();
+}
+
+void
+record_unwind_protect_void (void (*function) (void))
+{
+ specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID;
+ specpdl_ptr->unwind_void.func = function;
+ grow_specpdl ();
+}
+
Lisp_Object
unbind_to (ptrdiff_t count, Lisp_Object value)
{
switch (specpdl_ptr->kind)
{
case SPECPDL_UNWIND:
- specpdl_func (specpdl_ptr) (specpdl_arg (specpdl_ptr));
+ specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg);
+ break;
+ case SPECPDL_UNWIND_PTR:
+ specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg);
+ break;
+ case SPECPDL_UNWIND_INT:
+ specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg);
+ break;
+ case SPECPDL_UNWIND_VOID:
+ specpdl_ptr->unwind_void.func ();
break;
case SPECPDL_LET:
/* If variable has a trivial value (no forwarding), we can
report_file_errno (string, name, errno);
}
-Lisp_Object
-close_file_unwind (Lisp_Object fd)
+void
+close_file_unwind (int fd)
{
- emacs_close (XFASTINT (fd));
- return Qnil;
+ emacs_close (fd);
}
/* Restore point, having saved it as a marker. */
-Lisp_Object
+void
restore_point_unwind (Lisp_Object location)
{
Fgoto_char (location);
Fset_marker (location, Qnil, Qnil);
- return Qnil;
}
\f
if (ifd < 0)
report_file_error ("Opening input file", file);
- record_unwind_protect (close_file_unwind, make_number (ifd));
+ record_unwind_protect_int (close_file_unwind, ifd);
if (fstat (ifd, &st) != 0)
report_file_error ("Input file status", file);
if (ofd < 0)
report_file_error ("Opening output file", newname);
- record_unwind_protect (close_file_unwind, make_number (ofd));
+ record_unwind_protect_int (close_file_unwind, ofd);
immediate_quit = 1;
QUIT;
o remove all text properties.
o set back the buffer multibyteness. */
-static Lisp_Object
+static void
decide_coding_unwind (Lisp_Object unwind_data)
{
Lisp_Object multibyte, undo_list, buffer;
/* Now we are safe to change the buffer's multibyteness directly. */
bset_enable_multibyte_characters (current_buffer, multibyte);
bset_undo_list (current_buffer, undo_list);
-
- return Qnil;
}
/* Read from a non-regular file. STATE is a Lisp_Save_Value
if (!NILP (replace))
record_unwind_protect (restore_point_unwind, Fpoint_marker ());
- record_unwind_protect (close_file_unwind, make_number (fd));
+ record_unwind_protect_int (close_file_unwind, fd);
if (fstat (fd, &st) != 0)
report_file_error ("Input file status", orig_filename);
\f
static Lisp_Object build_annotations (Lisp_Object, Lisp_Object);
-static Lisp_Object
+static void
build_annotations_unwind (Lisp_Object arg)
{
Vwrite_region_annotation_buffers = arg;
- return Qnil;
}
/* Decide the coding-system to encode the data with. */
report_file_errno ("Opening output file", filename, open_errno);
}
- record_unwind_protect (close_file_unwind, make_number (desc));
+ record_unwind_protect_int (close_file_unwind, desc);
if (NUMBERP (append))
{
Qnil, Qnil);
}
-static Lisp_Object
-do_auto_save_unwind (Lisp_Object arg) /* used as unwind-protect function */
+struct auto_save_unwind
+{
+ FILE *stream;
+ bool auto_raise;
+};
+static void
+do_auto_save_unwind (void *arg)
{
- FILE *stream = XSAVE_POINTER (arg, 0);
+ struct auto_save_unwind *p = arg;
+ FILE *stream = p->stream;
+ minibuffer_auto_raise = p->auto_raise;
auto_saving = 0;
if (stream != NULL)
{
fclose (stream);
unblock_input ();
}
- return Qnil;
-}
-
-static Lisp_Object
-do_auto_save_unwind_1 (Lisp_Object value) /* used as unwind-protect function */
-
-{
- minibuffer_auto_raise = XINT (value);
- return Qnil;
}
static Lisp_Object
ptrdiff_t count = SPECPDL_INDEX ();
bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
bool old_message_p = 0;
+ struct auto_save_unwind auto_save_unwind;
struct gcpro gcpro1, gcpro2;
if (max_specpdl_size < specpdl_size + 40)
if (NILP (no_message))
{
old_message_p = push_message ();
- record_unwind_protect (pop_message_unwind, Qnil);
+ record_unwind_protect_void (pop_message_unwind);
}
/* Ordinarily don't quit within this function,
stream = emacs_fopen (SSDATA (listfile), "w");
}
- record_unwind_protect (do_auto_save_unwind,
- make_save_pointer (stream));
- record_unwind_protect (do_auto_save_unwind_1,
- make_number (minibuffer_auto_raise));
+ auto_save_unwind.stream = stream;
+ auto_save_unwind.auto_raise = minibuffer_auto_raise;
+ record_unwind_protect_ptr (do_auto_save_unwind, &auto_save_unwind);
minibuffer_auto_raise = 0;
auto_saving = 1;
auto_save_error_occurred = 0;
static Lisp_Object require_nesting_list;
-static Lisp_Object
+static void
require_unwind (Lisp_Object old_value)
{
- return require_nesting_list = old_value;
+ require_nesting_list = old_value;
}
DEFUN ("require", Frequire, Srequire, 1, 3, 0,
/* Destroy the dialog. This makes it pop down. */
-static Lisp_Object
-pop_down_dialog (Lisp_Object arg)
+static void
+pop_down_dialog (void *arg)
{
- struct xg_dialog_data *dd = XSAVE_POINTER (arg, 0);
+ struct xg_dialog_data *dd = arg;
block_input ();
if (dd->w) gtk_widget_destroy (dd->w);
g_main_loop_unref (dd->loop);
unblock_input ();
-
- return Qnil;
}
/* If there are any emacs timers pending, add a timeout to main loop in DATA.
g_signal_connect (G_OBJECT (w), "delete-event", G_CALLBACK (gtk_true), NULL);
gtk_widget_show (w);
- record_unwind_protect (pop_down_dialog, make_save_pointer (&dd));
+ record_unwind_protect_ptr (pop_down_dialog, &dd);
(void) xg_maybe_add_timer (&dd);
g_main_loop_run (dd.loop);
VARIABLE is the variable to maybe set to nil.
NO-ERROR-FLAG is nil if there was an error,
anything else meaning no error (so this function does nothing). */
-static Lisp_Object
-reset_var_on_error (Lisp_Object val)
+struct rvoe_arg
{
- if (NILP (XCDR (val)))
- Fset (XCAR (val), Qnil);
- return Qnil;
+ Lisp_Object *location;
+ bool errorp;
+};
+
+static void
+reset_var_on_error (void *ptr)
+{
+ struct rvoe_arg *p = ptr;
+ if (p->errorp)
+ *p->location = Qnil;
}
/* Signal a change to the buffer immediately before it happens.
Lisp_Object preserve_marker;
struct gcpro gcpro1, gcpro2, gcpro3;
ptrdiff_t count = SPECPDL_INDEX ();
+ struct rvoe_arg rvoe_arg;
if (inhibit_modification_hooks)
return;
if (!NILP (Vbefore_change_functions))
{
Lisp_Object args[3];
- Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
+ rvoe_arg.location = &Vbefore_change_functions;
+ rvoe_arg.errorp = 1;
PRESERVE_VALUE;
PRESERVE_START_END;
/* Mark before-change-functions to be reset to nil in case of error. */
- record_unwind_protect (reset_var_on_error, rvoe_arg);
+ record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg);
/* Actually run the hook functions. */
args[0] = Qbefore_change_functions;
Frun_hook_with_args (3, args);
/* There was no error: unarm the reset_on_error. */
- XSETCDR (rvoe_arg, Qt);
+ rvoe_arg.errorp = 0;
}
if (buffer_has_overlays ())
signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
{
ptrdiff_t count = SPECPDL_INDEX ();
+ struct rvoe_arg rvoe_arg;
+
if (inhibit_modification_hooks)
return;
if (!NILP (Vafter_change_functions))
{
Lisp_Object args[4];
- Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
+ rvoe_arg.location = &Vafter_change_functions;
+ rvoe_arg.errorp = 1;
/* Mark after-change-functions to be reset to nil in case of error. */
- record_unwind_protect (reset_var_on_error, rvoe_arg);
+ record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg);
/* Actually run the hook functions. */
args[0] = Qafter_change_functions;
Frun_hook_with_args (4, args);
/* There was no error: unarm the reset_on_error. */
- XSETCDR (rvoe_arg, Qt);
+ rvoe_arg.errorp = 0;
}
if (buffer_has_overlays ())
unbind_to (count, Qnil);
}
-static Lisp_Object
+static void
Fcombine_after_change_execute_1 (Lisp_Object val)
{
Vcombine_after_change_calls = val;
- return val;
}
DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
static Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
-static Lisp_Object recursive_edit_unwind (Lisp_Object buffer);
+static void recursive_edit_unwind (Lisp_Object buffer);
static Lisp_Object command_loop (void);
static Lisp_Object Qcommand_execute;
EMACS_TIME timer_check (void);
static void restore_getcjmp (sys_jmp_buf);
static Lisp_Object apply_modifiers (int, Lisp_Object);
static void clear_event (struct input_event *);
-static Lisp_Object restore_kboard_configuration (Lisp_Object);
+static void restore_kboard_configuration (int);
#ifdef USABLE_SIGIO
static void deliver_input_available_signal (int signo);
#endif
return unbind_to (count, Qnil);
}
-Lisp_Object
+void
recursive_edit_unwind (Lisp_Object buffer)
{
if (BUFFERP (buffer))
command_loop_level--;
update_mode_lines = 1;
- return Qnil;
}
\f
from which further input is accepted. If F is non-nil, set its
KBOARD as the current keyboard.
- This function uses record_unwind_protect to return to the previous
+ This function uses record_unwind_protect_int to return to the previous
state later.
If Emacs is already in single_kboard mode, and F's keyboard is
else if (f != NULL)
current_kboard = FRAME_KBOARD (f);
single_kboard = 1;
- record_unwind_protect (restore_kboard_configuration,
- (was_locked ? Qt : Qnil));
+ record_unwind_protect_int (restore_kboard_configuration, was_locked);
}
#if 0 /* This function is not needed anymore. */
{
if (single_kboard)
push_kboard (current_kboard);
- record_unwind_protect (restore_kboard_configuration,
- (single_kboard ? Qt : Qnil));
+ record_unwind_protect_int (restore_kboard_configuration, single_kboard);
}
#endif
-static Lisp_Object
-restore_kboard_configuration (Lisp_Object was_locked)
+static void
+restore_kboard_configuration (int was_locked)
{
- if (NILP (was_locked))
- single_kboard = 0;
- else
+ single_kboard = was_locked;
+ if (was_locked)
{
struct kboard *prev = current_kboard;
- single_kboard = 1;
pop_kboard ();
/* The pop should not change the kboard. */
if (single_kboard && current_kboard != prev)
emacs_abort ();
}
- return Qnil;
}
\f
/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
of this function. */
-static Lisp_Object
+static void
tracking_off (Lisp_Object old_value)
{
do_mouse_tracking = old_value;
get_input_pending (READABLE_EVENTS_DO_TIMERS_NOW);
}
}
- return Qnil;
}
DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0,
void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (ptrdiff_t, bool);
-/* Cancel hourglass from protect_unwind.
- ARG is not used. */
-#ifdef HAVE_WINDOW_SYSTEM
-static Lisp_Object
-cancel_hourglass_unwind (Lisp_Object arg)
-{
- cancel_hourglass ();
- return Qnil;
-}
-#endif
-
/* The last boundary auto-added to buffer-undo-list. */
Lisp_Object last_undo_boundary;
if (display_hourglass_p
&& NILP (Vexecuting_kbd_macro))
{
- record_unwind_protect (cancel_hourglass_unwind, Qnil);
+ record_unwind_protect_void (cancel_hourglass);
start_hourglass ();
}
#endif
static void record_char (Lisp_Object c);
static Lisp_Object help_form_saved_window_configs;
-static Lisp_Object
-read_char_help_form_unwind (Lisp_Object arg)
+static void
+read_char_help_form_unwind (void)
{
Lisp_Object window_config = XCAR (help_form_saved_window_configs);
help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
if (!NILP (window_config))
Fset_window_configuration (window_config);
- return Qnil;
}
#define STOP_POLLING \
help_form_saved_window_configs
= Fcons (Fcurrent_window_configuration (Qnil),
help_form_saved_window_configs);
- record_unwind_protect (read_char_help_form_unwind, Qnil);
+ record_unwind_protect_void (read_char_help_form_unwind);
call0 (Qhelp_form_show);
cancel_echoing ();
reset_all_sys_modes ();
/* sys_suspend can get an error if it tries to fork a subshell
and the system resources aren't available for that. */
- record_unwind_protect ((Lisp_Object (*) (Lisp_Object)) init_all_sys_modes,
- Qnil);
+ record_unwind_protect_void (init_all_sys_modes);
stuff_buffered_input (stuffstring);
if (cannot_suspend)
sys_subshell ();
MENU_ITEMS_ITEM_LENGTH
};
-extern Lisp_Object unuse_menu_items (Lisp_Object dummy);
+extern void unuse_menu_items (void);
/* This is how to deal with multibyte text if HAVE_MULTILINGUAL_MENU
isn't defined. The use of HAVE_MULTILINGUAL_MENU could probably be
/* Special object used to hold a different values for later use.
This is mostly used to package C integers and pointers to call
- record_unwind_protect. A typical task is to pass just one C object
- pointer to the unwind function. You should pack an object pointer with
- make_save_pointer and then get it back with XSAVE_POINTER, e.g.:
-
- ...
- struct my_data *md = get_my_data ();
- record_unwind_protect (my_unwind, make_save_pointer (md));
- ...
-
- Lisp_Object my_unwind (Lisp_Object arg)
- {
- struct my_data *md = XSAVE_POINTER (arg, 0);
- ...
- }
-
- If you need to pass something else you can use make_save_value,
- which allows you to pack up to SAVE_VALUE_SLOTS integers, pointers,
+ record_unwind_protect when two or more values need to be saved.
+ make_save_value lets you pack up to SAVE_VALUE_SLOTS integers, pointers,
function pointers or Lisp_Objects and conveniently get them back
with XSAVE_INTEGER, XSAVE_POINTER, XSAVE_FUNCPOINTER, and
XSAVE_OBJECT macros:
used all over the place, needs to be fast, and needs to know the size of
union specbinding. But only eval.c should access it. */
-typedef Lisp_Object (*specbinding_func) (Lisp_Object);
-
enum specbind_tag {
- SPECPDL_UNWIND, /* An unwind_protect function. */
+ SPECPDL_UNWIND, /* An unwind_protect function on Lisp_Object. */
+ SPECPDL_UNWIND_PTR, /* Likewise, on void *. */
+ SPECPDL_UNWIND_INT, /* Likewise, on int. */
+ SPECPDL_UNWIND_VOID, /* Likewise, with no arg. */
SPECPDL_BACKTRACE, /* An element of the backtrace. */
SPECPDL_LET, /* A plain and simple dynamic let-binding. */
/* Tags greater than SPECPDL_LET must be "subkinds" of LET. */
ENUM_BF (specbind_tag) kind : CHAR_BIT;
struct {
ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ void (*func) (Lisp_Object);
Lisp_Object arg;
- specbinding_func func;
} unwind;
+ struct {
+ ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ void (*func) (void *);
+ void *arg;
+ } unwind_ptr;
+ struct {
+ ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ void (*func) (int);
+ int arg;
+ } unwind_int;
+ struct {
+ ENUM_BF (specbind_tag) kind : CHAR_BIT;
+ void (*func) (void);
+ } unwind_void;
struct {
ENUM_BF (specbind_tag) kind : CHAR_BIT;
/* `where' is not used in the case of SPECPDL_LET. */
return specpdl_ptr - specpdl;
}
+LISP_INLINE void
+set_unwind_protect_ptr (ptrdiff_t count, void *arg)
+{
+ specpdl[count].unwind_ptr.arg = arg;
+}
+
/* Everything needed to describe an active condition case.
Members are volatile if their values need to survive _longjmp when
extern void check_message_stack (void);
extern void setup_echo_area_for_printing (int);
extern bool push_message (void);
-extern Lisp_Object pop_message_unwind (Lisp_Object);
+extern void pop_message_unwind (void);
extern Lisp_Object restore_message_unwind (Lisp_Object);
extern void restore_message (void);
extern Lisp_Object current_message (void);
extern ptrdiff_t inhibit_garbage_collection (void);
extern Lisp_Object make_save_value (enum Lisp_Save_Type, ...);
extern Lisp_Object make_save_pointer (void *);
+extern void free_save_value (Lisp_Object);
extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
extern void free_marker (Lisp_Object);
extern void free_cons (struct Lisp_Cons *);
(Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
extern void specbind (Lisp_Object, Lisp_Object);
-extern void record_unwind_protect (Lisp_Object (*) (Lisp_Object), Lisp_Object);
+extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
+extern void record_unwind_protect_int (void (*) (int), int);
+extern void record_unwind_protect_ptr (void (*) (void *), void *);
+extern void record_unwind_protect_void (void (*) (void));
extern Lisp_Object unbind_to (ptrdiff_t, Lisp_Object);
extern _Noreturn void error (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
extern _Noreturn void verror (const char *, va_list)
ATTRIBUTE_FORMAT_PRINTF (1, 0);
-extern Lisp_Object un_autoload (Lisp_Object);
+extern void un_autoload (Lisp_Object);
extern Lisp_Object call_debugger (Lisp_Object arg);
extern void init_eval_once (void);
extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
extern Lisp_Object safe_call2 (Lisp_Object, Lisp_Object, Lisp_Object);
extern void init_eval (void);
extern void syms_of_eval (void);
+extern void unwind_body (Lisp_Object);
extern void record_in_backtrace (Lisp_Object function,
Lisp_Object *args, ptrdiff_t nargs);
extern void mark_specpdl (void);
extern Lisp_Object format2 (const char *, Lisp_Object, Lisp_Object);
extern Lisp_Object save_excursion_save (void);
extern Lisp_Object save_restriction_save (void);
-extern Lisp_Object save_excursion_restore (Lisp_Object);
-extern Lisp_Object save_restriction_restore (Lisp_Object);
+extern void save_excursion_restore (Lisp_Object);
+extern void save_restriction_restore (Lisp_Object);
extern _Noreturn void time_overflow (void);
extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
Lisp_Object, Lisp_Object, Lisp_Object);
extern bool overlay_touches_p (ptrdiff_t);
extern Lisp_Object Vbuffer_alist;
-extern Lisp_Object set_buffer_if_live (Lisp_Object);
extern Lisp_Object other_buffer_safely (Lisp_Object);
extern Lisp_Object Qpriority, Qwindow, Qbefore_string, Qafter_string;
extern Lisp_Object get_truename_buffer (Lisp_Object);
extern Lisp_Object Qfile_name_history;
extern Lisp_Object expand_and_dir_to_file (Lisp_Object, Lisp_Object);
EXFUN (Fread_file_name, 6); /* Not a normal DEFUN. */
-extern Lisp_Object close_file_unwind (Lisp_Object);
-extern Lisp_Object restore_point_unwind (Lisp_Object);
+extern void close_file_unwind (int);
+extern void restore_point_unwind (Lisp_Object);
extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
extern _Noreturn void report_file_error (const char *, Lisp_Object);
extern bool internal_delete_file (Lisp_Object);
enum MAX_ALLOCA { MAX_ALLOCA = 16 * 1024 };
-extern Lisp_Object safe_alloca_unwind (Lisp_Object);
extern void *record_xmalloc (size_t);
#define USE_SAFE_ALLOCA \
{ \
(buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
sa_must_free = 1; \
- record_unwind_protect (safe_alloca_unwind, \
- make_save_pointer (buf)); \
+ record_unwind_protect_ptr (xfree, buf); \
} \
} while (0)
buf = xmalloc ((nelt) * word_size); \
arg_ = make_save_value (SAVE_TYPE_MEMORY, buf, nelt); \
sa_must_free = 1; \
- record_unwind_protect (safe_alloca_unwind, arg_); \
+ record_unwind_protect (free_save_value, arg_); \
} \
else \
memory_full (SIZE_MAX); \
static void readevalloop (Lisp_Object, FILE *, Lisp_Object, bool,
Lisp_Object, Lisp_Object,
Lisp_Object, Lisp_Object);
-static Lisp_Object load_unwind (Lisp_Object);
+static void load_unwind (void *);
\f
/* Functions that read one byte from the current source READCHARFUN
or unreads one byte. If the integer argument C is -1, it returns
/* Callback for record_unwind_protect. Restore the old load list OLD,
after loading a file successfully. */
-static Lisp_Object
+static void
record_load_unwind (Lisp_Object old)
{
- return Vloads_in_progress = old;
+ Vloads_in_progress = old;
}
/* This handler function is used via internal_condition_case_1. */
return Qnil;
}
-static Lisp_Object
+static void
load_warn_old_style_backquotes (Lisp_Object file)
{
if (!NILP (Vold_style_backquotes))
args[1] = file;
Fmessage (2, args);
}
- return Qnil;
}
DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0,
message_with_string ("Loading %s...", file, 1);
}
- record_unwind_protect (load_unwind, make_save_pointer (stream));
+ record_unwind_protect_ptr (load_unwind, stream);
specbind (Qload_file_name, found);
specbind (Qinhibit_file_name_operation, Qnil);
specbind (Qload_in_progress, Qt);
return Qt;
}
-static Lisp_Object
-load_unwind (Lisp_Object arg) /* Used as unwind-protect function in load. */
+static void
+load_unwind (void *arg)
{
- FILE *stream = XSAVE_POINTER (arg, 0);
+ FILE *stream = arg;
if (stream != NULL)
{
block_input ();
fclose (stream);
unblock_input ();
}
- return Qnil;
}
\f
static bool
Vload_history);
}
-static Lisp_Object
-readevalloop_1 (Lisp_Object old)
+static void
+readevalloop_1 (int old)
{
- load_convert_to_unibyte = ! NILP (old);
- return Qnil;
+ load_convert_to_unibyte = old;
}
/* Signal an `end-of-file' error, if possible with file name
specbind (Qstandard_input, readcharfun); /* GCPROs readcharfun. */
specbind (Qcurrent_load_list, Qnil);
- record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil);
+ record_unwind_protect_int (readevalloop_1, load_convert_to_unibyte);
load_convert_to_unibyte = !NILP (unibyte);
/* If lexical binding is active (either because it was specified in
/* Restore Vexecuting_kbd_macro and executing_kbd_macro_index.
Called when the unwind-protect in Fexecute_kbd_macro gets invoked. */
-static Lisp_Object
+static void
pop_kbd_macro (Lisp_Object info)
{
Lisp_Object tem;
executing_kbd_macro_index = XINT (XCAR (tem));
Vreal_this_command = XCDR (tem);
Frun_hooks (1, &Qkbd_macro_termination_hook);
- return Qnil;
}
DEFUN ("execute-kbd-macro", Fexecute_kbd_macro, Sexecute_kbd_macro, 1, 3, 0,
{
}
-Lisp_Object
-unuse_menu_items (Lisp_Object dummy)
+void
+unuse_menu_items (void)
{
- return menu_items_inuse = Qnil;
+ menu_items_inuse = Qnil;
}
/* Call when finished using the data for the current menu
eassert (NILP (menu_items_inuse));
}
-#ifdef HAVE_NS
-static Lisp_Object
-cleanup_popup_menu (Lisp_Object arg)
-{
- discard_menu_items ();
- return Qnil;
-}
-#endif
-
/* This undoes save_menu_items, and it is called by the specpdl unwind
mechanism. */
-static Lisp_Object
+static void
restore_menu_items (Lisp_Object saved)
{
menu_items = XCAR (saved);
menu_items_n_panes = XINT (XCAR (saved));
saved = XCDR (saved);
menu_items_submenu_depth = XINT (XCAR (saved));
- return Qnil;
}
/* Push the whole state of menu_items processing onto the specpdl.
#endif /* HAVE_MENUS */
/* Now parse the lisp menus. */
- record_unwind_protect (unuse_menu_items, Qnil);
+ record_unwind_protect_void (unuse_menu_items);
title = Qnil;
GCPRO1 (title);
#endif
#ifdef HAVE_NS /* FIXME: ns-specific, why? --Stef */
- record_unwind_protect (cleanup_popup_menu, Qnil);
+ record_unwind_protect_void (discard_menu_items);
#endif
/* Display them in a menu. */
}
}
-static Lisp_Object
-choose_minibuf_frame_1 (Lisp_Object ignore)
-{
- choose_minibuf_frame ();
- return Qnil;
-}
-
DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
Sactive_minibuffer_window, 0, 0, 0,
doc: /* Return the currently active minibuffer window, or nil if none. */)
\f
/* Actual minibuffer invocation. */
-static Lisp_Object read_minibuf_unwind (Lisp_Object);
-static Lisp_Object run_exit_minibuf_hook (Lisp_Object);
+static void read_minibuf_unwind (void);
+static void run_exit_minibuf_hook (void);
/* Read a Lisp object from VAL and return it. If VAL is an empty
/* Prepare for restoring the current buffer since choose_minibuf_frame
calling Fset_frame_selected_window may change it (Bug#12766). */
- record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ record_unwind_protect (restore_buffer, Fcurrent_buffer ());
choose_minibuf_frame ();
- record_unwind_protect (choose_minibuf_frame_1, Qnil);
+ record_unwind_protect_void (choose_minibuf_frame);
- record_unwind_protect (Fset_window_configuration,
+ record_unwind_protect (restore_window_configuration,
Fcurrent_window_configuration (Qnil));
/* If the minibuffer window is on a different frame, save that
frame's configuration too. */
mini_frame = WINDOW_FRAME (XWINDOW (minibuf_window));
if (!EQ (mini_frame, selected_frame))
- record_unwind_protect (Fset_window_configuration,
+ record_unwind_protect (restore_window_configuration,
Fcurrent_window_configuration (mini_frame));
/* If the minibuffer is on an iconified or invisible frame,
Fcons (Vminibuffer_history_variable,
minibuf_save_list))))));
- record_unwind_protect (read_minibuf_unwind, Qnil);
+ record_unwind_protect_void (read_minibuf_unwind);
minibuf_level++;
/* We are exiting the minibuffer one way or the other, so run the hook.
It should be run before unwinding the minibuf settings. Do it
separately from read_minibuf_unwind because we need to make sure that
read_minibuf_unwind is fully executed even if exit-minibuffer-hook
signals an error. --Stef */
- record_unwind_protect (run_exit_minibuf_hook, Qnil);
+ record_unwind_protect_void (run_exit_minibuf_hook);
/* Now that we can restore all those variables, start changing them. */
return buf;
}
-static Lisp_Object
-run_exit_minibuf_hook (Lisp_Object data)
+static void
+run_exit_minibuf_hook (void)
{
safe_run_hooks (Qminibuffer_exit_hook);
- return Qnil;
}
/* This function is called on exiting minibuffer, whether normally or
not, and it restores the current window, buffer, etc. */
-static Lisp_Object
-read_minibuf_unwind (Lisp_Object data)
+static void
+read_minibuf_unwind (void)
{
Lisp_Object old_deactivate_mark;
Lisp_Object window;
to make sure we don't leave around bindings and stuff which only
made sense during the read_minibuf invocation. */
call0 (intern ("minibuffer-inactive-mode"));
- return Qnil;
}
\f
/* Handler for signals raised during x_create_frame.
FRAME is the frame which is partially constructed. */
-static Lisp_Object
+static void
unwind_create_frame (Lisp_Object frame)
{
struct frame *f = XFRAME (frame);
display is disconnected after the frame has become official, but
before x_create_frame removes the unwind protect. */
if (!FRAME_LIVE_P (f))
- return Qnil;
+ return;
/* If frame is ``official'', nothing to do. */
if (NILP (Fmemq (frame, Vframe_list)))
/* Check that reference counts are indeed correct. */
eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount);
#endif
- return Qt;
}
-
- return Qnil;
}
/*
EmacsDialogPanel *dialog;
};
-static Lisp_Object
-pop_down_menu (Lisp_Object arg)
+static void
+pop_down_menu (void *arg)
{
- struct Popdown_data *unwind_data = XSAVE_POINTER (arg, 0);
+ struct Popdown_data *unwind_data = arg;
block_input ();
if (popup_activated_flag)
xfree (unwind_data);
unblock_input ();
-
- return Qnil;
}
unwind_data->pool = pool;
unwind_data->dialog = dialog;
- record_unwind_protect (pop_down_menu, make_save_pointer (unwind_data));
+ record_unwind_protect_ptr (pop_down_menu, unwind_data);
popup_activated_flag = 1;
tem = [dialog runDialogAt: p];
unbind_to (specpdl_count, Qnil); /* calls pop_down_menu */
/* This is used to restore the saved contents of print_buffer
when there is a recursive call to print. */
-static Lisp_Object
+static void
print_unwind (Lisp_Object saved_text)
{
memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text));
- return Qnil;
}
\f
/* Starting asynchronous inferior processes. */
-static Lisp_Object start_process_unwind (Lisp_Object proc);
+static void start_process_unwind (Lisp_Object proc);
DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
doc: /* Start a program in a subprocess. Return the process object for it.
PROC doesn't have its pid set, then we know someone has signaled
an error and the process wasn't started successfully, so we should
remove it from the process list. */
-static Lisp_Object
+static void
start_process_unwind (Lisp_Object proc)
{
if (!PROCESSP (proc))
-2 is used for a pty with no process, eg for gdb. */
if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2)
remove_process (proc);
-
- return Qnil;
}
static void
return Qnil;
}
-/* Used by make-serial-process to recover from errors. */
-static Lisp_Object
-make_serial_process_unwind (Lisp_Object proc)
-{
- if (!PROCESSP (proc))
- emacs_abort ();
- remove_process (proc);
- return Qnil;
-}
-
DEFUN ("make-serial-process", Fmake_serial_process, Smake_serial_process,
0, MANY, 0,
doc: /* Create and return a serial port process.
CHECK_STRING (name);
proc = make_process (name);
specpdl_count = SPECPDL_INDEX ();
- record_unwind_protect (make_serial_process_unwind, proc);
+ record_unwind_protect (remove_process, proc);
p = XPROCESS (proc);
fd = serial_open (port);
#ifdef POLL_FOR_INPUT
if (socktype != SOCK_DGRAM)
{
- record_unwind_protect (unwind_stop_other_atimers, Qnil);
+ record_unwind_protect_void (run_all_atimers);
bind_polling_period (10);
}
#endif
#endif
/* Make us close S if quit. */
- record_unwind_protect (close_file_unwind, make_number (s));
+ record_unwind_protect_int (close_file_unwind, s);
/* Parse network options in the arg list.
We simply ignore anything which isn't a known option (including other keywords).
when not inside wait_reading_process_output. */
static int waiting_for_user_input_p;
-static Lisp_Object
-wait_reading_process_output_unwind (Lisp_Object data)
+static void
+wait_reading_process_output_unwind (int data)
{
- waiting_for_user_input_p = XINT (data);
- return Qnil;
+ waiting_for_user_input_p = data;
}
/* This is here so breakpoints can be put on it. */
if (wait_proc != NULL)
wait_channel = wait_proc->infd;
- record_unwind_protect (wait_reading_process_output_unwind,
- make_number (waiting_for_user_input_p));
+ record_unwind_protect_int (wait_reading_process_output_unwind,
+ waiting_for_user_input_p);
waiting_for_user_input_p = read_kbd;
if (time_limit < 0)
}
}
-static Lisp_Object
+static void
unwind_set_match_data (Lisp_Object list)
{
/* It is NOT ALWAYS safe to free (evaporate) the markers immediately. */
- return Fset_match_data (list, Qt);
+ Fset_match_data (list, Qt);
}
/* Called to unwind protect the match data. */
}
-/* Function installed by play-sound-internal with record_unwind_protect. */
+/* Function installed by play-sound-internal with record_unwind_protect_void. */
-static Lisp_Object
-sound_cleanup (Lisp_Object arg)
+static void
+sound_cleanup (void)
{
if (current_sound_device->close)
current_sound_device->close (current_sound_device);
emacs_close (current_sound->fd);
xfree (current_sound_device);
xfree (current_sound);
-
- return Qnil;
}
/***********************************************************************
GCPRO2 (sound, file);
current_sound_device = xzalloc (sizeof *current_sound_device);
current_sound = xzalloc (sizeof *current_sound);
- record_unwind_protect (sound_cleanup, Qnil);
+ record_unwind_protect_void (sound_cleanup);
current_sound->header = alloca (MAX_SOUND_HEADER_BYTES);
if (STRINGP (attrs[SOUND_FILE]))
return Qnil;
}
+static void
+do_unwind_create_frame (Lisp_Object frame)
+{
+ unwind_create_frame (frame);
+}
+
static void
x_default_font_parameter (struct frame *f, Lisp_Object parms)
{
/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
/* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
- record_unwind_protect (unwind_create_frame, frame);
+ record_unwind_protect (do_unwind_create_frame, frame);
#ifdef GLYPH_DEBUG
image_cache_refcount =
FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
Lisp_Object last_show_tip_args;
-static Lisp_Object
+static void
unwind_create_tip_frame (Lisp_Object frame)
{
Lisp_Object deleted;
tip_window = NULL;
tip_frame = Qnil;
}
-
- return deleted;
}
call0 (XCAR (funs));
}
-static Lisp_Object
+static void
select_window_norecord (Lisp_Object window)
{
- return WINDOW_LIVE_P (window)
- ? Fselect_window (window, Qt) : selected_window;
+ if (WINDOW_LIVE_P (window))
+ Fselect_window (window, Qt);
}
-static Lisp_Object
+static void
select_frame_norecord (Lisp_Object frame)
{
- return FRAME_LIVE_P (XFRAME (frame))
- ? Fselect_frame (frame, Qt) : selected_frame;
+ if (FRAME_LIVE_P (XFRAME (frame)))
+ Fselect_frame (frame, Qt);
}
void
Note: Both Fselect_window and select_window_norecord may
set-buffer to the buffer displayed in the window,
so we need to save the current buffer. --stef */
- record_unwind_protect (Fset_buffer, prev_buffer);
+ record_unwind_protect (restore_buffer, prev_buffer);
record_unwind_protect (select_window_norecord, prev_window);
Fselect_window (window, Qt);
Fset_buffer (w->contents);
return (FRAME_LIVE_P (f) ? Qt : Qnil);
}
+void
+restore_window_configuration (Lisp_Object configuration)
+{
+ Fset_window_configuration (configuration);
+}
+
/* If WINDOW is an internal window, recursively delete all child windows
reachable via the next and contents slots of WINDOW. Otherwise setup
extern Lisp_Object window_from_coordinates (struct frame *, int, int,
enum window_part *, bool);
extern void resize_frame_windows (struct frame *, int, bool);
+extern void restore_window_configuration (Lisp_Object);
extern void delete_all_child_windows (Lisp_Object);
extern void freeze_window_starts (struct frame *, bool);
extern void grow_mini_window (struct window *, int);
static void handle_stop_backwards (struct it *, ptrdiff_t);
static void vmessage (const char *, va_list) ATTRIBUTE_FORMAT_PRINTF (1, 0);
static void ensure_echo_area_buffers (void);
-static Lisp_Object unwind_with_echo_area_buffer (Lisp_Object);
+static void unwind_with_echo_area_buffer (Lisp_Object);
static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
static int with_echo_area_buffer (struct window *, int,
int (*) (ptrdiff_t, Lisp_Object),
ptrdiff_t, Lisp_Object);
static void clear_garbaged_frames (void);
static int current_message_1 (ptrdiff_t, Lisp_Object);
-static void pop_message (void);
static int truncate_message_1 (ptrdiff_t, Lisp_Object);
static void set_message (Lisp_Object);
static int set_message_1 (ptrdiff_t, Lisp_Object);
static int display_echo_area (struct window *);
static int display_echo_area_1 (ptrdiff_t, Lisp_Object);
static int resize_mini_window_1 (ptrdiff_t, Lisp_Object);
-static Lisp_Object unwind_redisplay (Lisp_Object);
+static void unwind_redisplay (void);
static int string_char_and_length (const unsigned char *, int *);
static struct text_pos display_prop_end (struct it *, Lisp_Object,
struct text_pos);
/* Restore global state from VECTOR which was created by
with_echo_area_buffer_unwind_data. */
-static Lisp_Object
+static void
unwind_with_echo_area_buffer (Lisp_Object vector)
{
set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
}
Vwith_echo_area_save_vector = vector;
- return Qnil;
}
}
-/* Handler for record_unwind_protect calling pop_message. */
-
-Lisp_Object
-pop_message_unwind (Lisp_Object dummy)
-{
- pop_message ();
- return Qnil;
-}
-
-/* Pop the top-most entry off Vmessage_stack. */
+/* Handler for unwind-protect calling pop_message. */
-static void
-pop_message (void)
+void
+pop_message_unwind (void)
{
+ /* Pop the top-most entry off Vmessage_stack. */
eassert (CONSP (Vmessage_stack));
Vmessage_stack = XCDR (Vmessage_stack);
}
return vector;
}
-static Lisp_Object
+static void
unwind_format_mode_line (Lisp_Object vector)
{
Lisp_Object old_window = AREF (vector, 7);
}
Vmode_line_unwind_vector = vector;
- return Qnil;
}
do_switch_frame.
FIXME: Maybe do_switch_frame should be trimmed down similarly
when `norecord' is set. */
-static Lisp_Object
+static void
fast_set_selected_frame (Lisp_Object frame)
{
if (!EQ (selected_frame, frame))
selected_frame = frame;
selected_window = XFRAME (frame)->selected_window;
}
- return Qnil;
}
/* Update the tool-bar item list for frame F. This has to be done
/* Record a function that clears redisplaying_p
when we leave this function. */
count = SPECPDL_INDEX ();
- record_unwind_protect (unwind_redisplay, selected_frame);
+ record_unwind_protect_void (unwind_redisplay);
redisplaying_p = 1;
specbind (Qinhibit_free_realized_faces, Qnil);
}
-/* Function registered with record_unwind_protect in redisplay_internal.
- Clear redisplaying_p. Also select the previously selected frame. */
+/* Function registered with record_unwind_protect in redisplay_internal. */
-static Lisp_Object
-unwind_redisplay (Lisp_Object old_frame)
+static void
+unwind_redisplay (void)
{
redisplaying_p = 0;
- return Qnil;
}
return Qnil;
}
-static Lisp_Object
+static void
+do_unwind_create_frame (Lisp_Object frame)
+{
+ unwind_create_frame (frame);
+}
+
+static void
unwind_create_frame_1 (Lisp_Object val)
{
inhibit_lisp_code = val;
- return Qnil;
}
static void
FRAME_X_DISPLAY_INFO (f) = dpyinfo;
/* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
- record_unwind_protect (unwind_create_frame, frame);
+ record_unwind_protect (do_unwind_create_frame, frame);
/* These colors will be set anyway later, but it's important
to get the color reference counts right, so initialize them! */
static Lisp_Object last_show_tip_args;
-static Lisp_Object
+static void
unwind_create_tip_frame (Lisp_Object frame)
{
Lisp_Object deleted;
tip_window = None;
tip_frame = Qnil;
}
-
- return deleted;
}
*result = XmCR_CANCEL;
}
-static Lisp_Object
-clean_up_file_dialog (Lisp_Object arg)
+static void
+clean_up_file_dialog (void *arg)
{
- Widget dialog = XSAVE_POINTER (arg, 0);
+ Widget dialog = arg;
/* Clean up. */
block_input ();
XtDestroyWidget (dialog);
x_menu_set_in_use (0);
unblock_input ();
-
- return Qnil;
}
XmStringFree (default_xmstring);
}
- record_unwind_protect (clean_up_file_dialog, make_save_pointer (dialog));
+ record_unwind_protect_ptr (clean_up_file_dialog, dialog);
/* Process events until the user presses Cancel or OK. */
x_menu_set_in_use (1);
#ifdef USE_GTK
-static Lisp_Object
-clean_up_dialog (Lisp_Object arg)
+static void
+clean_up_dialog (void)
{
x_menu_set_in_use (0);
-
- return Qnil;
}
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 5, 0,
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
- record_unwind_protect (clean_up_dialog, Qnil);
+ record_unwind_protect_void (clean_up_dialog);
block_input ();
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
- record_unwind_protect (clean_up_dialog, Qnil);
+ record_unwind_protect_void (clean_up_dialog);
block_input ();
/* Decode the dialog items from what was specified. */
title = Fcar (contents);
CHECK_STRING (title);
- record_unwind_protect (unuse_menu_items, Qnil);
+ record_unwind_protect_void (unuse_menu_items);
if (NILP (Fcar (Fcdr (contents))))
/* No buttons specified, add an "Ok" button so users can pop down
if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data;
}
-static Lisp_Object
-pop_down_menu (Lisp_Object arg)
+static void
+pop_down_menu (void *arg)
{
popup_activated_flag = 0;
block_input ();
- gtk_widget_destroy (GTK_WIDGET (XSAVE_POINTER (arg, 0)));
+ gtk_widget_destroy (GTK_WIDGET (arg));
unblock_input ();
- return Qnil;
}
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i,
timestamp ? timestamp : gtk_get_current_event_time ());
- record_unwind_protect (pop_down_menu, make_save_pointer (menu));
+ record_unwind_protect_ptr (pop_down_menu, menu);
if (gtk_widget_get_mapped (menu))
{
/* ARG is the LWLIB ID of the dialog box, represented
as a Lisp object as (HIGHPART . LOWPART). */
-static Lisp_Object
+static void
pop_down_menu (Lisp_Object arg)
{
LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID)
lw_destroy_all_widgets (id);
unblock_input ();
popup_activated_flag = 0;
-
- return Qnil;
}
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the
#endif /* not USE_GTK */
-static Lisp_Object
-cleanup_widget_value_tree (Lisp_Object arg)
+static void
+cleanup_widget_value_tree (void *arg)
{
- free_menubar_widget_value_tree (XSAVE_POINTER (arg, 0));
- return Qnil;
+ free_menubar_widget_value_tree (arg);
}
Lisp_Object
/* Make sure to free the widget_value objects we used to specify the
contents even with longjmp. */
- record_unwind_protect (cleanup_widget_value_tree,
- make_save_pointer (first_wv));
+ record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
/* Actually create and show the menu until popped down. */
create_and_show_popup_menu (f, first_wv, x, y, for_click, timestamp);
if (menu)
{
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
- record_unwind_protect (pop_down_menu, make_save_pointer (menu));
+ record_unwind_protect_ptr (pop_down_menu, menu);
/* Display the menu. */
gtk_widget_show_all (menu);
/* Make sure to free the widget_value objects we used to specify the
contents even with longjmp. */
- record_unwind_protect (cleanup_widget_value_tree,
- make_save_pointer (first_wv));
+ record_unwind_protect_ptr (cleanup_widget_value_tree, first_wv);
/* Actually create and show the dialog. */
create_and_show_dialog (f, first_wv);
Qnil, menu_object, make_number (item));
}
-static Lisp_Object
+static void
pop_down_menu (Lisp_Object arg)
{
FRAME_PTR f = XSAVE_POINTER (arg, 0);
#endif /* HAVE_X_WINDOWS */
unblock_input ();
-
- return Qnil;
}
struct prop_location;
struct selection_data;
-static Lisp_Object x_atom_to_symbol (Display *dpy, Atom atom);
-static Atom symbol_to_x_atom (struct x_display_info *, Lisp_Object);
-static void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object);
-static Lisp_Object x_get_local_selection (Lisp_Object, Lisp_Object, int,
- struct x_display_info *);
static void x_decline_selection_request (struct input_event *);
-static Lisp_Object x_selection_request_lisp_error (Lisp_Object);
-static Lisp_Object queue_selection_requests_unwind (Lisp_Object);
-static Lisp_Object x_catch_errors_unwind (Lisp_Object);
-static void x_reply_selection_request (struct input_event *, struct x_display_info *);
static int x_convert_selection (struct input_event *, Lisp_Object, Lisp_Object,
Atom, int, struct x_display_info *);
static int waiting_for_other_props_on_window (Display *, Window);
static struct prop_location *expect_property_change (Display *, Window,
Atom, int);
static void unexpect_property_change (struct prop_location *);
-static Lisp_Object wait_for_property_change_unwind (Lisp_Object);
static void wait_for_property_change (struct prop_location *);
-static Lisp_Object x_get_foreign_selection (Lisp_Object, Lisp_Object,
- Lisp_Object, Lisp_Object);
static Lisp_Object x_get_window_property_as_lisp_data (Display *,
Window, Atom,
Lisp_Object, Atom);
static void lisp_data_to_selection_data (Display *, Lisp_Object,
unsigned char **, Atom *,
ptrdiff_t *, int *, int *);
-static Lisp_Object clean_local_selection_data (Lisp_Object);
/* Printing traces to stderr. */
an error, we tell the requestor that we were unable to do what they wanted
before we throw to top-level or go into the debugger or whatever. */
-static Lisp_Object
-x_selection_request_lisp_error (Lisp_Object ignore)
+static void
+x_selection_request_lisp_error (void)
{
struct selection_data *cs, *next;
if (x_selection_current_request != 0
&& selection_request_dpyinfo->display)
x_decline_selection_request (x_selection_current_request);
- return Qnil;
}
-static Lisp_Object
-x_catch_errors_unwind (Lisp_Object dummy)
+static void
+x_catch_errors_unwind (void)
{
block_input ();
x_uncatch_errors ();
unblock_input ();
- return Qnil;
}
\f
struct prop_location *next;
};
-static struct prop_location *expect_property_change (Display *display, Window window, Atom property, int state);
-static void wait_for_property_change (struct prop_location *location);
-static void unexpect_property_change (struct prop_location *location);
-static int waiting_for_other_props_on_window (Display *display, Window window);
-
static int prop_location_identifier;
static Lisp_Object property_change_reply;
static struct prop_location *property_change_wait_list;
-static Lisp_Object
-queue_selection_requests_unwind (Lisp_Object tem)
-{
- x_stop_queuing_selection_requests ();
- return Qnil;
-}
-
\f
/* Send the reply to a selection request event EVENT. */
/* The protected block contains wait_for_property_change, which can
run random lisp code (process handlers) or signal. Therefore, we
put the x_uncatch_errors call in an unwind. */
- record_unwind_protect (x_catch_errors_unwind, Qnil);
+ record_unwind_protect_void (x_catch_errors_unwind);
x_catch_errors (display);
/* Loop over converted selections, storing them in the requested
x_selection_current_request = event;
selection_request_dpyinfo = dpyinfo;
- record_unwind_protect (x_selection_request_lisp_error, Qnil);
+ record_unwind_protect_void (x_selection_request_lisp_error);
/* We might be able to handle nested x_handle_selection_requests,
but this is difficult to test, and seems unimportant. */
x_start_queuing_selection_requests ();
- record_unwind_protect (queue_selection_requests_unwind, Qnil);
+ record_unwind_protect_void (x_stop_queuing_selection_requests);
TRACE2 ("x_handle_selection_request: selection=%s, target=%s",
SDATA (SYMBOL_NAME (selection_symbol)),
/* Remove the property change expectation element for IDENTIFIER. */
-static Lisp_Object
-wait_for_property_change_unwind (Lisp_Object loc)
+static void
+wait_for_property_change_unwind (void *loc)
{
- struct prop_location *location = XSAVE_POINTER (loc, 0);
+ struct prop_location *location = loc;
unexpect_property_change (location);
if (location == property_change_reply_object)
property_change_reply_object = 0;
- return Qnil;
}
/* Actually wait for a property change.
emacs_abort ();
/* Make sure to do unexpect_property_change if we quit or err. */
- record_unwind_protect (wait_for_property_change_unwind,
- make_save_pointer (location));
+ record_unwind_protect_ptr (wait_for_property_change_unwind, location);
XSETCAR (property_change_reply, Qnil);
property_change_reply_object = location;
SelectionNotify. */
#if 0
x_start_queuing_selection_requests ();
- record_unwind_protect (queue_selection_requests_unwind, Qnil);
+ record_unwind_protect_void (x_stop_queuing_selection_requests);
#endif
unblock_input ();