Introduce command_line_up

This introduces command_line_up, a unique_ptr for command_line
objects, and changes many places to use it.  This removes a number of
cleanups.

Command lines are funny in that sometimes they are reference counted.
Once there is more C++-ification of some of the users, perhaps all of
these can be changed to use shared_ptr instead.

gdb/ChangeLog
2017-04-12  Tom Tromey  <tom@tromey.com>

	* tracepoint.c (actions_command): Update.
	* python/python.c (python_command, python_interactive_command):
	Update.
	* mi/mi-cmd-break.c (mi_cmd_break_commands): Update.
	* guile/guile.c (guile_command): Update.
	* defs.h (read_command_lines, read_command_lines_1): Return
	command_line_up.
	(command_lines_deleter): New struct.
	(command_line_up): New typedef.
	* compile/compile.c (compile_code_command)
	(compile_print_command): Update.
	* cli/cli-script.h (get_command_line, copy_command_lines): Return
	command_line_up.
	(make_cleanup_free_command_lines): Remove.
	* cli/cli-script.c (get_command_line, read_command_lines_1)
	(copy_command_lines): Return command_line_up.
	(while_command, if_command, read_command_lines, define_command)
	(document_command): Update.
	(do_free_command_lines_cleanup, make_cleanup_free_command_lines):
	Remove.
	* breakpoint.h (breakpoint_set_commands): Change type of
	"commands".
	* breakpoint.c (breakpoint_set_commands): Change type of
	"commands".  Update.
	(do_map_commands_command, update_dprintf_command_list)
	(create_tracepoint_from_upload): Update.
This commit is contained in:
Tom Tromey 2017-04-05 21:14:09 -06:00
parent ffc2605c41
commit 93921405a4
11 changed files with 108 additions and 115 deletions

View file

@ -1,3 +1,32 @@
2017-04-12 Tom Tromey <tom@tromey.com>
* tracepoint.c (actions_command): Update.
* python/python.c (python_command, python_interactive_command):
Update.
* mi/mi-cmd-break.c (mi_cmd_break_commands): Update.
* guile/guile.c (guile_command): Update.
* defs.h (read_command_lines, read_command_lines_1): Return
command_line_up.
(command_lines_deleter): New struct.
(command_line_up): New typedef.
* compile/compile.c (compile_code_command)
(compile_print_command): Update.
* cli/cli-script.h (get_command_line, copy_command_lines): Return
command_line_up.
(make_cleanup_free_command_lines): Remove.
* cli/cli-script.c (get_command_line, read_command_lines_1)
(copy_command_lines): Return command_line_up.
(while_command, if_command, read_command_lines, define_command)
(document_command): Update.
(do_free_command_lines_cleanup, make_cleanup_free_command_lines):
Remove.
* breakpoint.h (breakpoint_set_commands): Change type of
"commands".
* breakpoint.c (breakpoint_set_commands): Change type of
"commands". Update.
(do_map_commands_command, update_dprintf_command_list)
(create_tracepoint_from_upload): Update.
2017-04-12 Tom Tromey <tom@tromey.com> 2017-04-12 Tom Tromey <tom@tromey.com>
* tracepoint.c (scope_info): Update. * tracepoint.c (scope_info): Update.

View file

