Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]

Add [-q] [-t TYPEREGEXP] [NAMEREGEXP] args to info [args|functions|locals|variables]

Main changes are:
* stack.c: Add two regexp preg and treg to print_variable_and_value_data
  and used them inside do_print_variable_and_value to filter the
  variables to print.

* symtab.h: Add a new function bool treg_matches_sym_type_name, that
  factorises type matching logic.

* symtab.c: Add type/name matching logic to 'info functions|variables'.

* stack.c : Add type/name matching logic to 'info args|locals'.

gdb/ChangeLog
2018-10-27  Philippe Waroquiers  <philippe.waroquiers@skynet.be>

	* stack.c (print_variable_and_value_data): Add preg and treg.
	(print_frame_local_vars): Add quiet, regexp and t_regexp arguments,
	and update callers.
	(print_frame_arg_vars): Likewise.
	(prepare_reg): New function.
	(info_locals_command): Extract info print args and use them.
	(info_args_command): Likewise.
	(_initialize_stack): Modify on-line help.
	* symtab.c (treg_matches_sym_type_name): New function.
	(search_symbols): New arg t_regexp.
	(symtab_symbol_info): New args quiet, regexp, t_regexp.
	(info_variables_command): Extract info print args and use them.
	(info_functions_command): Likewise.
	(info_types_command): Update call to symtab_symbol_info.
	(_initialize_symtab): Modify on-line help.
	* symtab.h (treg_matches_sym_type_name): New function.
	(search_symbols): New t_regexp arg.
This commit is contained in:
Philippe Waroquiers 2018-07-01 22:56:56 +02:00
parent 0d4cad90ca
commit 12615cba84
5 changed files with 312 additions and 49 deletions

View file

@ -1,3 +1,23 @@
2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* stack.c (print_variable_and_value_data): Add preg and treg.
(print_frame_local_vars): Add quiet, regexp and t_regexp arguments,
and update callers.
(print_frame_arg_vars): Likewise.
(prepare_reg): New function.
(info_locals_command): Extract info print args and use them.
(info_args_command): Likewise.
(_initialize_stack): Modify on-line help.
* symtab.c (treg_matches_sym_type_name): New function.
(search_symbols): New arg t_regexp.
(symtab_symbol_info): New args quiet, regexp, t_regexp.
(info_variables_command): Extract info print args and use them.
(info_functions_command): Likewise.
(info_types_command): Update call to symtab_symbol_info.
(_initialize_symtab): Modify on-line help.
* symtab.h (treg_matches_sym_type_name): New function.
(search_symbols): New t_regexp arg.
2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be> 2018-10-27 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* cli-utils.c (extract_arg_maybe_quoted): New function. * cli-utils.c (extract_arg_maybe_quoted): New function.

View file

@ -743,11 +743,11 @@ gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
{ {
const char **files = symtab_paths.vec.data (); const char **files = symtab_paths.vec.data ();
symbols = search_symbols (regex, FUNCTIONS_DOMAIN, symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL,
symtab_paths.vec.size (), files); symtab_paths.vec.size (), files);
} }
else else
symbols = search_symbols (regex, FUNCTIONS_DOMAIN, 0, NULL); symbols = search_symbols (regex, FUNCTIONS_DOMAIN, NULL, 0, NULL);
/* Count the number of symbols (both symbols and optionally minimal /* Count the number of symbols (both symbols and optionally minimal
symbols) so we can correctly check the throttle limit. */ symbols) so we can correctly check the throttle limit. */

View file

