Unify actions and commands
* defs.h (read_command_lines, read_command_lines_1): New parameters validator and closure. * tracepoint.h (struct action_line): Remove. * breakpoint.h (struct breakpoint): Remove the 'actions' field. * defs.h (enum command_control_type): New value while_stepping_control. (struct command_line): Add comments. * breakpoint.c (breakoint_is_tracepoint): New. (breakpoint_set_commands): For tracepoints, verify the commands are permissible. (check_tracepoint_commands): New. (commands_command): Require that each new line is validated using check_tracepoint_command, if we set commands for a tracepoint. (create_tracepoint_from_upload): Likewise. (print_one_breakpoint_location): Remove the code to print actions specifically. (tracepoint_save_command): Relay to print_command_lines. * cli/cli-script.c (process_next_line): New parameters validator and closure. Handle 'while-stepping'. Call validator if not null. (read_command_lines, read_command_lines1): Likewise. (recurse_read_control_structure): New parameters validator and closure. Handle while_stepping_control. (print_command_lines): Handle while-stepping. (get_command_line, define_command, document_command): Adjust. * remote.c (remote_download_tracepoint): Adjust. * tracepoint.c (make_cleanup_free_actions, read_actions) (free_actions, do_free_actions_cleanup): Remove. (trace_actions_command): Use read_command_lines. (validate_actionline): Use error in one place. (encode_actions_1): New, extracted from... (encode_actions): ...this. Also use cleanups for exception safety. (trace_dump_command): Adjust. * mi/mi-cmd-break (mi_cmd_break_commands): Validate commands if it's tracepoint.
This commit is contained in:
parent
64e3cf3d4f
commit
a7bdde9e63
14 changed files with 377 additions and 344 deletions
|
@ -40,7 +40,9 @@
|
|||
|
||||
static enum command_control_type
|
||||
recurse_read_control_structure (char * (*read_next_line_func) (void),
|
||||
struct command_line *current_cmd);
|
||||
struct command_line *current_cmd,
|
||||
void (*validator)(char *, void *),
|
||||
void *closure);
|
||||
|
||||
static char *insert_args (char *line);
|
||||
|
||||
|
@ -117,7 +119,8 @@ get_command_line (enum command_control_type type, char *arg)
|
|||
old_chain = make_cleanup_free_command_lines (&cmd);
|
||||
|
||||
/* Read in the body of this command. */
|
||||
if (recurse_read_control_structure (read_next_line, cmd) == invalid_control)
|
||||
if (recurse_read_control_structure (read_next_line, cmd, 0, 0)
|
||||
== invalid_control)
|
||||
{
|
||||
warning (_("Error reading in canned sequence of commands."));
|
||||
do_cleanups (old_chain);
|
||||
|
@ -172,9 +175,16 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
|
|||
}
|
||||
|
||||
/* A while command. Recursively print its subcommands and continue. */
|
||||
if (list->control_type == while_control)
|
||||
if (list->control_type == while_control
|
||||
|| list->control_type == while_stepping_control)
|
||||
{
|
||||
ui_out_field_fmt (uiout, NULL, "while %s", list->line);
|
||||
/* For while-stepping, the line includes the 'while-stepping' token.
|
||||
See comment in process_next_line for explanation. Here,
|
||||
take care not print 'while-stepping' twice. */
|
||||
if (list->control_type == while_control)
|
||||
ui_out_field_fmt (uiout, NULL, "while %s", list->line);
|
||||
else
|
||||
ui_out_field_string (uiout, NULL, list->line);
|
||||
ui_out_text (uiout, "\n");
|
||||
print_command_lines (uiout, *list->body_list, depth + 1);
|
||||
if (depth)
|
||||
|
@ -876,7 +886,8 @@ read_next_line (void)
|
|||
Otherwise, only "end" is recognized. */
|
||||
|
||||
static enum misc_command_type
|
||||
process_next_line (char *p, struct command_line **command, int parse_commands)
|
||||
process_next_line (char *p, struct command_line **command, int parse_commands,
|
||||
void (*validator)(char *, void *), void *closure)
|
||||
{
|
||||
char *p_end;
|
||||
char *p_start;
|
||||
|
@ -920,7 +931,22 @@ process_next_line (char *p, struct command_line **command, int parse_commands)
|
|||
|
||||
/* Check for while, if, break, continue, etc and build a new command
|
||||
line structure for them. */
|
||||
if (p_end - p > 5 && !strncmp (p, "while", 5))
|
||||
if ((p_end - p >= 14 && !strncmp (p, "while-stepping", 14))
|
||||
|| (p_end -p >= 2 && !strncmp (p, "ws", 2)))
|
||||
{
|
||||
/* Because validate_actionline and encode_action lookup
|
||||
command's line as command, we need the line to
|
||||
include 'while-stepping'.
|
||||
|
||||
For 'ws' alias, the command will have 'ws', not expanded
|
||||
to 'while-stepping'. This is intentional -- we don't
|
||||
really want frontend to send a command list with 'ws',
|
||||
and next break-info returning command line with 'while-stepping'.
|
||||
This should work, but might cause the breakpoint to be marked as
|
||||
changed while it's actually not. */
|
||||
*command = build_command_line (while_stepping_control, p);
|
||||
}
|
||||
else if (p_end - p > 5 && !strncmp (p, "while", 5))
|
||||
{
|
||||
char *first_arg;
|
||||
first_arg = p + 5;
|
||||
|
@ -986,6 +1012,20 @@ process_next_line (char *p, struct command_line **command, int parse_commands)
|
|||
(*command)->body_list = NULL;
|
||||
}
|
||||
|
||||
if (validator)
|
||||
{
|
||||
volatile struct gdb_exception ex;
|
||||
TRY_CATCH (ex, RETURN_MASK_ALL)
|
||||
{
|
||||
validator ((*command)->line, closure);
|
||||
}
|
||||
if (ex.reason < 0)
|
||||
{
|
||||
xfree (*command);
|
||||
throw_exception (ex);
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing special. */
|
||||
return ok_command;
|
||||
}
|
||||
|
@ -998,7 +1038,9 @@ process_next_line (char *p, struct command_line **command, int parse_commands)
|
|||
|
||||
static enum command_control_type
|
||||
recurse_read_control_structure (char * (*read_next_line_func) (void),
|
||||
struct command_line *current_cmd)
|
||||
struct command_line *current_cmd,
|
||||
void (*validator)(char *, void *),
|
||||
void *closure)
|
||||
{
|
||||
int current_body, i;
|
||||
enum misc_command_type val;
|
||||
|
@ -1023,7 +1065,8 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
|
|||
|
||||
next = NULL;
|
||||
val = process_next_line (read_next_line_func (), &next,
|
||||
current_cmd->control_type != python_control);
|
||||
current_cmd->control_type != python_control,
|
||||
validator, closure);
|
||||
|
||||
/* Just skip blanks and comments. */
|
||||
if (val == nop_command)
|
||||
|
@ -1032,6 +1075,7 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
|
|||
if (val == end_command)
|
||||
{
|
||||
if (current_cmd->control_type == while_control
|
||||
|| current_cmd->control_type == while_stepping_control
|
||||
|| current_cmd->control_type == if_control
|
||||
|| current_cmd->control_type == python_control
|
||||
|| current_cmd->control_type == commands_control)
|
||||
|
@ -1084,12 +1128,14 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
|
|||
/* If the latest line is another control structure, then recurse
|
||||
on it. */
|
||||
if (next->control_type == while_control
|
||||
|| next->control_type == while_stepping_control
|
||||
|| next->control_type == if_control
|
||||
|| next->control_type == python_control
|
||||
|| next->control_type == commands_control)
|
||||
{
|
||||
control_level++;
|
||||
ret = recurse_read_control_structure (read_next_line_func, next);
|
||||
ret = recurse_read_control_structure (read_next_line_func, next,
|
||||
validator, closure);
|
||||
control_level--;
|
||||
|
||||
if (ret != simple_control)
|
||||
|
@ -1114,7 +1160,8 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
|
|||
#define END_MESSAGE "End with a line saying just \"end\"."
|
||||
|
||||
struct command_line *
|
||||
read_command_lines (char *prompt_arg, int from_tty, int parse_commands)
|
||||
read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
|
||||
void (*validator)(char *, void *), void *closure)
|
||||
{
|
||||
struct command_line *head;
|
||||
|
||||
|
@ -1132,7 +1179,8 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands)
|
|||
}
|
||||
}
|
||||
|
||||
head = read_command_lines_1 (read_next_line, parse_commands);
|
||||
head = read_command_lines_1 (read_next_line, parse_commands,
|
||||
validator, closure);
|
||||
|
||||
if (deprecated_readline_end_hook && from_tty && input_from_terminal_p ())
|
||||
{
|
||||
|
@ -1145,7 +1193,8 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands)
|
|||
obtained using READ_NEXT_LINE_FUNC. */
|
||||
|
||||
struct command_line *
|
||||
read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands)
|
||||
read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands,
|
||||
void (*validator)(char *, void *), void *closure)
|
||||
{
|
||||
struct command_line *head, *tail, *next;
|
||||
struct cleanup *old_chain;
|
||||
|
@ -1159,7 +1208,8 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands)
|
|||
while (1)
|
||||
{
|
||||
dont_repeat ();
|
||||
val = process_next_line (read_next_line_func (), &next, parse_commands);
|
||||
val = process_next_line (read_next_line_func (), &next, parse_commands,
|
||||
validator, closure);
|
||||
|
||||
/* Ignore blank lines or comments. */
|
||||
if (val == nop_command)
|
||||
|
@ -1180,10 +1230,12 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands)
|
|||
if (next->control_type == while_control
|
||||
|| next->control_type == if_control
|
||||
|| next->control_type == python_control
|
||||
|| next->control_type == commands_control)
|
||||
|| next->control_type == commands_control
|
||||
|| next->control_type == while_stepping_control)
|
||||
{
|
||||
control_level++;
|
||||
ret = recurse_read_control_structure (read_next_line_func, next);
|
||||
ret = recurse_read_control_structure (read_next_line_func, next,
|
||||
validator, closure);
|
||||
control_level--;
|
||||
|
||||
if (ret == invalid_control)
|
||||
|
@ -1426,7 +1478,7 @@ define_command (char *comname, int from_tty)
|
|||
*tem = tolower (*tem);
|
||||
|
||||
sprintf (tmpbuf, "Type commands for definition of \"%s\".", comfull);
|
||||
cmds = read_command_lines (tmpbuf, from_tty, 1);
|
||||
cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0);
|
||||
|
||||
if (c && c->class == class_user)
|
||||
free_command_lines (&c->user_commands);
|
||||
|
@ -1475,7 +1527,7 @@ document_command (char *comname, int from_tty)
|
|||
error (_("Command \"%s\" is built-in."), comfull);
|
||||
|
||||
sprintf (tmpbuf, "Type documentation for \"%s\".", comfull);
|
||||
doclines = read_command_lines (tmpbuf, from_tty, 0);
|
||||
doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0);
|
||||
|
||||
if (c->doc)
|
||||
xfree (c->doc);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue