+2013-01-23 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * xdisp.c (message2, message2_nolog): Remove functions.
+ (message3, message3_nolog): Extract nbytes and multibyteness directly
+ from the string. Change all callers.
+ (message3_nolog): Don't set message_enable_multibyte since set_message
+ will reset it anyway.
+ (message1, message1_nolog): Use message3.
+ (vmessage): Use a stack allocated buffer rather than f->message_buf.
+ (with_echo_area_buffer): Remove last two arguments. Update all callers.
+ (set_message): Drop all but the second arg, which has to be a string.
+ (set_message_1): Simplify now that we know that a1 is NULL and the
+ second arg is a string.
+ * frame.h (struct frame): Remove `message_buf' field.
+ Use glyphs_initialized_p instead.
+ (FRAME_MESSAGE_BUF): Remove macro.
+ * w16select.c (Fw16_set_clipboard_data): Prefer message3 to message2.
+ * lisp.h (message2, message2_nolog): Remove declarations.
+ (message3, message3_nolog): Update declarations.
+ * keyboard.c (read_char_minibuf_menu_text)
+ (read_char_minibuf_menu_width): Remove vars.
+ (read_char_minibuf_menu_prompt): Rewrite the menu's construction so as
+ to correctly handle multibyte strings.
+ * frame.c (delete_frame): Don't free message_buf any more.
+ * editfns.c (message_text, message_length): Remove vars.
+ (Fmessage_box): Don't copy the Lisp string's bytes any longer.
+ * fileio.c (auto_save_error): Use message3 instead of message2.
+ * dispnew.c (adjust_frame_message_buffer): Remove function.
+
2013-01-23 Eli Zaretskii <eliz@gnu.org>
* w32term.c (w32fullscreen_hook): Account correctly for the screen
#include <limits.h> /* For CHAR_BIT. */
#ifdef ENABLE_CHECKING
-#include <signal.h> /* For SIGABRT. */
+#include <signal.h> /* For SIGABRT. */
#endif
#ifdef HAVE_PTHREAD
b = lisp_malloc (size + GC_STRING_EXTRA, MEM_TYPE_NON_LISP);
#ifdef DOUG_LEA_MALLOC
- /* Back to a reasonable maximum of mmap'ed areas. */
+ /* Back to a reasonable maximum of mmap'ed areas. */
mallopt (M_MMAP_MAX, MMAP_MAX_AREAS);
#endif
#ifdef GC_CHECK_STRING_BYTES
/* Check that the string size recorded in the string is the
- same as the one recorded in the sdata structure. */
+ same as the one recorded in the sdata structure. */
if (s && string_bytes (s) != SDATA_NBYTES (from))
emacs_abort ();
#endif /* GC_CHECK_STRING_BYTES */
}
#endif
\f
-/* Initialization */
+/* Initialization. */
void
init_alloc_once (void)
#endif
#ifdef DOUG_LEA_MALLOC
- mallopt (M_TRIM_THRESHOLD, 128*1024); /* trim threshold */
- mallopt (M_MMAP_THRESHOLD, 64*1024); /* mmap threshold */
- mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* max. number of mmap'ed areas */
+ mallopt (M_TRIM_THRESHOLD, 128 * 1024); /* Trim threshold. */
+ mallopt (M_MMAP_THRESHOLD, 64 * 1024); /* Mmap threshold. */
+ mallopt (M_MMAP_MAX, MMAP_MAX_AREAS); /* Max. number of mmap'ed areas. */
#endif
init_strings ();
init_vectors ();
switch (*tem)
{
- case 'a': /* Symbol defined as a function */
+ case 'a': /* Symbol defined as a function. */
visargs[i] = Fcompleting_read (callint_message,
Vobarray, Qfboundp, Qt,
Qnil, Qnil, Qnil, Qnil);
- /* Passing args[i] directly stimulates compiler bug */
+ /* Passing args[i] directly stimulates compiler bug. */
teml = visargs[i];
args[i] = Fintern (teml, Qnil);
break;
- case 'b': /* Name of existing buffer */
+ case 'b': /* Name of existing buffer. */
args[i] = Fcurrent_buffer ();
if (EQ (selected_window, minibuf_window))
args[i] = Fother_buffer (args[i], Qnil, Qnil);
args[i] = Fread_buffer (callint_message, args[i], Qt);
break;
- case 'B': /* Name of buffer, possibly nonexistent */
+ case 'B': /* Name of buffer, possibly nonexistent. */
args[i] = Fread_buffer (callint_message,
Fother_buffer (Fcurrent_buffer (), Qnil, Qnil),
Qnil);
break;
- case 'c': /* Character */
+ case 'c': /* Character. */
/* Prompt in `minibuffer-prompt' face. */
Fput_text_property (make_number (0),
make_number (SCHARS (callint_message)),
Qface, Qminibuffer_prompt, callint_message);
args[i] = Fread_char (callint_message, Qnil, Qnil);
message1_nolog ((char *) 0);
- /* Passing args[i] directly stimulates compiler bug */
+ /* Passing args[i] directly stimulates compiler bug. */
teml = args[i];
/* See bug#8479. */
if (! CHARACTERP (teml)) error ("Non-character input-event");
visargs[i] = Fchar_to_string (teml);
break;
- case 'C': /* Command: symbol with interactive function */
+ case 'C': /* Command: symbol with interactive function. */
visargs[i] = Fcompleting_read (callint_message,
Vobarray, Qcommandp,
Qt, Qnil, Qnil, Qnil, Qnil);
- /* Passing args[i] directly stimulates compiler bug */
+ /* Passing args[i] directly stimulates compiler bug. */
teml = visargs[i];
args[i] = Fintern (teml, Qnil);
break;
varies[i] = 1;
break;
- case 'D': /* Directory name. */
+ case 'D': /* Directory name. */
args[i] = Fread_file_name (callint_message, Qnil,
BVAR (current_buffer, directory), Qlambda, Qnil,
Qfile_directory_p);
break;
- case 'f': /* Existing file name. */
+ case 'f': /* Existing file name. */
args[i] = Fread_file_name (callint_message,
Qnil, Qnil, Qlambda, Qnil, Qnil);
break;
- case 'F': /* Possibly nonexistent file name. */
+ case 'F': /* Possibly nonexistent file name. */
args[i] = Fread_file_name (callint_message,
Qnil, Qnil, Qnil, Qnil, Qnil);
break;
case 'G': /* Possibly nonexistent file name,
- default to directory alone. */
+ default to directory alone. */
args[i] = Fread_file_name (callint_message,
Qnil, Qnil, Qnil, empty_unibyte_string, Qnil);
break;
- case 'i': /* Ignore an argument -- Does not do I/O */
+ case 'i': /* Ignore an argument -- Does not do I/O. */
varies[i] = -1;
break;
- case 'k': /* Key sequence. */
+ case 'k': /* Key sequence. */
{
ptrdiff_t speccount1 = SPECPDL_INDEX ();
specbind (Qcursor_in_echo_area, Qt);
}
break;
- case 'K': /* Key sequence to be defined. */
+ case 'K': /* Key sequence to be defined. */
{
ptrdiff_t speccount1 = SPECPDL_INDEX ();
specbind (Qcursor_in_echo_area, Qt);
}
break;
- case 'U': /* Up event from last k or K */
+ case 'U': /* Up event from last k or K. */
if (!NILP (up_event))
{
args[i] = Fmake_vector (make_number (1), up_event);
Qnil, Qnil, Qnil, Qt);
break;
- case 'N': /* Prefix arg as number, else number from minibuffer */
+ case 'N': /* Prefix arg as number, else number from minibuffer. */
if (!NILP (prefix_arg))
goto have_prefix_arg;
case 'n': /* Read number from minibuffer. */
varies[i] = -1;
break;
- case 'p': /* Prefix arg converted to number. No I/O. */
+ case 'p': /* Prefix arg converted to number. No I/O. */
have_prefix_arg:
args[i] = Fprefix_numeric_value (prefix_arg);
/* visargs[i] = Qnil; */
varies[i] = -1;
break;
- case 'r': /* Region, point and mark as 2 args. */
+ case 'r': /* Region, point and mark as 2 args. */
check_mark (1);
set_marker_both (point_marker, Qnil, PT, PT_BYTE);
/* visargs[i+1] = Qnil; */
case 'S': /* Any symbol. */
visargs[i] = Fread_string (callint_message,
Qnil, Qnil, Qnil, Qnil);
- /* Passing args[i] directly stimulates compiler bug */
+ /* Passing args[i] directly stimulates compiler bug. */
teml = visargs[i];
args[i] = Fintern (teml, Qnil);
break;
case 'v': /* Variable name: symbol that is
- custom-variable-p. */
+ custom-variable-p. */
args[i] = Fread_variable (callint_message, Qnil);
visargs[i] = last_minibuf_string;
break;
- case 'x': /* Lisp expression read but not evaluated */
+ case 'x': /* Lisp expression read but not evaluated. */
args[i] = Fread_minibuffer (callint_message, Qnil);
visargs[i] = last_minibuf_string;
break;
- case 'X': /* Lisp expression read and evaluated */
+ case 'X': /* Lisp expression read and evaluated. */
args[i] = Feval_minibuffer (callint_message, Qnil);
visargs[i] = last_minibuf_string;
break;
case 'Z': /* Coding-system symbol, or ignore the
- argument if no prefix */
+ argument if no prefix. */
if (NILP (prefix_arg))
{
args[i] = Qnil;
}
break;
- case 'z': /* Coding-system symbol or nil */
+ case 'z': /* Coding-system symbol or nil. */
args[i] = Fread_coding_system (callint_message, Qnil);
visargs[i] = last_minibuf_string;
break;
struct window *);
static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
struct window *);
-static void adjust_frame_message_buffer (struct frame *);
static void adjust_decode_mode_spec_buffer (struct frame *);
static void fill_up_glyph_row_with_spaces (struct glyph_row *);
static void clear_window_matrices (struct window *, bool);
else
adjust_frame_glyphs_for_frame_redisplay (f);
- /* Don't forget the message buffer and the buffer for
- decode_mode_spec. */
- adjust_frame_message_buffer (f);
+ /* Don't forget the buffer for decode_mode_spec. */
adjust_decode_mode_spec_buffer (f);
f->glyphs_initialized_p = 1;
}
-/* Adjust/ allocate message buffer of frame F.
-
- Note that the message buffer is never freed. Since I could not
- find a free in 19.34, I assume that freeing it would be
- problematic in some way and don't do it either.
-
- (Implementation note: It should be checked if we can free it
- eventually without causing trouble). */
-
-static void
-adjust_frame_message_buffer (struct frame *f)
-{
- FRAME_MESSAGE_BUF (f) = xrealloc (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f) + 1);
-}
-
-
/* Re-allocate buffer for decode_mode_spec on frame F. */
static void
return unbind_to (count, val);
}
\f
-/* Buffer for the most recent text displayed by Fmessage_box. */
-static char *message_text;
-
-/* Allocated length of that buffer. */
-static ptrdiff_t message_length;
-
DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
doc: /* Display a message at the bottom of the screen.
The message also goes into the `*Messages*' buffer, if `message-log-max'
{
register Lisp_Object val;
val = Fformat (nargs, args);
- message3 (val, SBYTES (val), STRING_MULTIBYTE (val));
+ message3 (val);
return val;
}
}
}
else
{
- register Lisp_Object val;
- val = Fformat (nargs, args);
+ Lisp_Object val = Fformat (nargs, args);
#ifdef HAVE_MENUS
/* The MS-DOS frames support popup menus even though they are
not FRAME_WINDOW_P. */
return val;
}
#endif /* HAVE_MENUS */
- /* Copy the data so that it won't move when we GC. */
- if (SBYTES (val) > message_length)
- {
- ptrdiff_t new_length = SBYTES (val) + 80;
- message_text = xrealloc (message_text, new_length);
- message_length = new_length;
- }
- memcpy (message_text, SDATA (val), SBYTES (val));
- message2 (message_text, SBYTES (val),
- STRING_MULTIBYTE (val));
+ message3 (val);
return val;
}
}
auto_save_error (Lisp_Object error_val)
{
Lisp_Object args[3], msg;
- int i, nbytes;
+ int i;
struct gcpro gcpro1;
- char *msgbuf;
- USE_SAFE_ALLOCA;
auto_save_error_occurred = 1;
args[2] = Ferror_message_string (error_val);
msg = Fformat (3, args);
GCPRO1 (msg);
- nbytes = SBYTES (msg);
- msgbuf = SAFE_ALLOCA (nbytes);
- memcpy (msgbuf, SDATA (msg), nbytes);
for (i = 0; i < 3; ++i)
{
if (i == 0)
- message2 (msgbuf, nbytes, STRING_MULTIBYTE (msg));
+ message3 (msg);
else
- message2_nolog (msgbuf, nbytes, STRING_MULTIBYTE (msg));
+ message3_nolog (msg);
Fsleep_for (make_number (1), Qnil);
}
- SAFE_FREE ();
UNGCPRO;
return Qnil;
}
usage: (widget-apply WIDGET PROPERTY &rest ARGS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- /* This function can GC. */
+ /* This function can GC. */
Lisp_Object newargs[3];
struct gcpro gcpro1, gcpro2;
Lisp_Object result;
xfree (FRAME_DELETEN_COST (f));
xfree (FRAME_INSERTN_COST (f));
xfree (FRAME_DELETE_COST (f));
- xfree (FRAME_MESSAGE_BUF (f));
/* Since some events are handled at the interrupt level, we may get
an event for f at any time; if we zero out the frame's terminal
{
struct terminal *terminal = FRAME_TERMINAL (f);
f->output_data.nothing = 0;
- f->terminal = 0; /* Now the frame is dead. */
+ f->terminal = 0; /* Now the frame is dead. */
/* If needed, delete the terminal that this frame was on.
- (This must be done after the frame is killed.) */
+ (This must be done after the frame is killed.) */
terminal->reference_count--;
#ifdef USE_GTK
/* FIXME: Deleting the terminal crashes emacs because of a GTK
/* Don't multiply include: dispextern.h includes macterm.h which
includes frame.h some emacs source includes both dispextern.h and
- frame.h */
+ frame.h. */
#ifndef EMACS_FRAME_H
#define EMACS_FRAME_H
\f
/* Miscellanea. */
-/* Nonzero means there is at least one garbaged frame. */
+/* Nonzero means there is at least one garbaged frame. */
extern bool frame_garbaged;
\f
string's pointer (`name', above) because it might get relocated. */
char *namebuf;
- /* Glyph pool and matrix. */
+ /* Glyph pool and matrix. */
struct glyph_pool *current_pool;
struct glyph_pool *desired_pool;
struct glyph_matrix *desired_matrix;
/* Width of bar cursor (if we are using that) for blink-off state. */
int blink_off_cursor_width;
- /* Storage for messages to this frame. */
- char *message_buf;
-
/* Nonnegative if current redisplay should not do scroll computation
for lines beyond a certain vpos. This is the vpos. */
int scroll_bottom_vpos;
#define FRAME_DELETE_COST(f) (f)->delete_line_cost
#define FRAME_INSERTN_COST(f) (f)->insert_n_lines_cost
#define FRAME_DELETEN_COST(f) (f)->delete_n_lines_cost
-#define FRAME_MESSAGE_BUF(f) (f)->message_buf
#define FRAME_SCROLL_BOTTOM_VPOS(f) (f)->scroll_bottom_vpos
#define FRAME_FOCUS_FRAME(f) f->focus_frame
}
echoing = 1;
- message3_nolog (KVAR (current_kboard, echo_string),
- SBYTES (KVAR (current_kboard, echo_string)),
- STRING_MULTIBYTE (KVAR (current_kboard, echo_string)));
+ /* FIXME: Use call (Qmessage) so it can be advised (e.g. emacspeak). */
+ message3_nolog (KVAR (current_kboard, echo_string));
echoing = 0;
/* Record in what buffer we echoed, and from which kboard. */
sit_for (Vminibuffer_message_timeout, 0, 2);
/* Clear the echo area. */
- message2 (0, 0, 0);
+ message1 (0);
safe_run_hooks (Qecho_area_clear_hook);
unbind_to (count, Qnil);
return Qnil ;
}
-/* Buffer in use so far for the minibuf prompts for menu keymaps.
- We make this bigger when necessary, and never free it. */
-static char *read_char_minibuf_menu_text;
-/* Size of that buffer. */
-static ptrdiff_t read_char_minibuf_menu_width;
-
static Lisp_Object
read_char_minibuf_menu_prompt (int commandflag,
ptrdiff_t nmaps, Lisp_Object *maps)
ptrdiff_t idx = -1;
bool nobindings = 1;
Lisp_Object rest, vector;
- char *menu;
+ Lisp_Object prompt_strings = Qnil;
vector = Qnil;
name = Qnil;
if (!STRINGP (name))
return Qnil;
- /* Make sure we have a big enough buffer for the menu text. */
- width = max (width, SBYTES (name));
- if (STRING_BYTES_BOUND - 4 < width)
- memory_full (SIZE_MAX);
- if (width + 4 > read_char_minibuf_menu_width)
- {
- read_char_minibuf_menu_text
- = xrealloc (read_char_minibuf_menu_text, width + 4);
- read_char_minibuf_menu_width = width + 4;
- }
- menu = read_char_minibuf_menu_text;
-
+#define PUSH_C_STR(str, listvar) \
+ listvar = Fcons (make_unibyte_string (str, strlen (str)), listvar)
+
/* Prompt string always starts with map's prompt, and a space. */
- strcpy (menu, SSDATA (name));
- nlength = SBYTES (name);
- menu[nlength++] = ':';
- menu[nlength++] = ' ';
- menu[nlength] = 0;
+ prompt_strings = Fcons (name, prompt_strings);
+ PUSH_C_STR (": ", prompt_strings);
+ nlength = SCHARS (name) + 2;
/* Start prompting at start of first map. */
mapno = 0;
while (1)
{
bool notfirst = 0;
+ Lisp_Object menu_strings = prompt_strings;
ptrdiff_t i = nlength;
Lisp_Object obj;
Lisp_Object orig_defn_macro;
{
Lisp_Object elt;
+ /* FIXME: Use map_keymap to handle new keymap formats. */
+
/* If reached end of map, start at beginning of next map. */
if (NILP (rest))
{
/* Punctuate between strings. */
if (notfirst)
{
- strcpy (menu + i, ", ");
+ PUSH_C_STR (", ", menu_strings);
i += 2;
}
notfirst = 1;
{
/* Add as much of string as fits. */
thiswidth = min (SCHARS (desc), width - i);
- memcpy (menu + i, SDATA (desc), thiswidth);
+ menu_strings
+ = Fcons (Fsubstring (desc, make_number (0),
+ make_number (thiswidth)),
+ menu_strings);
i += thiswidth;
- strcpy (menu + i, " = ");
+ PUSH_C_STR (" = ", menu_strings);
i += 3;
}
/* Add as much of string as fits. */
thiswidth = min (SCHARS (s), width - i);
- memcpy (menu + i, SDATA (s), thiswidth);
+ menu_strings
+ = Fcons (Fsubstring (s, make_number (0),
+ make_number (thiswidth)),
+ menu_strings);
i += thiswidth;
- menu[i] = 0;
}
else
{
/* If this element does not fit, end the line now,
and save the element for the next line. */
- strcpy (menu + i, "...");
+ PUSH_C_STR ("...", menu_strings);
break;
}
}
}
/* Prompt with that and read response. */
- message2_nolog (menu, strlen (menu),
- ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
+ message3_nolog (apply1 (intern ("concat"), menu_strings));
- /* Make believe its not a keyboard macro in case the help char
+ /* Make believe it's not a keyboard macro in case the help char
is pressed. Help characters are not recorded because menu prompting
- is not used on replay.
- */
+ is not used on replay. */
orig_defn_macro = KVAR (current_kboard, defining_kbd_macro);
kset_defining_kbd_macro (current_kboard, Qnil);
do
while (BUFFERP (obj));
kset_defining_kbd_macro (current_kboard, orig_defn_macro);
- if (!INTEGERP (obj))
- return obj;
- else if (XINT (obj) == -2)
+ if (!INTEGERP (obj) || XINT (obj) == -2)
return obj;
if (! EQ (obj, menu_prompt_more_char)
store_kbd_macro_char (obj);
return obj;
}
- /* Help char - go round again */
+ /* Help char - go round again. */
}
}
\f
cancel_hourglass ();
#endif
- i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
+ i = read_key_sequence (keybuf, (sizeof keybuf / sizeof (keybuf[0])),
prompt, ! NILP (dont_downcase_last),
! NILP (can_return_switch_frame), 0);
extern void message (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2);
extern void message1 (const char *);
extern void message1_nolog (const char *);
-extern void message2 (const char *, ptrdiff_t, int);
-extern void message2_nolog (const char *, ptrdiff_t, int);
-extern void message3 (Lisp_Object, ptrdiff_t, int);
-extern void message3_nolog (Lisp_Object, ptrdiff_t, int);
+extern void message3 (Lisp_Object);
+extern void message3_nolog (Lisp_Object);
extern void message_dolog (const char *, ptrdiff_t, int, int);
extern void message_with_string (const char *, Lisp_Object, int);
extern void message_log_maybe_newline (void);
switch (put_status)
{
case 1:
- message2 (no_mem_msg, sizeof (no_mem_msg) - 1, 0);
+ message3 (make_unibyte_string (no_mem_msg, sizeof (no_mem_msg) - 1));
break;
case 2:
- message2 (binary_msg, sizeof (binary_msg) - 1, 0);
+ message3 (make_unibyte_string (binary_msg, sizeof (binary_msg) - 1));
break;
case 3:
- message2 (system_error_msg, sizeof (system_error_msg) - 1, 0);
+ message3 (make_unibyte_string (system_error_msg, sizeof (system_error_msg) - 1));
break;
}
sit_for (make_number (2), 0, 2);
static Lisp_Object 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, ptrdiff_t),
- ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+ int (*) (ptrdiff_t, Lisp_Object),
+ ptrdiff_t, Lisp_Object);
static void clear_garbaged_frames (void);
-static int current_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+static int current_message_1 (ptrdiff_t, Lisp_Object);
static void pop_message (void);
-static int truncate_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
-static void set_message (const char *, Lisp_Object, ptrdiff_t, int);
-static int set_message_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+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, ptrdiff_t, ptrdiff_t);
-static int resize_mini_window_1 (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t);
+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 int string_char_and_length (const unsigned char *, int *);
static struct text_pos display_prop_end (struct it *, Lisp_Object,
for (i = 0; i < len; i++)
{
- if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
+ if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
seen_dots = 1;
if (p1[i] != p2[i])
return seen_dots;
char *pend;
intmax_t n = strtoimax ((char *) p1, &pend, 10);
if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
- return n+1;
+ return n + 1;
}
return 0;
}
\f
-/* Display an echo area message M with a specified length of NBYTES
- bytes. The string may include null characters. If M is 0, clear
- out any existing message, and let the mini-buffer text show
- through.
-
- This may GC, so the buffer M must NOT point to a Lisp string. */
-
-void
-message2 (const char *m, ptrdiff_t nbytes, int multibyte)
-{
- /* First flush out any partial line written with print. */
- message_log_maybe_newline ();
- if (m)
- message_dolog (m, nbytes, 1, multibyte);
- message2_nolog (m, nbytes, multibyte);
-}
-
-
-/* The non-logging counterpart of message2. */
-
-void
-message2_nolog (const char *m, ptrdiff_t nbytes, int multibyte)
-{
- struct frame *sf = SELECTED_FRAME ();
- message_enable_multibyte = multibyte;
-
- if (FRAME_INITIAL_P (sf))
- {
- if (noninteractive_need_newline)
- putc ('\n', stderr);
- noninteractive_need_newline = 0;
- if (m)
- fwrite (m, nbytes, 1, stderr);
- if (cursor_in_echo_area == 0)
- fprintf (stderr, "\n");
- fflush (stderr);
- }
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
- else if (INTERACTIVE
- && sf->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (sf))
- {
- Lisp_Object mini_window;
- struct frame *f;
-
- /* Get the frame containing the mini-buffer
- that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (sf);
- f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
-
- FRAME_SAMPLE_VISIBILITY (f);
- if (FRAME_VISIBLE_P (sf)
- && ! FRAME_VISIBLE_P (f))
- Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
-
- if (m)
- {
- set_message (m, Qnil, nbytes, multibyte);
- if (minibuffer_auto_raise)
- Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
- }
- else
- clear_message (1, 1);
-
- do_pending_window_change (0);
- echo_area_display (1);
- do_pending_window_change (0);
- if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
- (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
- }
-}
-
-
/* Display an echo area message M with a specified length of NBYTES
bytes. The string may include null characters. If M is not a
string, clear out any existing message, and let the mini-buffer
This function cancels echoing. */
void
-message3 (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
+message3 (Lisp_Object m)
{
struct gcpro gcpro1;
message_log_maybe_newline ();
if (STRINGP (m))
{
+ ptrdiff_t nbytes = SBYTES (m);
+ int multibyte = STRING_MULTIBYTE (m);
USE_SAFE_ALLOCA;
char *buffer = SAFE_ALLOCA (nbytes);
memcpy (buffer, SDATA (m), nbytes);
message_dolog (buffer, nbytes, 1, multibyte);
SAFE_FREE ();
}
- message3_nolog (m, nbytes, multibyte);
+ message3_nolog (m);
UNGCPRO;
}
and make this cancel echoing. */
void
-message3_nolog (Lisp_Object m, ptrdiff_t nbytes, int multibyte)
+message3_nolog (Lisp_Object m)
{
struct frame *sf = SELECTED_FRAME ();
- message_enable_multibyte = multibyte;
if (FRAME_INITIAL_P (sf))
{
putc ('\n', stderr);
noninteractive_need_newline = 0;
if (STRINGP (m))
- fwrite (SDATA (m), nbytes, 1, stderr);
+ fwrite (SDATA (m), SBYTES (m), 1, stderr);
if (cursor_in_echo_area == 0)
fprintf (stderr, "\n");
fflush (stderr);
}
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
+ /* Error messages get reported properly by cmd_error, so this must be just an
+ informative message; if the frame hasn't really been initialized yet, just
+ toss it. */
else if (INTERACTIVE
- && sf->glyphs_initialized_p
- && FRAME_MESSAGE_BUF (sf))
+ && sf->glyphs_initialized_p)
{
- Lisp_Object mini_window;
- Lisp_Object frame;
- struct frame *f;
-
/* Get the frame containing the mini-buffer
that the selected frame is using. */
- mini_window = FRAME_MINIBUF_WINDOW (sf);
- frame = XWINDOW (mini_window)->frame;
- f = XFRAME (frame);
+ Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
+ Lisp_Object frame = XWINDOW (mini_window)->frame;
+ struct frame *f = XFRAME (frame);
FRAME_SAMPLE_VISIBILITY (f);
if (FRAME_VISIBLE_P (sf)
if (STRINGP (m) && SCHARS (m) > 0)
{
- set_message (NULL, m, nbytes, multibyte);
+ set_message (m);
if (minibuffer_auto_raise)
Fraise_frame (frame);
/* Assume we are not echoing.
void
message1 (const char *m)
{
- message2 (m, (m ? strlen (m) : 0), 0);
+ message3 (m ? make_unibyte_string (m, strlen (m)) : Qnil);
}
void
message1_nolog (const char *m)
{
- message2_nolog (m, (m ? strlen (m) : 0), 0);
+ message3_nolog (m ? make_unibyte_string (m, strlen (m)) : Qnil);
}
/* Display a message M which contains a single %s
mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
- if (FRAME_MESSAGE_BUF (f))
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (f->glyphs_initialized_p)
{
Lisp_Object args[2], msg;
struct gcpro gcpro1, gcpro2;
msg = Fformat (2, args);
if (log)
- message3 (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
+ message3 (msg);
else
- message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
+ message3_nolog (msg);
UNGCPRO;
mini_window = FRAME_MINIBUF_WINDOW (sf);
f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss
- it. */
- if (FRAME_MESSAGE_BUF (f))
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (f->glyphs_initialized_p)
{
if (m)
{
ptrdiff_t len;
+ ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
+ char *message_buf = alloca (maxsize + 1);
- len = doprnt (FRAME_MESSAGE_BUF (f),
- FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);
+ len = doprnt (message_buf, maxsize, m, (char *)0, ap);
- message2 (FRAME_MESSAGE_BUF (f), len, 1);
+ message3 (make_string (message_buf, len));
}
else
message1 (0);
{
Lisp_Object string;
string = Fcurrent_message ();
- message3 (string, SBYTES (string),
- !NILP (BVAR (current_buffer, enable_multibyte_characters)));
+ message3 (string);
}
}
}
-/* Call FN with args A1..A4 with either the current or last displayed
+/* Call FN with args A1..A2 with either the current or last displayed
echo_area_buffer as current buffer.
WHICH zero means use the current message buffer
static int
with_echo_area_buffer (struct window *w, int which,
- int (*fn) (ptrdiff_t, Lisp_Object, ptrdiff_t, ptrdiff_t),
- ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+ int (*fn) (ptrdiff_t, Lisp_Object),
+ ptrdiff_t a1, Lisp_Object a2)
{
Lisp_Object buffer;
int this_one, the_other, clear_buffer_p, rc;
eassert (BEGV >= BEG);
eassert (ZV <= Z && ZV >= BEGV);
- rc = fn (a1, a2, a3, a4);
+ rc = fn (a1, a2);
eassert (BEGV >= BEG);
eassert (ZV <= Z && ZV >= BEGV);
window_height_changed_p
= with_echo_area_buffer (w, display_last_displayed_message_p,
display_echo_area_1,
- (intptr_t) w, Qnil, 0, 0);
+ (intptr_t) w, Qnil);
if (no_message_p)
echo_area_buffer[i] = Qnil;
Value is non-zero if height of W was changed. */
static int
-display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
{
intptr_t i1 = a1;
struct window *w = (struct window *) i1;
resize_exactly = Qnil;
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
- (intptr_t) w, resize_exactly,
- 0, 0);
+ (intptr_t) w, resize_exactly);
if (resized_p)
{
++windows_or_buffers_changed;
resize_mini_window returns. */
static int
-resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly, ptrdiff_t a3, ptrdiff_t a4)
+resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
{
intptr_t i1 = a1;
return resize_mini_window ((struct window *) i1, !NILP (exactly));
else
{
with_echo_area_buffer (0, 0, current_message_1,
- (intptr_t) &msg, Qnil, 0, 0);
+ (intptr_t) &msg, Qnil);
if (NILP (msg))
echo_area_buffer[0] = Qnil;
}
static int
-current_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+current_message_1 (ptrdiff_t a1, Lisp_Object a2)
{
intptr_t i1 = a1;
Lisp_Object *msg = (Lisp_Object *) i1;
void
restore_message (void)
{
- Lisp_Object msg;
-
eassert (CONSP (Vmessage_stack));
- msg = XCAR (Vmessage_stack);
- if (STRINGP (msg))
- message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
- else
- message3_nolog (msg, 0, 0);
+ message3_nolog (XCAR (Vmessage_stack));
}
{
if (nchars == 0)
echo_area_buffer[0] = Qnil;
- /* A null message buffer means that the frame hasn't really been
- initialized yet. Error messages get reported properly by
- cmd_error, so this must be just an informative message; toss it. */
else if (!noninteractive
&& INTERACTIVE
&& !NILP (echo_area_buffer[0]))
{
struct frame *sf = SELECTED_FRAME ();
- if (FRAME_MESSAGE_BUF (sf))
- with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
+ /* Error messages get reported properly by cmd_error, so this must be
+ just an informative message; if the frame hasn't really been
+ initialized yet, just toss it. */
+ if (sf->glyphs_initialized_p)
+ with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
}
}
message to at most NCHARS characters. */
static int
-truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2, ptrdiff_t a3, ptrdiff_t a4)
+truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
{
if (BEG + nchars < Z)
del_range (BEG + nchars, Z);
return 0;
}
-/* Set the current message to a substring of S or STRING.
-
- If STRING is a Lisp string, set the message to the first NBYTES
- bytes from STRING. NBYTES zero means use the whole string. If
- STRING is multibyte, the message will be displayed multibyte.
-
- If S is not null, set the message to the first LEN bytes of S. LEN
- zero means use the whole string. MULTIBYTE_P non-zero means S is
- multibyte. Display the message multibyte in that case.
-
- Doesn't GC, as with_echo_area_buffer binds Qinhibit_modification_hooks
- to t before calling set_message_1 (which calls insert).
- */
+/* Set the current message to STRING. */
static void
-set_message (const char *s, Lisp_Object string,
- ptrdiff_t nbytes, int multibyte_p)
+set_message (Lisp_Object string)
{
- message_enable_multibyte
- = ((s && multibyte_p)
- || (STRINGP (string) && STRING_MULTIBYTE (string)));
+ eassert (STRINGP (string));
- with_echo_area_buffer (0, -1, set_message_1,
- (intptr_t) s, string, nbytes, multibyte_p);
+ message_enable_multibyte = STRING_MULTIBYTE (string);
+
+ with_echo_area_buffer (0, -1, set_message_1, 0, string);
message_buf_print = 0;
help_echo_showing_p = 0;
}
-/* Helper function for set_message. Arguments have the same meaning
- as there, with A1 corresponding to S and A2 corresponding to STRING
- This function is called with the echo area buffer being
- current. */
+/* Helper function for set_message. First argument is ignored and second
+ argument has the same meaning as for set_message.
+ This function is called with the echo area buffer being current. */
static int
-set_message_1 (ptrdiff_t a1, Lisp_Object a2, ptrdiff_t nbytes, ptrdiff_t multibyte_p)
+set_message_1 (ptrdiff_t a1, Lisp_Object string)
{
- intptr_t i1 = a1;
- const char *s = (const char *) i1;
- const unsigned char *msg = (const unsigned char *) s;
- Lisp_Object string = a2;
+ eassert (STRINGP (string));
/* Change multibyteness of the echo buffer appropriately. */
if (message_enable_multibyte
/* Insert new message at BEG. */
TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
- if (STRINGP (string))
- {
- ptrdiff_t nchars;
-
- if (nbytes == 0)
- nbytes = SBYTES (string);
- nchars = string_byte_to_char (string, nbytes);
-
- /* This function takes care of single/multibyte conversion. We
- just have to ensure that the echo area buffer has the right
- setting of enable_multibyte_characters. */
- insert_from_string (string, 0, 0, nchars, nbytes, 1);
- }
- else if (s)
- {
- if (nbytes == 0)
- nbytes = strlen (s);
-
- if (multibyte_p && NILP (BVAR (current_buffer, enable_multibyte_characters)))
- {
- /* Convert from multi-byte to single-byte. */
- ptrdiff_t i;
- int c, n;
- char work[1];
-
- /* Convert a multibyte string to single-byte. */
- for (i = 0; i < nbytes; i += n)
- {
- c = string_char_and_length (msg + i, &n);
- work[0] = (ASCII_CHAR_P (c)
- ? c
- : multibyte_char_to_unibyte (c));
- insert_1_both (work, 1, 1, 1, 0, 0);
- }
- }
- else if (!multibyte_p
- && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
- {
- /* Convert from single-byte to multi-byte. */
- ptrdiff_t i;
- int c, n;
- unsigned char str[MAX_MULTIBYTE_LENGTH];
-
- /* Convert a single-byte string to multibyte. */
- for (i = 0; i < nbytes; i++)
- {
- c = msg[i];
- MAKE_CHAR_MULTIBYTE (c);
- n = CHAR_STRING (c, str);
- insert_1_both ((char *) str, 1, n, 1, 0, 0);
- }
- }
- else
- insert_1 (s, nbytes, 1, 0, 0);
- }
+ /* This function takes care of single/multibyte conversion.
+ We just have to ensure that the echo area buffer has the right
+ setting of enable_multibyte_characters. */
+ insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), 1);
return 0;
}