@ -1271,12 +1271,12 @@ static_tracepoints_here (CORE_ADDR addr)
void void
breakpoint_set_commands (struct breakpoint *b, breakpoint_set_commands (struct breakpoint *b,
struct command_line *commands) command_line_up &&commands)
{ {
validate_commands_for_breakpoint (b, commands); validate_commands_for_breakpoint (b, commands.get ());
decref_counted_command_line (&b->commands); decref_counted_command_line (&b->commands);
b->commands = alloc_counted_command_line (commands); b->commands = alloc_counted_command_line (commands.release ());
observer_notify_breakpoint_modified (b); observer_notify_breakpoint_modified (b);
} }
@ -1358,7 +1358,7 @@ do_map_commands_command (struct breakpoint *b, void *data)
if (info->cmd == NULL) if (info->cmd == NULL)
{ {
struct command_line *l; command_line_up l;
if (info->control != NULL) if (info->control != NULL)
l = copy_command_lines (info->control->body_list[0]); l = copy_command_lines (info->control->body_list[0]);
@ -1382,7 +1382,7 @@ do_map_commands_command (struct breakpoint *b, void *data)
do_cleanups (old_chain); do_cleanups (old_chain);
} }
info->cmd = alloc_counted_command_line (l); info->cmd = alloc_counted_command_line (l.release ());
} }
/* If a breakpoint was on the list more than once, we don't need to /* If a breakpoint was on the list more than once, we don't need to
@ -9191,7 +9191,7 @@ update_dprintf_command_list (struct breakpoint *b)
printf_cmd_line->next = NULL; printf_cmd_line->next = NULL;
printf_cmd_line->line = printf_line; printf_cmd_line->line = printf_line;
breakpoint_set_commands (b, printf_cmd_line); breakpoint_set_commands (b, command_line_up (printf_cmd_line));
} }
} }
@ -15356,14 +15356,14 @@ create_tracepoint_from_upload (struct uploaded_tp *utp)
function. */ function. */
if (!VEC_empty (char_ptr, utp->cmd_strings)) if (!VEC_empty (char_ptr, utp->cmd_strings))
{ {
struct command_line *cmd_list; command_line_up cmd_list;
this_utp = utp; this_utp = utp;
next_cmd = 0; next_cmd = 0;
cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL); cmd_list = read_command_lines_1 (read_uploaded_action, 1, NULL, NULL);
breakpoint_set_commands (&tp->base, cmd_list); breakpoint_set_commands (&tp->base, std::move (cmd_list));
} }
else if (!VEC_empty (char_ptr, utp->actions) else if (!VEC_empty (char_ptr, utp->actions)
|| !VEC_empty (char_ptr, utp->step_actions)) || !VEC_empty (char_ptr, utp->step_actions))

View file

@ -1475,7 +1475,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,
struct command_line *commands); command_line_up &&commands);
extern void breakpoint_set_silent (struct breakpoint *b, int silent); extern void breakpoint_set_silent (struct breakpoint *b, int silent);

View file

