libzypp
10.5.0
|
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ 00002 /* Helper.cc 00003 * 00004 * Static helpers 00005 * 00006 * Copyright (C) 2000-2002 Ximian, Inc. 00007 * Copyright (C) 2005 SUSE Linux Products GmbH 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License, 00011 * version 2, as published by the Free Software Foundation. 00012 * 00013 * This program is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 00021 * 02111-1307, USA. 00022 */ 00023 #include <sstream> 00024 00025 #include "zypp/solver/detail/Helper.h" 00026 #include "zypp/Capabilities.h" 00027 #include "zypp/base/Logger.h" 00028 #include "zypp/base/String.h" 00029 #include "zypp/base/Gettext.h" 00030 #include "zypp/VendorAttr.h" 00031 #include "zypp/base/Algorithm.h" 00032 #include "zypp/ResPool.h" 00033 #include "zypp/ResFilters.h" 00034 #include "zypp/RepoInfo.h" 00035 00036 using namespace std; 00037 00039 namespace zypp 00040 { 00041 00042 namespace solver 00043 { 00044 00045 namespace detail 00046 { 00047 00048 ostream & 00049 operator<< (ostream & os, const PoolItemList & itemlist) 00050 { 00051 for (PoolItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); ++iter) { 00052 if (iter != itemlist.begin()) 00053 os << ", "; 00054 os << *iter; 00055 } 00056 return os; 00057 } 00058 00059 00060 class LookFor : public resfilter::PoolItemFilterFunctor 00061 { 00062 public: 00063 PoolItem item; 00064 00065 bool operator()( PoolItem provider ) 00066 { 00067 item = provider; 00068 return false; // stop here, we found it 00069 } 00070 }; 00071 00072 00073 // just find installed item with same kind/name as item 00074 00075 template<class _Iter> 00076 static PoolItem findInstalledByNameAndKind ( _Iter begin, _Iter end, const string & name, const Resolvable::Kind & kind) 00077 { 00078 LookFor info; 00079 00080 invokeOnEach(begin, end, 00081 resfilter::ByInstalled (), // ByInstalled 00082 functor::functorRef<bool,PoolItem> (info) ); 00083 00084 _XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item); 00085 return info.item; 00086 00087 } 00088 00089 PoolItem Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind) 00090 { return detail::findInstalledByNameAndKind( pool.byIdentBegin( kind, name ), pool.byIdentEnd( kind, name ), name, kind ); } 00091 00092 PoolItem Helper::findInstalledItem (const ResPool & pool, PoolItem item) 00093 { return findInstalledByNameAndKind(pool, item->name(), item->kind() ); } 00094 00095 PoolItem Helper::findInstalledItem( const std::vector<PoolItem> & pool, PoolItem item ) 00096 { return detail::findInstalledByNameAndKind( pool.begin(), pool.end(), item->name(), item->kind() ); } 00097 00098 00099 // just find uninstalled item with same kind/name as item 00100 00101 PoolItem 00102 Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind) 00103 { 00104 LookFor info; 00105 00106 invokeOnEach( pool.byIdentBegin( kind, name ), 00107 pool.byIdentEnd( kind, name ), 00108 resfilter::ByUninstalled(), // ByUninstalled 00109 functor::functorRef<bool,PoolItem> (info) ); 00110 00111 _XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item); 00112 return info.item; 00113 } 00114 00115 00116 //---------------------------------------------------------------------------- 00117 00118 class LookForUpdate : public resfilter::PoolItemFilterFunctor 00119 { 00120 public: 00121 PoolItem uninstalled; 00122 PoolItem installed; 00123 00124 bool operator()( PoolItem provider ) 00125 { 00126 // is valid 00127 if ( ! provider.resolvable() ) 00128 { 00129 WAR << "Warning: '" << provider << "' not valid" << endl; 00130 return true; 00131 } 00132 00133 if ( installed.resolvable() ) 00134 { 00135 if ( !VendorAttr::instance().equivalent( installed, provider ) ) 00136 { 00137 MIL << "Discarding '" << provider << "' from vendor '" 00138 << provider->vendor() << "' different to uninstalled '" 00139 << installed->vendor() << "' vendor." << endl; 00140 return true; 00141 } 00142 } 00143 00144 if ((!uninstalled // none yet 00145 || (uninstalled->edition().compare( provider->edition() ) < 0) // or a better edition 00146 || (uninstalled->arch().compare( provider->arch() ) < 0) ) // or a better architecture 00147 && !provider.status().isLocked() ) // is not locked 00148 { 00149 uninstalled = provider; // store 00150 } 00151 return true; 00152 } 00153 }; 00154 00155 00156 // just find best (according to edition) uninstalled item with same kind/name as item 00157 // *DOES* check edition 00158 00159 template<class _Iter> 00160 static PoolItem findUpdateItem( _Iter begin, _Iter end, PoolItem item ) 00161 { 00162 LookForUpdate info; 00163 info.installed = item; 00164 00165 invokeOnEach( begin, end, 00166 functor::chain (resfilter::ByUninstalled (), // ByUninstalled 00167 resfilter::byEdition<CompareByGT<Edition> >( item->edition() )), // only look at better editions 00168 functor::functorRef<bool,PoolItem> (info) ); 00169 00170 _XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled); 00171 return info.uninstalled; 00172 } 00173 00174 PoolItem Helper::findUpdateItem (const ResPool & pool, PoolItem item) 00175 { return detail::findUpdateItem( pool.byIdentBegin( item ), pool.byIdentEnd( item ), item ); } 00176 00177 PoolItem Helper::findUpdateItem (const std::vector<PoolItem> & pool, PoolItem item) 00178 { return detail::findUpdateItem( pool.begin(), pool.end(), item ); } 00179 00180 00181 //---------------------------------------------------------------------------- 00182 00183 class LookForReinstall : public resfilter::PoolItemFilterFunctor 00184 { 00185 public: 00186 PoolItem uninstalled; 00187 00188 bool operator()( PoolItem provider ) 00189 { 00190 if (provider.status().isLocked()) { 00191 return true; // search next 00192 } else { 00193 uninstalled = provider; 00194 return false; // stop here, we found it 00195 } 00196 } 00197 }; 00198 00199 00200 PoolItem 00201 Helper::findReinstallItem (const ResPool & pool, PoolItem item) 00202 { 00203 LookForReinstall info; 00204 00205 invokeOnEach( pool.byIdentBegin( item ), 00206 pool.byIdentEnd( item ), 00207 functor::chain (resfilter::ByUninstalled (), // ByUninstalled 00208 resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )), 00209 functor::functorRef<bool,PoolItem> (info) ); 00210 00211 _XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled); 00212 return info.uninstalled; 00213 } 00214 00215 //---------------------------------------------------------------------------- 00216 00217 class CheckIfBest : public resfilter::PoolItemFilterFunctor 00218 { 00219 public: 00220 PoolItem _item; 00221 bool is_best; 00222 00223 CheckIfBest( PoolItem item ) 00224 : _item( item ) 00225 , is_best( true ) // assume we already have the best 00226 {} 00227 00228 // check if provider is better. If yes, end the search. 00229 00230 bool operator()( PoolItem provider ) 00231 { 00232 int archcmp = _item->arch().compare( provider->arch() ); 00233 if (((archcmp < 0) // provider has a better architecture 00234 || ((archcmp == 0) 00235 && (_item->edition().compare( provider->edition() ) < 0))) // or a better edition 00236 && !provider.status().isLocked()) // and is not locked 00237 { 00238 is_best = false; 00239 return false; 00240 } 00241 return true; 00242 } 00243 }; 00244 00245 00246 // check if the given item is the best one of the pool 00247 00248 bool 00249 Helper::isBestUninstalledItem (const ResPool & pool, PoolItem item) 00250 { 00251 CheckIfBest info( item ); 00252 00253 invokeOnEach( pool.byIdentBegin( item ), 00254 pool.byIdentEnd( item ), 00255 resfilter::ByUninstalled(), // ByUninstalled 00256 functor::functorRef<bool,PoolItem>( info ) ); 00257 00258 _XDEBUG("Helper::isBestUninstalledItem(" << item << ") => " << info.is_best); 00259 return info.is_best; 00260 } 00261 00262 std::string 00263 Helper::itemToString (PoolItem item, bool shortVersion) 00264 { 00265 ostringstream os; 00266 if (!item) return ""; 00267 00268 if (item->kind() != ResKind::package) 00269 os << item->kind() << ':'; 00270 os << item->name(); 00271 if (!shortVersion) { 00272 os << '-' << item->edition(); 00273 if (item->arch() != "") { 00274 os << '.' << item->arch(); 00275 } 00276 00277 string alias = item->repoInfo().alias(); 00278 if (!alias.empty() 00279 && alias != "@System") 00280 { 00281 os << '[' << alias << ']'; 00282 } 00283 } 00284 return os.str(); 00285 } 00286 00287 std::string 00288 Helper::capToString (const Capability & capability) 00289 { 00290 ostringstream os; 00291 os << capability.asString(); 00292 return os.str(); 00293 } 00294 00295 00297 };// namespace detail 00300 };// namespace solver 00303 };// namespace zypp 00305