[Aptitude-devel] r3174 - in branches/aptitude-0.3/aptitude: . src src/cmdline

Daniel Burrows dburrows@costa.debian.org
Thu, 28 Apr 2005 16:09:34 +0000


Author: dburrows
Date: Thu Apr 28 16:09:30 2005
New Revision: 3174

Added:
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.h
Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/cmdline/Makefile.am
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.h
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_do_action.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.h
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.h
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show_broken.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.cc
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.h
   branches/aptitude-0.3/aptitude/src/cmdline/cmdline_upgrade.cc
   branches/aptitude-0.3/aptitude/src/main.cc
Log:
Add some debugging catches.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Thu Apr 28 16:09:30 2005
@@ -1,5 +1,15 @@
 2005-04-28  Daniel Burrows  <dburrows@debian.org>
 
+	* src/main.cc:
+
+	  Add debugging catches to trap unhandled exceptions.
+
+	* src/cmdline/cmdline_action.cc, src/cmdline/cmdline_action.h, src/cmdline/cmdline_do_action.cc, src/cmdline/cmdline_prompt.cc, src/cmdline/cmdline_prompt.h, src/cmdline/cmdline_resolver.cc, src/cmdline/cmdline_resolver.h, src/cmdline/cmdline_show_broken.cc, src/cmdline/cmdline_show.cc, src/cmdline/cmdline_show.h, src/cmdline/cmdline_simulate.cc, src/cmdline/cmdline_simulate.h, src/cmdline/cmdline_upgrade.cc, src/cmdline/Makefile.am:
+
+	  Start work on hooking the new resolver into the command-line.
+	  The new approach works by having a sub-loop that gets entered if
+	  broken dependencies are detected at the command-line prompt.
+
 	* src/generic/aptcache.cc, src/generic/aptcache.h, src/generic/problemresolver/problemresolver.h:
 
 	  Add provisions for adjusting package scores before running the

Modified: branches/aptitude-0.3/aptitude/src/cmdline/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/Makefile.am	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/Makefile.am	Thu Apr 28 16:09:30 2005
@@ -24,6 +24,8 @@
 	cmdline_progress.h \
 	cmdline_prompt.cc \
 	cmdline_prompt.h \
