[Aptitude-svn-commit] r3868 - in branches/aptitude-0.3/aptitude: . src/generic

Daniel Burrows dburrows at costa.debian.org
Tue Aug 16 19:32:15 UTC 2005


Author: dburrows
Date: Tue Aug 16 19:32:11 2005
New Revision: 3868

Added:
   branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc
Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/generic/Makefile.am
   branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.h
Log:
Hide most of the implementation of aptitude_universe in a .cc file.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Tue Aug 16 19:32:11 2005
@@ -1,5 +1,10 @@
 2005-08-16  Daniel Burrows  <dburrows at debian.org>
 
+	* src/generic/Makefile.am, src/generic/aptitude_resolver_universe.cc:
+
+	  Move most of the implementation of the resolver universe into a
+	  .cc file.
+
 	* src/solution_screen.cc:
 
 	  View unresolved recomendations in the solution tree too.

Modified: branches/aptitude-0.3/aptitude/src/generic/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/Makefile.am	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/Makefile.am	Tue Aug 16 19:32:11 2005
@@ -23,6 +23,7 @@
 	aptitudepolicy.cc\
 	aptitude_resolver.h\
 	aptitude_resolver.cc\
+	aptitude_resolver_universe.cc\
 	aptitude_resolver_universe.h\
 	apt_undo_group.h\
 	apt_undo_group.cc\

Added: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.cc	Tue Aug 16 19:32:11 2005
@@ -0,0 +1,494 @@
+// aptitude_resolver_universe.cc                       -*-c++-*-
+
+#include "aptitude_resolver_universe.h"
+
+#include <sstream>
+
+using namespace std;
+
+string aptitude_resolver_version::get_name() const
+{
+  if(!ver.end())
+    {
+      // If there are two distinct package files with the same
+      // Version, apt will give them the same VerStr.  Detect and
+      // compensate for this.
+      int count=0;
+      int idx=-1;
+
+      for(pkgCache::VerIterator i=pkg.VersionList(); !i.end(); ++i)
+	{
+	  if(i==ver)
+	    {
+	      idx=count;
+	      ++count;
+	    }
+	  else if(!strcmp(i.VerStr(), ver.VerStr()))
+	    ++count;
+	}
+
+      // if not, we have a "version" of this package that's not in
+      // its list of versions!
+      assert(idx>=0);
+
+      if(count>1)
+	{
+	  ostringstream s;
+	  s << ver.VerStr() << "<" << idx+1 << ">";
+	  return s.str();
+	}
+      else
+	return ver.VerStr();
+    }
+  else
+    // Note that this is an invalid version string for apt, so we
+    // can't clash with real versions.
+    return "[UNINST]";
+}
+
+bool aptitude_resolver_version::revdep_iterator::applicable() const
+{
+  if(!aptitude_universe_is_interesting_dep(dep_lst))
+    return false;
+
+  // Unversioned deps always apply.
+  if(!dep_lst.TargetVer())
+    return true;
+
+  if(provides_open)
+    return _system->VS->CheckDep(prv_lst.ProvideVersion(),
+				 dep_lst->CompareOp, dep_lst.TargetVer());
+  else
+    return _system->VS->CheckDep(ver.VerStr(),
+				 dep_lst->CompareOp, dep_lst.TargetVer());
+}
+
+void aptitude_resolver_version::revdep_iterator::normalize()
+{
+  while(!dep_lst.end() &&
+	(!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
+    ++dep_lst;
+
+  if(dep_lst.end() && !provides_open)
+    {
+      assert(prv_lst.end());
+      prv_lst=ver.ProvidesList();
+      if(!prv_lst.end())
+	{
+	  dep_lst=prv_lst.ParentPkg().RevDependsList();
+	  while(!dep_lst.end() &&
+		(!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
+	    ++dep_lst;
+	}
+      provides_open=true;
+    }
+
+  // When we've run out of provides, give up..
+  while(dep_lst.end() && !prv_lst.end())
+    {
+      assert(provides_open);
+      ++prv_lst;
+
+      if(!prv_lst.end())
+	{
+	  assert(!prv_lst.ParentPkg().end());
+	  dep_lst=prv_lst.ParentPkg().RevDependsList();
+
+	  while(!dep_lst.end() &&
+		(!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
+	    ++dep_lst;
+	}
+    }
+}
+
+void aptitude_resolver_version::dep_iterator::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() ||
+	 !aptitude_universe_is_interesting_dep(dep)))
+    ++dep;
+
+  // If we ran out of deps, we're done!
+}
+
+
+
+void aptitude_resolver_dep::solver_iterator::normalize()
+{
+  if(dep_lst->Type != pkgCache::Dep::Conflicts)
+    {
+      while(!end())
+	{
+	  while(!ver_lst.end())
+	    {
+	      bool ver_matches=(!dep_lst.TargetVer()) || _system->VS->CheckDep(ver_lst.VerStr(), dep_lst->CompareOp, dep_lst.TargetVer());
+
+	      if(ver_matches)
+		// Found the next entry; drop out.
+		return;
+	      else
+		++ver_lst;
+	    }
+
+	  // If we ran out of versions, try provides instead.
+	  while(!prv_lst.end())
+	    {
+	      bool prv_matches=(!dep_lst.TargetVer()) ||
+		(prv_lst.ProvideVersion() &&
+		 _system->VS->CheckDep(prv_lst.ProvideVersion(),
+				       dep_lst->CompareOp,
+				       dep_lst.TargetVer()));
+
+	      if(prv_matches)
+		return;
+	      else
+		++prv_lst;
+	    }
+
+	  // No more target versions or providers of the target;
+	  // increment the dependency list if we aren't yet at the
+	  // end of the OR group.
+
+	  if(!(dep_lst->CompareOp & pkgCache::Dep::Or))
+	    finished=true;
+	  else
+	    {
+	      ++dep_lst;
+	      // Since we aren't finished, dep_lst should still be
+	      // valid.
+	      assert(!dep_lst.end());
+	      ver_lst=dep_lst.TargetPkg().VersionList();
+
+	      // Only set the prv_lst to non-end if there is no target
+	      // version.
+	      prv_lst=dep_lst.TargetPkg().ProvidesList();
+	    }
+	}
+    }
+  else
+    {
+      // For Conflicts, we're iterating over all the versions of
+      // *one* package for *one* dep, either the owner of the
+      // dep or a provided package.  (prv_lst is mostly
+      // unnecessary, but it makes it simple to remember whether
+      // we have a provides).  Note that the efficiency of this
+      // stanza is based on the *assumption* that most packages
+      // only Provide a few things.
+
+      // For provided packages, return exactly those packages
+      // that *don't* have a matching Provides.
+      if(!prv_lst.end())
+	{
+	  while(!ver_lst.end())
+	    {
+	      bool ver_matches=false;
+
+	      // Does this version Provide something that hits
+	      // the conflict?
+	      for(pkgCache::PrvIterator prv2=ver_lst.ProvidesList();
+		  !ver_matches && !prv2.end(); ++prv2)
+		if(prv2.ParentPkg()==dep_lst.ParentPkg())
+		  ver_matches=(!dep_lst.TargetVer()) ||
+		    (prv2.ProvideVersion() &&
+		     _system->VS->CheckDep(prv2.ProvideVersion(),
+					   dep_lst->CompareOp,
+					   dep_lst.TargetVer()));
+
+	      // If not, it can resolve the conflict.
+	      if(!ver_matches)
+		return;
+
+	      ++ver_lst;
+	    }
+	  // Important point: end version iterators always match
+	  // a Conflicts! (i.e., any Conflicts can be resolved
+	  // by removing the conflicted package)
+	  return;
+	}
+      else
+	{
+	  while(!ver_lst.end())
+	    {
+	      bool ver_matches=(!dep_lst.TargetVer()) ||
+		(ver_lst.VerStr() &&
+		 _system->VS->CheckDep(ver_lst.VerStr(),
+				       dep_lst->CompareOp,
+				       dep_lst.TargetVer()));
+
+	      if(!ver_matches)
+		// This version resolves the conflict.
+		return;
+	      else
+		++ver_lst;
+	    }
+
+	  // Ignore provides; as above, end versions are A-OK.
+	  return;
+	}
+    }
+}
+
+aptitude_resolver_dep::solver_iterator &aptitude_resolver_dep::solver_iterator::operator++()
+{
+  assert(!end());
+
+  // Advance whatever needs to be advanced next in the
+  // sub-list.
+
+  if(!ver_lst.end())
+    ++ver_lst;
+  else if(dep_lst->Type != pkgCache::Dep::Conflicts)
+    {
+      if(!prv_lst.end())
+	++prv_lst;
+    }
+  else
+    finished=true;
+
+  normalize();
+
+  return *this;
+}
+
+aptitude_resolver_version::dep_iterator &aptitude_resolver_version::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;
+}
+
+aptitude_resolver_version aptitude_resolver_dep::solver_iterator::operator*() const
+{
+  assert(!end());
+
+  if(!ver_lst.end())
+    return aptitude_resolver_version(ver_lst.ParentPkg(),ver_lst,cache);
+  else // In this case we're trying to remove some package or other.
+    {
+      if(dep_lst->Type != pkgCache::Dep::Conflicts)
+	{
+	  // Assume this because otherwise end() should be true.
+	  assert(!prv_lst.end());
+
+	  return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerVer(),cache);
+	}
+      else if(!prv_lst.end())
+	return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),ver_lst,cache);
+      else
+	return aptitude_resolver_version(const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg(),ver_lst,cache);
+    }
+}
+
+void aptitude_universe::dep_iterator::normalize()
+{
+  while(dep.end() && !pkg.end())
+    {
+      while(dep.end() && !ver.end())
+	{
+	  ++ver;
+	  if(!ver.end())
+	    dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+							cache);
+	}
+
+      if(dep.end())
+	{
+	  ++pkg;
+	  if(!pkg.end())
+	    {
+	      ver=pkg.VersionList();
+	      if(!ver.end())
+		dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
+							    cache);
+	    }
+	}
+    }
+}
+
+bool aptitude_universe::broken_dep_iterator::dep_is_inst_broken(const pkgCache::DepIterator &d) const
+{
+  pkgCache::DepIterator d2=d;
+
+  while(d2->CompareOp & pkgCache::Dep::Or)
+    ++d2;
+
+  return ((*cache)[d2] & pkgDepCache::DepGInstall)==0;
+}
+
+void aptitude_universe::broken_dep_iterator::normalize()
+{
+  while(!the_dep.end() &&
+	!(aptitude_universe_is_interesting_dep(the_dep) &&
+	  dep_is_inst_broken(the_dep)))
+    ++the_dep;
+
+  while(the_dep.end() && !pkg.end())
+    {
+      // Make sure we move at least one package forward!
+      // Otherwise we just spin on the same package over and over,
+      // since it's still broken..
+      ++pkg;
+      while(!pkg.end() && !(*cache)[pkg].InstBroken())
+	++pkg;
+
+      if(!pkg.end())
+	{
+	  // Examine just the InstVer of the package.
+	  pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
+
+	  if(!ver.end())
+	    the_dep=ver.DependsList();
+
+	  while(!the_dep.end() &&
+		!(aptitude_universe_is_interesting_dep(the_dep) &&
+		  dep_is_inst_broken(the_dep)))
+	    ++the_dep;
+
+	  if(the_dep.end())
+	    ++ver;
+	}
+    }
+
+  assert(the_dep.end() || aptitude_universe_is_interesting_dep(the_dep));
+
+  // Now dep is a broken critical dep or an end dep.  If it is a
+  // conflicts, we might need to push down into Provides...
+  if(!the_dep.end() && the_dep->Type == pkgCache::Dep::Conflicts)
+    {
+      // If we aren't in provides, check whether the dep is
+      // trivially broken (i.e., without following provides).
+      if(!prv_open)
+	{
+	  // If it's a direct self-conflict, jump into provides
+	  // right away.
+	  if(the_dep.TargetPkg() != the_dep.ParentPkg())
+	    {
+	      pkgCache::VerIterator ver=(*cache)[the_dep.TargetPkg()].InstVerIter(*cache);
+
+	      if(!ver.end() &&
+		 (!the_dep.TargetVer() ||
+		  (ver.VerStr() &&
+		   _system->VS->CheckDep(ver.VerStr(),
+					 the_dep->CompareOp,
+					 the_dep.TargetVer()))))
+		// OK, the dep is broken without provides, no need
+		// to descend.
+		return;
+	    }
+
+	  prv_open=true;
+	  prv=the_dep.TargetPkg().ProvidesList();
+	}
+
+      // Ok, we have found something that causes breakage.  The
+      // provides-list is a list of all the package versions that
+      // provide this package name; move forward until we find one
+      // that matches.
+      while(!prv.end())
+	{
+	  // Ignore indirect self-conflicts.
+	  if(prv.OwnerPkg() != the_dep.TargetPkg())
+	    {
+	      // First, is the providing version going to be
+	      // installed?
+	      if((*cache)[prv.OwnerPkg()].InstVerIter(*cache) == prv.OwnerVer())
+		{
+		  // Ok, does it match the version string?
+		  if(!the_dep.TargetVer() ||
+		     (prv.ProvideVersion() &&
+		      _system->VS->CheckDep(prv.ProvideVersion(),
+					    the_dep->CompareOp,
+					    the_dep.TargetVer())))
+		    return;
+		}
+	    }
+
+	  ++prv;
+	}
+
+      // if all provides are exhausted, increment the dep and try
+      // again.  (probably this was only a self-conflict and
+      // nothing else)
+      ++the_dep;
+      prv_open=false;
+      normalize();
+      // hopefully g++ is smart enough to optimize this into a
+      // tail call.
+      return;
+    }
+}
+
+aptitude_universe::broken_dep_iterator &aptitude_universe::broken_dep_iterator::operator++()
+{
+  assert(!pkg.end());
+  // If the_dep.end() we have pkg.end().
+  assert(!the_dep.end());
+
+  if(!prv_open && the_dep->Type == pkgCache::Dep::Conflicts)
+    {
+      prv_open = true;
+      prv = the_dep.TargetPkg().ProvidesList();
+    }
+  else if(prv_open && !prv.end())
+    ++prv;
+  else
+    ++the_dep;
+
+  normalize();
+  return *this;
+}

