- make ResolverInfoMisc *much* more detailed.
authorKlaus Kaempf <kkaempf@suse.de>
Sun, 22 Jan 2006 13:59:52 +0000 (13:59 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Sun, 22 Jan 2006 13:59:52 +0000 (13:59 +0000)
- remove the strings inside, generate on demand in accessor
- prepare for Problem->Solution->Action interface required by UI

39 files changed:
zypp/solver/detail/Makefile.am
zypp/solver/detail/ProblemSolution.cc [new file with mode: 0644]
zypp/solver/detail/ProblemSolution.h [new file with mode: 0644]
zypp/solver/detail/ProblemSolutionPtr.h [new file with mode: 0644]
zypp/solver/detail/QueueItem.cc
zypp/solver/detail/QueueItem.h
zypp/solver/detail/QueueItemBranch.cc
zypp/solver/detail/QueueItemConflict.cc
zypp/solver/detail/QueueItemEstablish.cc
zypp/solver/detail/QueueItemGroup.cc
zypp/solver/detail/QueueItemInstall.cc
zypp/solver/detail/QueueItemRequire.cc
zypp/solver/detail/QueueItemUninstall.cc
zypp/solver/detail/QueueItemUninstall.h
zypp/solver/detail/Resolver.cc
zypp/solver/detail/Resolver.h
zypp/solver/detail/ResolverContext.cc
zypp/solver/detail/ResolverContext.h
zypp/solver/detail/ResolverInfo.cc
zypp/solver/detail/ResolverInfo.h
zypp/solver/detail/ResolverInfoChildOf.cc
zypp/solver/detail/ResolverInfoConflictsWith.cc
zypp/solver/detail/ResolverInfoContainer.cc
zypp/solver/detail/ResolverInfoContainer.h
zypp/solver/detail/ResolverInfoDependsOn.cc
zypp/solver/detail/ResolverInfoMisc.cc
zypp/solver/detail/ResolverInfoMisc.h
zypp/solver/detail/ResolverInfoMissingReq.cc
zypp/solver/detail/ResolverInfoMissingReq.h
zypp/solver/detail/ResolverInfoNeededBy.cc
zypp/solver/detail/ResolverInfoObsoletes.cc
zypp/solver/detail/ResolverProblem.cc [new file with mode: 0644]
zypp/solver/detail/ResolverProblem.h [new file with mode: 0644]
zypp/solver/detail/ResolverProblemPtr.h [new file with mode: 0644]
zypp/solver/detail/ResolverQueue.cc
zypp/solver/detail/Resolver_problems.cc [new file with mode: 0644]
zypp/solver/detail/SolutionAction.cc [new file with mode: 0644]
zypp/solver/detail/SolutionAction.h [new file with mode: 0644]
zypp/solver/detail/SolutionActionPtr.h [new file with mode: 0644]

index 3190dae..e246341 100644 (file)
@@ -58,7 +58,12 @@ solverdetailinclude_HEADERS = \
        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
 
@@ -76,6 +81,7 @@ lib@PACKAGE@_solver_detail_la_SOURCES =                       \
        QueueItemRequire.cc                             \
        QueueItemUninstall.cc                           \
        Resolver.cc                                     \
+       Resolver_problems.cc                            \
        ResolverInfo.cc                                 \
        ResolverInfoChildOf.cc                          \
        ResolverInfoConflictsWith.cc                    \
@@ -86,5 +92,7 @@ lib@PACKAGE@_solver_detail_la_SOURCES =                       \
        ResolverInfoNeededBy.cc                         \
        ResolverInfoObsoletes.cc                        \
        ResolverContext.cc                              \
-       ResolverQueue.cc
-
+       ResolverQueue.cc                                \
+       ProblemSolution.cc                              \
+       SolutionAction.cc                               \
+       ResolverProblem.cc
diff --git a/zypp/solver/detail/ProblemSolution.cc b/zypp/solver/detail/ProblemSolution.cc
new file mode 100644 (file)
index 0000000..d8a6a89
--- /dev/null
@@ -0,0 +1,154 @@
+
+/* -*- 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
+/////////////////////////////////////////////////////////////////////////
diff --git a/zypp/solver/detail/ProblemSolution.h b/zypp/solver/detail/ProblemSolution.h
new file mode 100644 (file)
index 0000000..31767f7
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+ *
+ * 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
+
diff --git a/zypp/solver/detail/ProblemSolutionPtr.h b/zypp/solver/detail/ProblemSolutionPtr.h
new file mode 100644 (file)
index 0000000..d744785
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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
index fe26392..785e529 100644 (file)
@@ -99,7 +99,7 @@ namespace zypp
       //---------------------------------------------------------------------------
       
       void
-      QueueItem::copy (QueueItem_constPtr from)
+      QueueItem::copy (const QueueItem *from)
       {
           _priority = from->_priority;
           _size = from->_size;
index 4b046f4..a74ba1f 100644 (file)
@@ -107,7 +107,7 @@ namespace zypp
 
           // ---------------------------------- 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; }
index 328d1fe..b5ac839 100644 (file)
@@ -34,249 +34,243 @@ namespace zypp
     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
     /////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////
index 58c694b..3384d6b 100644 (file)
@@ -138,38 +138,34 @@ upgrade_candidates_cb (ResItem_constPtr resItem, const Capability & cap, void *d
 
 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. */
@@ -178,145 +174,121 @@ conflict_process_cb (ResItem_constPtr resItem, const Capability & cap, void *dat
      * 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;
@@ -328,13 +300,14 @@ QueueItemConflict::process (ResolverContext_Ptr context, QueueItemList & new_ite
 {
     _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);
 
@@ -348,7 +321,7 @@ QueueItem_Ptr
 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 !
 
@@ -361,11 +334,11 @@ QueueItemConflict::cmp (QueueItem_constPtr item) const
 {
     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;
 }
index 8b6bc52..3588d0e 100644 (file)
 
 #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"
@@ -125,10 +124,8 @@ QueueItemEstablish::process (ResolverContext_Ptr context, QueueItemList & qil)
 
     _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.  */
@@ -176,7 +173,7 @@ QueueItem_Ptr
 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;
index bb87107..551e54f 100644 (file)
@@ -33,130 +33,130 @@ namespace zypp
     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
     /////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////
index ec7b441..42aea6a 100644 (file)
@@ -190,10 +190,7 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
            _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;
        }
@@ -229,7 +226,7 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
            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);
            }
 