+	cmdline_resolver.cc \
+	cmdline_resolver.h \
 	cmdline_search.cc \
 	cmdline_search.h \
 	cmdline_show.cc \

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.cc	Thu Apr 28 16:09:30 2005
@@ -16,7 +16,7 @@
 #include <apt-pkg/pkgcache.h>
 
 bool cmdline_applyaction(cmdline_pkgaction_type action,
-			 pkgProblemResolver &fixer, pkgCache::PkgIterator pkg,
+			 pkgCache::PkgIterator pkg,
 			 pkgset &to_install, pkgset &to_hold,
 			 pkgset &to_remove, pkgset &to_purge,
 			 int verbose,
@@ -137,33 +137,19 @@
 
       (*apt_cache_file)->set_candidate_version(ver, NULL);
       (*apt_cache_file)->mark_install(pkg, true, action == cmdline_reinstall, NULL);
-      fixer.Clear(pkg);
-      fixer.Protect(pkg);
       break;
     case cmdline_remove:
       (*apt_cache_file)->mark_delete(pkg, false, false, NULL);
-      fixer.Clear(pkg);
-      fixer.Protect(pkg);
-      fixer.Remove(pkg);
       break;
     case cmdline_purge:
       (*apt_cache_file)->mark_delete(pkg, true, false, NULL);
-      fixer.Clear(pkg);
-      fixer.Protect(pkg);
-      fixer.Remove(pkg);
       break;
     case cmdline_hold:
       (*apt_cache_file)->mark_keep(pkg, false, true, NULL);
-      fixer.Clear(pkg);
-      fixer.Protect(pkg);
       break;
     case cmdline_unhold:
-      fixer.Clear(pkg);
       if(pkg->CurrentState==pkgCache::State::Installed)
-	{
-	  (*apt_cache_file)->mark_install(pkg, true, false, NULL);
-	  fixer.Protect(pkg);
-	}
+	(*apt_cache_file)->mark_install(pkg, true, false, NULL);
       else
 	(*apt_cache_file)->mark_keep(pkg, false, false, NULL);
       break;
@@ -194,7 +180,6 @@
 
 bool cmdline_applyaction(string s,
 			 cmdline_pkgaction_type action,
-			 pkgProblemResolver &fixer,
 			 pkgset &to_install, pkgset &to_hold,
 			 pkgset &to_remove, pkgset &to_purge,
 			 int verbose)
@@ -221,7 +206,7 @@
 	  for(std::list<std::string>::iterator i=tasks->begin();
 	      i!=tasks->end(); ++i)
 	    if(*i==s)
-	      rval=cmdline_applyaction(action, fixer, pkg,
+	      rval=cmdline_applyaction(action, pkg,
 				       to_install, to_hold, to_remove, to_purge,
 				       verbose, source,
 				       sourcestr) && rval;
@@ -317,7 +302,7 @@
 	  return false;
 	}
 
-      rval=cmdline_applyaction(action, fixer, pkg,
+      rval=cmdline_applyaction(action, pkg,
 			       to_install, to_hold, to_remove, to_purge,
 			       verbose, source,
 			       sourcestr);
@@ -345,7 +330,7 @@
 	    testver=(*apt_cache_file)[pkg].InstVerIter(*apt_cache_file);
 
 	  if(m->matches(pkg, testver))
-	    rval=cmdline_applyaction(action, fixer, pkg,
+	    rval=cmdline_applyaction(action, pkg,
 				     to_install, to_hold, to_remove, to_purge,
 				     verbose, source,
 				     sourcestr) && rval;

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.h	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_action.h	Thu Apr 28 16:09:30 2005
@@ -7,10 +7,8 @@
 
 #include "cmdline_common.h"
 
-class pkgProblemResolver;
-
 bool cmdline_applyaction(cmdline_pkgaction_type action,
-			 pkgProblemResolver &fixer, pkgCache::PkgIterator pkg,
+			 pkgCache::PkgIterator pkg,
 			 pkgset &to_install, pkgset &to_hold,
 			 pkgset &to_remove, pkgset &to_purge,
 			 int verbose,
@@ -19,7 +17,6 @@
 
 bool cmdline_applyaction(string s,
 			 cmdline_pkgaction_type action,
-			 pkgProblemResolver &fixer,
 			 pkgset &to_install, pkgset &to_hold,
 			 pkgset &to_remove, pkgset &to_purge,
 			 int verbose);

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_do_action.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_do_action.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_do_action.cc	Thu Apr 28 16:09:30 2005
@@ -7,6 +7,7 @@
 #include "cmdline_action.h"
 #include "cmdline_common.h"
 #include "cmdline_prompt.h"
+#include "cmdline_resolver.h"
 #include "cmdline_show_broken.h"
 #include "cmdline_simulate.h"
 #include "cmdline_util.h"
@@ -102,7 +103,7 @@
       return -1;
     }
 
-  pkgset to_install, to_hold, to_remove, to_purge;
+  pkgset to_upgrade, to_install, to_hold, to_remove, to_purge;
 
   if(dist_upgrade)
     {
@@ -113,27 +114,23 @@
 
 	  if(!i.CurrentVer().end() &&
 	     state.Upgradable() && !(*apt_cache_file)->is_held(i))
-	    to_install.insert(i);
+	    to_upgrade.insert(i);
 
 	}
 
       (*apt_cache_file)->mark_all_upgradable(true, NULL);
     }
-  else if(argc==1 && default_action==cmdline_install)
+  /*else if(argc==1 && default_action==cmdline_install)
     {
       // FIXME: Build to_install to avoid a big printout
       for(pkgCache::PkgIterator i=(*apt_cache_file)->PkgBegin(); !i.end(); ++i)
 	{
 
 	}
-    }
+	}*/
 
   // TODO: look for filenames and call dpkg directly if that's the case.
 
-  pkgProblemResolver fixer(*apt_cache_file);
-  // Used when doing only a local optimization (ie, we aren't trying to
-  // do a dist-upgrade)
-
   (*apt_cache_file)->begin_action_group();
   // Mark packages 'n stuff.
   for(int i=1; i<argc; ++i)
@@ -164,26 +161,19 @@
 	    break;
 	  }
 
-      cmdline_applyaction(argv[i], action, fixer,
+      cmdline_applyaction(argv[i], action,
 			  to_install, to_hold, to_remove, to_purge,
 			  verbose);
     }
   (*apt_cache_file)->end_action_group(NULL);
 
-  if(dist_upgrade ||
-     (fix_broken && argc==1 && default_action==cmdline_install))
-    {
-      if(!(*apt_cache_file)->try_fix_broken(NULL))
-	{
-	  _error->DumpErrors();
-	  return -1;
-	}
-    }
-  else
-    {
-      if(!(*apt_cache_file)->try_fix_broken(fixer, NULL))
-	_error->Error("Unable to resolve some dependencies!");
-    }
+
+  cmdline_resolve_deps(to_install,
+		       to_hold,
+		       to_remove,
+		       to_purge,
+		       assume_yes,
+		       !fix_broken);
 
   _error->DumpErrors();
 
@@ -198,13 +188,15 @@
   else if(simulate)
     return cmdline_simulate(dist_upgrade, to_install, to_hold, to_remove, to_purge,
 			    showvers, showdeps, showsize,
-			    always_prompt, verbose, assume_yes);
+			    always_prompt, verbose, assume_yes,
+			    !fix_broken);
   else
     {
       if(!cmdline_do_prompt(dist_upgrade,
 			    to_install, to_hold, to_remove, to_purge,
 			    showvers, showdeps, showsize,
-			    always_prompt, verbose, assume_yes))
+			    always_prompt, verbose, assume_yes,
+			    !fix_broken))
 	{
 	  printf(_("Abort.\n"));
 	  return 0;

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.cc	Thu Apr 28 16:09:30 2005
@@ -6,6 +6,7 @@
 
 #include "cmdline_action.h"
 #include "cmdline_changelog.h"
+#include "cmdline_resolver.h"
 #include "cmdline_show.h"
 #include "cmdline_util.h"
 
@@ -260,8 +261,11 @@
 
 // Probably something like cin.getline() would work, but I don't trust that
 // for interactive use.
-static string prompt_string()
+string prompt_string(const string &prompt)
 {
+  printf("%s", prompt.c_str());
+  fflush(stdout);
+
   string rval;
   char buf[1024];
   cin.getline(buf, 1023);
@@ -485,15 +489,14 @@
   return rval;
 }
 
-// Parses a list of actions and does them, running a fixer afterwards.
-// Aborts after a partial action if something bad happens.
+// Parses a list of actions and executes them.  Aborts after a partial
+// action if something bad happens.
 static void cmdline_parse_action(string s,
 				 pkgset &to_install, pkgset &to_hold,
 				 pkgset &to_remove, pkgset &to_purge,
 				 int verbose)
 {
   string::size_type loc=0;
-  pkgProblemResolver fixer(*apt_cache_file);
 
   while(loc<s.size() && isspace(s[loc]))
     ++loc;
@@ -554,7 +557,7 @@
 	      while(loc<s.size() && !isspace(s[loc]))
 		pkgname+=s[loc++];
 
-	      if(!cmdline_applyaction(pkgname, action, fixer,
+	      if(!cmdline_applyaction(pkgname, action,
 				      to_install, to_hold,
 				      to_remove, to_purge,
 				      verbose))
@@ -562,10 +565,6 @@
 	    }
 	  }
     }
-
-  // Er, what do we do here?
-  if(!(*apt_cache_file)->try_fix_broken(fixer, NULL))
-    _error->DumpErrors();
 }
 
 static void cmdline_parse_show(string response,
@@ -595,8 +594,7 @@
   if(!one_shown)
     printf(_("No packages to show -- enter the package names on the line after 'i'.\n"));
 
-  printf(_("Press Return to continue."));
-  prompt_string();
+  prompt_string(_("Press Return to continue."));
 }
 
 // Erm.  Merge w/ above?
