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