summaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2021-05-18 13:46:19 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2021-06-25 20:54:29 +0100
commit0e350a054bbeb4d00f2c430c4815c82d5ffb47a7 (patch)
tree079b2ed8a2344ef2b6b7c854b9ccfe8450d34137 /gdb/symtab.c
parent4a0788e08cbf9e7b90640475b17afbbf5423ea9d (diff)
downloadbinutils-gdb-0e350a054bbeb4d00f2c430c4815c82d5ffb47a7.tar.gz
gdb/mi: add regexp filtering to -file-list-exec-source-files
This commit extends the existing MI command -file-list-exec-source-files to provide the same regular expression based filtering that the equivalent CLI command "info sources" provides. The new command syntax is: -file-list-exec-source-files [--basename | --dirname] [--] [REGEXP] All options are optional, which ensures the command is backward compatible. As part of this work I have unified the CLI and MI code. As a result of the unified code I now provide additional information in the MI command output, there is now a new field 'debug-fully-read' included with each source file. This field which has the values 'true' or 'false', indicates if the source file is from a compilation unit that has had its debug information fully read. However, as this is additional information, a well written front-end should just ignore this field if it doesn't understand it, so things should still be backward compatible. gdb/ChangeLog: * NEWS: Mention additions to -file-list-exec-source-files. * mi/mi-cmd-file.c (print_partial_file_name): Delete. (mi_cmd_file_list_exec_source_files): Rewrite to handle command options, and make use of info_sources_worker. * symtab.c (struct info_sources_filter): Moved to symtab.h. (info_sources_filter::print): Take uiout argument, produce output through uiout. (struct output_source_filename_data) <output_source_filename_data>: Take uiout argument, store into m_uiout. <output>: Rewrite comment, add additional arguments to declaration. <operator()>: Send more arguments to output. <m_uiout>: New member variable. (output_source_filename_data::output): Take extra arguments, produce output through m_uiout, and structure for MI. (output_source_filename_data::print_header): Produce output through m_uiout. (info_sources_worker): New function, the implementation is taken from info_sources_command, but modified so produce output through a ui_out. (info_sources_command): The second half of this function has gone to become info_sources_worker. * symtab.h (struct info_sources_filter): Moved from symtab.c, add extra parameter to print member function. (info_sources_worker): Declare. gdb/doc/ChangeLog: * gdb.texinfo (GDB/MI File Commands): Document extensions to -file-list-exec-source-files. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-filename.exp: Update expected results. * gdb.mi/mi-file.exp: Likewise. * gdb.mi/mi-info-sources-base.c: New file. * gdb.mi/mi-info-sources.c: New file. * gdb.mi/mi-info-sources.exp: New file.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c190
1 files changed, 92 insertions, 98 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 2ff79e0cddf..e300596be6e 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -4200,58 +4200,6 @@ operator_chars (const char *p, const char **end)
}
-/* Class used to encapsulate the filename filtering for the "info sources"
- command. */
-struct info_sources_filter
-{
- /* If filename filtering is being used (see M_C_REGEXP) then which part
- of the filename is being filtered against? */
- enum class match_on
- {
- /* Match against the full filename. */
- FULLNAME,
-
- /* Match only against the directory part of the full filename. */
- DIRNAME,
-
- /* Match only against the basename part of the full filename. */
- BASENAME
- };
-
- /* Create a filter of MATCH_TYPE using regular expression REGEXP. If
- REGEXP is nullptr then all files will match the filter and MATCH_TYPE
- is ignored.
-
- The string pointed too by REGEXP must remain live and unchanged for
- this lifetime of this object as the object only retains a copy of the
- pointer. */
- info_sources_filter (match_on match_type, const char *regexp);
-
- DISABLE_COPY_AND_ASSIGN (info_sources_filter);
-
- /* Does FULLNAME match the filter defined by this object, return true if
- it does, otherwise, return false. If there is no filtering defined
- then this function will always return true. */
- bool matches (const char *fullname) const;
-
- /* Print a single line describing this filter, used as part of the "info
- sources" command output. If there is no filter in place then nothing
- is printed. */
- void print () const;
-
-private:
-
- /* The type of filtering in place. */
- match_on m_match_type;
-
- /* Points to the original regexp used to create this filter. */
- const char *m_regexp;
-
- /* A compiled version of M_REGEXP. This object is only given a value if
- M_REGEXP is not nullptr and is not the empty string. */
- gdb::optional<compiled_regex> m_c_regexp;
-};
-
/* See class declaration. */
info_sources_filter::info_sources_filter (match_on match_type,
@@ -4307,7 +4255,7 @@ info_sources_filter::matches (const char *fullname) const
/* See class declaration. */
void
-info_sources_filter::print () const
+info_sources_filter::print (struct ui_out *uiout) const
{
if (m_c_regexp.has_value ())
{
@@ -4316,12 +4264,12 @@ info_sources_filter::print () const
switch (m_match_type)
{
case match_on::DIRNAME:
- printf_filtered (_("(dirname matching regular expression \"%s\")"),
- m_regexp);
+ uiout->message (_("(dirname matching regular expression \"%s\")"),
+ m_regexp);
break;
case match_on::BASENAME:
- printf_filtered (_("(basename matching regular expression \"%s\")"),
- m_regexp);
+ uiout->message (_("(basename matching regular expression \"%s\")"),
+ m_regexp);
break;
case match_on::FULLNAME:
printf_filtered (_("(filename matching regular expression \"%s\")"),
@@ -4337,10 +4285,12 @@ info_sources_filter::print () const
struct output_source_filename_data
{
/* Create an object for displaying the results of the 'info sources'
- command. FILTER must remain valid and unchanged for the lifetime of
- this object as this object retains a reference to FILTER. */
- output_source_filename_data (const info_sources_filter &filter)
- : m_filter (filter)
+ command to UIOUT. FILTER must remain valid and unchanged for the
+ lifetime of this object as this object retains a reference to FILTER. */
+ output_source_filename_data (struct ui_out *uiout,
+ const info_sources_filter &filter)
+ : m_filter (filter),
+ m_uiout (uiout)
{ /* Nothing. */ }
DISABLE_COPY_AND_ASSIGN (output_source_filename_data);
@@ -4353,9 +4303,14 @@ struct output_source_filename_data
m_filename_seen_cache.clear ();
}
- /* Worker for sources_info. Force line breaks at ,'s. NAME is the name
- to print. */
- void output (const char *name);
+ /* Worker for sources_info, outputs the file name formatted for either
+ cli or mi (based on the current_uiout). In cli mode displays
+ FULLNAME with a comma separating this name from any previously
+ printed name (line breaks are added at the comma). In MI mode
+ outputs a tuple containing DISP_NAME (the files display name),
+ FULLNAME, and EXPANDED_P (true when this file is from a fully
+ expanded symtab, otherwise false). */
+ void output (const char *disp_name, const char *fullname, bool expanded_p);
/* Prints the header messages for the source files that will be printed
with the matching info present in the current object state.
@@ -4367,7 +4322,9 @@ struct output_source_filename_data
quick_symbol_functions::map_symbol_filenames. */
void operator() (const char *filename, const char *fullname)
{
- output (fullname != nullptr ? fullname : filename);
+ /* The false here indicates that this file is from an unexpanded
+ symtab. */
+ output (filename, fullname, false);
}
private:
@@ -4380,12 +4337,17 @@ private:
/* How source filename should be filtered. */
const info_sources_filter &m_filter;
+
+ /* The object to which output is sent. */
+ struct ui_out *m_uiout;
};
/* See comment in class declaration above. */
void
-output_source_filename_data::output (const char *name)
+output_source_filename_data::output (const char *disp_name,
+ const char *fullname,
+ bool expanded_p)
{
/* Since a single source file can result in several partial symbol
tables, we need to avoid printing it more than once. Note: if
@@ -4397,20 +4359,37 @@ output_source_filename_data::output (const char *name)
symtabs; it doesn't hurt to check. */
/* Was NAME already seen? If so, then don't print it again. */
- if (m_filename_seen_cache.seen (name))
+ if (m_filename_seen_cache.seen (fullname))
return;
/* If the filter rejects this file then don't print it. */
- if (!m_filter.matches (name))
+ if (!m_filter.matches (fullname))
return;
+ ui_out_emit_tuple ui_emitter (m_uiout, nullptr);
+
/* Print it and reset *FIRST. */
if (!m_first)
- printf_filtered (", ");
+ m_uiout->text (", ");
m_first = false;
wrap_here ("");
- fputs_styled (name, file_name_style.style (), gdb_stdout);
+ if (m_uiout->is_mi_like_p ())
+ {
+ m_uiout->field_string ("file", disp_name, file_name_style.style ());
+ if (fullname != nullptr)
+ m_uiout->field_string ("fullname", fullname,
+ file_name_style.style ());
+ m_uiout->field_string ("debug-fully-read",
+ (expanded_p ? "true" : "false"));
+ }
+ else
+ {
+ if (fullname == nullptr)
+ fullname = disp_name;
+ m_uiout->field_string ("fullname", fullname,
+ file_name_style.style ());
+ }
}
/* See comment is class declaration above. */
@@ -4418,9 +4397,9 @@ output_source_filename_data::output (const char *name)
void
output_source_filename_data::print_header (const char *symbol_msg)
{
- puts_filtered (symbol_msg);
- m_filter.print ();
- puts_filtered ("\n");
+ m_uiout->text (symbol_msg);
+ m_filter.print (m_uiout);
+ m_uiout->text ("\n");
}
/* For the 'info sources' command, what part of the file names should we be
@@ -4476,6 +4455,42 @@ info_sources_command_completer (cmd_list_element *ignore,
return;
}
+/* See symtab.h. */
+
+void
+info_sources_worker (struct ui_out *uiout,
+ const info_sources_filter &filter)
+{
+ output_source_filename_data data (uiout, filter);
+
+ ui_out_emit_list results_emitter (uiout, "files");
+ gdb::optional<ui_out_emit_tuple> output_tuple;
+ gdb::optional<ui_out_emit_list> sources_list;
+
+ if (!uiout->is_mi_like_p ())
+ data.print_header (_("Source files for which symbols have been read in:\n"));
+
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ for (compunit_symtab *cu : objfile->compunits ())
+ {
+ for (symtab *s : compunit_filetabs (cu))
+ {
+ const char *file = symtab_to_filename_for_display (s);
+ const char *fullname = symtab_to_fullname (s);
+ data.output (file, fullname, true);
+ }
+ }
+ }
+
+ uiout->text ("\n\n");
+ if (!uiout->is_mi_like_p ())
+ data.print_header (_("Source files for which symbols will be read in on demand:\n"));
+ data.reset_output ();
+ map_symbol_filenames (data, true /*need_fullname*/);
+ uiout->text ("\n");
+}
+
/* Implement the 'info sources' command. */
static void
@@ -4493,7 +4508,7 @@ info_sources_command (const char *args, int from_tty)
error (_("You cannot give both -basename and -dirname to 'info sources'."));
const char *regex = nullptr;
- if (args != nullptr && *args != '\000')
+ if (args != NULL && *args != '\000')
regex = args;
if ((match_opts.dirname || match_opts.basename) && regex == nullptr)
@@ -4508,29 +4523,7 @@ info_sources_command (const char *args, int from_tty)
match_type = info_sources_filter::match_on::FULLNAME;
info_sources_filter filter (match_type, regex);
- output_source_filename_data data (filter);
-
- data.print_header (_("Source files for which symbols have been read in:\n"));
-
- for (objfile *objfile : current_program_space->objfiles ())
- {
- for (compunit_symtab *cu : objfile->compunits ())
- {
- for (symtab *s : compunit_filetabs (cu))
- {
- const char *fullname = symtab_to_fullname (s);
-
- data.output (fullname);
- }
- }
- }
- printf_filtered ("\n\n");
-
- data.print_header (_("Source files for which symbols will be read in on demand:\n"));
-
- data.reset_output ();
- map_symbol_filenames (data, true /*need_fullname*/);
- printf_filtered ("\n");
+ info_sources_worker (current_uiout, filter);
}
/* Compare FILE against all the entries of FILENAMES. If BASENAMES is
@@ -6890,7 +6883,8 @@ Print information about all types matching REGEXP, or all types if no\n\
REGEXP is given. The optional flag -q disables printing of headers."));
set_cmd_completer_handle_brkchars (c, info_types_command_completer);
- const auto info_sources_opts = make_info_sources_options_def_group (nullptr);
+ const auto info_sources_opts
+ = make_info_sources_options_def_group (nullptr);
static std::string info_sources_help
= gdb::option::build_help (_("\