aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorDavid Carlton <carlton@bactrian.org>2003-02-24 23:37:02 +0000
committerDavid Carlton <carlton@bactrian.org>2003-02-24 23:37:02 +0000
commit0fe19209f9dde2fd4450b13a9e772203cf313eff (patch)
tree5c56927bc27c7bdb16a65cbc6664f872ddbbe207 /gdb
parentc8d6825d9aa09b432701bb990fe9610442fcbaa1 (diff)
downloadgdb-0fe19209f9dde2fd4450b13a9e772203cf313eff.zip
gdb-0fe19209f9dde2fd4450b13a9e772203cf313eff.tar.gz
gdb-0fe19209f9dde2fd4450b13a9e772203cf313eff.tar.bz2
2003-02-24 David Carlton <carlton@math.stanford.edu>
* symtab.c (lookup_partial_symbol): Use strcmp_iw_ordered to do the comparison, not strcmp. * symfile.c (compare_psymbols): Ditto. * defs.h: Declare strcmp_iw_ordered. * utils.c (strcmp_iw_ordered): New function.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/defs.h2
-rw-r--r--gdb/symfile.c47
-rw-r--r--gdb/symtab.c9
-rw-r--r--gdb/utils.c80
5 files changed, 101 insertions, 45 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dbc65bd..dce6f50 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2003-02-24 David Carlton <carlton@math.stanford.edu>
+
+ * symtab.c (lookup_partial_symbol): Use strcmp_iw_ordered to
+ do the comparison, not strcmp.
+ * symfile.c (compare_psymbols): Ditto.
+ * defs.h: Declare strcmp_iw_ordered.
+ * utils.c (strcmp_iw_ordered): New function.
+
2003-02-24 Jim Blandy <jimb@redhat.com>
* MAINTAINERS (GNU/Linux/x86, linespec, breakpoints, Scheme
diff --git a/gdb/defs.h b/gdb/defs.h
index 7caef76..9aa4ff3 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -305,6 +305,8 @@ extern void notice_quit (void);
extern int strcmp_iw (const char *, const char *);
+extern int strcmp_iw_ordered (const char *, const char *);
+
extern int streq (const char *, const char *);
extern int subset_compare (char *, char *);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 86508d1..9615987 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -213,52 +213,17 @@ compare_symbols (const void *s1p, const void *s2p)
return (strcmp (SYMBOL_PRINT_NAME (*s1), SYMBOL_PRINT_NAME (*s2)));
}
-/*
-
- LOCAL FUNCTION
-
- compare_psymbols -- compare two partial symbols by name
-
- DESCRIPTION
-
- Given pointers to pointers to two partial symbol table entries,
- compare them by name and return -N, 0, or +N (ala strcmp).
- Typically used by sorting routines like qsort().
-
- NOTES
-
- Does direct compare of first two characters before punting
- and passing to strcmp for longer compares. Note that the
- original version had a bug whereby two null strings or two
- identically named one character strings would return the
- comparison of memory following the null byte.
-
- */
+/* This compares two partial symbols by names, using strcmp_iw_ordered
+ for the comparison. */
static int
compare_psymbols (const void *s1p, const void *s2p)
{
- register struct partial_symbol **s1, **s2;
- register char *st1, *st2;
-
- s1 = (struct partial_symbol **) s1p;
- s2 = (struct partial_symbol **) s2p;
- st1 = SYMBOL_PRINT_NAME (*s1);
- st2 = SYMBOL_PRINT_NAME (*s2);
+ struct partial_symbol *const *s1 = s1p;
+ struct partial_symbol *const *s2 = s2p;
-
- if ((st1[0] - st2[0]) || !st1[0])
- {
- return (st1[0] - st2[0]);
- }
- else if ((st1[1] - st2[1]) || !st1[1])
- {
- return (st1[1] - st2[1]);
- }
- else
- {
- return (strcmp (st1, st2));
- }
+ return strcmp_iw_ordered (SYMBOL_PRINT_NAME (*s1),
+ SYMBOL_PRINT_NAME (*s2));
}
void
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 1a123fb..1b1e375 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1374,9 +1374,10 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
do_linear_search = 0;
/* Binary search. This search is guaranteed to end with center
- pointing at the earliest partial symbol with the correct
- name. At that point *all* partial symbols with that name
- will be checked against the correct namespace. */
+ pointing at the earliest partial symbol whose name might be
+ correct. At that point *all* partial symbols with an
+ appropriate name will be checked against the correct
+ namespace. */
bottom = start;
top = start + length - 1;
@@ -1391,7 +1392,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name, int global,
{
do_linear_search = 1;
}
- if (strcmp (SYMBOL_PRINT_NAME (*center), name) >= 0)
+ if (strcmp_iw_ordered (SYMBOL_PRINT_NAME (*center), name) >= 0)
{
top = center;
}
diff --git a/gdb/utils.c b/gdb/utils.c
index 0d9fb31..df196ec 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -2358,6 +2358,86 @@ strcmp_iw (const char *string1, const char *string2)
return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
}
+/* This is like strcmp except that it ignores whitespace and treats
+ '(' as the first non-NULL character in terms of ordering. Like
+ strcmp (and unlike strcmp_iw), it returns negative if STRING1 <
+ STRING2, 0 if STRING2 = STRING2, and positive if STRING1 > STRING2
+ according to that ordering.
+
+ If a list is sorted according to this function and if you want to
+ find names in the list that match some fixed NAME according to
+ strcmp_iw(LIST_ELT, NAME), then the place to start looking is right
+ where this function would put NAME.
+
+ Here are some examples of why using strcmp to sort is a bad idea:
+
+ Whitespace example:
+
+ Say your partial symtab contains: "foo<char *>", "goo". Then, if
+ we try to do a search for "foo<char*>", strcmp will locate this
+ after "foo<char *>" and before "goo". Then lookup_partial_symbol
+ will start looking at strings beginning with "goo", and will never
+ see the correct match of "foo<char *>".
+
+ Parenthesis example:
+
+ In practice, this is less like to be an issue, but I'll give it a
+ shot. Let's assume that '$' is a legitimate character to occur in
+ symbols. (Which may well even be the case on some systems.) Then
+ say that the partial symbol table contains "foo$" and "foo(int)".
+ strcmp will put them in this order, since '$' < '('. Now, if the
+ user searches for "foo", then strcmp will sort "foo" before "foo$".
+ Then lookup_partial_symbol will notice that strcmp_iw("foo$",
+ "foo") is false, so it won't proceed to the actual match of
+ "foo(int)" with "foo". */
+
+int
+strcmp_iw_ordered (const char *string1, const char *string2)
+{
+ while ((*string1 != '\0') && (*string2 != '\0'))
+ {
+ while (isspace (*string1))
+ {
+ string1++;
+ }
+ while (isspace (*string2))
+ {
+ string2++;
+ }
+ if (*string1 != *string2)
+ {
+ break;
+ }
+ if (*string1 != '\0')
+ {
+ string1++;
+ string2++;
+ }
+ }
+
+ switch (*string1)
+ {
+ /* Characters are non-equal unless they're both '\0'; we want to
+ make sure we get the comparison right according to our
+ comparison in the cases where one of them is '\0' or '('. */
+ case '\0':
+ if (*string2 == '\0')
+ return 0;
+ else
+ return -1;
+ case '(':
+ if (*string2 == '\0')
+ return 1;
+ else
+ return -1;
+ default:
+ if (*string2 == '(')
+ return 1;
+ else
+ return *string1 - *string2;
+ }
+}
+
/* A simple comparison function with opposite semantics to strcmp. */
int