Use counted_command_line everywhere

Currently command lines are reference counted using shared_ptr only
when attached to breakpoints.  This patch changes gdb to use
shared_ptr in commands as well.  This allows for the removal of
copy_command_lines.

Note that the change to execute_user_command explicitly makes a new
reference to the command line.  This will be used in a later patch.

This simplifies struct command_line based on the observation that a
given command can have at most two child bodies: an "if" can have both
"then" and "else" parts.  Perhaps the names I've chosen for the
replacements here are not very good -- your input requested.

ChangeLog
2018-05-04  Tom Tromey  <tom@tromey.com>

	* tracepoint.c (all_tracepoint_actions): Rename from
	all_tracepoint_actions_and_cleanup.  Change return type.
	(actions_command, encode_actions_1, encode_actions)
	(trace_dump_actions, tdump_command): Update.
	* remote.c (remote_download_command_source): Update.
	* python/python.c (gdbpy_eval_from_control_command)
	(python_command, python_interactive_command): Update.
	* mi/mi-cmd-break.c (mi_cmd_break_commands): Update.
	* guile/guile.c (guile_command)
	(gdbscm_eval_from_control_command, guile_command): Update.
	* compile/compile.c (compile_code_command)
	(compile_print_command, compile_to_object): Update.
	* cli/cli-script.h (struct command_lines_deleter): New.
	(counted_command_line): New typedef.
	(struct command_line): Add constructor, destructor.
	<body_list>: Remove.
	<body_list_0, body_list_1>: New members.
	(command_line_up): Remove typedef.
	(read_command_lines, read_command_lines_1, get_command_line):
	Update.
	(copy_command_lines): Don't declare.
	* cli/cli-script.c (build_command_line): Use "new".
	(get_command_line): Return counted_command_line.
	(print_command_lines, execute_user_command)
	(execute_control_command_1, while_command, if_command): Update.
	(realloc_body_list): Remove.
	(process_next_line, recurse_read_control_structure): Update.
	(read_command_lines, read_command_lines_1): Return counted_command_line.
	(free_command_lines): Use "delete".
	(copy_command_lines): Remove.
	(define_command, document_command, show_user_1): Update.
	* cli/cli-decode.h (struct cmd_list_element) <user_commands>: Now
	a counted_command_line.
	* breakpoint.h (counted_command_line): Remove typedef.
	(breakpoint_set_commands): Update.
	* breakpoint.c (check_no_tracepoint_commands)
	(validate_commands_for_breakpoint): Update.
	(breakpoint_set_commands): Change commands to be a
	counted_command_line.
	(commands_command_1, update_dprintf_command_list)
	(create_tracepoint_from_upload): Update.
This commit is contained in:
Tom Tromey 2018-04-16 23:13:18 -06:00
parent e2fc72e2c5
commit 12973681f5
12 changed files with 195 additions and 255 deletions

View File

@ -1,3 +1,47 @@
2018-05-04 Tom Tromey <tom@tromey.com>
* tracepoint.c (all_tracepoint_actions): Rename from
all_tracepoint_actions_and_cleanup. Change return type.
(actions_command, encode_actions_1, encode_actions)
(trace_dump_actions, tdump_command): Update.
* remote.c (remote_download_command_source): Update.
* python/python.c (gdbpy_eval_from_control_command)
(python_command, python_interactive_command): Update.
* mi/mi-cmd-break.c (mi_cmd_break_commands): Update.
* guile/guile.c (guile_command)
(gdbscm_eval_from_control_command, guile_command): Update.
* compile/compile.c (compile_code_command)
(compile_print_command, compile_to_object): Update.
* cli/cli-script.h (struct command_lines_deleter): New.
(counted_command_line): New typedef.
(struct command_line): Add constructor, destructor.
<body_list>: Remove.
<body_list_0, body_list_1>: New members.
(command_line_up): Remove typedef.
(read_command_lines, read_command_lines_1, get_command_line):
Update.
(copy_command_lines): Don't declare.
* cli/cli-script.c (build_command_line): Use "new".
(get_command_line): Return counted_command_line.
(print_command_lines, execute_user_command)
(execute_control_command_1, while_command, if_command): Update.
(realloc_body_list): Remove.
(process_next_line, recurse_read_control_structure): Update.
(read_command_lines, read_command_lines_1): Return counted_command_line.
(free_command_lines): Use "delete".
(copy_command_lines): Remove.
(define_command, document_command, show_user_1): Update.
* cli/cli-decode.h (struct cmd_list_element) <user_commands>: Now
a counted_command_line.
* breakpoint.h (counted_command_line): Remove typedef.
(breakpoint_set_commands): Update.
* breakpoint.c (check_no_tracepoint_commands)
(validate_commands_for_breakpoint): Update.
(breakpoint_set_commands): Change commands to be a
counted_command_line.
(commands_command_1, update_dprintf_command_list)
(create_tracepoint_from_upload): Update.
2018-05-04 Tom Tromey <tom@tromey.com> 2018-05-04 Tom Tromey <tom@tromey.com>
* cli/cli-decode.h (cmd_list_element): New constructor. * cli/cli-decode.h (cmd_list_element): New constructor.

View File

