Support dependencies requiring a specific architecture:
[platform/upstream/libzypp.git] / zypp / Capability.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Capability.h
10  *
11 */
12 #ifndef ZYPP_CAPABILITY_H
13 #define ZYPP_CAPABILITY_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/SafeBool.h"
18 #include "zypp/base/Deprecated.h"
19
20 #include "zypp/sat/detail/PoolMember.h"
21
22 #include "zypp/IdString.h"
23 #include "zypp/Edition.h"
24 #include "zypp/Rel.h"
25 #include "zypp/ResTraits.h"
26
27 #include "zypp/CapMatch.h"
28
29 ///////////////////////////////////////////////////////////////////
30 namespace zypp
31 { /////////////////////////////////////////////////////////////////
32
33   class Capability;
34   class CapDetail;
35   class Arch;
36
37   typedef std::tr1::unordered_set<Capability> CapabilitySet;
38
39   ///////////////////////////////////////////////////////////////////
40   //
41   //    CLASS NAME : Capability
42   //
43   /** A sat capability.
44    *
45    * A Capability: <tt>"name[.arch] [op edition]"</tt>
46    *
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
50    * already prefixed:
51    * \code
52    * Capability( "foo" )                   ==> 'foo'
53    * Capability( "foo", ResKind::package ) ==> 'foo'
54    * Capability( "foo", ResKind::pattern ) ==> 'pattern:foo'
55    * Capability( "pattern:foo" )           ==> 'pattern:foo'
56      * // avoid this:
57    * Capability( "pattern:foo", ResKind::pattern ) ==> 'pattern:pattern:foo'
58    * \endcode
59    */
60   class Capability: protected sat::detail::PoolMember,
61                     private base::SafeBool<Capability>
62   {
63     public:
64       enum CtorFlag { PARSED, UNPARSED };
65
66     public:
67       /** Default ctor, \ref Empty capability. */
68       Capability() : _id( sat::detail::emptyId ) {}
69
70       /** Ctor from id. */
71       explicit Capability( sat::detail::IdType id_r ) : _id( id_r ) {}
72
73       /** \name Ctors parsing a Capability: <tt>"name[.arch] [op edition]"</tt>
74       */
75       //@{
76       /** Ctor from string.
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>
79        * is assumed.
80       */
81       explicit Capability( const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
82       /** \overload */
83       explicit Capability( const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
84       /** \overload Convenience for parsed (name only) packages. */
85       Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
86       /** \overload */
87       Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
88       //@}
89
90       /** \name Ctors parsing a broken down Capability: <tt>( "name[.arch]", op, edition )</tt>
91       */
92       //@{
93       /** Ctor from <tt>name[.arch] op edition</tt>. */
94       Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
95       /** \overload */
96       Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
97       /** \overload */
98       Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
99       //@}
100
101       /** \name Ctors taking a broken down Capability: <tt>( arch, name, op, edition )</tt>
102       */
103       //@{
104       /** Ctor from <tt>arch name op edition</tt>. */
105       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() );
106       /** \overload */
107       Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
108       /** \overload */
109       Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
110       /** \overload */
111       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() );
112       /** \overload */
113       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
114       /** \overload */
115       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
116       //@}
117
118     public:
119       /** No or Null \ref Capability ( Id \c 0 ). */
120       static const Capability Null;
121
122       /** Empty Capability. */
123       static const Capability Empty;
124
125     public:
126       /** Evaluate in a boolean context <tt>( ! empty() )</tt>. */
127       using base::SafeBool<Capability>::operator bool_type;
128
129       /** Whether the \ref Capability is empty.
130        * This is true for \ref Null and \ref Empty.
131        */
132       bool empty() const
133       { return( _id == sat::detail::emptyId || _id == sat::detail::noId ); }
134
135     public:
136       /** Conversion to <tt>const char *</tt> */
137       const char * c_str() const;
138
139       /** \overload */
140       std::string asString() const
141       { return c_str(); }
142
143     public:
144       /** Helper providing more detailed information about a \ref Capability. */
145       CapDetail detail() const;
146
147     public:
148       /** \name Match two simple capabilities.
149        *
150        * Two simple capabilities match if they have the same \c name
151        * and their \c edition ranges overlap. Where no edition matches
152        * ANY edition. \see \ref Edition::match.
153        *
154        * If a capability expression is involved, \ref matches returns
155        * \ref CapMatch::irrelevant.
156        */
157       //@{
158       static CapMatch matches( const Capability & lhs,  const Capability & rhs )     { return _doMatch( lhs.id(), rhs.id() ); }
159       static CapMatch matches( const Capability & lhs,  const IdString & rhs )       { return _doMatch( lhs.id(), rhs.id() ); }
160       static CapMatch matches( const Capability & lhs,  const std::string & rhs )    { return _doMatch( lhs.id(), Capability(rhs).id() ); }
161       static CapMatch matches( const Capability & lhs,  const char * rhs )           { return _doMatch( lhs.id(), Capability(rhs).id() );}
162
163       static CapMatch matches( const IdString & lhs,    const Capability & rhs )     { return _doMatch( lhs.id(), rhs.id() ); }
164       static CapMatch matches( const IdString & lhs,    const IdString & rhs )       { return _doMatch( lhs.id(), rhs.id() ); }
165       static CapMatch matches( const IdString & lhs,    const std::string & rhs )    { return _doMatch( lhs.id(), Capability(rhs).id() ); }
166       static CapMatch matches( const IdString & lhs,    const char * rhs )           { return _doMatch( lhs.id(), Capability(rhs).id() ); }
167
168       static CapMatch matches( const std::string & lhs, const Capability & rhs )     { return _doMatch( Capability(lhs).id(), rhs.id() );}
169       static CapMatch matches( const std::string & lhs, const IdString & rhs )       { return _doMatch( Capability(lhs).id(), rhs.id() ); }
170       static CapMatch matches( const std::string & lhs, const std::string & rhs )    { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
171       static CapMatch matches( const std::string & lhs, const char * rhs )           { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
172
173       static CapMatch matches( const char * lhs,        const Capability & rhs )     { return _doMatch( Capability(lhs).id(), rhs.id() );}
174       static CapMatch matches( const char * lhs,        const IdString & rhs )       { return _doMatch( Capability(lhs).id(), rhs.id() ); }
175       static CapMatch matches( const char * lhs,        const std::string & rhs )    { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
176       static CapMatch matches( const char * lhs,        const char * rhs )           { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
177
178       CapMatch matches( const Capability & rhs )  const { return _doMatch( id(), rhs.id() ); }
179       CapMatch matches( const IdString & rhs )    const { return _doMatch( id(), rhs.id() ); }
180       CapMatch matches( const std::string & rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
181       CapMatch matches( const char * rhs )        const { return _doMatch( id(), Capability(rhs).id() ); }
182       //@}
183
184       /** \ref matches functor.
185        */
186       struct Matches: public std::binary_function<Capability,Capability,CapMatch>
187       {
188         CapMatch operator()( const Capability & lhs, const Capability & rhs ) const
189         { return Capability::matches( lhs, rhs ); }
190       };
191
192     public:
193       /** Test for a filename that is likely being REQUIRED.
194        * Files below \c /bin , \c /sbin ,  \c /lib etc. Scanning a
195        * packages filelist, an \e interesting filename might be worth
196        * being remembered in PROVIDES.
197        */
198       static bool isInterestingFileSpec( const IdString & name_r )    { return isInterestingFileSpec( name_r.c_str() ); }
199       static bool isInterestingFileSpec( const std::string & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
200       static bool isInterestingFileSpec( const char * name_r );
201
202     public:
203       /** Expert backdoor. */
204       sat::detail::IdType id() const
205       { return _id; }
206     private:
207       /** Match two Capabilities */
208       static CapMatch _doMatch( sat::detail::IdType lhs,  sat::detail::IdType rhs );
209     private:
210       friend base::SafeBool<Capability>::operator bool_type() const;
211       bool boolTest() const { return ! empty(); }
212     private:
213       sat::detail::IdType _id;
214   };
215   ///////////////////////////////////////////////////////////////////
216
217   /** \relates Capability Stream output */
218   std::ostream & operator<<( std::ostream & str, const Capability & obj );
219
220   /** \relates Capability Detailed stream output */
221   std::ostream & dumpOn( std::ostream & str, const Capability & obj );
222
223   /** \relates Capability */
224   inline bool operator==( const Capability & lhs, const Capability & rhs )
225   { return lhs.id() == rhs.id(); }
226
227   /** \relates Capability */
228   inline bool operator!=( const Capability & lhs, const Capability & rhs )
229   { return lhs.id() != rhs.id(); }
230
231   /** \relates Capability Arbitrary order. */
232   inline bool operator<( const Capability & lhs, const Capability & rhs )
233   { return lhs.id() < rhs.id(); }
234
235   ///////////////////////////////////////////////////////////////////
236   //
237   //    CLASS NAME : CapDetail
238   //
239   /** Helper providing more detailed information about a \ref Capability.
240    *
241    * Capabilities are classified to be either \c SIMPLE:
242    * \code
243    *   name[.arch] [op edition]
244    *   with op := <|<=|=|>=|>|!=
245    * \endcode
246    * or formed by some \c EXPRESSION:
247    * \code
248    *   left_cap op right_cap
249    *   with op := AND|OR|WITH|NAMESPACE
250    * \endcode
251    */
252   class CapDetail: protected sat::detail::PoolMember
253   {
254     public:
255       enum Kind
256       {
257         NOCAP      = 0x00,
258         NAMED      = 0x01,
259         VERSIONED  = 0x02,
260         EXPRESSION = 0x04
261       };
262
263       /** Enum values corresponding with libsatsolver defines.
264        * \note MPL check in PoolImpl.cc
265       */
266       enum CapRel
267       {
268         REL_NONE      = 0,
269         CAP_AND       = 16,
270         CAP_OR        = 17,
271         CAP_WITH      = 18,
272         CAP_NAMESPACE = 19,
273         CAP_ARCH      = 20
274       };
275
276     public:
277       CapDetail()
278       : _kind( NOCAP ), _lhs( 0 ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
279       {}
280       explicit CapDetail( const Capability & cap_r )
281       : _kind( NOCAP ), _lhs( cap_r.id() ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
282       { _init(); }
283       explicit CapDetail( sat::detail::IdType id_r )
284       : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
285       { _init(); }
286
287     public:
288       Kind kind()         const { return _kind; }
289       bool isNull()       const { return _kind == NOCAP; }
290       bool isNamed()      const { return _kind == NAMED; }
291       bool isVersioned()  const { return _kind == VERSIONED; }
292       bool isSimple()     const { return _kind & (NAMED|VERSIONED); }
293       bool isExpression() const { return _kind == EXPRESSION; }
294
295       /** \name Is simple: <tt>name[.arch] [op edition]</tt> */
296       //@{
297       bool     hasArch()  const { return _archIfSimple; }
298       IdString arch()     const { return _archIfSimple ? IdString( _archIfSimple ) : IdString(); }
299       IdString name()     const { return isSimple()    ? IdString( _lhs ) : IdString(); }
300       Rel      op()       const { return isVersioned() ? Rel( _flag )     : Rel::ANY; }
301       Edition  ed()       const { return isVersioned() ? Edition( _rhs )  : Edition(); }
302       //@}
303
304       /** \name Is expression <tt>cap op cap</tt> */
305       //@{
306       Capability lhs()    const { return isExpression() ? Capability( _lhs ) : Capability::Null; }
307       CapRel     capRel() const { return isExpression() ? CapRel(_flag)      : REL_NONE; }
308       Capability rhs()    const { return isExpression() ? Capability( _rhs ) : Capability::Null; }
309      //@}
310
311     private:
312       void _init();
313     private:
314       Kind                _kind;
315       sat::detail::IdType _lhs;
316       sat::detail::IdType _rhs;
317       unsigned            _flag;
318       sat::detail::IdType _archIfSimple;
319   };
320   ///////////////////////////////////////////////////////////////////
321
322   /** \relates CapDetail Stream output */
323   std::ostream & operator<<( std::ostream & str, const CapDetail & obj );
324
325   /** \relates CapDetail Stream output */
326   std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj );
327
328   /** \relates CapDetail Stream output */
329   std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj );
330
331   ///////////////////////////////////////////////////////////////////
332
333   inline CapDetail Capability::detail() const { return CapDetail( _id ); }
334
335   /////////////////////////////////////////////////////////////////
336 } // namespace zypp
337 ///////////////////////////////////////////////////////////////////
338
339 ZYPP_DEFINE_ID_HASHABLE( ::zypp::Capability )
340
341 #endif // ZYPP_CAPABILITY_H