summaryrefslogtreecommitdiff
path: root/src/callint.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2018-01-29 09:42:42 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2018-01-29 09:45:04 -0800
commit29abae3572090a86beedb66822ccf34356c8a00c (patch)
tree0ee7184012c3dc00b9c546e4b4204b503d46a4fa /src/callint.c
parent81c2c2fa319b27550a2eb5021618c5eef3e813fd (diff)
downloademacs-29abae3572090a86beedb66822ccf34356c8a00c.tar.gz
Simplify Fcall_interactively
* src/callint.c (Fcall_interactively): Use C99 constructs to simplify the code a bit. Stop worrying about circa-1990 compiler bugs.
Diffstat (limited to 'src/callint.c')
-rw-r--r--src/callint.c286
1 files changed, 109 insertions, 177 deletions
diff --git a/src/callint.c b/src/callint.c
index 3d2ed0016cc..08a8bba4646 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -271,45 +271,16 @@ invoke it. If KEYS is omitted or nil, the return value of
`this-command-keys-vector' is used. */)
(Lisp_Object function, Lisp_Object record_flag, Lisp_Object keys)
{
- /* `args' will contain the array of arguments to pass to the function.
- `visargs' will contain the same list but in a nicer form, so that if we
- pass it to Fformat_message it will be understandable to a human. */
- Lisp_Object *args, *visargs;
- Lisp_Object specs;
- Lisp_Object filter_specs;
- Lisp_Object teml;
- Lisp_Object up_event;
- Lisp_Object enable;
- USE_SAFE_ALLOCA;
ptrdiff_t speccount = SPECPDL_INDEX ();
- /* The index of the next element of this_command_keys to examine for
- the 'e' interactive code. */
- ptrdiff_t next_event;
-
- Lisp_Object prefix_arg;
- char *string, *string_end;
- ptrdiff_t string_len;
- const char *tem;
-
- /* If varies[i] > 0, the i'th argument shouldn't just have its value
- in this call quoted in the command history. It should be
- recorded as a call to the function named callint_argfuns[varies[i]]. */
- signed char *varies;
-
- ptrdiff_t i, nargs;
- ptrdiff_t mark;
- bool arg_from_tty = 0;
+ bool arg_from_tty = false;
ptrdiff_t key_count;
- bool record_then_fail = 0;
+ bool record_then_fail = false;
- Lisp_Object save_this_command, save_last_command;
- Lisp_Object save_this_original_command, save_real_this_command;
-
- save_this_command = Vthis_command;
- save_this_original_command = Vthis_original_command;
- save_real_this_command = Vreal_this_command;
- save_last_command = KVAR (current_kboard, Vlast_command);
+ Lisp_Object save_this_command = Vthis_command;
+ Lisp_Object save_this_original_command = Vthis_original_command;
+ Lisp_Object save_real_this_command = Vreal_this_command;
+ Lisp_Object save_last_command = KVAR (current_kboard, Vlast_command);
if (NILP (keys))
keys = this_command_keys, key_count = this_command_key_count;
@@ -320,55 +291,44 @@ invoke it. If KEYS is omitted or nil, the return value of
}
/* Save this now, since use of minibuffer will clobber it. */
- prefix_arg = Vcurrent_prefix_arg;
-
- if (SYMBOLP (function))
- enable = Fget (function, Qenable_recursive_minibuffers);
- else
- enable = Qnil;
+ Lisp_Object prefix_arg = Vcurrent_prefix_arg;
- specs = Qnil;
- string = 0;
- /* The idea of FILTER_SPECS is to provide a way to
- specify how to represent the arguments in command history.
- The feature is not fully implemented. */
- filter_specs = Qnil;
+ Lisp_Object enable = (SYMBOLP (function)
+ ? Fget (function, Qenable_recursive_minibuffers)
+ : Qnil);
/* If k or K discard an up-event, save it here so it can be retrieved with
U. */
- up_event = Qnil;
+ Lisp_Object up_event = Qnil;
/* Set SPECS to the interactive form, or barf if not interactive. */
- {
- Lisp_Object form;
- form = Finteractive_form (function);
- if (CONSP (form))
- specs = filter_specs = Fcar (XCDR (form));
- else
- wrong_type_argument (Qcommandp, function);
- }
+ Lisp_Object form = Finteractive_form (function);
+ if (! CONSP (form))
+ wrong_type_argument (Qcommandp, function);
+ Lisp_Object specs = Fcar (XCDR (form));
+
+ /* At this point the value of SPECS could help provide a way to
+ specify how to represent the arguments in command history.
+ The feature is not fully implemented. */
/* If SPECS is not a string, invent one. */
if (! STRINGP (specs))
{
- Lisp_Object input;
Lisp_Object funval = Findirect_function (function, Qt);
uintmax_t events = num_input_events;
- input = specs;
+ Lisp_Object input = specs;
/* Compute the arg values using the user's expression. */
specs = Feval (specs,
CONSP (funval) && EQ (Qclosure, XCAR (funval))
? CAR_SAFE (XCDR (funval)) : Qnil);
if (events != num_input_events || !NILP (record_flag))
{
- /* We should record this command on the command history. */
- Lisp_Object values;
- Lisp_Object this_cmd;
- /* Make a copy of the list of values, for the command history,
+ /* We should record this command on the command history.
+ Make a copy of the list of values, for the command history,
and turn them into things we can eval. */
- values = quotify_args (Fcopy_sequence (specs));
+ Lisp_Object values = quotify_args (Fcopy_sequence (specs));
fix_command (input, values);
- this_cmd = Fcons (function, values);
+ Lisp_Object this_cmd = Fcons (function, values);
if (history_delete_duplicates)
Vcommand_history = Fdelete (this_cmd, Vcommand_history);
Vcommand_history = Fcons (this_cmd, Vcommand_history);
@@ -376,7 +336,7 @@ invoke it. If KEYS is omitted or nil, the return value of
/* Don't keep command history around forever. */
if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
{
- teml = Fnthcdr (Vhistory_length, Vcommand_history);
+ Lisp_Object teml = Fnthcdr (Vhistory_length, Vcommand_history);
if (CONSP (teml))
XSETCDR (teml, Qnil);
}
@@ -387,48 +347,42 @@ invoke it. If KEYS is omitted or nil, the return value of
Vreal_this_command = save_real_this_command;
kset_last_command (current_kboard, save_last_command);
- Lisp_Object result
- = unbind_to (speccount, CALLN (Fapply, Qfuncall_interactively,
- function, specs));
- SAFE_FREE ();
- return result;
+ return unbind_to (speccount, CALLN (Fapply, Qfuncall_interactively,
+ function, specs));
}
/* SPECS is set to a string; use it as an interactive prompt.
Copy it so that STRING will be valid even if a GC relocates SPECS. */
- SAFE_ALLOCA_STRING (string, specs);
- string_len = SBYTES (specs);
- string_end = string + string_len;
-
- /* Here if function specifies a string to control parsing the defaults. */
+ USE_SAFE_ALLOCA;
+ ptrdiff_t string_len = SBYTES (specs);
+ char *string = SAFE_ALLOCA (string_len + 1);
+ memcpy (string, SDATA (specs), string_len + 1);
+ char *string_end = string + string_len;
- /* Set next_event to point to the first event with parameters. */
+ /* The index of the next element of this_command_keys to examine for
+ the 'e' interactive code. Initialize it to point to the first
+ event with parameters. */
+ ptrdiff_t next_event;
for (next_event = 0; next_event < key_count; next_event++)
if (EVENT_HAS_PARAMETERS (AREF (keys, next_event)))
break;
/* Handle special starting chars `*' and `@'. Also `-'. */
/* Note that `+' is reserved for user extensions. */
- while (1)
+ for (;; string++)
{
if (*string == '+')
error ("`+' is not used in `interactive' for ordinary commands");
else if (*string == '*')
{
- string++;
if (!NILP (BVAR (current_buffer, read_only)))
{
if (!NILP (record_flag))
{
- char *p = string;
- while (p < string_end)
- {
- if (! (*p == 'r' || *p == 'p' || *p == 'P'
- || *p == '\n'))
- Fbarf_if_buffer_read_only (Qnil);
- p++;
- }
- record_then_fail = 1;
+ for (char *p = string + 1; p < string_end; p++)
+ if (! (*p == 'r' || *p == 'p' || *p == 'P' || *p == '\n'))
+ Fbarf_if_buffer_read_only (Qnil);
+ record_then_fail = true;
}
else
Fbarf_if_buffer_read_only (Qnil);
@@ -436,14 +390,12 @@ invoke it. If KEYS is omitted or nil, the return value of
}
/* Ignore this for semi-compatibility with Lucid. */
else if (*string == '-')
- string++;
+ ;
else if (*string == '@')
{
- Lisp_Object event, w;
-
- event = (next_event < key_count
- ? AREF (keys, next_event)
- : Qnil);
+ Lisp_Object w, event = (next_event < key_count
+ ? AREF (keys, next_event)
+ : Qnil);
if (EVENT_HAS_PARAMETERS (event)
&& (w = XCDR (event), CONSP (w))
&& (w = XCAR (w), CONSP (w))
@@ -458,32 +410,23 @@ invoke it. If KEYS is omitted or nil, the return value of
Fselect_window (w, Qnil);
}
- string++;
}
else if (*string == '^')
- {
- call0 (Qhandle_shift_selection);
- string++;
- }
+ call0 (Qhandle_shift_selection);
else break;
}
/* Count the number of arguments, which is two (the function itself and
`funcall-interactively') plus the number of arguments the interactive spec
would have us give to the function. */
- tem = string;
- for (nargs = 2; tem < string_end; )
+ ptrdiff_t nargs = 2;
+ for (char const *tem = string; tem < string_end; tem++)
{
/* 'r' specifications ("point and mark as 2 numeric args")
produce *two* arguments. */
- if (*tem == 'r')
- nargs += 2;
- else
- nargs++;
+ nargs += 1 + (*tem == 'r');
tem = memchr (tem, '\n', string_len - (tem - string));
- if (tem)
- ++tem;
- else
+ if (!tem)
break;
}
@@ -491,11 +434,18 @@ invoke it. If KEYS is omitted or nil, the return value of
&& MOST_POSITIVE_FIXNUM < nargs)
memory_full (SIZE_MAX);
- /* Allocate them all at one go. This wastes a bit of memory, but
+ /* ARGS will contain the array of arguments to pass to the function.
+ VISARGS will contain the same list but in a nicer form, so that if we
+ pass it to Fformat_message it will be understandable to a human.
+ Allocate them all at one go. This wastes a bit of memory, but
it's OK to trade space for speed. */
+ Lisp_Object *args;
SAFE_NALLOCA (args, 3, nargs);
- visargs = args + nargs;
- varies = (signed char *) (visargs + nargs);
+ Lisp_Object *visargs = args + nargs;
+ /* If varies[I] > 0, the Ith argument shouldn't just have its value
+ in this call quoted in the command history. It should be
+ recorded as a call to the function named callint_argfuns[varies[I]]. */
+ signed char *varies = (signed char *) (visargs + nargs);
memclear (args, nargs * (2 * word_size + 1));
args = ptr_bounds_clip (args, nargs * sizeof *args);
@@ -505,8 +455,8 @@ invoke it. If KEYS is omitted or nil, the return value of
if (!NILP (enable))
specbind (Qenable_recursive_minibuffers, Qt);
- tem = string;
- for (i = 2; tem < string_end; i++)
+ char const *tem = string;
+ for (ptrdiff_t i = 2; tem < string_end; i++)
{
char *pnl = memchr (tem + 1, '\n', string_len - (tem + 1 - string));
ptrdiff_t sz = pnl ? pnl - (tem + 1) : string_end - (tem + 1);
@@ -520,9 +470,7 @@ invoke it. If KEYS is omitted or nil, the return value of
visargs[i] = Fcompleting_read (callint_message,
Vobarray, Qfboundp, Qt,
Qnil, Qnil, Qnil, Qnil);
- /* Passing args[i] directly stimulates compiler bug. */
- teml = visargs[i];
- args[i] = Fintern (teml, Qnil);
+ args[i] = Fintern (visargs[i], Qnil);
break;
case 'b': /* Name of existing buffer. */
@@ -534,7 +482,8 @@ invoke it. If KEYS is omitted or nil, the return value of
case 'B': /* Name of buffer, possibly nonexistent. */
args[i] = Fread_buffer (callint_message,
- Fother_buffer (Fcurrent_buffer (), Qnil, Qnil),
+ Fother_buffer (Fcurrent_buffer (),
+ Qnil, Qnil),
Qnil, Qnil);
break;
@@ -545,20 +494,17 @@ invoke it. If KEYS is omitted or nil, the return value of
Qface, Qminibuffer_prompt, callint_message);
args[i] = Fread_char (callint_message, Qnil, Qnil);
message1_nolog (0);
- /* 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);
+ if (! CHARACTERP (args[i]))
+ error ("Non-character input-event");
+ visargs[i] = Fchar_to_string (args[i]);
break;
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. */
- teml = visargs[i];
- args[i] = Fintern (teml, Qnil);
+ args[i] = Fintern (visargs[i], Qnil);
break;
case 'd': /* Value of point. Does not do I/O. */
@@ -569,8 +515,8 @@ invoke it. If KEYS is omitted or nil, the return value of
break;
case 'D': /* Directory name. */
- args[i] = read_file_name (BVAR (current_buffer, directory), Qlambda, Qnil,
- Qfile_directory_p);
+ args[i] = read_file_name (BVAR (current_buffer, directory), Qlambda,
+ Qnil, Qfile_directory_p);
break;
case 'f': /* Existing file name. */
@@ -601,21 +547,19 @@ invoke it. If KEYS is omitted or nil, the return value of
args[i] = Fread_key_sequence (callint_message,
Qnil, Qnil, Qnil, Qnil);
unbind_to (speccount1, Qnil);
- teml = args[i];
- visargs[i] = Fkey_description (teml, Qnil);
+ visargs[i] = Fkey_description (args[i], Qnil);
/* If the key sequence ends with a down-event,
discard the following up-event. */
- teml = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
+ Lisp_Object teml
+ = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
if (CONSP (teml))
teml = XCAR (teml);
if (SYMBOLP (teml))
{
- Lisp_Object tem2;
-
teml = Fget (teml, Qevent_symbol_elements);
/* Ignore first element, which is the base key. */
- tem2 = Fmemq (Qdown, Fcdr (teml));
+ Lisp_Object tem2 = Fmemq (Qdown, Fcdr (teml));
if (! NILP (tem2))
up_event = Fread_event (Qnil, Qnil, Qnil);
}
@@ -632,22 +576,20 @@ invoke it. If KEYS is omitted or nil, the return value of
Qface, Qminibuffer_prompt, callint_message);
args[i] = Fread_key_sequence_vector (callint_message,
Qnil, Qt, Qnil, Qnil);
- teml = args[i];
- visargs[i] = Fkey_description (teml, Qnil);
+ visargs[i] = Fkey_description (args[i], Qnil);
unbind_to (speccount1, Qnil);
/* If the key sequence ends with a down-event,
discard the following up-event. */
- teml = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
+ Lisp_Object teml
+ = Faref (args[i], make_number (XINT (Flength (args[i])) - 1));
if (CONSP (teml))
teml = XCAR (teml);
if (SYMBOLP (teml))
{
- Lisp_Object tem2;
-
teml = Fget (teml, Qevent_symbol_elements);
/* Ignore first element, which is the base key. */
- tem2 = Fmemq (Qdown, Fcdr (teml));
+ Lisp_Object tem2 = Fmemq (Qdown, Fcdr (teml));
if (! NILP (tem2))
up_event = Fread_event (Qnil, Qnil, Qnil);
}
@@ -659,8 +601,7 @@ invoke it. If KEYS is omitted or nil, the return value of
{
args[i] = Fmake_vector (make_number (1), up_event);
up_event = Qnil;
- teml = args[i];
- visargs[i] = Fkey_description (teml, Qnil);
+ visargs[i] = Fkey_description (args[i], Qnil);
}
break;
@@ -671,18 +612,18 @@ invoke it. If KEYS is omitted or nil, the return value of
? SSDATA (SYMBOL_NAME (function))
: "command"));
args[i] = AREF (keys, next_event);
- next_event++;
varies[i] = -1;
/* Find the next parameterized event. */
- while (next_event < key_count
- && !(EVENT_HAS_PARAMETERS (AREF (keys, next_event))))
+ do
next_event++;
+ while (next_event < key_count
+ && ! EVENT_HAS_PARAMETERS (AREF (keys, next_event)));
break;
case 'm': /* Value of mark. Does not do I/O. */
- check_mark (0);
+ check_mark (false);
/* visargs[i] = Qnil; */
args[i] = BVAR (current_buffer, mark);
varies[i] = 2;
@@ -700,9 +641,7 @@ invoke it. If KEYS is omitted or nil, the return value of
FALLTHROUGH;
case 'n': /* Read number from minibuffer. */
args[i] = call1 (Qread_number, callint_message);
- /* Passing args[i] directly stimulates compiler bug. */
- teml = args[i];
- visargs[i] = Fnumber_to_string (teml);
+ visargs[i] = Fnumber_to_string (args[i]);
break;
case 'P': /* Prefix arg in raw form. Does no I/O. */
@@ -719,15 +658,16 @@ invoke it. If KEYS is omitted or nil, the return value of
break;
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; */
- mark = marker_position (BVAR (current_buffer, mark));
- /* visargs[i] = Qnil; */
- args[i] = PT < mark ? point_marker : BVAR (current_buffer, mark);
- varies[i] = 3;
- args[++i] = PT > mark ? point_marker : BVAR (current_buffer, mark);
- varies[i] = 4;
+ {
+ check_mark (true);
+ set_marker_both (point_marker, Qnil, PT, PT_BYTE);
+ ptrdiff_t mark = marker_position (BVAR (current_buffer, mark));
+ /* visargs[i] = visargs[i + 1] = Qnil; */
+ args[i] = PT < mark ? point_marker : BVAR (current_buffer, mark);
+ varies[i] = 3;
+ args[++i] = PT > mark ? point_marker : BVAR (current_buffer, mark);
+ varies[i] = 4;
+ }
break;
case 's': /* String read via minibuffer without
@@ -739,9 +679,7 @@ invoke it. If KEYS is omitted or nil, the return value of
case 'S': /* Any symbol. */
visargs[i] = Fread_string (callint_message,
Qnil, Qnil, Qnil, Qnil);
- /* Passing args[i] directly stimulates compiler bug. */
- teml = visargs[i];
- args[i] = Fintern (teml, Qnil);
+ args[i] = Fintern (visargs[i], Qnil);
break;
case 'v': /* Variable name: symbol that is
@@ -798,13 +736,14 @@ invoke it. If KEYS is omitted or nil, the return value of
else
letter = *((unsigned char *) tem);
- error ("Invalid control letter `%c' (#o%03o, #x%04x) in interactive calling string",
+ error (("Invalid control letter `%c' (#o%03o, #x%04x)"
+ " in interactive calling string"),
(int) letter, letter, letter);
}
}
if (varies[i] == 0)
- arg_from_tty = 1;
+ arg_from_tty = true;
if (NILP (visargs[i]) && STRINGP (args[i]))
visargs[i] = args[i];
@@ -825,19 +764,16 @@ invoke it. If KEYS is omitted or nil, the return value of
/* We don't need `visargs' any more, so let's recycle it since we need
an array of just the same size. */
visargs[1] = function;
- for (i = 2; i < nargs; i++)
- {
- if (varies[i] > 0)
- visargs[i] = list1 (intern (callint_argfuns[varies[i]]));
- else
- visargs[i] = quotify_arg (args[i]);
- }
+ for (ptrdiff_t i = 2; i < nargs; i++)
+ visargs[i] = (varies[i] > 0
+ ? list1 (intern (callint_argfuns[varies[i]]))
+ : quotify_arg (args[i]));
Vcommand_history = Fcons (Flist (nargs - 1, visargs + 1),
Vcommand_history);
/* Don't keep command history around forever. */
if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
{
- teml = Fnthcdr (Vhistory_length, Vcommand_history);
+ Lisp_Object teml = Fnthcdr (Vhistory_length, Vcommand_history);
if (CONSP (teml))
XSETCDR (teml, Qnil);
}
@@ -845,7 +781,7 @@ invoke it. If KEYS is omitted or nil, the return value of
/* If we used a marker to hold point, mark, or an end of the region,
temporarily, convert it to an integer now. */
- for (i = 2; i < nargs; i++)
+ for (ptrdiff_t i = 2; i < nargs; i++)
if (varies[i] >= 1 && varies[i] <= 4)
XSETINT (args[i], marker_position (args[i]));
@@ -857,15 +793,11 @@ invoke it. If KEYS is omitted or nil, the return value of
Vreal_this_command = save_real_this_command;
kset_last_command (current_kboard, save_last_command);
- {
- Lisp_Object val;
- specbind (Qcommand_debug_status, Qnil);
+ specbind (Qcommand_debug_status, Qnil);
- val = Ffuncall (nargs, args);
- val = unbind_to (speccount, val);
- SAFE_FREE ();
- return val;
- }
+ Lisp_Object val = Ffuncall (nargs, args);
+ SAFE_FREE ();
+ return unbind_to (speccount, val);
}
DEFUN ("prefix-numeric-value", Fprefix_numeric_value, Sprefix_numeric_value,