*/
#include <iostream>
#include <set>
-#include <sys/utsname.h>
#include "zypp/Arch.h"
#undef DEF_BUILTIN
- static const string system_arch (void);
static const string canonical_arch (const string & arch);
-
- const Arch Arch::System = Arch(system_arch ());
-
//---------------------------------------------------------------------------
// architecture stuff
static canonical canonical_archs[] = {
{ "noarch", "noarch" },
{ "unknown", "unknown" },
- { "any", "any" },
+ { "any", "any" },
{ "all", "any" },
{ "i386", "i386" },
{ "ix86", "i386" }, /* OpenPKG uses this */
return "canonical";
}
-
- static const string
- system_arch (void)
- {
- static struct utsname buf;
- static bool checked = false;
-
- if (!checked) {
- if (uname (&buf) < 0) {
- return NULL;
- }
- checked = true;
- }
-
- return string (buf.machine);
- }
-
-
- //---------------------------------------------------------------------------
-
-
+//---------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////
//
bool Arch::compatibleWith( const Arch & rhs ) const
{
- return CompatTable::compatible( *this, rhs );
+ return _value.empty()
+ || *this == rhs
+ || CompatTable::compatible( *this, rhs );
}
/////////////////////////////////////////////////////////////////
int compare( const Arch & rhs ) const
{ return _value.compare( rhs._value ); }
- /** Architecture of the current working system
- * \return \c Arch.
- * \todo Eliminate this, it's not task of a data type to
- * detect and define what the system architecture is.
- */
- static const Arch System;
-
private:
/** String representation of Arch. */
std::string _value;
TranslatedText.cc \
ZYppFactory.cc
+
lib@PACKAGE@_la_LDFLAGS = @LIBZYPP_VERSION_INFO@
lib@PACKAGE@_la_LIBADD = base/lib@PACKAGE@_base.la \
{ return _pimpl->applySolutions (solutions); }
void Resolver::doUpgrade( UpgradeStatistics & opt_stats_r )
{ return _pimpl->doUpgrade(opt_stats_r); }
+ Arch Resolver::architecture() const
+ { return _pimpl->architecture(); }
+ void Resolver::setArchitecture( const Arch & arch )
+ { _pimpl->setArchitecture( arch ); }
/////////////////////////////////////////////////////////////////
} // namespace zypp
**/
bool applySolutions( const ProblemSolutionList & solutions );
+ Arch architecture() const;
+ void setArchitecture( const Arch & arch);
+
protected:
private:
ResPool::const_nameiterator pend = pool.nameend(name);
for (ResPool::const_nameiterator it = pool.namebegin(name); it != pend; ++it) {
PoolItem item = it->second;
- if (item.status().staysInstalled()
+ if (item.status().isInstalled()
&& item->kind() == kind) {
if (!info( it->second ))
break;
#endif
ResPool::const_indexiterator pend = _pool.providesend(requirement.index());
for (ResPool::const_indexiterator it = _pool.providesbegin(requirement.index()); it != pend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
if (requirement.matches (it->second.first) == CapMatch::yes) {
if (!info( it->second.second, it->second.first))
break;
#endif
ResPool::const_indexiterator pend = pool.providesend(maybe_upgrade_cap.index());
for (ResPool::const_indexiterator it = pool.providesbegin(maybe_upgrade_cap.index()); it != pend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
if (maybe_upgrade_cap.matches (it->second.first) == CapMatch::yes) {
if (!upgrade_info( it->second.second, it->second.first))
break;
ResPool::const_indexiterator cend = pool().conflictsend(cap.index());
for (ResPool::const_indexiterator it = pool().conflictsbegin(cap.index()); it != cend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
+
if (cap.matches (it->second.first) == CapMatch::yes) {
// conflicting item found
PoolItem_Ref conflicting_item = it->second.second;
return true;
}
+ if (!provider->arch().compatibleWith( context->architecture() )) {
+ MIL << "provider " << provider << " has incompatible arch '" << provider->arch() << "'" << endl;
+ return true;
+ }
+
if (! (status.isToBeUninstalled() || status.isImpossible())
&& ! context->isParallelInstall (provider)
&& ! uniq.has(provider)
// world->foreachProvidingResItem (_capability, require_process_cb, &info);
ResPool::const_indexiterator pend = pool().providesend(_capability.index());
for (ResPool::const_indexiterator it = pool().providesbegin(_capability.index()); it != pend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
if (_capability.matches (it->second.first) == CapMatch::yes) {
if (!info( it->second.second, it->second.first))
break;
// Maybe we can add some extra info on why none of the providers are suitable.
// pool()->foreachProvidingResItem (_capability, no_installable_providers_info_cb, (void *)&info);
-
+#if 0
Dep dep( Dep::PROVIDES );
invokeOnEach( pool().byCapabilityIndexBegin( _capability.index(), dep ), // begin()
pool().byCapabilityIndexEnd( _capability.index(), dep ), // end()
resfilter::callOnCapMatchIn( dep, _capability, functor::functorRef<bool,PoolItem,Capability>(info)) );
+#endif
+ // world->foreachProvidingResItem (_capability, require_process_cb, &info);
+ ResPool::const_indexiterator pend = pool().providesend(_capability.index());
+ for (ResPool::const_indexiterator it = pool().providesbegin(_capability.index()); it != pend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
+ if (_capability.matches (it->second.first) == CapMatch::yes) {
+ if (!info( it->second.second, it->second.first))
+ break;
+ }
+ }
}
#if 0 // **!!!** re-enable editon check in LookForUpgrades()
invokeOnEach( pool().byNameBegin( _requiring_item->name() ), pool().byNameEnd( _requiring_item->name() ),
- functor::chain( resfilter::ByUninstalled(),
- resfilter::ByKind( _requiring_item->kind() ) ),
+ resfilter::ByKind( _requiring_item->kind() ),
#if 0
// CompareByGT is broken resfilter::byEdition<CompareByGT<Edition> >( _requiring_item->edition() )),
#endif
ResPool::const_nameiterator pend = pool().nameend(_requiring_item->name());
for (ResPool::const_nameiterator it = pool().namebegin(_requiring_item->name()); it != pend; ++it) {
PoolItem pos = it->second;
- if (pos.status().staysUninstalled()
- && pos->kind() == _requiring_item->kind()
+ if (pos->kind() == _requiring_item->kind()
&& _requiring_item->edition().compare(pos->edition()) < 0)
{
if (!info( pos ))
if (context->requirementIsMet (match, false)) // its provided by another installed resolvable -> dont care
return true;
- if (requirer.status().isSatisfied()) { // it is just satisfied, check freshens
+ if (context->getStatus(requirer).isSatisfied()) { // it is just satisfied, check freshens
#warning If an uninstall incompletes a satisfied, the uninstall should be cancelled
QueueItemEstablish_Ptr establish_item = new QueueItemEstablish (pool, requirer, soft); // re-check if its still needed
qil.push_back (establish_item);
Capability c = *iter;
ResPool::const_indexiterator rend = pool().requiresend(c.index());
for (ResPool::const_indexiterator it = pool().requiresbegin(c.index()); it != rend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
if (c.matches (it->second.first) == CapMatch::yes) {
if (!info( it->second.second, it->second.first))
break;
Capability c = *iter;
ResPool::const_indexiterator rend = pool().requiresend(c.index());
for (ResPool::const_indexiterator it = pool().requiresbegin(c.index()); it != rend; ++it) {
+ if (it->second.second->arch() == Arch_src)
+ continue;
if (c.matches (it->second.first) == CapMatch::yes) {
if (!info( it->second.second, it->second.first))
break;
* 02111-1307, USA.
*/
+#include <sys/utsname.h>
+
#include "zypp/solver/detail/Resolver.h"
#include "zypp/solver/detail/Helper.h"
, _best_context (NULL)
, _timed_out (false)
{
+ struct utsname buf;
+ if (uname (&buf) < 0) {
+ ERR << "Can't determine system architecture" << endl;
+ }
+ else {
+ MIL << "System architecture is '" << buf.machine << "'" << endl;
+ _architecture = Arch(buf.machine);
+ }
}
}
if (context == NULL)
- context = new ResolverContext(_pool);
+ context = new ResolverContext(_pool, _architecture);
context->setEstablishing (true);
// create initial_queue
- ResolverQueue_Ptr initial_queue = new ResolverQueue(_pool, context);
+ ResolverQueue_Ptr initial_queue = new ResolverQueue(_pool, _architecture, context);
/* If this is a verify, we do a "soft resolution" */
{
CollectTransact info (*this);
-#if 0
+#if 1
MIL << "Resolver::resolvePool()" << endl;
MIL << "Pool before resolve" << endl;
MIL << "---------------------------------------" << endl;
MIL << "Have solution, copying back to pool" << endl;
ResolverContext_Ptr solution = bestContext();
solution->foreachMarked (solution_to_pool, NULL);
-#if 0
+#if 1
MIL << "Pool after resolve" << endl;
MIL << "---------------------------------------" << endl;
for (ResPool::const_iterator it = _pool.begin(); it != _pool.end(); ++it) {
std::set<Source_Ref> _subscribed;
+ Arch _architecture;
+
// helpers
bool doesObsoleteCapability (PoolItem_Ref candidate, const Capability & cap);
bool doesObsoleteItem (PoolItem_Ref candidate, PoolItem_Ref installed);
bool applySolutions (const ProblemSolutionList &solutions);
void reset (void);
+
+ Arch architecture() const { return _architecture; }
+ void setArchitecture( const Arch & arch) { _architecture = arch; }
};
///////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
-ResolverContext::ResolverContext (const ResPool & pool, ResolverContext_Ptr parent)
+ResolverContext::ResolverContext (const ResPool & pool, const Arch & arch, ResolverContext_Ptr parent)
: _parent (parent)
, _pool (pool)
, _download_size (0)
, _verifying (false)
, _establishing (false)
, _invalid (false)
+ , _architecture(arch)
{
_DEBUG( "ResolverContext[" << this << "]::ResolverContext(" << parent << ")" );
if (parent != NULL) {
}
context = context->_parent; // N: go up the chain
}
- _last_checked_status = item.status();
-_XDEBUG( "[NULL]:" << item.status() );
- return item.status(); // Not part of context, return Pool status
+ ResStatus status;
+ if (item.status().isInstalled())
+ status = ResStatus::installed;
+ else
+ status = ResStatus::uninstalled;
+
+ _last_checked_status = status;
+_XDEBUG( "[NULL]:" << status );
+ return status; // Not part of context, return Pool status
}
setStatus (item, ResStatus::toBeInstalled);
}
- if (old_item.status().wasUninstalled()) {
- Resolvable::constPtr res = old_item.resolvable();
- Package::constPtr pkg = asKind<Package>(res); // try to access it as a package
- if (pkg) { // if its !=NULL, get size information
+ Resolvable::constPtr res = old_item.resolvable();
+ Package::constPtr pkg = asKind<Package>(res); // try to access it as a package
+ if (pkg) { // if its !=NULL, get size information
- _install_size -= pkg->size();
- }
+ _install_size -= pkg->size();
+ }
+ if (status == ResStatus::uninstalled) {
res = item.resolvable();
pkg = asKind<Package>(res); // try to access it as a package
if (pkg) { // if its !=NULL, get size information
_other_penalties += other_penalty;
}
-
return true;
}
} InstallInfo;
static void
-install_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+install_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
InstallInfo *info = (InstallInfo *)data;
+MIL << "install_item_cb " << item << ": " << status << endl;
if (status.isToBeInstalled()
+ && !item.status().isInstalled()
&& !Helper::findInstalledItem( info->pool, item))
{
+MIL << "install !" << endl;
if (info->fn) info->fn (item, status, info->rl);
++info->count;
}
PoolItemList *rl = (PoolItemList *)data;
InstallInfo info = { _pool, fn, rl, 0 };
- foreachMarked (install_pkg_cb, (void *)&info);
+ foreachMarked (install_item_cb, (void *)&info);
return info.count;
}
} SatisfyInfo;
static void
-satisfy_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+satisfy_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
SatisfyInfo *info = (SatisfyInfo *)data;
if (status.isSatisfied()
PoolItemList *rl = (PoolItemList *)data;
SatisfyInfo info = { _pool, fn, rl, 0 };
- foreachMarked (satisfy_pkg_cb, (void *)&info);
+ foreachMarked (satisfy_item_cb, (void *)&info);
return info.count;
}
} IncompleteInfo;
static void
-incomplete_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+incomplete_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
IncompleteInfo *info = (IncompleteInfo *)data;
PoolItemList *rl = (PoolItemList *)data;
IncompleteInfo info = { _pool, fn, rl, 0 };
- foreachMarked (incomplete_pkg_cb, (void *)&info);
+ foreachMarked (incomplete_item_cb, (void *)&info);
return info.count;
}
} UpgradeInfo;
static void
-upgrade_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+upgrade_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
UpgradeInfo *info = (UpgradeInfo *)data;
PoolItem_Ref to_be_upgraded;
+MIL << "upgrade_item_cb " << item << ": " << status << endl;
if (status.isToBeInstalled()
- && ! status.staysInstalled ())
+ && ! item.status().isInstalled ())
{
+MIL << "upgrade_item_cb which ?" << endl;
to_be_upgraded = Helper::findInstalledItem(info->pool, item);
if (to_be_upgraded) {
+MIL << "upgrade_item_cb ! " << to_be_upgraded << endl;
if (info->fn) {
info->fn (item, status, to_be_upgraded, info->context->getStatus(to_be_upgraded), info->data);
}
{
UpgradeInfo info = { _pool, fn, data, this, 0 };
- foreachMarked (upgrade_pkg_cb, (void *)&info);
+ foreachMarked (upgrade_item_cb, (void *)&info);
return info.count;
}
} UninstallInfo;
static void
-uninstall_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+uninstall_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
UninstallInfo *info = (UninstallInfo *)data;
+MIL << "uninstall_item_cb " << item << ": " << status << endl;
UpgradeTable::const_iterator pos = info->upgrade_hash.find(item->name());
if (status.isToBeUninstalled ()
&& pos == info->upgrade_hash.end()) // dont count upgrades
{
+MIL << "uninstall_item_cb! " << endl;
if (info->fn)
info->fn (item, status, info->rl);
++info->count;
info.count = 0;
foreachUpgrade (build_upgrade_hash_cb, (void *)&(info.upgrade_hash));
- foreachMarked (uninstall_pkg_cb, (void *)&info);
+ foreachMarked (uninstall_item_cb, (void *)&info);
return info.count;
}
} ImpossibleInfo;
static void
-impossible_pkg_cb (PoolItem_Ref item, const ResStatus & status, void *data)
+impossible_item_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
ImpossibleInfo *info = (ImpossibleInfo *)data;
{
ImpossibleInfo info = { _pool, fn, 0, data };
- foreachMarked (impossible_pkg_cb, (void *)&info);
+ foreachMarked (impossible_item_cb, (void *)&info);
return info.count;
}
install_count_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
int *count = (int *)data;
- if (item.status().wasUninstalled ()) {
+ if (!item.status().isInstalled ()) {
++*count;
}
}
uninstall_count_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
int *count = (int *)data;
- if (item.status().wasInstalled ()) {
+ if (item.status().isInstalled ()) {
++*count;
}
}
satisfy_count_cb (PoolItem_Ref item, const ResStatus & status, void *data)
{
int *count = (int *)data;
- if (item.status().wasUninstalled ()) {
+ if (!item.status().isInstalled ()) {
++*count;
}
}
PoolItem_Ref _last_checked_item; // cache for {get,set}Status
ResStatus _last_checked_status;
+ Arch _architecture;
+
public:
- ResolverContext (const ResPool & pool, ResolverContext_Ptr parent = NULL);
+ ResolverContext (const ResPool & pool, const Arch & arch, ResolverContext_Ptr parent = NULL);
virtual ~ResolverContext();
// ---------------------------------- I/O
inline ResPool pool() const { return _pool; }
+ inline Arch architecture() const { return _architecture; }
+
// ---------------------------------- methods
/**
ResolverInfoChildOf::message( ) const
{
string affected_str = ResolverInfo::toString(affected());
- string container_str = itemsToString( false );
+ string container_str = itemsToString( true );
// TranslatorExplanation: 1.%s name of package, 2.%s list of names
// TranslatorExplanation: 1.%s is part of 'bundles', the bundles are listed in 2.%s
ResolverInfoConflictsWith::message( ) const
{
string affected_str = ResolverInfo::toString(affected());
- string container_str = itemsToString( false );
+ string container_str = itemsToString( true );
// TranslatorExplanation: 1.%s name of package, 2.%s list of names
// TranslatorExplanation: 1.%s is conflicting with multiple others
ResolverInfoDependsOn::message( ) const
{
string affected_str = ResolverInfo::toString(affected());
- string container_str = itemsToString( false );
+ string container_str = itemsToString( true );
// TranslatorExplanation: 1.%s name of package, 2.%s list of names
// TranslatorExplanation: 1.%s is dependent on list of names
// Translator: all.%s = name of package,patch,...
os << str::form (_("%s is needed by %s"),
affected_str.str().c_str(),
- itemsToString(false).c_str());
+ itemsToString(true).c_str());
return os;
}
// Translator: all.%s = name of package,patch,....
os << str::form (_("%s is replaced by %s"),
affected_str.str().c_str(),
- itemsToString(false).c_str());
+ itemsToString(true).c_str());
return os;
}
//---------------------------------------------------------------------------
-ResolverQueue::ResolverQueue (const ResPool & pool, ResolverContext_Ptr context)
+ResolverQueue::ResolverQueue (const ResPool & pool, const Arch & arch, ResolverContext_Ptr context)
: _context (context)
{
_DEBUG("ResolverQueue::ResolverQueue(pool, " << context << ")");
if (context == NULL)
- _context = new ResolverContext(pool);
+ _context = new ResolverContext(pool, arch);
}
//---------------------------------------------------------------------------
-static ResolverQueue_Ptr
-copy_queue_except_for_branch (ResolverQueue_Ptr queue, QueueItem_Ptr branch_qitem, QueueItem_Ptr subqitem)
+ResolverQueue_Ptr
+ResolverQueue::copy_queue_except_for_branch (QueueItem_Ptr branch_qitem, QueueItem_Ptr subqitem) const
{
ResolverContext_Ptr new_context;
ResolverQueue_Ptr new_queue;
_DEBUG("copy_queue_except_for_branch");
- new_context = new ResolverContext (queue->context()->pool(), queue->context());
- new_queue = new ResolverQueue (new_context->pool(), new_context);
+ new_context = new ResolverContext (_context->pool(), _context->architecture(), _context);
+ new_queue = new ResolverQueue (new_context->pool(), new_context->architecture(), new_context);
- QueueItemList qil = queue->qitems();
+ QueueItemList qil = _qitems;
for (QueueItemList::const_iterator iter = qil.begin(); iter != qil.end(); ++iter) {
QueueItem_Ptr qitem = *iter;
QueueItem_Ptr new_qitem;
if (new_qitem->isInstall()) {
QueueItemInstall_Ptr install_qitem = dynamic_pointer_cast<QueueItemInstall>(new_qitem);
-#warning needs Source backref
-#if 0
+
/* Penalties are negative priorities */
int penalty;
- penalty = - queue->context()->getChannelPriority (install_qitem->poolItem()->channel());
+ Source_Ref src = install_qitem->item()->source();
+ penalty = - src.priority();
install_qitem->setOtherPenalty (penalty);
-#endif
}
} else {
ResolverQueue_Ptr new_queue;
QueueItem_Ptr new_qitem = *iter;
- new_queue = copy_queue_except_for_branch (this, (QueueItem_Ptr) first_branch, new_qitem);
+ new_queue = copy_queue_except_for_branch ((QueueItem_Ptr) first_branch, new_qitem);
DeferTable::const_iterator pos = to_defer.find (new_qitem);
if (pos != to_defer.end()) {
IgnoreMap _ignoreConflicts;
IgnoreMap _ignoreRequires;
+ ResolverQueue_Ptr copy_queue_except_for_branch (QueueItem_Ptr branch_qitem, QueueItem_Ptr subqitem) const;
+
public:
- ResolverQueue (const ResPool & pool, ResolverContext_Ptr context = NULL);
+ ResolverQueue (const ResPool & pool, const Arch & arch, ResolverContext_Ptr context = NULL);
virtual ~ResolverQueue();
// ---------------------------------- I/O
// ---------------------------------- methods
-
void addPoolItemToInstall (PoolItem_Ref poolItem);
void addPoolItemToEstablish (PoolItem_Ref poolItem);
void addPoolItemToRemove (PoolItem_Ref poolItem, bool remove_only_mode);
bool operator()( PoolItem_Ref provider, const Capability & match )
{
- obsoletes = true; // we have a match
+ if (provider->arch() == Arch_src)
+ return true;
+
+ obsoletes = true; // we have a match
return false; // stop looping here
}
};