00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <string>
00014 #include <map>
00015 #include "zypp/base/Logger.h"
00016
00017 #include "zypp/ZYpp.h"
00018 #include "zypp/ZYppFactory.h"
00019
00020 #include "zypp/base/Algorithm.h"
00021 #include "zypp/base/Sysconfig.h"
00022 #include "zypp/detail/ResolvableImpl.h"
00023 #include "zypp/capability/CapabilityImpl.h"
00024 #include "zypp/capability/Capabilities.h"
00025
00026 using std::endl;
00027
00029 namespace zypp
00030 {
00031
00032 namespace
00033 {
00034 struct FilterUnwantedReq
00035 {
00036 bool operator()( const Capability & cap_r ) const
00037 {
00038 return cap_r.index().substr( 0, 7 ) == "rpmlib(";
00039 }
00040 };
00041
00042 void filterUnwantedReq( const CapSet & from, CapSet & to )
00043 {
00044 to.clear();
00045 std::remove_copy_if( from.begin(), from.end(),
00046 std::inserter( to, to.end() ),
00047 FilterUnwantedReq() );
00048 }
00049 }
00050
00051 namespace
00052 {
00053 struct FilterExtraDependency
00054 {
00055 Dependencies & deps;
00056 CapSet & languages;
00057
00058 FilterExtraDependency( Dependencies & d , CapSet & l)
00059 : deps( d ),
00060 languages( l )
00061 { }
00062
00063 bool operator()( const Capability & cap_r ) const
00064 {
00065 if ( isKind<capability::ModaliasCap>(cap_r) )
00066 {
00067
00068
00069
00070 intrusive_ptr<const capability::ModaliasCap> cap( capability::asKind<capability::ModaliasCap>(cap_r) );
00071 if ( cap ) {
00072 std::string pkgname( cap->pkgname() );
00073 if ( pkgname.empty() ) {
00074 pkgname = "kernel";
00075 }
00076 deps[Dep::SUPPLEMENTS].insert( CapFactory().parse( ResTraits<Package>::kind, pkgname ) );
00077 deps[Dep::FRESHENS].insert(cap_r);
00078 }
00079 return true;
00080 }
00081
00082 if ( isKind<capability::HalCap>(cap_r) )
00083 {
00084 deps[Dep::SUPPLEMENTS].insert( cap_r );
00085 return true;
00086 }
00087
00088 std::string capString = cap_r.index();
00089
00090 if (capString.substr( 0, 11 ) == "packageand(") {
00091
00092
00093
00094 if (capString[capString.size()-1] == ')') {
00095 CapFactory f;
00096 std::string andDep( capString, 11 );
00097 std::string::size_type pos = andDep.find( ":" );
00098 if (pos != std::string::npos) {
00099 deps[Dep::SUPPLEMENTS].insert( f.parse( ResTraits<Package>::kind, std::string( andDep, 0, pos ) ) );
00100 pos++;
00101 std::string depString( andDep, pos, andDep.size()-pos-1 );
00102 deps[Dep::FRESHENS].insert( f.parse( ResTraits<Package>::kind, depString ) );
00103 } else {
00104 ERR << "wrong dependency (missing \":\") : " << capString <<endl;
00105 }
00106 } else {
00107 ERR << "wrong dependency (missing \")\"): " << capString <<endl;
00108 }
00109 return true;
00110 }
00111
00112 if (capString.substr( 0, 7 ) != "locale(")
00113 return false;
00114
00115 CapFactory f;
00116
00117 std::string locales( capString, 7 );
00118 std::string::size_type pos = locales.find( ":" );
00119 if (pos != std::string::npos) {
00120 deps[Dep::SUPPLEMENTS].insert( f.parse( ResTraits<Package>::kind, std::string( locales, 0, pos ) ) );
00121 locales.erase( 0, pos+1 );
00122 }
00123 pos = 0;
00124 std::string::size_type next = pos;
00125 while (pos < locales.size()) {
00126 next = locales.find( ";", pos );
00127 if (next == std::string::npos)
00128 next = locales.size()-1;
00129
00130 std::string loc( locales, pos, next-pos );
00131 getZYpp()->availableLocale( Locale( loc ) );
00132 deps[Dep::FRESHENS].insert( f.parse( ResTraits<Language>::kind, loc ) );
00133 languages.insert( f.parse( ResTraits<Language>::kind, loc ) );
00134 pos = next + 1;
00135 }
00136 return true;
00137 }
00138 };
00139
00140 void filterExtraProvides( const Dependencies & from, Dependencies & to )
00141 {
00142 CapSet provides;
00143 CapSet languages;
00144
00145 FilterExtraDependency flp( to, languages );
00146
00147 std::remove_copy_if( from[Dep::PROVIDES].begin(), from[Dep::PROVIDES].end(),
00148 std::inserter( provides, provides.end() ),
00149 flp );
00150 to[Dep::PROVIDES] = provides;
00151
00152
00153
00154
00155 if (languages.size() > 0
00156 && to[Dep::SUPPLEMENTS].size() == 0) {
00157 to[Dep::SUPPLEMENTS] = languages;
00158 }
00159 }
00160
00161 void filterExtraSupplements( const Dependencies & from, Dependencies & to )
00162 {
00163 CapSet supplements;
00164 CapSet dummy;
00165 to[Dep::SUPPLEMENTS].clear();
00166
00167 FilterExtraDependency flp( to, dummy );
00168
00169 std::remove_copy_if( from[Dep::SUPPLEMENTS].begin(), from[Dep::SUPPLEMENTS].end(),
00170 std::inserter( supplements, supplements.end() ),
00171 flp );
00172 to[Dep::SUPPLEMENTS].insert(supplements.begin(), supplements.end());
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 std::string findKernelFlavor( const CapSet & cset, const Dep & dep )
00187 {
00188 for (CapSet::iterator it = cset.begin(); it != cset.end(); ++it) {
00189
00190
00191
00192
00193
00194
00195
00196 if ( it->index().substr( 0, 7 ) == "kernel-"
00197 && (dep == Dep::REQUIRES
00198 || it->edition() != Edition::noedition ) )
00199 {
00200 return it->index().erase( 0, 7 );
00201 }
00202 }
00203 return "";
00204 }
00205
00206 void rewriteKernelDeps( Dependencies & deps )
00207 {
00208
00209 Dep dep = Dep::REQUIRES;
00210 CapSet cset = deps[dep];
00211 std::string flavor( findKernelFlavor( cset, dep ) );
00212 if (flavor.empty()) {
00213 dep = Dep::PROVIDES;
00214 cset = deps[dep];
00215 flavor = findKernelFlavor( cset, dep );
00216 }
00217
00218 if (flavor.empty())
00219 return;
00220
00221
00222
00223
00224
00225 flavor.append( ":" );
00226 CapFactory factory;
00227 deps[dep].clear();
00228 for (CapSet::iterator it = cset.begin(); it != cset.end(); ++it) {
00229 std::string idx( it->index() );
00230 if ( idx.substr( 0, 7 ) == "kernel("
00231 && idx.find( ":" ) == std::string::npos )
00232 {
00233 deps[dep].insert( factory.parse( it->refers(), idx.insert( 7, flavor ), it->op(), it->edition() ) );
00234 }
00235 else {
00236 deps[dep].insert( *it );
00237 }
00238 }
00239 return;
00240 }
00241
00242 }
00243
00245
00246
00247
00248
00249 Resolvable::Impl::Impl( const Kind & kind_r,
00250 const NVRAD & nvrad_r )
00251 : _kind( kind_r )
00252 , _name( nvrad_r.name )
00253 , _edition( nvrad_r.edition )
00254 , _arch( nvrad_r.arch )
00255 , _deps( nvrad_r )
00256 {
00257
00258
00259 if ( _kind != ResTraits<SystemResObject>::kind )
00260 {
00261 filterExtraSupplements( nvrad_r, _deps );
00262 filterExtraProvides( nvrad_r, _deps );
00263 }
00264
00265
00266 CapSet::iterator it = _deps[Dep::PROVIDES].find( CapFactory().parse( _kind, _name ) );
00267 if ( it != _deps[Dep::PROVIDES].end() )
00268 {
00269 dumpOn( WAR << "Strip self provides without edition in " ) << endl;
00270 _deps[Dep::PROVIDES].erase( it );
00271 }
00272
00273
00274 _deps[Dep::PROVIDES].insert( CapFactory()
00275 .parse( _kind, _name, Rel::EQ, _edition ) );
00276
00277
00278 filterUnwantedReq( nvrad_r[Dep::PREREQUIRES], _deps[Dep::PREREQUIRES] );
00279 filterUnwantedReq( nvrad_r[Dep::REQUIRES], _deps[Dep::REQUIRES] );
00280
00281
00282 if ( _kind == ResTraits<Package>::kind )
00283 {
00284 rewriteKernelDeps( _deps );
00285 }
00286
00287
00288 _deps[Dep::REQUIRES].insert( _deps[Dep::PREREQUIRES].begin(),
00289 _deps[Dep::PREREQUIRES].end() );
00290
00291 if ( _arch.empty() )
00292 dumpOn( WAR << "Has empty Arch: " ) << std::endl;
00293 }
00294
00295 std::ostream & Resolvable::Impl::dumpOn( std::ostream & str ) const
00296 {
00297 return str << '[' << kind() << ']'
00298 << name() << '-' << edition() << '.' << arch();
00299 }
00300
00302 }