gdb: Make use of gdb::option framework for some info commands

Update the 'info variables', 'info functions', 'info locals', and
'info args' commands to make use of the gdb::options framework.

There should be no user visible changes after this commit as I have
left the help text generation using the existing mechanism, which
already tries to customise the text for each of the commands.

gdb/ChangeLog:

	* cli/cli-utils.c (extract_info_print_args): Delete.
	(extract_arg_maybe_quoted): Delete.
	(info_print_options_defs): New variable.
	(make_info_print_options_def_group): New function.
	(extract_info_print_options): Define new function.
	* cli/cli-utils.h (extract_info_print_args): Delete.
	(struct info_print_options): New structure.
	(extract_info_print_options): Declare new function.
	* stack.c (info_locals_command): Update to use new
	extract_info_print_options, also add a header comment.
	(info_args_command): Likewise.
	* symtab.c (info_variables_command): Likewise.
	(info_functions_command): Likewise.
This commit is contained in:
Andrew Burgess 2019-07-10 22:52:38 +01:00
parent 021d8588f6
commit b16507e091
5 changed files with 96 additions and 168 deletions

View File

@ -1,3 +1,19 @@
2019-07-11 Andrew Burgess <andrew.burgess@embecosm.com>
* cli/cli-utils.c (extract_info_print_args): Delete.
(extract_arg_maybe_quoted): Delete.
(info_print_options_defs): New variable.
(make_info_print_options_def_group): New function.
(extract_info_print_options): Define new function.
* cli/cli-utils.h (extract_info_print_args): Delete.
(struct info_print_options): New structure.
(extract_info_print_options): Declare new function.
* stack.c (info_locals_command): Update to use new
extract_info_print_options, also add a header comment.
(info_args_command): Likewise.
* symtab.c (info_variables_command): Likewise.
(info_functions_command): Likewise.
2019-07-11 Andrew Burgess <andrew.burgess@embecosm.com>
* cli/cli-option.c (parse_option): Use extract_string_maybe_quoted

View File

@ -23,8 +23,6 @@
#include <ctype.h>
static std::string extract_arg_maybe_quoted (const char **arg);
/* See documentation in cli-utils.h. */
ULONGEST
@ -182,38 +180,6 @@ get_number (char **pp)
/* See documentation in cli-utils.h. */
bool
extract_info_print_args (const char **args,
bool *quiet,
std::string *regexp,
std::string *t_regexp)
{
/* Check for NAMEREGEXP or -- NAMEREGEXP. */
if (**args != '-' || check_for_argument (args, "--", 2))
{
*regexp = *args;
*args = NULL;
return true;
}
if (check_for_argument (args, "-t", 2))
{
*t_regexp = extract_arg_maybe_quoted (args);
*args = skip_spaces (*args);
return true;
}
if (check_for_argument (args, "-q", 2))
{
*quiet = true;
return true;
}
return false;
}
/* See documentation in cli-utils.h. */
void
report_unrecognized_option_error (const char *command, const char *args)
{
@ -407,69 +373,6 @@ remove_trailing_whitespace (const char *start, const char *s)
return s;
}
/* A helper function to extract an argument from *ARG. An argument is
delimited by whitespace, but it can also be optionally quoted.
The quoting and special characters are handled similarly to
the parsing done by gdb_argv.
The return value is empty if no argument was found. */
static std::string
extract_arg_maybe_quoted (const char **arg)
{
bool squote = false;
bool dquote = false;
bool bsquote = false;
std::string result;
const char *p = *arg;
/* Find the start of the argument. */
p = skip_spaces (p);
/* Parse p similarly to gdb_argv buildargv function. */
while (*p != '\0')
{
if (isspace (*p) && !squote && !dquote && !bsquote)
break;
else
{
if (bsquote)
{
bsquote = false;
result += *p;
}
else if (*p == '\\')
bsquote = true;
else if (squote)
{
if (*p == '\'')
squote = false;
else
result += *p;
}
else if (dquote)
{
if (*p == '"')
dquote = false;
else
result += *p;
}
else
{
if (*p == '\'')
squote = true;
else if (*p == '"')
dquote = true;
else
result += *p;
}
p++;
}
}
*arg = p;
return result;
}
/* See documentation in cli-utils.h. */
std::string
@ -532,4 +435,41 @@ validate_flags_qcs (const char *which_command, qcs_flags *flags)
error (_("%s: -c and -s are mutually exclusive"), which_command);
}
/* The options used by the 'info variables' commands and similar. */
static const gdb::option::option_def info_print_options_defs[] = {
gdb::option::boolean_option_def<info_print_options> {
"q",
[] (info_print_options *opt) { return &opt->quiet; },
nullptr, /* show_cmd_cb */
nullptr /* set_doc */
},
gdb::option::string_option_def<info_print_options> {
"t",
[] (info_print_options *opt) { return &opt->type_regexp; },
nullptr, /* show_cmd_cb */
nullptr /* set_doc */
}
};
/* Returns the option group used by 'info variables' and similar. */
static gdb::option::option_def_group
make_info_print_options_def_group (info_print_options *opts)
{
return {{info_print_options_defs}, opts};
}
/* See documentation in cli-utils.h. */
void
extract_info_print_options (info_print_options *opts,
const char **args)
{
auto grp = make_info_print_options_def_group (opts);
gdb::option::process_options
(args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, grp);
if (*args != nullptr && **args == '\0')
*args = nullptr;
}

