[Aptitude-devel] r3252 - in branches/aptitude-0.3/aptitude: . src/generic src/generic/problemresolver
Daniel Burrows
dburrows@costa.debian.org
Mon, 02 May 2005 01:39:02 +0000
Author: dburrows
Date: Mon May 2 01:38:58 2005
New Revision: 3252
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
Log:
Make sure to iterate over the dependencies of a version when marking it for
installation.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Mon May 2 01:38:58 2005
@@ -1,5 +1,11 @@
2005-05-01 Daniel Burrows <dburrows@debian.org>
+ * src/generic/aptitude_resolver.h, src/generic/problemresolver/problemresolver.h, src/generic/problemresolver/test.cc:
+
+ Fix a mistake in how successors are generated -- of course we have
+ to test the dependencies of the new version being installed as
+ well!
+
* src/solution_fragment.cc:
Fix a silly thinko that caused segfaults when trying to display
Modified: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h (original)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver.h Mon May 2 01:38:58 2005
@@ -216,8 +216,10 @@
}
class revdep_iterator;
+ class dep_iterator;
revdep_iterator revdeps_begin() const;
+ dep_iterator deps_begin() const;
};
inline aptitude_resolver_version aptitude_resolver_package::current_version() const
@@ -518,11 +520,145 @@
}
};
+/** Iterates over the distinct dependencies of a version. These
+ * include its direct/indirect dependencies (separated into OR
+ * groups) and its direct/indirect conflicts (one apiece).
+ */
+class aptitude_resolver_version::dep_iterator
+{
+ pkgDepCache *cache;
+ pkgCache::DepIterator dep;
+ pkgCache::PrvIterator prv;
+ /** If \b true, then dep is a Conflicts and we are iterating over
+ * the packages providing its target.
+ */
+ bool prv_open;
+
+ void normalize()
+ {
+ if(prv_open)
+ {
+ assert(!dep.end());
+ assert(dep->Type == pkgCache::Dep::Conflicts);
+
+ while(!prv.end() && prv.OwnerPkg()==dep.ParentPkg())
+ ++prv;
+
+ if(prv.end())
+ {
+ prv_open=false;
+ ++dep;
+ }
+ else
+ return;
+ }
+
+ assert(!prv_open);
+
+
+ // Skip non-critical and self dependencies. Need to do this here
+ // as well as below in case dep already points to such a
+ // dependency.
+ while(!dep.end() &&
+ (dep.ParentPkg() == dep.TargetPkg() ||
+ !dep.IsCritical()))
+ ++dep;
+
+ // If we ran out of deps, we're done!
+ }
+
+public:
+ dep_iterator(pkgDepCache *_cache)
+ :cache(_cache),
+ prv(*_cache, 0, (pkgCache::Package *) 0),
+ prv_open(false)
+ {
+ }
+
+
+ dep_iterator(const pkgCache::DepIterator &start,
+ pkgDepCache *_cache)
+ :cache(_cache),
+ dep(start),
+ prv(*_cache, 0, (pkgCache::Package *) 0),
+ prv_open(false)
+ {
+ normalize();
+ }
+
+ dep_iterator &operator=(const dep_iterator &other)
+ {
+ cache=other.cache;
+ dep=other.dep;
+ prv=other.prv;
+ prv_open=other.prv_open;
+
+ return *this;
+ }
+
+ aptitude_resolver_dep operator*() const
+ {
+ return aptitude_resolver_dep(dep, prv, cache);
+ }
+
+ bool end() const
+ {
+ return dep.end();
+ }
+
+ dep_iterator &operator++()
+ {
+ assert(!dep.end());
+
+ // If the Provides list is nonempty, advance it.
+ if(!prv.end())
+ ++prv;
+ // If we weren't trying to iterate over a Provides list *and* the
+ // current dep is a non-versioned Conflicts, start such an
+ // iteration.
+ else if(!prv_open && dep->Type == pkgCache::Dep::Conflicts &&
+ !dep.TargetVer())
+ {
+ prv_open=true;
+ prv=dep.TargetPkg().ProvidesList();
+ }
+ // Otherwise push on to the next top-level dep.
+ else
+ {
+ if(!dep.end() && dep->Type == pkgCache::Dep::Conflicts)
+ ++dep;
+ else
+ {
+ // If it's not a conflict, skip a whole OR group.
+ while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
+ ++dep;
+
+ // Now we're on the last element of the OR group, push
+ // forward.
+ if(!dep.end())
+ ++dep;
+ }
+ }
+
+ normalize();
+
+ return *this;
+ }
+};
+
inline aptitude_resolver_version::revdep_iterator aptitude_resolver_version::revdeps_begin() const
{
return revdep_iterator(ver, cache);
}
+inline aptitude_resolver_version::dep_iterator aptitude_resolver_version::deps_begin() const
+{
+ if(ver.end())
+ return dep_iterator(cache);
+ else
+ return dep_iterator(ver.DependsList(), cache);
+}
+
/** This class uses a technique similar to rev_dep_lst. It assumes
* that the dependency is critical (noncritical deps are weeded out
* by the universe's broken_dep_iterator and hidden from the
@@ -926,57 +1062,21 @@
{
pkgDepCache *cache;
- class pkgCache::PkgIterator pkg;
- class pkgCache::VerIterator ver;
- class pkgCache::DepIterator dep;
- class pkgCache::PrvIterator prv;
- bool prv_open;
+ pkgCache::PkgIterator pkg;
+ pkgCache::VerIterator ver;
+ aptitude_resolver_version::dep_iterator dep;
// Advance to the next valid dep (inclusive of dep).
void normalize()
{
- // If prv_open, we are iterating over the Provides of something
- // upon which a package depends. This is a good situation
- // *unless* we ran out of Provides or we have an indirect
- // self-conflict.
- if(prv_open)
- {
- assert(!dep.end());
- assert(dep->Type == pkgCache::Dep::Conflicts);
-
- while(!prv.end() && prv.OwnerPkg()==dep.ParentPkg())
- ++prv;
-
- if(prv.end())
- {
- prv_open=false;
- ++dep;
- }
- else
- return;
- }
-
- assert(!prv_open);
-
- // Skip any dependencies that shouldn't show up in the output.
- // Need to do this here as well as below in case dep already
- // points to such a dependency.
- while(!dep.end() &&
- (dep.ParentPkg() == dep.TargetPkg() ||
- !dep.IsCritical()))
- ++dep;
-
- // Now, if we ran our of deps, try to find another one.
while(dep.end() && !pkg.end())
{
while(dep.end() && !ver.end())
{
- // Since dep is an end iterator, advance at least
- // to the next version.
++ver;
-
if(!ver.end())
- dep=ver.DependsList();
+ dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+ cache);
}
if(dep.end())
@@ -986,80 +1086,41 @@
{
ver=pkg.VersionList();
if(!ver.end())
- dep=ver.DependsList();
+ dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+ cache);
}
}
-
- // Avoid direct self-deps and non-critical
- // deps. (self-conflicts in particular, but a non-conflict
- // self-dep is pointless)
- while(!dep.end() &&
- (dep.ParentPkg() == dep.TargetPkg() ||
- !dep.IsCritical()))
- ++dep;
}
}
public:
-#if 0
- dep_iterator()
- :cache(0)
- {
- }
-#endif
-
// Start from the given package (typically Head() or End()).
dep_iterator(const pkgCache::PkgIterator &_pkg,
pkgDepCache *_cache)
:cache(_cache),
- pkg(_pkg), prv(*_cache, 0, (pkgCache::Package *) 0),
- prv_open(false)
+ pkg(_pkg),
+ ver(_pkg.VersionList()),
+ dep(_cache)
{
if(!pkg.end())
ver=pkg.VersionList();
if(!ver.end())
- dep=ver.DependsList();
+ dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+ _cache);
normalize();
}
aptitude_universe::dep operator*() const
{
- return aptitude_universe::dep(dep, prv, cache);
+ return *dep;
}
dep_iterator &operator++()
{
assert(!dep.end());
- // If the Provides list is open, advance it.
- if(!prv.end())
- ++prv;
- // otherwise, if we aren't trying to iterate over a Provides
- // list and the current dep is a Conflicts, start such an
- // iteration.
- else if(!prv_open && dep->Type == pkgCache::Dep::Conflicts)
- {
- prv_open=true;
- prv=dep.TargetPkg().ProvidesList();
- }
- // Otherwise just advance blindly.
- else
- {
- if(!dep.end() && dep->Type == pkgCache::Dep::Conflicts)
- ++dep;
- else
- {
- // Advance to the end of the OR...
- while(!dep.end() && (dep->CompareOp & pkgCache::Dep::Or))
- ++dep;
-
- // ...and beyond!
- if(!dep.end())
- ++dep;
- }
- }
+ ++dep;
- // Look for a valid dep.
normalize();
return *this;
Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h (original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/problemresolver.h Mon May 2 01:38:58 2005
@@ -754,6 +754,13 @@
!rd.end(); ++rd)
if((*rd).broken_under(tmpsol))
new_broken.insert(*rd);
+
+ // Remember: the dependencies of the *new versions being
+ // installed* might also be broken!
+ for(typename version::dep_iterator di=v.deps_begin();
+ !di.end(); ++di)
+ if((*di).broken_under(tmpsol))
+ new_broken.insert(*di);
}
const std::set<dep> &old_broken=s.get_broken();
Modified: branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc (original)
+++ branches/aptitude-0.3/aptitude/src/generic/problemresolver/test.cc Mon May 2 01:38:58 2005
@@ -177,6 +177,7 @@
const dummy_package *package;
vector<dummy_dep *> revdeps;
+ vector<dummy_dep *> deps;
/** The numerical ID of this version. */
int ID;
@@ -184,6 +185,7 @@
dummy_version(const dummy_version &other);
public:
typedef vector<dummy_dep *>::const_iterator revdep_iterator;
+ typedef vector<dummy_dep *>::const_iterator dep_iterator;
dummy_version(string _name, const dummy_package *_package,
unsigned int id)
@@ -214,10 +216,18 @@
revdeps.push_back(dep);
}
+ void add_dep(dummy_dep *dep)
+ {
+ deps.push_back(dep);
+ }
+
const dummy_package &get_package() const {return *package;}
revdep_iterator revdeps_begin() const {return revdeps.begin();}
revdep_iterator revdeps_end() const {return revdeps.end();}
+
+ dep_iterator deps_begin() const {return deps.begin();}
+ dep_iterator deps_end() const {return deps.end();}
};
dummy_package::dummy_package(string _name, unsigned int id)
@@ -245,7 +255,7 @@
*/
class dummy_dep
{
- const dummy_version *source;
+ dummy_version *source;
vector<dummy_version *> target_set;
dummy_dep(const dummy_dep &other);
@@ -254,7 +264,7 @@
public:
typedef vector<dummy_version *>::const_iterator solver_iterator;
- dummy_dep(const dummy_version *_source,
+ dummy_dep(dummy_version *_source,
const vector<dummy_version *> &_target_set,
unsigned int _ID)
:source(_source), target_set(_target_set), ID(_ID)
@@ -276,7 +286,7 @@
return ID<other.ID;
}
- const dummy_version &get_source() const {return *source;}
+ dummy_version &get_source() const {return *source;}
solver_iterator solvers_begin() const
{
@@ -371,6 +381,7 @@
const dummy_version *real_version;
public:
typedef wrap_ptr_iter<dummy_dep, dep> revdep_iterator;
+ typedef wrap_ptr_iter<dummy_dep, dep> dep_iterator;
version():real_version(0) {}
version(const dummy_version *_real_version)
@@ -413,6 +424,12 @@
return wrap_ptr_iter<dummy_dep, dep>(real_version->revdeps_begin(),
real_version->revdeps_end());
}
+
+ wrap_ptr_iter<dummy_dep, dep> deps_begin() const
+ {
+ return wrap_ptr_iter<dummy_dep, dep>(real_version->deps_begin(),
+ real_version->deps_end());
+ }
};
@@ -651,6 +668,8 @@
dummy_dep *newdep=deps.back();
+ newdep->get_source().add_dep(newdep);
+
for(dummy_dep::solver_iterator i=newdep->solvers_begin();
i!=newdep->solvers_end(); ++i)
(*i)->add_revdep(newdep);