summaryrefslogtreecommitdiff
path: root/src/minibuf.c
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2021-05-14 15:52:21 +0000
committerAlan Mackenzie <acm@muc.de>2021-05-14 15:52:21 +0000
commit780b1db126fcfdbb50da5c1acf24b3c6e614dd9f (patch)
treed25c9beba857c62ecda5353a38a093f694a3f238 /src/minibuf.c
parent43701a84367b76ccc93ad46f89110486988eec10 (diff)
downloademacs-780b1db126fcfdbb50da5c1acf24b3c6e614dd9f.tar.gz
Various detailed fixes to minibuf.c, etc., to fix bug #48337
Also fix some unsafe coding. * lisp/window.el (push-window-buffer-onto-prev): New function, extracted from (record-window-buffer): Refactor by extracting the above, and removing the now redundant parameter DO-MINIBUF. * src/minibuf.c (zip_minibuffer_stacks, read_minibuf): Replace calls to get_minibuffer (0) by nth_minibuffer (0). Replace calls to Qrecord_window_buffer by calls to Qpush_window_buffer_onto_prev. (Factive_minibuffer_window, read_minibuf_unwind): Call abort_emacs should an "impossible" null value be returned by nth_minibuffer. (read_minibuf): Move the get_minibuffer_call to just after the incrementation of minibuf_level as a precaution against a missing buffer in Vminibuffer_list. (nth_minibuffer): Replace XCAR by Fcar, to allow (car nil) to work. (init_minibuf_once): Create the inactive buffer *Minibuf-0*. (syms_of_minibuf): New DEFSYM, Qpush_window_buffer_onto_prev. * src/window.c (restore_window_configuration): Replace some XCARs and XCDRs by Fcar_safe and Fcdr_safe.
Diffstat (limited to 'src/minibuf.c')
-rw-r--r--src/minibuf.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/minibuf.c b/src/minibuf.c
index 52d1275451b..428998a639b 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -157,16 +157,15 @@ zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window)
Fset_window_start (dest_window, Fwindow_start (source_window), Qnil);
Fset_window_point (dest_window, Fwindow_point (source_window));
dw->prev_buffers = sw->prev_buffers;
- set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+ set_window_buffer (source_window, nth_minibuffer (0), 0, 0);
sw->prev_buffers = Qnil;
return;
}
if (live_minibuffer_p (dw->contents))
- call2 (Qrecord_window_buffer, dest_window, Qt);
+ call1 (Qpush_window_buffer_onto_prev, dest_window);
if (live_minibuffer_p (sw->contents))
- call2 (Qrecord_window_buffer, source_window, Qt);
-
+ call1 (Qpush_window_buffer_onto_prev, source_window);
acc = merge_c (dw->prev_buffers, sw->prev_buffers, minibuffer_ent_greater);
if (!NILP (acc))
@@ -179,7 +178,7 @@ zip_minibuffer_stacks (Lisp_Object dest_window, Lisp_Object source_window)
}
dw->prev_buffers = acc;
sw->prev_buffers = Qnil;
- set_window_buffer (source_window, get_minibuffer (0), 0, 0);
+ set_window_buffer (source_window, nth_minibuffer (0), 0, 0);
}
/* If `minibuffer_follows_selected_frame' is t, or we're about to
@@ -228,6 +227,8 @@ DEFUN ("active-minibuffer-window", Factive_minibuffer_window,
return Qnil;
innermost_MB = nth_minibuffer (minibuf_level);
+ if (NILP (innermost_MB))
+ emacs_abort ();
FOR_EACH_FRAME (frames, frame)
{
f = XFRAME (frame);
@@ -653,6 +654,10 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
}
minibuf_level++; /* Before calling choose_minibuf_frame. */
+ /* Ensure now that the latest minibuffer has been created, in case
+ anything happens which depends on MINNIBUF_LEVEL and
+ Vminibuffer_list being consistent with eachother. */
+ minibuffer = get_minibuffer (minibuf_level);
/* Choose the minibuffer window and frame, and take action on them. */
@@ -680,7 +685,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
}
MB_frame = XWINDOW (XFRAME (selected_frame)->minibuffer_window)->frame;
if (live_minibuffer_p (XWINDOW (minibuf_window)->contents))
- call2 (Qrecord_window_buffer, minibuf_window, Qt);
+ call1 (Qpush_window_buffer_onto_prev, minibuf_window);
record_unwind_protect_void (minibuffer_unwind);
record_unwind_protect (restore_window_configuration,
@@ -766,7 +771,6 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
/* Switch to the minibuffer. */
- minibuffer = get_minibuffer (minibuf_level);
set_minibuffer_mode (minibuffer, minibuf_level);
Fset_buffer (minibuffer);
@@ -807,7 +811,7 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt,
/* Empty out the minibuffers of all frames, except those frames
where there is an active minibuffer.
Set them to point to ` *Minibuf-0*', which is always empty. */
- empty_minibuf = get_minibuffer (0);
+ empty_minibuf = nth_minibuffer (0);
set_minibuffer_mode (empty_minibuf, 0);
/* Display this minibuffer in the proper window. */
@@ -969,9 +973,7 @@ static Lisp_Object
nth_minibuffer (EMACS_INT depth)
{
Lisp_Object tail = Fnthcdr (make_fixnum (depth), Vminibuffer_list);
- if (NILP (tail))
- return Qnil;
- return XCAR (tail);
+ return Fcar (tail);
}
/* Set the major mode of the minibuffer BUF, depending on DEPTH, the
@@ -1076,9 +1078,13 @@ read_minibuf_unwind (void)
Lisp_Object future_mini_window;
Lisp_Object saved_selected_frame = selected_frame;
Lisp_Object window, frames;
+ Lisp_Object expired_MB = nth_minibuffer (minibuf_level);
struct window *w;
struct frame *f;
+ if (NILP (expired_MB))
+ emacs_abort ();
+
/* Locate the expired minibuffer. */
FOR_EACH_FRAME (frames, exp_MB_frame)
{
@@ -1088,7 +1094,7 @@ read_minibuf_unwind (void)
{
w = XWINDOW (window);
if (EQ (w->frame, exp_MB_frame)
- && EQ (w->contents, nth_minibuffer (minibuf_level)))
+ && EQ (w->contents, expired_MB))
goto found;
}
}
@@ -1104,7 +1110,7 @@ read_minibuf_unwind (void)
minibuffer when we reset the relevant variables. Don't depend on
`minibuf_window' here. This could by now be the mini-window of any
frame. */
- Fset_buffer (nth_minibuffer (minibuf_level));
+ Fset_buffer (expired_MB);
minibuf_level--;
/* Restore prompt, etc, from outer minibuffer level. */
@@ -2272,6 +2278,8 @@ init_minibuf_once (void)
staticpro (&Vminibuffer_list);
staticpro (&Vcommand_loop_level_list);
pdumper_do_now_and_after_load (init_minibuf_once_for_pdumper);
+ /* Ensure our inactive minibuffer exists. */
+ get_minibuffer (0);
}
static void
@@ -2337,6 +2345,7 @@ syms_of_minibuf (void)
DEFSYM (Qminibuffer_completing_file_name, "minibuffer-completing-file-name");
DEFSYM (Qselect_frame_set_input_focus, "select-frame-set-input-focus");
DEFSYM (Qadd_to_history, "add-to-history");
+ DEFSYM (Qpush_window_buffer_onto_prev, "push-window-buffer-onto-prev");
DEFVAR_LISP ("read-expression-history", Vread_expression_history,
doc: /* A history list for arguments that are Lisp expressions to evaluate.