aboutsummaryrefslogtreecommitdiff
path: root/gdb/stack.c
diff options
context:
space:
mode:
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>2018-07-01 22:56:56 +0200
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>2018-10-27 13:47:45 +0200
commit12615cba8411c845b33b98cc616439c66a34f03a (patch)
tree4187da3c080cabaed4db481f7791f5fb6d1f2186 /gdb/stack.c
parent0d4cad90ca7c4394a1799efaa79c784f84a18161 (diff)
downloadgdb-12615cba8411c845b33b98cc616439c66a34f03a.zip
gdb-12615cba8411c845b33b98cc616439c66a34f03a.tar.gz
gdb-12615cba8411c845b33b98cc616439c66a34f03a.tar.bz2
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.
Diffstat (limited to 'gdb/stack.c')
-rw-r--r--gdb/stack.c139
1 files changed, 121 insertions, 18 deletions
diff --git a/gdb/stack.c b/gdb/stack.c
index 87b493f..abbaf5d 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -88,8 +88,10 @@ const char *print_entry_values = print_entry_values_default;
/* Prototypes for local functions. */
-static void print_frame_local_vars (struct frame_info *, int,
- struct ui_file *);
+static void print_frame_local_vars (struct frame_info *frame,
+ 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,
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);
- 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. */
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
{
+ gdb::optional<compiled_regex> preg;
+ gdb::optional<compiled_regex> treg;
struct frame_id frame_id;
int num_tabs;
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 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);
if (frame == NULL)
{
@@ -2092,14 +2104,38 @@ do_print_variable_and_value (const char *print_name,
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 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. */
static void
-print_frame_local_vars (struct frame_info *frame, int num_tabs,
- struct ui_file *stream)
+print_frame_local_vars (struct frame_info *frame,
+ bool quiet,
+ const char *regexp, const char *t_regexp,
+ int num_tabs, struct ui_file *stream)
{
struct print_variable_and_value_data cb_data;
const struct block *block;
@@ -2107,18 +2143,22 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
if (!get_frame_pc_if_available (frame, &pc))
{
- fprintf_filtered (stream,
- _("PC unavailable, cannot determine locals.\n"));
+ if (!quiet)
+ fprintf_filtered (stream,
+ _("PC unavailable, cannot determine locals.\n"));
return;
}
block = get_frame_block (frame, 0);
if (block == 0)
{
- fprintf_filtered (stream, "No symbol table info available.\n");
+ if (!quiet)
+ fprintf_filtered (stream, "No symbol table info available.\n");
return;
}
+ prepare_reg (regexp, &cb_data.preg);
+ prepare_reg (t_regexp, &cb_data.treg);
cb_data.frame_id = get_frame_id (frame);
cb_data.num_tabs = 4 * num_tabs;
cb_data.stream = stream;
@@ -2134,14 +2174,33 @@ print_frame_local_vars (struct frame_info *frame, int num_tabs,
do_print_variable_and_value,
&cb_data);
- if (!cb_data.values_printed)
- fprintf_filtered (stream, _("No locals.\n"));
+ if (!cb_data.values_printed && !quiet)
+ {
+ if (regexp == NULL && t_regexp == NULL)
+ fprintf_filtered (stream, _("No locals.\n"));
+ else
+ fprintf_filtered (stream, _("No matching locals.\n"));
+ }
}
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);
+
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);
}
@@ -2180,29 +2239,45 @@ iterate_over_block_arg_vars (const struct block *b,
/* Print all argument variables of the function of FRAME.
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. */
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 symbol *func;
CORE_ADDR pc;
+ gdb::optional<compiled_regex> preg;
+ gdb::optional<compiled_regex> treg;
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;
}
func = get_frame_function (frame);
if (func == NULL)
{
- fprintf_filtered (stream, _("No symbol table info available.\n"));
+ if (!quiet)
+ fprintf_filtered (stream, _("No symbol table info available.\n"));
return;
}
+ prepare_reg (regexp, &cb_data.preg);
+ prepare_reg (t_regexp, &cb_data.treg);
cb_data.frame_id = get_frame_id (frame);
cb_data.num_tabs = 0;
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. */
frame = NULL;
- if (!cb_data.values_printed)
- fprintf_filtered (stream, _("No arguments.\n"));
+ if (!cb_data.values_printed && !quiet)
+ {
+ if (regexp == NULL && t_regexp == NULL)
+ fprintf_filtered (stream, _("No arguments.\n"));
+ else
+ fprintf_filtered (stream, _("No matching arguments.\n"));
+ }
}
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.")),
+ quiet,
+ regexp.empty () ? NULL : regexp.c_str (),
+ t_regexp.empty () ? NULL : t_regexp.c_str (),
gdb_stdout);
}
@@ -2994,9 +3089,17 @@ Usage: info frame level LEVEL"),
&info_frame_cmd_list);
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,
- _("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)
add_com ("func", class_stack, func_command, _("\