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