View File

@ -43,22 +43,28 @@ extern int get_number (char **);
error instead of returning 0. */
extern ULONGEST get_ulongest (const char **pp, int trailer = '\0');
/* Extract from ARGS the arguments [-q] [-t TYPEREGEXP] [--] NAMEREGEXP.
/* Structure to hold the values of the options used by the 'info
variables' command and other similar commands. These correspond to the
-q and -t options. */
The caller is responsible to initialize *QUIET to false, *REGEXP
and *T_REGEXP to "".
extract_info_print_args can then be called iteratively to search
for valid arguments, as part of a 'main parsing loop' searching for
-q/-t/-- arguments together with other flags and options.
struct info_print_options
{
int quiet = false;
char *type_regexp = nullptr;
Returns true and updates *ARGS + one of *QUIET, *REGEXP, *T_REGEXP if
it finds a valid argument.
Returns false if no valid argument is found at the beginning of ARGS. */
~info_print_options ()
{
xfree (type_regexp);
}
};
extern bool extract_info_print_args (const char **args,
bool *quiet,
std::string *regexp,
std::string *t_regexp);
/* Extract options from ARGS for commands like 'info variables', placing
the options into OPTS. ARGS is updated to point to the first character
after the options, or, if there is nothing after the options, then ARGS
is set to nullptr. */
extern void extract_info_print_options (info_print_options *opts,
const char **args);
/* Throws an error telling the user that ARGS starts with an option
unrecognized by COMMAND. */

View File

@ -2359,24 +2359,16 @@ print_frame_local_vars (struct frame_info *frame,
}
}
/* Implement the 'info locals' command. */
void
info_locals_command (const char *args, int from_tty)
{
std::string regexp;
std::string t_regexp;
bool quiet = false;
while (args != NULL
&& extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
;
if (args != NULL)
report_unrecognized_option_error ("info locals", args);
info_print_options opts;
extract_info_print_options (&opts, &args);
print_frame_local_vars (get_selected_frame (_("No frame selected.")),
quiet,
regexp.empty () ? NULL : regexp.c_str (),
t_regexp.empty () ? NULL : t_regexp.c_str (),
opts.quiet, args, opts.type_regexp,
0, gdb_stdout);
}
@ -2474,26 +2466,16 @@ print_frame_arg_vars (struct frame_info *frame,
}
}
/* Implement the 'info args' command. */
void
info_args_command (const char *args, int from_tty)
{
std::string regexp;
std::string t_regexp;
bool quiet = false;
while (args != NULL
&& extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
;
if (args != NULL)
report_unrecognized_option_error ("info args", args);
info_print_options opts;
extract_info_print_options (&opts, &args);
print_frame_arg_vars (get_selected_frame (_("No frame selected.")),
quiet,
regexp.empty () ? NULL : regexp.c_str (),
t_regexp.empty () ? NULL : t_regexp.c_str (),
gdb_stdout);
opts.quiet, args, opts.type_regexp, gdb_stdout);
}
/* Return the symbol-block in which the selected frame is executing.

View File

@ -4687,6 +4687,9 @@ symtab_symbol_info (bool quiet,
gdb_assert (kind <= TYPES_DOMAIN);
if (regexp != nullptr && *regexp == '\0')
regexp = nullptr;
/* Must make sure that if we're interrupted, symbols gets freed. */
std::vector<symbol_search> symbols = search_symbols (regexp, kind,
t_regexp, 0, NULL);
@ -4742,47 +4745,28 @@ symtab_symbol_info (bool quiet,
}
}
/* Implement the 'info variables' command. */
static void
info_variables_command (const char *args, int from_tty)
{
std::string regexp;
std::string t_regexp;
bool quiet = false;
info_print_options opts;
extract_info_print_options (&opts, &args);
while (args != NULL
&& extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
;
if (args != NULL)
report_unrecognized_option_error ("info variables", args);
symtab_symbol_info (quiet,
regexp.empty () ? NULL : regexp.c_str (),
VARIABLES_DOMAIN,
t_regexp.empty () ? NULL : t_regexp.c_str (),
from_tty);
symtab_symbol_info (opts.quiet, args, VARIABLES_DOMAIN,
opts.type_regexp, from_tty);
}
/* Implement the 'info functions' command. */
static void
info_functions_command (const char *args, int from_tty)
{
std::string regexp;
std::string t_regexp;
bool quiet = false;
info_print_options opts;
extract_info_print_options (&opts, &args);
while (args != NULL
&& extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
;
if (args != NULL)
report_unrecognized_option_error ("info functions", args);
symtab_symbol_info (quiet,
regexp.empty () ? NULL : regexp.c_str (),
FUNCTIONS_DOMAIN,
t_regexp.empty () ? NULL : t_regexp.c_str (),
from_tty);
symtab_symbol_info (opts.quiet, args, FUNCTIONS_DOMAIN,
opts.type_regexp, from_tty);
}