@@ -626,8 +624,7 @@
   else
     do_cmdline_changelog(packages);
 
-  printf(_("Press Return to continue."));
-  prompt_string();
+  prompt_string(_("Press Return to continue"));
 }
 
 bool cmdline_do_prompt(bool as_upgrade,
@@ -640,7 +637,8 @@
 		       bool showsize,
 		       bool always_prompt,
 		       int verbose,
-		       bool assume_yes)
+		       bool assume_yes,
+		       bool force_no_change)
 {
   bool cont=false;
   bool rval=true;
@@ -653,6 +651,16 @@
 	 first &&
 	 !always_prompt)
 	cont=true;
+      else if(!cmdline_resolve_deps(to_install,
+				    to_hold,
+				    to_remove,
+				    to_purge,
+				    assume_yes,
+				    force_no_change))
+	{
+	  cont=true;
+	  rval=false;
+	}
       else if(assume_yes)
 	cont=true;
       else
@@ -662,19 +670,21 @@
 	  while(!valid_response)
 	    {
 	      valid_response=true;
-	      printf(_("Do you want to continue? [Y/n/?] "));
 	      fflush(stdout);
 
-	      string response=prompt_string();
+	      string response=prompt_string(_("Do you want to continue? [Y/n/?] "));
 	      string::size_type loc=0;
 
 	      while(loc<response.size() && isspace(response[loc]))
 		++loc;
 
 	      if(loc==response.size())
-		response='y';
+		{
+		  response='y';
+		  loc=0;
+		}
 
-	      switch(toupper(response[0]))
+	      switch(toupper(response[loc]))
 		{
 		case 'Y':
 		  rval=true;

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.h	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_prompt.h	Thu Apr 28 16:09:30 2005
@@ -26,6 +26,9 @@
  *  \param verbose the current verbosity level
  *  \param assume_yes if \b true, assume the user entered "yes"
  *                    at the prompt.
+ *  \param force_no_change if \b true, try extra-hard to preserve
+ *                         the user's explicit requests (as
+ *                         specified in to_install et al)
  */
 bool cmdline_do_prompt(bool as_upgrade,
 		       pkgset &to_install,
@@ -37,6 +40,15 @@
 		       bool showsize,
 		       bool always_prompt,
 		       int verbose,
-		       bool assume_yes);
+		       bool assume_yes,
+		       bool force_no_change);
+
+/** Prompt for a single line of input from the user.
+ *
+ *  \param prompt a message to display before reading input.
+ *  \return the text the user entered
+ */
+string prompt_string(const string &prompt);
+
 
 #endif // CMDLINE_PROMPT_H

