mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-15 14:34:38 +00:00
Support the "name_not_regexp" property in the [suppress_type] section
When writting a suppression specification in which the user wants to keep a family of types (whose names set is specified by a regular expression) and suppress/drop all other types, one needs to write something like: [suppress_type] name_regexp = (?!the-regexp-of-the-types-to-keep) It would be nicer (like what is done for other properties that take regular expressions as value in suppression specifications) to be able to write: [suppress_type] name_not_regexp = the-regexp-of-types-to-keep This patch does just that. It augments the abigail::suppr::type_suppression type to make it carry the new 'name_not_regex' property. It updates the suppression engine to take the 'name_not_regex' property into account when interpreting instances of abigail::suppr::type_suppression. The parser for type suppression directives is updated to recognize the new name_not_regexp property. The manual has been updated accordingly to describe the new property. New regression tests have been added. * doc/manuals/libabigail-concepts.rst: Update this to document the new name_not_regexp property of the suppress_type directive. * include/abg-suppression.h (type_suppression::{g,s}et_type_name_not_regex_str): Declare new accessors. * src/abg-suppression-priv.h (type_suppression::priv::{type_name_not_regex_str_, type_name_not_regex_}): Define new data members. (type_suppression::priv::{get_type_name_not_regex, set_type_name_not_regex, get_type_name_not_regex_str, set_type_name_not_regex_str}): Define new member functions. * src/abg-suppression.cc (type_suppression::get_type_name_regex_str): Fix comments. (type_suppression::{set_type_name_not_regex_str, get_type_name_not_regex_str}): Define new data members. (suppression_matches_type_name): Adapt to support the new type_name_not_regex property. (read_type_suppression): Support parsing the type_name_not_regexp property. * tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt: New test reference output. * tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt: New test input. * tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-v0.{cc, o}: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-v1.{cc, o}: Likewise. * tests/data/Makefile.am: Add the test files above to source distribution. * tests/test-diff-suppr.cc (int_out_specs): Add the new tests to the harness. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
bdd927f663
commit
d2c88645e8
@ -247,8 +247,9 @@ Note that for the ``[suppress_type]`` directive to work, at least one
|
||||
of the following properties must be provided:
|
||||
|
||||
``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``,
|
||||
``soname_not_regexp``, ``name``, ``name_regexp``, ``type_kind``,
|
||||
``source_location_not_in``, ``source_location_not_regexp``.
|
||||
``soname_not_regexp``, ``name``, ``name_regexp``,
|
||||
``name_not_regexp``, ``type_kind``, ``source_location_not_in``,
|
||||
``source_location_not_regexp``.
|
||||
|
||||
If none of the following properties are provided, then the
|
||||
``[suppress_type]`` directive is simply ignored.
|
||||
@ -305,6 +306,18 @@ The potential properties of this sections are listed below:
|
||||
Suppresses change reports involving types whose name matches the
|
||||
regular expression specified as value of this property.
|
||||
|
||||
|
||||
* ``name_not_regexp``
|
||||
|
||||
Usage:
|
||||
|
||||
``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
|
||||
|
||||
Suppresses change reports involving types whose name does *NOT* match
|
||||
the regular expression specified as value of this property. Said
|
||||
otherwise, this property specifies which types to keep, rather than
|
||||
types to suppress from reports.
|
||||
|
||||
* ``name``
|
||||
|
||||
Usage:
|
||||
|
@ -200,6 +200,12 @@ public:
|
||||
const string&
|
||||
get_type_name_regex_str() const;
|
||||
|
||||
void
|
||||
set_type_name_not_regex_str(const string& name_regex_str);
|
||||
|
||||
const string&
|
||||
get_type_name_not_regex_str() const;
|
||||
|
||||
void
|
||||
set_type_name(const string& name);
|
||||
|
||||
|
@ -675,6 +675,8 @@ class type_suppression::priv
|
||||
string type_name_regex_str_;
|
||||
mutable sptr_utils::regex_t_sptr type_name_regex_;
|
||||
string type_name_;
|
||||
string type_name_not_regex_str_;
|
||||
mutable sptr_utils::regex_t_sptr type_name_not_regex_;
|
||||
bool consider_type_kind_;
|
||||
type_suppression::type_kind type_kind_;
|
||||
bool consider_reach_kind_;
|
||||
@ -734,6 +736,56 @@ public:
|
||||
set_type_name_regex(sptr_utils::regex_t_sptr r)
|
||||
{type_name_regex_ = r;}
|
||||
|
||||
/// Get the regular expression object associated to the
|
||||
/// 'type_name_not_regex' property of @ref type_suppression.
|
||||
///
|
||||
/// If the regular expression object is not created, this method
|
||||
/// creates it and returns it.
|
||||
///
|
||||
/// If the 'type_name_not_regex' property of @ref type_suppression is
|
||||
/// empty then this method returns nil.
|
||||
const sptr_utils::regex_t_sptr
|
||||
get_type_name_not_regex() const
|
||||
{
|
||||
if (!type_name_not_regex_)
|
||||
{
|
||||
if (!type_name_not_regex_str_.empty())
|
||||
{
|
||||
sptr_utils::regex_t_sptr r = sptr_utils::build_sptr<regex_t>();
|
||||
if (regcomp(r.get(),
|
||||
type_name_not_regex_str_.c_str(),
|
||||
REG_EXTENDED) == 0)
|
||||
type_name_not_regex_ = r;
|
||||
}
|
||||
}
|
||||
return type_name_not_regex_;
|
||||
}
|
||||
|
||||
/// Setter for the type_name_not_regex object.
|
||||
///
|
||||
/// @param r the new type_name_not_regex object.
|
||||
void
|
||||
set_type_name_not_regex(sptr_utils::regex_t_sptr r)
|
||||
{type_name_not_regex_ = r;}
|
||||
|
||||
/// Getter for the string that denotes the 'type_name_not_regex'
|
||||
/// property.
|
||||
///
|
||||
/// @return the value of the string value of the
|
||||
/// 'type_name_not_regex' property.
|
||||
const string&
|
||||
get_type_name_not_regex_str() const
|
||||
{return type_name_not_regex_str_;}
|
||||
|
||||
/// Setter for the string that denotes the 'type_name_not_regex'
|
||||
/// property.
|
||||
///
|
||||
/// @return the value of the string value of the
|
||||
/// 'type_name_not_regex' property.
|
||||
void
|
||||
set_type_name_not_regex_str(const string regex_str)
|
||||
{type_name_not_regex_str_ = regex_str;}
|
||||
|
||||
/// Getter for the source_location_to_keep_regex object.
|
||||
///
|
||||
/// This function builds the regex if it's not yet built.
|
||||
|
@ -406,14 +406,36 @@ type_suppression::set_type_name_regex_str(const string& name_regex_str)
|
||||
/// Getter for the "type_name_regex" property of the type suppression
|
||||
/// specification.
|
||||
///
|
||||
/// This returns a regular expression that specifies the family of
|
||||
/// types about which diff reports should be suppressed.
|
||||
/// This returns a regular expression string that specifies the family
|
||||
/// of types about which diff reports should be suppressed.
|
||||
///
|
||||
/// @return the regular expression.
|
||||
/// @return the regular expression string.
|
||||
const string&
|
||||
type_suppression::get_type_name_regex_str() const
|
||||
{return priv_->type_name_regex_str_;}
|
||||
|
||||
/// Setter for the "type_name_not_regex_str" property of the type
|
||||
/// suppression specification.
|
||||
///
|
||||
/// This returns a regular expression string that specifies the family
|
||||
/// of types that should be kept after suppression.
|
||||
///
|
||||
/// @param r the new regexp string.
|
||||
void
|
||||
type_suppression::set_type_name_not_regex_str(const string& r)
|
||||
{priv_->set_type_name_not_regex_str(r);}
|
||||
|
||||
/// Getter for the "type_name_not_regex_str" property of the type
|
||||
/// suppression specification.
|
||||
///
|
||||
/// This returns a regular expression string that specifies the family
|
||||
/// of types that should be kept after suppression.
|
||||
///
|
||||
/// @return the new regexp string.
|
||||
const string&
|
||||
type_suppression::get_type_name_not_regex_str() const
|
||||
{return priv_->get_type_name_not_regex_str();}
|
||||
|
||||
/// Setter for the name of the type about which diff reports should be
|
||||
/// suppressed.
|
||||
///
|
||||
@ -921,7 +943,9 @@ bool
|
||||
suppression_matches_type_name(const type_suppression& s,
|
||||
const string& type_name)
|
||||
{
|
||||
if (!s.get_type_name().empty() || s.priv_->get_type_name_regex())
|
||||
if (!s.get_type_name().empty()
|
||||
|| s.priv_->get_type_name_regex()
|
||||
|| s.priv_->get_type_name_not_regex())
|
||||
{
|
||||
// Check if there is an exact type name match.
|
||||
if (!s.get_type_name().empty())
|
||||
@ -936,12 +960,23 @@ suppression_matches_type_name(const type_suppression& s,
|
||||
// If the qualified name of the considered type doesn't match
|
||||
// the regular expression of the type name, then this
|
||||
// suppression doesn't apply.
|
||||
const sptr_utils::regex_t_sptr& type_name_regex =
|
||||
s.priv_->get_type_name_regex();
|
||||
if (type_name_regex && (regexec(type_name_regex.get(),
|
||||
type_name.c_str(),
|
||||
0, NULL, 0) != 0))
|
||||
return false;
|
||||
if (const sptr_utils::regex_t_sptr& type_name_regex =
|
||||
s.priv_->get_type_name_regex())
|
||||
{
|
||||
if (regexec(type_name_regex.get(),
|
||||
type_name.c_str(),
|
||||
0, NULL, 0) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const sptr_utils::regex_t_sptr type_name_not_regex =
|
||||
s.priv_->get_type_name_not_regex())
|
||||
{
|
||||
if (regexec(type_name_not_regex.get(),
|
||||
type_name.c_str(),
|
||||
0, NULL, 0) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1530,6 +1565,12 @@ read_type_suppression(const ini::config::section& section)
|
||||
? name_regex_prop->get_value()->as_string()
|
||||
: "";
|
||||
|
||||
ini::simple_property_sptr name_not_regex_prop =
|
||||
is_simple_property(section.find_property("name_not_regexp"));
|
||||
string name_not_regex_str = name_not_regex_prop
|
||||
? name_not_regex_prop->get_value()->as_string()
|
||||
: "";
|
||||
|
||||
ini::simple_property_sptr name_prop =
|
||||
is_simple_property(section.find_property("name"));
|
||||
string name_str = name_prop
|
||||
@ -1774,6 +1815,8 @@ read_type_suppression(const ini::config::section& section)
|
||||
&& soname_regex_str.empty()
|
||||
&& soname_not_regex_str.empty()
|
||||
&& (!name_regex_prop || name_regex_prop->get_value()->as_string().empty())
|
||||
&& (!name_not_regex_prop
|
||||
|| name_not_regex_prop->get_value()->as_string().empty())
|
||||
&& (!name_prop || name_prop->get_value()->as_string().empty())
|
||||
&& !consider_type_kind
|
||||
&& srcloc_not_regexp_str.empty()
|
||||
@ -1798,6 +1841,9 @@ read_type_suppression(const ini::config::section& section)
|
||||
if (consider_data_member_insertion)
|
||||
suppr->set_data_member_insertion_ranges(insert_ranges);
|
||||
|
||||
if (!name_not_regex_str.empty())
|
||||
suppr->set_type_name_not_regex_str(name_not_regex_str);
|
||||
|
||||
if (!file_name_regex_str.empty())
|
||||
suppr->set_file_name_regex_str(file_name_regex_str);
|
||||
|
||||
|
@ -1205,6 +1205,14 @@ test-diff-suppr/test41-enumerator-changes-0.suppr \
|
||||
test-diff-suppr/test41-enumerator-changes-report-0.txt \
|
||||
test-diff-suppr/test41-enumerator-changes-v0.cc \
|
||||
test-diff-suppr/test41-enumerator-changes-v1.cc \
|
||||
test-diff-suppr/test42-negative-suppr-type-report-0.txt \
|
||||
test-diff-suppr/test42-negative-suppr-type-report-1.txt \
|
||||
test-diff-suppr/test42-negative-suppr-type-suppr-1.txt \
|
||||
test-diff-suppr/test42-negative-suppr-type-suppr-2.txt \
|
||||
test-diff-suppr/test42-negative-suppr-type-v0.cc \
|
||||
test-diff-suppr/test42-negative-suppr-type-v0.o \
|
||||
test-diff-suppr/test42-negative-suppr-type-v1.cc \
|
||||
test-diff-suppr/test42-negative-suppr-type-v1.o \
|
||||
test-diff-suppr/test43-suppr-direct-fn-subtype-suppr-1.txt \
|
||||
test-diff-suppr/test43-suppr-direct-fn-subtype-v0.cc \
|
||||
test-diff-suppr/test43-suppr-direct-fn-subtype-v0.o \
|
||||
|
@ -0,0 +1,12 @@
|
||||
Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions
|
||||
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
|
||||
|
||||
1 function with some indirect sub-type change:
|
||||
|
||||
[C]'function void func0(type_to_keep)' at test42-negative-suppr-type-v1.cc:15:1 has some indirect sub-type changes:
|
||||
parameter 1 of type 'struct type_to_keep' has sub-type changes:
|
||||
type size changed from 32 to 64 (in bits)
|
||||
1 data member insertion:
|
||||
'char type_to_keep::m1', at offset 32 (in bits) at test42-negative-suppr-type-v1.cc:4:1
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions
|
||||
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
|
||||
|
||||
1 function with some indirect sub-type change:
|
||||
|
||||
[C]'function void func0(type_to_keep)' at test42-negative-suppr-type-v1.cc:15:1 has some indirect sub-type changes:
|
||||
parameter 1 of type 'struct type_to_keep' has sub-type changes:
|
||||
type size changed from 32 to 64 (in bits)
|
||||
1 data member insertion:
|
||||
'char type_to_keep::m1', at offset 32 (in bits) at test42-negative-suppr-type-v1.cc:4:1
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
[suppress_type]
|
||||
name_not_regexp = type_to_keep
|
||||
|
@ -0,0 +1,2 @@
|
||||
[suppress_type]
|
||||
name_regexp = type_to_suppress
|
20
tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc
Normal file
20
tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc
Normal file
@ -0,0 +1,20 @@
|
||||
struct type_to_keep
|
||||
{
|
||||
int m0;
|
||||
};
|
||||
|
||||
struct type_to_suppress
|
||||
{
|
||||
int m0;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
func0(struct type_to_keep)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
func1(struct type_to_suppress)
|
||||
{
|
||||
}
|
BIN
tests/data/test-diff-suppr/test42-negative-suppr-type-v0.o
Normal file
BIN
tests/data/test-diff-suppr/test42-negative-suppr-type-v0.o
Normal file
Binary file not shown.
22
tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc
Normal file
22
tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc
Normal file
@ -0,0 +1,22 @@
|
||||
struct type_to_keep
|
||||
{
|
||||
int m0;
|
||||
char m1;
|
||||
};
|
||||
|
||||
struct type_to_suppress
|
||||
{
|
||||
int m0;
|
||||
char m1;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
func0(struct type_to_keep)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
func1(struct type_to_suppress)
|
||||
{
|
||||
}
|
BIN
tests/data/test-diff-suppr/test42-negative-suppr-type-v1.o
Normal file
BIN
tests/data/test-diff-suppr/test42-negative-suppr-type-v1.o
Normal file
Binary file not shown.
@ -1748,6 +1748,26 @@ InOutSpec in_out_specs[] =
|
||||
"data/test-diff-suppr/test41-enumerator-changes-report-0.txt",
|
||||
"output/test-diff-suppr/test41-enumerator-changes-report-0.txt"
|
||||
},
|
||||
{
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-v0.o",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-v1.o",
|
||||
"",
|
||||
"",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt",
|
||||
"--no-default-suppression",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-report-0.txt",
|
||||
"output/test-diff-suppr/test42-negative-suppr-type-report-0.txt"
|
||||
},
|
||||
{
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-v0.o",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-v1.o",
|
||||
"",
|
||||
"",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt",
|
||||
"--no-default-suppression",
|
||||
"data/test-diff-suppr/test42-negative-suppr-type-report-1.txt",
|
||||
"output/test-diff-suppr/test42-negative-suppr-type-report-1.txt"
|
||||
},
|
||||
{
|
||||
"data/test-diff-suppr/test43-suppr-direct-fn-subtype-v0.o",
|
||||
"data/test-diff-suppr/test43-suppr-direct-fn-subtype-v1.o",
|
||||
|
Loading…
Reference in New Issue
Block a user