@ -165,27 +165,20 @@ build_command_line (enum command_control_type type, const char *args)
/* 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". */
struct command_line * command_line_up
get_command_line (enum command_control_type type, const char *arg) get_command_line (enum command_control_type type, const char *arg)
{ {
struct command_line *cmd;
struct cleanup *old_chain = NULL;
/* Allocate and build a new command line structure. */ /* Allocate and build a new command line structure. */
cmd = build_command_line (type, arg); command_line_up cmd (build_command_line (type, arg));
old_chain = make_cleanup_free_command_lines (&cmd);
/* Read in the body of this command. */ /* Read in the body of this command. */
if (recurse_read_control_structure (read_next_line, cmd, 0, 0) if (recurse_read_control_structure (read_next_line, cmd.get (), 0, 0)
== invalid_control) == invalid_control)
{ {
warning (_("Error reading in canned sequence of commands.")); warning (_("Error reading in canned sequence of commands."));
do_cleanups (old_chain);
return NULL; return NULL;
} }
discard_cleanups (old_chain);
return cmd; return cmd;
} }
@ -677,18 +670,15 @@ execute_control_command_untraced (struct command_line *cmd)
static void static void
while_command (char *arg, int from_tty) while_command (char *arg, int from_tty)
{ {
struct command_line *command = NULL;
control_level = 1; control_level = 1;
command = get_command_line (while_control, arg); command_line_up command = get_command_line (while_control, arg);
if (command == NULL) if (command == NULL)
return; return;
scoped_restore save_async = make_scoped_restore (&current_ui->async, 0); scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
execute_control_command_untraced (command); execute_control_command_untraced (command.get ());
free_command_lines (&command);
} }
/* "if" command support. Execute either the true or false arm depending /* "if" command support. Execute either the true or false arm depending
@ -697,19 +687,15 @@ while_command (char *arg, int from_tty)
static void static void
if_command (char *arg, int from_tty) if_command (char *arg, int from_tty)
{ {
struct command_line *command = NULL;
struct cleanup *old_chain;
control_level = 1; control_level = 1;
command = get_command_line (if_control, arg); command_line_up command = get_command_line (if_control, arg);
if (command == NULL) if (command == NULL)
return; return;
scoped_restore save_async = make_scoped_restore (&current_ui->async, 0); scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
execute_control_command_untraced (command); execute_control_command_untraced (command.get ());
free_command_lines (&command);
} }
/* Bind the incoming arguments for a user defined command to $arg0, /* Bind the incoming arguments for a user defined command to $arg0,
@ -1208,12 +1194,10 @@ restore_interp (void *arg)
#define END_MESSAGE "End with a line saying just \"end\"." #define END_MESSAGE "End with a line saying just \"end\"."
struct command_line * command_line_up
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)
{ {
struct command_line *head;
if (from_tty && input_interactive_p (current_ui)) if (from_tty && input_interactive_p (current_ui))
{ {
if (deprecated_readline_begin_hook) if (deprecated_readline_begin_hook)
@ -1232,6 +1216,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;
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);
@ -1256,17 +1241,17 @@ 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. */
struct command_line * command_line_up
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 *head, *tail, *next; struct command_line *tail, *next;
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); command_line_up head;
enum command_control_type ret; enum command_control_type ret;
enum misc_command_type val; enum misc_command_type val;
control_level = 0; control_level = 0;
head = tail = NULL; tail = NULL;
while (1) while (1)
{ {
@ -1307,18 +1292,15 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands,
} }
else else
{ {
head = next; head.reset (next);
make_cleanup_free_command_lines (&head);
} }
tail = next; tail = next;
} }
dont_repeat (); dont_repeat ();
if (ret != invalid_control) if (ret == invalid_control)
discard_cleanups (old_chain); return NULL;
else
do_cleanups (old_chain);
return head; return head;
} }
@ -1349,19 +1331,7 @@ free_command_lines (struct command_line **lptr)
*lptr = NULL; *lptr = NULL;
} }
static void command_line_up
do_free_command_lines_cleanup (void *arg)
{
free_command_lines ((struct command_line **) arg);
}
struct cleanup *
make_cleanup_free_command_lines (struct command_line **arg)
{
return make_cleanup (do_free_command_lines_cleanup, arg);
}
struct command_line *
copy_command_lines (struct command_line *cmds) copy_command_lines (struct command_line *cmds)
{ {
struct command_line *result = NULL; struct command_line *result = NULL;
@ -1370,7 +1340,7 @@ copy_command_lines (struct command_line *cmds)
{ {
result = XNEW (struct command_line); result = XNEW (struct command_line);
result->next = copy_command_lines (cmds->next); result->next = copy_command_lines (cmds->next).release ();
result->line = xstrdup (cmds->line); result->line = xstrdup (cmds->line);
result->control_type = cmds->control_type; result->control_type = cmds->control_type;
result->body_count = cmds->body_count; result->body_count = cmds->body_count;
@ -1381,13 +1351,14 @@ copy_command_lines (struct command_line *cmds)
result->body_list = XNEWVEC (struct command_line *, cmds->body_count); result->body_list = XNEWVEC (struct command_line *, cmds->body_count);
for (i = 0; i < cmds->body_count; i++) for (i = 0; i < cmds->body_count; i++)
result->body_list[i] = copy_command_lines (cmds->body_list[i]); result->body_list[i]
= copy_command_lines (cmds->body_list[i]).release ();
} }
else else
result->body_list = NULL; result->body_list = NULL;
} }
return result; 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
@ -1460,7 +1431,6 @@ define_command (char *comname, int from_tty)
CMD_PRE_HOOK, CMD_PRE_HOOK,
CMD_POST_HOOK CMD_POST_HOOK
}; };
struct command_line *cmds;
struct cmd_list_element *c, *newc, *hookc = 0, **list; struct cmd_list_element *c, *newc, *hookc = 0, **list;
char *tem, *comfull; char *tem, *comfull;
const char *tem_c; const char *tem_c;
@ -1536,7 +1506,7 @@ define_command (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);
cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0); command_line_up cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0);
if (c && c->theclass == class_user) if (c && c->theclass == class_user)
free_command_lines (&c->user_commands); free_command_lines (&c->user_commands);
@ -1544,7 +1514,7 @@ define_command (char *comname, int from_tty)
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; newc->user_commands = cmds.release ();
/* 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. */
@ -1571,7 +1541,6 @@ define_command (char *comname, int from_tty)
static void static void
document_command (char *comname, int from_tty) document_command (char *comname, int from_tty)
{ {
struct command_line *doclines;
struct cmd_list_element *c, **list; struct cmd_list_element *c, **list;
const char *tem; const char *tem;
char *comfull; char *comfull;
@ -1588,7 +1557,7 @@ document_command (char *comname, int from_tty)
xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".", xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".",
comfull); comfull);
doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0); command_line_up doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0);
if (c->doc) if (c->doc)
xfree ((char *) c->doc); xfree ((char *) c->doc);
@ -1598,13 +1567,13 @@ document_command (char *comname, int from_tty)
int len = 0; int len = 0;
char *doc; char *doc;
for (cl1 = doclines; cl1; cl1 = cl1->next) for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
len += strlen (cl1->line) + 1; len += strlen (cl1->line) + 1;
doc = (char *) xmalloc (len + 1); doc = (char *) xmalloc (len + 1);
*doc = 0; *doc = 0;
for (cl1 = doclines; cl1; cl1 = cl1->next) for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
{ {
strcat (doc, cl1->line); strcat (doc, cl1->line);
if (cl1->next) if (cl1->next)
@ -1613,8 +1582,6 @@ document_command (char *comname, int from_tty)
c->doc = doc; c->doc = doc;
} }
free_command_lines (&doclines);
} }
struct source_cleanup_lines_args struct source_cleanup_lines_args

