#include "process.h"
#include <errno.h>
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
#ifdef MSDOS
int quit_char;
/* Current depth in recursive edits. */
-int command_loop_level;
+EMACS_INT command_loop_level;
/* If not Qnil, this is a switch-frame event which we decided to put
off until the end of a key sequence. This should be read as the
/* Last size recorded for a current buffer which is not a minibuffer. */
static EMACS_INT last_non_minibuf_size;
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1. */
-size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
+uintmax_t num_input_events;
/* Value of num_nonmacro_input_events as of last auto save. */
/* The timestamp of the last input event we received from the X server.
X Windows wants this for selection ownership. */
-unsigned long last_event_timestamp;
+Time last_event_timestamp;
static Lisp_Object Qx_set_selection, Qhandle_switch_frame;
Lisp_Object QPRIMARY;
static int read_avail_input (int);
static void get_input_pending (int *, int);
static int readable_events (int);
-static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *,
+static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
Lisp_Object, int *);
-static Lisp_Object read_char_minibuf_menu_prompt (int, int,
+static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
Lisp_Object *);
static Lisp_Object make_lispy_event (struct input_event *);
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
enum scroll_bar_part,
Lisp_Object, Lisp_Object,
- unsigned long);
+ Time);
#endif
static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
Lisp_Object, const char *const *,
- Lisp_Object *, unsigned);
+ Lisp_Object *, EMACS_INT);
static Lisp_Object make_lispy_switch_frame (Lisp_Object);
static int help_char_p (Lisp_Object);
static void save_getcjmp (jmp_buf);
cmd_error (Lisp_Object data)
{
Lisp_Object old_level, old_length;
- char macroerror[50];
+ char macroerror[sizeof "After..kbd macro iterations: "
+ + INT_STRLEN_BOUND (EMACS_INT)];
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
if (executing_kbd_macro_iterations == 1)
sprintf (macroerror, "After 1 kbd macro iteration: ");
else
- sprintf (macroerror, "After %d kbd macro iterations: ",
+ sprintf (macroerror, "After %"pI"d kbd macro iterations: ",
executing_kbd_macro_iterations);
}
else
/* This is the actual command reading loop,
sans error-handling encapsulation. */
-static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
int, int, int);
void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (EMACS_INT, int);
message_with_string ("%s is undefined", keys, 0);
KVAR (current_kboard, defining_kbd_macro) = Qnil;
update_mode_lines = 1;
- KVAR (current_kboard, Vprefix_arg) = Qnil;
+ /* If this is a down-mouse event, don't reset prefix-arg;
+ pass it to the command run by the up event. */
+ if (EVENT_HAS_PARAMETERS (last_command_event))
+ {
+ Lisp_Object breakdown
+ = parse_modifiers (EVENT_HEAD (last_command_event));
+ int modifiers = XINT (XCAR (XCDR (breakdown)));
+ if (!(modifiers & down_modifier))
+ KVAR (current_kboard, Vprefix_arg) = Qnil;
+ }
+ else
+ KVAR (current_kboard, Vprefix_arg) = Qnil;
}
else
{
}
static Lisp_Object
-safe_run_hook_funcall (size_t nargs, Lisp_Object *args)
+safe_run_hook_funcall (ptrdiff_t nargs, Lisp_Object *args)
{
eassert (nargs == 1);
if (CONSP (Vinhibit_quit))
Value is t if we showed a menu and the user rejected it. */
Lisp_Object
-read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
+read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event,
int *used_mouse_menu, struct timeval *end_time)
{
volatile Lisp_Object c;
c = Faref (Vexecuting_kbd_macro, make_number (executing_kbd_macro_index));
if (STRINGP (Vexecuting_kbd_macro)
- && (XINT (c) & 0x80) && (XUINT (c) <= 0xff))
- XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
+ && (XFASTINT (c) & 0x80) && (XFASTINT (c) <= 0xff))
+ XSETFASTINT (c, CHAR_META | (XFASTINT (c) & ~0x80));
executing_kbd_macro_index++;
goto exit;
if ((STRINGP (KVAR (current_kboard, Vkeyboard_translate_table))
- && SCHARS (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c))
+ && UNSIGNED_CMP (XFASTINT (c), <,
+ SCHARS (KVAR (current_kboard,
+ Vkeyboard_translate_table))))
|| (VECTORP (KVAR (current_kboard, Vkeyboard_translate_table))
- && ASIZE (KVAR (current_kboard, Vkeyboard_translate_table)) > (unsigned) XFASTINT (c))
+ && UNSIGNED_CMP (XFASTINT (c), <,
+ ASIZE (KVAR (current_kboard,
+ Vkeyboard_translate_table))))
|| (CHAR_TABLE_P (KVAR (current_kboard, Vkeyboard_translate_table))
&& CHARACTERP (c)))
{
save the echo area contents for it to refer to. */
if (INTEGERP (c)
&& ! NILP (Vinput_method_function)
- && (unsigned) XINT (c) >= ' '
- && (unsigned) XINT (c) != 127
- && (unsigned) XINT (c) < 256)
+ && ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127)
{
previous_echo_area_message = Fcurrent_message ();
Vinput_method_previous_message = previous_echo_area_message;
/* Don't run the input method within a key sequence,
after the first event of the key sequence. */
&& NILP (prev_event)
- && (unsigned) XINT (c) >= ' '
- && (unsigned) XINT (c) != 127
- && (unsigned) XINT (c) < 256)
+ && ' ' <= XINT (c) && XINT (c) < 256 && XINT (c) != 127)
{
Lisp_Object keys;
int key_count, key_count_reset;
if (INTEGERP (c))
{
if (XUINT (c) < 0x100)
- putc (XINT (c), dribble);
+ putc (XUINT (c), dribble);
else
fprintf (dribble, " 0x%"pI"x", XUINT (c));
}
\f
/* Clear input event EVENT. */
-static INLINE void
+static inline void
clear_event (struct input_event *event)
{
event->kind = NO_EVENT;
Lisp_Object bar_window;
enum scroll_bar_part part;
Lisp_Object x, y;
- unsigned long t;
+ Time t;
*kbp = current_kboard;
/* Note that this uses F to determine which terminal to look at.
static int last_mouse_button;
static int last_mouse_x;
static int last_mouse_y;
-static unsigned long button_down_time;
+static Time button_down_time;
/* The number of clicks in this multiple-click. */
static Lisp_Object
make_lispy_position (struct frame *f, Lisp_Object x, Lisp_Object y,
- unsigned long t)
+ Time t)
{
enum window_part part;
Lisp_Object posn = Qnil;
Qfunction_key,
KVAR (current_kboard, Vsystem_key_alist),
0, &KVAR (current_kboard, system_key_syms),
- (unsigned) -1);
+ TYPE_MAXIMUM (EMACS_INT));
}
return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
&& (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
&& button_down_time != 0
&& (EQ (Vdouble_click_time, Qt)
- || (INTEGERP (Vdouble_click_time)
- && ((int)(event->timestamp - button_down_time)
- < XINT (Vdouble_click_time)))));
+ || (NATNUMP (Vdouble_click_time)
+ && (event->timestamp - button_down_time
+ < XFASTINT (Vdouble_click_time)))));
}
last_mouse_button = button;
&& (eabs (XINT (event->y) - last_mouse_y) <= fuzz)
&& button_down_time != 0
&& (EQ (Vdouble_click_time, Qt)
- || (INTEGERP (Vdouble_click_time)
- && ((int)(event->timestamp - button_down_time)
- < XINT (Vdouble_click_time)))));
+ || (NATNUMP (Vdouble_click_time)
+ && (event->timestamp - button_down_time
+ < XFASTINT (Vdouble_click_time)))));
if (is_double)
{
double_click_count++;
static Lisp_Object
make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
- Lisp_Object x, Lisp_Object y, unsigned long t)
+ Lisp_Object x, Lisp_Object y, Time t)
{
/* Is it a scroll bar movement? */
if (frame && ! NILP (bar_window))
Lisp_Object parsed;
parsed = parse_modifiers (symbol);
- return apply_modifiers ((int) XINT (XCAR (XCDR (parsed))),
+ return apply_modifiers (XFASTINT (XCAR (XCDR (parsed))),
XCAR (parsed));
}
static Lisp_Object
modify_event_symbol (EMACS_INT symbol_num, unsigned int modifiers, Lisp_Object symbol_kind,
Lisp_Object name_alist_or_stem, const char *const *name_table,
- Lisp_Object *symbol_table, unsigned int table_size)
+ Lisp_Object *symbol_table, EMACS_INT table_size)
{
Lisp_Object value;
Lisp_Object symbol_int;
value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
else if (STRINGP (name_alist_or_stem))
{
- int len = SBYTES (name_alist_or_stem);
- char *buf = (char *) alloca (len + 50);
- sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
- XINT (symbol_int) + 1);
+ char *buf;
+ ptrdiff_t len = (SBYTES (name_alist_or_stem)
+ + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
+ USE_SAFE_ALLOCA;
+ SAFE_ALLOCA (buf, char *, len);
+ esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
+ XINT (symbol_int) + 1);
value = intern (buf);
+ SAFE_FREE ();
}
else if (name_table != 0 && name_table[symbol_num])
value = intern (name_table[symbol_num]);
if (NILP (value))
{
- char buf[20];
+ char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
sprintf (buf, "key-%"pI"d", symbol_num);
value = intern (buf);
}
{
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
+ ptrdiff_t nmaps;
/* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
in the current keymaps, or nil where it is not a prefix. */
Lisp_Object def, tail;
- int mapno;
+ ptrdiff_t mapno;
Lisp_Object oquit;
/* In order to build the menus, we need to call the keymap
recognized when the menu-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
if (CONSP (def))
{
menu_bar_one_keymap_changed_items = Qnil;
- map_keymap (def, menu_bar_item, Qnil, NULL, 1);
+ map_keymap_canonical (def, menu_bar_item, Qnil, NULL);
}
}
/* If we got no definition, this item is just unselectable text which
is OK in a submenu but not in the menubar. */
if (NILP (def))
- return (inmenubar ? 0 : 1);
+ return (!inmenubar);
/* See if this is a separate pane or a submenu. */
def = AREF (item_properties, ITEM_PROPERTY_DEF);
tool_bar_items (Lisp_Object reuse, int *nitems)
{
Lisp_Object *maps;
- int nmaps, i;
+ ptrdiff_t nmaps, i;
Lisp_Object oquit;
Lisp_Object *tmaps;
recognized when the tool-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
/* `:label LABEL-STRING'. */
PROP (TOOL_BAR_ITEM_LABEL) = STRINGP (value)
? value
- : make_string (bad_label, strlen (bad_label));
+ : build_string (bad_label);
have_label = 1;
}
else if (EQ (ikey, QCfilter))
Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION);
const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : "";
const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
- EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+ ptrdiff_t max_lbl =
+ 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
char *buf = (char *) xmalloc (max_lbl + 1);
Lisp_Object new_lbl;
- size_t caption_len = strlen (capt);
+ ptrdiff_t caption_len = strlen (capt);
if (caption_len <= max_lbl && capt[0] != '\0')
{
if (strlen (label) <= max_lbl && label[0] != '\0')
{
- int j;
+ ptrdiff_t j;
if (label != buf)
strcpy (buf, label);
else
label = "";
- new_lbl = Fupcase_initials (make_string (label, strlen (label)));
+ new_lbl = Fupcase_initials (build_string (label));
if (SCHARS (new_lbl) <= tool_bar_max_label_size)
PROP (TOOL_BAR_ITEM_LABEL) = new_lbl;
else
and do auto-saving in the inner call of read_char. */
static Lisp_Object
-read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
- int *used_mouse_menu)
+read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event, int *used_mouse_menu)
{
- int mapno;
+ ptrdiff_t mapno;
if (used_mouse_menu)
*used_mouse_menu = 0;
Lisp_Object *realmaps
= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
Lisp_Object value;
- int nmaps1 = 0;
+ ptrdiff_t nmaps1 = 0;
/* Use the maps that are not nil. */
for (mapno = 0; mapno < nmaps; mapno++)
We make this bigger when necessary, and never free it. */
static char *read_char_minibuf_menu_text;
/* Size of that buffer. */
-static int read_char_minibuf_menu_width;
+static ptrdiff_t read_char_minibuf_menu_width;
static Lisp_Object
-read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
+read_char_minibuf_menu_prompt (int commandflag,
+ ptrdiff_t nmaps, Lisp_Object *maps)
{
- int mapno;
+ ptrdiff_t mapno;
register Lisp_Object name;
- int nlength;
+ ptrdiff_t nlength;
/* FIXME: Use the minibuffer's frame width. */
- int width = FRAME_COLS (SELECTED_FRAME ()) - 4;
- int idx = -1;
+ ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
+ ptrdiff_t idx = -1;
int nobindings = 1;
Lisp_Object rest, vector;
char *menu;
/* Make sure we have a big enough buffer for the menu text. */
width = max (width, SBYTES (name));
- if (read_char_minibuf_menu_text == 0)
+ if (STRING_BYTES_BOUND - 4 < width)
+ memory_full (SIZE_MAX);
+ if (width + 4 > read_char_minibuf_menu_width)
{
- read_char_minibuf_menu_width = width + 4;
- read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
- }
- else if (width + 4 > read_char_minibuf_menu_width)
- {
- read_char_minibuf_menu_width = width + 4;
read_char_minibuf_menu_text
= (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+ read_char_minibuf_menu_width = width + 4;
}
menu = read_char_minibuf_menu_text;
while (1)
{
int notfirst = 0;
- int i = nlength;
+ ptrdiff_t i = nlength;
Lisp_Object obj;
Lisp_Object orig_defn_macro;
< width
|| !notfirst)
{
- int thiswidth;
+ ptrdiff_t thiswidth;
/* Punctuate between strings. */
if (notfirst)
if (! char_matches)
{
/* Add as much of string as fits. */
- thiswidth = SCHARS (desc);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (desc), width - i);
memcpy (menu + i, SDATA (desc), thiswidth);
i += thiswidth;
strcpy (menu + i, " = ");
}
/* Add as much of string as fits. */
- thiswidth = SCHARS (s);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (s), width - i);
memcpy (menu + i, SDATA (s), thiswidth);
i += thiswidth;
menu[i] = 0;
NEXT may be the same array as CURRENT. */
static int
-follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs,
- Lisp_Object *next)
+follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
+ Lisp_Object *defs, Lisp_Object *next)
{
- int i, first_binding;
+ ptrdiff_t i, first_binding;
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
The return value is non-zero if the remapping actually took place. */
static int
-keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
int input, int doit, int *diff, Lisp_Object prompt)
{
Lisp_Object next, key;
*diff = len - (fkey->end - fkey->start);
- if (input + *diff >= bufsize)
+ if (bufsize - input <= *diff)
error ("Key sequence too long");
/* Shift the keys that follow fkey->end. */
from the selected window's buffer. */
static int
-read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
int dont_downcase_last, int can_return_switch_frame,
int fix_current_buffer)
{
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
- int nmaps_allocated = 0;
+ ptrdiff_t nmaps;
+ ptrdiff_t nmaps_allocated = 0;
/* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
the current keymaps. */
/* The index in submaps[] of the first keymap that has a binding for
this key sequence. In other words, the lowest i such that
submaps[i] is non-nil. */
- int first_binding;
+ ptrdiff_t first_binding;
/* Index of the first key that has no binding.
It is useless to try fkey.start larger than that. */
int first_unbound;
}
else
{
- int nminor;
- int total;
+ ptrdiff_t nminor;
+ ptrdiff_t total;
Lisp_Object *maps;
nminor = current_minor_maps (0, &maps);
echo_local_start and keys_local_start allow us to throw away
just one key. */
int echo_local_start IF_LINT (= 0);
- int keys_local_start, local_first_binding;
+ int keys_local_start;
+ ptrdiff_t local_first_binding;
eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
eassert (indec.start <= indec.end);
&& (NILP (fake_prefixed_keys)
|| NILP (Fmemq (key, fake_prefixed_keys))))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
keybuf[t+1] = key;
char *newmessage;
int message_p = push_message ();
int count = SPECPDL_INDEX ();
+ ptrdiff_t newmessage_len, newmessage_alloc;
+ USE_SAFE_ALLOCA;
record_unwind_protect (pop_message_unwind, Qnil);
binding = Fkey_description (bindings, Qnil);
-
- newmessage
- = (char *) alloca (SCHARS (SYMBOL_NAME (function))
- + SBYTES (binding)
- + 100);
- sprintf (newmessage, "You can run the command `%s' with %s",
- SDATA (SYMBOL_NAME (function)),
- SDATA (binding));
+ newmessage_alloc =
+ (sizeof "You can run the command `' with "
+ + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
+ SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
+ newmessage_len =
+ esprintf (newmessage, "You can run the command `%s' with %s",
+ SDATA (SYMBOL_NAME (function)),
+ SDATA (binding));
message2 (newmessage,
- strlen (newmessage),
+ newmessage_len,
STRING_MULTIBYTE (binding));
if (NUMBERP (Vsuggest_key_bindings))
waited = sit_for (Vsuggest_key_bindings, 0, 2);
if (!NILP (waited) && message_p)
restore_message ();
+ SAFE_FREE ();
unbind_to (count, Qnil);
}
}
(void)
{
Lisp_Object temp;
- XSETFASTINT (temp, command_loop_level + minibuf_level);
+ /* Wrap around reliably on integer overflow. */
+ EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK);
+ XSETINT (temp, sum);
return temp;
}
DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
"FOpen dribble file: ",
doc: /* Start writing all keyboard characters to a dribble file called FILE.
-If FILE is nil, close any open dribble file. */)
+If FILE is nil, close any open dribble file.
+The file will be closed when Emacs exits. */)
(Lisp_Object file)
{
if (dribble)