Modified: branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.h	(original)
+++ branches/aptitude-0.3/aptitude/src/generic/aptitude_resolver_universe.h	Tue Aug 16 19:32:11 2005
@@ -24,8 +24,6 @@
 #include <apt-pkg/pkgsystem.h>
 #include <apt-pkg/version.h>
 
-#include <sstream>
-
 #include "apt.h"
 #include "aptcache.h"
 
@@ -141,45 +139,7 @@
       return cache->Head().VersionCount+pkg->ID;
   }
 
-  std::string get_name() const
-  {
-    if(!ver.end())
-      {
-	// If there are two distinct package files with the same
-	// Version, apt will give them the same VerStr.  Detect and
-	// compensate for this.
-	int count=0;
-	int idx=-1;
-
-	for(pkgCache::VerIterator i=pkg.VersionList(); !i.end(); ++i)
-	  {
-	    if(i==ver)
-	      {
-		idx=count;
-		++count;
-	      }
-	    else if(!strcmp(i.VerStr(), ver.VerStr()))
-	      ++count;
-	  }
-
-	// if not, we have a "version" of this package that's not in
-	// its list of versions!
-	assert(idx>=0);
-
-	if(count>1)
-	  {
-	    std::ostringstream s;
-	    s << ver.VerStr() << "<" << idx+1 << ">";
-	    return s.str();
-	  }
-	else
-	  return ver.VerStr();
-      }
-    else
-      // Note that this is an invalid version string for apt, so we
-      // can't clash with real versions.
-      return "[UNINST]";
-  }
+  std::string get_name() const;
 
   aptitude_resolver_package get_package() const
   {
@@ -403,63 +363,12 @@
   bool provides_open;
 
   /** Advance to the next valid iterator. */
-  void normalize()
-  {
-    while(!dep_lst.end() &&
-	  (!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
-      ++dep_lst;
-
-    if(dep_lst.end() && !provides_open)
-      {
-	assert(prv_lst.end());
-	prv_lst=ver.ProvidesList();
-	if(!prv_lst.end())
-	  {
-	    dep_lst=prv_lst.ParentPkg().RevDependsList();
-	    while(!dep_lst.end() &&
-		  (!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
-	      ++dep_lst;
-	  }
-	provides_open=true;
-      }
-
-    // When we've run out of provides, give up..
-    while(dep_lst.end() && !prv_lst.end())
-      {
-	assert(provides_open);
-	++prv_lst;
-
-	if(!prv_lst.end())
-	  {
-	    assert(!prv_lst.ParentPkg().end());
-	    dep_lst=prv_lst.ParentPkg().RevDependsList();
-
-	    while(!dep_lst.end() &&
-		  (!aptitude_universe_is_interesting_dep(dep_lst) || !applicable()))
-	      ++dep_lst;
-	  }
-      }
-  }
+  void normalize();
 
   /** \return true if dep_lst applies to ver: this is, if it is
    *               a strong dependency on ver.
    */
-  bool applicable() const
-  {
-    if(!aptitude_universe_is_interesting_dep(dep_lst))
-      return false;
-
-    // Unversioned deps always apply.
-    if(!dep_lst.TargetVer())
-      return true;
-
-    if(provides_open)
-      return _system->VS->CheckDep(prv_lst.ProvideVersion(),
-				   dep_lst->CompareOp, dep_lst.TargetVer());
-    else
-      return _system->VS->CheckDep(ver.VerStr(),
-				   dep_lst->CompareOp, dep_lst.TargetVer());
-  }
+  bool applicable() const;
 public:
 #if 0
   revdep_iterator()
@@ -533,38 +442,7 @@
    */
   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() ||
-	   !aptitude_universe_is_interesting_dep(dep)))
-      ++dep;
-
-    // If we ran out of deps, we're done!
-  }
+  void normalize();
 
 public:
   dep_iterator(pkgDepCache *_cache)
@@ -605,44 +483,7 @@
     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;
-  }
+  dep_iterator &operator++();
 };
 
 inline aptitude_resolver_version::revdep_iterator aptitude_resolver_version::revdeps_begin() const