View file

@ -38,16 +38,13 @@ 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 struct command_line *get_command_line (enum command_control_type, extern command_line_up 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 struct command_line * copy_command_lines (struct command_line *cmds); extern command_line_up copy_command_lines (struct command_line *cmds);
extern struct cleanup *
make_cleanup_free_command_lines (struct command_line **arg);
/* Exported to gdb/infrun.c */ /* Exported to gdb/infrun.c */

View file

@ -151,12 +151,10 @@ compile_code_command (char *arg, int from_tty)
eval_compile_command (NULL, arg, scope, NULL); eval_compile_command (NULL, arg, scope, NULL);
else else
{ {
struct command_line *l = get_command_line (compile_control, ""); command_line_up l = get_command_line (compile_control, "");
struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
l->control_u.compile.scope = scope; l->control_u.compile.scope = scope;
execute_control_command_untraced (l); execute_control_command_untraced (l.get ());
do_cleanups (cleanup);
} }
} }
@ -192,13 +190,11 @@ compile_print_command (char *arg_param, int from_tty)
eval_compile_command (NULL, arg, scope, &fmt); eval_compile_command (NULL, arg, scope, &fmt);
else else
{ {
struct command_line *l = get_command_line (compile_control, ""); command_line_up l = get_command_line (compile_control, "");
struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
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;
execute_control_command_untraced (l); execute_control_command_untraced (l.get ());
do_cleanups (cleanup);
} }
} }

View file

