From 73589123891e1c5ae9ee9c6e359a2a37133200de Mon Sep 17 00:00:00 2001 From: "Paul N. Hilfinger" Date: Mon, 4 Oct 2010 06:34:40 +0000 Subject: [PATCH] Replace wild_match with faster version and modify its interface. This new version of wild_match is comparable in speed to strcmp_iw, and has the same signature and same return value for equal names. gdb/ChangeLog: * ada-lang.c (wild_match): Reimplement. Change API to eliminate unused length argument, reverse arguments and make 0 the 'true' return value. (advance_wild_match): New auxiliary function for wild_match to improve readability. (ada_match_name, ada_add_block_symbols): Use new API for wild_match. * psymtab.c (ada_lookup_partial_symbol, map_ada_symtabs): Use new API for wild_match. * symfile.h (map_ada_symtabs): Modify declaration to use new API for wild_match. * dwarf2read.c (dw2_map_ada_symtabs): Ditto. --- gdb/ChangeLog | 14 +++++++++ gdb/ada-lang.c | 89 +++++++++++++++++++++++++++++++++++++++++++------------- gdb/dwarf2read.c | 2 +- gdb/psymtab.c | 6 ++-- gdb/symfile.h | 2 +- 5 files changed, 88 insertions(+), 25 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d119872..7a385fb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2010-10-03 Paul Hilfinger + + * ada-lang.c (wild_match): Reimplement. + Change API to eliminate unused length argument, reverse arguments and + make 0 the 'true' return value. + (advance_wild_match): New auxiliary function for wild_match to improve + readability. + (ada_match_name, ada_add_block_symbols): Use new API for wild_match. + * psymtab.c (ada_lookup_partial_symbol, map_ada_symtabs): Use new + API for wild_match. + * symfile.h (map_ada_symtabs): Modify declaration to use new API for + wild_match. + * dwarf2read.c (dw2_map_ada_symtabs): Ditto. + 2010-10-01 Doug Evans * dwarf2read.c (_initialize_dwarf2_read): Add usage info to help text diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 173e901..668b2e2 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -200,7 +200,9 @@ static int equiv_types (struct type *, struct type *); static int is_name_suffix (const char *); -static int wild_match (const char *, int, const char *); +static int advance_wild_match (const char **, const char *, int); + +static int wild_match (const char *, const char *); static struct value *ada_coerce_ref (struct value *); @@ -1260,7 +1262,7 @@ ada_match_name (const char *sym_name, const char *name, int wild) if (sym_name == NULL || name == NULL) return 0; else if (wild) - return wild_match (name, strlen (name), sym_name); + return wild_match (sym_name, name) == 0; else { int len_name = strlen (name); @@ -5012,30 +5014,77 @@ is_valid_name_for_wild_match (const char *name0) return 1; } -/* True if NAME represents a name of the form A1.A2....An, n>=1 and - PATN[0..PATN_LEN-1] = Ak.Ak+1.....An for some k >= 1. Ignores - informational suffixes of NAME (i.e., for which is_name_suffix is - true). */ +/* Advance *NAMEP to next occurrence of TARGET0 in the string NAME0 + that could start a simple name. Assumes that *NAMEP points into + the string beginning at NAME0. */ static int -wild_match (const char *patn0, int patn_len, const char *name0) +advance_wild_match (const char **namep, const char *name0, int target0) { - char* match; - const char* start; + const char *name = *namep; - start = name0; while (1) { - match = strstr (start, patn0); - if (match == NULL) + int t0, t1, t2; + + t0 = *name; + if (t0 == '_') + { + t1 = name[1]; + if ((t1 >= 'a' && t1 <= 'z') || (t1 >= '0' && t1 <= '9')) + { + name += 1; + if (name == name0 + 5 && strncmp (name0, "_ada", 4) == 0) + break; + else + name += 1; + } + else if (t1 == '_' && + (((t2 = name[2]) >= 'a' && t2 <= 'z') || t2 == target0)) + { + name += 2; + break; + } + else + return 0; + } + else if ((t0 >= 'a' && t0 <= 'z') || (t0 >= '0' && t0 <= '9')) + name += 1; + else return 0; - if ((match == name0 - || match[-1] == '.' - || (match > name0 + 1 && match[-1] == '_' && match[-2] == '_') - || (match == name0 + 5 && strncmp ("_ada_", name0, 5) == 0)) - && is_name_suffix (match + patn_len)) - return (match == name0 || is_valid_name_for_wild_match (name0)); - start = match + 1; + } + + *namep = name; + return 1; +} + +/* Return 0 iff NAME encodes a name of the form prefix.PATN. Ignores any + informational suffixes of NAME (i.e., for which is_name_suffix is + true). Assumes that PATN is a lower-cased Ada simple name. */ + +static int +wild_match (const char *name, const char *patn) +{ + const char *p, *n; + const char *name0 = name; + + while (1) + { + const char *match = name; + + if (*name == *patn) + { + for (name += 1, p = patn + 1; *p != '\0'; name += 1, p += 1) + if (*p != *name) + break; + if (*p == '\0' && is_name_suffix (name)) + return match != name0 && !is_valid_name_for_wild_match (name0); + + if (name[-1] == '_') + name -= 1; + } + if (!advance_wild_match (&name, name0, *patn)) + return 1; } } @@ -5069,7 +5118,7 @@ ada_add_block_symbols (struct obstack *obstackp, { if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), SYMBOL_DOMAIN (sym), domain) - && wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym))) + && wild_match (SYMBOL_LINKAGE_NAME (sym), name) == 0) { if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED) continue; diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 302f81f..e48f91e 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2359,7 +2359,7 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) static void dw2_map_ada_symtabs (struct objfile *objfile, - int (*wild_match) (const char *, int, const char *), + int (*wild_match) (const char *, const char *), int (*is_name_suffix) (const char *), void (*callback) (struct objfile *, struct symtab *, void *), diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 4aec16e..eac3e1a 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -974,7 +974,7 @@ find_symbol_file_from_partial (struct objfile *objfile, const char *name) static struct partial_symbol * ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global, domain_enum namespace, int wild, - int (*wild_match) (const char *, int, const char *), + int (*wild_match) (const char *, const char *), int (*is_name_suffix) (const char *)) { struct partial_symbol **start; @@ -999,7 +999,7 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), SYMBOL_DOMAIN (psym), namespace) - && (*wild_match) (name, name_len, SYMBOL_LINKAGE_NAME (psym))) + && (*wild_match) (SYMBOL_LINKAGE_NAME (psym), name) == 0) return psym; } return NULL; @@ -1112,7 +1112,7 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, static void map_ada_symtabs (struct objfile *objfile, - int (*wild_match) (const char *, int, const char *), + int (*wild_match) (const char *, const char *), int (*is_name_suffix) (const char *), void (*callback) (struct objfile *, struct symtab *, void *), const char *name, int global, domain_enum namespace, int wild, diff --git a/gdb/symfile.h b/gdb/symfile.h index ae0421d..f9b4e01 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -220,7 +220,7 @@ struct quick_symbol_functions This function is completely ad hoc and new implementations should refer to the psymtab implementation to see what to do. */ void (*map_ada_symtabs) (struct objfile *objfile, - int (*wild_match) (const char *, int, const char *), + int (*wild_match) (const char *, const char *), int (*is_name_suffix) (const char *), void (*callback) (struct objfile *, struct symtab *, void *), -- 2.7.4