@ -1015,8 +1015,8 @@ check_no_tracepoint_commands (struct command_line *commands)
error (_("The 'while-stepping' command can " error (_("The 'while-stepping' command can "
"only be used for tracepoints")); "only be used for tracepoints"));
for (i = 0; i < c->body_count; ++i) check_no_tracepoint_commands (c->body_list_0.get ());
check_no_tracepoint_commands ((c->body_list)[i]); check_no_tracepoint_commands (c->body_list_1.get ());
/* Not that command parsing removes leading whitespace and comment /* Not that command parsing removes leading whitespace and comment
lines and also empty lines. So, we only need to check for lines and also empty lines. So, we only need to check for
@ -1127,8 +1127,8 @@ validate_commands_for_breakpoint (struct breakpoint *b,
{ {
struct command_line *c2; struct command_line *c2;
gdb_assert (while_stepping->body_count == 1); gdb_assert (while_stepping->body_list_1 == nullptr);
c2 = while_stepping->body_list[0]; c2 = while_stepping->body_list_0.get ();
for (; c2; c2 = c2->next) for (; c2; c2 = c2->next)
{ {
if (c2->control_type == while_stepping_control) if (c2->control_type == while_stepping_control)
@ -1168,7 +1168,7 @@ static_tracepoints_here (CORE_ADDR addr)
void void
breakpoint_set_commands (struct breakpoint *b, breakpoint_set_commands (struct breakpoint *b,
command_line_up &&commands) counted_command_line &&commands)
{ {
validate_commands_for_breakpoint (b, commands.get ()); validate_commands_for_breakpoint (b, commands.get ());
@ -1248,7 +1248,7 @@ commands_command_1 (const char *arg, int from_tty,
if (cmd == NULL) if (cmd == NULL)
{ {
if (control != NULL) if (control != NULL)
cmd = copy_command_lines (control->body_list[0]); cmd = control->body_list_0;
else else
{ {
std::string str std::string str
@ -8773,18 +8773,12 @@ update_dprintf_command_list (struct breakpoint *b)
_("Invalid dprintf style.")); _("Invalid dprintf style."));
gdb_assert (printf_line != NULL); gdb_assert (printf_line != NULL);
/* Manufacture a printf sequence. */ /* Manufacture a printf sequence. */
{ struct command_line *printf_cmd_line
struct command_line *printf_cmd_line = XNEW (struct command_line); = new struct command_line (simple_control, printf_line);
breakpoint_set_commands (b, counted_command_line (printf_cmd_line,
printf_cmd_line->control_type = simple_control; command_lines_deleter ()));
printf_cmd_line->body_count = 0;
printf_cmd_line->body_list = NULL;
printf_cmd_line->next = NULL;
printf_cmd_line->line = printf_line;
breakpoint_set_commands (b, command_line_up (printf_cmd_line));
}
} }
/* Update all dprintf commands, making their command lists reflect /* Update all dprintf commands, making their command lists reflect
@ -14785,7 +14779,7 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
function. */ function. */
if (!utp->cmd_strings.empty ()) if (!utp->cmd_strings.empty ())
{ {
command_line_up cmd_list; counted_command_line cmd_list;
this_utp = utp; this_utp = utp;
next_cmd = 0; next_cmd = 0;

View File

@ -669,10 +669,6 @@ enum watchpoint_triggered
typedef struct bp_location *bp_location_p; typedef struct bp_location *bp_location_p;
DEF_VEC_P(bp_location_p); DEF_VEC_P(bp_location_p);
/* A reference-counted struct command_line. This is an implementation
detail to the breakpoints module. */
typedef std::shared_ptr<command_line> counted_command_line;
/* Some targets (e.g., embedded PowerPC) need two debug registers to set /* Some targets (e.g., embedded PowerPC) need two debug registers to set
a watchpoint over a memory region. If this flag is true, GDB will use a watchpoint over a memory region. If this flag is true, GDB will use
only one register per watchpoint, thus assuming that all acesses that only one register per watchpoint, thus assuming that all acesses that
@ -1487,7 +1483,7 @@ extern void disable_breakpoint (struct breakpoint *);
extern void enable_breakpoint (struct breakpoint *); extern void enable_breakpoint (struct breakpoint *);
extern void breakpoint_set_commands (struct breakpoint *b, extern void breakpoint_set_commands (struct breakpoint *b,
command_line_up &&commands); counted_command_line &&commands);
extern void breakpoint_set_silent (struct breakpoint *b, int silent); extern void breakpoint_set_silent (struct breakpoint *b, int silent);

View File

@ -24,6 +24,7 @@
/* Include the public interfaces. */ /* Include the public interfaces. */
#include "command.h" #include "command.h"
#include "gdb_regex.h" #include "gdb_regex.h"
#include "cli-script.h"
#if 0 #if 0
/* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum /* FIXME: cagney/2002-03-17: Once cmd_type() has been removed, ``enum
@ -213,7 +214,7 @@ struct cmd_list_element
const char *const *enums = nullptr; const char *const *enums = nullptr;
/* Pointer to command strings of user-defined commands */ /* Pointer to command strings of user-defined commands */
struct command_line *user_commands = nullptr; counted_command_line user_commands;
/* Pointer to command that is hooked by this one, (by hook_pre) /* Pointer to command that is hooked by this one, (by hook_pre)
so the hook can be removed when this one is deleted. */ so the hook can be removed when this one is deleted. */

View File

@ -134,32 +134,23 @@ multi_line_command_p (enum command_control_type type)
static struct command_line * static struct command_line *
build_command_line (enum command_control_type type, const char *args) build_command_line (enum command_control_type type, const char *args)
{ {
struct command_line *cmd;
if ((args == NULL || *args == '\0') if ((args == NULL || *args == '\0')
&& (type == if_control || type == while_control)) && (type == if_control || type == while_control))
error (_("if/while commands require arguments.")); error (_("if/while commands require arguments."));
gdb_assert (args != NULL); gdb_assert (args != NULL);
cmd = XNEW (struct command_line); return new struct command_line (type, xstrdup (args));
cmd->next = NULL;
cmd->control_type = type;
cmd->body_count = 1;
cmd->body_list = XCNEWVEC (struct command_line *, cmd->body_count);
cmd->line = xstrdup (args);
return cmd;
} }
/* Build and return a new command structure for the control commands /* Build and return a new command structure for the control commands
such as "if" and "while". */ such as "if" and "while". */
command_line_up counted_command_line
get_command_line (enum command_control_type type, const char *arg) get_command_line (enum command_control_type type, const char *arg)
{ {
/* Allocate and build a new command line structure. */ /* Allocate and build a new command line structure. */
command_line_up cmd (build_command_line (type, arg)); counted_command_line cmd (build_command_line (type, arg),
command_lines_deleter ());
/* Read in the body of this command. */ /* Read in the body of this command. */
if (recurse_read_control_structure (read_next_line, cmd.get (), 0, 0) if (recurse_read_control_structure (read_next_line, cmd.get (), 0, 0)
@ -228,7 +219,7 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
else else
uiout->field_string (NULL, list->line); uiout->field_string (NULL, list->line);
uiout->text ("\n"); uiout->text ("\n");
print_command_lines (uiout, *list->body_list, depth + 1); print_command_lines (uiout, list->body_list_0.get (), depth + 1);
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "end"); uiout->field_string (NULL, "end");
@ -244,16 +235,16 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
uiout->field_fmt (NULL, "if %s", list->line); uiout->field_fmt (NULL, "if %s", list->line);
uiout->text ("\n"); uiout->text ("\n");
/* The true arm. */ /* The true arm. */
print_command_lines (uiout, list->body_list[0], depth + 1); print_command_lines (uiout, list->body_list_0.get (), depth + 1);
/* Show the false arm if it exists. */ /* Show the false arm if it exists. */
if (list->body_count == 2) if (list->body_list_1 != nullptr)
{ {
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "else"); uiout->field_string (NULL, "else");
uiout->text ("\n"); uiout->text ("\n");
print_command_lines (uiout, list->body_list[1], depth + 1); print_command_lines (uiout, list->body_list_1.get (), depth + 1);
} }
if (depth) if (depth)
@ -273,7 +264,7 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
else else
uiout->field_string (NULL, "commands"); uiout->field_string (NULL, "commands");
uiout->text ("\n"); uiout->text ("\n");
print_command_lines (uiout, *list->body_list, depth + 1); print_command_lines (uiout, list->body_list_0.get (), depth + 1);
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "end"); uiout->field_string (NULL, "end");
@ -287,7 +278,7 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
uiout->field_string (NULL, "python"); uiout->field_string (NULL, "python");
uiout->text ("\n"); uiout->text ("\n");
/* Don't indent python code at all. */ /* Don't indent python code at all. */
print_command_lines (uiout, *list->body_list, 0); print_command_lines (uiout, list->body_list_0.get (), 0);
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "end"); uiout->field_string (NULL, "end");
@ -300,7 +291,7 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
{ {
uiout->field_string (NULL, "compile expression"); uiout->field_string (NULL, "compile expression");
uiout->text ("\n"); uiout->text ("\n");
print_command_lines (uiout, *list->body_list, 0); print_command_lines (uiout, list->body_list_0.get (), 0);
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "end"); uiout->field_string (NULL, "end");
@ -313,7 +304,7 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd,
{ {
uiout->field_string (NULL, "guile"); uiout->field_string (NULL, "guile");
uiout->text ("\n"); uiout->text ("\n");
print_command_lines (uiout, *list->body_list, depth + 1); print_command_lines (uiout, list->body_list_0.get (), depth + 1);
if (depth) if (depth)
uiout->spaces (2 * depth); uiout->spaces (2 * depth);
uiout->field_string (NULL, "end"); uiout->field_string (NULL, "end");
@ -377,14 +368,17 @@ void
execute_user_command (struct cmd_list_element *c, const char *args) execute_user_command (struct cmd_list_element *c, const char *args)
{ {
struct ui *ui = current_ui; struct ui *ui = current_ui;
struct command_line *cmdlines; counted_command_line cmdlines_copy;
enum command_control_type ret; enum command_control_type ret;
extern unsigned int max_user_call_depth; extern unsigned int max_user_call_depth;
cmdlines = c->user_commands; /* Ensure that the user commands can't be deleted while they are
if (cmdlines == 0) executing. */
cmdlines_copy = c->user_commands;
if (cmdlines_copy == 0)
/* Null command */ /* Null command */
return; return;
struct command_line *cmdlines = cmdlines_copy.get ();
scoped_user_args_level push_user_args (args); scoped_user_args_level push_user_args (args);
@ -527,7 +521,7 @@ execute_control_command_1 (struct command_line *cmd)
break; break;
/* Execute the body of the while statement. */ /* Execute the body of the while statement. */
current = *cmd->body_list; current = cmd->body_list_0.get ();
while (current) while (current)
{ {
scoped_restore save_nesting scoped_restore save_nesting
@ -581,9 +575,9 @@ execute_control_command_1 (struct command_line *cmd)
/* Choose which arm to take commands from based on the value /* Choose which arm to take commands from based on the value
of the conditional expression. */ of the conditional expression. */
if (value_true (val)) if (value_true (val))
current = *cmd->body_list; current = cmd->body_list_0.get ();
else if (cmd->body_count == 2) else if (cmd->body_list_1 != nullptr)
current = *(cmd->body_list + 1); current = cmd->body_list_1.get ();
value_free_to_mark (val_mark); value_free_to_mark (val_mark);
/* Execute commands in the given arm. */ /* Execute commands in the given arm. */
@ -665,7 +659,7 @@ static void
while_command (const char *arg, int from_tty) while_command (const char *arg, int from_tty)
{ {
control_level = 1; control_level = 1;
command_line_up command = get_command_line (while_control, arg); counted_command_line command = get_command_line (while_control, arg);
if (command == NULL) if (command == NULL)
return; return;
@ -682,7 +676,7 @@ static void
if_command (const char *arg, int from_tty) if_command (const char *arg, int from_tty)
{ {
control_level = 1; control_level = 1;
command_line_up command = get_command_line (if_control, arg); counted_command_line command = get_command_line (if_control, arg);
if (command == NULL) if (command == NULL)
return; return;
@ -828,31 +822,6 @@ user_args::insert_args (const char *line) const
} }
/* Expand the body_list of COMMAND so that it can hold NEW_LENGTH
code bodies. This is typically used when we encounter an "else"
clause for an "if" command. */
static void
realloc_body_list (struct command_line *command, int new_length)
{
int n;
struct command_line **body_list;
n = command->body_count;
/* Nothing to do? */
if (new_length <= n)
return;
body_list = XCNEWVEC (struct command_line *, new_length);
memcpy (body_list, command->body_list, sizeof (struct command_line *) * n);
xfree (command->body_list);
command->body_list = body_list;
command->body_count = new_length;
}
/* Read next line from stdin. Passed to read_command_line_1 and /* Read next line from stdin. Passed to read_command_line_1 and
recurse_read_control_structure whenever we need to read commands recurse_read_control_structure whenever we need to read commands
from stdin. */ from stdin. */
@ -1012,23 +981,9 @@ process_next_line (char *p, struct command_line **command, int parse_commands,
*command = build_command_line (guile_control, ""); *command = build_command_line (guile_control, "");
} }
else if (p_end - p == 10 && startswith (p, "loop_break")) else if (p_end - p == 10 && startswith (p, "loop_break"))
{ *command = new struct command_line (break_control);
*command = XNEW (struct command_line);
(*command)->next = NULL;
(*command)->line = NULL;
(*command)->control_type = break_control;
(*command)->body_count = 0;
(*command)->body_list = NULL;
}
else if (p_end - p == 13 && startswith (p, "loop_continue")) else if (p_end - p == 13 && startswith (p, "loop_continue"))
{ *command = new struct command_line (continue_control);
*command = XNEW (struct command_line);
(*command)->next = NULL;
(*command)->line = NULL;
(*command)->control_type = continue_control;
(*command)->body_count = 0;
(*command)->body_list = NULL;
}
else else
not_handled = 1; not_handled = 1;
} }
@ -1036,12 +991,8 @@ process_next_line (char *p, struct command_line **command, int parse_commands,
if (!parse_commands || not_handled) if (!parse_commands || not_handled)
{ {
/* A normal command. */ /* A normal command. */
*command = XNEW (struct command_line); *command = new struct command_line (simple_control,
(*command)->next = NULL; savestring (p, p_end - p));
(*command)->line = savestring (p, p_end - p);
(*command)->control_type = simple_control;
(*command)->body_count = 0;
(*command)->body_list = NULL;
} }
if (validator) if (validator)
@ -1053,7 +1004,7 @@ process_next_line (char *p, struct command_line **command, int parse_commands,
} }
CATCH (ex, RETURN_MASK_ALL) CATCH (ex, RETURN_MASK_ALL)
{ {
xfree (*command); free_command_lines (command);
throw_exception (ex); throw_exception (ex);
} }
END_CATCH END_CATCH
@ -1073,21 +1024,17 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
void (*validator)(char *, void *), void (*validator)(char *, void *),
void *closure) void *closure)
{ {
int current_body, i;
enum misc_command_type val; enum misc_command_type val;
enum command_control_type ret; enum command_control_type ret;
struct command_line **body_ptr, *child_tail, *next; struct command_line **body_ptr, *child_tail, *next;
counted_command_line *current_body = &current_cmd->body_list_0;
child_tail = NULL; child_tail = NULL;
current_body = 1;
/* Sanity checks. */ /* Sanity checks. */
if (current_cmd->control_type == simple_control) if (current_cmd->control_type == simple_control)
error (_("Recursed on a simple control type.")); error (_("Recursed on a simple control type."));
if (current_body > current_cmd->body_count)
error (_("Allocated body is smaller than this command type needs."));
/* Read lines from the input stream and build control structures. */ /* Read lines from the input stream and build control structures. */
while (1) while (1)
{ {
@ -1123,10 +1070,9 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
if (val == else_command) if (val == else_command)
{ {
if (current_cmd->control_type == if_control if (current_cmd->control_type == if_control
&& current_body == 1) && current_body == &current_cmd->body_list_0)
{ {
realloc_body_list (current_cmd, 2); current_body = &current_cmd->body_list_1;
current_body = 2;
child_tail = NULL; child_tail = NULL;
continue; continue;
} }
@ -1142,14 +1088,7 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
child_tail->next = next; child_tail->next = next;
} }
else else
{ *current_body = counted_command_line (next, command_lines_deleter ());
body_ptr = current_cmd->body_list;
for (i = 1; i < current_body; i++)
body_ptr++;
*body_ptr = next;
}
child_tail = next; child_tail = next;
@ -1183,7 +1122,7 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
#define END_MESSAGE "End with a line saying just \"end\"." #define END_MESSAGE "End with a line saying just \"end\"."
command_line_up counted_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) void (*validator)(char *, void *), void *closure)
{ {
@ -1205,7 +1144,7 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
/* Reading commands assumes the CLI behavior, so temporarily /* Reading commands assumes the CLI behavior, so temporarily
override the current interpreter with CLI. */ override the current interpreter with CLI. */
command_line_up head; counted_command_line head (nullptr, command_lines_deleter ());
if (current_interp_named_p (INTERP_CONSOLE)) if (current_interp_named_p (INTERP_CONSOLE))
head = read_command_lines_1 (read_next_line, parse_commands, head = read_command_lines_1 (read_next_line, parse_commands,
validator, closure); validator, closure);
@ -1228,12 +1167,12 @@ read_command_lines (char *prompt_arg, int from_tty, int parse_commands,
/* Act the same way as read_command_lines, except that each new line is /* Act the same way as read_command_lines, except that each new line is
obtained using READ_NEXT_LINE_FUNC. */ obtained using READ_NEXT_LINE_FUNC. */
command_line_up counted_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) void (*validator)(char *, void *), void *closure)
{ {
struct command_line *tail, *next; struct command_line *tail, *next;
command_line_up head; counted_command_line head (nullptr, command_lines_deleter ());
enum command_control_type ret; enum command_control_type ret;
enum misc_command_type val; enum misc_command_type val;
@ -1279,7 +1218,7 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands,
} }
else else
{ {
head.reset (next); head = counted_command_line (next, command_lines_deleter ());
} }
tail = next; tail = next;
} }
@ -1299,54 +1238,15 @@ free_command_lines (struct command_line **lptr)
{ {
struct command_line *l = *lptr; struct command_line *l = *lptr;
struct command_line *next; struct command_line *next;
struct command_line **blist;
int i;
while (l) while (l)
{ {
if (l->body_count > 0)
{
blist = l->body_list;
for (i = 0; i < l->body_count; i++, blist++)
free_command_lines (blist);
}
next = l->next; next = l->next;
xfree (l->line); delete l;
xfree (l);
l = next; l = next;
} }
*lptr = NULL; *lptr = NULL;
} }
command_line_up
copy_command_lines (struct command_line *cmds)
{
struct command_line *result = NULL;
if (cmds)
{
result = XNEW (struct command_line);
result->next = copy_command_lines (cmds->next).release ();
result->line = xstrdup (cmds->line);
result->control_type = cmds->control_type;
result->body_count = cmds->body_count;
if (cmds->body_count > 0)
{
int i;
result->body_list = XNEWVEC (struct command_line *, cmds->body_count);
for (i = 0; i < cmds->body_count; i++)
result->body_list[i]
= copy_command_lines (cmds->body_list[i]).release ();
}
else
result->body_list = NULL;
}
return command_line_up (result);
}
/* Validate that *COMNAME is a valid name for a command. Return the /* Validate that *COMNAME is a valid name for a command. Return the
containing command list, in case it starts with a prefix command. containing command list, in case it starts with a prefix command.
@ -1483,15 +1383,12 @@ define_command (const char *comname, int from_tty)
xsnprintf (tmpbuf, sizeof (tmpbuf), xsnprintf (tmpbuf, sizeof (tmpbuf),
"Type commands for definition of \"%s\".", comfull); "Type commands for definition of \"%s\".", comfull);
command_line_up cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0); counted_command_line cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0);
if (c && c->theclass == class_user)
free_command_lines (&c->user_commands);
newc = add_cmd (comname, class_user, user_defined_command, newc = add_cmd (comname, class_user, user_defined_command,
(c && c->theclass == class_user) (c && c->theclass == class_user)
? c->doc : xstrdup ("User-defined."), list); ? c->doc : xstrdup ("User-defined."), list);
newc->user_commands = cmds.release (); newc->user_commands = std::move (cmds);
/* If this new command is a hook, then mark both commands as being /* If this new command is a hook, then mark both commands as being
tied. */ tied. */
@ -1534,7 +1431,8 @@ document_command (const char *comname, int from_tty)
xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".", xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".",
comfull); comfull);
command_line_up doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0); counted_command_line doclines = read_command_lines (tmpbuf, from_tty,
0, 0, 0);
if (c->doc) if (c->doc)
xfree ((char *) c->doc); xfree ((char *) c->doc);
@ -1611,7 +1509,7 @@ show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
return; return;
} }
cmdlines = c->user_commands; cmdlines = c->user_commands.get ();
fprintf_filtered (stream, "User command \"%s%s\":\n", prefix, name); fprintf_filtered (stream, "User command \"%s%s\":\n", prefix, name);
if (!cmdlines) if (!cmdlines)

View File

@ -45,31 +45,7 @@ enum command_control_type
invalid_control invalid_control
}; };
/* * Structure for saved commands lines (for breakpoints, defined struct command_line;
commands, etc). */
struct command_line
{
struct command_line *next;
char *line;
enum command_control_type control_type;
union
{
struct
{
enum compile_i_scope_types scope;
void *scope_data;
}
compile;
}
control_u;
/* * The number of elements in body_list. */
int body_count;
/* * For composite commands, the nested lists of commands. For
example, for "if" command this will contain the then branch and
the else branch, if that is available. */
struct command_line **body_list;
};
extern void free_command_lines (struct command_line **); extern void free_command_lines (struct command_line **);
@ -83,14 +59,56 @@ struct command_lines_deleter
} }
}; };
/* A unique pointer to a command_line. */ /* A reference-counted struct command_line. */
typedef std::shared_ptr<command_line> counted_command_line;
typedef std::unique_ptr<command_line, command_lines_deleter> command_line_up; /* * Structure for saved commands lines (for breakpoints, defined
commands, etc). */
extern command_line_up read_command_lines (char *, int, int, struct command_line
{
explicit command_line (command_control_type type_, char *line_ = nullptr)
: line (line_),
control_type (type_)
{
memset (&control_u, 0, sizeof (control_u));
}
DISABLE_COPY_AND_ASSIGN (command_line);
struct command_line *next = nullptr;
char *line;
enum command_control_type control_type;
union
{
struct
{
enum compile_i_scope_types scope;
void *scope_data;
}
compile;
}
control_u;
/* * For composite commands, the nested lists of commands. For
example, for "if" command this will contain the then branch and
the else branch, if that is available. */
counted_command_line body_list_0;
counted_command_line body_list_1;
private:
friend void free_command_lines (struct command_line **);
~command_line ()
{
xfree (line);
}
};
extern counted_command_line read_command_lines (char *, int, int,
void (*)(char *, void *), void (*)(char *, void *),
void *); void *);
extern command_line_up read_command_lines_1 (char * (*) (void), int, extern counted_command_line read_command_lines_1 (char * (*) (void), int,
void (*)(char *, void *), void (*)(char *, void *),
void *); void *);
@ -112,14 +130,12 @@ extern enum command_control_type
extern enum command_control_type extern enum command_control_type
execute_control_command_untraced (struct command_line *cmd); execute_control_command_untraced (struct command_line *cmd);
extern command_line_up get_command_line (enum command_control_type, extern counted_command_line get_command_line (enum command_control_type,
const char *); const char *);
extern void print_command_lines (struct ui_out *, extern void print_command_lines (struct ui_out *,
struct command_line *, unsigned int); struct command_line *, unsigned int);
extern command_line_up copy_command_lines (struct command_line *cmds);
/* Exported to gdb/infrun.c */ /* Exported to gdb/infrun.c */
extern void execute_user_command (struct cmd_list_element *c, const char *args); extern void execute_user_command (struct cmd_list_element *c, const char *args);

