using zypp::CpeId;
typedef CpeId::Value Value;
+///////////////////////////////////////////////////////////////////
+/// Symmetric attribute compare if wildcards are involved!
+/// The specs define any comarison with a wildcarded attribute as
+/// target to return \c uncomparable:
+/// \code
+/// wildcardfree <=> wildcarded ==> uncomparable,
+/// wildcarded <=> wildcardfree ==> superset or disjoint
+/// \endcode
+/// But a symmetric result is much more intuitive:
+/// \code
+/// wildcardfree <=> wildcarded ==> subset or disjoint
+/// wildcarded <=> wildcardfree ==> superset or disjoint
+/// \endcode
+///////////////////////////////////////////////////////////////////
+#define WFN_STRICT_SPEC 0
+
#define defVALUE(N,S) \
const std::string N##Str( S ); \
Value N( N##Str );
BOOST_CHECK( c != Value::ANY );
BOOST_CHECK( c != Value::NA );
BOOST_CHECK( c != wildcardfree );
+#if WFN_STRICT_SPEC
BOOST_CHECK( c != wildcarded ); // !!! According to the CPE Name Matching Specification Version 2.3
// unquoted wildcard characters yield an undefined result (not ==).
+#else
+ BOOST_CHECK( c == wildcarded );
+#endif
BOOST_CHECK( ! c.isWildcardfree() );
BOOST_CHECK( c.isWildcarded() );
BOOST_CHECK_EQUAL( c.asFs(), wildcardedFs );
BOOST_CHECK_EQUAL( c.asString(), c.asWfn() );
}
+#if WFN_STRICT_SPEC
BOOST_CHECK( wildcarded2 != wildcarded2 ); // unquoted wildcard characters yield an undefined result (not ==).
+#else
+ BOOST_CHECK( wildcarded2 == wildcarded2 );
+#endif
BOOST_CHECK( wildcarded2 != wildcardfree );
BOOST_CHECK( wildcarded2 != wildcarded );
BOOST_CHECK( ! wildcarded2.isWildcardfree() );
BOOST_CHECK( compare( Value::ANY, Value::ANY, SetCompare::equal ) );
BOOST_CHECK( compare( Value::ANY, Value::NA, SetCompare::properSuperset ) );
BOOST_CHECK( compare( Value::ANY, wildcardfree, SetCompare::properSuperset ) );
+#if WFN_STRICT_SPEC
BOOST_CHECK( compare( Value::ANY, wildcarded, SetCompare::uncomparable ) );
+#else
+ BOOST_CHECK( compare( Value::ANY, wildcarded, SetCompare::properSuperset ) );
+#endif
BOOST_CHECK( compare( Value::NA, Value::ANY, SetCompare::properSubset ) );
BOOST_CHECK( compare( Value::NA, Value::NA, SetCompare::equal ) );
BOOST_CHECK( compare( Value::NA, wildcardfree, SetCompare::disjoint ) );
+#if WFN_STRICT_SPEC
BOOST_CHECK( compare( Value::NA, wildcarded, SetCompare::uncomparable ) );
+#else
+ BOOST_CHECK( compare( Value::NA, wildcarded, SetCompare::disjoint ) );
+#endif
BOOST_CHECK( compare( wildcardfree, Value::ANY, SetCompare::properSubset ) );
BOOST_CHECK( compare( wildcardfree, Value::NA, SetCompare::disjoint ) );
//BOOST_CHECK( compare( wildcardfree, wildcardfree, _NeedsCloserLook, // equal or disjoint
BOOST_CHECK( compare( wildcardfree, wildcardfree, SetCompare::equal ) );
BOOST_CHECK( compare( wildcardfree, wildcardfree2, SetCompare::disjoint ) );
+#if WFN_STRICT_SPEC
BOOST_CHECK( compare( wildcardfree, wildcarded, SetCompare::uncomparable ) );
+#else
+ //BOOST_CHECK( compare( wildcardfree, wildcarded, _NeedsCloserLook, // subset or disjoint
+ BOOST_CHECK( compare( wildcardfree, wildcarded, SetCompare::properSubset ) );
+ BOOST_CHECK( compare( wildcardfree, wildcarded2, SetCompare::disjoint ) );
+#endif
BOOST_CHECK( compare( wildcarded, Value::ANY, SetCompare::properSubset ) );
BOOST_CHECK( compare( wildcarded, Value::NA, SetCompare::disjoint ) );
//BOOST_CHECK( compare( wildcarded, wildcardfree, _NeedsCloserLook, // superset or disjoint
BOOST_CHECK( compare( wildcarded, wildcardfree, SetCompare::properSuperset ) );
BOOST_CHECK( compare( wildcarded, wildcardfree2, SetCompare::disjoint ) );
+#if WFN_STRICT_SPEC
BOOST_CHECK( compare( wildcarded, wildcarded, SetCompare::uncomparable ) );
+#else
+ //BOOST_CHECK( compare( wildcarded, wildcarded, _NeedsCloserLook, // equal or uncomparable
+ BOOST_CHECK( compare( wildcarded, wildcarded, SetCompare::equal ) );
+ BOOST_CHECK( compare( wildcarded, wildcarded2, SetCompare::uncomparable ) );
+#endif
}
CpeId win( "cpe:/o:windows" );
CpeId any;
CpeId ons( "cpe:2.3:o:??????s" );
+ CpeId oops( "cpe:2.3:o:?????s" );
BOOST_CHECK_EQUAL( compare( sle, win ), SetRelation::disjoint );
BOOST_CHECK_EQUAL( compare( any, sle ), SetRelation::superset );
BOOST_CHECK_EQUAL( compare( any, win ), SetRelation::superset );
+#if WFN_STRICT_SPEC
BOOST_CHECK_EQUAL( compare( sle, ons ), SetRelation::uncomparable );
BOOST_CHECK_EQUAL( compare( win, ons ), SetRelation::uncomparable );
+#else
+ BOOST_CHECK_EQUAL( compare( sle, ons ), SetRelation::subset );
+ BOOST_CHECK_EQUAL( compare( win, ons ), SetRelation::subset );
+#endif
BOOST_CHECK_EQUAL( compare( ons, sle ), SetRelation::superset );
BOOST_CHECK_EQUAL( compare( ons, win ), SetRelation::superset );
+
+ BOOST_CHECK_EQUAL( compare( oops, sle ), SetRelation::superset );
+ BOOST_CHECK_EQUAL( compare( oops, win ), SetRelation::disjoint );
+
}
|| ( isWildchar( *value.rbegin() ) && evenNumberOfBackslashes( ++value.rbegin(), value.rend() ) ) );
}
- SetCompare CpeId::Value::setRelationMixinCompare( const CpeId::Value & trg ) const
+ ///////////////////////////////////////////////////////////////////
+ /// Symmetric attribute compare if wildcards are involved!
+ /// The specs define any comarison with a wildcarded attribute as
+ /// target to return \c uncomparable:
+ /// \code
+ /// wildcardfree <=> wildcarded ==> uncomparable,
+ /// wildcarded <=> wildcardfree ==> superset or disjoint
+ /// \endcode
+ /// But a symmetric result is much more intuitive:
+ /// \code
+ /// wildcardfree <=> wildcarded ==> subset or disjoint
+ /// wildcarded <=> wildcardfree ==> superset or disjoint
+ /// \endcode
+ ///////////////////////////////////////////////////////////////////
+#define WFN_STRICT_SPEC 0
+#if WFN_STRICT_SPEC
+ //SetCompare CpeId::Value::setRelationMixinCompare( const CpeId::Value & trg ) const
{
static const SetCompare _NeedsCloserLook( SetCompare::Enum(-1) ); // artificial Compare value
static const SetCompare matchTabel[4][4] = {{
}
return ret;
}
+#else
+ SetCompare CpeId::Value::setRelationMixinCompare( const CpeId::Value & trg ) const
+ {
+ ///////////////////////////////////////////////////////////////////
+ // ANY, ANY => equal
+ // ANY, NA => properSuperset
+ // ANY, wildcardfree => properSuperset
+ // ANY, wildcarded => properSuperset
+ //
+ // NA, ANY => properSubset
+ // NA, NA => equal
+ // NA, wildcardfree => disjoint
+ // NA, wildcarded => disjoint
+ //
+ // wildcardfree, ANY => properSubset
+ // wildcardfree, NA => disjoint
+ // wildcardfree, wildcardfree => NeedsCloserLook: equal or disjoint
+ // wildcardfree, wildcarded => NeedsCloserLook: subset or disjoint
+ //
+ // wildcarded, ANY => properSubset
+ // wildcarded, NA => disjoint
+ // wildcarded, wildcardfree => NeedsCloserLook: superset or disjoint
+ // wildcarded, wildcarded => NeedsCloserLook" equal or uncomparable
+ ///////////////////////////////////////////////////////////////////
+
+ SetCompare ret = SetCompare::disjoint;
+
+ if ( isANY() )
+ {
+ ret = trg.isANY() ? SetCompare::equal : SetCompare::properSuperset;
+ }
+ else if ( trg.isANY() )
+ {
+ ret = SetCompare::properSubset;
+ }
+ else if ( isNA() )
+ {
+ if ( trg.isNA() ) ret = SetCompare::equal; // else: SetCompare::disjoint;
+ }
+ else if ( ! trg.isNA() ) // else: SetCompare::disjoint;
+ {
+ // NeedsCloserLook:
+ if ( isWildcarded() )
+ {
+ if ( trg.isWildcarded() )
+ {
+ // simple string compare just to detect 'equal'
+ ret = matchWildcardfreeString( *_value, *trg._value ) ? SetCompare::equal : SetCompare::uncomparable;
+ }
+ else
+ {
+ // Needs wildcard compare (src,trg)
+ if ( matchWildcardedString( *_value, *trg._value ) ) ret = SetCompare::properSuperset; // else: SetCompare::disjoint;
+ }
+ }
+ else
+ {
+ if ( trg.isWildcarded() )
+ {
+ // Needs wildcard compare (trg,src)
+ if ( matchWildcardedString( *trg._value, *_value ) ) ret = SetCompare::properSubset; // else: SetCompare::disjoint;
+ }
+ else
+ {
+ // simple string compare
+ if ( matchWildcardfreeString( *_value, *trg._value ) ) ret = SetCompare::equal; // else: SetCompare::disjoint;
+ }
+ }
+ }
+ return ret;
+ }
+#endif // WFN_STRICT_SPEC
std::ostream & operator<<( std::ostream & str, const CpeId::Value & obj )
{ return str << obj.asString(); }