printf_filtered ("\n");
}
-/* Compare FILE against all the NFILES entries of FILES. If BASENAMES is
- non-zero compare only lbasename of FILES. */
+/* Compare FILE against all the entries of FILENAMES. If BASENAMES is
+ true compare only lbasename of FILENAMES. */
-static int
-file_matches (const char *file, const char *files[], int nfiles, int basenames)
+static bool
+file_matches (const char *file, const std::vector<const char *> &filenames,
+ bool basenames)
{
- int i;
+ if (filenames.empty ())
+ return true;
- if (file != NULL && nfiles != 0)
+ for (const char *name : filenames)
{
- for (i = 0; i < nfiles; i++)
- {
- if (compare_filenames_for_search (file, (basenames
- ? lbasename (files[i])
- : files[i])))
- return 1;
- }
+ name = (basenames ? lbasename (name) : name);
+ if (compare_filenames_for_search (file, name))
+ return true;
}
- else if (nfiles == 0)
- return 1;
- return 0;
+
+ return false;
}
/* Helper function for sort_search_symbols_remove_dups and qsort. Can only
result->end ());
}
-/* Search the symbol table for matches to the regular expression REGEXP,
- returning the results.
-
- Only symbols of KIND are searched:
- VARIABLES_DOMAIN - search all symbols, excluding functions, type names,
- 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
- TYPES_DOMAIN - search all type names
- ALL_DOMAIN - an internal error for this function
-
- Within each file the results are sorted locally; each symtab's global and
- static blocks are separately alphabetized.
- Duplicate entries are removed.
-
- When EXCLUDE_MINSYMS is false then matching minsyms are also returned,
- otherwise they are excluded. */
+/* See symtab.h. */
std::vector<symbol_search>
-search_symbols (const char *regexp, enum search_domain kind,
- const char *t_regexp,
- int nfiles, const char *files[],
- bool exclude_minsyms)
+global_symbol_searcher::search () const
{
const struct blockvector *bv;
const struct block *b;
gdb::optional<compiled_regex> preg;
gdb::optional<compiled_regex> treg;
- gdb_assert (kind != ALL_DOMAIN);
+ gdb_assert (m_kind != ALL_DOMAIN);
- ourtype = types[kind];
- ourtype2 = types2[kind];
- ourtype3 = types3[kind];
- ourtype4 = types4[kind];
+ ourtype = types[m_kind];
+ ourtype2 = types2[m_kind];
+ ourtype3 = types3[m_kind];
+ ourtype4 = types4[m_kind];
- if (regexp != NULL)
+ if (m_symbol_name_regexp != NULL)
{
+ const char *symbol_name_regexp = m_symbol_name_regexp;
+
/* Make sure spacing is right for C++ operators.
This is just a courtesy to make the matching less sensitive
to how many spaces the user leaves between 'operator'
and <TYPENAME> or <OPERATOR>. */
const char *opend;
- const char *opname = operator_chars (regexp, &opend);
+ const char *opname = operator_chars (symbol_name_regexp, &opend);
if (*opname)
{
char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
sprintf (tmp, "operator%.*s%s", fix, " ", opname);
- regexp = tmp;
+ symbol_name_regexp = tmp;
}
}
int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
? REG_ICASE : 0);
- preg.emplace (regexp, cflags, _("Invalid regexp"));
+ preg.emplace (symbol_name_regexp, cflags,
+ _("Invalid regexp"));
}
- if (t_regexp != NULL)
+ if (m_symbol_type_regexp != NULL)
{
int cflags = REG_NOSUB | (case_sensitivity == case_sensitive_off
? REG_ICASE : 0);
- treg.emplace (t_regexp, cflags, _("Invalid regexp"));
+ treg.emplace (m_symbol_type_regexp, cflags,
+ _("Invalid regexp"));
}
- /* Search through the partial symtabs *first* for all symbols
- matching the regexp. That way we don't have to reproduce all of
- the machinery below. */
+ /* Search through the partial symtabs *first* for all symbols matching
+ the m_symbol_name_regexp (in preg). That way we don't have to
+ reproduce all of the machinery below. */
expand_symtabs_matching ([&] (const char *filename, bool basenames)
{
- return file_matches (filename, files, nfiles,
+ return file_matches (filename, filenames,
basenames);
},
lookup_name_info::match_any (),
0, NULL, 0) == 0);
},
NULL,
- kind);
+ m_kind);
/* Here, we search through the minimal symbol tables for functions
and variables that match, and force their symbols to be read.
all objfiles. In large programs (1000s of shared libs) searching all
objfiles is not worth the pain. */
- if (nfiles == 0 && (kind == VARIABLES_DOMAIN || kind == FUNCTIONS_DOMAIN))
+ if (filenames.empty () && (m_kind == VARIABLES_DOMAIN
+ || m_kind == FUNCTIONS_DOMAIN))
{
for (objfile *objfile : current_program_space->objfiles ())
{
lookup functions is to expand the symbol
table if msymbol is found, for the benefit of
the next loop on compunits. */
- if (kind == FUNCTIONS_DOMAIN
+ if (m_kind == FUNCTIONS_DOMAIN
? (find_pc_compunit_symtab
(MSYMBOL_VALUE_ADDRESS (objfile, msymbol))
== NULL)
/* Check first sole REAL_SYMTAB->FILENAME. It does
not need to be a substring of symtab_to_fullname as
it may contain "./" etc. */
- if ((file_matches (real_symtab->filename, files, nfiles, 0)
+ if ((file_matches (real_symtab->filename, filenames, false)
|| ((basenames_may_differ
|| file_matches (lbasename (real_symtab->filename),
- files, nfiles, 1))
+ filenames, true))
&& file_matches (symtab_to_fullname (real_symtab),
- files, nfiles, 0)))
+ filenames, false)))
&& ((!preg.has_value ()
|| preg->exec (sym->natural_name (), 0,
NULL, 0) == 0)
- && ((kind == VARIABLES_DOMAIN
+ && ((m_kind == VARIABLES_DOMAIN
&& SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_UNRESOLVED
&& SYMBOL_CLASS (sym) != LOC_BLOCK
== TYPE_CODE_ENUM))
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg, sym)))
- || (kind == FUNCTIONS_DOMAIN
+ || (m_kind == FUNCTIONS_DOMAIN
&& SYMBOL_CLASS (sym) == LOC_BLOCK
&& (!treg.has_value ()
|| treg_matches_sym_type_name (*treg,
sym)))
- || (kind == TYPES_DOMAIN
+ || (m_kind == TYPES_DOMAIN
&& SYMBOL_CLASS (sym) == LOC_TYPEDEF
&& SYMBOL_DOMAIN (sym) != MODULE_DOMAIN)
- || (kind == MODULES_DOMAIN
+ || (m_kind == MODULES_DOMAIN
&& SYMBOL_DOMAIN (sym) == MODULE_DOMAIN
&& SYMBOL_LINE (sym) != 0))))
{
if (!result.empty ())
sort_search_symbols_remove_dups (&result);
- /* If there are no eyes, avoid all contact. I mean, if there are
- no debug symbols, then add matching minsyms. But if the user wants
- to see symbols matching a type regexp, then never give a minimal symbol,
- as we assume that a minimal symbol does not have a type. */
+ /* If there are no debug symbols, then add matching minsyms. But if the
+ user wants to see symbols matching a type m_symbol_type_regexp, then
+ never give a minimal symbol, as we assume that a minimal symbol does
+ not have a type. */
- if ((found_misc || (nfiles == 0 && kind != FUNCTIONS_DOMAIN))
- && !exclude_minsyms
+ if ((found_misc || (filenames.empty () && m_kind != FUNCTIONS_DOMAIN))
+ && !m_exclude_minsyms
&& !treg.has_value ())
{
for (objfile *objfile : current_program_space->objfiles ())
{
/* For functions we can do a quick check of whether the
symbol might be found via find_pc_symtab. */
- if (kind != FUNCTIONS_DOMAIN
+ if (m_kind != FUNCTIONS_DOMAIN
|| (find_pc_compunit_symtab
(MSYMBOL_VALUE_ADDRESS (objfile, msymbol))
== NULL))
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,
- exclude_minsyms);
+ global_symbol_searcher spec (kind, regexp);
+ spec.set_symbol_type_regexp (t_regexp);
+ spec.set_exclude_minsyms (exclude_minsyms);
+ std::vector<symbol_search> symbols = spec.search ();
if (!quiet)
{
rbreak_command (const char *regexp, int from_tty)
{
std::string string;
- const char **files = NULL;
- const char *file_name;
- int nfiles = 0;
+ const char *file_name = nullptr;
- if (regexp)
+ if (regexp != nullptr)
{
const char *colon = strchr (regexp, ':');
while (isspace (local_name[colon_index]))
local_name[colon_index--] = 0;
file_name = local_name;
- files = &file_name;
- nfiles = 1;
regexp = skip_spaces (colon + 1);
}
}
- std::vector<symbol_search> symbols = search_symbols (regexp,
- FUNCTIONS_DOMAIN,
- NULL,
- nfiles, files,
- false);
+ global_symbol_searcher spec (FUNCTIONS_DOMAIN, regexp);
+ if (file_name != nullptr)
+ spec.filenames.push_back (file_name);
+ std::vector<symbol_search> symbols = spec.search ();
scoped_rbreak_breakpoints finalize;
for (const symbol_search &p : symbols)
std::vector<module_symbol_search> results;
/* Search for all modules matching MODULE_REGEXP. */
- std::vector<symbol_search> modules = search_symbols (module_regexp,
- MODULES_DOMAIN,
- NULL, 0, NULL,
- true);
+ global_symbol_searcher spec1 (MODULES_DOMAIN, module_regexp);
+ spec1.set_exclude_minsyms (true);
+ std::vector<symbol_search> modules = spec1.search ();
/* Now search for all symbols of the required KIND matching the required
regular expressions. We figure out which ones are in which modules
below. */
- std::vector<symbol_search> symbols = search_symbols (regexp, kind,
- type_regexp, 0,
- NULL, true);
+ global_symbol_searcher spec2 (kind, regexp);
+ spec2.set_symbol_type_regexp (type_regexp);
+ spec2.set_exclude_minsyms (true);
+ std::vector<symbol_search> symbols = spec2.search ();
/* Now iterate over all MODULES, checking to see which items from
SYMBOLS are in each module. */
extern const char *domain_name (domain_enum);
-/* Searching domains, used for `search_symbols'. Element numbers are
+/* Searching domains, used when searching for symbols. Element numbers are
hardcoded in GDB, check all enum uses before changing it. */
enum search_domain
extern symbol *find_function_alias_target (bound_minimal_symbol msymbol);
/* Symbol searching */
-/* Note: struct symbol_search, search_symbols, et.al. are declared here,
- instead of making them local to symtab.c, for gdbtk's sake. */
-/* When using search_symbols, a vector of the following structs is
- returned. */
+/* When using the symbol_searcher struct to search for symbols, a vector of
+ the following structs is returned. */
struct symbol_search
{
symbol_search (int block_, struct symbol *symbol_)
const symbol_search &sym_b);
};
-extern std::vector<symbol_search> search_symbols (const char *,
- enum search_domain,
- const char *,
- int,
- const char **,
- bool);
+/* In order to search for global symbols of a particular kind matching
+ particular regular expressions, create an instance of this structure and
+ call the SEARCH member function. */
+class global_symbol_searcher
+{
+public:
+
+ /* Constructor. */
+ global_symbol_searcher (enum search_domain kind,
+ const char *symbol_name_regexp)
+ : m_kind (kind),
+ m_symbol_name_regexp (symbol_name_regexp)
+ {
+ /* The symbol searching is designed to only find one kind of thing. */
+ gdb_assert (m_kind != ALL_DOMAIN);
+ }
+
+ /* Set the optional regexp that matches against the symbol type. */
+ void set_symbol_type_regexp (const char *regexp)
+ {
+ m_symbol_type_regexp = regexp;
+ }
+
+ /* Set the flag to exclude minsyms from the search results. */
+ void set_exclude_minsyms (bool exclude_minsyms)
+ {
+ m_exclude_minsyms = exclude_minsyms;
+ }
+
+ /* Search the symbols from all objfiles in the current program space
+ looking for matches as defined by the current state of this object.
+
+ Within each file the results are sorted locally; each symtab's global
+ and static blocks are separately alphabetized. Duplicate entries are
+ removed. */
+ std::vector<symbol_search> search () const;
+
+ /* The set of source files to search in for matching symbols. This is
+ currently public so that it can be populated after this object has
+ been constructed. */
+ std::vector<const char *> filenames;
+
+private:
+ /* The kind of symbols are we searching for.
+ VARIABLES_DOMAIN - Search all symbols, excluding functions, type
+ names, and constants (enums).
+ FUNCTIONS_DOMAIN - Search all functions..
+ TYPES_DOMAIN - Search all type names.
+ MODULES_DOMAIN - Search all Fortran modules.
+ ALL_DOMAIN - Not valid for this function. */
+ enum search_domain m_kind;
+
+ /* Regular expression to match against the symbol name. */
+ const char *m_symbol_name_regexp = nullptr;
+
+ /* Regular expression to match against the symbol type. */
+ const char *m_symbol_type_regexp = nullptr;
+
+ /* When this flag is false then minsyms that match M_SYMBOL_REGEXP will
+ be included in the results, otherwise they are excluded. */
+ bool m_exclude_minsyms = false;
+};
/* When searching for Fortran symbols within modules (functions/variables)
we return a vector of this type. The first item in the pair is the