ResolvableImpl.cc

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
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             // in case cap provides a packagename, inject a SUPPLEMENTS.
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;        // strip from provides
00069           }
00070 
00071         if ( isKind<capability::HalCap>(cap_r) )
00072           {
00073             deps[Dep::SUPPLEMENTS].insert( cap_r );
00074             return true;        // strip from provides
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 );                        // strip "locale("
00083         std::string::size_type pos = locales.find( ":" );               // colon given ?
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 );                    // look for ; separator
00092             if (next == std::string::npos)
00093                 next = locales.size()-1;                        // none left, set next to end-1 (strip trailing ')' )
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     // check if we provide/supplements any extra ('locale(...)', 'modalias(...)', ...) tags
00138     // and split them up to freshens/supplements (except for SystemResObject)
00139       if ( _kind != ResTraits<SystemResObject>::kind ) {
00140           filterExtraSupplements( nvrad_r, _deps );
00141           filterExtraProvides( nvrad_r, _deps );
00142       }
00143 
00144     // assert self provides
00145     _deps[Dep::PROVIDES].insert( CapFactory()
00146                                  .parse( _kind, _name, Rel::EQ, _edition ) );
00147 
00148     // Filter 'rpmlib(...)' requirements (refill from nvrad_r)
00149     filterUnwantedReq( nvrad_r[Dep::PREREQUIRES], _deps[Dep::PREREQUIRES] );
00150     filterUnwantedReq( nvrad_r[Dep::REQUIRES], _deps[Dep::REQUIRES] );
00151 
00152     // assert all prerequires are in requires too
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 } // namespace zypp

Generated on Mon Jun 5 19:10:32 2006 for zypp by  doxygen 1.4.6