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:
parent
0d4cad90ca
commit
12615cba84
5 changed files with 312 additions and 49 deletions
|
@ -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.
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
127
gdb/stack.c
127
gdb/stack.c
|
@ -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, ®exp, &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, ®exp, &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, _("\
|
||||||
|
|
175
gdb/symtab.c
175
gdb/symtab.c
|
@ -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, ®exp, &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, ®exp, &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).
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue