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.
This commit is contained in:
David Carlton 2003-02-24 23:37:02 +00:00
parent c8d6825d9a
commit 0fe19209f9
5 changed files with 101 additions and 45 deletions

View File

@ -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

View File

@ -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 *);

View File

@ -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;
struct partial_symbol *const *s1 = s1p;
struct partial_symbol *const *s2 = s2p;
s1 = (struct partial_symbol **) s1p;
s2 = (struct partial_symbol **) s2p;
st1 = SYMBOL_PRINT_NAME (*s1);
st2 = SYMBOL_PRINT_NAME (*s2);
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

View File

@ -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;
}

View File

@ -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