@ -445,15 +445,29 @@ struct command_line
struct command_line **body_list; struct command_line **body_list;
}; };
extern struct command_line *read_command_lines (char *, int, int,
void (*)(char *, void *),
void *);
extern struct command_line *read_command_lines_1 (char * (*) (void), int,
void (*)(char *, void *),
void *);
extern void free_command_lines (struct command_line **); extern void free_command_lines (struct command_line **);
/* A deleter for command_line that calls free_command_lines. */
struct command_lines_deleter
{
void operator() (command_line *lines) const
{
free_command_lines (&lines);
}
};
/* A unique pointer to a command_line. */
typedef std::unique_ptr<command_line, command_lines_deleter> command_line_up;
extern command_line_up read_command_lines (char *, int, int,
void (*)(char *, void *),
void *);
extern command_line_up read_command_lines_1 (char * (*) (void), int,
void (*)(char *, void *),
void *);
/* * Parameters of the "info proc" command. */ /* * Parameters of the "info proc" command. */
enum info_proc_what enum info_proc_what

View file

@ -215,10 +215,9 @@ guile_command (char *arg, int from_tty)
} }
else else
{ {
struct command_line *l = get_command_line (guile_control, ""); command_line_up l = get_command_line (guile_control, "");
make_cleanup_free_command_lines (&l); execute_control_command_untraced (l.get ());
execute_control_command_untraced (l);
} }
do_cleanups (cleanup); do_cleanups (cleanup);
@ -421,11 +420,9 @@ guile_command (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". */
struct command_line *l = get_command_line (guile_control, ""); command_line_up l = get_command_line (guile_control, "");
struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
execute_control_command_untraced (l); execute_control_command_untraced (l.get ());
do_cleanups (cleanups);
} }
} }

View file

@ -493,7 +493,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)
{ {
struct command_line *break_command; command_line_up break_command;
char *endptr; char *endptr;
int bnum; int bnum;
struct breakpoint *b; struct breakpoint *b;
@ -523,6 +523,6 @@ mi_cmd_break_commands (const char *command, char **argv, int argc)
else else
break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0); break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
breakpoint_set_commands (b, break_command); breakpoint_set_commands (b, std::move (break_command));
} }

View file

@ -433,11 +433,9 @@ python_command (char *arg, int from_tty)
} }
else else
{ {
struct command_line *l = get_command_line (python_control, ""); command_line_up l = get_command_line (python_control, "");
struct cleanup *cleanup = make_cleanup_free_command_lines (&l);
execute_control_command_untraced (l); execute_control_command_untraced (l.get ());
do_cleanups (cleanup);
} }
} }
@ -1452,11 +1450,9 @@ python_interactive_command (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
{ {
struct command_line *l = get_command_line (python_control, ""); command_line_up l = get_command_line (python_control, "");
struct cleanup *cleanups = make_cleanup_free_command_lines (&l);
execute_control_command_untraced (l); execute_control_command_untraced (l.get ());
do_cleanups (cleanups);
} }
} }

View file

@ -647,20 +647,17 @@ static void
actions_command (char *args, int from_tty) actions_command (char *args, int from_tty)
{ {
struct tracepoint *t; struct tracepoint *t;
struct command_line *l;
t = get_tracepoint_by_number (&args, NULL); t = get_tracepoint_by_number (&args, NULL);
if (t) if (t)
{ {
char *tmpbuf = std::string tmpbuf =
xstrprintf ("Enter actions for tracepoint %d, one per line.", string_printf ("Enter actions for tracepoint %d, one per line.",
t->base.number); t->base.number);
struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
l = read_command_lines (tmpbuf, from_tty, 1, command_line_up l = read_command_lines (&tmpbuf[0], from_tty, 1,
check_tracepoint_command, t); check_tracepoint_command, t);
do_cleanups (cleanups); breakpoint_set_commands (&t->base, std::move (l));
breakpoint_set_commands (&t->base, l);
} }
/* else just return */ /* else just return */
} }