summaryrefslogtreecommitdiff
path: root/gdb/symtab.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-01-16 20:40:47 +0000
committerTom Tromey <tromey@redhat.com>2012-01-16 20:40:47 +0000
commit024e0e8b29c57131c65424b31e931e6f8f511248 (patch)
tree83e423e4a9dc457087a4a1a83e9fcbb292055d3f /gdb/symtab.c
parenteb28de4a09f016d3de7caccec781eb70995a4001 (diff)
downloadgdb-024e0e8b29c57131c65424b31e931e6f8f511248.tar.gz
gdb
* NEWS: Add item. * symtab.h (compare_filenames_for_search): Declare. * symtab.c (compare_filenames_for_search): New function. (iterate_over_some_symtabs): Use it. * symfile.h (struct quick_symbol_functions) <map_symtabs_matching_filename>: Change spec. * psymtab.c (partial_map_symtabs_matching_filename): Use compare_filenames_for_search. Update for new spec. * dwarf2read.c (dw2_map_symtabs_matching_filename): Use compare_filenames_for_search. Update for new spec. * breakpoint.c (clear_command): Use compare_filenames_for_search. gdb/doc * gdb.texinfo (Specify Location): Document relative file name handling. gdb/testsuite * gdb.linespec/linespec.exp: Change some tests to use $decimal. Add tests for relative directory.
Diffstat (limited to 'gdb/symtab.c')
-rw-r--r--gdb/symtab.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/gdb/symtab.c b/gdb/symtab.c
index ab6a1aa40cb..1746d69a3e8 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -145,6 +145,35 @@ multiple_symbols_select_mode (void)
const struct block *block_found;
+/* See whether FILENAME matches SEARCH_NAME using the rule that we
+ advertise to the user. (The manual's description of linespecs
+ describes what we advertise). SEARCH_LEN is the length of
+ SEARCH_NAME. We assume that SEARCH_NAME is a relative path.
+ Returns true if they match, false otherwise. */
+
+int
+compare_filenames_for_search (const char *filename, const char *search_name,
+ int search_len)
+{
+ int len = strlen (filename);
+ int offset;
+
+ if (len < search_len)
+ return 0;
+
+ /* The tail of FILENAME must match. */
+ if (FILENAME_CMP (filename + len - search_len, search_name) != 0)
+ return 0;
+
+ /* Either the names must completely match, or the character
+ preceding the trailing SEARCH_NAME segment of FILENAME must be a
+ directory separator. */
+ return (len == search_len
+ || IS_DIR_SEPARATOR (filename[len - search_len - 1])
+ || (HAS_DRIVE_SPEC (filename)
+ && STRIP_DRIVE_SPEC (filename) == &filename[len - search_len]));
+}
+
/* Check for a symtab of a specific name by searching some symtabs.
This is a helper function for callbacks of iterate_over_symtabs.
@@ -169,15 +198,24 @@ iterate_over_some_symtabs (const char *name,
struct symtab *s = NULL;
struct cleanup *cleanup;
const char* base_name = lbasename (name);
+ int name_len = strlen (name);
+ int is_abs = IS_ABSOLUTE_PATH (name);
for (s = first; s != NULL && s != after_last; s = s->next)
{
+ /* Exact match is always ok. */
if (FILENAME_CMP (name, s->filename) == 0)
{
if (callback (s, data))
return 1;
}
+ if (!is_abs && compare_filenames_for_search (s->filename, name, name_len))
+ {
+ if (callback (s, data))
+ return 1;
+ }
+
/* Before we invoke realpath, which can get expensive when many
files are involved, do a quick comparison of the basenames. */
if (! basenames_may_differ
@@ -196,6 +234,13 @@ iterate_over_some_symtabs (const char *name,
if (callback (s, data))
return 1;
}
+
+ if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name,
+ name_len))
+ {
+ if (callback (s, data))
+ return 1;
+ }
}
if (real_path != NULL)
@@ -212,24 +257,16 @@ iterate_over_some_symtabs (const char *name,
if (callback (s, data))
return 1;
}
+
+ if (!is_abs && compare_filenames_for_search (rp, name, name_len))
+ {
+ if (callback (s, data))
+ return 1;
+ }
}
}
}
- /* Now, search for a matching tail (only if name doesn't have any dirs). */
-
- if (lbasename (name) == name)
- {
- for (s = first; s != NULL && s != after_last; s = s->next)
- {
- if (FILENAME_CMP (lbasename (s->filename), name) == 0)
- {
- if (callback (s, data))
- return 1;
- }
- }
- }
-
return 0;
}