1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/Capability.cc
13 #include "zypp/base/Logger.h"
15 #include "zypp/base/String.h"
16 #include "zypp/base/Regex.h"
17 #include "zypp/base/Gettext.h"
18 #include "zypp/base/Exception.h"
20 #include "zypp/Arch.h"
22 #include "zypp/Edition.h"
23 #include "zypp/Capability.h"
25 #include "zypp/sat/detail/PoolImpl.h"
26 #include "zypp/sat/Pool.h"
30 ///////////////////////////////////////////////////////////////////
32 { /////////////////////////////////////////////////////////////////
33 ///////////////////////////////////////////////////////////////////
35 { /////////////////////////////////////////////////////////////////
36 sat::detail::IdType relFromStr( ::_Pool * pool_r,
38 const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & kind_r )
40 sat::detail::IdType nid( sat::detail::noId );
44 sat::detail::IdType relFromStr( ::_Pool * pool_r,
45 const std::string & name_r, Rel op_r, const Edition & ed_r,
46 const ResKind & kind_r )
48 sat::detail::IdType nid( sat::detail::noId );
49 if ( ! kind_r || kind_r == ResKind::package )
51 nid = IdString( name_r ).id();
55 // non-packages prefixed by kind
56 nid = IdString( str::form( "%s:%s",
58 name_r.c_str() ) ).id();
61 if ( op_r != Rel::ANY && ed_r != Edition::noedition )
63 nid = ::rel2id( pool_r, nid, ed_r.id(), op_r.bits(), /*create*/true );
69 sat::detail::IdType relFromStr( ::_Pool * pool_r,
70 const std::string & str_r, const ResKind & kind_r,
71 Capability::CtorFlag flag_r )
73 // strval_r has at least two words which could make 'op edition'?
75 static const str::regex rx( "(.*[^ \t])([ \t]+)([^ \t]+)([ \t]+)([^ \t]+)" );
76 static str::smatch what;
78 std::string name( str_r );
81 if ( flag_r == Capability::UNPARSED
82 && str_r.find(' ') != std::string::npos
83 && str::regex_match( str_r, what, rx ) )
88 Edition ced( what[5] );
93 catch ( Exception & excpt )
95 // So they don't make valid 'op edition'
97 DBG << "Trying named relation for: " << str_r << endl;
101 // not a versioned relation
103 return relFromStr( pool_r, name, op, ed, kind_r );
106 /////////////////////////////////////////////////////////////////
108 ///////////////////////////////////////////////////////////////////
110 const Capability Capability::Null( STRID_NULL );
112 /////////////////////////////////////////////////////////////////
114 Capability::Capability( const char * str_r, const ResKind & prefix_r, CtorFlag flag_r )
115 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
118 Capability::Capability( const std::string & str_r, const ResKind & prefix_r, CtorFlag flag_r )
119 : _id( relFromStr( myPool().getPool(), str_r.c_str(), prefix_r, flag_r ) )
122 Capability::Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r )
123 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
126 Capability::Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r )
127 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
131 Capability::Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r )
132 : _id( relFromStr( myPool().getPool(), name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
135 Capability::Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
136 : _id( relFromStr( myPool().getPool(), name_r, op_r, Edition(ed_r), prefix_r ) )
139 Capability::Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
140 : _id( relFromStr( myPool().getPool(), name_r, op_r, ed_r, prefix_r ) )
144 Capability::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() );
145 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
146 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
147 Capability::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() );
148 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r = ResKind() );
149 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r = ResKind() );
152 const char * Capability::c_str() const
153 { return( _id ? ::dep2str( myPool().getPool(), _id ) : "" ); }
155 CapMatch Capability::_doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs )
157 #warning MIGRATE TO SAT
160 return CapMatch::yes;
167 case CapDetail::NOCAP:
168 return( r.kind() == CapDetail::NOCAP ); // NOCAP matches NOCAP only
170 case CapDetail::EXPRESSION:
171 return CapMatch::irrelevant;
173 case CapDetail::NAMED:
174 case CapDetail::VERSIONED:
180 case CapDetail::NOCAP:
181 return CapMatch::no; // match case handled above
183 case CapDetail::EXPRESSION:
184 return CapMatch::irrelevant;
186 case CapDetail::NAMED:
187 case CapDetail::VERSIONED:
190 // comparing two simple caps:
191 if ( l.name() != r.name() )
194 // isNamed matches ANY edition:
195 if ( l.isNamed() || r.isNamed() )
196 return CapMatch::yes;
198 // both are versioned:
199 return overlaps( Edition::MatchRange( l.op(), l.ed() ),
200 Edition::MatchRange( r.op(), r.ed() ) );
203 bool Capability::isInterestingFileSpec( const char * name_r )
205 static str::smatch what;
206 static const str::regex filenameRegex(
207 "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/",
208 str::regex::optimize|str::regex::nosubs );
210 return str::regex_match( name_r, what, filenameRegex );
213 /******************************************************************
215 ** FUNCTION NAME : operator<<
216 ** FUNCTION TYPE : std::ostream &
218 std::ostream & operator<<( std::ostream & str, const Capability & obj )
220 return str << obj.detail();
223 std::ostream & dumpOn( std::ostream & str, const Capability & obj )
225 return str << obj.detail();
228 ///////////////////////////////////////////////////////////////////
230 // CLASS NAME : CapDetail
232 ///////////////////////////////////////////////////////////////////
234 void CapDetail::_init()
236 // : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 )
238 if ( _lhs == sat::detail::emptyId || _lhs == sat::detail::noId )
241 if ( ! ISRELDEP(_lhs) )
247 ::Reldep * rd = GETRELDEP( myPool().getPool(), _lhs );
252 _kind = Rel::isRel( _flag ) ? VERSIONED : EXPRESSION;
255 /******************************************************************
257 ** FUNCTION NAME : operator<<
258 ** FUNCTION TYPE : std::ostream &
260 std::ostream & operator<<( std::ostream & str, const CapDetail & obj )
262 switch ( obj.kind() )
264 case CapDetail::NOCAP:
265 return str << "<NoCap>";
267 case CapDetail::NAMED:
268 return str << obj.name();
270 case CapDetail::VERSIONED:
271 return str << obj.name() << " " << obj.op() << " " << obj.ed();
273 case CapDetail::EXPRESSION:
274 switch ( obj.capRel() )
276 case CapDetail::REL_NONE:
277 case CapDetail::CAP_AND:
278 case CapDetail::CAP_OR:
279 case CapDetail::CAP_WITH:
280 return str << obj.lhs().detail() << " " << obj.capRel() << " " << obj.rhs().detail();
282 case CapDetail::CAP_NAMESPACE:
283 return str << obj.lhs().detail() << "(" << obj.rhs().detail() << ")";
287 return str << "<UnknownCap>";
290 std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj )
294 case CapDetail::NOCAP: return str << "NoCap"; break;
295 case CapDetail::NAMED: return str << "NamedCap"; break;
296 case CapDetail::VERSIONED: return str << "VersionedCap"; break;
297 case CapDetail::EXPRESSION: return str << "CapExpression"; break;
299 return str << "UnknownCap";
302 std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj )
306 case CapDetail::REL_NONE: return str << "NoCapRel"; break;
307 case CapDetail::CAP_AND: return str << "AND"; break;
308 case CapDetail::CAP_OR: return str << "OR"; break;
309 case CapDetail::CAP_WITH: return str << "WITH"; break;
310 case CapDetail::CAP_NAMESPACE: return str << "NAMESPACE"; break;
312 return str << "UnknownCapRel";
315 /////////////////////////////////////////////////////////////////
317 ///////////////////////////////////////////////////////////////////