Added: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.cc	Thu Apr 28 16:09:30 2005
@@ -0,0 +1,243 @@
+// cmdline_resolver.cc
+//
+//   Copyright (C) 2005 Daniel Burrows
+//
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the GNU General Public License as
+//   published by the Free Software Foundation; either version 2 of
+//   the License, or (at your option) any later version.
+//
+//   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; see the file COPYING.  If not, write to
+//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+//   Boston, MA 02111-1307, USA.
+
+#include "cmdline_resolver.h"
+
+#include "cmdline_common.h"
+#include "cmdline_prompt.h"
+#include "cmdline_show.h"
+#include "cmdline_show_broken.h"
+
+#include <aptitude.h>
+#include <solution_fragment.h>
+
+#include <generic/aptcache.h>
+#include <generic/aptitude_resolver.h>
+#include <generic/config_signal.h>
+
+#include <vscreen/fragment.h>
+
+#include <iostream>
+
+using namespace std;
+
+static void setup_resolver(pkgset &to_install,
+			   pkgset &to_hold,
+			   pkgset &to_remove,
+			   pkgset &to_purge,
+			   bool force_no_change)
+{
+  // For all packages that the user listed on the command-line (i.e.,
+  // all in to_install, to_hold, to_remove, and to_purge), tell the
+  // resolver to try *really really hard* to avoid altering their
+  // state.
+  if(force_no_change && (*apt_cache_file)->resolver_exists())
+    {
+      pkgset *sets[4]={&to_install, &to_hold, &to_remove, &to_purge};
+      int tweak_amt=aptcfg->FindI(PACKAGE "::CmdLine::Request-Strictness", 10000);
+
+      for(int i=0; i<4; ++i)
+	{
+	  pkgset &S=*sets[i];
+
+	  for(pkgset::const_iterator p=S.begin();
+	      p!=S.end(); ++i)
+	    {
+	      pkgDepCache::StateCache &state=(*apt_cache_file)[*p];
+	      pkgCache::VerIterator instver=state.InstVerIter(*apt_cache_file);
+
+	      for(pkgCache::VerIterator v=p->CurrentVer();
+		  !v.end(); ++v)
+		if(instver == v)
+		  (*apt_cache_file)->tweak_score(*p, v,
+						 tweak_amt);
+
+	      if(!instver.end())
+		(*apt_cache_file)->tweak_score(*p, pkgCache::VerIterator(),
+					       tweak_amt);
+	    }
+	}
+    }
+}
+
+static void resolver_help(ostream &out)
+{
+  fragment *f=flowbox(indentbox(2, 2,
+				fragf(_("y: %F%n"
+					"n: %F%n"
+					"q: %F%n"
+					",: %F%n"
+					".: %F%n"),
+				      indentbox(0, 3,
+						fragf(_("accept the proposed changes"))),
+				      indentbox(0, 3,
+						fragf(_("reject the proposed changes and search for another solution"))),
+				      indentbox(0, 3,
+						fragf(_("give up and quit the program"))),
+				      indentbox(0, 3,
+						fragf(_("move to the next solution"))),
+				      indentbox(0, 3,
+						fragf(_("move to the previous solution"))))));
+
+  update_screen_width();
+  out << f->layout(screen_width, screen_width);
+  delete f;
+}
+
+bool cmdline_resolve_deps(pkgset &to_install,
+			  pkgset &to_hold,
+			  pkgset &to_remove,
+			  pkgset &to_purge,
+			  bool assume_yes,
+			  bool force_no_change)
+{
+  while(!show_broken())
+    {
+      setup_resolver(to_install, to_hold, to_remove, to_purge,
+		     force_no_change);
+      aptitude_resolver::solution lastsol;
+
+      // The inner loop tries to generate solutions until some
+      // packages are modified (then the new set of broken packages,
+      // if any, is displayed and we start over)
+      bool modified_pkgs=false;
+      while(!modified_pkgs)
+	try
+	  {
+	    try
+	      {
+		aptitude_resolver::solution sol=(*apt_cache_file)->get_current_solution();
+
+		if(sol != lastsol)
+		  {
+		    fragment *f=sequence_fragment(flowbox(text_fragment(_("The following actions will resolve these dependencies:"))),
+						  newline_fragment(),
+						  solution_fragment(sol));
+
+		    update_screen_width();
+
+		    fragment_contents lines=f->layout(screen_width, screen_width);
+
+		    delete f;
+
+		    cout << lines << endl;
+		    lastsol=sol;
+		  }
+
+		string response=assume_yes?"Y":prompt_string(_("Accept this solution? [Y/n/q/?]"));
+
+		string::size_type loc=0;
+		while(loc<response.size() && isspace(response[loc]))
+		  ++loc;
+		if(loc == response.size())
+		  {
+		    response='Y';
+		    loc=0;
+		  }
+
+		switch(toupper(response[loc]))
+		  {
+		  case 'Y':
+		    (*apt_cache_file)->apply_current_solution(NULL);
+		    modified_pkgs=true;
+		    break;
+		  case 'N':
+		    {
+		      int curr_count=(*apt_cache_file)->generated_solution_count();
+
+		      // Move to the last cached solution.
+		      if(curr_count>0)
+			while((*apt_cache_file)->get_selected_solution()+1<curr_count)
+			  (*apt_cache_file)->next_solution();
+
+		      (*apt_cache_file)->next_solution();
+		    }
+		    break;
+		  case 'Q':
+		    cout << _("Abandoning all efforts to resolve these dependencies.") << endl;
+		    return false;
+		  case '.':
+		    (*apt_cache_file)->next_solution();
+		    break;
+		  case ',':
+		    // As above, errors pop to the outer 'catch'
+		    (*apt_cache_file)->previous_solution();
+		    break;
+		  case '?':
+		    cout << _("The following commands are available:") << endl;
+		    resolver_help(cout);
+		    break;
+		  default:
+		    cout << _("Invalid response; please enter one of the following commands:") << endl;
+		    resolver_help(cout);
+		    break;
+		  }
+	      }
+	    catch(NoMoreTime)
+	      {
+		bool done=false;
+		while(!done)
+		  {
+		    string response=prompt_string(_("No solution found within the allotted time.  Try harder? [Y/n]"));
+
+		    string::size_type loc=0;
+		    while(loc<response.size() && isspace(response[loc]))
+		      ++loc;
+		    if(loc == response.size())
+		      {
+			loc=0;
+			response='Y';
+		      }
+		    switch(toupper(response[loc]))
+		      {
+		      case 'Y':
+			try
+			  {
+			    (*apt_cache_file)->next_solution();
+			    done=true;
+			  }
+			catch(NoMoreTime)
+			  {
+			    // ignore and continue looping.
+			  }
+			// NoMoreExceptions flows to the outer catch.
+			break;
+		      case 'N':
+			done=true;
+			break;
+		      default:
+			cout << _("Invalid response; please enter 'y' or 'n'.") << endl;
+		      }
+		  }
+	      }
+	  }
+	catch(NoMoreSolutions)
+	  {
+	    if((*apt_cache_file)->generated_solution_count()==0)
+	      {
+		cout << _("Unable to resolve dependencies!  Giving up...") << endl;
+		return false;
+	      }
+	    else
+	      cout << _("No more solutions.") << endl;
+	  }
+    }
+
+  return true;
+}