@@ -253,7 +250,7 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
            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)
@@ -281,23 +278,23 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
            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();
@@ -359,7 +356,7 @@ QueueItemInstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
            _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);
@@ -386,7 +383,7 @@ QueueItem_Ptr
 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());
index 1f1b025..928ca4a 100644 (file)
@@ -180,30 +180,24 @@ no_installable_providers_info_cb (ResItem_constPtr resItem, const Capability & c
 
     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;
@@ -253,8 +247,7 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
     _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;
     }
 
@@ -281,7 +274,7 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
 
     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;
@@ -291,31 +284,11 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
            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.
@@ -383,17 +356,10 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
                && 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);
 
@@ -422,7 +388,7 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
 
        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) {
@@ -443,16 +409,14 @@ QueueItemRequire::process (ResolverContext_Ptr context, QueueItemList & new_item
            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);
@@ -498,8 +462,8 @@ QueueItem_Ptr
 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;
index 10bb0f8..2bacf85 100644 (file)
@@ -26,6 +26,7 @@
 #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"
@@ -61,7 +62,17 @@ QueueItemUninstall::toString ( const QueueItemUninstall & item)
     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();
@@ -97,7 +108,7 @@ operator<<( ostream& os, const QueueItemUninstall & item)
 
 //---------------------------------------------------------------------------
 
-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)
@@ -134,25 +145,29 @@ QueueItemUninstall::setUnlink ()
 
 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;
 }