@ -88,8 +88,10 @@ const char *print_entry_values = print_entry_values_default;
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static void print_frame_local_vars (struct frame_info *, int, static void print_frame_local_vars (struct frame_info *frame,
struct ui_file *); bool quiet,
const char *regexp, const char *t_regexp,
int num_tabs, struct ui_file *stream);
static void print_frame (struct frame_info *frame, int print_level, static void print_frame (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args, enum print_what print_what, int print_args,
@ -1878,7 +1880,7 @@ backtrace_command_1 (const char *count_exp, frame_filter_flags flags,
{ {
struct frame_id frame_id = get_frame_id (fi); struct frame_id frame_id = get_frame_id (fi);
print_frame_local_vars (fi, 1, gdb_stdout); print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout);
/* print_frame_local_vars invalidates FI. */ /* print_frame_local_vars invalidates FI. */
fi = frame_find_by_id (frame_id); fi = frame_find_by_id (frame_id);
@ -2060,6 +2062,8 @@ iterate_over_block_local_vars (const struct block *block,
struct print_variable_and_value_data struct print_variable_and_value_data
{ {
gdb::optional<compiled_regex> preg;
gdb::optional<compiled_regex> treg;
struct frame_id frame_id; struct frame_id frame_id;
int num_tabs; int num_tabs;
struct ui_file *stream; struct ui_file *stream;
@ -2077,6 +2081,14 @@ do_print_variable_and_value (const char *print_name,
= (struct print_variable_and_value_data *) cb_data; = (struct print_variable_and_value_data *) cb_data;
struct frame_info *frame; struct frame_info *frame;
if (p->preg.has_value ()
&& p->preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
NULL, 0) != 0)
return;
if (p->treg.has_value ()
&& !treg_matches_sym_type_name (*p->treg, sym))
return;
frame = frame_find_by_id (p->frame_id); frame = frame_find_by_id (p->frame_id);
if (frame == NULL) if (frame == NULL)
{ {
@ -2092,14 +2104,38 @@ do_print_variable_and_value (const char *print_name,
p->values_printed = 1; p->values_printed = 1;
} }
/* Prepares the regular expression REG from REGEXP.
If REGEXP is NULL, it results in an empty regular expression. */
static void
prepare_reg (const char *regexp, gdb::optional<compiled_regex> *reg)
{
if (regexp != NULL)
{
int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
? REG_ICASE : 0);
reg->emplace (regexp, cflags, _("Invalid regexp"));
}
else
reg->reset ();
}
/* Print all variables from the innermost up to the function block of FRAME. /* Print all variables from the innermost up to the function block of FRAME.
Print them with values to STREAM indented by NUM_TABS. Print them with values to STREAM indented by NUM_TABS.
If REGEXP is not NULL, only print local variables whose name
matches REGEXP.
If T_REGEXP is not NULL, only print local variables whose type
matches T_REGEXP.
If no local variables have been printed and !QUIET, prints a message
explaining why no local variables could be printed.
This function will invalidate FRAME. */ This function will invalidate FRAME. */
static void static void
print_frame_local_vars (struct frame_info *frame, int num_tabs, print_frame_local_vars (struct frame_info *frame,
struct ui_file *stream) bool quiet,
const char *regexp, const char *t_regexp,
int num_tabs, struct ui_file *stream)
{ {
struct print_variable_and_value_data cb_data; struct print_variable_and_value_data cb_data;
const struct block *block; const struct block *block;
@ -2107,6 +2143,7 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
if (!get_frame_pc_if_available (frame, &pc)) if (!get_frame_pc_if_available (frame, &pc))
{ {
if (!quiet)
fprintf_filtered (stream, fprintf_filtered (stream,
_("PC unavailable, cannot determine locals.\n")); _("PC unavailable, cannot determine locals.\n"));
return; return;
@ -2115,10 +2152,13 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
block = get_frame_block (frame, 0); block = get_frame_block (frame, 0);
if (block == 0) if (block == 0)
{ {
if (!quiet)
fprintf_filtered (stream, "No symbol table info available.\n"); fprintf_filtered (stream, "No symbol table info available.\n");
return; return;
} }
prepare_reg (regexp, &cb_data.preg);
prepare_reg (t_regexp, &cb_data.treg);
cb_data.frame_id = get_frame_id (frame); cb_data.frame_id = get_frame_id (frame);
cb_data.num_tabs = 4 * num_tabs; cb_data.num_tabs = 4 * num_tabs;
cb_data.stream = stream; cb_data.stream = stream;
@ -2134,14 +2174,33 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
do_print_variable_and_value, do_print_variable_and_value,
&cb_data); &cb_data);
if (!cb_data.values_printed) if (!cb_data.values_printed && !quiet)
{
if (regexp == NULL && t_regexp == NULL)
fprintf_filtered (stream, _("No locals.\n")); fprintf_filtered (stream, _("No locals.\n"));
else
fprintf_filtered (stream, _("No matching locals.\n"));
}
} }
void void
info_locals_command (const char *args, int from_tty) 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);
print_frame_local_vars (get_selected_frame (_("No frame selected.")), 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 (),
0, gdb_stdout); 0, gdb_stdout);
} }
@ -2180,29 +2239,45 @@ iterate_over_block_arg_vars (const struct block *b,
/* Print all argument variables of the function of FRAME. /* Print all argument variables of the function of FRAME.
Print them with values to STREAM. Print them with values to STREAM.
If REGEXP is not NULL, only print argument variables whose name
matches REGEXP.
If T_REGEXP is not NULL, only print argument variables whose type
matches T_REGEXP.
If no argument variables have been printed and !QUIET, prints a message
explaining why no argument variables could be printed.
This function will invalidate FRAME. */ This function will invalidate FRAME. */
static void static void
print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream) print_frame_arg_vars (struct frame_info *frame,
bool quiet,
const char *regexp, const char *t_regexp,
struct ui_file *stream)
{ {
struct print_variable_and_value_data cb_data; struct print_variable_and_value_data cb_data;
struct symbol *func; struct symbol *func;
CORE_ADDR pc; CORE_ADDR pc;
gdb::optional<compiled_regex> preg;
gdb::optional<compiled_regex> treg;
if (!get_frame_pc_if_available (frame, &pc)) if (!get_frame_pc_if_available (frame, &pc))
{ {
fprintf_filtered (stream, _("PC unavailable, cannot determine args.\n")); if (!quiet)
fprintf_filtered (stream,
_("PC unavailable, cannot determine args.\n"));
return; return;
} }
func = get_frame_function (frame); func = get_frame_function (frame);
if (func == NULL) if (func == NULL)
{ {
if (!quiet)
fprintf_filtered (stream, _("No symbol table info available.\n")); fprintf_filtered (stream, _("No symbol table info available.\n"));
return; return;
} }
prepare_reg (regexp, &cb_data.preg);
prepare_reg (t_regexp, &cb_data.treg);
cb_data.frame_id = get_frame_id (frame); cb_data.frame_id = get_frame_id (frame);
cb_data.num_tabs = 0; cb_data.num_tabs = 0;
cb_data.stream = stream; cb_data.stream = stream;
@ -2214,14 +2289,34 @@ print_frame_arg_vars (struct frame_info *frame, struct ui_file *stream)
/* do_print_variable_and_value invalidates FRAME. */ /* do_print_variable_and_value invalidates FRAME. */
frame = NULL; frame = NULL;
if (!cb_data.values_printed) if (!cb_data.values_printed && !quiet)
{
if (regexp == NULL && t_regexp == NULL)
fprintf_filtered (stream, _("No arguments.\n")); fprintf_filtered (stream, _("No arguments.\n"));
else
fprintf_filtered (stream, _("No matching arguments.\n"));
}
} }
void void
info_args_command (const char *ignore, int from_tty) info_args_command (const char *args, int from_tty)
{ {
std::string regexp;
std::string t_regexp;
bool quiet;
while (args != NULL
&& extract_info_print_args (&args, &quiet, &regexp, &t_regexp))
;
if (args != NULL)
report_unrecognized_option_error ("info args", args);
print_frame_arg_vars (get_selected_frame (_("No frame selected.")), 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); gdb_stdout);
} }
@ -2994,9 +3089,17 @@ Usage: info frame level LEVEL"),
&info_frame_cmd_list); &info_frame_cmd_list);
add_info ("locals", info_locals_command, add_info ("locals", info_locals_command,
_("Local variables of current stack frame.")); info_print_args_help (_("\
All local variables of current stack frame or those matching REGEXPs.\n\
Usage: info locals [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the local variables of the current stack frame.\n"),
_("local variables")));
add_info ("args", info_args_command, add_info ("args", info_args_command,
_("Argument variables of current stack frame.")); info_print_args_help (_("\
All argument variables of current stack frame or those matching REGEXPs.\n\
Usage: info args [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the argument variables of the current stack frame.\n"),
_("argument variables")));
if (dbx_commands) if (dbx_commands)
add_com ("func", class_stack, func_command, _("\ add_com ("func", class_stack, func_command, _("\

View file

@ -43,6 +43,7 @@
#include "cli/cli-utils.h" #include "cli/cli-utils.h"
#include "fnmatch.h" #include "fnmatch.h"
#include "hashtab.h" #include "hashtab.h"
#include "typeprint.h"
#include "gdb_obstack.h" #include "gdb_obstack.h"
#include "block.h" #include "block.h"
@ -4266,6 +4267,52 @@ symbol_search::compare_search_syms (const symbol_search &sym_a,
SYMBOL_PRINT_NAME (sym_b.symbol)); SYMBOL_PRINT_NAME (sym_b.symbol));
} }
/* Returns true if the type_name of symbol_type of SYM matches TREG.
If SYM has no symbol_type or symbol_name, returns false. */
bool
treg_matches_sym_type_name (const compiled_regex &treg,
const struct symbol *sym)
{
struct type *sym_type;
std::string printed_sym_type_name;
if (symbol_lookup_debug > 1)
{
fprintf_unfiltered (gdb_stdlog,
"treg_matches_sym_type_name\n sym %s\n",
SYMBOL_NATURAL_NAME (sym));
}
sym_type = SYMBOL_TYPE (sym);
if (sym_type == NULL)
return false;
if (language_mode == language_mode_auto)
{
scoped_restore_current_language l;
set_language (SYMBOL_LANGUAGE (sym));
printed_sym_type_name = type_to_string (sym_type);
}
else
printed_sym_type_name = type_to_string (sym_type);
if (symbol_lookup_debug > 1)
{
fprintf_unfiltered (gdb_stdlog,
" sym_type_name %s\n",
printed_sym_type_name.c_str ());
}
if (printed_sym_type_name.empty ())
return false;
return treg.exec (printed_sym_type_name.c_str (), 0, NULL, 0) == 0;
}
/* Sort the symbols in RESULT and remove duplicates. */ /* Sort the symbols in RESULT and remove duplicates. */
static void static void
@ -4281,7 +4328,9 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
Only symbols of KIND are searched: Only symbols of KIND are searched:
VARIABLES_DOMAIN - search all symbols, excluding functions, type names, VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
and constants (enums) and constants (enums).
if T_REGEXP is not NULL, only returns var that have
a type matching regular expression T_REGEXP.
FUNCTIONS_DOMAIN - search all functions FUNCTIONS_DOMAIN - search all functions
TYPES_DOMAIN - search all type names TYPES_DOMAIN - search all type names
ALL_DOMAIN - an internal error for this function ALL_DOMAIN - an internal error for this function
@ -4292,6 +4341,7 @@ sort_search_symbols_remove_dups (std::vector<symbol_search> *result)
std::vector<symbol_search> std::vector<symbol_search>
search_symbols (const char *regexp, enum search_domain kind, search_symbols (const char *regexp, enum search_domain kind,
const char *t_regexp,
int nfiles, const char *files[]) int nfiles, const char *files[])
{ {
struct compunit_symtab *cust; struct compunit_symtab *cust;
@ -4317,6 +4367,7 @@ search_symbols (const char *regexp, enum search_domain kind,
enum minimal_symbol_type ourtype4; enum minimal_symbol_type ourtype4;
std::vector<symbol_search> result; std::vector<symbol_search> result;
gdb::optional<compiled_regex> preg; gdb::optional<compiled_regex> preg;
gdb::optional<compiled_regex> treg;
gdb_assert (kind <= TYPES_DOMAIN); gdb_assert (kind <= TYPES_DOMAIN);
@ -4366,6 +4417,13 @@ search_symbols (const char *regexp, enum search_domain kind,
preg.emplace (regexp, cflags, _("Invalid regexp")); preg.emplace (regexp, cflags, _("Invalid regexp"));
} }
if (t_regexp != NULL)
{
int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
? REG_ICASE : 0);
treg.emplace (t_regexp, cflags, _("Invalid regexp"));
}
/* Search through the partial symtabs *first* for all symbols /* Search through the partial symtabs *first* for all symbols
matching the regexp. That way we don't have to reproduce all of matching the regexp. That way we don't have to reproduce all of
the machinery below. */ the machinery below. */
@ -4377,7 +4435,8 @@ search_symbols (const char *regexp, enum search_domain kind,
lookup_name_info::match_any (), lookup_name_info::match_any (),
[&] (const char *symname) [&] (const char *symname)
{ {
return (!preg || preg->exec (symname, return (!preg.has_value ()
|| preg->exec (symname,
0, NULL, 0) == 0); 0, NULL, 0) == 0);
}, },
NULL, NULL,
@ -4413,7 +4472,7 @@ search_symbols (const char *regexp, enum search_domain kind,
|| MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype3
|| MSYMBOL_TYPE (msymbol) == ourtype4) || MSYMBOL_TYPE (msymbol) == ourtype4)
{ {
if (!preg if (!preg.has_value ()
|| preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
NULL, 0) == 0) NULL, 0) == 0)
{ {
@ -4452,7 +4511,7 @@ search_symbols (const char *regexp, enum search_domain kind,
files, nfiles, 1)) files, nfiles, 1))
&& file_matches (symtab_to_fullname (real_symtab), && file_matches (symtab_to_fullname (real_symtab),
files, nfiles, 0))) files, nfiles, 0)))
&& ((!preg && ((!preg.has_value ()
|| preg->exec (SYMBOL_NATURAL_NAME (sym), 0, || preg->exec (SYMBOL_NATURAL_NAME (sym), 0,
NULL, 0) == 0) NULL, 0) == 0)
&& ((kind == VARIABLES_DOMAIN && ((kind == VARIABLES_DOMAIN
@ -4464,9 +4523,13 @@ search_symbols (const char *regexp, enum search_domain kind,
We only want to skip enums here. */ We only want to skip enums here. */
&& !(SYMBOL_CLASS (sym) == LOC_CONST && !(SYMBOL_CLASS (sym) == LOC_CONST
&& (TYPE_CODE (SYMBOL_TYPE (sym)) && (TYPE_CODE (SYMBOL_TYPE (sym))
== TYPE_CODE_ENUM))) == TYPE_CODE_ENUM))
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg, sym)))
|| (kind == FUNCTIONS_DOMAIN || (kind == FUNCTIONS_DOMAIN
&& SYMBOL_CLASS (sym) == LOC_BLOCK) && SYMBOL_CLASS (sym) == LOC_BLOCK
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg, sym)))
|| (kind == TYPES_DOMAIN || (kind == TYPES_DOMAIN
&& SYMBOL_CLASS (sym) == LOC_TYPEDEF)))) && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
{ {
@ -4497,8 +4560,13 @@ search_symbols (const char *regexp, enum search_domain kind,
|| MSYMBOL_TYPE (msymbol) == ourtype3 || MSYMBOL_TYPE (msymbol) == ourtype3
|| MSYMBOL_TYPE (msymbol) == ourtype4) || MSYMBOL_TYPE (msymbol) == ourtype4)
{ {
if (!preg || preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0, /* If the user wants to see var matching a type regexp,
NULL, 0) == 0) then never give a minimal symbol. */
if (kind != VARIABLES_DOMAIN
&& !treg.has_value () /* minimal symbol has never a type ???? */
&& (!preg.has_value ()
|| preg->exec (MSYMBOL_NATURAL_NAME (msymbol), 0,
NULL, 0) == 0))
{ {
/* For functions we can do a quick check of whether the /* For functions we can do a quick check of whether the
symbol might be found via find_pc_symtab. */ symbol might be found via find_pc_symtab. */
@ -4599,7 +4667,9 @@ print_msymbol_info (struct bound_minimal_symbol msymbol)
matches. */ matches. */
static void static void
symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty) symtab_symbol_info (bool quiet,
const char *regexp, enum search_domain kind,
const char *t_regexp, int from_tty)
{ {
static const char * const classnames[] = static const char * const classnames[] =
{"variable", "function", "type"}; {"variable", "function", "type"};
@ -4609,13 +4679,33 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
gdb_assert (kind <= TYPES_DOMAIN); gdb_assert (kind <= TYPES_DOMAIN);
/* Must make sure that if we're interrupted, symbols gets freed. */ /* Must make sure that if we're interrupted, symbols gets freed. */
std::vector<symbol_search> symbols = search_symbols (regexp, kind, 0, NULL); std::vector<symbol_search> symbols = search_symbols (regexp, kind,
t_regexp, 0, NULL);
if (!quiet)
{
if (regexp != NULL) if (regexp != NULL)
{
if (t_regexp != NULL)
printf_filtered
(_("All %ss matching regular expression \"%s\""
" with type matching regulation expression \"%s\":\n"),
classnames[kind], regexp, t_regexp);
else
printf_filtered (_("All %ss matching regular expression \"%s\":\n"), printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
classnames[kind], regexp); classnames[kind], regexp);
}
else
{
if (t_regexp != NULL)
printf_filtered
(_("All defined %ss"
" with type matching regulation expression \"%s\" :\n"),
classnames[kind], t_regexp);
else else
printf_filtered (_("All defined %ss:\n"), classnames[kind]); printf_filtered (_("All defined %ss:\n"), classnames[kind]);
}
}
for (const symbol_search &p : symbols) for (const symbol_search &p : symbols)
{ {
@ -4625,6 +4715,7 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
{ {
if (first) if (first)
{ {
if (!quiet)
printf_filtered (_("\nNon-debugging symbols:\n")); printf_filtered (_("\nNon-debugging symbols:\n"));
first = 0; first = 0;
} }
@ -4643,22 +4734,53 @@ symtab_symbol_info (const char *regexp, enum search_domain kind, int from_tty)
} }
static void static void
info_variables_command (const char *regexp, int from_tty) info_variables_command (const char *args, int from_tty)
{ {
symtab_symbol_info (regexp, VARIABLES_DOMAIN, 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 variables", args);
symtab_symbol_info (quiet,
regexp.empty () ? NULL : regexp.c_str (),
VARIABLES_DOMAIN,
t_regexp.empty () ? NULL : t_regexp.c_str (),
from_tty);
} }
static void static void
info_functions_command (const char *regexp, int from_tty) info_functions_command (const char *args, int from_tty)
{ {
symtab_symbol_info (regexp, FUNCTIONS_DOMAIN, from_tty); std::string regexp;
std::string t_regexp;
bool quiet;
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);
} }
static void static void
info_types_command (const char *regexp, int from_tty) info_types_command (const char *regexp, int from_tty)
{ {
symtab_symbol_info (regexp, TYPES_DOMAIN, from_tty); symtab_symbol_info (false, regexp, TYPES_DOMAIN, NULL, from_tty);
} }
/* Breakpoint all functions matching regular expression. */ /* Breakpoint all functions matching regular expression. */
@ -4701,6 +4823,7 @@ rbreak_command (const char *regexp, int from_tty)
std::vector<symbol_search> symbols = search_symbols (regexp, std::vector<symbol_search> symbols = search_symbols (regexp,
FUNCTIONS_DOMAIN, FUNCTIONS_DOMAIN,
NULL,
nfiles, files); nfiles, files);
scoped_rbreak_breakpoints finalize; scoped_rbreak_breakpoints finalize;
@ -5902,14 +6025,26 @@ _initialize_symtab (void)
symbol_cache_key symbol_cache_key
= register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup); = register_program_space_data_with_cleanup (NULL, symbol_cache_cleanup);
add_info ("variables", info_variables_command, _("\ add_info ("variables", info_variables_command,
All global and static variable names, or those matching REGEXP.")); info_print_args_help (_("\
All global and static variable names or those matching REGEXPs.\n\
Usage: info variables [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
_("global and static variables")));
if (dbx_commands) if (dbx_commands)
add_com ("whereis", class_info, info_variables_command, _("\ add_com ("whereis", class_info, info_variables_command,
All global and static variable names, or those matching REGEXP.")); info_print_args_help (_("\
All global and static variable names, or those matching REGEXPs.\n\
Usage: whereis [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the global and static variables.\n"),
_("global and static variables")));
add_info ("functions", info_functions_command, add_info ("functions", info_functions_command,
_("All function names, or those matching REGEXP.")); info_print_args_help (_("\
All function names or those matching REGEXPs.\n\
Usage: info functions [-q] [-t TYPEREGEXP] [NAMEREGEXP]\n\
Prints the functions.\n"),
_("functions")));
/* FIXME: This command has at least the following problems: /* FIXME: This command has at least the following problems:
1. It prints builtin types (in a very strange and confusing fashion). 1. It prints builtin types (in a very strange and confusing fashion).

View file

@ -25,6 +25,7 @@
#include <string> #include <string>
#include "gdb_vecs.h" #include "gdb_vecs.h"
#include "gdbtypes.h" #include "gdbtypes.h"
#include "gdb_regex.h"
#include "common/enum-flags.h" #include "common/enum-flags.h"
#include "common/function-view.h" #include "common/function-view.h"
#include "common/gdb_optional.h" #include "common/gdb_optional.h"
@ -2057,8 +2058,12 @@ private:
}; };
extern std::vector<symbol_search> search_symbols (const char *, extern std::vector<symbol_search> search_symbols (const char *,
enum search_domain, int, enum search_domain,
const char *,
int,
const char **); const char **);
extern bool treg_matches_sym_type_name (const compiled_regex &treg,
const struct symbol *sym);
/* The name of the ``main'' function. /* The name of the ``main'' function.
FIXME: cagney/2001-03-20: Can't make main_name() const since some FIXME: cagney/2001-03-20: Can't make main_name() const since some