Added: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.h
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_resolver.h	Thu Apr 28 16:09:30 2005
@@ -0,0 +1,53 @@
+// cmdline_resolver.h                              -*-c++-*-
+//
+//   Copyright (C) 2005 Daniel Burrows
+//
+//   This program is free software; you can redistribute it and/or
+//   modify it under the terms of the GNU General Public License as
+//   published by the Free Software Foundation; either version 2 of
+//   the License, or (at your option) any later version.
+//
+//   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; see the file COPYING.  If not, write to
+//   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+//   Boston, MA 02111-1307, USA.
+
+#ifndef CMDLINE_RESOLVER_H
+#define CMDLINE_RESOLVER_H
+
+#include "cmdline_common.h"
+
+/** Run the resolver once, possibly prompting the user in the process.
+ *
+ *  \param to_install a list of packages which the user explicitly
+ *  asked to install
+ *
+ *  \param to_hold a list of packages which the user explicitly asked
+ *  to hold back
+ *
+ *  \param to_remove a list of packages which the user explicitly
+ *  asked to remove
+ *
+ *  \param to_purge a list of packages which the user explicitly asked
+ *  to purge
+ *
+ *  \param assume_yes if \b true, try to find a single solution
+ *  (regardless of how long it takes) and accept it immediately.
+ *
+ *  \param force_no_change if \b true, assign estra version scores to
+ *  heavily bias the resolver against changing any packages in the
+ *  supplied sets.
+ */
+bool cmdline_resolve_deps(pkgset &to_install,
+			  pkgset &to_hold,
+			  pkgset &to_remove,
+			  pkgset &to_purge,
+			  bool assume_yes,
+			  bool force_no_change);
+
+#endif // CMDLINE_RESOLVER_H

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.cc	Thu Apr 28 16:09:30 2005
@@ -26,7 +26,7 @@
 
 using namespace std;
 