View File

@ -149,7 +149,7 @@ compile_code_command (const char *arg, int from_tty)
eval_compile_command (NULL, arg, scope, NULL); eval_compile_command (NULL, arg, scope, NULL);
else else
{ {
command_line_up l = get_command_line (compile_control, ""); counted_command_line l = get_command_line (compile_control, "");
l->control_u.compile.scope = scope; l->control_u.compile.scope = scope;
execute_control_command_untraced (l.get ()); execute_control_command_untraced (l.get ());
@ -187,7 +187,7 @@ compile_print_command (const char *arg, int from_tty)
eval_compile_command (NULL, arg, scope, &fmt); eval_compile_command (NULL, arg, scope, &fmt);
else else
{ {
command_line_up l = get_command_line (compile_control, ""); counted_command_line l = get_command_line (compile_control, "");
l->control_u.compile.scope = scope; l->control_u.compile.scope = scope;
l->control_u.compile.scope_data = &fmt; l->control_u.compile.scope_data = &fmt;
@ -512,7 +512,7 @@ compile_to_object (struct command_line *cmd, const char *cmd_string,
{ {
struct command_line *iter; struct command_line *iter;
for (iter = cmd->body_list[0]; iter; iter = iter->next) for (iter = cmd->body_list_0.get (); iter; iter = iter->next)
{ {
input_buf.puts (iter->line); input_buf.puts (iter->line);
input_buf.puts ("\n"); input_buf.puts ("\n");

View File

@ -209,7 +209,7 @@ guile_command (const char *arg, int from_tty)
} }
else else
{ {
command_line_up l = get_command_line (guile_control, ""); counted_command_line l = get_command_line (guile_control, "");
execute_control_command_untraced (l.get ()); execute_control_command_untraced (l.get ());
} }
@ -256,12 +256,12 @@ gdbscm_eval_from_control_command
char *script, *msg; char *script, *msg;
struct cleanup *cleanup; struct cleanup *cleanup;
if (cmd->body_count != 1) if (cmd->body_list_1 != nullptr)
error (_("Invalid \"guile\" block structure.")); error (_("Invalid \"guile\" block structure."));
cleanup = make_cleanup (null_cleanup, NULL); cleanup = make_cleanup (null_cleanup, NULL);
script = compute_scheme_string (cmd->body_list[0]); script = compute_scheme_string (cmd->body_list_0.get ());
msg = gdbscm_safe_eval_string (script, 0); msg = gdbscm_safe_eval_string (script, 0);
xfree (script); xfree (script);
if (msg != NULL) if (msg != NULL)
@ -408,7 +408,7 @@ guile_command (const char *arg, int from_tty)
{ {
/* Even if Guile isn't enabled, we still have to slurp the /* Even if Guile isn't enabled, we still have to slurp the
command list to the corresponding "end". */ command list to the corresponding "end". */
command_line_up l = get_command_line (guile_control, ""); counted_command_line l = get_command_line (guile_control, "");
execute_control_command_untraced (l.get ()); execute_control_command_untraced (l.get ());
} }

View File

@ -489,7 +489,7 @@ mi_read_next_line (void)
void void
mi_cmd_break_commands (const char *command, char **argv, int argc) mi_cmd_break_commands (const char *command, char **argv, int argc)
{ {
command_line_up break_command; counted_command_line break_command;
char *endptr; char *endptr;
int bnum; int bnum;
struct breakpoint *b; struct breakpoint *b;

View File

@ -385,12 +385,12 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
{ {
int ret; int ret;
if (cmd->body_count != 1) if (cmd->body_list_1 != nullptr)
error (_("Invalid \"python\" block structure.")); error (_("Invalid \"python\" block structure."));
gdbpy_enter enter_py (get_current_arch (), current_language); gdbpy_enter enter_py (get_current_arch (), current_language);
std::string script = compute_python_string (cmd->body_list[0]); std::string script = compute_python_string (cmd->body_list_0.get ());
ret = PyRun_SimpleString (script.c_str ()); ret = PyRun_SimpleString (script.c_str ());
if (ret) if (ret)
error (_("Error while executing Python code.")); error (_("Error while executing Python code."));
@ -413,7 +413,7 @@ python_command (const char *arg, int from_tty)
} }
else else
{ {
command_line_up l = get_command_line (python_control, ""); counted_command_line l = get_command_line (python_control, "");
execute_control_command_untraced (l.get ()); execute_control_command_untraced (l.get ());
} }
@ -1583,7 +1583,7 @@ python_interactive_command (const char *arg, int from_tty)
error (_("Python scripting is not supported in this copy of GDB.")); error (_("Python scripting is not supported in this copy of GDB."));
else else
{ {
command_line_up l = get_command_line (python_control, ""); counted_command_line l = get_command_line (python_control, "");
execute_control_command_untraced (l.get ()); execute_control_command_untraced (l.get ());
} }

View File

@ -12537,7 +12537,7 @@ remote_download_command_source (int num, ULONGEST addr,
if (cmd->control_type == while_control if (cmd->control_type == while_control
|| cmd->control_type == while_stepping_control) || cmd->control_type == while_stepping_control)
{ {
remote_download_command_source (num, addr, *cmd->body_list); remote_download_command_source (num, addr, cmd->body_list_0.get ());
QUIT; /* Allow user to bail out with ^C. */ QUIT; /* Allow user to bail out with ^C. */
strcpy (rs->buf, "QTDPsrc:"); strcpy (rs->buf, "QTDPsrc:");

View File

@ -167,8 +167,7 @@ char *trace_stop_notes = NULL;
struct collection_list; struct collection_list;
static char *mem2hex (gdb_byte *, char *, int); static char *mem2hex (gdb_byte *, char *, int);
static struct command_line * static counted_command_line all_tracepoint_actions (struct breakpoint *);
all_tracepoint_actions_and_cleanup (struct breakpoint *t);
static struct trace_status trace_status; static struct trace_status trace_status;
@ -578,8 +577,9 @@ actions_command (const char *args, int from_tty)
string_printf ("Enter actions for tracepoint %d, one per line.", string_printf ("Enter actions for tracepoint %d, one per line.",
t->number); t->number);
command_line_up l = read_command_lines (&tmpbuf[0], from_tty, 1, counted_command_line l = read_command_lines (&tmpbuf[0], from_tty, 1,
check_tracepoint_command, t); check_tracepoint_command,
t);
breakpoint_set_commands (t, std::move (l)); breakpoint_set_commands (t, std::move (l));
} }
/* else just return */ /* else just return */
@ -1436,7 +1436,7 @@ encode_actions_1 (struct command_line *action,
here. */ here. */
gdb_assert (stepping_list); gdb_assert (stepping_list);
encode_actions_1 (action->body_list[0], tloc, frame_reg, encode_actions_1 (action->body_list_0.get (), tloc, frame_reg,
frame_offset, stepping_list, NULL); frame_offset, stepping_list, NULL);
} }
else else
@ -1452,17 +1452,17 @@ encode_actions (struct bp_location *tloc,
struct collection_list *tracepoint_list, struct collection_list *tracepoint_list,
struct collection_list *stepping_list) struct collection_list *stepping_list)
{ {
struct command_line *actions;
int frame_reg; int frame_reg;
LONGEST frame_offset; LONGEST frame_offset;
gdbarch_virtual_frame_pointer (tloc->gdbarch, gdbarch_virtual_frame_pointer (tloc->gdbarch,
tloc->address, &frame_reg, &frame_offset); tloc->address, &frame_reg, &frame_offset);
actions = all_tracepoint_actions_and_cleanup (tloc->owner); counted_command_line actions = all_tracepoint_actions (tloc->owner);
encode_actions_1 (actions.get (), tloc, frame_reg, frame_offset,
encode_actions_1 (actions, tloc, frame_reg, frame_offset,
tracepoint_list, stepping_list); tracepoint_list, stepping_list);
encode_actions_1 (breakpoint_commands (tloc->owner), tloc,
frame_reg, frame_offset, tracepoint_list, stepping_list);
tracepoint_list->finish (); tracepoint_list->finish ();
stepping_list->finish (); stepping_list->finish ();
@ -2662,10 +2662,8 @@ trace_dump_actions (struct command_line *action,
if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand)) if (cmd_cfunc_eq (cmd, while_stepping_pseudocommand))
{ {
int i; gdb_assert (action->body_list_1 == nullptr);
trace_dump_actions (action->body_list_0.get (),
for (i = 0; i < action->body_count; ++i)
trace_dump_actions (action->body_list[i],
1, stepping_frame, from_tty); 1, stepping_frame, from_tty);
} }
else if (cmd_cfunc_eq (cmd, collect_pseudocommand)) else if (cmd_cfunc_eq (cmd, collect_pseudocommand))
@ -2777,16 +2775,12 @@ get_traceframe_location (int *stepping_frame_p)
return t->loc; return t->loc;
} }
/* Return all the actions, including default collect, of a tracepoint /* Return the default collect actions of a tracepoint T. */
T. It constructs cleanups into the chain, and leaves the caller to
handle them (call do_cleanups). */
static struct command_line * static counted_command_line
all_tracepoint_actions_and_cleanup (struct breakpoint *t) all_tracepoint_actions (struct breakpoint *t)
{ {
struct command_line *actions; counted_command_line actions (nullptr, command_lines_deleter ());
actions = breakpoint_commands (t);
/* If there are default expressions to collect, make up a collect /* If there are default expressions to collect, make up a collect
action and prepend to the action list to encode. Note that since action and prepend to the action list to encode. Note that since
@ -2796,17 +2790,13 @@ all_tracepoint_actions_and_cleanup (struct breakpoint *t)
if (*default_collect) if (*default_collect)
{ {
struct command_line *default_collect_action; struct command_line *default_collect_action;
char *default_collect_line; gdb::unique_xmalloc_ptr<char> default_collect_line
(xstrprintf ("collect %s", default_collect));
default_collect_line = xstrprintf ("collect %s", default_collect); validate_actionline (default_collect_line.get (), t);
make_cleanup (xfree, default_collect_line); actions.reset (new struct command_line (simple_control,
default_collect_line.release ()),
validate_actionline (default_collect_line, t); command_lines_deleter ());
default_collect_action = XNEW (struct command_line);
make_cleanup (xfree, default_collect_action);
default_collect_action->next = actions;
default_collect_action->line = default_collect_line;
actions = default_collect_action;
} }
return actions; return actions;
@ -2819,7 +2809,6 @@ tdump_command (const char *args, int from_tty)
{ {
int stepping_frame = 0; int stepping_frame = 0;
struct bp_location *loc; struct bp_location *loc;
struct command_line *actions;
/* This throws an error is not inspecting a trace frame. */ /* This throws an error is not inspecting a trace frame. */
loc = get_traceframe_location (&stepping_frame); loc = get_traceframe_location (&stepping_frame);
@ -2833,9 +2822,11 @@ tdump_command (const char *args, int from_tty)
select_frame (get_current_frame ()); select_frame (get_current_frame ());
actions = all_tracepoint_actions_and_cleanup (loc->owner); counted_command_line actions = all_tracepoint_actions (loc->owner);
trace_dump_actions (actions, 0, stepping_frame, from_tty); trace_dump_actions (actions.get (), 0, stepping_frame, from_tty);
trace_dump_actions (breakpoint_commands (loc->owner), 0, stepping_frame,
from_tty);
} }
/* Encode a piece of a tracepoint's source-level definition in a form /* Encode a piece of a tracepoint's source-level definition in a form