1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/capability/CapabilityImpl.cc
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/Exception.h"
16 #include "zypp/capability/CapabilityImpl.h"
17 #include "zypp/capability/Capabilities.h"
21 ///////////////////////////////////////////////////////////////////
23 { /////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
27 IMPL_PTR_TYPE(CapabilityImpl)
29 ///////////////////////////////////////////////////////////////////
31 // METHOD NAME : CapabilityImpl::CapabilityImpl
34 CapabilityImpl::CapabilityImpl( const Resolvable::Kind & refers_r )
38 ///////////////////////////////////////////////////////////////////
40 // METHOD NAME : CapabilityImpl::capImplOrderLess
43 bool CapabilityImpl::capImplOrderLess( const constPtr & rhs ) const
45 return encode() < rhs->encode();
48 ///////////////////////////////////////////////////////////////////
50 // METHOD NAME : CapabilityImpl::capImplOrderLess
53 std::ostream & CapabilityImpl::dumpOn( std::ostream & str ) const
55 return str << '[' << refers() << "] "
56 << '(' << kind() << ") "
60 /** Assert a valid Resolvable::Kind. */
61 static void assertResKind( const Resolvable::Kind & refers_r )
63 if ( refers_r == Resolvable::Kind() )
64 ZYPP_THROW( Exception("Missing or empty Resolvable::Kind in Capability") );
67 bool isEditionSpec( Rel op_r, const Edition & edition_r )
69 switch ( op_r.inSwitch() )
72 if ( edition_r != Edition::noedition )
73 WAR << "Operator " << op_r << " causes Edition "
74 << edition_r << " to be ignored." << endl;
79 ZYPP_THROW( Exception("Operator NONE is not allowed in Capability") );
91 // SHOULD NOT GET HERE
92 ZYPP_THROW( Exception("Unknown Operator NONE is not allowed in Capability") );
93 return false; // not reached
96 bool isFileSpec( const std::string & name_r )
98 return *name_r.c_str() == '/';
101 bool isSplitSpec( const std::string & name_r )
103 return name_r.find( ":/" ) != std::string::npos;
106 bool isHalSpec( const std::string & name_r )
108 return name_r.substr(0,4) == "hal(";
111 bool isModaliasSpec( const std::string & name_r )
113 return name_r.substr(0,9) == "modalias(";
116 bool isFilesystemSpec( const std::string & name_r )
118 return name_r.substr(0,11) == "filesystem(";
121 CapabilityImpl::Ptr buildFile( const Resolvable::Kind & refers_r,
122 const std::string & name_r )
124 // NullCap check first:
125 if ( name_r.empty() )
127 // Singleton, so no need to put it into _uset !?
128 return capability::NullCap::instance();
131 assertResKind( refers_r );
133 return new capability::FileCap( refers_r, name_r );
136 CapabilityImpl::Ptr buildNamed( const Resolvable::Kind & refers_r,
137 const std::string & name_r )
139 // NullCap check first:
140 if ( name_r.empty() )
142 // Singleton, so no need to put it into _uset !?
143 return capability::NullCap::instance();
146 assertResKind( refers_r );
148 // file: /absolute/path
149 if ( isFileSpec( name_r ) )
151 return new capability::FileCap( refers_r, name_r );
153 if ( isFilesystemSpec( name_r ) )
155 return buildFilesystem( refers_r, name_r );
158 //split: name:/absolute/path
159 static const str::regex rx( "([^/]*):(/.*)" );
161 if( str::regex_match( name_r.begin(), name_r.end(), what, rx ) )
163 return new capability::SplitCap( refers_r, what[1].str(), what[2].str() );
167 return new capability::NamedCap( refers_r, name_r );
170 CapabilityImpl::Ptr buildVersioned( const Resolvable::Kind & refers_r,
171 const std::string & name_r,
173 const Edition & edition_r )
175 if ( isEditionSpec( op_r, edition_r ) )
177 assertResKind( refers_r );
179 // build a VersionedCap
180 return new capability::VersionedCap( refers_r, name_r, op_r, edition_r );
185 return buildNamed( refers_r, name_r );
188 CapabilityImpl::Ptr buildHal( const Resolvable::Kind & refers_r,
189 const std::string & name_r,
191 const std::string & value_r )
193 if ( op_r != Rel::ANY )
195 ZYPP_THROW( Exception("Unsupported kind of Hal Capability '" + op_r.asString() + "'") );
198 //split: hal(name) [op string]
199 static const str::regex rx( "hal\\(([^)]*)\\)" );
201 if( str::regex_match( name_r.begin(), name_r.end(), what, rx ) )
203 // Hal always refers to 'System' kind of Resolvable.
204 return new capability::HalCap( ResTraits<SystemResObject>::kind,
208 ZYPP_THROW( Exception("Unsupported kind of Hal Capability '" + name_r + "'") );
209 return NULL; // make gcc happy
212 CapabilityImpl::Ptr buildModalias( const Resolvable::Kind & refers_r,
213 const std::string & name_r,
215 const std::string & value_r )
217 if ( op_r != Rel::ANY )
219 ZYPP_THROW( Exception("Unsupported kind of Modalias Capability '" + op_r.asString() + "'") );
222 //split: modalias(name) [op string]
223 static const str::regex rx( "modalias\\(([^)]*)\\)" );
225 if( str::regex_match( name_r.begin(), name_r.end(), what, rx ) )
227 // Modalias always refers to 'System' kind of Resolvable
228 return new capability::ModaliasCap( ResTraits<SystemResObject>::kind,
232 ZYPP_THROW( Exception("Unsupported kind of Modalias Capability'" + name_r + "'") );
233 return NULL; // make gcc happy
236 /******************************************************************
238 ** FUNCTION NAME : buildFilesystem
239 ** FUNCTION TYPE : CapabilityImpl::Ptr
241 CapabilityImpl::Ptr buildFilesystem( const Resolvable::Kind & refers_r,
242 const std::string & name_r )
244 //split: filesystem(name) [op string]
245 static const str::regex rx( "filesystem\\(([^)]*)\\)" );
247 if( str::regex_match( name_r.begin(), name_r.end(), what, rx ) )
249 // Filesystem always refers to 'System' kind of Resolvable
250 return new capability::FilesystemCap( ResTraits<SystemResObject>::kind,
254 ZYPP_THROW( Exception("Unsupported kind of Filesystem Capability'" + name_r + "'") );
255 return NULL; // make gcc happy
259 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
260 const std::string & strval_r )
263 if ( isHalSpec( strval_r ) )
265 return buildHal( refers_r, strval_r );
267 if ( isModaliasSpec( strval_r ) )
269 return buildModalias( refers_r, strval_r );
271 if ( isFilesystemSpec( strval_r ) )
273 return buildFilesystem( refers_r, strval_r );
275 if ( isFileSpec( strval_r ) )
277 return buildFile( refers_r, strval_r );
280 // strval_r has at least two words which could make 'op edition'?
282 static const str::regex rx( "(.*[^ \t])([ \t]+)([^ \t]+)([ \t]+)([^ \t]+)" );
284 if( str::regex_match( strval_r.begin(), strval_r.end(),what, rx ) )
290 op = Rel(what[3].str());
291 edition = Edition(what[5].str());
293 catch ( Exception & excpt )
295 // So they don't make valid 'op edition'
296 ZYPP_CAUGHT( excpt );
297 DBG << "Trying named cap for: " << strval_r << endl;
298 // See whether it makes a named cap.
299 return buildNamed( refers_r, strval_r );
302 // Valid 'op edition'
303 return buildVersioned( refers_r,
304 what[1].str(), op, edition );
307 // not a VersionedCap
308 return buildNamed( refers_r, strval_r );
310 catch ( Exception & excpt )
312 ZYPP_RETHROW( excpt );
313 return NULL; // not reached
317 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
318 const std::string & name_r,
319 const std::string & op_r,
320 const std::string & edition_r )
323 if ( isHalSpec( name_r ) )
325 return buildHal( refers_r, name_r, Rel(op_r), edition_r );
327 if ( isModaliasSpec( name_r ) )
329 return buildModalias( refers_r, name_r, Rel(op_r), edition_r );
331 // Try creating Rel and Edition, then parse
332 return parse( refers_r, name_r, Rel(op_r), Edition(edition_r) );
334 catch ( Exception & excpt )
336 ZYPP_RETHROW( excpt );
337 return NULL; // not reached
340 ///////////////////////////////////////////////////////////////////
342 // METHOD NAME : CapFactory::parse
343 // METHOD TYPE : Capability
345 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
346 const std::string & name_r,
348 const Edition & edition_r )
351 if ( isHalSpec( name_r ) )
353 return buildHal( refers_r, name_r, op_r, edition_r.asString() );
355 if ( isModaliasSpec( name_r ) )
357 return buildModalias( refers_r, name_r, op_r, edition_r.asString() );
359 return buildVersioned( refers_r, name_r, op_r, edition_r );
361 catch ( Exception & excpt )
363 ZYPP_RETHROW( excpt );
364 return NULL; // not reached
367 ///////////////////////////////////////////////////////////////////
369 /////////////////////////////////////////////////////////////////
370 } // namespace capability
371 ///////////////////////////////////////////////////////////////////
372 /////////////////////////////////////////////////////////////////
374 ///////////////////////////////////////////////////////////////////