-static ostream &operator<<(ostream &out, const fragment_contents &contents)
+ostream &operator<<(ostream &out, const fragment_contents &contents)
 {
   for(fragment_contents::const_iterator i=contents.begin();
       i!=contents.end(); ++i)

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.h	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show.h	Thu Apr 28 16:09:30 2005
@@ -5,13 +5,17 @@
 #ifndef CMDLINE_SHOW_H
 #define CMDLINE_SHOW_H
 
+#include <iosfwd>
 #include <string>
 
+class fragment_contents;
+
 /** Run the "show" operation on a single argument, presented as a string. */
 bool do_cmdline_show(std::string s, int verbose);
 
 /** The "show" user command. */
 int cmdline_show(int argc, char *argv[], int verbose);
 
+std::ostream &operator<<(std::ostream &out, const fragment_contents &contents);
 
 #endif // CMDLINE_SHOW_H

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show_broken.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show_broken.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_show_broken.cc	Thu Apr 28 16:09:30 2005
@@ -110,8 +110,6 @@
 
   if(!broken.empty())
     {
-      // Use apt-get's familiar error message,
-      printf(_("Some packages had unmet dependencies.  This may mean that you have\nrequested an impossible situation or if you are using the unstable\ndistribution that some required packages have not yet been created\nor been moved out of Incoming.\n\n"));
       printf(_("The following packages have unmet dependencies:\n"));
 
       for(pkgvector::iterator pkg=broken.begin(); pkg!=broken.end(); ++pkg)

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.cc	Thu Apr 28 16:09:30 2005
@@ -20,12 +20,13 @@
 		     pkgset &to_install, pkgset &to_hold, pkgset &to_remove,
 		     pkgset &to_purge,
 		     bool showvers, bool showdeps, bool showsize,
-		     bool always_prompt, int verbose, bool assume_yes)
+		     bool always_prompt, int verbose,
+		     bool assume_yes, bool force_no_change)
 {
   if(!cmdline_do_prompt(as_upgrade,
 			to_install, to_hold, to_remove, to_purge,
 			showvers, showdeps, showsize, always_prompt, verbose,
-			assume_yes))
+			assume_yes, force_no_change))
     {
       printf(_("Abort.\n"));
       return 0;

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.h	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_simulate.h	Thu Apr 28 16:09:30 2005
@@ -23,13 +23,17 @@
  *  \param verbose the current verbosity level
  *  \param assume_yes if \b true, assume the user entered "yes"
  *                    at the prompt.
+ *  \param fornce_no_change if \b true, make an effort to avoid
+ *                          undoing the user's explicit requests as
+ *                          given in to_install et al.
  */
 
 int cmdline_simulate(bool as_upgrade,
 		     pkgset &to_install, pkgset &to_hold, pkgset &to_remove,
 		     pkgset &to_purge,
 		     bool showvers, bool showdeps, bool showsize,
-		     bool always_prompt, int verbose, bool assume_yes);
+		     bool always_prompt, int verbose,
+		     bool assume_yes, bool force_no_change);
 
 
 #endif // CMDLINE_SIMULATE_H

