00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014
00015 #include "zypp/ZYpp.h"
00016 #include "zypp/ZYppFactory.h"
00017
00018 #include "zypp/base/Algorithm.h"
00019 #include "zypp/detail/ResolvableImpl.h"
00020 #include "zypp/capability/CapabilityImpl.h"
00021 #include "zypp/capability/Capabilities.h"
00022
00023 using std::endl;
00024
00026 namespace zypp
00027 {
00028
00029 namespace
00030 {
00031 struct FilterUnwantedReq
00032 {
00033 bool operator()( const Capability & cap_r ) const
00034 {
00035 return cap_r.index().substr( 0, 7 ) == "rpmlib(";
00036 }
00037 };
00038
00039 void filterUnwantedReq( const CapSet & from, CapSet & to )
00040 {
00041 to.clear();
00042 std::remove_copy_if( from.begin(), from.end(),
00043 std::inserter( to, to.end() ),
00044 FilterUnwantedReq() );
00045 }
00046 }
00047
00048 namespace
00049 {
00050 struct FilterExtraDependency
00051 {
00052 Dependencies & deps;
00053
00054 FilterExtraDependency( Dependencies & d )
00055 : deps( d )
00056 { }
00057
00058 bool operator()( const Capability & cap_r ) const
00059 {
00060 if ( isKind<capability::ModaliasCap>(cap_r) )
00061 {
00062
00063
00064
00065 intrusive_ptr<const capability::ModaliasCap> cap( capability::asKind<capability::ModaliasCap>(cap_r) );
00066 if ( cap ) {
00067 std::string pkgname( cap->pkgname() );
00068 if ( pkgname.empty() ) {
00069 pkgname = "kernel";
00070 }
00071 deps[Dep::SUPPLEMENTS].insert( CapFactory().parse( ResTraits<Package>::kind, pkgname ) );
00072 deps[Dep::FRESHENS].insert(cap_r);
00073 }
00074 return true;
00075 }
00076
00077 if ( isKind<capability::HalCap>(cap_r) )
00078 {
00079 deps[Dep::SUPPLEMENTS].insert( cap_r );
00080 return true;
00081 }
00082
00083 if (cap_r.index().substr( 0, 7 ) != "locale(")
00084 return false;
00085
00086 CapFactory f;
00087
00088 std::string locales( cap_r.index(), 7 );
00089 std::string::size_type pos = locales.find( ":" );
00090 if (pos != std::string::npos) {
00091 deps[Dep::SUPPLEMENTS].insert( f.parse( ResTraits<Package>::kind, std::string( locales, 0, pos ) ) );
00092 locales.erase( 0, pos+1 );
00093 }
00094 pos = 0;
00095 std::string::size_type next = pos;
00096 while (pos < locales.size()) {
00097 next = locales.find( ";", pos );
00098 if (next == std::string::npos)
00099 next = locales.size()-1;
00100
00101 std::string loc( locales, pos, next-pos );
00102 getZYpp()->availableLocale( Locale( loc ) );
00103 deps[Dep::FRESHENS].insert( f.parse( ResTraits<Language>::kind, loc ) );
00104 pos = next + 1;
00105 }
00106 return true;
00107 }
00108 };
00109
00110 void filterExtraProvides( const Dependencies & from, Dependencies & to )
00111 {
00112 CapSet provides;
00113 FilterExtraDependency flp( to );
00114
00115 std::remove_copy_if( from[Dep::PROVIDES].begin(), from[Dep::PROVIDES].end(),
00116 std::inserter( provides, provides.end() ),
00117 flp );
00118 to[Dep::PROVIDES] = provides;
00119 }
00120
00121 void filterExtraSupplements( const Dependencies & from, Dependencies & to )
00122 {
00123 CapSet supplements;
00124 to[Dep::SUPPLEMENTS].clear();
00125
00126 FilterExtraDependency flp( to );
00127
00128 std::remove_copy_if( from[Dep::SUPPLEMENTS].begin(), from[Dep::SUPPLEMENTS].end(),
00129 std::inserter( supplements, supplements.end() ),
00130 flp );
00131 to[Dep::SUPPLEMENTS].insert(supplements.begin(), supplements.end());
00132 }
00133 }
00134
00136
00137
00138
00139
00140 Resolvable::Impl::Impl( const Kind & kind_r,
00141 const NVRAD & nvrad_r )
00142 : _kind( kind_r )
00143 , _name( nvrad_r.name )
00144 , _edition( nvrad_r.edition )
00145 , _arch( nvrad_r.arch )
00146 , _deps( nvrad_r )
00147 {
00148
00149
00150 if ( _kind != ResTraits<SystemResObject>::kind )
00151 {
00152 filterExtraSupplements( nvrad_r, _deps );
00153 filterExtraProvides( nvrad_r, _deps );
00154 }
00155
00156
00157 CapSet::iterator it = _deps[Dep::PROVIDES].find( CapFactory().parse( _kind, _name ) );
00158 if ( it != _deps[Dep::PROVIDES].end() )
00159 {
00160 dumpOn( WAR << "Strip self provides without edition in " ) << endl;
00161 _deps[Dep::PROVIDES].erase( it );
00162 }
00163
00164
00165 _deps[Dep::PROVIDES].insert( CapFactory()
00166 .parse( _kind, _name, Rel::EQ, _edition ) );
00167
00168
00169 filterUnwantedReq( nvrad_r[Dep::PREREQUIRES], _deps[Dep::PREREQUIRES] );
00170 filterUnwantedReq( nvrad_r[Dep::REQUIRES], _deps[Dep::REQUIRES] );
00171
00172
00173 _deps[Dep::REQUIRES].insert( _deps[Dep::PREREQUIRES].begin(),
00174 _deps[Dep::PREREQUIRES].end() );
00175
00176
00177 if ( _arch.empty() )
00178 dumpOn( WAR << "Has empty Arch: " ) << std::endl;
00179 }
00180
00181 std::ostream & Resolvable::Impl::dumpOn( std::ostream & str ) const
00182 {
00183 return str << '[' << kind() << ']'
00184 << name() << '-' << edition() << '.' << arch();
00185 }
00186
00188 }