@@ -174,13 +189,13 @@ uninstall_process_cb (ResItem_constPtr resItem, const Capability & dep, void *da
 {
     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;
@@ -223,12 +238,12 @@ QueueItemUninstall::process (ResolverContext_Ptr context, QueueItemList & qil)
        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;
@@ -240,6 +255,9 @@ QueueItemUninstall::process (ResolverContext_Ptr context, QueueItemList & qil)
            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);
@@ -248,17 +266,13 @@ QueueItemUninstall::process (ResolverContext_Ptr context, QueueItemList & qil)
            /* 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);
@@ -267,16 +281,15 @@ QueueItemUninstall::process (ResolverContext_Ptr context, QueueItemList & qil)
 
        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)
        {
@@ -322,7 +335,7 @@ QueueItem_Ptr
 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;
index e32b2be..545c988 100644 (file)
@@ -47,52 +47,63 @@ namespace zypp
       //       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; }
 
       };
 
index 34da797..556cc8c 100644 (file)
@@ -261,13 +261,13 @@ Resolver::verifySystem (void)
                    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);
@@ -336,7 +336,7 @@ Resolver::establishState (ResolverContext_Ptr context)
 
 //---------------------------------------------------------------------------
 
-void
+bool
 Resolver::resolveDependencies (const ResolverContext_Ptr context)
 {
 
@@ -436,7 +436,7 @@ 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);
@@ -445,32 +445,34 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
 
     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);
 
@@ -519,7 +521,8 @@ Resolver::resolveDependencies (const ResolverContext_Ptr context)
                        << " / Prun " << (long) _pruned_queues.size()
                        << " / Defr " << (long) _deferred_queues.size()
                        << " / Invl " << (long) _invalid_queues.size() << endl;
-    return;
+
+    return _best_context && _best_context->isValid();
 }
 
 ///////////////////////////////////////////////////////////////////
index fee16c3..f19f5c3 100644 (file)
 #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"
@@ -134,7 +135,10 @@ namespace zypp
 
           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);
       };
index 15010e1..7dd5a67 100644 (file)
@@ -254,6 +254,8 @@ ResolverContext::getStatus (ResItem_constPtr resItem)
 //---------------------------------------------------------------------------
 // status change
 
+// change state to TO_BE_INSTALLED (does not upgrade)
+
 bool
 ResolverContext::installResItem (ResItem_constPtr resItem, bool is_soft, int other_penalty)
 {
@@ -267,17 +269,14 @@ ResolverContext::installResItem (ResItem_constPtr resItem, bool is_soft, int oth
 
     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;
     }
 
@@ -286,10 +285,8 @@ ResolverContext::installResItem (ResItem_constPtr resItem, bool is_soft, int oth
     }
 
     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;
     }
 
@@ -324,6 +321,8 @@ ResolverContext::installResItem (ResItem_constPtr resItem, bool is_soft, int oth
 }
 
 
+// change state to TO_BE_INSTALLED (does upgrade)
+
 bool
 ResolverContext::upgradeResItem (ResItem_constPtr resItem, ResItem_constPtr old_resItem, bool is_soft, int other_penalty)
 {
@@ -367,6 +366,8 @@ ResolverContext::upgradeResItem (ResItem_constPtr resItem, ResItem_constPtr old_
 }
 
 
+// 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)
 {
@@ -383,9 +384,8 @@ ResolverContext::uninstallResItem (ResItem_constPtr resItem, bool part_of_upgrad
     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;
     }
 
@@ -396,12 +396,10 @@ ResolverContext::uninstallResItem (ResItem_constPtr resItem, bool part_of_upgrad
 
     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;
@@ -416,6 +414,8 @@ ResolverContext::uninstallResItem (ResItem_constPtr resItem, bool part_of_upgrad
 }
 
 
+// change state to UNNEEDED
+
 bool
 ResolverContext::unneededResItem (ResItem_constPtr resItem, int other_penalty)
 {
@@ -435,6 +435,8 @@ ResolverContext::unneededResItem (ResItem_constPtr resItem, int other_penalty)
 }
 
 
+// change state to SATISFIED
+
 bool
 ResolverContext::satisfyResItem (ResItem_constPtr resItem, int other_penalty)
 {
@@ -457,6 +459,8 @@ ResolverContext::satisfyResItem (ResItem_constPtr resItem, int other_penalty)
 }
 
 
+// change state to INCOMPLETE
+
 bool
 ResolverContext::incompleteResItem (ResItem_constPtr resItem, int other_penalty)
 {
@@ -467,8 +471,8 @@ 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;
@@ -956,7 +960,7 @@ ResolverContext::addInfo (ResolverInfo_Ptr info)
     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);
        }
@@ -967,18 +971,8 @@ ResolverContext::addInfo (ResolverInfo_Ptr 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);
 }
@@ -1010,7 +1004,7 @@ mark_important_info (InfoList & il)
        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);
            }
@@ -1091,7 +1085,7 @@ ResolverContext::foreachInfo (ResItem_Ptr resItem, int priority, ResolverInfoFn
     // 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());
            }
index c5b6cfe..74d3ef2 100644 (file)
@@ -181,8 +181,7 @@ class ResolverContext : public base::ReferenceCounted, private base::NonCopyable
     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);
index a91c36c..9e8e219 100644 (file)
@@ -34,164 +34,176 @@ namespace zypp
     /////////////////////////////////////////////////////////////////////
     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
     /////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////
index 0b7787a..a3b11e9 100644 (file)
@@ -52,7 +52,36 @@ typedef enum {
     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
@@ -72,7 +101,9 @@ class ResolverInfo : public base::ReferenceCounted, private base::NonCopyable {
   private:
 
     ResolverInfoType _type;
-    ResItem_constPtr _resItem;
+
+    ResItem_constPtr _affected;
+
     int _priority;
 
     bool _error;
@@ -80,7 +111,7 @@ class ResolverInfo : public base::ReferenceCounted, private base::NonCopyable {
 
   protected:
 
-    ResolverInfo (ResolverInfoType type, ResItem_constPtr resItem, int priority);
+    ResolverInfo (ResolverInfoType type, ResItem_constPtr affected, int priority);
 
   public:
 
@@ -98,7 +129,7 @@ class ResolverInfo : public base::ReferenceCounted, private base::NonCopyable {
     // ---------------------------------- 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; }
index de5378e..899d41f 100644 (file)
@@ -95,7 +95,7 @@ namespace zypp
       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);
       
index 20a6949..84b3ce0 100644 (file)
@@ -92,7 +92,7 @@ namespace zypp
       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);
       
index 4363b82..7e23327 100644 (file)
@@ -32,175 +32,175 @@ namespace zypp
     /////////////////////////////////////////////////////////////////////
     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
     /////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////
index e010212..bff7424 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <iosfwd>
 #include <list>
-#include <map>
 #include <string>
 #include "zypp/solver/detail/ResolverInfoContainerPtr.h"
 #include "zypp/solver/detail/ResolverInfo.h"
index 799c515..33b8640 100644 (file)
@@ -91,7 +91,7 @@ namespace zypp
       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);
       
index 862f9f8..f61ce14 100644 (file)
@@ -24,6 +24,7 @@
 #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"
 
 /////////////////////////////////////////////////////////////////////////
@@ -36,116 +37,573 @@ namespace zypp
     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
     /////////////////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////////////////
index 2fac8ea..b0c7476 100644 (file)
@@ -42,36 +42,47 @@ namespace zypp
       
       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);
       };
 
       ///////////////////////////////////////////////////////////////////
index 754924b..606571d 100644 (file)
@@ -92,7 +92,7 @@ namespace zypp
       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);
       
index 8caeddd..64ef895 100644 (file)
@@ -27,7 +27,7 @@
 #include "zypp/Capability.h"
 
 /////////////////////////////////////////////////////////////////////////
-namespace zypp 
+namespace zypp
 { ///////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////
   namespace solver
@@ -35,39 +35,39 @@ namespace zypp
     /////////////////////////////////////////////////////////////////////
     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
     /////////////////////////////////////////////////////////////////////
@@ -77,5 +77,6 @@ namespace zypp
   ///////////////////////////////////////////////////////////////////////
 };// namespace zypp
 /////////////////////////////////////////////////////////////////////////
+
 #endif // ZYPP_SOLVER_DETAIL_RESOLVERINFOMISSINGREQ_H
+
index 8de5913..407b169 100644 (file)
@@ -91,7 +91,7 @@ namespace zypp
       ResolverInfo_Ptr
       ResolverInfoNeededBy::copy (void) const
       {
-          ResolverInfoNeededBy_Ptr cpy = new ResolverInfoNeededBy(resItem());
+          ResolverInfoNeededBy_Ptr cpy = new ResolverInfoNeededBy(affected());
       
           ((ResolverInfoContainer_Ptr)cpy)->copy (this);
       
index 7761840..a623c7f 100644 (file)
@@ -91,7 +91,7 @@ namespace zypp
       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);
       
diff --git a/zypp/solver/detail/ResolverProblem.cc b/zypp/solver/detail/ResolverProblem.cc
new file mode 100644 (file)
index 0000000..8962bd5
--- /dev/null
@@ -0,0 +1,150 @@
+/* -*- 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
+/////////////////////////////////////////////////////////////////////////
diff --git a/zypp/solver/detail/ResolverProblem.h b/zypp/solver/detail/ResolverProblem.h
new file mode 100644 (file)
index 0000000..3950355
--- /dev/null
@@ -0,0 +1,129 @@
+/**
+ *
+ * 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
+
diff --git a/zypp/solver/detail/ResolverProblemPtr.h b/zypp/solver/detail/ResolverProblemPtr.h
new file mode 100644 (file)
index 0000000..cd391c4
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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
index c9ec8f7..276cda9 100644 (file)
@@ -142,7 +142,7 @@ ResolverQueue::addResItemToRemove (ResItem_constPtr resItem, bool remove_only_mo
     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 ();
 
diff --git a/zypp/solver/detail/Resolver_problems.cc b/zypp/solver/detail/Resolver_problems.cc
new file mode 100644 (file)
index 0000000..b4fc939
--- /dev/null
@@ -0,0 +1,294 @@
+/* -*- 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
+/////////////////////////////////////////////////////////////////////////
+
diff --git a/zypp/solver/detail/SolutionAction.cc b/zypp/solver/detail/SolutionAction.cc
new file mode 100644 (file)
index 0000000..03e5c1c
--- /dev/null
@@ -0,0 +1,172 @@
+/* -*- 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
+/////////////////////////////////////////////////////////////////////////
diff --git a/zypp/solver/detail/SolutionAction.h b/zypp/solver/detail/SolutionAction.h
new file mode 100644 (file)
index 0000000..34451a9
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+ *
+ * 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
+
diff --git a/zypp/solver/detail/SolutionActionPtr.h b/zypp/solver/detail/SolutionActionPtr.h
new file mode 100644 (file)
index 0000000..0c6b220
--- /dev/null
@@ -0,0 +1,56 @@
+/* -*- 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