1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/sat/Solvable.cc
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/Gettext.h"
16 #include "zypp/base/Exception.h"
18 #include "zypp/sat/detail/PoolImpl.h"
19 #include "zypp/sat/Solvable.h"
20 #include "zypp/sat/Repo.h"
24 ///////////////////////////////////////////////////////////////////
26 { /////////////////////////////////////////////////////////////////
27 ///////////////////////////////////////////////////////////////////
29 { /////////////////////////////////////////////////////////////////
31 const Solvable Solvable::nosolvable;
33 /////////////////////////////////////////////////////////////////
35 ::_Solvable * Solvable::get() const
36 { return myPool().getSolvable( _id ); }
38 #define NO_SOLVABLE_RETURN( VAL ) \
39 ::_Solvable * _solvable( get() ); \
40 if ( ! _solvable ) return VAL
42 Solvable Solvable::nextInPool() const
43 { return Solvable( myPool().getNextId( _id ) ); }
45 Solvable Solvable::nextInRepo() const
47 NO_SOLVABLE_RETURN( nosolvable );
48 for ( detail::SolvableIdType next = _id+1; next < unsigned(_solvable->repo->end); ++next )
50 ::_Solvable * nextS( myPool().getSolvable( next ) );
51 if ( nextS && nextS->repo == _solvable->repo )
53 return Solvable( next );
59 Repo Solvable::repo() const
61 NO_SOLVABLE_RETURN( Repo::norepo );
62 return Repo( _solvable->repo );
65 bool Solvable::isSystem() const
66 { return repo().isSystemRepo(); }
68 IdString Solvable::ident() const
70 NO_SOLVABLE_RETURN( IdString() );
71 return IdString( _solvable->name );
74 ResKind Solvable::kind() const
76 NO_SOLVABLE_RETURN( ResKind() );
77 // detect srcpackages by 'arch'
78 switch ( _solvable->arch )
82 return ResKind::srcpackage;
86 const char * ident = IdString( _solvable->name ).c_str();
87 const char * sep = ::strchr( ident, ':' );
89 // no ':' in package names (hopefully)
91 return ResKind::package;
93 // quick check for well known kinds
98 #define OUTS(K,S) if ( ::strncmp( ident, ResKind::K.c_str(), S ) ) return ResKind::K
100 case 'c': OUTS( patch, 5 ); break;
101 case 'd': OUTS( product, 7 ); break;
102 case 'e': OUTS( selection, 9 ); break;
103 case 'g': OUTS( language, 8 ); break;
104 case 'i': OUTS( script, 6 ); break;
105 case 'k': OUTS( package, 7 ); break;
106 case 'm': OUTS( atom, 4 ); break;
107 case 'p': OUTS( srcpackage, 10 ); break;
108 case 's': OUTS( message, 7 ); break;
109 case 't': OUTS( pattern, 7 ); break;
115 return ResKind( std::string( ident, sep-ident ) );
118 bool Solvable::isKind( const ResKind & kind_r ) const
120 NO_SOLVABLE_RETURN( false );
122 // detect srcpackages by 'arch'
123 if ( kind_r == ResKind::srcpackage )
125 return( _solvable->arch == ARCH_SRC || _solvable->arch == ARCH_NOSRC );
128 // no ':' in package names (hopefully)
129 const char * ident = IdString( _solvable->name ).c_str();
130 if ( kind_r == ResKind::package )
132 return( ::strchr( ident, ':' ) == 0 );
135 // look for a 'kind:' prefix
136 const char * kind = kind_r.c_str();
137 unsigned ksize = ::strlen( kind );
138 return( ::strncmp( ident, kind, ksize ) == 0
139 && ident[ksize] == ':' );
142 std::string Solvable::name() const
144 NO_SOLVABLE_RETURN( std::string() );
145 const char * ident = IdString( _solvable->name ).c_str();
146 const char * sep = ::strchr( ident, ':' );
147 return( sep ? sep+1 : ident );
150 Edition Solvable::edition() const
152 NO_SOLVABLE_RETURN( Edition() );
153 return Edition( _solvable->evr );
156 Arch Solvable::arch() const
158 NO_SOLVABLE_RETURN( Arch_noarch ); //ArchId() );
159 switch ( _solvable->arch )
163 return Arch_noarch; //ArchId( ARCH_NOARCH );
166 return Arch( IdString(_solvable->arch).asString() );
167 //return ArchId( _solvable->arch );
170 IdString Solvable::vendor() const
172 NO_SOLVABLE_RETURN( IdString() );
173 return IdString( _solvable->vendor );
176 Capabilities Solvable::operator[]( Dep which_r ) const
178 NO_SOLVABLE_RETURN( Capabilities() );
180 switch( which_r.inSwitch() )
182 case Dep::PROVIDES_e: offs = _solvable->provides; break;
183 case Dep::REQUIRES_e: offs = _solvable->requires; break;
184 case Dep::CONFLICTS_e: offs = _solvable->conflicts; break;
185 case Dep::OBSOLETES_e: offs = _solvable->obsoletes; break;
186 case Dep::RECOMMENDS_e: offs = _solvable->recommends; break;
187 case Dep::SUGGESTS_e: offs = _solvable->suggests; break;
188 case Dep::FRESHENS_e: offs = _solvable->freshens; break;
189 case Dep::ENHANCES_e: offs = _solvable->enhances; break;
190 case Dep::SUPPLEMENTS_e: offs = _solvable->supplements; break;
192 case Dep::PREREQUIRES_e:
193 // prerequires are a subset of requires
194 if ( (offs = _solvable->requires) )
195 return Capabilities( _solvable->repo->idarraydata + offs, detail::solvablePrereqMarker );
197 return Capabilities();
201 return offs ? Capabilities( _solvable->repo->idarraydata + offs )
205 /******************************************************************
207 ** FUNCTION NAME : operator<<
208 ** FUNCTION TYPE : std::ostream &
210 std::ostream & operator<<( std::ostream & str, const Solvable & obj )
213 return str << "sat::solvable()";
215 return str << "sat::solvable(" << obj.id() << "|"
216 << ( obj.isKind( ResKind::srcpackage ) ? "srcpackage:" : "" ) << obj.ident()
217 << '-' << obj.edition() << '.' << obj.arch() << "){"
218 << obj.repo().name() << "}";
221 /******************************************************************
223 ** FUNCTION NAME : dumpOn
224 ** FUNCTION TYPE : std::ostream &
226 std::ostream & dumpOn( std::ostream & str, const Solvable & obj )
231 #define OUTS(X) if ( ! obj[Dep::X].empty() ) str << endl << " " #X " " << obj[Dep::X]
247 /////////////////////////////////////////////////////////////////
249 ///////////////////////////////////////////////////////////////////
250 /////////////////////////////////////////////////////////////////
252 ///////////////////////////////////////////////////////////////////