Use libsolv includes and adjust documentation
[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, unless it already conatins a
49    * well known kind spec. If no \ref ResKind is specified, it's assumed
50    * you refer to a package or the name is 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    * // in doubt an explicit name prefix wins:
57    * Capability( "pattern:foo", ResKind::package ) ==> 'pattern:foo'
58    * Capability( "package:foo", ResKind::pattern ) ==> 'foo'
59    * \endcode
60    */
61   class Capability: protected sat::detail::PoolMember,
62                     private base::SafeBool<Capability>
63   {
64     public:
65       enum CtorFlag { PARSED, UNPARSED };
66
67     public:
68       /** Default ctor, \ref Empty capability. */
69       Capability() : _id( sat::detail::emptyId ) {}
70
71       /** Ctor from id. */
72       explicit Capability( sat::detail::IdType id_r ) : _id( id_r ) {}
73
74       /** \name Ctors parsing a Capability: <tt>"name[.arch] [op edition]"</tt> or <tt>( arch, "name [op edition]")</tt>
75       */
76       //@{
77       /** Ctor from string.
78        * \a str_r is parsed to check whether it contains an <tt>[op edition]</tt> part,
79        * unless the \ref PARSED flag is passed to the ctor. In that case <tt>"name[.arch]"</tt>
80        * is assumed.
81       */
82       explicit Capability( const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
83       /** \overload */
84       explicit Capability( const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
85       /** \overload Explicitly specify the \c arch. */
86       Capability( const Arch & arch_r, const char * str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
87       /** \overload Explicitly specify the \c arch. */
88       Capability( const Arch & arch_r, const std::string & str_r, const ResKind & prefix_r = ResKind(), CtorFlag flag_r = UNPARSED );
89
90       /** \overload Convenience for parsed (name only, no <tt>"[op edition]</tt>) packages: <tt>Capability( "glibc", PARSED ); */
91       Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
92       /** \overload */
93       Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
94       /** \overload Explicitly specify the \c arch. */
95       Capability( const Arch & arch_r, const char * str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
96       /** \overload */
97       Capability( const Arch & arch_r, const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r = ResKind() );
98       //@}
99
100
101       /** \name Ctors parsing a broken down Capability: <tt>( "name[.arch]", op, edition )</tt>
102       */
103       //@{
104       /** Ctor from <tt>name[.arch] op edition</tt>. */
105       Capability( 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 & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
108       /** \overload */
109       Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
110       //@}
111
112       /** \name Ctors taking a broken down Capability: <tt>( arch, name, op, edition )</tt>
113       */
114       //@{
115       /** Ctor from <tt>arch name op edition</tt>. */
116       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       /** \overload */
118       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       /** \overload */
120       Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
121       /** \overload */
122       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       /** \overload */
124       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
125       /** \overload */
126       Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
127       //@}
128
129     public:
130       /** No or Null \ref Capability ( Id \c 0 ). */
131       static const Capability Null;
132
133       /** Empty Capability. */
134       static const Capability Empty;
135
136     public:
137 #ifndef SWIG // Swig treats it as syntax error
138       /** Evaluate in a boolean context <tt>( ! empty() )</tt>. */
139       using base::SafeBool<Capability>::operator bool_type;
140 #endif
141       /** Whether the \ref Capability is empty.
142        * This is true for \ref Null and \ref Empty.
143        */
144       bool empty() const
145       { return( _id == sat::detail::emptyId || _id == sat::detail::noId ); }
146
147     public:
148       /** Conversion to <tt>const char *</tt> */
149       const char * c_str() const;
150
151       /** \overload */
152       std::string asString() const
153       { return c_str(); }
154
155     public:
156       /** Helper providing more detailed information about a \ref Capability. */
157       CapDetail detail() const;
158
159     public:
160       /** \name Match two simple capabilities.
161        *
162        * Two simple capabilities match if they have the same \c name
163        * and their \c edition ranges overlap. Where no edition matches
164        * ANY edition. \see \ref Edition::match.
165        *
166        * If a capability expression is involved, \ref matches returns
167        * \ref CapMatch::irrelevant.
168        */
169       //@{
170       static CapMatch matches( const Capability & lhs,  const Capability & rhs )     { return _doMatch( lhs.id(), rhs.id() ); }
171       static CapMatch matches( const Capability & lhs,  const IdString & rhs )       { return _doMatch( lhs.id(), rhs.id() ); }
172       static CapMatch matches( const Capability & lhs,  const std::string & rhs )    { return _doMatch( lhs.id(), Capability(rhs).id() ); }
173       static CapMatch matches( const Capability & lhs,  const char * rhs )           { return _doMatch( lhs.id(), Capability(rhs).id() );}
174
175       static CapMatch matches( const IdString & lhs,    const Capability & rhs )     { return _doMatch( lhs.id(), rhs.id() ); }
176       static CapMatch matches( const IdString & lhs,    const IdString & rhs )       { return _doMatch( lhs.id(), rhs.id() ); }
177       static CapMatch matches( const IdString & lhs,    const std::string & rhs )    { return _doMatch( lhs.id(), Capability(rhs).id() ); }
178       static CapMatch matches( const IdString & lhs,    const char * rhs )           { return _doMatch( lhs.id(), Capability(rhs).id() ); }
179
180       static CapMatch matches( const std::string & lhs, const Capability & rhs )     { return _doMatch( Capability(lhs).id(), rhs.id() );}
181       static CapMatch matches( const std::string & lhs, const IdString & rhs )       { return _doMatch( Capability(lhs).id(), rhs.id() ); }
182       static CapMatch matches( const std::string & lhs, const std::string & rhs )    { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
183       static CapMatch matches( const std::string & lhs, const char * rhs )           { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
184
185       static CapMatch matches( const char * lhs,        const Capability & rhs )     { return _doMatch( Capability(lhs).id(), rhs.id() );}
186       static CapMatch matches( const char * lhs,        const IdString & rhs )       { return _doMatch( Capability(lhs).id(), rhs.id() ); }
187       static CapMatch matches( const char * lhs,        const std::string & rhs )    { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
188       static CapMatch matches( const char * lhs,        const char * rhs )           { return _doMatch( Capability(lhs).id(), Capability(rhs).id() ); }
189
190       CapMatch matches( const Capability & rhs )  const { return _doMatch( id(), rhs.id() ); }
191       CapMatch matches( const IdString & rhs )    const { return _doMatch( id(), rhs.id() ); }
192       CapMatch matches( const std::string & rhs ) const { return _doMatch( id(), Capability(rhs).id() ); }
193       CapMatch matches( const char * rhs )        const { return _doMatch( id(), Capability(rhs).id() ); }
194       //@}
195
196       /** \ref matches functor.
197        */
198       struct Matches: public std::binary_function<Capability,Capability,CapMatch>
199       {
200         CapMatch operator()( const Capability & lhs, const Capability & rhs ) const
201         { return Capability::matches( lhs, rhs ); }
202       };
203
204     public:
205       /** Test for a filename that is likely being REQUIRED.
206        * Files below \c /bin , \c /sbin ,  \c /lib etc. Scanning a
207        * packages filelist, an \e interesting filename might be worth
208        * being remembered in PROVIDES.
209        */
210       static bool isInterestingFileSpec( const IdString & name_r )    { return isInterestingFileSpec( name_r.c_str() ); }
211       static bool isInterestingFileSpec( const std::string & name_r ) { return isInterestingFileSpec( name_r.c_str() ); }
212       static bool isInterestingFileSpec( const char * name_r );
213
214       /** \ref Capability parser also guessing \c "libzypp-1.2.3-4.5.x86_64" formats.
215        *
216        * The argument might be in the form \c "libzypp-devel-1.2.3.x86_64".
217        * Passed to the Capability ctor, this would correctly be parsed as name
218        * capability, because actually the edition part had to be separated by a
219        * \c '=', and the architecture had to be appended to the name.
220        * So this is how it actually had to look like: \c "libzypp-devel.x86_64=1.2.3"
221        *
222        * Obviously we have to guess if, and where to split name and edition. In
223        * fact \c "devel" could also be the version and \c "1.2.3" would be the
224        * release then.
225        *
226        * Assuming this Capability should be provided by some package in
227        * the \ref ResPool, we check this. If unprovided, we substitute the last,
228        * (or one but last) \c '-' by a \c '='. If the name part (without version)
229        * of the resulting Capability matches a package name (not provides!) in
230        * the \ref ResPool, this Capability is returned.
231        *
232        * Otherwise we return the Capability originally created from
233        * \a str_r.
234        *
235        * \note: As this method will access the global pool, the returned
236        * result depends on the pools content.
237        */
238       static Capability guessPackageSpec( const std::string & str_r );
239       /** \overload Taking an additional bool indicating whether \c str_r made
240        * a valid \ref Capability (\c true) or the result was was guessed by
241        * rewiting a \c '-' to \c '='. (\c false).
242        */
243       static Capability guessPackageSpec( const std::string & str_r, bool & rewrote_r );
244
245     public:
246       /** Expert backdoor. */
247       sat::detail::IdType id() const
248       { return _id; }
249     private:
250       /** Match two Capabilities */
251       static CapMatch _doMatch( sat::detail::IdType lhs,  sat::detail::IdType rhs );
252     private:
253 #ifndef SWIG // Swig treats it as syntax error
254       friend base::SafeBool<Capability>::operator bool_type() const;
255 #endif
256       bool boolTest() const { return ! empty(); }
257     private:
258       sat::detail::IdType _id;
259   };
260   ///////////////////////////////////////////////////////////////////
261
262   /** \relates Capability Stream output */
263   std::ostream & operator<<( std::ostream & str, const Capability & obj );
264
265   /** \relates Capability Detailed stream output */
266   std::ostream & dumpOn( std::ostream & str, const Capability & obj );
267
268   /** \relates Capability */
269   inline bool operator==( const Capability & lhs, const Capability & rhs )
270   { return lhs.id() == rhs.id(); }
271
272   /** \relates Capability */
273   inline bool operator!=( const Capability & lhs, const Capability & rhs )
274   { return lhs.id() != rhs.id(); }
275
276   /** \relates Capability Arbitrary order. */
277   inline bool operator<( const Capability & lhs, const Capability & rhs )
278   { return lhs.id() < rhs.id(); }
279
280   ///////////////////////////////////////////////////////////////////
281   //
282   //    CLASS NAME : CapDetail
283   //
284   /** Helper providing more detailed information about a \ref Capability.
285    *
286    * Capabilities are classified to be either \c SIMPLE:
287    * \code
288    *   name[.arch] [op edition]
289    *   with op := <|<=|=|>=|>|!=
290    * \endcode
291    * or formed by some \c EXPRESSION:
292    * \code
293    *   left_cap op right_cap
294    *   with op := AND|OR|WITH|NAMESPACE
295    * \endcode
296    */
297   class CapDetail: protected sat::detail::PoolMember
298   {
299     public:
300       enum Kind
301       {
302         NOCAP      = 0x00,
303         NAMED      = 0x01,
304         VERSIONED  = 0x02,
305         EXPRESSION = 0x04
306       };
307
308       /** Enum values corresponding with libsolv defines.
309        * \note MPL check in PoolImpl.cc
310       */
311       enum CapRel
312       {
313         REL_NONE      = 0,
314         CAP_AND       = 16,
315         CAP_OR        = 17,
316         CAP_WITH      = 18,
317         CAP_NAMESPACE = 19,
318         CAP_ARCH      = 20
319       };
320
321     public:
322       CapDetail()
323       : _kind( NOCAP ), _lhs( 0 ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
324       {}
325       explicit CapDetail( const Capability & cap_r )
326       : _kind( NOCAP ), _lhs( cap_r.id() ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
327       { _init(); }
328       explicit CapDetail( sat::detail::IdType id_r )
329       : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
330       { _init(); }
331
332     public:
333       Kind kind()         const { return _kind; }
334       bool isNull()       const { return _kind == NOCAP; }
335       bool isNamed()      const { return _kind == NAMED; }
336       bool isVersioned()  const { return _kind == VERSIONED; }
337       bool isSimple()     const { return _kind & (NAMED|VERSIONED); }
338       bool isExpression() const { return _kind == EXPRESSION; }
339
340       /** \name Is simple: <tt>name[.arch] [op edition]</tt> */
341       //@{
342       bool     hasArch()  const { return _archIfSimple; }
343       IdString arch()     const { return _archIfSimple ? IdString( _archIfSimple ) : IdString(); }
344       IdString name()     const { return isSimple()    ? IdString( _lhs ) : IdString(); }
345       Rel      op()       const { return isVersioned() ? Rel( _flag )     : Rel::ANY; }
346       Edition  ed()       const { return isVersioned() ? Edition( _rhs )  : Edition(); }
347       //@}
348
349       /** \name Is expression <tt>cap op cap</tt> */
350       //@{
351       Capability lhs()    const { return isExpression() ? Capability( _lhs ) : Capability::Null; }
352       CapRel     capRel() const { return isExpression() ? CapRel(_flag)      : REL_NONE; }
353       Capability rhs()    const { return isExpression() ? Capability( _rhs ) : Capability::Null; }
354      //@}
355
356     private:
357       void _init();
358     private:
359       Kind                _kind;
360       sat::detail::IdType _lhs;
361       sat::detail::IdType _rhs;
362       unsigned            _flag;
363       sat::detail::IdType _archIfSimple;
364   };
365   ///////////////////////////////////////////////////////////////////
366
367   /** \relates CapDetail Stream output */
368   std::ostream & operator<<( std::ostream & str, const CapDetail & obj );
369
370   /** \relates CapDetail Stream output */
371   std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj );
372
373   /** \relates CapDetail Stream output */
374   std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj );
375
376   ///////////////////////////////////////////////////////////////////
377
378   inline CapDetail Capability::detail() const { return CapDetail( _id ); }
379
380   /////////////////////////////////////////////////////////////////
381 } // namespace zypp
382 ///////////////////////////////////////////////////////////////////
383
384 ZYPP_DEFINE_ID_HASHABLE( ::zypp::Capability );
385
386 #endif // ZYPP_CAPABILITY_H