1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
6 * Copyright (C) 2000-2002 Ximian, Inc.
7 * Copyright (C) 2005 SUSE Linux Products GmbH
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 #include "zypp/solver/detail/Helper.h"
26 #include "zypp/Capabilities.h"
27 #include "zypp/base/Logger.h"
28 #include "zypp/base/String.h"
29 #include "zypp/base/Gettext.h"
30 #include "zypp/VendorAttr.h"
31 #include "zypp/base/Algorithm.h"
32 #include "zypp/ResPool.h"
33 #include "zypp/ResFilters.h"
34 #include "zypp/RepoInfo.h"
38 /////////////////////////////////////////////////////////////////////////
40 { ///////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////
43 { /////////////////////////////////////////////////////////////////////
44 /////////////////////////////////////////////////////////////////////
46 { ///////////////////////////////////////////////////////////////////
49 operator<< (ostream & os, const PoolItemList & itemlist)
51 for (PoolItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
52 if (iter != itemlist.begin())
60 class LookFor : public resfilter::PoolItemFilterFunctor
65 bool operator()( PoolItem provider )
68 return false; // stop here, we found it
73 // just find installed item with same kind/name as item
76 static PoolItem findInstalledByNameAndKind ( _Iter begin, _Iter end, const string & name, const Resolvable::Kind & kind)
80 invokeOnEach(begin, end,
81 resfilter::ByInstalled (), // ByInstalled
82 functor::functorRef<bool,PoolItem> (info) );
84 _XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
89 PoolItem Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
90 { return detail::findInstalledByNameAndKind( pool.byIdentBegin( kind, name ), pool.byIdentEnd( kind, name ), name, kind ); }
92 PoolItem Helper::findInstalledItem (const ResPool & pool, PoolItem item)
93 { return findInstalledByNameAndKind(pool, item->name(), item->kind() ); }
95 PoolItem Helper::findInstalledItem( const std::vector<PoolItem> & pool, PoolItem item )
96 { return detail::findInstalledByNameAndKind( pool.begin(), pool.end(), item->name(), item->kind() ); }
99 // just find uninstalled item with same kind/name as item
102 Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
106 invokeOnEach( pool.byIdentBegin( kind, name ),
107 pool.byIdentEnd( kind, name ),
108 resfilter::ByUninstalled(), // ByUninstalled
109 functor::functorRef<bool,PoolItem> (info) );
111 _XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
116 //----------------------------------------------------------------------------
118 class LookForUpdate : public resfilter::PoolItemFilterFunctor
121 PoolItem uninstalled;
124 bool operator()( PoolItem provider )
127 if ( ! provider.resolvable() )
129 WAR << "Warning: '" << provider << "' not valid" << endl;
133 if ( installed.resolvable() )
135 if ( !VendorAttr::instance().equivalent(installed->vendor(),provider->vendor()) )
137 MIL << "Discarding '" << provider << "' from vendor '"
138 << provider->vendor() << "' different to uninstalled '"
139 << installed->vendor() << "' vendor." << endl;
144 if ((!uninstalled // none yet
145 || (uninstalled->edition().compare( provider->edition() ) < 0) // or a better edition
146 || (uninstalled->arch().compare( provider->arch() ) < 0) ) // or a better architecture
147 && !provider.status().isLocked() ) // is not locked
149 uninstalled = provider; // store
156 // just find best (according to edition) uninstalled item with same kind/name as item
157 // *DOES* check edition
159 template<class _Iter>
160 static PoolItem findUpdateItem( _Iter begin, _Iter end, PoolItem item )
163 info.installed = item;
165 invokeOnEach( begin, end,
166 functor::chain (resfilter::ByUninstalled (), // ByUninstalled
167 resfilter::byEdition<CompareByGT<Edition> >( item->edition() )), // only look at better editions
168 functor::functorRef<bool,PoolItem> (info) );
170 _XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled);
171 return info.uninstalled;
174 PoolItem Helper::findUpdateItem (const ResPool & pool, PoolItem item)
175 { return detail::findUpdateItem( pool.byIdentBegin( item ), pool.byIdentEnd( item ), item ); }
177 PoolItem Helper::findUpdateItem (const std::vector<PoolItem> & pool, PoolItem item)
178 { return detail::findUpdateItem( pool.begin(), pool.end(), item ); }
181 //----------------------------------------------------------------------------
183 class LookForReinstall : public resfilter::PoolItemFilterFunctor
186 PoolItem uninstalled;
188 bool operator()( PoolItem provider )
190 if (provider.status().isLocked()) {
191 return true; // search next
193 uninstalled = provider;
194 return false; // stop here, we found it
201 Helper::findReinstallItem (const ResPool & pool, PoolItem item)
203 LookForReinstall info;
205 invokeOnEach( pool.byIdentBegin( item ),
206 pool.byIdentEnd( item ),
207 functor::chain (resfilter::ByUninstalled (), // ByUninstalled
208 resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )),
209 functor::functorRef<bool,PoolItem> (info) );
211 _XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled);
212 return info.uninstalled;
215 //----------------------------------------------------------------------------
217 class CheckIfBest : public resfilter::PoolItemFilterFunctor
223 CheckIfBest( PoolItem item )
225 , is_best( true ) // assume we already have the best
228 // check if provider is better. If yes, end the search.
230 bool operator()( PoolItem provider )
232 int archcmp = _item->arch().compare( provider->arch() );
233 if (((archcmp < 0) // provider has a better architecture
235 && (_item->edition().compare( provider->edition() ) < 0))) // or a better edition
236 && !provider.status().isLocked()) // and is not locked
246 // check if the given item is the best one of the pool
249 Helper::isBestUninstalledItem (const ResPool & pool, PoolItem item)
251 CheckIfBest info( item );
253 invokeOnEach( pool.byIdentBegin( item ),
254 pool.byIdentEnd( item ),
255 resfilter::ByUninstalled(), // ByUninstalled
256 functor::functorRef<bool,PoolItem>( info ) );
258 _XDEBUG("Helper::isBestUninstalledItem(" << item << ") => " << info.is_best);
263 Helper::itemToString (PoolItem item, bool shortVersion)
266 if (!item) return "";
268 if (item->kind() != ResKind::package)
269 os << item->kind() << ':';
272 os << '-' << item->edition();
273 if (item->arch() != "") {
274 os << '.' << item->arch();
277 string alias = item->repoInfo().alias();
279 && alias != "@System")
281 os << '[' << alias << ']';
288 Helper::capToString (const Capability & capability)
291 os << capability.asString();
296 ///////////////////////////////////////////////////////////////////
297 };// namespace detail
298 /////////////////////////////////////////////////////////////////////
299 /////////////////////////////////////////////////////////////////////
300 };// namespace solver
301 ///////////////////////////////////////////////////////////////////////
302 ///////////////////////////////////////////////////////////////////////
304 /////////////////////////////////////////////////////////////////////////