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 /** Build \ref Capability from data. No parsing required.
38 sat::detail::IdType relFromStr( ::_Pool * pool_r,
40 const std::string & name_r,
43 const ResKind & kind_r )
45 // First build the name, non-packages prefixed by kind
46 sat::detail::IdType nid( sat::detail::noId );
47 if ( ! kind_r || kind_r == ResKind::package )
49 nid = IdString( name_r ).id();
53 nid = IdString( str::form( "%s:%s",
55 name_r.c_str() ) ).id();
59 // Extend name by architecture, if provided
60 if ( ! arch_r.empty() )
62 nid = ::rel2id( pool_r, nid, arch_r.id(), REL_ARCH, /*create*/true );
65 // Extend 'op edition', if provided
66 if ( op_r != Rel::ANY && ed_r != Edition::noedition )
68 nid = ::rel2id( pool_r, nid, ed_r.id(), op_r.bits(), /*create*/true );
74 /** Build \ref Capability from data, just parsing name for '[.arch]'.
76 sat::detail::IdType relFromStr( ::_Pool * pool_r,
77 const std::string & name_r, Rel op_r, const Edition & ed_r,
78 const ResKind & kind_r )
80 Arch arch( Arch_empty );
81 std::string name( name_r );
83 std::string::size_type asep( name_r.rfind( "." ) );
84 if ( asep != std::string::npos )
86 Arch ext( name_r.substr( asep+1 ) );
87 if ( ext.isBuiltIn() )
94 return relFromStr( pool_r, arch, name, op_r, ed_r, kind_r );
97 /** Full parse from string, unless Capability::PARSED.
99 sat::detail::IdType relFromStr( ::_Pool * pool_r,
100 const std::string & str_r, const ResKind & kind_r,
101 Capability::CtorFlag flag_r )
103 // strval_r has at least two words which could make 'op edition'?
105 static const str::regex rx( "(.*[^ \t])([ \t]+)([^ \t]+)([ \t]+)([^ \t]+)" );
106 static str::smatch what;
108 std::string name( str_r );
111 if ( flag_r == Capability::UNPARSED
112 && str_r.find(' ') != std::string::npos
113 && str::regex_match( str_r, what, rx ) )
118 Edition ced( what[5] );
123 catch ( Exception & excpt )
125 // So they don't make valid 'op edition'
126 ZYPP_CAUGHT( excpt );
127 DBG << "Trying named relation for: " << str_r << endl;
131 // not a versioned relation
133 return relFromStr( pool_r, name, op, ed, kind_r ); // parses for name[.arch]
136 /////////////////////////////////////////////////////////////////
138 ///////////////////////////////////////////////////////////////////
140 const Capability Capability::Null( STRID_NULL );
142 /////////////////////////////////////////////////////////////////
144 Capability::Capability( const char * str_r, const ResKind & prefix_r, CtorFlag flag_r )
145 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
148 Capability::Capability( const std::string & str_r, const ResKind & prefix_r, CtorFlag flag_r )
149 : _id( relFromStr( myPool().getPool(), str_r.c_str(), prefix_r, flag_r ) )
152 Capability::Capability( const char * str_r, CtorFlag flag_r, const ResKind & prefix_r )
153 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
156 Capability::Capability( const std::string & str_r, CtorFlag flag_r, const ResKind & prefix_r )
157 : _id( relFromStr( myPool().getPool(), str_r, prefix_r, flag_r ) )
160 ///////////////////////////////////////////////////////////////////
161 // Ctor from <name[.arch] op edition>.
162 ///////////////////////////////////////////////////////////////////
164 Capability::Capability( const std::string & name_r, const std::string & op_r, const std::string & ed_r, const ResKind & prefix_r )
165 : _id( relFromStr( myPool().getPool(), name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
167 Capability::Capability( const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
168 : _id( relFromStr( myPool().getPool(), name_r, op_r, Edition(ed_r), prefix_r ) )
170 Capability::Capability( const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
171 : _id( relFromStr( myPool().getPool(), name_r, op_r, ed_r, prefix_r ) )
174 ///////////////////////////////////////////////////////////////////
175 // Ctor from <arch name op edition>.
176 ///////////////////////////////////////////////////////////////////
178 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 )
179 : _id( relFromStr( myPool().getPool(), Arch(arch_r), name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
181 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
182 : _id( relFromStr( myPool().getPool(), Arch(arch_r), name_r, op_r, Edition(ed_r), prefix_r ) )
184 Capability::Capability( const std::string & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
185 : _id( relFromStr( myPool().getPool(), Arch(arch_r), name_r, op_r, ed_r, prefix_r ) )
187 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 )
188 : _id( relFromStr( myPool().getPool(), arch_r, name_r, Rel(op_r), Edition(ed_r), prefix_r ) )
190 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const std::string & ed_r, const ResKind & prefix_r )
191 : _id( relFromStr( myPool().getPool(), arch_r, name_r, op_r, Edition(ed_r), prefix_r ) )
193 Capability::Capability( const Arch & arch_r, const std::string & name_r, Rel op_r, const Edition & ed_r, const ResKind & prefix_r )
194 : _id( relFromStr( myPool().getPool(), arch_r, name_r, op_r, ed_r, prefix_r ) )
197 const char * Capability::c_str() const
198 { return( _id ? ::dep2str( myPool().getPool(), _id ) : "" ); }
200 CapMatch Capability::_doMatch( sat::detail::IdType lhs, sat::detail::IdType rhs )
202 #warning MIGRATE TO SAT
205 return CapMatch::yes;
212 case CapDetail::NOCAP:
213 return( r.kind() == CapDetail::NOCAP ); // NOCAP matches NOCAP only
215 case CapDetail::EXPRESSION:
216 return CapMatch::irrelevant;
218 case CapDetail::NAMED:
219 case CapDetail::VERSIONED:
225 case CapDetail::NOCAP:
226 return CapMatch::no; // match case handled above
228 case CapDetail::EXPRESSION:
229 return CapMatch::irrelevant;
231 case CapDetail::NAMED:
232 case CapDetail::VERSIONED:
235 // comparing two simple caps:
236 if ( l.name() != r.name() )
239 // if both are arch restricted they must match
240 if ( l.arch() != r.arch()
241 && ! ( l.arch().empty() || r.arch().empty() ) )
244 // isNamed matches ANY edition:
245 if ( l.isNamed() || r.isNamed() )
246 return CapMatch::yes;
248 // both are versioned:
249 return overlaps( Edition::MatchRange( l.op(), l.ed() ),
250 Edition::MatchRange( r.op(), r.ed() ) );
253 bool Capability::isInterestingFileSpec( const char * name_r )
255 static str::smatch what;
256 static const str::regex filenameRegex(
257 "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/",
258 str::regex::optimize|str::regex::nosubs );
260 return str::regex_match( name_r, what, filenameRegex );
263 /******************************************************************
265 ** FUNCTION NAME : operator<<
266 ** FUNCTION TYPE : std::ostream &
268 std::ostream & operator<<( std::ostream & str, const Capability & obj )
270 return str << obj.detail();
273 std::ostream & dumpOn( std::ostream & str, const Capability & obj )
275 return str << obj.detail();
278 ///////////////////////////////////////////////////////////////////
280 // CLASS NAME : CapDetail
282 ///////////////////////////////////////////////////////////////////
284 void CapDetail::_init()
286 // : _kind( NOCAP ), _lhs( id_r ), _rhs( 0 ), _flag( 0 ), _archIfSimple( 0 )
288 if ( _lhs == sat::detail::emptyId || _lhs == sat::detail::noId )
291 if ( ! ISRELDEP(_lhs) )
293 // this is name without arch!
298 ::Reldep * rd = GETRELDEP( myPool().getPool(), _lhs );
303 if ( Rel::isRel( _flag ) )
306 // Check for name.arch...
307 if ( ! ISRELDEP(_lhs) )
308 return; // this is name without arch!
309 rd = GETRELDEP( myPool().getPool(), _lhs );
310 if ( rd->flags != CAP_ARCH )
311 return; // this is not name.arch
312 // This is name.arch:
314 _archIfSimple = rd->evr;
316 else if ( rd->flags == CAP_ARCH )
319 // This is name.arch:
321 _archIfSimple = rd->evr;
330 /******************************************************************
332 ** FUNCTION NAME : operator<<
333 ** FUNCTION TYPE : std::ostream &
335 std::ostream & operator<<( std::ostream & str, const CapDetail & obj )
337 switch ( obj.kind() )
339 case CapDetail::NOCAP:
340 return str << "<NoCap>";
342 case CapDetail::NAMED:
345 str << '.' << obj.arch();
348 case CapDetail::VERSIONED:
351 str << '.' << obj.arch();
352 return str << " " << obj.op() << " " << obj.ed();
354 case CapDetail::EXPRESSION:
355 switch ( obj.capRel() )
357 case CapDetail::REL_NONE:
358 case CapDetail::CAP_AND:
359 case CapDetail::CAP_OR:
360 case CapDetail::CAP_WITH:
361 case CapDetail::CAP_ARCH:
362 return str << obj.lhs().detail() << " " << obj.capRel() << " " << obj.rhs().detail();
364 case CapDetail::CAP_NAMESPACE:
365 return str << obj.lhs().detail() << "(" << obj.rhs().detail() << ")";
369 return str << "<UnknownCap>";
372 std::ostream & operator<<( std::ostream & str, CapDetail::Kind obj )
376 case CapDetail::NOCAP: return str << "NoCap"; break;
377 case CapDetail::NAMED: return str << "NamedCap"; break;
378 case CapDetail::VERSIONED: return str << "VersionedCap"; break;
379 case CapDetail::EXPRESSION: return str << "CapExpression"; break;
381 return str << "UnknownCap";
384 std::ostream & operator<<( std::ostream & str, CapDetail::CapRel obj )
388 case CapDetail::REL_NONE: return str << "NoCapRel"; break;
389 case CapDetail::CAP_AND: return str << "&"; break; // AND
390 case CapDetail::CAP_OR: return str << "|"; break; // OR
391 case CapDetail::CAP_WITH: return str << "+"; break; // WITH
392 case CapDetail::CAP_NAMESPACE: return str << "NAMESPACE"; break;
393 case CapDetail::CAP_ARCH: return str << "ARCH"; break;
395 return str << "UnknownCapRel";
398 /////////////////////////////////////////////////////////////////
400 ///////////////////////////////////////////////////////////////////