00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013
00014
00015 #include "zypp/ui/PatternExpander.h"
00016
00017 #include "zypp/base/Algorithm.h"
00018 #include "zypp/base/Function.h"
00019 #include "zypp/ResPool.h"
00020 #include "zypp/CapMatchHelper.h"
00021
00022 using std::endl;
00023
00025 namespace zypp
00026 {
00027
00028 namespace ui
00029 {
00030
00032
00033
00034
00036 class PatternExpander::Impl
00037 {
00038 public:
00039 Impl( const ResPool & pool_r )
00040 : _pool( pool_r )
00041 {}
00042
00044 size_type doExpand( Pattern::constPtr pat_r )
00045 {
00046
00047 _patternMap.clear();
00048 if ( pat_r )
00049 {
00050 _patternMap[pat_r];
00051 Pattern::constPtr unprocessed( pat_r );
00052
00053 do {
00054 expandIncludes( unprocessed );
00055 expandExtending( unprocessed );
00056 _patternMap[unprocessed] = true;
00057
00058 } while( (unprocessed = nextUnprocessed()) );
00059 }
00060
00061 return _patternMap.size();
00062 }
00063
00064 const PatternMap & patternMap() const
00065 { return _patternMap; }
00066
00067 private:
00069 Pattern::constPtr nextUnprocessed() const
00070 {
00071 for ( PatternMap::const_iterator it = _patternMap.begin(); it != _patternMap.end(); ++it )
00072 {
00073 if ( ! it->second )
00074 return it->first;
00075 }
00076 return NULL;
00077 }
00078
00079 private:
00081 void expandIncludes( const Pattern::constPtr & pat_r )
00082 {
00083 if ( ! pat_r->includes().empty() )
00084 {
00085 for_each( pat_r->includes().begin(),
00086 pat_r->includes().end(),
00087 bind( &Impl::expandInclude, this, _1 ) );
00088 }
00089 }
00090
00092 void expandInclude( const Capability & include_r )
00093 {
00094 forEachMatchIn( _pool, Dep::PROVIDES, include_r,
00095 bind( &Impl::storeIncludeMatch, this, _1 ) );
00096 }
00097
00099 bool storeIncludeMatch( const CapAndItem & capitem_r )
00100 {
00101 _patternMap[asKind<Pattern>(capitem_r.item)];
00102
00103 return true;
00104 }
00105
00106 private:
00108 void expandExtending( const Pattern::constPtr & pat_r )
00109 {
00110 for_each( _pool.byKindBegin<Pattern>(),
00111 _pool.byKindEnd<Pattern>(),
00112 bind( &Impl::expandIfExtends, this, pat_r, _1 ) );
00113 }
00114
00116 void expandIfExtends( const Pattern::constPtr & pat_r, const PoolItem & extending_r )
00117 {
00118 Pattern::constPtr extending( asKind<Pattern>(extending_r) );
00119
00120 if ( ! extending->extends().empty() )
00121 {
00122 if ( find_if( extending->extends().begin(),
00123 extending->extends().end(),
00124 bind( &Impl::providedBy, this, pat_r, _1 ) )
00125 != extending->extends().end() )
00126 {
00127
00128 _patternMap[extending];
00129
00130 }
00131 }
00132 }
00133
00135 bool providedBy( const Pattern::constPtr & pat_r, const Capability & extends_r )
00136 {
00137 std::string index( extends_r.index() );
00138 return( find_if( _pool.byCapabilityIndexBegin( index, Dep::PROVIDES ),
00139 _pool.byCapabilityIndexEnd( index, Dep::PROVIDES ),
00140 bind( &Impl::providedByFilter, this, pat_r, extends_r, _1 ) )
00141 != _pool.byCapabilityIndexEnd( index, Dep::PROVIDES ) );
00142 }
00143
00145 bool providedByFilter( const Pattern::constPtr & pat_r, const Capability & extends_r,
00146 const CapAndItem & capitem_r ) const
00147 {
00148 return( capitem_r.item == pat_r
00149 && extends_r.matches( capitem_r.cap ) == CapMatch::yes );
00150 }
00151
00152 private:
00153 ResPool _pool;
00154 PatternMap _patternMap;
00155 };
00157
00159
00160
00161
00163
00165
00166
00167
00168
00169 PatternExpander::PatternExpander( const ResPool & pool_r )
00170 : _pimpl( new Impl( pool_r ) )
00171 {}
00172
00173 PatternExpander::size_type PatternExpander::expand( const Pattern::constPtr & pat_r )
00174 { return _pimpl->doExpand( pat_r ); }
00175
00176 PatternExpander::size_type PatternExpander::size() const
00177 { return _pimpl->patternMap().size(); }
00178
00179 bool PatternExpander::empty() const
00180 { return _pimpl->patternMap().empty(); }
00181
00182 PatternExpander::const_iterator PatternExpander::begin() const
00183 { return make_map_key_begin( _pimpl->patternMap() ); }
00184
00185 PatternExpander::const_iterator PatternExpander::end() const
00186 { return make_map_key_end( _pimpl->patternMap() ); }
00187
00189 }
00192 }