forked from Imagelibrary/binutils-gdb
Fix PR 20559 - "eval" command and $arg0...$arg9/$argc substitution
It'd be handy to be able to iterate over command arguments in
user-defined commands, in order to support optional arguments
($arg0..$argN).
I thought I could make it work with "eval", but alas, it doesn't work
currently. E.g., with:
define test
set $i = 0
while $i < $argc
eval "print $arg%d", $i
set $i = $i + 1
end
end
we get:
(gdb) test 1
$1 = void
(gdb) test 1 2 3
$2 = void
$3 = void
$4 = void
(gdb)
The problem is that "eval" doesn't do user-defined command arguments
substitution after expanding its own argument. This patch fixes that,
which makes the example above work:
(gdb) test 1
$1 = 1
(gdb) test 1 2 3
$2 = 1
$3 = 2
$4 = 3
(gdb)
New test included, similar the above, but also exercises expanding
$argc.
I think this is likely to simplify many scripts out there, so I'm
adding an example to the manual and mentioning it in NEWS as well.
gdb/ChangeLog:
2016-12-02 Pedro Alves <palves@redhat.com>
PR cli/20559
* NEWS: Mention "eval" expands user-defined command arguments.
* cli/cli-script.c (execute_control_command): Adjust to rename.
(insert_args): Rename to ...
(insert_user_defined_cmd_args): ... this, and make extern.
* cli/cli-script.h (insert_user_defined_cmd_args): New
declaration.
* printcmd.c: Include "cli/cli-script.h".
(eval_command): Call insert_user_defined_cmd_args.
gdb/doc/ChangeLog:
2016-12-02 Pedro Alves <palves@redhat.com>
PR cli/20559
* gdb.texinfo (Define): Add example of using "eval" to process a
variable number of arguments.
(Output) <eval>: Add anchor.
gdb/testsuite/ChangeLog:
2016-12-02 Pedro Alves <palves@redhat.com>
PR cli/20559
* gdb.base/commands.exp (user_defined_command_args_eval): New
procedure.
(top level): Call it.
This commit is contained in:
@@ -41,8 +41,6 @@ recurse_read_control_structure (char * (*read_next_line_func) (void),
|
||||
void (*validator)(char *, void *),
|
||||
void *closure);
|
||||
|
||||
static std::string insert_args (const char *line);
|
||||
|
||||
static struct cleanup * setup_user_args (char *p);
|
||||
|
||||
static char *read_next_line (void);
|
||||
@@ -455,7 +453,7 @@ execute_control_command (struct command_line *cmd)
|
||||
case simple_control:
|
||||
{
|
||||
/* A simple command, execute it and return. */
|
||||
std::string new_line = insert_args (cmd->line);
|
||||
std::string new_line = insert_user_defined_cmd_args (cmd->line);
|
||||
execute_command (&new_line[0], 0);
|
||||
ret = cmd->control_type;
|
||||
break;
|
||||
@@ -486,7 +484,7 @@ execute_control_command (struct command_line *cmd)
|
||||
print_command_trace (buffer);
|
||||
|
||||
/* Parse the loop control expression for the while statement. */
|
||||
std::string new_line = insert_args (cmd->line);
|
||||
std::string new_line = insert_user_defined_cmd_args (cmd->line);
|
||||
expression_up expr = parse_expression (new_line.c_str ());
|
||||
|
||||
ret = simple_control;
|
||||
@@ -551,7 +549,7 @@ execute_control_command (struct command_line *cmd)
|
||||
print_command_trace (buffer);
|
||||
|
||||
/* Parse the conditional for the if statement. */
|
||||
std::string new_line = insert_args (cmd->line);
|
||||
std::string new_line = insert_user_defined_cmd_args (cmd->line);
|
||||
expression_up expr = parse_expression (new_line.c_str ());
|
||||
|
||||
current = NULL;
|
||||
@@ -591,7 +589,7 @@ execute_control_command (struct command_line *cmd)
|
||||
{
|
||||
/* Breakpoint commands list, record the commands in the
|
||||
breakpoint's command list and return. */
|
||||
std::string new_line = insert_args (cmd->line);
|
||||
std::string new_line = insert_user_defined_cmd_args (cmd->line);
|
||||
ret = commands_from_control_command (new_line.c_str (), cmd);
|
||||
break;
|
||||
}
|
||||
@@ -782,13 +780,12 @@ locate_arg (const char *p)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Insert the user defined arguments stored in user_arg into the $arg
|
||||
arguments found in line. */
|
||||
/* See cli-script.h. */
|
||||
|
||||
static std::string
|
||||
insert_args (const char *line)
|
||||
std::string
|
||||
insert_user_defined_cmd_args (const char *line)
|
||||
{
|
||||
/* If we are not in a user-defined function, treat $argc, $arg0, et
|
||||
/* If we are not in a user-defined command, treat $argc, $arg0, et
|
||||
cetera as normal convenience variables. */
|
||||
if (user_args == NULL)
|
||||
return line;
|
||||
|
||||
Reference in New Issue
Block a user