1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Capability.h
12 #ifndef ZYPP_CAPABILITY_H
13 #define ZYPP_CAPABILITY_H
17 #include "zypp/base/SafeBool.h"
18 #include "zypp/base/Deprecated.h"
20 #include "zypp/sat/detail/PoolMember.h"
22 #include "zypp/IdString.h"
23 #include "zypp/Edition.h"
25 #include "zypp/ResTraits.h"
27 #include "zypp/CapMatch.h"
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
37 typedef std::tr1::unordered_set<Capability> CapabilitySet;
39 ///////////////////////////////////////////////////////////////////
41 // CLASS NAME : Capability
45 * A Capability: <tt>"name[.arch] [op edition]"</tt>
47 * If a certain \ref ResKind is specified upon construction, the
48 * capabilities name part is prefixed accordingly. If no \ref ResKind
49 * is specified, it's assumed you refer to a package or the name is
52 * Capability( "foo" ) ==> 'foo'
53 * Capability( "foo", ResKind::package ) ==> 'foo'
54 * Capability( "foo", ResKind::pattern ) ==> 'pattern:foo'
55 * Capability( "pattern:foo" ) ==> 'pattern:foo'
57 * Capability( "pattern:foo", ResKind::pattern ) ==> 'pattern:pattern:foo'
60 class Capability: protected sat::detail::PoolMember,
61 private base::SafeBool<Capability>
64 enum CtorFlag { PARSED, UNPARSED };
67 /** Default ctor, \ref Empty capability. */
68 Capability() : _id( sat::detail::emptyId ) {}
71 explicit Capability( sat::detail::IdType id_r ) : _id( id_r ) {}
73 /** \name Ctors parsing a Capability: <tt>"name[.arch] [op edition]"</tt> or <tt>( arch, "name [op edition]")</tt>
77 * \a str_r is parsed to check whether it contains an <tt>[op edition]</tt> part,
78 * unless the \ref PARSED flag is passed to the ctor. In that case <tt>"name[.arch]"</tt>
81 explicit Capability( const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
83 explicit Capability( const std::string & 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 char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
86 /** \overload Explicitly specify the \c arch. */
87 Capability( const Arch & arch_r, const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
89 /** \overload Convenience for parsed (name only, no <tt>"[op edition]</tt>) packages: <tt>Capability( "glibc", PARSED ); */
90 Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
92 Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
93 /** \overload Explicitly specify the \c arch. */
94 Capability( const Arch & arch_r, const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
96 Capability( const Arch & arch_r, const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
100 /** \name Ctors parsing a broken down Capability: <tt>( "name[.arch]", op, edition )</tt>
103 /** Ctor from <tt>name[.arch] op edition</tt>. */
104 Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
106 Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
108 Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
111 /** \name Ctors taking a broken down Capability: <tt>( arch, name, op, edition )</tt>
114 /** Ctor from <tt>arch name op edition</tt>. */
115 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() );
117 Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
119 Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
121 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() );
123 Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
125 Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
129 /** No or Null \ref Capability ( Id \c 0 ). */
130 static const Capability Null;
132 /** Empty Capability. */
133 static const Capability Empty;
136 #ifndef SWIG // Swig treats it as syntax error
137 /** Evaluate in a boolean context <tt>( ! empty() )</tt>. */
138 using base::SafeBool<Capability>::operator bool_type;
140 /** Whether the \ref Capability is empty.
141 * This is true for \ref Null and \ref Empty.
144 { return( _id == sat::detail::emptyId || _id == sat::detail::noId ); }
147 /** Conversion to <tt>const char *</tt> */
148 const char * c_str() const;
151 std::string asString() const
155 /** Helper providing more detailed information about a \ref Capability. */
156 CapDetail detail() const;
159 /** \name Match two simple capabilities.
161 * Two simple capabilities match if they have the same \c name
162 * and their \c edition ranges overlap. Where no edition matches
163 * ANY edition. \see \ref Edition::match.
165 * If a capability expression is involved, \ref matches returns
166 * \ref CapMatch::irrelevant.
169 static CapMatch matches( const Capability & lhs, const Capability & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
170 static CapMatch matches( const Capability & lhs, const IdString & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
171 static CapMatch matches( const Capability & lhs, const std::string & rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
172 static CapMatch matches( const Capability & lhs, const char * rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() );}
174 static CapMatch matches( const IdString & lhs, const Capability & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
175 static CapMatch matches( const IdString & lhs, const IdString & rhs ) { return _doMatch( lhs.id(), rhs.id() ); }
176 static CapMatch matches( const IdString & lhs, const std::string & rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
177 static CapMatch matches( const IdString & lhs, const char * rhs ) { return _doMatch( lhs.id(), Capability(rhs).id() ); }
179 static CapMatch matches( const std::string & lhs, const Capability & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() );}
180 static CapMatch matches( const std::string & lhs, const IdString & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() ); }
181 static CapMatch matches( const std::string & lhs, const std::string & rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
182 static CapMatch matches( const std::string & lhs, const char * rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
184 static CapMatch matches( const char * lhs, const Capability & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() );}
185 static CapMatch matches( const char * lhs, const IdString & rhs ) { return _doMatch( Capability(lhs).id(), rhs.id() ); }
186 static CapMatch matches( const char * lhs, const std::string & rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
187 static CapMatch matches( const char * lhs, const char * rhs ) { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
189 CapMatch matches( const Capability & rhs ) const { return _doMatch( id(), rhs.id() ); }
190 CapMatch matches( const IdString & rhs ) const { return _doMatch( id(), rhs.id() ); }
191 CapMatch matches( const std::string & rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
192 CapMatch matches( const char * rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
195 /** \ref matches functor.
197 struct Matches: public std::binary_function<Capability,Capability,CapMatch>
199 CapMatch operator()( const Capability & lhs, const Capability & rhs ) const
200 { return Capability::matches( lhs, rhs ); }
204 /** Test for a filename that is likely being REQUIRED.
205 * Files below \c /bin , \c /sbin , \c /lib etc. Scanning a
206 * packages filelist, an \e interesting filename might be worth
207 * being remembered in PROVIDES.
209 static bool isInterestingFileSpec( const IdString & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
210 static bool isInterestingFileSpec( const std::string & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
211 static bool isInterestingFileSpec( const char * name_r );
213 /** \ref Capability parser also guessing \c "libzypp-1.2.3-4.5.x86_64" formats.
215 * The argument might be in the form \c "libzypp-devel-1.2.3.x86_64".
216 * Passed to the Capability ctor, this would correctly be parsed as name
217 * capability, because actually the edition part had to be separated by a
218 * \c '=', and the architecture had to be appended to the name.
219 * So this is how it actually had to look like: \c "libzypp-devel.x86_64=1.2.3"
221 * Obviously we have to guess if, and where to split name and edition. In
222 * fact \c "devel" could also be the version and \c "1.2.3" would be the
225 * Assuming this Capability should be provided by some package in
226 * the \ref ResPool, we check this. If unprovided, we substitute the last,
227 * (or one but last) \c '-' by a \c '='. If the name part
228 * (without version) of the resulting Capability is provided
229 * by the \ref ResPool, this Capability is returned.
231 * Otherwise we return the Capability originally created from
234 * \note: As this method will access the global pool, the returned
235 * result depends on the pools content.
237 static Capability guessPackageSpec( const std::string & str_r );
240 /** Expert backdoor. */
241 sat::detail::IdType id() const
244 /** Match two Capabilities */
245 static CapMatch _doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs );
247 #ifndef SWIG // Swig treats it as syntax error
248 friend base::SafeBool<Capability>::operator bool_type() const;
250 bool boolTest() const { return ! empty(); }
252 sat::detail::IdType _id;
254 ///////////////////////////////////////////////////////////////////
256 /** \relates Capability Stream output */
257 std::ostream & operator<<( std::ostream & str, const Capability & obj );
259 /** \relates Capability Detailed stream output */
260 std::ostream & dumpOn( std::ostream & str, const Capability & obj );
262 /** \relates Capability */
263 inline bool operator==( const Capability & lhs, const Capability & rhs )
264 { return lhs.id() == rhs.id(); }
266 /** \relates Capability */
267 inline bool operator!=( const Capability & lhs, const Capability & rhs )
268 { return lhs.id() != rhs.id(); }
270 /** \relates Capability Arbitrary order. */
271 inline bool operator<( const Capability & lhs, const Capability & rhs )
272 { return lhs.id() < rhs.id(); }
274 ///////////////////////////////////////////////////////////////////
276 // CLASS NAME : CapDetail
278 /** Helper providing more detailed information about a \ref Capability.
280 * Capabilities are classified to be either \c SIMPLE:
282 * name[.arch] [op edition]
283 * with op := <|<=|=|>=|>|!=
285 * or formed by some \c EXPRESSION:
287 * left_cap op right_cap
288 * with op := AND|OR|WITH|NAMESPACE
291 class CapDetail: protected sat::detail::PoolMember
302 /** Enum values corresponding with libsatsolver defines.
303 * \note MPL check in PoolImpl.cc
317 : _kind( NOCAP ), _lhs( 0 ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
319 explicit CapDetail( const Capability & cap_r )
320 : _kind( NOCAP ), _lhs( cap_r.id() ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
322 explicit CapDetail( sat::detail::IdType id_r )
323 : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
327 Kind kind() const { return _kind; }
328 bool isNull() const { return _kind == NOCAP; }
329 bool isNamed() const { return _kind == NAMED; }
330 bool isVersioned() const { return _kind == VERSIONED; }
331 bool isSimple() const { return _kind & (NAMED|VERSIONED); }
332 bool isExpression() const { return _kind == EXPRESSION; }
334 /** \name Is simple: <tt>name[.arch] [op edition]</tt> */
336 bool hasArch() const { return _archIfSimple; }
337 IdString arch() const { return _archIfSimple ? IdString( _archIfSimple ) : IdString(); }
338 IdString name() const { return isSimple() ? IdString( _lhs ) : IdString(); }
339 Rel op() const { return isVersioned() ? Rel( _flag ) : Rel::ANY; }
340 Edition ed() const { return isVersioned() ? Edition( _rhs ) : Edition(); }
343 /** \name Is expression <tt>cap op cap</tt> */
345 Capability lhs() const { return isExpression() ? Capability( _lhs ) : Capability::Null; }
346 CapRel capRel() const { return isExpression() ? CapRel(_flag) : REL_NONE; }
347 Capability rhs() const { return isExpression() ? Capability( _rhs ) : Capability::Null; }
354 sat::detail::IdType _lhs;
355 sat::detail::IdType _rhs;
357 sat::detail::IdType _archIfSimple;
359 ///////////////////////////////////////////////////////////////////
361 /** \relates CapDetail Stream output */
362 std::ostream & operator<<( std::ostream & str, const CapDetail & obj );
364 /** \relates CapDetail Stream output */
365 std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj );
367 /** \relates CapDetail Stream output */
368 std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj );
370 ///////////////////////////////////////////////////////////////////
372 inline CapDetail Capability::detail() const { return CapDetail( _id ); }
374 /////////////////////////////////////////////////////////////////
376 ///////////////////////////////////////////////////////////////////
378 ZYPP_DEFINE_ID_HASHABLE( ::zypp::Capability );
380 #endif // ZYPP_CAPABILITY_H