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 intrusive_ptr<const capability::ModaliasCap> cap( capability::asKind<capability::ModaliasCap>(cap_r) );
00064 if ( cap && ! cap->pkgname().empty() )
00065 deps[Dep::SUPPLEMENTS].insert( CapFactory().parse( ResTraits<Package>::kind, cap->pkgname() ) );
00066
00067 deps[Dep::FRESHENS].insert(cap_r);
00068 return true;
00069 }
00070
00071 if ( isKind<capability::HalCap>(cap_r) )
00072 {
00073 deps[Dep::SUPPLEMENTS].insert( cap_r );
00074 return true;
00075 }
00076
00077 if (cap_r.index().substr( 0, 7 ) != "locale(")
00078 return false;
00079
00080 CapFactory f;
00081
00082 std::string locales( cap_r.index(), 7 );
00083 std::string::size_type pos = locales.find( ":" );
00084 if (pos != std::string::npos) {
00085 deps[Dep::SUPPLEMENTS].insert( f.parse( ResTraits<Package>::kind, std::string( locales, 0, pos ) ) );
00086 locales.erase( 0, pos+1 );
00087 }
00088 pos = 0;
00089 std::string::size_type next = pos;
00090 while (pos < locales.size()) {
00091 next = locales.find( ";", pos );
00092 if (next == std::string::npos)
00093 next = locales.size()-1;
00094
00095 std::string loc( locales, pos, next-pos );
00096 getZYpp()->availableLocale( Locale( loc ) );
00097 deps[Dep::FRESHENS].insert( f.parse( ResTraits<Language>::kind, loc ) );
00098 pos = next + 1;
00099 }
00100 return true;
00101 }
00102 };
00103
00104 void filterExtraProvides( const Dependencies & from, Dependencies & to )
00105 {
00106 CapSet provides;
00107 FilterExtraDependency flp( to );
00108
00109 std::remove_copy_if( from[Dep::PROVIDES].begin(), from[Dep::PROVIDES].end(),
00110 std::inserter( provides, provides.end() ),
00111 flp );
00112 to[Dep::PROVIDES] = provides;
00113 }
00114
00115 void filterExtraSupplements( const Dependencies & from, Dependencies & to )
00116 {
00117 CapSet supplements;
00118 to[Dep::SUPPLEMENTS].clear();
00119
00120 FilterExtraDependency flp( to );
00121
00122 std::remove_copy_if( from[Dep::SUPPLEMENTS].begin(), from[Dep::SUPPLEMENTS].end(),
00123 std::inserter( supplements, supplements.end() ),
00124 flp );
00125 to[Dep::SUPPLEMENTS].insert(supplements.begin(), supplements.end());
00126 }
00127 }
00128
00129 Resolvable::Impl::Impl( const Kind & kind_r,
00130 const NVRAD & nvrad_r )
00131 : _kind( kind_r )
00132 , _name( nvrad_r.name )
00133 , _edition( nvrad_r.edition )
00134 , _arch( nvrad_r.arch )
00135 , _deps( nvrad_r )
00136 {
00137
00138
00139 if ( _kind != ResTraits<SystemResObject>::kind ) {
00140 filterExtraSupplements( nvrad_r, _deps );
00141 filterExtraProvides( nvrad_r, _deps );
00142 }
00143
00144
00145 _deps[Dep::PROVIDES].insert( CapFactory()
00146 .parse( _kind, _name, Rel::EQ, _edition ) );
00147
00148
00149 filterUnwantedReq( nvrad_r[Dep::PREREQUIRES], _deps[Dep::PREREQUIRES] );
00150 filterUnwantedReq( nvrad_r[Dep::REQUIRES], _deps[Dep::REQUIRES] );
00151
00152
00153 _deps[Dep::REQUIRES].insert( _deps[Dep::PREREQUIRES].begin(),
00154 _deps[Dep::PREREQUIRES].end() );
00155
00156
00157 if ( _arch.empty() )
00158 dumpOn( WAR << "Has empty Arch: " ) << std::endl;
00159 }
00160
00161 std::ostream & Resolvable::Impl::dumpOn( std::ostream & str ) const
00162 {
00163 return str << '[' << kind() << ']'
00164 << name() << '-' << edition() << '.' << arch();
00165 }
00166
00168 }