mirror of
git://sourceware.org/git/libabigail.git
synced 2025-02-24 01:46:50 +00:00
Make decl_names_equal more accurate
This utility function compares qualified names component-wise with special handling of components that are anonymous names. The code is incorrect for some cases when there are different numbers of components on each side. Also, the control flow in the loop body is more complex than it needs to be. This commit simplifies the control flow, fixes the comparison bugs and adds some extra tests to cover these cases. * src/abg-tools-utils.cc (decl_names_equal): Move {l,r}_pos2 declarations into the loop and make {l,r}_length const. Avoid chance of arithmetic on string::npos values. Rework logic so there is a single test for "names compare equal" and a single test for different numbers of name components. * tests/test-tools-utils.cc (main): Add nine more tests. Signed-off-by: Giuliano Procida <gprocida@google.com>
This commit is contained in:
parent
817a2755bc
commit
2862147c0a
@ -510,61 +510,45 @@ get_anonymous_enum_internal_name_prefix()
|
||||
bool
|
||||
decl_names_equal(const string& l, const string& r)
|
||||
{
|
||||
string::size_type l_pos1 = 0, l_pos2 = 0, r_pos1 = 0, r_pos2 = 0;
|
||||
string::size_type l_length = l.length(), r_length = r.length();
|
||||
string::size_type l_pos1 = 0, r_pos1 = 0;
|
||||
const string::size_type l_length = l.length(), r_length = r.length();
|
||||
|
||||
while (l_pos1 < l_length && r_pos1 < r_length)
|
||||
{
|
||||
l_pos2 = l.find("::", l_pos1);
|
||||
r_pos2 = r.find("::", r_pos1);
|
||||
|
||||
if ((l.compare(l_pos1,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME) == 0
|
||||
&& r.compare(r_pos1,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME) == 0)
|
||||
||
|
||||
(l.compare(l_pos1,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME) == 0
|
||||
&& r.compare(r_pos1,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME) == 0)
|
||||
||
|
||||
(l.compare(l_pos1,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME) == 0
|
||||
&& r.compare(r_pos1,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME) == 0))
|
||||
{
|
||||
if (l_pos2 == l.npos || r_pos2 == r.npos)
|
||||
return true;
|
||||
|
||||
l_pos1 = l_pos2 + 2;
|
||||
r_pos1 = r_pos2 + 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (l_pos2 == l.npos || r_pos2 == r.npos)
|
||||
{
|
||||
if (l_pos2 != r_pos2)
|
||||
return false;
|
||||
|
||||
return !l.compare(l_pos1, l_pos2, r,
|
||||
r_pos1, r_pos2);
|
||||
}
|
||||
string::size_type l_pos2 = l.find("::", l_pos1);
|
||||
string::size_type r_pos2 = r.find("::", r_pos1);
|
||||
if (l_pos2 == string::npos)
|
||||
l_pos2 = l_length;
|
||||
if (r_pos2 == string::npos)
|
||||
r_pos2 = r_length;
|
||||
|
||||
if (l.compare(l_pos1, l_pos2 - l_pos1, r,
|
||||
r_pos1, r_pos2 - r_pos1))
|
||||
r_pos1, r_pos2 - r_pos1)
|
||||
&& (l.compare(l_pos1,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME)
|
||||
|| r.compare(r_pos1,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_STRUCT_INTERNAL_NAME))
|
||||
&& (l.compare(l_pos1,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME)
|
||||
|| r.compare(r_pos1,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_UNION_INTERNAL_NAME))
|
||||
&& (l.compare(l_pos1,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME)
|
||||
|| r.compare(r_pos1,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME_LEN,
|
||||
ANONYMOUS_ENUM_INTERNAL_NAME)))
|
||||
return false;
|
||||
|
||||
l_pos1 = l_pos2 + 2;
|
||||
r_pos1 = r_pos2 + 2;
|
||||
l_pos1 = l_pos2 == l_length ? l_pos2 : l_pos2 + 2;
|
||||
r_pos1 = r_pos2 == r_length ? r_pos2 : r_pos2 + 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
return (l_pos1 == l_length) == (r_pos1 == r_length);
|
||||
}
|
||||
|
||||
/// If a given file is a symbolic link, get the canonicalized absolute
|
||||
|
@ -86,5 +86,15 @@ main(int, char**)
|
||||
|
||||
ABG_ASSERT(decl_names_equal("S0::m2", "S0::m12") == false);
|
||||
|
||||
ABG_ASSERT(!decl_names_equal("S0::S1", "S0"));
|
||||
ABG_ASSERT(!decl_names_equal("S0", "S0::S1"));
|
||||
ABG_ASSERT(!decl_names_equal("S1::S0", "S0::S1"));
|
||||
ABG_ASSERT(!decl_names_equal("__anonymous_struct__::S0", "__anonymous_struct__"));
|
||||
ABG_ASSERT(!decl_names_equal("__anonymous_struct__", "__anonymous_struct__::S1"));
|
||||
ABG_ASSERT(!decl_names_equal("__anonymous_struct__::S0", "__anonymous_struct__::S1"));
|
||||
ABG_ASSERT(!decl_names_equal("S0::__anonymous_struct__", "__anonymous_struct__"));
|
||||
ABG_ASSERT(!decl_names_equal("__anonymous_struct__", "S1::__anonymous_struct__"));
|
||||
ABG_ASSERT(!decl_names_equal("S0::__anonymous_struct__", "S1::__anonymous_struct__"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user