summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/contrib/error.cc4
-rw-r--r--apt-pkg/contrib/error.h23
-rw-r--r--apt-pkg/orderlist.cc79
3 files changed, 98 insertions, 8 deletions
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index fbb6e4636..d63b06d13 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -180,7 +180,7 @@ bool GlobalError::PopMessage(std::string &Text) {
}
/*}}}*/
// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/
-void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold,
+void GlobalError::DumpErrors(std::ostream &out, MsgType const &threshold,
bool const &mergeStack) {
if (mergeStack == true)
for (std::list<MsgStack>::const_reverse_iterator s = Stacks.rbegin();
@@ -189,7 +189,7 @@ void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold,
for (std::list<Item>::const_iterator m = Messages.begin();
m != Messages.end(); m++)
- if (m->Type >= trashhold)
+ if (m->Type >= threshold)
out << (*m) << std::endl;
Discard();
}
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
index e5517c2da..4af0302c0 100644
--- a/apt-pkg/contrib/error.h
+++ b/apt-pkg/contrib/error.h
@@ -204,9 +204,10 @@ public: /*{{{*/
* displayed or not.
*
* \param[out] out output stream to write the messages in
- * \param WithoutNotice output notices or not
+ * \param threshold minimim level considered
+ * \param mergeStack
*/
- void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING,
+ void DumpErrors(std::ostream &out, MsgType const &threshold = WARNING,
bool const &mergeStack = true);
/** \brief dumps the list of messages to std::cerr
@@ -214,10 +215,22 @@ public: /*{{{*/
* Note that all messages are discarded, also the notices
* displayed or not.
*
- * \param WithoutNotice print notices or not
+ * \param threshold minimum level printed
*/
- void inline DumpErrors(MsgType const &trashhold = WARNING) {
- DumpErrors(std::cerr, trashhold);
+ void inline DumpErrors(MsgType const &threshold) {
+ DumpErrors(std::cerr, threshold);
+ }
+
+ // mvo: we do this instead of using a default parameter in the
+ // previous declaration to avoid a (subtle) API break for
+ // e.g. sigc++ and mem_fun0
+ /** \brief dumps the messages of type WARNING or higher to std::cerr
+ *
+ * Note that all messages are discarded, displayed or not.
+ *
+ */
+ void inline DumpErrors() {
+ DumpErrors(WARNING);
}
/** \brief put the current Messages into the stack
diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc
index 55f9cb9cc..602b63d3b 100644
--- a/apt-pkg/orderlist.cc
+++ b/apt-pkg/orderlist.cc
@@ -886,13 +886,16 @@ bool pkgOrderList::DepRemove(DepIterator D)
continue;
/* We wish to see if the dep on the parent package is okay
- in the removed (install) state of the target pkg. */
+ in the removed (install) state of the target pkg. */
+ bool tryFixDeps = false;
if (CheckDep(D) == true)
{
// We want to catch loops with the code below.
if (IsFlag(D.ParentPkg(),AddPending) == false)
continue;
}
+ else
+ tryFixDeps = true;
// This is the loop detection
if (IsFlag(D.ParentPkg(),Added) == true ||
@@ -903,6 +906,80 @@ bool pkgOrderList::DepRemove(DepIterator D)
continue;
}
+ if (tryFixDeps == true)
+ {
+ for (pkgCache::DepIterator F = D.ParentPkg().CurrentVer().DependsList();
+ F.end() == false; ++F)
+ {
+ if (F->Type != pkgCache::Dep::Depends && F->Type != pkgCache::Dep::PreDepends)
+ continue;
+ // Check the Providers
+ if (F.TargetPkg()->ProvidesList != 0)
+ {
+ pkgCache::PrvIterator Prov = F.TargetPkg().ProvidesList();
+ for (; Prov.end() == false; ++Prov)
+ {
+ pkgCache::PkgIterator const P = Prov.OwnerPkg();
+ if (IsFlag(P, InList) == true &&
+ IsFlag(P, AddPending) == true &&
+ IsFlag(P, Added) == false &&
+ Cache[P].InstallVer == 0)
+ break;
+ }
+ if (Prov.end() == false)
+ for (pkgCache::PrvIterator Prv = F.TargetPkg().ProvidesList();
+ Prv.end() == false; ++Prv)
+ {
+ pkgCache::PkgIterator const P = Prv.OwnerPkg();
+ if (IsFlag(P, InList) == true &&
+ IsFlag(P, AddPending) == false &&
+ Cache[P].InstallVer != 0 &&
+ VisitNode(P) == true)
+ {
+ Flag(P, Immediate);
+ tryFixDeps = false;
+ break;
+ }
+ }
+ if (tryFixDeps == false)
+ break;
+ }
+
+ // Check for Or groups
+ if ((F->CompareOp & pkgCache::Dep::Or) != pkgCache::Dep::Or)
+ continue;
+ // Lets see if the package is part of the Or group
+ pkgCache::DepIterator S = F;
+ for (; S.end() == false; ++S)
+ {
+ if (S.TargetPkg() == D.TargetPkg())
+ break;
+ if ((S->CompareOp & pkgCache::Dep::Or) != pkgCache::Dep::Or ||
+ CheckDep(S)) // Or group is satisfied by another package
+ for (;S.end() == false; ++S);
+ }
+ if (S.end() == true)
+ continue;
+ // skip to the end of the or group
+ for (;S.end() == false && (S->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; ++S);
+ ++S;
+ // The soon to be removed is part of the Or group
+ // start again in the or group and find something which will serve as replacement
+ for (; F.end() == false && F != S; ++F)
+ {
+ if (F.TargetPkg() == D.TargetPkg() ||
+ IsFlag(F.TargetPkg(), InList) == false ||
+ VisitNode(F.TargetPkg()) == false)
+ continue;
+ Flag(F.TargetPkg(), Immediate);
+ tryFixDeps = false;
+ break;
+ }
+ if (tryFixDeps == false)
+ break;
+ }
+ }
+
// Skip over missing files
if (IsMissing(D.ParentPkg()) == true)
continue;