Deprecate MediaAccess::downloads (accidentally deleted)
[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> or <tt>( arch, "name [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 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 );
88
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() );
91       /** \overload */
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() );
95       /** \overload */
96       Capability( const Arch & arch_r, const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
97       //@}
98
99
100       /** \name Ctors parsing a broken down Capability: <tt>( "name[.arch]", op, edition )</tt>
101       */
102       //@{
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() );
105       /** \overload */
106       Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
107       /** \overload */
108       Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
109       //@}
110
111       /** \name Ctors taking a broken down Capability: <tt>( arch, name, op, edition )</tt>
112       */
113       //@{
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() );
116       /** \overload */
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() );
118       /** \overload */
119       Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
120       /** \overload */
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() );
122       /** \overload */
123       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
124       /** \overload */
125       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
126       //@}
127
128     public:
129       /** No or Null \ref Capability ( Id \c 0 ). */
130       static const Capability Null;
131
132       /** Empty Capability. */
133       static const Capability Empty;
134
135     public:
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;
139 #endif
140       /** Whether the \ref Capability is empty.
141        * This is true for \ref Null and \ref Empty.
142        */
143       bool empty() const
144       { return( _id == sat::detail::emptyId || _id == sat::detail::noId ); }
145
146     public:
147       /** Conversion to <tt>const char *</tt> */
148       const char * c_str() const;
149
150       /** \overload */
151       std::string asString() const
152       { return c_str(); }
153
154     public:
155       /** Helper providing more detailed information about a \ref Capability. */
156       CapDetail detail() const;
157
158     public:
159       /** \name Match two simple capabilities.
160        *
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.
164        *
165        * If a capability expression is involved, \ref matches returns
166        * \ref CapMatch::irrelevant.
167        */
168       //@{
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() );}
173
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() ); }
178
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() ); }
183
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() ); }
188
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() ); }
193       //@}
194
195       /** \ref matches functor.
196        */
197       struct Matches: public std::binary_function<Capability,Capability,CapMatch>
198       {
199         CapMatch operator()( const Capability & lhs, const Capability & rhs ) const
200         { return Capability::matches( lhs, rhs ); }
201       };
202
203     public:
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.
208        */
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 );
212
213       /** \ref Capability parser also guessing \c "libzypp-1.2.3-4.5.x86_64" formats.
214        *
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"
220        *
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
223        * release then.
224        *
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.
230        *
231        * Otherwise we return the Capability originally created from
232        * \a str_r.
233        *
234        * \note: As this method will access the global pool, the returned
235        * result depends on the pools content.
236        */
237       static Capability guessPackageSpec( const std::string & str_r );
238
239     public:
240       /** Expert backdoor. */
241       sat::detail::IdType id() const
242       { return _id; }
243     private:
244       /** Match two Capabilities */
245       static CapMatch _doMatch( sat::detail::IdType lhs,  sat::detail::IdType rhs );
246     private:
247 #ifndef SWIG // Swig treats it as syntax error
248       friend base::SafeBool<Capability>::operator bool_type() const;
249 #endif
250       bool boolTest() const { return ! empty(); }
251     private:
252       sat::detail::IdType _id;
253   };
254   ///////////////////////////////////////////////////////////////////
255
256   /** \relates Capability Stream output */
257   std::ostream & operator<<( std::ostream & str, const Capability & obj );
258
259   /** \relates Capability Detailed stream output */
260   std::ostream & dumpOn( std::ostream & str, const Capability & obj );
261
262   /** \relates Capability */
263   inline bool operator==( const Capability & lhs, const Capability & rhs )
264   { return lhs.id() == rhs.id(); }
265
266   /** \relates Capability */
267   inline bool operator!=( const Capability & lhs, const Capability & rhs )
268   { return lhs.id() != rhs.id(); }
269
270   /** \relates Capability Arbitrary order. */
271   inline bool operator<( const Capability & lhs, const Capability & rhs )
272   { return lhs.id() < rhs.id(); }
273
274   ///////////////////////////////////////////////////////////////////
275   //
276   //    CLASS NAME : CapDetail
277   //
278   /** Helper providing more detailed information about a \ref Capability.
279    *
280    * Capabilities are classified to be either \c SIMPLE:
281    * \code
282    *   name[.arch] [op edition]
283    *   with op := <|<=|=|>=|>|!=
284    * \endcode
285    * or formed by some \c EXPRESSION:
286    * \code
287    *   left_cap op right_cap
288    *   with op := AND|OR|WITH|NAMESPACE
289    * \endcode
290    */
291   class CapDetail: protected sat::detail::PoolMember
292   {
293     public:
294       enum Kind
295       {
296         NOCAP      = 0x00,
297         NAMED      = 0x01,
298         VERSIONED  = 0x02,
299         EXPRESSION = 0x04
300       };
301
302       /** Enum values corresponding with libsatsolver defines.
303        * \note MPL check in PoolImpl.cc
304       */
305       enum CapRel
306       {
307         REL_NONE      = 0,
308         CAP_AND       = 16,
309         CAP_OR        = 17,
310         CAP_WITH      = 18,
311         CAP_NAMESPACE = 19,
312         CAP_ARCH      = 20
313       };
314
315     public:
316       CapDetail()
317       : _kind( NOCAP ), _lhs( 0 ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
318       {}
319       explicit CapDetail( const Capability & cap_r )
320       : _kind( NOCAP ), _lhs( cap_r.id() ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
321       { _init(); }
322       explicit CapDetail( sat::detail::IdType id_r )
323       : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
324       { _init(); }
325
326     public:
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; }
333
334       /** \name Is simple: <tt>name[.arch] [op edition]</tt> */
335       //@{
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(); }
341       //@}
342
343       /** \name Is expression <tt>cap op cap</tt> */
344       //@{
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; }
348      //@}
349
350     private:
351       void _init();
352     private:
353       Kind                _kind;
354       sat::detail::IdType _lhs;
355       sat::detail::IdType _rhs;
356       unsigned            _flag;
357       sat::detail::IdType _archIfSimple;
358   };
359   ///////////////////////////////////////////////////////////////////
360
361   /** \relates CapDetail Stream output */
362   std::ostream & operator<<( std::ostream & str, const CapDetail & obj );
363
364   /** \relates CapDetail Stream output */
365   std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj );
366
367   /** \relates CapDetail Stream output */
368   std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj );
369
370   ///////////////////////////////////////////////////////////////////
371
372   inline CapDetail Capability::detail() const { return CapDetail( _id ); }
373
374   /////////////////////////////////////////////////////////////////
375 } // namespace zypp
376 ///////////////////////////////////////////////////////////////////
377
378 ZYPP_DEFINE_ID_HASHABLE( ::zypp::Capability );
379
380 #endif // ZYPP_CAPABILITY_H