1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Capability.h
12 #ifndef ZYPP_CAPABILITY_H
13 #define ZYPP_CAPABILITY_H
17 #include "zypp/APIConfig.h"
18 #include "zypp/sat/detail/PoolMember.h"
20 #include "zypp/IdString.h"
21 #include "zypp/Edition.h"
23 #include "zypp/ResTraits.h"
24 #include "zypp/ResolverNamespace.h"
25 #include "zypp/CapMatch.h"
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
35 typedef std::unordered_set<Capability> CapabilitySet;
37 ///////////////////////////////////////////////////////////////////
39 // CLASS NAME : Capability
43 * A Capability: <tt>"name[.arch] [op edition]"</tt>
45 * If a certain \ref ResKind is specified upon construction, the
46 * capabilities name part is prefixed, unless it already conatins a
47 * well known kind spec. If no \ref ResKind is specified, it's assumed
48 * you refer to a package or the name is already prefixed:
50 * Capability( "foo" ) ==> 'foo'
51 * Capability( "foo", ResKind::package ) ==> 'foo'
52 * Capability( "foo", ResKind::pattern ) ==> 'pattern:foo'
53 * Capability( "pattern:foo" ) ==> 'pattern:foo'
54 * // in doubt an explicit name prefix wins:
55 * Capability( "pattern:foo", ResKind::package ) ==> 'pattern:foo'
56 * Capability( "package:foo", ResKind::pattern ) ==> 'foo'
59 class Capability: protected sat::detail::PoolMember
62 enum CtorFlag { PARSED, UNPARSED };
65 /** Default ctor, \ref Empty capability. */
66 Capability() : _id( sat::detail::emptyId ) {}
69 explicit Capability( sat::detail::IdType id_r ) : _id( id_r ) {}
71 /** \name Ctors parsing a Capability: <tt>"name[.arch] [op edition]"</tt> or <tt>( arch, "name [op edition]")</tt>
75 * \a str_r is parsed to check whether it contains an <tt>[op edition]</tt> part,
76 * unless the \ref PARSED flag is passed to the ctor. In that case <tt>"name[.arch]"</tt>
79 explicit Capability( const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
81 explicit Capability( const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
82 /** \overload Explicitly specify the \c arch. */
83 Capability( const Arch & arch_r, const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
84 /** \overload Explicitly specify the \c arch. */
85 Capability( const Arch & arch_r, const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
87 /** \overload Convenience for parsed (name only, no <tt>"[op edition]</tt>) packages: <tt>Capability( "glibc", PARSED ); */
88 Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
90 Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
91 /** \overload Explicitly specify the \c arch. */
92 Capability( const Arch & arch_r, const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
94 Capability( const Arch & arch_r, const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
98 /** \name Ctors parsing a broken down Capability: <tt>( "name[.arch]", op, edition )</tt>
101 /** Ctor from <tt>name[.arch] op edition</tt>. */
102 Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
104 Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
106 Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
109 /** \name Ctors taking a broken down Capability: <tt>( arch, name, op, edition )</tt>
112 /** Ctor from <tt>arch name op edition</tt>. */
113 Capability( const std::string & arch_r, const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
115 Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
117 Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
119 Capability( const Arch & arch_r, const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
121 Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
123 Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
126 /** \name Ctor creating a namespace: capability.
127 * An empty \a value_r (std::string or IdString) will also be mapped to IdString::Null,
128 * creating a namespace: capability which in most contexts matches all members of this namespace.
131 Capability( ResolverNamespace namespace_r, IdString value_r = IdString::Null );
132 Capability( ResolverNamespace namespace_r, const char * value_r ) : Capability( namespace_r, IdString(value_r) ) {}
133 Capability( ResolverNamespace namespace_r, const std::string & value_r ) : Capability( namespace_r, IdString(value_r) ) {}
136 /** No or Null \ref Capability ( Id \c 0 ). */
137 static const Capability Null;
139 /** Empty Capability. */
140 static const Capability Empty;
143 /** Evaluate in a boolean context <tt>( ! empty() )</tt>. */
144 explicit operator bool() const
145 { return ! empty(); }
147 /** Whether the \ref Capability is empty.
148 * This is true for \ref Null and \ref Empty.
151 { return( _id == sat::detail::emptyId || _id == sat::detail::noId ); }
154 /** Conversion to <tt>const char *</tt> */
155 const char * c_str() const;
158 std::string asString() const
162 /** Helper providing more detailed information about a \ref Capability. */
163 CapDetail detail() const;
166 /** \name Match two simple capabilities.
168 * Two simple capabilities match if they have the same \c name
169 * and their \c edition ranges overlap. Where no edition matches
170 * ANY edition. \see \ref Edition::match.
172 * If a capability expression is involved, \ref matches returns
173 * \ref CapMatch::irrelevant.
176 static CapMatch matches( const Capability & lhs, const Capability & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
177 static CapMatch matches( const Capability & lhs, const IdString & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
178 static CapMatch matches( const Capability & lhs, const std::string & rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
179 static CapMatch matches( const Capability & lhs, const char * rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() );}
181 static CapMatch matches( const IdString & lhs, const Capability & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
182 static CapMatch matches( const IdString & lhs, const IdString & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
183 static CapMatch matches( const IdString & lhs, const std::string & rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
184 static CapMatch matches( const IdString & lhs, const char * rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
186 static CapMatch matches( const std::string & lhs, const Capability & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() );}
187 static CapMatch matches( const std::string & lhs, const IdString & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() ); }
188 static CapMatch matches( const std::string & lhs, const std::string & rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
189 static CapMatch matches( const std::string & lhs, const char * rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
191 static CapMatch matches( const char * lhs, const Capability & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() );}
192 static CapMatch matches( const char * lhs, const IdString & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() ); }
193 static CapMatch matches( const char * lhs, const std::string & rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
194 static CapMatch matches( const char * lhs, const char * rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
196 CapMatch matches( const Capability & rhs ) const { return _doMatch( id(), rhs.id() ); }
197 CapMatch matches( const IdString & rhs ) const { return _doMatch( id(), rhs.id() ); }
198 CapMatch matches( const std::string & rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
199 CapMatch matches( const char * rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
202 /** \ref matches functor.
204 struct Matches: public std::binary_function<Capability,Capability,CapMatch>
206 CapMatch operator()( const Capability & lhs, const Capability & rhs ) const
207 { return Capability::matches( lhs, rhs ); }
211 /** Test for a filename that is likely being REQUIRED.
212 * Files below \c /bin , \c /sbin , \c /lib etc. Scanning a
213 * packages filelist, an \e interesting filename might be worth
214 * being remembered in PROVIDES.
216 static bool isInterestingFileSpec( const IdString & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
217 static bool isInterestingFileSpec( const std::string & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
218 static bool isInterestingFileSpec( const char * name_r );
220 /** \ref Capability parser also guessing \c "libzypp-1.2.3-4.5.x86_64" formats.
222 * The argument might be in the form \c "libzypp-devel-1.2.3.x86_64".
223 * Passed to the Capability ctor, this would correctly be parsed as name
224 * capability, because actually the edition part had to be separated by a
225 * \c '=', and the architecture had to be appended to the name.
226 * So this is how it actually had to look like: \c "libzypp-devel.x86_64=1.2.3"
228 * Obviously we have to guess if, and where to split name and edition. In
229 * fact \c "devel" could also be the version and \c "1.2.3" would be the
232 * Assuming this Capability should be provided by some package in
233 * the \ref ResPool, we check this. If unprovided, we substitute the last,
234 * (or one but last) \c '-' by a \c '='. If the name part (without version)
235 * of the resulting Capability matches a package name (not provides!) in
236 * the \ref ResPool, this Capability is returned.
238 * Otherwise we return the Capability originally created from
241 * \note: As this method will access the global pool, the returned
242 * result depends on the pools content.
244 static Capability guessPackageSpec( const std::string & str_r );
245 /** \overload Taking an additional bool indicating whether \c str_r made
246 * a valid \ref Capability (\c true) or the result was was guessed by
247 * rewiting a \c '-' to \c '='. (\c false).
249 static Capability guessPackageSpec( const std::string & str_r, bool & rewrote_r );
252 /** Expert backdoor. */
253 sat::detail::IdType id() const
256 /** Match two Capabilities */
257 static CapMatch _doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs );
259 sat::detail::IdType _id;
261 ///////////////////////////////////////////////////////////////////
263 /** \relates Capability Stream output */
264 std::ostream & operator<<( std::ostream & str, const Capability & obj );
266 /** \relates Capability Detailed stream output */
267 std::ostream & dumpOn( std::ostream & str, const Capability & obj );
269 /** \relates Capability */
270 inline bool operator==( const Capability & lhs, const Capability & rhs )
271 { return lhs.id() == rhs.id(); }
273 /** \relates Capability */
274 inline bool operator!=( const Capability & lhs, const Capability & rhs )
275 { return lhs.id() != rhs.id(); }
277 /** \relates Capability Arbitrary order. */
278 inline bool operator<( const Capability & lhs, const Capability & rhs )
279 { return lhs.id() < rhs.id(); }
281 ///////////////////////////////////////////////////////////////////
283 // CLASS NAME : CapDetail
285 /** Helper providing more detailed information about a \ref Capability.
287 * Capabilities are classified to be either \c SIMPLE:
289 * name[.arch] [op edition]
290 * with op := <|<=|=|>=|>|!=
292 * or formed by some \c EXPRESSION:
294 * left_cap op right_cap
295 * with op := AND|OR|WITH|NAMESPACE
298 class CapDetail: protected sat::detail::PoolMember
309 /** Enum values corresponding with libsolv defines.
310 * \note MPL check in PoolImpl.cc
324 : _kind( NOCAP ), _lhs( 0 ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
326 explicit CapDetail( const Capability & cap_r )
327 : _kind( NOCAP ), _lhs( cap_r.id() ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
329 explicit CapDetail( sat::detail::IdType id_r )
330 : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
334 Kind kind() const { return _kind; }
335 bool isNull() const { return _kind == NOCAP; }
336 bool isNamed() const { return _kind == NAMED; }
337 bool isVersioned() const { return _kind == VERSIONED; }
338 bool isSimple() const { return _kind & (NAMED|VERSIONED); }
339 bool isExpression() const { return _kind == EXPRESSION; }
341 /** \name Is simple: <tt>name[.arch] [op edition]</tt> */
343 bool hasArch() const { return _archIfSimple; }
344 IdString arch() const { return _archIfSimple ? IdString( _archIfSimple ) : IdString(); }
345 IdString name() const { return isSimple() ? IdString( _lhs ) : IdString(); }
346 Rel op() const { return isVersioned() ? Rel( _flag ) : Rel::ANY; }
347 Edition ed() const { return isVersioned() ? Edition( _rhs ) : Edition(); }
350 /** \name Is expression <tt>cap op cap</tt> */
352 Capability lhs() const { return isExpression() ? Capability( _lhs ) : Capability::Null; }
353 CapRel capRel() const { return isExpression() ? CapRel(_flag) : REL_NONE; }
354 Capability rhs() const { return isExpression() ? Capability( _rhs ) : Capability::Null; }
361 sat::detail::IdType _lhs;
362 sat::detail::IdType _rhs;
364 sat::detail::IdType _archIfSimple;
366 ///////////////////////////////////////////////////////////////////
368 /** \relates CapDetail Stream output */
369 std::ostream & operator<<( std::ostream & str, const CapDetail & obj );
371 /** \relates CapDetail Stream output */
372 std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj );
374 /** \relates CapDetail Stream output */
375 std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj );
377 ///////////////////////////////////////////////////////////////////
379 inline CapDetail Capability::detail() const { return CapDetail( _id ); }
381 /////////////////////////////////////////////////////////////////
383 ///////////////////////////////////////////////////////////////////
385 ZYPP_DEFINE_ID_HASHABLE( ::zypp::Capability );
387 #endif // ZYPP_CAPABILITY_H