ResolverQueue.h \
ResolverQueuePtr.h \
Resolver.h \
- ResolverPtr.h
+ ResolverPtr.h \
+ ProblemSolution.h \
+ ProblemSolutionPtr.h \
+ SolutionAction.h \
+ SolutionActionPtr.h \
+ ResolverProblem.h
noinst_LTLIBRARIES = lib@PACKAGE@_solver_detail.la
QueueItemRequire.cc \
QueueItemUninstall.cc \
Resolver.cc \
+ Resolver_problems.cc \
ResolverInfo.cc \
ResolverInfoChildOf.cc \
ResolverInfoConflictsWith.cc \
ResolverInfoNeededBy.cc \
ResolverInfoObsoletes.cc \
ResolverContext.cc \
- ResolverQueue.cc
-
+ ResolverQueue.cc \
+ ProblemSolution.cc \
+ SolutionAction.cc \
+ ResolverProblem.cc
--- /dev/null
+
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* ProblemSolution.cc
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "zypp/solver/detail/ProblemSolution.h"
+
+using namespace std;
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+IMPL_PTR_TYPE(ProblemSolution);
+
+//---------------------------------------------------------------------------
+
+string
+ProblemSolution::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+ProblemSolution::toString ( const ProblemSolution & solution )
+{
+ string ret ("Solution:\n");
+ ret += solution._description + "\n";
+ ret += solution._details + "\n";
+ ret += SolutionAction::toString (solution._actions);
+ return ret;
+}
+
+
+std::string
+ProblemSolution::toString (const ProblemSolutionList & solutionlist)
+{
+ string ret;
+ for (ProblemSolutionList::const_iterator iter = solutionlist.begin(); iter != solutionlist.end(); ++iter) {
+ ret += (*iter)->asString();
+ ret += "\n";
+ }
+ return ret;
+}
+
+
+std::string
+ProblemSolution::toString (const CProblemSolutionList & solutionlist)
+{
+ string ret;
+ for (CProblemSolutionList::const_iterator iter = solutionlist.begin(); iter != solutionlist.end(); ++iter) {
+ ret += (*iter)->asString();
+ ret += "\n";
+ }
+ return ret;
+}
+
+
+ostream &
+ProblemSolution::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const ProblemSolution & solution)
+{
+ return os << solution.asString();
+}
+
+//---------------------------------------------------------------------------
+
+ProblemSolution::ProblemSolution( ResolverProblem_Ptr parent, const string & description, const string & details )
+ : _problem (parent)
+ , _description (description)
+ , _details (details)
+{
+}
+
+
+ProblemSolution::~ProblemSolution()
+{
+}
+
+
+/**
+ * Apply this solution, i.e. execute all of its actions.
+ *
+ * Returns 'true' on success, 'false' if actions could not be performed.
+ **/
+
+bool
+ProblemSolution::apply()
+{
+ for (CSolutionActionList::const_iterator iter = _actions.begin(); iter != _actions.end(); ++iter) {
+ }
+ return true;
+}
+
+
+/**
+ * Add an action to the actions list.
+ **/
+void
+ProblemSolution::addAction( SolutionAction_constPtr action )
+{
+ _actions.push_back (action);
+}
+
+
+void
+ProblemSolution::clear()
+{
+ _actions.clear();
+}
+
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
--- /dev/null
+/**
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Author: Stefan Hundhammer <sh@suse.de>
+ *
+ **/
+
+#ifndef ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_H
+#define ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_H
+
+#include <list>
+#include <string>
+
+#include "zypp/base/ReferenceCounted.h"
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/solver/detail/Resolver.h"
+#include "zypp/solver/detail/ProblemSolutionPtr.h"
+#include "zypp/solver/detail/ResolverProblemPtr.h"
+#include "zypp/solver/detail/SolutionAction.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Class representing one possible solution to one problem found during resolving
+ *
+ * All problems should have at least 2-3 (mutually exclusive) solutions:
+ *
+ * - Undo: Do not perform the offending transaction
+ * (do not install the package that had unsatisfied requirements,
+ * do not remove the package that would break other packages' requirements)
+ *
+ * - Remove referrers: Remove all packages that would break because
+ * they depend on the package that is requested to be removed
+ *
+ * - Ignore: Inject artificial "provides" for a missing requirement
+ * (pretend that requirement is satisfied)
+ **/
+ class ProblemSolution : public base::ReferenceCounted
+ {
+ private:
+
+ /**
+ * Clear all data.
+ * In particular, delete all members of _actions.
+ **/
+ void clear();
+
+ //
+ // Data members
+ //
+
+ ResolverProblem_Ptr _problem;
+ CSolutionActionList _actions;
+ std::string _description;
+ std::string _details;
+
+ public:
+
+ /**
+ * Constructor.
+ **/
+ ProblemSolution( ResolverProblem_Ptr parent, const std::string & description, const std::string & details );
+
+ /**
+ * Destructor.
+ **/
+ ~ProblemSolution();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ProblemSolution & solution);
+ static std::string toString (const ProblemSolutionList & solutionlist);
+ static std::string toString (const CProblemSolutionList & solutionlist);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const ProblemSolution & solution);
+
+ std::string asString (void) const;
+
+ // ---------------------------------- accessors
+ /**
+ * Return a one-line text description of this solution.
+ **/
+ std::string description() const { return _description; }
+
+ /**
+ * Return a (possibly multi-line) detailed description of this
+ * solution or an empty string if there are no useful details.
+ **/
+ std::string details() const { return _details; }
+
+ /**
+ * Return the parent dependency problem.
+ **/
+ ResolverProblem_Ptr problem() const { return _problem; }
+
+ // ---------------------------------- methods
+
+ /**
+ * Apply this solution, i.e. execute all of its actions.
+ *
+ * Returns 'true' on success, 'false' if actions could not be performed.
+ **/
+ bool apply();
+
+ /**
+ * Add an action to the actions list.
+ **/
+ void addAction( SolutionAction_constPtr action );
+
+ };
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_H
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* ProblemSolutionPtr.h
+ *
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_PTR_H
+#define ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_PTR_H
+
+#include <list>
+#include "zypp/base/PtrTypes.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ProblemSolution_Ptr
+ // CLASS NAME : ProblemSolution_constPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_PTR_TYPE(ProblemSolution);
+ ///////////////////////////////////////////////////////////////////
+
+ typedef std::list<ProblemSolution_Ptr> ProblemSolutionList;
+ typedef std::list<ProblemSolution_constPtr> CProblemSolutionList;
+
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+
+#endif // ZYPP_SOLVER_DETAIL_PROBLEMSOLUTION_PTR_H
//---------------------------------------------------------------------------
void
- QueueItem::copy (QueueItem_constPtr from)
+ QueueItem::copy (const QueueItem *from)
{
_priority = from->_priority;
_size = from->_size;
// ---------------------------------- methods
- void copy (QueueItem_constPtr from);
+ void copy (const QueueItem *from);
bool isBranch (void) const { return _type == QUEUE_ITEM_TYPE_BRANCH; }
bool isConflict (void) const { return _type == QUEUE_ITEM_TYPE_CONFLICT; }
namespace detail
{ ///////////////////////////////////////////////////////////////////
- using namespace std;
+using namespace std;
- IMPL_PTR_TYPE(QueueItemBranch);
+IMPL_PTR_TYPE(QueueItemBranch);
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- string
- QueueItemBranch::asString ( void ) const
- {
- return toString (*this);
- }
+string
+QueueItemBranch::asString ( void ) const
+{
+ return toString (*this);
+}
- string
- QueueItemBranch::toString ( const QueueItemBranch & item)
- {
- string res = "[Branch: ";
- if (!item._label.empty()) {
- res += item._label;
- }
- res += "\n\t";
- res += QueueItem::toString(item._possible_items, "\n\t");
- res += "]";
- return res;
- }
+string
+QueueItemBranch::toString ( const QueueItemBranch & item)
+{
+ string res = "[Branch: ";
+ if (!item._label.empty()) {
+ res += item._label;
+ }
+ res += "\n\t";
+ res += QueueItem::toString(item._possible_items, "\n\t");
+ res += "]";
+ return res;
+}
- ostream &
- QueueItemBranch::dumpOn( ostream & str ) const
- {
- str << asString();
- return str;
- }
+ostream &
+QueueItemBranch::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
- ostream&
- operator<<( ostream& os, const QueueItemBranch & item)
- {
- return os << item.asString();
- }
+ostream&
+operator<<( ostream& os, const QueueItemBranch & item)
+{
+ return os << item.asString();
+}
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- QueueItemBranch::QueueItemBranch (World_Ptr world)
- : QueueItem (QUEUE_ITEM_TYPE_BRANCH, world)
- {
- }
+QueueItemBranch::QueueItemBranch (World_Ptr world)
+ : QueueItem (QUEUE_ITEM_TYPE_BRANCH, world)
+{
+}
- QueueItemBranch::~QueueItemBranch()
- {
- }
+QueueItemBranch::~QueueItemBranch()
+{
+}
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- void
- QueueItemBranch::addItem (QueueItem_Ptr subitem)
- {
- assert (static_cast<QueueItem*>(this) != subitem);
- #if 0
- // We want to keep the list of possible items sorted for easy comparison later.
- for (QueueItemList::iterator pos = _possible_items.begin(); pos != _possible_items.end(); pos++) {
-
- if ((*pos)->cmp(subitem) >= 0) { // found a larger one
- _possible_items.insert (pos, subitem); // insert before
- return;
- }
- }
- #endif
- _possible_items.push_back (subitem); // no larger found, subitem must be largest
-
- return;
- }
+void
+QueueItemBranch::addItem (QueueItem_Ptr subitem)
+{
+ assert (static_cast<QueueItem*>(this) != subitem);
+#if 0
+ // We want to keep the list of possible items sorted for easy comparison later.
+ for (QueueItemList::iterator pos = _possible_items.begin(); pos != _possible_items.end(); pos++) {
+
+ if ((*pos)->cmp(subitem) >= 0) { // found a larger one
+ _possible_items.insert (pos, subitem); // insert before
+ return;
+ }
+ }
+#endif
+ _possible_items.push_back (subitem); // no larger found, subitem must be largest
+ return;
+}
- bool
- QueueItemBranch::contains (QueueItem_Ptr possible_subbranch)
- {
- QueueItemBranch_Ptr branch = dynamic_pointer_cast<QueueItemBranch>(possible_subbranch);
- if (branch == NULL
- || !branch->isBranch()) {
- return false;
- }
+bool
+QueueItemBranch::contains (QueueItem_Ptr possible_subbranch)
+{
+ QueueItemBranch_Ptr branch = dynamic_pointer_cast<QueueItemBranch>(possible_subbranch);
+ if (branch == NULL
+ || !branch->isBranch()) {
+ return false;
+ }
- if (_possible_items.size() < branch->_possible_items.size()) {
- return false;
- }
- QueueItemList::iterator iter = _possible_items.begin();
- QueueItemList::iterator iter_sub = branch->_possible_items.begin();
+ if (_possible_items.size() < branch->_possible_items.size()) {
+ return false;
+ }
- /* For every item inside the possible sub-branch, look for a matching item
- in the branch. If we can't find a match, fail. (We can do this in one
- pass since the possible_items lists are sorted)
- */
- while (iter_sub != branch->_possible_items.end()) {
+ QueueItemList::iterator iter = _possible_items.begin();
+ QueueItemList::iterator iter_sub = branch->_possible_items.begin();
- while (iter != _possible_items.end()
- && (*iter)->cmp (*iter_sub)) {
- iter++;
- }
+ /* For every item inside the possible sub-branch, look for a matching item
+ in the branch. If we can't find a match, fail. (We can do this in one
+ pass since the possible_items lists are sorted)
+ */
+ while (iter_sub != branch->_possible_items.end()) {
- if (iter == _possible_items.end())
- return false;
+ while (iter != _possible_items.end()
+ && (*iter)->cmp (*iter_sub)) {
+ iter++;
+ }
- iter++;
- iter_sub++;
- }
+ if (iter == _possible_items.end())
+ return false;
- return true;
- }
+ iter++;
+ iter_sub++;
+ }
- //---------------------------------------------------------------------------
+ return true;
+}
- bool
- QueueItemBranch::process (ResolverContext_Ptr context, QueueItemList & qil)
- {
- _DBG("RC_SPEW") << "QueueItemBranch::process(" << asString() << ")" << endl;
+//---------------------------------------------------------------------------
- QueueItemList live_branches;
- unsigned int branch_count;
- bool did_something = true;
+bool
+QueueItemBranch::process (ResolverContext_Ptr context, QueueItemList & qil)
+{
+ _DBG("RC_SPEW") << "QueueItemBranch::process(" << asString() << ")" << endl;
- for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+ QueueItemList live_branches;
+ unsigned int branch_count;
+ bool did_something = true;
- QueueItem_Ptr item = *iter;
+ for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
- if (item->isSatisfied (context))
- goto finished;
+ QueueItem_Ptr item = *iter;
- /* Drop any useless branch items */
- if (! item->isRedundant (context)) {
- live_branches.push_front (item);
- }
- }
+ if (item->isSatisfied (context))
+ goto finished;
- branch_count = live_branches.size();
+ /* Drop any useless branch items */
+ if (! item->isRedundant (context)) {
+ live_branches.push_front (item);
+ }
+ }
- if (branch_count == 0) {
+ branch_count = live_branches.size();
- /* Do nothing */
+ if (branch_count == 0) {
- } else if (branch_count == 1) {
+ /* Do nothing */
- /* If we just have one possible item, process it. */
+ } else if (branch_count == 1) {
- QueueItem_Ptr item = live_branches.front();
- did_something = item->process (context, qil);
+ /* If we just have one possible item, process it. */
- /* Set the item pointer to NULL inside of our original branch
- item, since our call to rc_queue_item_process is now
- responsible for freeing it. */
+ QueueItem_Ptr item = live_branches.front();
+ did_something = item->process (context, qil);
- for (QueueItemList::iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
- if (*iter == item) {
- _possible_items.erase (iter);
- break;
- }
- }
+ /* Set the item pointer to NULL inside of our original branch
+ item, since our call to rc_queue_item_process is now
+ responsible for freeing it. */
- } else if (branch_count == _possible_items.size()) {
+ for (QueueItemList::iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+ if (*iter == item) {
+ _possible_items.erase (iter);
+ break;
+ }
+ }
- /* Nothing was eliminated, so just pass the branch through (and set it to
- NULL so that it won't get freed when we exit. */
+ } else if (branch_count == _possible_items.size()) {
- qil.push_front (this);
- // FIXME: dont free item = NULL;
- did_something = false;
+ /* Nothing was eliminated, so just pass the branch through (and set it to
+ NULL so that it won't get freed when we exit. */
- } else {
- // ERR << "QueueItemBranch::process rebranching" << endl;
- QueueItemBranch_Ptr new_branch = new QueueItemBranch (world());
- for (QueueItemList::const_iterator iter = live_branches.begin(); iter != live_branches.end(); iter++) {
- new_branch->addItem ((*iter)->copy());
- }
- qil.push_front (new_branch);
- }
+ qil.push_front (this);
+// FIXME: dont free item = NULL;
+ did_something = false;
- finished:
- //FIXME rc_queue_item_free (item);
+ } else {
+// ERR << "QueueItemBranch::process rebranching" << endl;
+ QueueItemBranch_Ptr new_branch = new QueueItemBranch (world());
+ for (QueueItemList::const_iterator iter = live_branches.begin(); iter != live_branches.end(); iter++) {
+ new_branch->addItem ((*iter)->copy());
+ }
+ qil.push_front (new_branch);
+ }
- return did_something;
- }
+ finished:
+//FIXME rc_queue_item_free (item);
+ return did_something;
+}
- int
- QueueItemBranch::cmp (QueueItem_constPtr item) const
- {
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
- QueueItemBranch_constPtr branch = dynamic_pointer_cast<const QueueItemBranch>(item);
+int
+QueueItemBranch::cmp (QueueItem_constPtr item) const
+{
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
- /* First, sort by # of possible items. */
- cmp = CMP(_possible_items.size(), branch->_possible_items.size());
- if (cmp != 0)
- return cmp;
+ QueueItemBranch_constPtr branch = dynamic_pointer_cast<const QueueItemBranch>(item);
- /* We can do a by-item cmp since the possible items are kept in sorted order. */
- QueueItemList::const_iterator ia = _possible_items.begin();
- QueueItemList::const_iterator ib = branch->_possible_items.begin();
+ /* First, sort by # of possible items. */
+ cmp = CMP(_possible_items.size(), branch->_possible_items.size());
+ if (cmp != 0)
+ return cmp;
- while (ia != _possible_items.end() && ib != branch->_possible_items.end()) {
- if (*ia && *ib) {
- cmp = (*ia)->cmp (*ib);
- if (cmp != 0) {
- return cmp;
- }
- }
- ia++;
- ib++;
- }
+ /* We can do a by-item cmp since the possible items are kept in sorted order. */
+ QueueItemList::const_iterator ia = _possible_items.begin();
+ QueueItemList::const_iterator ib = branch->_possible_items.begin();
- /* Both lists should end at the same time, since we initially sorted on length. */
- assert (ia == _possible_items.end() && ib == branch->_possible_items.end());
+ while (ia != _possible_items.end() && ib != branch->_possible_items.end()) {
+ if (*ia && *ib) {
+ cmp = (*ia)->cmp (*ib);
+ if (cmp != 0) {
+ return cmp;
+ }
+ }
+ ia++;
+ ib++;
+ }
- return 0;
- }
+ /* Both lists should end at the same time, since we initially sorted on length. */
+ assert (ia == _possible_items.end() && ib == branch->_possible_items.end());
- /***/
- QueueItem_Ptr
- QueueItemBranch::copy (void) const
- {
- QueueItemBranch_Ptr new_branch = new QueueItemBranch (world());
-#if 0
- //original code
- ((QueueItem_Ptr)new_branch)->copy((QueueItem_constPtr)this);
-#else
-#warning Check whether this is the intended behaviour
- new_branch->QueueItem::copy(this);
-#endif
- for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
- QueueItem_Ptr cpy = (*iter)->copy();
- new_branch->_possible_items.push_front (cpy);
- }
+ return 0;
+}
- return new_branch;
- }
+/***/
+QueueItem_Ptr
+QueueItemBranch::copy (void) const
+{
+ QueueItemBranch_Ptr new_branch = new QueueItemBranch (world());
+ new_branch->QueueItem::copy(this);
+ for (QueueItemList::const_iterator iter = _possible_items.begin(); iter != _possible_items.end(); iter++) {
+ QueueItem_Ptr cpy = (*iter)->copy();
+ new_branch->_possible_items.push_front (cpy);
+ }
+
+ return new_branch;
+}
- ///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
typedef struct {
World_Ptr world;
- ResItem_constPtr conflicting_resItem;
- const Capability dep;
+ ResItem_constPtr conflict_issuer; // the item which issues 'conflicts:'
+ const Capability conflict_capability; // the capability mentioned in the 'conflicts'
ResolverContext_Ptr context;
QueueItemList & new_items;
- string pkg_str;
- string dep_str;
-
bool actually_an_obsolete;
} ConflictProcessInfo;
+// resItem provides cap
static bool
-conflict_process_cb (ResItem_constPtr resItem, const Capability & cap, void *data)
+conflict_process_cb (ResItem_constPtr provider, const Capability & provides, void *data)
{
ConflictProcessInfo *info = (ConflictProcessInfo *)data;
ResItemStatus status;
- string pkg_str, cap_str, msg;
ResolverInfo_Ptr log_info;
- CapFactory factory;
+ CapFactory factory;
- _DBG("RC_SPEW") << "conflict_process_cb (resolvable[" << resItem->asString() <<"], cap[" << cap.asString() << "], info [" <<
- info->conflicting_resItem->asString() << "]" << endl;
- _DBG("RC_SPEW") << "conflict_process_cb (info->dep [" << info->dep.asString() << "]" << endl;
+ _DBG("RC_SPEW") << "conflict_process_cb (resolvable[" << provider->asString() <<"], provides[" << provides.asString() << "], conflicts with [" <<
+ info->conflict_issuer->asString() << " conflicts: " << info->conflict_capability.asString() << endl;
/* We conflict with ourself. For the purpose of installing ourself, we
* just ignore it, but it's Debian's way of saying that one and only one
* resItem with this provide may exist on the system at a time. */
- if (info->conflicting_resItem
- && resItem->equals (info->conflicting_resItem)) {
- return true;
+ if (info->conflict_issuer
+ && provider->equals (info->conflict_issuer)) {
+ return true;
}
/* FIXME: This should probably be a GVersion capability. */
* as the resItem that's providing it. This, of course, only
* applies to RPM, since it's the only one with obsoletes right
* now. */
- Capability capTest = factory.parse ( resItem->kind(),
- resItem->name(),
- Rel::EQ,
- resItem->edition());
+ Capability capTest = factory.parse ( provider->kind(),
+ provider->name(),
+ Rel::EQ,
+ provider->edition());
if (info->actually_an_obsolete
- && capTest.matches (cap) != CapMatch::yes )
+ && capTest.matches (provides) != CapMatch::yes )
{
- return true;
+ return true;
}
- pkg_str = resItem->asString();
- cap_str = cap.asString();
-
- status = info->context->getStatus (resItem);
+ status = info->context->getStatus (provider);
- _DBG("RC_SPEW") << "conflict_process_cb (resolvable[" << resItem->asString() << "]<" << ResolverContext::toString(status) << ">" << endl;
+ _DBG("RC_SPEW") << "conflict_process_cb (resolvable[" << provider->asString() << "]<" << ResolverContext::toString(status) << ">" << endl;
switch (status) {
- case RESOLVABLE_STATUS_INSTALLED:
- case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: {
- QueueItemUninstall_Ptr uninstall;
- ResolverInfo_Ptr log_info;
+ case RESOLVABLE_STATUS_INSTALLED:
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED_SOFT: {
+ QueueItemUninstall_Ptr uninstall;
+ ResolverInfo_Ptr log_info;
#if PHI
- // maybe an upgrade can resolve the conflict ?
- // check if other resItem is available which upgrades
+ // maybe an upgrade can resolve the conflict ?
+ // check if other resItem is available which upgrades
- // find non-installed packages which provide the conflicting name
+ // find non-installed packages which provide the conflicting name
- UpgradeCandidateInfo upgrade_info;
- upgrade_info.context = info->context;
- upgrade_info.resItem = resItem;
+ UpgradeCandidateInfo upgrade_info;
+ upgrade_info.context = info->context;
+ upgrade_info.resItem = provider;
- Capability maybe_upgrade_dep = factory.parse ( resItem->kind(),
- resItem->name(),
- Rel::ANY,
- Edition::noedition );
+ Capability maybe_upgrade_dep = factory.parse ( provider->kind(),
+ provider->name(),
+ Rel::ANY,
+ Edition::noedition );
- info->world->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);
+ info->world->foreachProvidingResItem (maybe_upgrade_dep, upgrade_candidates_cb, (void *)&upgrade_info);
#endif
- uninstall = new QueueItemUninstall (info->world, resItem, "conflict");
- uninstall->setDependency (info->dep);
+ uninstall = new QueueItemUninstall (info->world, provider, info->actually_an_obsolete ? QueueItemUninstall::OBSOLETE : QueueItemUninstall::CONFLICT);
+ uninstall->setDependency (info->conflict_capability);
- if (info->actually_an_obsolete) {
- uninstall->setDueToObsolete ();
- log_info = new ResolverInfoObsoletes (resItem, info->conflicting_resItem);
- } else {
- uninstall->setDueToConflict ();
- log_info = new ResolverInfoConflictsWith (resItem, info->conflicting_resItem);
- }
+ if (info->actually_an_obsolete) {
+ uninstall->setDueToObsolete ();
+ log_info = new ResolverInfoObsoletes (provider, info->conflict_issuer);
+ } else {
+ uninstall->setDueToConflict ();
+ log_info = new ResolverInfoConflictsWith (provider, info->conflict_issuer);
+ }
- uninstall->addInfo (log_info);
+ uninstall->addInfo (log_info);
#if PHI
- if (upgrade_info.upgrades.empty ()) {
+ if (upgrade_info.upgrades.empty ()) {
#endif
- info->new_items.push_back (uninstall);
+ info->new_items.push_back (uninstall);
#if PHI
- }
- else {
- // there are upgrade candidates for the conflicting resItem
- // branch to: 1. uninstall, 2. upgrade (for each upgrading resItem)
-
- QueueItemBranch_Ptr branch = new QueueItemBranch (info->world);
-
- branch->addItem (uninstall); // try uninstall
-
- for (CResItemList::const_iterator iter = upgrade_info.upgrades.begin(); iter != upgrade_info.upgrades.end(); iter++) {
- QueueItemInstall_Ptr upgrade = new QueueItemInstall (info->world, *iter);
- upgrade->setUpgrades (resItem);
- branch->addItem (upgrade); // try upgrade
- }
- info->new_items.push_back (branch);
- }
+ }
+ else {
+ // there are upgrade candidates for the conflicting resItem
+ // branch to: 1. uninstall, 2. upgrade (for each upgrading resItem)
+
+ QueueItemBranch_Ptr branch = new QueueItemBranch (info->world);
+
+ branch->addItem (uninstall); // try uninstall
+
+ for (CResItemList::const_iterator iter = upgrade_info.upgrades.begin(); iter != upgrade_info.upgrades.end(); iter++) {
+ QueueItemInstall_Ptr upgrade = new QueueItemInstall (info->world, *iter);
+ upgrade->setUpgrades (provider);
+ branch->addItem (upgrade); // try upgrade
+ }
+ info->new_items.push_back (branch);
+ }
#endif
- break;
- }
-
- case RESOLVABLE_STATUS_TO_BE_INSTALLED: {
- // Translator: 1.%s and 2.%s = Dependency; 3.%s = name of package,patch,...
- msg = str::form(_("A conflict over %s (%s) requires the removal of the to-be-installed resolvable %s"),
- info->dep_str.c_str(),
- cap_str.c_str(),
- pkg_str.c_str());
-
- ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (resItem,RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
- misc_info->flagAsError ();
- if (info->conflicting_resItem) {
- misc_info->addRelatedResItem (info->conflicting_resItem);
- }
- info->context->addInfo (misc_info);
-
- break;
- }
-
- case RESOLVABLE_STATUS_UNINSTALLED: {
- info->context->setStatus (resItem, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
- msg = string ("Marking ") + pkg_str + " as uninstallable due to conflicts over " + info->dep_str + " (" + cap_str + ")";
- if (!(info->pkg_str.empty())) {
- // Translator: 1.%s = name of package,patch,...; 2.%s and 3.%s = Dependency; 4.%s = name of package,patch,...
- msg = str::form (_("Marking %s as uninstallable due to conflicts over %s (%s) from %s"),
- pkg_str.c_str(),
- info->dep_str.c_str(),
- cap_str.c_str(),
- info->pkg_str.c_str());
- } else {
- // Translator: 1.%s = name of package,patch,...; 2.%s and 3.%s = Dependency;
- msg = str::form (_("Marking %s as uninstallable due to conflicts over %s (%s)"),
- pkg_str.c_str(),
- info->dep_str.c_str(),
- cap_str.c_str());
+ break;
+ }
+
+ case RESOLVABLE_STATUS_TO_BE_INSTALLED: {
+ ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL, provider, RESOLVER_INFO_PRIORITY_VERBOSE, provides);
+
+ misc_info->flagAsError ();
+ if (info->conflict_issuer) {
+ misc_info->setOtherResItem (info->conflict_issuer);
+ misc_info->setOtherCapability (info->conflict_capability);
}
+ info->context->addInfo (misc_info);
+
+ break;
+ }
+
+ case RESOLVABLE_STATUS_UNINSTALLED: {
+ info->context->setStatus (provider, RESOLVABLE_STATUS_TO_BE_UNINSTALLED);
- ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE, provider, RESOLVER_INFO_PRIORITY_VERBOSE, provides);
- misc_info->addRelatedResItem (resItem);
- if (info->conflicting_resItem) {
- misc_info->addRelatedResItem(info->conflicting_resItem);
- }
- info->context->addInfo (misc_info);
+ misc_info->setOtherResItem (info->conflict_issuer);
+ misc_info->setOtherCapability (info->conflict_capability);
- break;
- }
+ info->context->addInfo (misc_info);
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED:
- case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE:
- /* This is the easy case -- we do nothing. */
- break;
+ break;
+ }
- default:
- abort();
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED:
+ case RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE:
+ /* This is the easy case -- we do nothing. */
+ break;
+
+ default:
+ abort();
}
return true;
{
_DBG("RC_SPEW") << "QueueItemConflict::process(" << this->asString() << ")" << endl;
- ConflictProcessInfo info = { world(), _conflicting_resItem, _dep, context, new_items, "", "", _actually_an_obsolete };
-
- if (_conflicting_resItem) {
- info.pkg_str = _conflicting_resItem->asString();
- }
-
- info.dep_str = _dep.asString();
+ ConflictProcessInfo info = {
+ world(),
+ _conflicting_resItem, // conflict_issuer
+ _dep, // conflict_capability
+ context,
+ new_items,
+ _actually_an_obsolete
+ };
world()->foreachProvidingResItem (_dep, conflict_process_cb, (void *)&info);
QueueItemConflict::copy (void) const
{
QueueItemConflict_Ptr new_conflict = new QueueItemConflict (world(), _dep, _conflicting_resItem);
- ((QueueItem_Ptr)new_conflict)->copy((QueueItem_constPtr)this);
+ new_conflict->QueueItem::copy(this);
// _actually_an_obsolete is not being copied !
{
int cmp = this->compare (item); // assures equal type
if (cmp != 0)
- return cmp;
+ return cmp;
QueueItemConflict_constPtr conflict = dynamic_pointer_cast<const QueueItemConflict>(item);
if ( _dep != conflict->dependency())
- cmp = -1;
+ cmp = -1;
return cmp;
}
#include "zypp/solver/detail/QueueItemEstablish.h"
#include "zypp/solver/detail/QueueItemInstall.h"
-#include "zypp/solver/detail/QueueItemUninstall.h"
#include "zypp/solver/detail/QueueItemRequire.h"
#include "zypp/solver/detail/QueueItemConflict.h"
#include "zypp/solver/detail/QueueItem.h"
#include "zypp/solver/detail/ResolverContext.h"
#include "zypp/solver/detail/ResolverInfoConflictsWith.h"
-#include "zypp/solver/detail/ResolverInfoMisc.h"
#include "zypp/solver/detail/ResolverInfoNeededBy.h"
+#include "zypp/solver/detail/ResolverInfoMisc.h"
#include "zypp/solver/detail/ResItemAndDependency.h"
#include "zypp/CapSet.h"
#include "zypp/base/Logger.h"
_DBG("RC_SPEW") << "simple establish of " << _resItem->asString() << " with " << _resItem->freshens().size() << " freshens" << endl;
- string msg = string ("Establishing ") + _resItem->name();
-
- context->addInfoString (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_ESTABLISHING, _resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ context->addInfo (misc_info);
logInfo (context);
/* Loop through all freshen dependencies. If one is satisfied, queue the _resItem for installation. */
QueueItemEstablish::copy (void) const
{
QueueItemEstablish_Ptr new_install = new QueueItemEstablish (world(), _resItem);
- ((QueueItem_Ptr)new_install)->copy((QueueItem_constPtr)this);
+ new_install->QueueItem::copy(this);
new_install->_channel_priority = _channel_priority;
new_install->_other_penalty = _other_penalty;
namespace detail
{ ///////////////////////////////////////////////////////////////////
- using namespace std;
+using namespace std;
- IMPL_PTR_TYPE(QueueItemGroup);
+IMPL_PTR_TYPE(QueueItemGroup);
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- string
- QueueItemGroup::asString ( void ) const
- {
- return toString (*this);
- }
+string
+QueueItemGroup::asString ( void ) const
+{
+ return toString (*this);
+}
- string
- QueueItemGroup::toString ( const QueueItemGroup & item)
- {
- string ret = "[Group: ";
- ret += QueueItem::toString(item._subitems);
- ret += "]";
- return ret;
- }
+string
+QueueItemGroup::toString ( const QueueItemGroup & item)
+{
+ string ret = "[Group: ";
+ ret += QueueItem::toString(item._subitems);
+ ret += "]";
+ return ret;
+}
- ostream &
- QueueItemGroup::dumpOn( ostream & str ) const
- {
- str << asString();
- return str;
- }
+ostream &
+QueueItemGroup::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
- ostream&
- operator<<( ostream& os, const QueueItemGroup & item)
- {
- return os << item.asString();
- }
+ostream&
+operator<<( ostream& os, const QueueItemGroup & item)
+{
+ return os << item.asString();
+}
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- QueueItemGroup::QueueItemGroup (World_Ptr world)
- : QueueItem (QUEUE_ITEM_TYPE_GROUP, world)
- {
- }
+QueueItemGroup::QueueItemGroup (World_Ptr world)
+ : QueueItem (QUEUE_ITEM_TYPE_GROUP, world)
+{
+}
- QueueItemGroup::~QueueItemGroup()
- {
- }
+QueueItemGroup::~QueueItemGroup()
+{
+}
- //---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
- bool
- QueueItemGroup::process (ResolverContext_Ptr context, QueueItemList & new_items)
- {
- _DBG("RC_SPEW") << "QueueItemGroup::process" << endl;
+bool
+QueueItemGroup::process (ResolverContext_Ptr context, QueueItemList & new_items)
+{
+ _DBG("RC_SPEW") << "QueueItemGroup::process" << endl;
- bool did_something = false;
+ bool did_something = false;
- // Just move all of the group's subitems onto the new_items list.
+ // Just move all of the group's subitems onto the new_items list.
- for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
- new_items.push_front (*iter);
- did_something = true;
- }
+ for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
+ new_items.push_front (*iter);
+ did_something = true;
+ }
- _subitems.clear();
+ _subitems.clear();
- // FIXME: delete self
+// FIXME: delete self
- return did_something;
- }
+ return did_something;
+}
- QueueItem_Ptr
- QueueItemGroup::copy (void) const
- {
- QueueItemGroup_Ptr new_group = new QueueItemGroup (world());
- ((QueueItem_Ptr)new_group)->copy((QueueItem_constPtr)this);
+QueueItem_Ptr
+QueueItemGroup::copy (void) const
+{
+ QueueItemGroup_Ptr new_group = new QueueItemGroup (world());
+ new_group->QueueItem::copy(this);
- for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
- new_group->_subitems.push_back ((*iter)->copy());
- }
- return new_group;
- }
+ for (QueueItemList::const_iterator iter = _subitems.begin(); iter != _subitems.end(); iter++) {
+ new_group->_subitems.push_back ((*iter)->copy());
+ }
+ return new_group;
+}
- int
- QueueItemGroup::cmp (QueueItem_constPtr item) const
- {
- int cmp = this->compare (item); // assures equal type
- if (cmp != 0)
- return cmp;
+int
+QueueItemGroup::cmp (QueueItem_constPtr item) const
+{
+ int cmp = this->compare (item); // assures equal type
+ if (cmp != 0)
+ return cmp;
- QueueItemGroup_constPtr group = dynamic_pointer_cast<const QueueItemGroup>(item);
+ QueueItemGroup_constPtr group = dynamic_pointer_cast<const QueueItemGroup>(item);
- // First, sort by # of subitems
+ // First, sort by # of subitems
- cmp = CMP(_subitems.size(), group->_subitems.size());
- if (cmp)
- return cmp;
+ cmp = CMP(_subitems.size(), group->_subitems.size());
+ if (cmp)
+ return cmp;
- // We can do a by-item cmp since the possible items are kept in sorted order.
- QueueItemList::const_iterator iter2;
- for (QueueItemList::const_iterator iter = _subitems.begin(), iter2 = group->_subitems.begin();
- iter != _subitems.end() && iter2 != group->_subitems.end(); iter++, iter2++) {
- cmp = (*iter)->cmp (*iter2);
- if (cmp) {
- return cmp;
- }
- }
+ // We can do a by-item cmp since the possible items are kept in sorted order.
+ QueueItemList::const_iterator iter2;
+ for (QueueItemList::const_iterator iter = _subitems.begin(), iter2 = group->_subitems.begin();
+ iter != _subitems.end() && iter2 != group->_subitems.end(); iter++, iter2++) {
+ cmp = (*iter)->cmp (*iter2);
+ if (cmp) {
+ return cmp;
+ }
+ }
- return 0;
- }
+ return 0;
+}
- void
- QueueItemGroup::addItem (QueueItem_Ptr subitem)
- {
- // We need to keep the list sorted for comparison purposes.
- _subitems.push_back (subitem);
- // FIXME _subitems.sort(cmp)
- }
+void
+QueueItemGroup::addItem (QueueItem_Ptr subitem)
+{
+ // We need to keep the list sorted for comparison purposes.
+ _subitems.push_back (subitem);
+// FIXME _subitems.sort(cmp)
+}
- ///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
_DBG("RC_SPEW") << "upgrades equal resItem, skipping" << endl;
- // Translator: %s = name of package,patch,...
- msg = str::form (_("Skipping %s: already installed"),
- res_name.c_str());
- info = new ResolverInfoMisc (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_SKIPPING, _resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
context->addInfo (info);
goto finished;
}
QueueItemUninstall_Ptr uninstall_item;
for (CResItemList::const_iterator iter = _needed_by.begin(); iter != _needed_by.end(); iter++) {
- uninstall_item = new QueueItemUninstall (world(), *iter, "uninstallable resolvable");
+ uninstall_item = new QueueItemUninstall (world(), *iter, QueueItemUninstall::BACKOUT);
qil.push_front (uninstall_item);
}
context->upgradeResItem (resItem, _upgrades, context->verifying() /* is_soft */, _other_penalty);
- uninstall_item = new QueueItemUninstall (world(), _upgrades, "upgrade");
+ uninstall_item = new QueueItemUninstall (world(), _upgrades, QueueItemUninstall::UPGRADE);
uninstall_item->setUpgradedTo (resItem);
if (_explicitly_requested)
goto finished;
}
+ { // just a block for local initializers, the goto above makes this necessary
+
+ ResolverInfoMisc_Ptr misc_info;
+
if (_upgrades != NULL) {
- // Translator: 1.%s and 2.%s = name of package
- msg = str::form (_("Upgrading %s => %s"),
- _upgrades->asString().c_str(),
- res_name.c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UPDATING, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ misc_info->setOtherResItem (_upgrades);
+cerr << "Updating " << _upgrades->asString() << " to " << resItem->asString() << endl;
} else {
- // Translator: %s = packagename
- msg = str::form (_("Installing %s"),
- res_name.c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INSTALLING, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
}
- context->addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
+ context->addInfo (misc_info);
logInfo (context);
/* Construct require items for each of the resItem's requires that is still unsatisfied. */
- {
+
CapSet deps;
deps = resItem->requires();
_DBG("RC_SPEW") << "because: '" << conflicting_resItem->asString(true) << "'" << endl;
- uninstall_item = new QueueItemUninstall (world(), conflicting_resItem, "conflict");
+ uninstall_item = new QueueItemUninstall (world(), conflicting_resItem, QueueItemUninstall::CONFLICT);
uninstall_item->setDueToConflict ();
log_info = new ResolverInfoConflictsWith (conflicting_resItem, resItem);
uninstall_item->addInfo (log_info);
QueueItemInstall::copy (void) const
{
QueueItemInstall_Ptr new_install = new QueueItemInstall (world(), _resItem);
- ((QueueItem_Ptr)new_install)->copy((QueueItem_constPtr)this);
+ new_install->QueueItem::copy(this);
new_install->_upgrades = _upgrades;
new_install->_deps_satisfied_by_this_install = CapSet(_deps_satisfied_by_this_install.begin(), _deps_satisfied_by_this_install.end());
status = info->context->getStatus (resItem);
+ ResolverInfoMisc_Ptr misc_info;
+
if (resItem_status_is_to_be_uninstalled (status)) {
- // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
- msg_str = str::form (_("%s provides %s, but is scheduled to be uninstalled."),
- resItem->name().c_str(),
- cap.asString().c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER, info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, cap);
+ misc_info->setOtherResItem (resItem);
} else if (info->context->isParallelInstall (resItem)) {
- // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
- msg_str = str::form (_("%s provides %s, but another version of that resItem is already installed."),
- resItem->name().c_str(),
- cap.asString().c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_PARALLEL_PROVIDER, info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, cap);
+ misc_info->setOtherResItem (resItem);
} else if (! info->context->resItemIsPossible (resItem)) {
- // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
- msg_str = str::form (_("%s provides %s, but it is uninstallable. Try installing it on its own for more details."),
- resItem->name().c_str(),
- cap.asString().c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER, info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, cap);
+ misc_info->setOtherResItem (resItem);
} else if (info->world->resItemIsLocked (resItem)) {
- // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
- msg_str = str::form (_("%s provides %s, but it is locked."),
- resItem->name().c_str(),
- cap.asString().c_str());
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_LOCKED_PROVIDER, info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, cap);
+ misc_info->setOtherResItem (resItem);
}
- if (!msg_str.empty()) {
- info->context->addInfoString (info->resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg_str);
+ if (misc_info != NULL) {
+ info->context->addInfo (misc_info);
}
return true;
_DBG("RC_SPEW") << "QueueItemRequire::process(" << this->asString() << ")" << endl;
if (context->requirementIsMet (_dep, _is_child)) {
- _DBG("RC_SPEW") << "requirement is already met in current context" << endl;
-// rc_queue_item_free (item);
+ _DBG("RC_SPEW") << "requirement is already met in current context" << endl;
return true;
}
if (num_providers == 0) {
- _DBG("RC_SPEW") << "Unfulfilled requirement, try different solution" << endl;
+ _DBG("RC_SPEW") << "Unfulfilled requirement, try different solution" << endl;
QueueItemUninstall_Ptr uninstall_item = NULL;
QueueItemBranch_Ptr branch_item = NULL;
ResolverInfo_Ptr err_info;
if (_remove_only) {
- if (_requiring_resItem != NULL) {
- // Translator: 1.%s = dependency ; 2.%s = name of package,patch....
- msg = str::form (_("There are no alternative installed providers of %s for %s"),
- _dep.asString().c_str(),
- _requiring_resItem->asString().c_str());
- } else {
- // Translator: %s = dependency
- msg = str::form (_("There are no alternative installed providers of %s"),
- _dep.asString().c_str());
- }
+ err_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER, _requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, _dep);
} else {
- if (_requiring_resItem != NULL) {
- // Translator: 1.%s = dependency ; 2.%s = name of package,patch....
- msg = str::form (_("There are no installable providers of %s for %s"),
- _dep.asString().c_str(),
- _requiring_resItem->asString().c_str());
- } else {
- // Translator: %s = dependency
- msg = str::form (_("There are no installable providers of %s"),
- _dep.asString().c_str());
- }
+ err_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_NO_PROVIDER, _requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, _dep);
}
- err_info = new ResolverInfoMisc (_requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
-
context->addInfo (err_info);
// Maybe we can add some extra info on why none of the providers are suitable.
&& branch_item->isEmpty ()) {
for (CResItemList::const_iterator iter = upgrade_list.begin(); iter != upgrade_list.end(); iter++) {
- string str;
- string p1, p2;
-
- p1 = _requiring_resItem->asString();
- p2 = (*iter)->asString();
- // Translator: all.%s = name of package,patch,...
- str = str::form (_("Upgrade to %s to avoid removing %s is not possible."),
- p2.c_str(),
- p1.c_str());
- ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, str);
- misc_info->addRelatedResItem (_requiring_resItem);
+ ResolverInfoMisc_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_NO_UPGRADE, _requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ if (iter == upgrade_list.begin()) {
+ misc_info->setOtherResItem (*iter);
+ }
misc_info->addRelatedResItem (*iter);
context->addInfo (misc_info);
if (explore_uninstall_branch && _requiring_resItem) {
ResolverInfo_Ptr log_info;
- uninstall_item = new QueueItemUninstall (world(),_requiring_resItem, "unsatisfied requirements");
+ uninstall_item = new QueueItemUninstall (world(), _requiring_resItem, QueueItemUninstall::UNSATISFIED);
uninstall_item->setDependency (_dep);
if (_lost_resItem) {
new_items.push_front (branch_item);
} else {
// We can't do anything to resolve the missing requirement, so we fail.
- // Translator: %s = dependency
- string msg = str::form (_("Can't satisfy requirement '%s'"),
- _dep.asString().c_str());
-
- context->addErrorString (NULL, msg);
+
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_CANT_SATISFY, _requiring_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, _dep);
+ context->addError (misc_info);
}
} else if (num_providers == 1) {
- _DBG("RC_SPEW") << "Found exactly one resolvable, installing it." << endl;
+ _DBG("RC_SPEW") << "Found exactly one resolvable, installing it." << endl;
QueueItemInstall_Ptr install_item = new QueueItemInstall (world(), info.providers.front());
install_item->addDependency (_dep);
QueueItemRequire::copy (void) const
{
QueueItemRequire_Ptr new_require = new QueueItemRequire (world(), _dep);
-#warning wrong casts
- ((QueueItem_Ptr)new_require)->copy((QueueItem_constPtr)this);
+
+ new_require->QueueItem::copy(this);
new_require->_requiring_resItem = _requiring_resItem;
new_require->_upgraded_resItem = _upgraded_resItem;
#include "zypp/solver/detail/QueueItemRequire.h"
#include "zypp/solver/detail/QueueItem.h"
#include "zypp/solver/detail/ResolverContext.h"
+#include "zypp/solver/detail/ResolverInfoMisc.h"
#include "zypp/solver/detail/ResolverInfoMissingReq.h"
#include "zypp/CapSet.h"
#include "zypp/base/Logger.h"
string ret = "[Uninstall: ";
ret += item._resItem->asString();
- ret += " ("; ret += item._reason; ret += ")";
+ ret += " (";
+ switch (item._reason) {
+ case CONFLICT: ret += "conflicts"; break;
+ case OBSOLETE: ret += "obsoletes"; break;
+ case UNSATISFIED: ret += "unsatisfied dependency"; break;
+ case BACKOUT: ret += "uninstallable"; break;
+ case UPGRADE: ret += "upgrade"; break;
+ case DUPLICATE: ret += "duplicate"; break;
+ case EXPLICIT: ret += "explicit"; break;
+ }
+ ret += ")";
if (item._dep_leading_to_uninstall != Capability()) {
ret += ", Triggered By ";
ret += item._dep_leading_to_uninstall.asString();
//---------------------------------------------------------------------------
-QueueItemUninstall::QueueItemUninstall (World_Ptr world, ResItem_constPtr resItem, const std::string & reason)
+QueueItemUninstall::QueueItemUninstall (World_Ptr world, ResItem_constPtr resItem, UninstallReason reason)
: QueueItem (QUEUE_ITEM_TYPE_UNINSTALL, world)
, _resItem (resItem)
, _reason (reason)
typedef struct {
ResolverContext_Ptr context;
+ Capability capability;
bool cancel_unlink;
} UnlinkCheckInfo;
+// A resolvable providing dep is to be uninstalled, resItem requires dep
+// check if we have to cancel the uninstallation
static bool
unlink_check_cb (ResItem_constPtr resItem, const Capability & dep, void *data)
{
UnlinkCheckInfo *info = (UnlinkCheckInfo *)data;
- if (info->cancel_unlink)
+ if (info->cancel_unlink) // already cancelled
return true;
- if (! info->context->resItemIsPresent (resItem))
+ if (! info->context->resItemIsPresent (resItem)) // resItem is not installed
return true;
- if (info->context->requirementIsMet (dep))
+ if (info->context->requirementIsMet (dep)) // another resolvable provided dep
return true;
- info->cancel_unlink = true;
+ info->capability = dep;
+ info->cancel_unlink = true; // cancel, as this would break dependencies
return true;
}
{
UninstallProcessInfo *info = (UninstallProcessInfo *)data;
- if (! info->context->resItemIsPresent (resItem)) // its not installed -> dont care
+ if (! info->context->resItemIsPresent (resItem)) // its not installed -> dont care
return true;
- if (info->context->requirementIsMet (dep, false)) // its provided by another installed resolvable -> dont care
+ if (info->context->requirementIsMet (dep, false)) // its provided by another installed resolvable -> dont care
return true;
- if (resItem_status_is_satisfied (info->context->getStatus (resItem))) { // it is just satisfied, check freshens
+ if (resItem_status_is_satisfied (info->context->getStatus (resItem))) { // it is just satisfied, check freshens
QueueItemEstablish_Ptr establish_item = new QueueItemEstablish (info->world, resItem); // re-check if its still needed
info->qil->push_front (establish_item);
return true;
problem. */
if (_unlink) {
- bool unlink_cancelled = false;
-
/* If the resItem is to-be-installed, obviously it is being use! */
if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
- unlink_cancelled = true;
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED, _resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ context->addInfo (misc_info);
+ goto finished;
} else if (status == RESOLVABLE_STATUS_INSTALLED) {
UnlinkCheckInfo info;
info.context = context;
info.cancel_unlink = false;
+ // look at the provides of the to-be-uninstalled resolvable and
+ // check if anyone (installed) needs it
+
CapSet provides = _resItem->provides();
for (CapSet::const_iterator iter = provides.begin(); iter != provides.end() && ! info.cancel_unlink; iter++) {
world()->foreachRequiringResItem (*iter, unlink_check_cb, &info);
/* Set the status back to normal. */
context->setStatus (_resItem, status);
- if (info.cancel_unlink)
- unlink_cancelled = true;
+ if (info.cancel_unlink) {
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED, _resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ context->addInfo (misc_info);
+ goto finished;
+ }
}
- if (unlink_cancelled) {
- // Translator: %s = name of package,patch,...
- string msg = str::form (_("%s is required by other installed resolvable, so it won't be unlinked."),
- pkg_str.c_str());
- context->addInfoString (_resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
- goto finished;
- }
}
context->uninstallResItem (_resItem, _upgraded_to != NULL, _due_to_obsolete, _unlink);
if (! _explicitly_requested
&& world()->resItemIsLocked (_resItem)) {
- // Translator: %s = name of package,patch,...
- string msg = str::form (_("%s is locked, and cannot be uninstalled."),
- pkg_str.c_str());
- context->addErrorString (_resItem, msg);
+
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALL_LOCKED, _resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ context->addError (misc_info);
goto finished;
}
this->logInfo (context);
- if (_dep_leading_to_uninstall != Capability()
+ if (_dep_leading_to_uninstall != Capability() // non-empty _dep_leading_to_uninstall
&& !_due_to_conflict
&& !_due_to_obsolete)
{
QueueItemUninstall::copy (void) const
{
QueueItemUninstall_Ptr new_uninstall = new QueueItemUninstall (world(), _resItem, _reason);
- ((QueueItem_Ptr)new_uninstall)->copy((QueueItem_constPtr)this);
+ new_uninstall->QueueItem::copy(this);
new_uninstall->_resItem = _resItem;
// CLASS NAME : QueueItemUninstall
class QueueItemUninstall : public QueueItem {
+ public:
+ typedef enum {
+ CONFLICT, // conflicts [dep]
+ OBSOLETE, // obsolets [dep]
+ UNSATISFIED, // unsatisfied dep, must be unistalled since required dep isnt provided anymore
+ BACKOUT, // back out during verify
+ UPGRADE, // its being upgraded, so the original get uninstalled, find out if this breaks something
+ DUPLICATE, // duplicate install
+ EXPLICIT, // user request
+ } UninstallReason;
- private:
- ResItem_constPtr _resItem;
- const std::string _reason;
- Capability _dep_leading_to_uninstall;
- ResItem_constPtr _upgraded_to;
+ private:
+ ResItem_constPtr _resItem;
+ UninstallReason _reason;
+ Capability _dep_leading_to_uninstall;
+ ResItem_constPtr _upgraded_to;
- bool _explicitly_requested;
- bool _remove_only;
- bool _due_to_conflict;
- bool _due_to_obsolete;
- bool _unlink;
+ bool _explicitly_requested;
+ bool _remove_only;
+ bool _due_to_conflict;
+ bool _due_to_obsolete;
+ bool _unlink;
- public:
+ public:
- QueueItemUninstall (World_Ptr world, ResItem_constPtr resItem, const std::string & reason);
- virtual ~QueueItemUninstall();
+ QueueItemUninstall (World_Ptr world, ResItem_constPtr resItem, UninstallReason reason);
+ virtual ~QueueItemUninstall();
- // ---------------------------------- I/O
+ // ---------------------------------- I/O
- static std::string toString (const QueueItemUninstall & item);
+ static std::string toString (const QueueItemUninstall & item);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const QueueItemUninstall & item);
+ friend std::ostream& operator<<(std::ostream&, const QueueItemUninstall & item);
- std::string asString (void ) const;
+ std::string asString (void ) const;
- // ---------------------------------- accessors
+ // ---------------------------------- accessors
- void setDependency (const Capability & dep) { _dep_leading_to_uninstall = dep; }
- void setExplicitlyRequested (void) { _explicitly_requested = true; }
- void setRemoveOnly (void) { _remove_only = true; }
- void setUpgradedTo (ResItem_constPtr resItem) { _upgraded_to = resItem; }
- void setDueToConflict (void) { _due_to_conflict = true; }
- void setDueToObsolete (void) { _due_to_obsolete = true; }
- void setUnlink (void);
+ UninstallReason reason (void) const { return _reason; }
+ void setDependency (const Capability & dep) { _dep_leading_to_uninstall = dep; }
+ void setExplicitlyRequested (void) { _explicitly_requested = true; }
+ void setRemoveOnly (void) { _remove_only = true; }
+ void setUpgradedTo (ResItem_constPtr resItem) { _upgraded_to = resItem; }
+ void setDueToConflict (void) { _due_to_conflict = true; }
+ void setDueToObsolete (void) { _due_to_obsolete = true; }
+ void setUnlink (void);
- // ---------------------------------- methods
+ // ---------------------------------- methods
- virtual bool process (ResolverContext_Ptr context, QueueItemList & qil);
- virtual QueueItem_Ptr copy (void) const;
- virtual int cmp (QueueItem_constPtr item) const;
- virtual bool isRedundant (ResolverContext_Ptr context) const { return false; }
- virtual bool isSatisfied (ResolverContext_Ptr context) const { return false; }
+ virtual bool process (ResolverContext_Ptr context, QueueItemList & qil);
+ virtual QueueItem_Ptr copy (void) const;
+ virtual int cmp (QueueItem_constPtr item) const;
+ virtual bool isRedundant (ResolverContext_Ptr context) const { return false; }
+ virtual bool isSatisfied (ResolverContext_Ptr context) const { return false; }
};
QueueItemUninstall_Ptr uninstall_item;
if (i != j) {
- uninstall_item = new QueueItemUninstall (world(), dup_pkg, "duplicate install");
+ uninstall_item = new QueueItemUninstall (world(), dup_pkg, QueueItemUninstall::DUPLICATE);
grp_item->addItem (uninstall_item);
}
}
- branch_item->adddIitem (grp_item);
+ branch_item->addItem (grp_item);
}
_initial_items.push_back (branch_item);
//---------------------------------------------------------------------------
-void
+bool
Resolver::resolveDependencies (const ResolverContext_Ptr context)
{
if (initial_queue->isEmpty()) {
INT << "Empty Queue, nothing to resolve" << endl;
- return;
+ return true;
}
_pending_queues.push_front (initial_queue);
while (!_pending_queues.empty()) {
- _XXX("RC_SPEW") << "Pend " << (long) _pending_queues.size()
+ _XXX("RC_SPEW") << "Pend " << (long) _pending_queues.size()
<< " / Cmpl " << (long) _complete_queues.size()
<< " / Prun " << (long) _pruned_queues.size()
<< " / Defr " << (long) _deferred_queues.size()
<< " / Invl " << (long) _invalid_queues.size() << endl;
if (_timeout_seconds > 0) {
- time (&t_now);
- if (difftime (t_now, t_start) > _timeout_seconds) {
- _timed_out = true;
- break;
- }
- }
+ time (&t_now);
+ if (difftime (t_now, t_start) > _timeout_seconds) {
+ _timed_out = true;
+ break;
+ }
+ }
- ResolverQueue_Ptr queue = _pending_queues.front();
- _pending_queues.pop_front();
- ResolverContext_Ptr context = queue->context();
+ ResolverQueue_Ptr queue = _pending_queues.front();
+ _pending_queues.pop_front();
+ ResolverContext_Ptr context = queue->context();
- queue->process();
+ queue->process();
- if (queue->isInvalid ()) {
- _XXX("RC_SPEW") << "Invalid Queue\n" << endl;;
- _invalid_queues.push_front (queue);
+ if (queue->isInvalid ()) {
- } else if (queue->isEmpty ()) {
- _XXX("RC_SPEW") <<"Empty Queue\n" << endl;
+ _XXX("RC_SPEW") << "Invalid Queue\n" << endl;;
+ _invalid_queues.push_front (queue);
+
+ } else if (queue->isEmpty ()) {
+
+ _XXX("RC_SPEW") <<"Empty Queue\n" << endl;
_complete_queues.push_front (queue);
<< " / Prun " << (long) _pruned_queues.size()
<< " / Defr " << (long) _deferred_queues.size()
<< " / Invl " << (long) _invalid_queues.size() << endl;
- return;
+
+ return _best_context && _best_context->isValid();
}
///////////////////////////////////////////////////////////////////
#include <string>
#include "zypp/base/ReferenceCounted.h"
-#include "zypp/base/NonCopyable.h"
#include "zypp/base/PtrTypes.h"
#include "zypp/solver/detail/ResolverPtr.h"
#include "zypp/solver/detail/ResolverQueue.h"
+#include "zypp/solver/detail/ResolverProblemPtr.h"
+#include "zypp/solver/detail/ProblemSolutionPtr.h"
#include "zypp/solver/temporary/ResItem.h"
#include "zypp/solver/temporary/Channel.h"
#include "zypp/CapSet.h"
void verifySystem (void);
void establishState (const ResolverContext_Ptr context = NULL);
- void resolveDependencies (const ResolverContext_Ptr context = NULL);
+ bool resolveDependencies (const ResolverContext_Ptr context = NULL);
+
+ ResolverProblemList problems (void) const;
+ void applySolutions (const ProblemSolutionList & solutions);
void reset (void);
};
//---------------------------------------------------------------------------
// status change
+// change state to TO_BE_INSTALLED (does not upgrade)
+
bool
ResolverContext::installResItem (ResItem_constPtr resItem, bool is_soft, int other_penalty)
{
if (resItem_status_is_to_be_uninstalled (status)
&& status != RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- // Translator: %s = name of package,patch,...
- msg = str::form (_("Can't install %s since it is already marked as needing to be uninstalled"),
- resItem->asString().c_str());
-
- addErrorString (resItem, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addError (misc_info);
return false;
}
if (resItem_status_is_unneeded (status)) {
- msg = str::form (_("Can't install %s since it is does not apply to this system."), resItem->asString().c_str());
- addErrorString (resItem, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INSTALL_UNNEEDED, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addError (misc_info);
return false;
}
}
if (isParallelInstall (resItem)) {
- // Translator: %s = name of package,patch,...
- msg = str::form (_("Can't install %s, since a resolvable of the same name is already marked as needing to be installed"),
- resItem->asString().c_str());
- addErrorString (resItem, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INSTALL_PARALLEL, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addError (misc_info);
return false;
}
}
+// change state to TO_BE_INSTALLED (does upgrade)
+
bool
ResolverContext::upgradeResItem (ResItem_constPtr resItem, ResItem_constPtr old_resItem, bool is_soft, int other_penalty)
{
}
+// change state to 'TO_BE_UNINSTALLED{, DUE_TO_OBSOLETE, DUE_TO_UNLINK}'
+
bool
ResolverContext::uninstallResItem (ResItem_constPtr resItem, bool part_of_upgrade, bool due_to_obsolete, bool due_to_unlink)
{
status = getStatus (resItem);
if (status == RESOLVABLE_STATUS_TO_BE_INSTALLED) {
- // Translator: %s = name of packages,patch,...
- msg = str::form (_("%s is scheduled to be installed, but this is not possible because of dependency problems."), resItem->asString().c_str());
- addErrorString (resItem, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_REJECT_INSTALL, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addError (misc_info);
return false;
}
if (status == RESOLVABLE_STATUS_UNINSTALLED
|| status == RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK) {
- // Translator: %s = name of packages,patch,...
- msg = str::form (_("Marking resolvable %s as uninstallable"), resItem->asString().c_str());
- addInfoString (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_UNINSTALLABLE, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addInfo (misc_info);
}
-
if (due_to_obsolete) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_OBSOLETE;
else if (due_to_unlink) new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED_DUE_TO_UNLINK;
else new_status = RESOLVABLE_STATUS_TO_BE_UNINSTALLED;
}
+// change state to UNNEEDED
+
bool
ResolverContext::unneededResItem (ResItem_constPtr resItem, int other_penalty)
{
}
+// change state to SATISFIED
+
bool
ResolverContext::satisfyResItem (ResItem_constPtr resItem, int other_penalty)
{
}
+// change state to INCOMPLETE
+
bool
ResolverContext::incompleteResItem (ResItem_constPtr resItem, int other_penalty)
{
switch (status) {
case RESOLVABLE_STATUS_INSTALLED: {
- std::string msg = str::form (_("This conflicts with installed %s."), resItem->asString().c_str());
- addErrorString (resItem, msg);
+ ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INCOMPLETES, resItem, RESOLVER_INFO_PRIORITY_VERBOSE);
+ addError (misc_info);
return false;
}
break;
if (info->error ()) {
if (! _invalid) {
- ResolverInfo_Ptr info = new ResolverInfoMisc (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, _("Marking this resolution attempt as invalid."));
+ ResolverInfo_Ptr info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INVALID, NULL, RESOLVER_INFO_PRIORITY_VERBOSE);
info->flagAsError ();
_log.push_back (info);
}
void
-ResolverContext::addInfoString (ResItem_constPtr resItem, int priority, string msg)
-{
- _XXX("RC_SPEW") << "ResolverContext::addInfoString(" << (resItem ? resItem->asString().c_str() : "") << ") " << msg << endl;
- ResolverInfo_Ptr info = new ResolverInfoMisc (resItem, priority, msg);
- addInfo (info);
-}
-
-
-void
-ResolverContext::addErrorString (ResItem_constPtr resItem, string msg)
+ResolverContext::addError (ResolverInfo_Ptr info)
{
- ResolverInfo_Ptr info = new ResolverInfoMisc (resItem, RESOLVER_INFO_PRIORITY_VERBOSE, msg);
info->flagAsError ();
addInfo (info);
}
if (info != NULL // list items might be NULL
&& info->error ()) { // only look at error infos
- ResItem_constPtr resItem = info->resItem(); // get resItem from InfoList
+ ResItem_constPtr resItem = info->affected(); // get resItem from InfoList
if (resItem != NULL) {
error_set.insert (resItem);
}
// Assemble a list of copies of all of the info objects
while (context != NULL) {
for (InfoList::iterator iter = context->_log.begin(); iter != context->_log.end(); iter++) {
- if ((resItem == NULL || (*iter)->resItem() == resItem)
+ if ((resItem == NULL || (*iter)->affected() == resItem)
&& (*iter)->priority() >= priority) {
info_list.push_back ((*iter)->copy());
}
int incompleteCount (void);
void addInfo (ResolverInfo_Ptr info);
- void addInfoString (ResItem_constPtr resItem, int priority, std::string str);
- void addErrorString (ResItem_constPtr resItem, std::string str);
+ void addError (ResolverInfo_Ptr info);
void foreachInfo (ResItem_Ptr resItem, int priority, ResolverInfoFn fn, void *data);
InfoList getInfo (void);
/////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
-
- using namespace std;
-
- IMPL_PTR_TYPE(ResolverInfo);
-
- //---------------------------------------------------------------------------
-
- static struct {
- ResolverInfoType type;
- const char *str;
- } type_str_table[] = {
- { RESOLVER_INFO_TYPE_NEEDED_BY, "needed_by" },
- { RESOLVER_INFO_TYPE_CONFLICTS_WITH, "conflicts_with" },
- { RESOLVER_INFO_TYPE_OBSOLETES, "obsoletes" },
- { RESOLVER_INFO_TYPE_DEPENDS_ON, "depended_on" },
- { RESOLVER_INFO_TYPE_CHILD_OF, "child_of" },
- { RESOLVER_INFO_TYPE_MISSING_REQ, "missing_req" },
- { RESOLVER_INFO_TYPE_MISC, "misc" },
- { RESOLVER_INFO_TYPE_INVALID, "invalid" },
- { RESOLVER_INFO_TYPE_INVALID, NULL }
- };
-
- static const char *
- info_type_to_string (ResolverInfoType type)
- {
- int i;
-
- for (i = 0; type_str_table[i].str != NULL; ++i) {
- if (type == type_str_table[i].type)
- return type_str_table[i].str;
- }
-
- return NULL;
- }
-
-
- ResolverInfoType
- resolver_info_type_from_string (const char *str)
- {
- int i;
-
- if (str == NULL) return RESOLVER_INFO_TYPE_INVALID;
-
- for (i = 0; type_str_table[i].str != NULL; ++i) {
- if (strcasecmp (str, type_str_table[i].str) == 0)
- return type_str_table[i].type;
- }
-
- return RESOLVER_INFO_TYPE_INVALID;
- }
-
- //---------------------------------------------------------------------------
-
- string
- ResolverInfo::asString ( void ) const
- {
- return toString (*this);
- }
-
-
- string
- ResolverInfo::toString ( const ResolverInfo & resolverinfo, bool full )
- {
- string res;
-
- if (full) {
- res += "<";
- res += info_type_to_string (resolverinfo._type);
- res += "> ";
- }
- if (resolverinfo._resItem != NULL) {
- res += resolverinfo._resItem->asString();
- res += ":";
- }
-
- if (resolverinfo._error) res += _(" Error!");
- if (resolverinfo._important) res += _(" Important!");
-
- return res;
- }
-
-
- ostream &
- ResolverInfo::dumpOn( ostream & str ) const
- {
- str << asString();
- return str;
- }
-
-
- ostream&
- operator<<( ostream& os, const ResolverInfo & resolver)
- {
- return os << resolver.asString();
- }
-
- //---------------------------------------------------------------------------
-
- ResolverInfo::ResolverInfo (ResolverInfoType type, ResItem_constPtr resItem, int priority)
- : _type (type)
- , _resItem (resItem)
- , _priority (priority)
- , _error (false)
- , _important (false)
- {
- }
-
-
- ResolverInfo::~ResolverInfo()
- {
- }
-
- //---------------------------------------------------------------------------
-
- bool
- ResolverInfo::merge (ResolverInfo_Ptr to_be_merged)
- {
- if (to_be_merged == NULL) return false;
-
- if (_type != to_be_merged->_type
- || _resItem != to_be_merged->_resItem) {
- return false;
- }
-
- return true;
- }
-
- void
- ResolverInfo::copy (ResolverInfo_constPtr from)
- {
- _error = from->_error;
- _important = from->_important;
- }
-
-
- ResolverInfo_Ptr
- ResolverInfo::copy (void) const
- {
- ResolverInfo_Ptr cpy = new ResolverInfo(_type, _resItem, _priority);
-
- cpy->copy (this);
-
- return cpy;
- }
-
-
- //---------------------------------------------------------------------------
-
- bool
- ResolverInfo::isAbout (ResItem_constPtr resItem) const
- {
- if (_resItem == NULL)
- return false;
-
- return _resItem->name() == resItem->name();
- }
-
- ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+IMPL_PTR_TYPE(ResolverInfo);
+
+//---------------------------------------------------------------------------
+
+static struct {
+ ResolverInfoType type;
+ const char *str;
+} type_str_table[] = {
+ { RESOLVER_INFO_TYPE_NEEDED_BY, "needed_by" },
+ { RESOLVER_INFO_TYPE_CONFLICTS_WITH, "conflicts_with" },
+ { RESOLVER_INFO_TYPE_OBSOLETES, "obsoletes" },
+ { RESOLVER_INFO_TYPE_DEPENDS_ON, "depended_on" },
+ { RESOLVER_INFO_TYPE_CHILD_OF, "child_of" },
+ { RESOLVER_INFO_TYPE_MISSING_REQ, "missing_req" },
+ { RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER, "There are no alternative installed providers of c [for p]" },
+ { RESOLVER_INFO_TYPE_NO_PROVIDER, "There are no installable providers of c [for p]" },
+ { RESOLVER_INFO_TYPE_NO_UPGRADE, "Upgrade to q to avoid removing p is not possible." },
+ { RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER, "p provides c but is scheduled to be uninstalled" },
+ { RESOLVER_INFO_TYPE_PARALLEL_PROVIDER, "p provides c but another version is already installed" },
+ { RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER, "p provides c but is uninstallable" },
+ { RESOLVER_INFO_TYPE_LOCKED_PROVIDER, "p provides c but is locked" },
+ { RESOLVER_INFO_TYPE_SKIPPING, "Skipping p, already installed" },
+ { RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED, "p is to-be-installed, so it won't be unlinked." },
+ { RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED, "p is required by installed, so it won't be unlinked." },
+ { RESOLVER_INFO_TYPE_UNINSTALL_LOCKED, "cant uninstall, its locked" },
+ { RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL, "to-be-installed p conflicts with q due to c" },
+ { RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE, "uninstalled p is marked uninstallable it conflicts [with q] due to c" },
+ { RESOLVER_INFO_TYPE_INVALID, "invalid" },
+ { RESOLVER_INFO_TYPE_INVALID, NULL }
+};
+
+static const char *
+info_type_to_string (ResolverInfoType type)
+{
+ int i;
+
+ for (i = 0; type_str_table[i].str != NULL; ++i) {
+ if (type == type_str_table[i].type)
+ return type_str_table[i].str;
+ }
+
+ return NULL;
+}
+
+
+ResolverInfoType
+resolver_info_type_from_string (const char *str)
+{
+ int i;
+
+ if (str == NULL) return RESOLVER_INFO_TYPE_INVALID;
+
+ for (i = 0; type_str_table[i].str != NULL; ++i) {
+ if (strcasecmp (str, type_str_table[i].str) == 0)
+ return type_str_table[i].type;
+ }
+
+ return RESOLVER_INFO_TYPE_INVALID;
+}
+
+//---------------------------------------------------------------------------
+
+string
+ResolverInfo::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+ResolverInfo::toString ( const ResolverInfo & resolverinfo, bool full )
+{
+ string res;
+
+ if (full) {
+ res += "<";
+ res += info_type_to_string (resolverinfo._type);
+ res += "> ";
+ }
+ if (resolverinfo._affected!= NULL) {
+ res += resolverinfo._affected->asString();
+ res += ":";
+ }
+
+ if (resolverinfo._error) res += _(" Error!");
+ if (resolverinfo._important) res += _(" Important!");
+
+ return res;
+}
+
+
+ostream &
+ResolverInfo::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const ResolverInfo & resolver)
+{
+ return os << resolver.asString();
+}
+
+//---------------------------------------------------------------------------
+
+ResolverInfo::ResolverInfo (ResolverInfoType type, ResItem_constPtr resItem, int priority)
+ : _type (type)
+ , _affected (resItem)
+ , _priority (priority)
+ , _error (false)
+ , _important (false)
+{
+}
+
+
+ResolverInfo::~ResolverInfo()
+{
+}
+
+//---------------------------------------------------------------------------
+
+bool
+ResolverInfo::merge (ResolverInfo_Ptr to_be_merged)
+{
+ if (to_be_merged == NULL) return false;
+
+ if (_type != to_be_merged->_type
+ || _affected != to_be_merged->_affected) {
+ return false;
+ }
+
+ return true;
+}
+
+void
+ResolverInfo::copy (ResolverInfo_constPtr from)
+{
+ _error = from->_error;
+ _important = from->_important;
+}
+
+
+ResolverInfo_Ptr
+ResolverInfo::copy (void) const
+{
+ ResolverInfo_Ptr cpy = new ResolverInfo(_type, _affected, _priority);
+
+ cpy->copy (this);
+
+ return cpy;
+}
+
+
+//---------------------------------------------------------------------------
+
+bool
+ResolverInfo::isAbout (ResItem_constPtr resItem) const
+{
+ if (_affected == NULL)
+ return false;
+
+ return _affected->name() == resItem->name();
+}
+
+///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
RESOLVER_INFO_TYPE_DEPENDS_ON,
RESOLVER_INFO_TYPE_CHILD_OF,
RESOLVER_INFO_TYPE_MISSING_REQ,
- RESOLVER_INFO_TYPE_MISC
+ // from ResolverContext
+ RESOLVER_INFO_TYPE_INVALID_SOLUTION, // Marking this resolution attempt as invalid.
+ RESOLVER_INFO_TYPE_UNINSTALLABLE, // Marking p as uninstallable
+ RESOLVER_INFO_TYPE_REJECT_INSTALL, // p is scheduled to be installed, but this is not possible because of dependency problems.
+ RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED, // Can't install p since it is already marked as needing to be uninstalled
+ RESOLVER_INFO_TYPE_INSTALL_UNNEEDED, // Can't install p since it is does not apply to this system.
+ RESOLVER_INFO_TYPE_INSTALL_PARALLEL, // Can't install p, since a resolvable of the same name is already marked as needing to be installed.
+ RESOLVER_INFO_TYPE_INCOMPLETES, // This would invalidate p
+ // from QueueItemEstablish
+ RESOLVER_INFO_TYPE_ESTABLISHING, // Establishing p
+ // from QueueItemInstall
+ RESOLVER_INFO_TYPE_INSTALLING, // Installing p
+ RESOLVER_INFO_TYPE_UPDATING, // Updating p
+ RESOLVER_INFO_TYPE_SKIPPING, // Skipping p, already installed
+ // from QueueItemRequire
+ RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER, // There are no alternative installed providers of c [for p]
+ RESOLVER_INFO_TYPE_NO_PROVIDER, // There are no installable providers of c [for p]
+ RESOLVER_INFO_TYPE_NO_UPGRADE, // Upgrade to q to avoid removing p is not possible.
+ RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER, // p provides c but is scheduled to be uninstalled
+ RESOLVER_INFO_TYPE_PARALLEL_PROVIDER, // p provides c but another version is already installed
+ RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER, // p provides c but is uninstallable
+ RESOLVER_INFO_TYPE_LOCKED_PROVIDER, // p provides c but is locked
+ RESOLVER_INFO_TYPE_CANT_SATISFY, // Can't satisfy requirement c
+ // from QueueItemUninstall
+ RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED, // p is to-be-installed, so it won't be unlinked.
+ RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED, // p is required by installed, so it won't be unlinked.
+ RESOLVER_INFO_TYPE_UNINSTALL_LOCKED, // cant uninstall, its locked
+ // from QueueItemConflict
+ RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL, // to-be-installed p conflicts with q due to c
+ RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE // uninstalled p is marked uninstallable it conflicts [with q] due to c
} ResolverInfoType;
#define RESOLVER_INFO_PRIORITY_USER 500
private:
ResolverInfoType _type;
- ResItem_constPtr _resItem;
+
+ ResItem_constPtr _affected;
+
int _priority;
bool _error;
protected:
- ResolverInfo (ResolverInfoType type, ResItem_constPtr resItem, int priority);
+ ResolverInfo (ResolverInfoType type, ResItem_constPtr affected, int priority);
public:
// ---------------------------------- accessors
ResolverInfoType type (void) const { return _type; }
- ResItem_constPtr resItem (void) const { return _resItem; }
+ ResItem_constPtr affected (void) const { return _affected; }
int priority (void) const { return _priority; }
int error (void) const { return _error; }
ResolverInfo_Ptr
ResolverInfoChildOf::copy (void) const
{
- ResolverInfoChildOf_Ptr cpy = new ResolverInfoChildOf(resItem(), NULL);
+ ResolverInfoChildOf_Ptr cpy = new ResolverInfoChildOf(affected(), NULL);
((ResolverInfoContainer_Ptr)cpy)->copy (this);
ResolverInfo_Ptr
ResolverInfoConflictsWith::copy (void) const
{
- ResolverInfoConflictsWith_Ptr cpy = new ResolverInfoConflictsWith(resItem(), NULL);
+ ResolverInfoConflictsWith_Ptr cpy = new ResolverInfoConflictsWith(affected(), NULL);
((ResolverInfoContainer_Ptr)cpy)->copy (this);
/////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
-
- using namespace std;
-
- IMPL_PTR_TYPE(ResolverInfoContainer);
-
- //---------------------------------------------------------------------------
-
-
- string
- ResolverInfoContainer::asString ( void ) const
- {
- return toString (*this);
- }
-
-
- string
- ResolverInfoContainer::toString ( const ResolverInfoContainer & container )
- {
- string res = "<resolverinfocontainer '";
-
- res += ResolverInfo::toString (container);
- for (CResItemList::const_iterator iter = container._resItem_list.begin(); iter != container._resItem_list.end(); iter++) {
- if (iter != container._resItem_list.begin()) res += ", ";
- res += (*iter)->asString();
- }
- res += "'>";
-
- return res;
- }
-
-
- ostream &
- ResolverInfoContainer::dumpOn( ostream & str ) const
- {
- str << asString();
- return str;
- }
-
-
- ostream&
- operator<<( ostream& os, const ResolverInfoContainer & container)
- {
- return os << container.asString();
- }
-
- //---------------------------------------------------------------------------
-
- ResolverInfoContainer::ResolverInfoContainer (ResolverInfoType type, ResItem_constPtr resItem, int priority, ResItem_constPtr child)
- : ResolverInfo (type, resItem, priority)
- {
- if (child != NULL)
- _resItem_list.push_back (child);
- }
-
-
- ResolverInfoContainer::~ResolverInfoContainer ()
- {
- }
-
- //---------------------------------------------------------------------------
-
- bool
- ResolverInfoContainer::merge (ResolverInfoContainer_Ptr to_be_merged)
- {
- bool res;
-
- res = ((ResolverInfo_Ptr)this)->merge ((ResolverInfo_Ptr)to_be_merged);
- if (!res) return res;
-
- typedef std::map<ResItem_constPtr, bool> SeenTable;
- SeenTable seen_packages;
-
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- seen_packages[*iter] = true;
- }
-
- CResItemList rl = to_be_merged->resItems();
- for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
- SeenTable::const_iterator pos = seen_packages.find(*iter);
- if (pos == seen_packages.end()) {
- _resItem_list.push_front (*iter);
- seen_packages[*iter] = true;
- }
- }
-
- return true;
- }
-
-
- void
- ResolverInfoContainer::copy (ResolverInfoContainer_constPtr from)
- {
- ((ResolverInfo_Ptr)this)->copy(from);
-
- for (CResItemList::const_iterator iter = from->_resItem_list.begin(); iter != from->_resItem_list.end(); iter++) {
- _resItem_list.push_back (*iter);
- }
- }
-
-
- ResolverInfo_Ptr
- ResolverInfoContainer::copy (void) const
- {
- ResolverInfoContainer_Ptr cpy = new ResolverInfoContainer(type(), resItem(), priority());
-
- cpy->copy (this);
-
- return cpy;
- }
-
- //---------------------------------------------------------------------------
-
- string
- ResolverInfoContainer::resItemsToString (bool names_only) const
- {
- string res;
-
- if (_resItem_list.empty())
- return res;
-
- res += " [";
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- if (iter != _resItem_list.begin())
- res += ", ";
-
- res += (names_only ? (*iter)->name() : (*iter)->asString());
- }
- res += "]";
-
- return res;
- }
-
-
- bool
- ResolverInfoContainer::mentions (ResItem_constPtr resItem) const
- {
- if (isAbout(resItem))
- return true;
-
- // Search resItem_list for any mention of the resItem.
-
- for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
- if ((*iter)->name() == resItem->name()) {
- return true;
- }
- }
-
- return false;
- }
-
-
- void
- ResolverInfoContainer::addRelatedResItem (ResItem_constPtr resItem)
- {
- if (!mentions(resItem)) {
- _resItem_list.push_front (resItem);
- }
- }
-
-
- void
- ResolverInfoContainer::addRelatedResItemList (const CResItemList & resItems)
- {
- for (CResItemList::const_iterator iter = resItems.begin(); iter != resItems.end(); iter++) {
- _resItem_list.push_front (*iter);
- }
- }
-
- ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+IMPL_PTR_TYPE(ResolverInfoContainer);
+
+//---------------------------------------------------------------------------
+
+
+string
+ResolverInfoContainer::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+ResolverInfoContainer::toString ( const ResolverInfoContainer & container )
+{
+ string res = "<resolverinfocontainer '";
+
+ res += ResolverInfo::toString (container);
+ for (CResItemList::const_iterator iter = container._resItem_list.begin(); iter != container._resItem_list.end(); iter++) {
+ if (iter != container._resItem_list.begin()) res += ", ";
+ res += (*iter)->asString();
+ }
+ res += "'>";
+
+ return res;
+}
+
+
+ostream &
+ResolverInfoContainer::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const ResolverInfoContainer & container)
+{
+ return os << container.asString();
+}
+
+//---------------------------------------------------------------------------
+
+ResolverInfoContainer::ResolverInfoContainer (ResolverInfoType type, ResItem_constPtr resItem, int priority, ResItem_constPtr child)
+ : ResolverInfo (type, resItem, priority)
+{
+ if (child != NULL)
+ _resItem_list.push_back (child);
+}
+
+
+ResolverInfoContainer::~ResolverInfoContainer ()
+{
+}
+
+//---------------------------------------------------------------------------
+
+bool
+ResolverInfoContainer::merge (ResolverInfoContainer_Ptr to_be_merged)
+{
+ bool res;
+
+ res = ((ResolverInfo_Ptr)this)->merge ((ResolverInfo_Ptr)to_be_merged);
+ if (!res) return res;
+
+ typedef std::map<ResItem_constPtr, bool> SeenTable;
+ SeenTable seen_packages;
+
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ seen_packages[*iter] = true;
+ }
+
+ CResItemList rl = to_be_merged->resItems();
+ for (CResItemList::const_iterator iter = rl.begin(); iter != rl.end(); iter++) {
+ SeenTable::const_iterator pos = seen_packages.find(*iter);
+ if (pos == seen_packages.end()) {
+ _resItem_list.push_front (*iter);
+ seen_packages[*iter] = true;
+ }
+ }
+
+ return true;
+}
+
+
+void
+ResolverInfoContainer::copy (ResolverInfoContainer_constPtr from)
+{
+ ((ResolverInfo_Ptr)this)->copy(from);
+
+ for (CResItemList::const_iterator iter = from->_resItem_list.begin(); iter != from->_resItem_list.end(); iter++) {
+ _resItem_list.push_back (*iter);
+ }
+}
+
+
+ResolverInfo_Ptr
+ResolverInfoContainer::copy (void) const
+{
+ ResolverInfoContainer_Ptr cpy = new ResolverInfoContainer(type(), affected(), priority());
+
+ cpy->copy (this);
+
+ return cpy;
+}
+
+//---------------------------------------------------------------------------
+
+string
+ResolverInfoContainer::resItemsToString (bool names_only) const
+{
+ string res;
+
+ if (_resItem_list.empty())
+ return res;
+
+ res += " [";
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ if (iter != _resItem_list.begin())
+ res += ", ";
+
+ res += (names_only ? (*iter)->name() : (*iter)->asString());
+ }
+ res += "]";
+
+ return res;
+}
+
+
+bool
+ResolverInfoContainer::mentions (ResItem_constPtr resItem) const
+{
+ if (isAbout(resItem))
+ return true;
+
+ // Search resItem_list for any mention of the resItem.
+
+ for (CResItemList::const_iterator iter = _resItem_list.begin(); iter != _resItem_list.end(); iter++) {
+ if ((*iter)->name() == resItem->name()) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void
+ResolverInfoContainer::addRelatedResItem (ResItem_constPtr resItem)
+{
+ if (!mentions(resItem)) {
+ _resItem_list.push_front (resItem);
+ }
+}
+
+
+void
+ResolverInfoContainer::addRelatedResItemList (const CResItemList & resItems)
+{
+ for (CResItemList::const_iterator iter = resItems.begin(); iter != resItems.end(); iter++) {
+ _resItem_list.push_front (*iter);
+ }
+}
+
+///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
#include <iosfwd>
#include <list>
-#include <map>
#include <string>
#include "zypp/solver/detail/ResolverInfoContainerPtr.h"
#include "zypp/solver/detail/ResolverInfo.h"
ResolverInfo_Ptr
ResolverInfoDependsOn::copy (void) const
{
- ResolverInfoDependsOn_Ptr cpy = new ResolverInfoDependsOn(resItem(), NULL);
+ ResolverInfoDependsOn_Ptr cpy = new ResolverInfoDependsOn(affected(), NULL);
((ResolverInfoContainer_Ptr)cpy)->copy (this);
#include "zypp/solver/detail/ResolverInfo.h"
#include "zypp/solver/detail/ResolverInfoMisc.h"
#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
#include "zypp/base/Gettext.h"
/////////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
- using namespace std;
-
- IMPL_PTR_TYPE(ResolverInfoMisc);
-
- //---------------------------------------------------------------------------
-
-
- string
- ResolverInfoMisc::asString ( void ) const
- {
- return toString (*this);
- }
-
-
- string
- ResolverInfoMisc::toString ( const ResolverInfoMisc & misc)
- {
- string res;
- res += misc._msg;
- #if 0
- res += " [";
- res += ResolverInfo::toString (misc, false);
- res += "]";
- #endif
- res += misc.resItemsToString(false);
- if (!misc._action.empty()) {
- res += string (_(", Action: ")) + misc._action + "\n";
- }
- if (!misc._trigger.empty()) {
- res += string (_(", Trigger: ")) + misc._trigger + "\n";
- }
-
- return res;
- }
-
-
- ostream &
- ResolverInfoMisc::dumpOn( ostream & str ) const
- {
- str << asString();
- return str;
- }
-
-
- ostream&
- operator<<( ostream& os, const ResolverInfoMisc & misc)
- {
- return os << misc.asString();
- }
-
- //---------------------------------------------------------------------------
-
- ResolverInfoMisc::ResolverInfoMisc (ResItem_constPtr resItem, int priority, const string & msg)
- : ResolverInfoContainer (RESOLVER_INFO_TYPE_MISC, resItem, priority)
- , _msg (msg)
- {
- }
-
-
- ResolverInfoMisc::~ResolverInfoMisc ()
- {
- }
-
- //---------------------------------------------------------------------------
-
- bool
- ResolverInfoMisc::merge (ResolverInfo_Ptr info)
- {
- bool res;
- ResolverInfoMisc_Ptr to_be_merged = dynamic_pointer_cast<ResolverInfoMisc>(info);
-
- res = ResolverInfo::merge(to_be_merged);
- if (!res) return res;
-
- if (!_msg.empty()
- && !to_be_merged->_msg.empty()
- && _msg == to_be_merged->_msg) {
- return true;
- }
-
- return false;
- }
-
-
- ResolverInfo_Ptr
- ResolverInfoMisc::copy (void) const
- {
- ResolverInfoMisc_Ptr cpy = new ResolverInfoMisc(resItem(), priority(), _msg);
-
- ((ResolverInfoContainer_Ptr)cpy)->copy (this);
-
- return cpy;
- }
-
- //---------------------------------------------------------------------------
-
- void
- ResolverInfoMisc::addAction (const std::string & action_msg)
- {
- _action = action_msg;
- }
-
-
- void
- ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
- {
- _trigger = trigger_msg;
- }
-
- ///////////////////////////////////////////////////////////////////
+using namespace std;
+
+IMPL_PTR_TYPE(ResolverInfoMisc);
+
+//---------------------------------------------------------------------------
+
+
+string
+ResolverInfoMisc::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+ResolverInfoMisc::toString ( const ResolverInfoMisc & misc)
+{
+ string res;
+ res += misc.message();
+#if 0
+ res += " [";
+ res += ResolverInfo::toString (misc, false);
+ res += "]";
+#endif
+ res += misc.resItemsToString(false);
+ if (!misc._action.empty()) {
+ res += string (_(", Action: ")) + misc._action + "\n";
+ }
+ if (!misc._trigger.empty()) {
+ res += string (_(", Trigger: ")) + misc._trigger + "\n";
+ }
+
+ return res;
+}
+
+
+ostream &
+ResolverInfoMisc::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const ResolverInfoMisc & misc)
+{
+ return os << misc.asString();
+}
+
+//---------------------------------------------------------------------------
+
+ResolverInfoMisc::ResolverInfoMisc (ResolverInfoType detailedtype, ResItem_constPtr affected, int priority, const Capability & capability)
+ : ResolverInfoContainer (detailedtype, affected, priority)
+ , _capability (capability)
+{
+}
+
+
+ResolverInfoMisc::~ResolverInfoMisc ()
+{
+}
+
+//---------------------------------------------------------------------------
+
+static string
+translateResTraits (const Resolvable::Kind & kind)
+{
+ if (kind == ResTraits<Package>::kind) {
+ // Translator: Notation for (RPM) package
+ return _( "package" );
+ }
+ else if (kind == ResTraits<Selection>::kind) {
+ // Translator: Notation for SuSE package selection (set of packages)
+ return _( "selection" );
+ }
+ else if (kind == ResTraits<Pattern>::kind) {
+ // Translator: Notation for SuSE installation pattern (set of packages, describing use of system)
+ return _( "pattern" );
+ }
+ else if (kind == ResTraits<Product>::kind) {
+ // Translator: Notation for product
+ return _( "product" );
+ }
+ else if (kind == ResTraits<Patch>::kind) {
+ // Translator: Notation for patch
+ return _( "patch" );
+ }
+ else if (kind == ResTraits<Script>::kind) {
+ // Translator: Notation for script (part of a patch)
+ return _( "script" );
+ }
+ else if (kind == ResTraits<Message>::kind) {
+ // Translator: Notation for message (part of a patch)
+ return _( "message" );
+ }
+ else if (kind == ResTraits<System>::kind) {
+ // Translator: Notation for computer system
+ return _( "system" );
+ }
+
+ // Translator: Generic term for an item with dependencies, please leave untranslated for now
+ return _("Resolvable");
+}
+
+
+std::string
+ResolverInfoMisc::message (void) const
+{
+ string msg;
+
+ switch (type()) {
+
+ //===================
+ // from ResolverContext
+
+ case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {
+ // TranslatorExplanation: Additional information to dependency solver result, no solution could be found
+ msg = _("Marking this resolution attempt as invalid.");
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_UNINSTALLABLE: {
+ // Translator: %s = name of packages,patch,...
+ // TranslatorExplanation: Additional information to dependency solver result.
+ msg = str::form (_("Marking resolvable %s as uninstallable"),
+ affected()->asString().c_str());
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_REJECT_INSTALL: {
+ // Translator: %s = name of packages,patch,...
+ // TranslatorExplanation: Additional information to dependency solver result.
+ msg = str::form (_("%s is scheduled to be installed, but this is not possible because of dependency problems."),
+ affected()->asString().c_str());
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {
+ // Translator: %s = name of package,patch,...
+ // TranslatorExplanation: Additional information to dependency solver result.
+ msg = str::form (_("Can't install %s since it is already marked as needing to be uninstalled"),
+ affected()->asString().c_str());
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {
+ // Translator: %s = name of patch
+ // TranslatorExplanation: A patch which is not needed (does not apply) cant be installed
+ // TranslatorExplanation: Patches contain updates (bug fixes) to packages. Such fixes
+ // TranslatorExplanation: do only apply if the package to-be-fixed is actually installed.
+ // TranslatorExplanation: Here a patch was selected for installation but the to-be-fixed
+ // TranslatorExplanation: package is not installed.
+ msg = str::form (_("Can't install %s since it is does not apply to this system."),
+ affected()->asString().c_str());
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_INSTALL_PARALLEL: {
+ // Translator: %s = name of package,patch,...
+ msg = str::form (_("Can't install %s, since a resolvable of the same name is already marked as needing to be installed"),
+ affected()->asString().c_str());
+ }
+ break;
+
+ case RESOLVER_INFO_TYPE_INCOMPLETES: {
+ // Translator: %s = name of patch,product
+ msg = str::form (_("This would invalidate %s."),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //===================
+ // from QueueItemEstablish
+
+ //-------------------
+ // Establishing p
+ case RESOLVER_INFO_TYPE_ESTABLISHING: {
+ // Translator: %s = name of patch, pattern, ...
+ // TranslatorExplanation: Establishing is the process of computing which patches are needed
+ // TranslatorExplanation: This is just a progress indicator
+ // TranslatorExplanation: It is also used for other types of resolvables in order to verify
+ // TranslatorExplanation: the completeness of their dependencies
+ msg = str::form (_("Establishing %s"), affected()->asString().c_str());
+ }
+ break;
+
+
+ //===================
+ // from QueueItemInstall
+
+ //-------------------
+ // Installing p
+
+ case RESOLVER_INFO_TYPE_INSTALLING: {
+ // affected() = resolvable to be installed
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: %s = name of package,patch,...
+ // TranslatorExample: Installing foo
+ // TranslatorExplanation: Just a progress indicator that something is scheduled for installation
+ // Translator: %s = packagename
+ msg = str::form (_("Installing %s"),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // Updating q to p
+
+ case RESOLVER_INFO_TYPE_UPDATING: {
+ // affected() = updated resolvable
+ // _capability =
+ // other() = currently installed, being updated resolvable
+ // other_capability() =
+
+ // Translator: 1.%s and 2.%s = name of package
+ // TranslatorExample: Updating foo-1.1 to foo-1.2
+ // TranslatorExplanation: Just a progress indicator that something is scheduled for upgrade
+ msg = str::form (_("Updating %s to %s"),
+ other()->asString().c_str(),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // skipping p, already installed
+
+ case RESOLVER_INFO_TYPE_SKIPPING: {
+ // affected() =
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: %s = name of package,patch,...
+ // TranslatorExample: Skipping foo: already installed
+ // TranslatorExplanation: An installation request for foo is skipped since foo is already installed
+ msg = str::form (_("Skipping %s: already installed"), affected()->asString().c_str());
+ }
+ break;
+
+ //===================
+ // from QueueItemRequire
+
+ //-------------------
+ // There are no alternative installed providers of c [for p]
+
+ case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {
+ // affected() =
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: 1.%s = dependency
+ // TranslatorExample: There are no alternative installed providers of foo
+ // TranslatorExplanation: A resolvable is to be uninstalled. It provides 'foo' which is needed by others
+ // TranslatorExplanation: We just found out that 'foo' is not provided by anything else (an alternative)
+ // TranslatorExplanation: removal of this resolvable would therefore break dependency
+ // TranslatorExplanation: This is an error message explaining that the resolvable cannot be uninstalled
+ msg = str::form (_("There are no alternative installed providers of %s"), _capability.asString().c_str());
+ if (affected() != NULL) {
+ msg += " ";
+ // Translator: 1.%s = name of package,patch....
+ // TranslatorExample: for bar
+ // TranslatorExplanation: extension to previous message if we know what the resolvable is
+ msg += str::form (_("for %s"), affected()->asString().c_str());
+ }
+ }
+ break;
+
+ //-------------------
+ // There are no installable providers of c [for p]
+
+ case RESOLVER_INFO_TYPE_NO_PROVIDER: {
+ // affected() =
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: 1.%s = dependency
+ // TranslatorExample: There are no installable providers of foo
+ // TranslatorExplanation: A resolvable is to be installed which requires foo
+ // TranslatorExplanation: But there is nothing available to fulfill this requirement
+ // TranslatorExplanation: This is an error message explaining that the resolvable cannot be installed
+ msg = str::form (_("There are no installable providers of %s"), _capability.asString().c_str());
+ if (affected() != NULL) {
+ msg += " ";
+ // Translator: 1.%s = name of package,patch....
+ // TranslatorExample: for bar
+ // TranslatorExplanation: extension to previous message if we know what the resolvable is
+ msg += str::form (_("for %s"), affected()->asString().c_str());
+ }
+ }
+ break;
+
+ //-------------------
+ // Upgrade to q to avoid removing p is not possible
+
+ case RESOLVER_INFO_TYPE_NO_UPGRADE: {
+ // affected() = resolvable to be removed
+ // _capability =
+ // other() = failed upgrade to affected()
+ // other_capability() =
+
+ // Translator: 1.%s = name of package,patch,..., 2.%s = name of package,patch,...
+ // TranslatorExample: Upgrade to foo to avoid removing bar is not possible
+ // TranslatorExplanation: bar requires something from foo
+ msg = str::form (_("Upgrade to %s to avoid removing %s is not possible."),
+ other()->asString().c_str(),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // p provides c but is scheduled to be uninstalled
+
+ case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {
+ // affected() = requirer of capability
+ // _capability = provided by other()
+ // other() = provider of capability
+ // other_capability() = - empty -
+
+ // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
+ msg = str::form (_("%s provides %s, but is scheduled to be uninstalled."),
+ other()->asString().c_str(),
+ _capability.asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // p provides c but another version is already installed
+
+ case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {
+ // affected() = requirer of capability
+ // _capability = provided by other()
+ // other() = provider of capability
+ // other_capability() = - empty -
+
+ // Translator: 1.%s = name of package,patch,...; 2.%s = dependency; 3.%s type (package, patch, ...)
+ msg = str::form (_("%s provides %s, but another version of that %s is already installed."),
+ other()->name().c_str(),
+ _capability.asString().c_str(),
+ translateResTraits(other()->kind()).c_str());
+ }
+ break;
+
+ //-------------------
+ // p provides c but is uninstallable
+
+ case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {
+ // affected() = requirer of capability
+ // _capability = provided by other()
+ // other() = provider of capability
+ // other_capability() = - empty -
+
+ // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
+ msg = str::form (_("%s provides %s, but it is uninstallable. Try installing it on its own for more details."),
+ other()->name().c_str(),
+ _capability.asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // p provides c but is locked
+
+ case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {
+ // affected() = requirer of capability
+ // _capability = provided by other()
+ // other() = provider of capability
+ // other_capability() = - empty -
+
+ // Translator: 1.%s = name of package,patch,...; 2.%s = dependency;
+ msg = str::form (_("%s provides %s, but it is locked."),
+ other()->name().c_str(),
+ _capability.asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // Can't satisfy requirement
+
+ case RESOLVER_INFO_TYPE_CANT_SATISFY: {
+ // affected() = requirer of capability
+ // _capability = required capability
+ // other() = - empty -
+ // other_capability() = - empty -
+
+ // Translator: 1.%s = dependency. 2.%s name of package, patch, ...
+ msg = str::form (_("Can't satisfy requirement %s for %s"),
+ _capability.asString().c_str(),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //===================
+ // from QueueItemUninstall
+
+ //-------------------
+ // p is to-be-installed, so it won't be unlinked.
+
+ case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {
+ // affected() = to-be-installed resolvable which was scheduled to be uninstalled
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: %s = name of package,patch,...
+ // TranslatorExample: foo is required by other to-be-installed resolvable, so it won't be unlinked.
+ // TranslatorExplanation: Cant uninstall foo since it is required by an to-be-installed resolvable
+ string msg = str::form (_("%s is required by other to-be-installed resolvable, so it won't be unlinked."),
+ affected()->name().c_str());
+ }
+ break;
+
+ //-------------------
+ // p is required by another installed resolvable q, so it won't be unlinked.
+
+ case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {
+ // affected() = provider of cap
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: %s = name of package,patch,...
+ // TranslatorExample: foo is required by other installed resolvable, so it won't be unlinked.
+ // TranslatorExplanation: Cant uninstall foo since it is required by an installed resolvable
+ string msg = str::form (_("%s is required by other installed resolvable, so it won't be unlinked."),
+ affected()->name().c_str());
+ }
+ break;
+
+ //-------------------
+ // cant uninstall, its locked
+
+ case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {
+ // affected() = to-be-uninstalled resolvable which is locked
+ // _capability =
+ // other() =
+ // other_capability() =
+
+ // Translator: %s = name of package,patch,...
+ // TranslatorExample: foo is locked and cannot be uninstalled.
+ // TranslatorExplanation: foo is to-be-uninstalled but it is locked
+ string msg = str::form (_("%s is locked and cannot be uninstalled."),
+ affected()->name().c_str());
+ }
+ break;
+
+ //===================
+ // from QueueItemConflict
+
+ //-------------------
+ // to-be-installed p conflicts with q due to c
+
+ case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {
+ // affected() = provider of capability
+ // _capability = provided by provider
+ // other() = conflict issuer
+ // other_capability() = conflict capability
+
+ // Translator: 1.%s and 2.%s = Dependency; 4.%s = name of package,patch,...
+ // TranslatorExample: A conflict over foo (bar) requires the removal of to-be-installed xyz
+ msg = str::form(_("A conflict over %s (%s) requires the removal of to-be-installed %s"),
+ _capability.asString().c_str(),
+ _other_capability.asString().c_str(),
+ affected()->asString().c_str());
+ }
+ break;
+
+ //-------------------
+ // uninstalled p is marked uninstallable it conflicts [with q] due to c
+
+ case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {
+ // affected() = provider of capability
+ // _capability = provided by provider
+ // other() = conflict issuer
+ // other_capability() = conflict capability from issuer
+
+ // Translator: 1.%s = name of package,patch,...; 3.%s and 4.%s = Dependency;
+ // TranslatorExample: Marking xyz as uninstallable due to conflicts over foo (bar)
+ msg = str::form (_("Marking %s as uninstallable due to conflicts over %s"),
+ affected()->asString().c_str(),
+ _capability.asString().c_str());
+ ResItem_constPtr issuer = other();
+ if (issuer != NULL) {
+ msg += " ";
+ // Translator: %s = name of package,patch
+ // TranslatorExample: from abc
+ msg += str::form (_("from %s"),
+ issuer->asString().c_str());
+ }
+ }
+ break;
+
+ //===================
+ //-------------------
+
+ default:
+ WAR << "Not a InfoMisc type: " << type() << endl;
+ msg = "Unknown";
+ break;
+ }
+ return msg;
+}
+
+//---------------------------------------------------------------------------
+
+bool
+ResolverInfoMisc::merge (ResolverInfo_Ptr info)
+{
+ bool res;
+ ResolverInfoMisc_Ptr to_be_merged = dynamic_pointer_cast<ResolverInfoMisc>(info);
+
+ res = ResolverInfo::merge(to_be_merged);
+ if (!res) return res;
+
+ if (type() == to_be_merged->type()
+ && affected() == to_be_merged->affected()
+ && _capability == to_be_merged->_capability) {
+
+ return true;
+ }
+
+ return false;
+}
+
+
+ResolverInfo_Ptr
+ResolverInfoMisc::copy (void) const
+{
+ ResolverInfoMisc_Ptr cpy = new ResolverInfoMisc(type(), affected(), priority(), _capability);
+
+ ((ResolverInfoContainer_Ptr)cpy)->copy (this);
+ cpy->_other_resolvable = _other_resolvable;
+ return cpy;
+}
+
+//---------------------------------------------------------------------------
+
+void
+ResolverInfoMisc::addAction (const std::string & action_msg)
+{
+ _action = action_msg;
+}
+
+
+void
+ResolverInfoMisc::addTrigger (const std::string & trigger_msg)
+{
+ _trigger = trigger_msg;
+}
+
+void
+ResolverInfoMisc::setOtherResItem (ResItem_constPtr other)
+{
+ _other_resolvable = other;
+}
+
+void
+ResolverInfoMisc::setOtherCapability (const Capability & capability)
+{
+ _other_capability = capability;
+}
+
+///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
class ResolverInfoMisc : public ResolverInfoContainer {
-
-
- private:
-
- std::string _msg;
- std::string _action;
- std::string _trigger;
-
- public:
-
- ResolverInfoMisc (ResItem_constPtr resItem, int priority, const std::string & msg);
- virtual ~ResolverInfoMisc();
+ private:
+
+ Capability _capability; // capability leading to this info
+
+ ResItem_constPtr _other_resolvable;
+ Capability _other_capability;
+
+ std::string _action;
+ std::string _trigger;
- // ---------------------------------- I/O
+ public:
- static std::string toString (const ResolverInfoMisc & context);
- virtual std::ostream & dumpOn(std::ostream & str ) const;
- friend std::ostream& operator<<(std::ostream&, const ResolverInfoMisc & context);
- std::string asString (void ) const;
+ ResolverInfoMisc (ResolverInfoType detailedtype, ResItem_constPtr affected, int priority, const Capability & capability = Capability());
+ virtual ~ResolverInfoMisc();
- // ---------------------------------- accessors
+ // ---------------------------------- I/O
- // ---------------------------------- methods
+ static std::string toString (const ResolverInfoMisc & context);
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+ friend std::ostream& operator<<(std::ostream&, const ResolverInfoMisc & context);
+ std::string asString (void ) const;
- virtual bool merge (ResolverInfo_Ptr to_be_merged);
- virtual ResolverInfo_Ptr copy (void) const;
+ // ---------------------------------- accessors
+
+ std::string message (void) const;
+ std::string action (void) const { return _action; }
+ std::string trigger (void) const { return _trigger; }
+
+ ResItem_constPtr other (void) const { return _other_resolvable; }
+ const Capability other_capability (void) const { return _other_capability; }
+
+ // ---------------------------------- methods
- void addAction (const std::string & action_msg);
- void addTrigger (const std::string & trigger_msg);
+ virtual bool merge (ResolverInfo_Ptr to_be_merged);
+ virtual ResolverInfo_Ptr copy (void) const;
+ void addAction (const std::string & action_msg);
+ void addTrigger (const std::string & trigger_msg);
+
+ void setOtherResItem (ResItem_constPtr other);
+ void setOtherCapability (const Capability & capability);
};
///////////////////////////////////////////////////////////////////
ResolverInfo_Ptr
ResolverInfoMissingReq::copy (void) const
{
- ResolverInfoMissingReq_Ptr cpy = new ResolverInfoMissingReq(resItem(), _missing_req);
+ ResolverInfoMissingReq_Ptr cpy = new ResolverInfoMissingReq(affected(), _missing_req);
((ResolverInfo_Ptr)cpy)->copy (this);
#include "zypp/Capability.h"
/////////////////////////////////////////////////////////////////////////
-namespace zypp
+namespace zypp
{ ///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
namespace solver
/////////////////////////////////////////////////////////////////////
namespace detail
{ ///////////////////////////////////////////////////////////////////
-
+
///////////////////////////////////////////////////////////////////
//
// CLASS NAME : ResolverInfoMissingReq
-
+
class ResolverInfoMissingReq : public ResolverInfo {
-
-
-
+
private:
-
+
const Capability _missing_req;
-
+
public:
-
+
ResolverInfoMissingReq (ResItem_constPtr resItem, const Capability & missing_req);
virtual ~ResolverInfoMissingReq();
-
+
// ---------------------------------- I/O
-
+
static std::string toString (const ResolverInfoMissingReq & context);
virtual std::ostream & dumpOn(std::ostream & str ) const;
friend std::ostream& operator<<(std::ostream&, const ResolverInfoMissingReq & context);
std::string asString (void ) const;
-
+
// ---------------------------------- accessors
-
+
+ const Capability capability (void) const { return _missing_req; }
+
// ---------------------------------- methods
-
+
virtual ResolverInfo_Ptr copy (void) const;
-
+
};
-
+
///////////////////////////////////////////////////////////////////
};// namespace detail
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
};// namespace zypp
/////////////////////////////////////////////////////////////////////////
+
#endif // ZYPP_SOLVER_DETAIL_RESOLVERINFOMISSINGREQ_H
-
+
ResolverInfo_Ptr
ResolverInfoNeededBy::copy (void) const
{
- ResolverInfoNeededBy_Ptr cpy = new ResolverInfoNeededBy(resItem());
+ ResolverInfoNeededBy_Ptr cpy = new ResolverInfoNeededBy(affected());
((ResolverInfoContainer_Ptr)cpy)->copy (this);
ResolverInfo_Ptr
ResolverInfoObsoletes::copy (void) const
{
- ResolverInfoObsoletes_Ptr cpy = new ResolverInfoObsoletes(resItem(), NULL);
+ ResolverInfoObsoletes_Ptr cpy = new ResolverInfoObsoletes(affected(), NULL);
((ResolverInfoContainer_Ptr)cpy)->copy (this);
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* ResolverProblem.cc
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "zypp/solver/detail/ResolverProblem.h"
+#include "zypp/solver/detail/ProblemSolution.h"
+
+using namespace std;
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+IMPL_PTR_TYPE(ResolverProblem);
+
+//---------------------------------------------------------------------------
+
+string
+ResolverProblem::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+ResolverProblem::toString ( const ResolverProblem & problem )
+{
+ string ret ("Problem:\n");
+ ret += problem._description + "\n";
+ ret += problem._details + "\n";
+ ret += ProblemSolution::toString (problem._solutions);
+ return ret;
+}
+
+
+std::string
+ResolverProblem::toString (const ResolverProblemList & problemlist)
+{
+ string ret;
+ for (ResolverProblemList::const_iterator iter = problemlist.begin(); iter != problemlist.end(); ++iter) {
+ ret += (*iter)->asString();
+ }
+ return ret;
+}
+
+
+ostream &
+ResolverProblem::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const ResolverProblem & problem)
+{
+ return os << problem.asString();
+}
+
+//---------------------------------------------------------------------------
+
+/**
+ * Constructor.
+ **/
+ResolverProblem::ResolverProblem( const string & description, const string & details )
+ : _description (description)
+ , _details (details)
+{
+}
+
+/**
+ * Destructor.
+ **/
+ResolverProblem::~ResolverProblem()
+{
+}
+
+/**
+ * Return the possible solutions to this problem.
+ * All problems should have at least 2-3 (mutually exclusive) solutions:
+ *
+ * - Undo: Do not perform the offending transaction
+ * (do not install the package that had unsatisfied requirements,
+ * do not remove the package that would break other packages' requirements)
+ *
+ * - Remove referrers: Remove all packages that would break because
+ * they depend on the package that is requested to be removed
+ *
+ * - Ignore: Inject artificial "provides" for a missing requirement
+ * (pretend that requirement is satisfied)
+ **/
+
+ProblemSolutionList
+ResolverProblem::solutions() const
+{
+ return _solutions;
+}
+
+/**
+ * Add a solution to this problem. This class takes over ownership of
+ * the problem and will delete it when neccessary.
+ **/
+
+void
+ResolverProblem::addSolution( ProblemSolution_Ptr solution )
+{
+ _solutions.push_back (solution);
+}
+
+void
+ResolverProblem::clear()
+{
+ _solutions.clear();
+}
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
--- /dev/null
+/**
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Author: Stefan Hundhammer <sh@suse.de>
+ *
+ **/
+
+#ifndef ZYPP_SOLVER_DETAIL_RESOLVERPROBLEM_H
+#define ZYPP_SOLVER_DETAIL_RESOLVERPROBLEM_H
+
+#include <list>
+#include <string>
+
+#include "zypp/base/ReferenceCounted.h"
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/solver/detail/ResolverPtr.h"
+#include "zypp/solver/detail/ProblemSolutionPtr.h"
+#include "zypp/solver/detail/ResolverProblemPtr.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ class ResolverProblem : public base::ReferenceCounted
+ {
+ private:
+
+ /**
+ * Clear all data.
+ * In particular, delete all members of _solutions.
+ **/
+ void clear();
+
+
+ //
+ // Data members
+ //
+
+ Resolver_constPtr _resolver;
+ std::string _description;
+ std::string _details;
+ ProblemSolutionList _solutions;
+
+ public:
+
+ /**
+ * Constructor.
+ **/
+ ResolverProblem( const std::string & description, const std::string & details );
+
+ /**
+ * Destructor.
+ **/
+ ~ResolverProblem();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const ResolverProblem & problem);
+ static std::string toString (const ResolverProblemList & problemlist);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const ResolverProblem & problem);
+
+ std::string asString (void ) const;
+
+ // ---------------------------------- accessors
+
+ /**
+ * Return a one-line description of the problem.
+ **/
+ std::string description() const { return _description; }
+
+ /**
+ * Return a (possibly muti-line) detailed description of the problem
+ * or an empty string if there are no useful details.
+ **/
+ std::string details() const { return _details; }
+
+ /**
+ * Return the possible solutions to this problem.
+ * All problems should have at least 2-3 (mutually exclusive) solutions:
+ *
+ * - Undo: Do not perform the offending transaction
+ * (do not install the package that had unsatisfied requirements,
+ * do not remove the package that would break other packages' requirements)
+ *
+ * - Remove referrers: Remove all packages that would break because
+ * they depend on the package that is requested to be removed
+ *
+ * - Ignore: Inject artificial "provides" for a missing requirement
+ * (pretend that requirement is satisfied)
+ **/
+ ProblemSolutionList solutions() const;
+
+ /**
+ * Return the parent dependency resolver.
+ **/
+ Resolver_constPtr resolver() const { return _resolver; }
+
+ // ---------------------------------- methods
+
+ /**
+ * Add a solution to this problem. This class takes over ownership of
+ * the problem and will delete it when neccessary.
+ **/
+ void addSolution( ProblemSolution_Ptr solution );
+
+ };
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_SOLVER_DETAIL_RESOLVERPROBLEM_H
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* ResolverProblemPtr.h
+ *
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ZYPP_SOLVER_DETAIL_RESOLVERPROBLEMPTR_H
+#define ZYPP_SOLVER_DETAIL_RESOLVERPROBLEMPTR_H
+
+#include <list>
+#include "zypp/base/PtrTypes.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : ResolverProblem_Ptr
+ // CLASS NAME : ResolverProblem_constPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_PTR_TYPE(ResolverProblem);
+ ///////////////////////////////////////////////////////////////////
+
+ typedef std::list<ResolverProblem_Ptr> ResolverProblemList;
+ typedef std::list<ResolverProblem_constPtr> CResolverProblemList;
+
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+
+#endif // ZYPP_SOLVER_DETAIL_RESOLVERPROBLEMPTR_H
if (_context->resItemIsAbsent (resItem))
return;
- item = new QueueItemUninstall (_context->world(), resItem, "user request");
+ item = new QueueItemUninstall (_context->world(), resItem, QueueItemUninstall::EXPLICIT);
if (remove_only_mode)
item->setRemoveOnly ();
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* Resolver_problems.cc
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <map>
+
+#include "zypp/solver/temporary/ResItem.h"
+
+#include "zypp/solver/detail/Resolver.h"
+#include "zypp/solver/detail/ResolverContext.h"
+#include "zypp/solver/detail/ResolverProblem.h"
+#include "zypp/solver/detail/ProblemSolution.h"
+
+#include "zypp/solver/detail/ResolverInfoChildOf.h"
+#include "zypp/solver/detail/ResolverInfoConflictsWith.h"
+#include "zypp/solver/detail/ResolverInfoContainer.h"
+#include "zypp/solver/detail/ResolverInfoDependsOn.h"
+#include "zypp/solver/detail/ResolverInfoMisc.h"
+#include "zypp/solver/detail/ResolverInfoMissingReq.h"
+#include "zypp/solver/detail/ResolverInfoNeededBy.h"
+#include "zypp/solver/detail/ResolverInfoObsoletes.h"
+
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+#include "zypp/base/Gettext.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+typedef map<ResItem_constPtr, ResolverInfo_Ptr> ProblemMap;
+
+// set resolvables with errors
+
+typedef struct {
+ ProblemMap problems;
+} ResItemCollector;
+
+
+static void
+collector_cb (ResolverInfo_Ptr info, void *data)
+{
+ ResItemCollector *collector = (ResItemCollector *)data;
+ ResItem_constPtr resItem = info->affected();
+ if (resItem != NULL) {
+ collector->problems[resItem] = info;
+ }
+}
+
+
+ResolverProblemList
+Resolver::problems (void) const
+{
+ ResolverProblemList problems;
+
+ if (_best_context) {
+ MIL << "Valid solution found, no problems" << endl;
+ return problems;
+ }
+
+ // collect all resolvables with error
+
+ ResolverQueueList invalid = invalidQueues();
+ MIL << invalid.size() << " invalid queues" << endl;
+
+ if (invalid.empty()) {
+ WAR << "No solver problems, other error" << endl;
+ }
+
+ ResolverContext_Ptr context = invalid.front()->context();
+
+ ResItemCollector collector;
+ context->foreachInfo (NULL, RESOLVER_INFO_PRIORITY_VERBOSE, collector_cb, &collector);
+
+ for (ProblemMap::const_iterator iter = collector.problems.begin(); iter != collector.problems.end(); ++iter) {
+ ResItem_constPtr resItem = iter->first;
+ ResolverInfo_Ptr info = iter->second;
+ string who = resItem->asString();
+ string why;
+ string details;
+ switch (info->type()) {
+ case RESOLVER_INFO_TYPE_INVALID: {
+ why = "Invalide information";
+ }
+ break;
+ case RESOLVER_INFO_TYPE_NEEDED_BY: {
+ ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
+ why = "Is needed by " + needed_by->resItemsToString(true);
+ }
+ break;
+ case RESOLVER_INFO_TYPE_CONFLICTS_WITH: {
+ ResolverInfoConflictsWith_constPtr conflicts_with = dynamic_pointer_cast<const ResolverInfoConflictsWith>(info);
+ why = "Conflicts with " + conflicts_with->resItemsToString(true);
+ }
+ break;
+ case RESOLVER_INFO_TYPE_OBSOLETES: {
+ ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
+ why = "Obsoletes " + obsoletes->resItemsToString(true);
+ }
+ break;
+ case RESOLVER_INFO_TYPE_DEPENDS_ON: {
+ ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
+ why = "Depends on " + depends_on->resItemsToString(true);
+ }
+ break;
+ case RESOLVER_INFO_TYPE_CHILD_OF: { // unused
+ ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
+ why = "Child of";
+ }
+ break;
+ case RESOLVER_INFO_TYPE_MISSING_REQ: {
+ ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
+ why = "Noone provides " + missing_req->capability().asString();
+ }
+ break;
+
+ // from ResolverContext
+ case RESOLVER_INFO_TYPE_INVALID_SOLUTION: { // Marking this resolution attempt as invalid.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_UNINSTALLABLE: { // Marking p as uninstallable
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_REJECT_INSTALL: { // p is scheduled to be installed, but this is not possible because of dependency problems.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: { // Can't install p since it is already marked as needing to be uninstalled
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: { // Can't install p since it is does not apply to this system.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_INSTALL_PARALLEL: { // Can't install p, since a resolvable of the same name is already marked as needing to be installed.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_INCOMPLETES: { // This would invalidate p
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ // from QueueItemEstablish
+ case RESOLVER_INFO_TYPE_ESTABLISHING: { // Establishing p
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ // from QueueItemInstall
+ case RESOLVER_INFO_TYPE_INSTALLING: { // Installing p
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_UPDATING: { // Updating p
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_SKIPPING: { // Skipping p, already installed
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ // from QueueItemRequire
+ case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: { // There are no alternative installed providers of c [for p]
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_NO_PROVIDER: { // There are no installable providers of c [for p]
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_NO_UPGRADE: { // Upgrade to q to avoid removing p is not possible.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: { // p provides c but is scheduled to be uninstalled
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: { // p provides c but another version is already installed
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: { // p provides c but is uninstallable
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: { // p provides c but is locked
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_CANT_SATISFY: { // Can't satisfy requirement c
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ // from QueueItemUninstall
+ case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: { // p is to-be-installed, so it won't be unlinked.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: { // p is required by installed, so it won't be unlinked.
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: { // cant uninstall, its locked
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ // from QueueItemConflict
+ case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: { // to-be-installed p conflicts with q due to c
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: { // uninstalled p is marked uninstallable it conflicts [with q] due to c
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ why = misc_info->message();
+ }
+ break;
+ }
+ ResolverProblem_Ptr problem = new ResolverProblem (why, details);
+ problems.push_back (problem);
+ }
+ if (problems.empty()) {
+ context->spewInfo();
+ }
+ return problems;
+}
+
+
+void
+Resolver::applySolutions (const ProblemSolutionList & solutions)
+{
+ return;
+}
+
+///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SolutionAction.cc
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "zypp/solver/detail/Resolver.h"
+#include "zypp/solver/detail/SolutionAction.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+IMPL_PTR_TYPE(SolutionAction);
+IMPL_PTR_TYPE(TransactionSolutionAction);
+IMPL_PTR_TYPE(InjectSolutionAction);
+
+//---------------------------------------------------------------------------
+
+SolutionAction::SolutionAction()
+{
+}
+
+
+SolutionAction::~SolutionAction()
+{
+}
+
+
+std::string
+SolutionAction::toString (const SolutionActionList & actionlist)
+{
+ string ret;
+ for (SolutionActionList::const_iterator iter = actionlist.begin(); iter != actionlist.end(); ++iter) {
+ ret += (*iter)->asString();
+ ret += "\n";
+ }
+ return ret;
+}
+
+std::string
+SolutionAction::toString (const CSolutionActionList & actionlist)
+{
+ string ret;
+ for (CSolutionActionList::const_iterator iter = actionlist.begin(); iter != actionlist.end(); ++iter) {
+ ret += (*iter)->asString();
+ ret += "\n";
+ }
+ return ret;
+}
+
+//---------------------------------------------------------------------------
+
+string
+TransactionSolutionAction::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+TransactionSolutionAction::toString ( const TransactionSolutionAction & action )
+{
+ string ret ("TransactionSolutionAction: ");
+ switch (action._action) {
+ case Keep: ret += "Keep"; break;
+ case Install: ret += "Install"; break;
+ case Update: ret += "Update"; break;
+ case Remove: ret += "Remove"; break;
+ }
+ ret += " ";
+ ret += action._resolvable->asString();
+ ret += "\n";
+ return ret;
+}
+
+
+ostream &
+TransactionSolutionAction::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const TransactionSolutionAction & action)
+{
+ return os << action.asString();
+}
+
+//---------------------------------------------------------------------------
+
+string
+InjectSolutionAction::asString ( void ) const
+{
+ return toString (*this);
+}
+
+
+string
+InjectSolutionAction::toString ( const InjectSolutionAction & action )
+{
+ string ret ("InjectSolutionAction: ");
+ ret += action._capability.asString();
+ ret += "\n";
+ return ret;
+}
+
+
+ostream &
+InjectSolutionAction::dumpOn( ostream & str ) const
+{
+ str << asString();
+ return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const InjectSolutionAction & action)
+{
+ return os << action.asString();
+}
+
+//---------------------------------------------------------------------------
+
+bool
+TransactionSolutionAction::execute()
+{
+ return true;
+}
+
+bool
+InjectSolutionAction::execute()
+{
+ return true;
+}
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
--- /dev/null
+/**
+ *
+ * Easy-to use interface to the ZYPP dependency resolver
+ *
+ * Author: Stefan Hundhammer <sh@suse.de>
+ *
+ **/
+
+#ifndef ZYPP_SOLVER_DETAIL_SOLUTIONACTION_H
+#define ZYPP_SOLVER_DETAIL_SOLUTIONACTION_H
+
+#include <list>
+#include <string>
+
+#include "zypp/base/ReferenceCounted.h"
+#include "zypp/base/PtrTypes.h"
+
+#include "zypp/Capability.h"
+#include "zypp/solver/detail/Resolver.h"
+#include "zypp/solver/detail/ProblemSolutionPtr.h"
+#include "zypp/solver/detail/ResolverProblemPtr.h"
+#include "zypp/solver/detail/SolutionActionPtr.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ /**
+ * Abstract base class for one action of a problem solution.
+ **/
+ class SolutionAction : public base::ReferenceCounted
+ {
+ public:
+ SolutionAction();
+ virtual ~SolutionAction();
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const SolutionAction & action);
+ static std::string toString (const SolutionActionList & actionlist);
+ static std::string toString (const CSolutionActionList & actionlist);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const = 0;
+
+ friend std::ostream& operator<<(std::ostream&, const SolutionAction & action);
+
+ virtual std::string asString (void) const = 0;
+
+ // ---------------------------------- methods
+ /**
+ * Execute this action.
+ * Returns 'true' on success, 'false' on error.
+ **/
+ virtual bool execute() = 0;
+ };
+
+
+ /**
+ * A problem solution action that performs a transaction
+ * (installs, updates, removes, ...) one resolvable
+ * (package, patch, pattern, product).
+ **/
+ class TransactionSolutionAction: public SolutionAction
+ {
+ public:
+
+ typedef enum
+ {
+ // TO DO: use some already existing enum (?)
+ Keep,
+ Install,
+ Update,
+ Remove
+ } TransactionKind;
+
+
+ TransactionSolutionAction( ResItem_constPtr resolvable,
+ TransactionKind action )
+ : SolutionAction(), _resolvable( resolvable ), _action( action ) {}
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const TransactionSolutionAction & action);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const TransactionSolutionAction & action);
+
+ std::string asString (void) const;
+
+ // ---------------------------------- accessors
+ ResItem_constPtr resolvable() const { return _resolvable; }
+ TransactionKind action() const { return _action; }
+
+ // ---------------------------------- methods
+ virtual bool execute();
+
+
+ protected:
+
+ ResItem_constPtr _resolvable;
+ TransactionKind _action;
+ };
+
+
+ /**
+ * A problem solution action that injects an artificial "provides" to
+ * the pool to satisfy open requirements.
+ *
+ * This is typically used by "ignore" (user override) solutions.
+ **/
+ class InjectSolutionAction: public SolutionAction
+ {
+ public:
+
+ InjectSolutionAction( const Capability & provides )
+ : SolutionAction(), _capability( provides ) {}
+
+ // ---------------------------------- I/O
+
+ static std::string toString (const InjectSolutionAction & action);
+
+ virtual std::ostream & dumpOn(std::ostream & str ) const;
+
+ friend std::ostream& operator<<(std::ostream&, const InjectSolutionAction & action);
+
+ std::string asString (void) const;
+
+ // ---------------------------------- accessors
+ const Capability & capability() const { return _capability; };
+
+ // ---------------------------------- methods
+ virtual bool execute();
+
+ protected:
+
+ const Capability & _capability;
+ };
+
+
+ ///////////////////////////////////////////////////////////////////
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_SOLVER_DETAIL_SOLUTIONACTION_H
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* SolutionActionPtr.h
+ *
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef ZYPP_SOLVER_DETAIL_SOLUTIONACTIONPTR_H
+#define ZYPP_SOLVER_DETAIL_SOLUTIONACTIONPTR_H
+
+#include "zypp/base/PtrTypes.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ namespace solver
+ { /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ namespace detail
+ { ///////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////
+ // CLASS NAME : SolutionAction_Ptr
+ // CLASS NAME : SolutionAction_constPtr
+ ///////////////////////////////////////////////////////////////////
+ DEFINE_PTR_TYPE(SolutionAction);
+ ///////////////////////////////////////////////////////////////////
+
+ typedef std::list<SolutionAction_Ptr> SolutionActionList;
+ typedef std::list<SolutionAction_constPtr> CSolutionActionList;
+
+ };// namespace detail
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ };// namespace solver
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+
+#endif // ZYPP_SOLVER_DETAIL_SOLUTIONACTIONPTR_H