@@ -683,121 +524,7 @@
   /** Advance to the next interesting version/provides -- i.e., skip
    *  uninteresting ones.
    */
-  void normalize()
-  {
-    if(dep_lst->Type != pkgCache::Dep::Conflicts)
-      {
-	while(!end())
-	  {
-	    while(!ver_lst.end())
-	      {
-		bool ver_matches=(!dep_lst.TargetVer()) || _system->VS->CheckDep(ver_lst.VerStr(), dep_lst->CompareOp, dep_lst.TargetVer());
-
-		if(ver_matches)
-		  // Found the next entry; drop out.
-		  return;
-		else
-		  ++ver_lst;
-	      }
-
-	    // If we ran out of versions, try provides instead.
-	    while(!prv_lst.end())
-	      {
-		bool prv_matches=(!dep_lst.TargetVer()) ||
-		  (prv_lst.ProvideVersion() &&
-		   _system->VS->CheckDep(prv_lst.ProvideVersion(),
-					 dep_lst->CompareOp,
-					 dep_lst.TargetVer()));
-
-		if(prv_matches)
-		  return;
-		else
-		  ++prv_lst;
-	      }
-
-	    // No more target versions or providers of the target;
-	    // increment the dependency list if we aren't yet at the
-	    // end of the OR group.
-
-	    if(!(dep_lst->CompareOp & pkgCache::Dep::Or))
-	      finished=true;
-	    else
-	      {
-		++dep_lst;
-		// Since we aren't finished, dep_lst should still be
-		// valid.
-		assert(!dep_lst.end());
-		ver_lst=dep_lst.TargetPkg().VersionList();
-
-		// Only set the prv_lst to non-end if there is no target
-		// version.
-		prv_lst=dep_lst.TargetPkg().ProvidesList();
-	      }
-	  }
-      }
-    else
-      {
-	// For Conflicts, we're iterating over all the versions of
-	// *one* package for *one* dep, either the owner of the
-	// dep or a provided package.  (prv_lst is mostly
-	// unnecessary, but it makes it simple to remember whether
-	// we have a provides).  Note that the efficiency of this
-	// stanza is based on the *assumption* that most packages
-	// only Provide a few things.
-
-	// For provided packages, return exactly those packages
-	// that *don't* have a matching Provides.
-	if(!prv_lst.end())
-	  {
-	    while(!ver_lst.end())
-	      {
-		bool ver_matches=false;
-
-		// Does this version Provide something that hits
-		// the conflict?
-		for(pkgCache::PrvIterator prv2=ver_lst.ProvidesList();
-		    !ver_matches && !prv2.end(); ++prv2)
-		  if(prv2.ParentPkg()==dep_lst.ParentPkg())
-		    ver_matches=(!dep_lst.TargetVer()) ||
-		      (prv2.ProvideVersion() &&
-		       _system->VS->CheckDep(prv2.ProvideVersion(),
-					     dep_lst->CompareOp,
-					     dep_lst.TargetVer()));
-
-		// If not, it can resolve the conflict.
-		if(!ver_matches)
-		  return;
-
-		++ver_lst;
-	      }
-	    // Important point: end version iterators always match
-	    // a Conflicts! (i.e., any Conflicts can be resolved
-	    // by removing the conflicted package)
-	    return;
-	  }
-	else
-	  {
-	    while(!ver_lst.end())
-	      {
-		bool ver_matches=(!dep_lst.TargetVer()) ||
-		  (ver_lst.VerStr() &&
-		   _system->VS->CheckDep(ver_lst.VerStr(),
-					 dep_lst->CompareOp,
-					 dep_lst.TargetVer()));
-
-		if(!ver_matches)
-		  // This version resolves the conflict.
-		  return;
-		else
-		  ++ver_lst;
-	      }
-
-	    // Ignore provides; as above, end versions are A-OK.
-	    return;
-	  }
-      }
-
-  }
+  void normalize();
 
 public:
   solver_iterator(const pkgCache::DepIterator &start,
@@ -863,49 +590,9 @@
       finished != other.finished;
   }
 