Modified: branches/aptitude-0.3/aptitude/src/cmdline/cmdline_upgrade.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/cmdline/cmdline_upgrade.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/cmdline/cmdline_upgrade.cc	Thu Apr 28 16:09:30 2005
@@ -78,13 +78,15 @@
   else if(simulate)
     return cmdline_simulate(true, to_install, to_hold, to_remove, to_purge,
 			    showvers, showdeps, showsize,
-			    always_prompt, verbose, assume_yes);
+			    always_prompt, verbose, assume_yes,
+			    false);
   else
     {
 
       if(!cmdline_do_prompt(true, to_install, to_hold, to_remove,
 			    to_purge, showvers, showdeps, showsize,
-			    always_prompt, verbose, assume_yes))
+			    always_prompt, verbose,
+			    assume_yes, false))
 	{
 	  printf(_("Abort.\n"));
 	  return 0;

Modified: branches/aptitude-0.3/aptitude/src/main.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/main.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/main.cc	Thu Apr 28 16:09:30 2005
@@ -29,8 +29,10 @@
 
 #include "../config.h"
 
-#include "generic/apt.h"
-#include "generic/config_signal.h"
+#include <generic/apt.h>
+// for NoMoreSolutions/NoMoreTime:
+#include <generic/problemresolver/problemresolver.h>
+#include <generic/config_signal.h>
 
 #include <vscreen/config/keybindings.h>
 #include <vscreen/vscreen.h>
@@ -328,73 +330,86 @@
   // Possibly run off and do other commands.
   if(optind!=argc)
     {
-      // Connect up the "please consume errors" routine for the
-      // command-line.
-      consume_errors.connect(sigc::mem_fun(_error, &GlobalError::DumpErrors));
-
-      if(update_only || install_only)
+      try
 	{
-	  fprintf(stderr, "%s",
-		  _("-u and -i may not be specified with a command"));
-	  usage();
-	  exit(1);
-	}
+	  // Connect up the "please consume errors" routine for the
+	  // command-line.
+	  consume_errors.connect(sigc::mem_fun(_error, &GlobalError::DumpErrors));
 
-      if(!strcasecmp(argv[optind], "update"))
-	return cmdline_update(argc-optind, argv+optind);
-      else if(!strcasecmp(argv[optind], "clean"))
-	return cmdline_clean(argc-optind, argv+optind, simulate);
-      else if(!strcasecmp(argv[optind], "autoclean"))
-	return cmdline_autoclean(argc-optind, argv+optind, simulate);
-      else if(!strcasecmp(argv[optind], "forget-new"))
-	return cmdline_forget_new(argc-optind, argv+optind,
-				  status_fname, simulate);
-      else if(!strcasecmp(argv[optind], "search"))
-	return cmdline_search(argc-optind, argv+optind,
-			      status_fname,
-			      display_format, width,
-			      sort_policy);
-      else if( (!strcasecmp(argv[optind], "install")) ||
-	       (!strcasecmp(argv[optind], "reinstall")) ||
-	       (!strcasecmp(argv[optind], "dist-upgrade")) ||
-	       (!strcasecmp(argv[optind], "remove")) ||
-	       (!strcasecmp(argv[optind], "purge")) ||
-	       (!strcasecmp(argv[optind], "hold")) ||
-	       (!strcasecmp(argv[optind], "unhold")) ||
-	       (!strcasecmp(argv[optind], "markauto")) ||
-	       (!strcasecmp(argv[optind], "unmarkauto")) ||
-	       (!strcasecmp(argv[optind], "forbid-version")) )
-	return cmdline_do_action(argc-optind, argv+optind,
-				 status_fname,
-				 simulate, assume_yes, download_only,
-				 fix_broken, showvers, showdeps, showsize,
-				 visual_preview, always_prompt, verbose);
-      else if(!strcasecmp(argv[optind], "upgrade"))
-	return cmdline_upgrade(argc-optind, argv+optind,
-			       status_fname,
-			       simulate, assume_yes, download_only,
-			       showvers, showdeps, showsize,
-			       visual_preview, always_prompt, verbose);
-      else if(!strcasecmp(argv[optind], "download"))
-	return cmdline_download(argc-optind, argv+optind);
-      else if(!strcasecmp(argv[optind], "changelog"))
-	return cmdline_changelog(argc-optind, argv+optind);
-      else if(!strcasecmp(argv[optind], "moo"))
-	return cmdline_moo(argc-optind, argv+optind, verbose);
-      else if(!strcasecmp(argv[optind], "show"))
-	return cmdline_show(argc-optind, argv+optind, verbose);
-      else if(!strcasecmp(argv[optind], "dump-resolver"))
-	return cmdline_dump_resolver(argc-optind, argv+optind, status_fname);
-      else if(!strcasecmp(argv[optind], "help"))
+	  if(update_only || install_only)
+	    {
+	      fprintf(stderr, "%s",
+		      _("-u and -i may not be specified with a command"));
+	      usage();
+	      exit(1);
+	    }
+
+	  if(!strcasecmp(argv[optind], "update"))
+	    return cmdline_update(argc-optind, argv+optind);
+	  else if(!strcasecmp(argv[optind], "clean"))
+	    return cmdline_clean(argc-optind, argv+optind, simulate);
+	  else if(!strcasecmp(argv[optind], "autoclean"))
+	    return cmdline_autoclean(argc-optind, argv+optind, simulate);
+	  else if(!strcasecmp(argv[optind], "forget-new"))
+	    return cmdline_forget_new(argc-optind, argv+optind,
+				      status_fname, simulate);
+	  else if(!strcasecmp(argv[optind], "search"))
+	    return cmdline_search(argc-optind, argv+optind,
+				  status_fname,
+				  display_format, width,
+				  sort_policy);
+	  else if( (!strcasecmp(argv[optind], "install")) ||
+		   (!strcasecmp(argv[optind], "reinstall")) ||
+		   (!strcasecmp(argv[optind], "dist-upgrade")) ||
+		   (!strcasecmp(argv[optind], "remove")) ||
+		   (!strcasecmp(argv[optind], "purge")) ||
+		   (!strcasecmp(argv[optind], "hold")) ||
+		   (!strcasecmp(argv[optind], "unhold")) ||
+		   (!strcasecmp(argv[optind], "markauto")) ||
+		   (!strcasecmp(argv[optind], "unmarkauto")) ||
+		   (!strcasecmp(argv[optind], "forbid-version")) )
+	    return cmdline_do_action(argc-optind, argv+optind,
+				     status_fname,
+				     simulate, assume_yes, download_only,
+				     fix_broken, showvers, showdeps, showsize,
+				     visual_preview, always_prompt, verbose);
+	  else if(!strcasecmp(argv[optind], "upgrade"))
+	    return cmdline_upgrade(argc-optind, argv+optind,
+				   status_fname,
+				   simulate, assume_yes, download_only,
+				   showvers, showdeps, showsize,
+				   visual_preview, always_prompt, verbose);
+	  else if(!strcasecmp(argv[optind], "download"))
+	    return cmdline_download(argc-optind, argv+optind);
+	  else if(!strcasecmp(argv[optind], "changelog"))
+	    return cmdline_changelog(argc-optind, argv+optind);
+	  else if(!strcasecmp(argv[optind], "moo"))
+	    return cmdline_moo(argc-optind, argv+optind, verbose);
+	  else if(!strcasecmp(argv[optind], "show"))
+	    return cmdline_show(argc-optind, argv+optind, verbose);
+	  else if(!strcasecmp(argv[optind], "dump-resolver"))
+	    return cmdline_dump_resolver(argc-optind, argv+optind, status_fname);
+	  else if(!strcasecmp(argv[optind], "help"))
+	    {
+	      usage();
+	      exit(0);
+	    }
+	  else
+	    {
+	      fprintf(stderr, _("Unknown command \"%s\"\n"), argv[optind]);
+	      usage();
+	      exit(1);
+	    }
+	}
+      catch(NoMoreSolutions)
 	{
-	  usage();
-	  exit(0);
+	  fprintf(stderr, "%s", _("Internal error: uncaught 'out of solutions' exception.\n"));
+	  exit(-1);
 	}
-      else
+      catch(NoMoreTime)
 	{
-	  fprintf(stderr, _("Unknown command \"%s\"\n"), argv[optind]);
-	  usage();
-	  exit(1);
+	  fprintf(stderr, "%s", _("Internal error: uncaught 'out of time' exception.\n"));
+	  exit(-1);
 	}
     }
 