-  solver_iterator &operator++()
-  {
-    assert(!end());
-
-    // Advance whatever needs to be advanced next in the
-    // sub-list.
-
-    if(!ver_lst.end())
-      ++ver_lst;
-    else if(dep_lst->Type != pkgCache::Dep::Conflicts)
-      {
-	if(!prv_lst.end())
-	  ++prv_lst;
-      }
-    else
-      finished=true;
-
-    normalize();
+  solver_iterator &operator++();
 
-    return *this;
-  }
-
-  aptitude_resolver_version operator*() const
-  {
-    assert(!end());
-
-    if(!ver_lst.end())
-      return aptitude_resolver_version(ver_lst.ParentPkg(),ver_lst,cache);
-    else // In this case we're trying to remove some package or other.
-      {
-	if(dep_lst->Type != pkgCache::Dep::Conflicts)
-	  {
-	    // Assume this because otherwise end() should be true.
-	    assert(!prv_lst.end());
-
-	    return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerVer(),cache);
-	  }
-	else if(!prv_lst.end())
-	  return aptitude_resolver_version(const_cast<pkgCache::PrvIterator &>(prv_lst).OwnerPkg(),ver_lst,cache);
-	else
-	  return aptitude_resolver_version(const_cast<pkgCache::DepIterator &>(dep_lst).TargetPkg(),ver_lst,cache);
-      }
-  }
+  aptitude_resolver_version operator*() const;
 
   bool end() const
   {
@@ -1066,31 +753,8 @@
     aptitude_resolver_version::dep_iterator dep;
 
     // Advance to the next valid dep (inclusive of dep).
-    void normalize()
-    {
-      while(dep.end() && !pkg.end())
-	{
-	  while(dep.end() && !ver.end())
-	    {
-	      ++ver;
-	      if(!ver.end())
-		dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
-							    cache);
-	    }
+    void normalize();
 
-	  if(dep.end())
-	    {
-	      ++pkg;
-	      if(!pkg.end())
-		{
-		  ver=pkg.VersionList();
-		  if(!ver.end())
-		    dep=aptitude_resolver_version::dep_iterator(ver.DependsList(),
-								cache);
-		}
-	    }
-	}
-    }
   public:
     // Start from the given package (typically Head() or End()).
     dep_iterator(const pkgCache::PkgIterator &_pkg,
@@ -1157,119 +821,11 @@
     bool prv_open;
 
     /** \return \b true if the given non-end dep is InstBroken. */
-    bool dep_is_inst_broken(const pkgCache::DepIterator &d)
-    {
-      pkgCache::DepIterator d2=d;
-
-      while(d2->CompareOp & pkgCache::Dep::Or)
-	++d2;
-
-      return ((*cache)[d2] & pkgDepCache::DepGInstall)==0;
-    }
+    bool dep_is_inst_broken(const pkgCache::DepIterator &d) const;
 
     // Push forward to the next interesting point.
-    void normalize()
-    {
-      while(!the_dep.end() &&
-	    !(aptitude_universe_is_interesting_dep(the_dep) &&
-	      dep_is_inst_broken(the_dep)))
-	++the_dep;
+    void normalize();
 
-      while(the_dep.end() && !pkg.end())
-	{
-	  // Make sure we move at least one package forward!
-	  // Otherwise we just spin on the same package over and over,
-	  // since it's still broken..
-	  ++pkg;
-	  while(!pkg.end() && !(*cache)[pkg].InstBroken())
-	    ++pkg;
-
-	  if(!pkg.end())
-	    {
-	      // Examine just the InstVer of the package.
-	      pkgCache::VerIterator ver=(*cache)[pkg].InstVerIter(*cache);
-
-	      if(!ver.end())
-		the_dep=ver.DependsList();
-
-	      while(!the_dep.end() &&
-		    !(aptitude_universe_is_interesting_dep(the_dep) &&
-		      dep_is_inst_broken(the_dep)))
-		++the_dep;
-
-	      if(the_dep.end())
-		++ver;
-	    }
-	}
-
-      assert(the_dep.end() || aptitude_universe_is_interesting_dep(the_dep));
-
-      // Now dep is a broken critical dep or an end dep.  If it is a
-      // conflicts, we might need to push down into Provides...
-      if(!the_dep.end() && the_dep->Type == pkgCache::Dep::Conflicts)
-	{
-	  // If we aren't in provides, check whether the dep is
-	  // trivially broken (i.e., without following provides).
-	  if(!prv_open)
-	    {
-	      // If it's a direct self-conflict, jump into provides
-	      // right away.
-	      if(the_dep.TargetPkg() != the_dep.ParentPkg())
-		{
-		  pkgCache::VerIterator ver=(*cache)[the_dep.TargetPkg()].InstVerIter(*cache);
-
-		  if(!ver.end() &&
-		     (!the_dep.TargetVer() ||
-		      (ver.VerStr() &&
-		       _system->VS->CheckDep(ver.VerStr(),
-					     the_dep->CompareOp,
-					     the_dep.TargetVer()))))
-		    // OK, the dep is broken without provides, no need
-		    // to descend.
-		    return;
-		}
-
-	      prv_open=true;
-	      prv=the_dep.TargetPkg().ProvidesList();
-	    }
-
-	  // Ok, we have found something that causes breakage.  The
-	  // provides-list is a list of all the package versions that
-	  // provide this package name; move forward until we find one
-	  // that matches.
-	  while(!prv.end())
-	    {
-	      // Ignore indirect self-conflicts.
-	      if(prv.OwnerPkg() != the_dep.TargetPkg())
-		{
-		  // First, is the providing version going to be
-		  // installed?
-		  if((*cache)[prv.OwnerPkg()].InstVerIter(*cache) == prv.OwnerVer())
-		    {
-		      // Ok, does it match the version string?
-		      if(!the_dep.TargetVer() ||
-			 (prv.ProvideVersion() &&
-			  _system->VS->CheckDep(prv.ProvideVersion(),
-						the_dep->CompareOp,
-						the_dep.TargetVer())))
-			return;
-		    }
-		}
-
-	      ++prv;
-	    }
-
-	  // if all provides are exhausted, increment the dep and try
-	  // again.  (probably this was only a self-conflict and
-	  // nothing else)
-	  ++the_dep;
-	  prv_open=false;
-	  normalize();
-	  // hopefully g++ is smart enough to optimize this into a
-	  // tail call.
-	  return;
-	}
-    }
   public:
 #if 0
     broken_dep_iterator()
@@ -1301,25 +857,7 @@
       return aptitude_universe::dep(the_dep, prv, cache);
     }
 
-    broken_dep_iterator &operator++()
-    {
-      assert(!pkg.end());
-      // If the_dep.end() we have pkg.end().
-      assert(!the_dep.end());
-
-      if(!prv_open && the_dep->Type == pkgCache::Dep::Conflicts)
-	{
-	  prv_open = true;
-	  prv = the_dep.TargetPkg().ProvidesList();
-	}
-      else if(prv_open && !prv.end())
-	++prv;
-      else
-	++the_dep;
-
-      normalize();
-      return *this;
-    }
+    broken_dep_iterator &operator++();
 
     bool end() const
     {



More information about the Aptitude-svn-commit mailing list