@@ -416,30 +431,43 @@
   
   ui_init();
 
-  vs_progress *p=gen_progress_bar();
-  apt_init(p, true, status_fname);
-  if(status_fname)
-    free(status_fname);
-  check_apt_errors();
+  try
+    {
+      vs_progress *p=gen_progress_bar();
+      apt_init(p, true, status_fname);
+      if(status_fname)
+	free(status_fname);
+      check_apt_errors();
 
-  file_quit.connect(sigc::ptr_fun(vscreen_exitmain));
+      file_quit.connect(sigc::ptr_fun(vscreen_exitmain));
 
-  if(apt_cache_file)
-    {
-      (*apt_cache_file)->package_state_changed.connect(sigc::ptr_fun(vscreen_update));
-      (*apt_cache_file)->package_category_changed.connect(sigc::ptr_fun(vscreen_update));
-    }
+      if(apt_cache_file)
+	{
+	  (*apt_cache_file)->package_state_changed.connect(sigc::ptr_fun(vscreen_update));
+	  (*apt_cache_file)->package_category_changed.connect(sigc::ptr_fun(vscreen_update));
+	}
 
-  do_new_package_view(*p);
-  p->destroy();
+      do_new_package_view(*p);
+      p->destroy();
 
-  if(update_only)
-    do_update_lists();
-  else if(install_only)
-    do_package_run_or_show_preview();
-    //install_or_remove_packages();
+      if(update_only)
+	do_update_lists();
+      else if(install_only)
+	do_package_run_or_show_preview();
+      //install_or_remove_packages();
 
-  ui_main();
+      ui_main();
+    }
+  catch(NoMoreSolutions)
+    {
+      fprintf(stderr, "%s", _("Internal error: uncaught 'out of solutions' exception.\n"));
+      exit(-1);
+    }
+  catch(NoMoreTime)
+    {
+      fprintf(stderr, "%s", _("Internal error: uncaught 'out of time' exception.\n"));
+      exit(-1);
+    }
 
   return 0;
 }