Bladeren bron

Merge remote-tracking branch 'donkult/debian/sid' into debian/experimental

Conflicts:
	apt-private/private-install.cc
Michael Vogt 12 jaren geleden
bovenliggende
commit
8d20b69d2f

+ 14 - 7
apt-pkg/contrib/strutl.cc

@@ -434,23 +434,30 @@ string TimeToStr(unsigned long Sec)
 /* This replaces all occurrences of Subst with Contents in Str. */
 /* This replaces all occurrences of Subst with Contents in Str. */
 string SubstVar(const string &Str,const string &Subst,const string &Contents)
 string SubstVar(const string &Str,const string &Subst,const string &Contents)
 {
 {
+   if (Subst.empty() == true)
+      return Str;
+
    string::size_type Pos = 0;
    string::size_type Pos = 0;
    string::size_type OldPos = 0;
    string::size_type OldPos = 0;
    string Temp;
    string Temp;
-   
-   while (OldPos < Str.length() && 
+
+   while (OldPos < Str.length() &&
 	  (Pos = Str.find(Subst,OldPos)) != string::npos)
 	  (Pos = Str.find(Subst,OldPos)) != string::npos)
    {
    {
-      Temp += string(Str,OldPos,Pos) + Contents;
-      OldPos = Pos + Subst.length();      
+      if (OldPos != Pos)
+	 Temp.append(Str, OldPos, Pos - OldPos);
+      if (Contents.empty() == false)
+	 Temp.append(Contents);
+      OldPos = Pos + Subst.length();
    }
    }
-   
+
    if (OldPos == 0)
    if (OldPos == 0)
       return Str;
       return Str;
-   
+
+   if (OldPos >= Str.length())
+      return Temp;
    return Temp + string(Str,OldPos);
    return Temp + string(Str,OldPos);
 }
 }
-
 string SubstVar(string Str,const struct SubstVar *Vars)
 string SubstVar(string Str,const struct SubstVar *Vars)
 {
 {
    for (; Vars->Subst != 0; Vars++)
    for (; Vars->Subst != 0; Vars++)

+ 7 - 0
apt-pkg/edsp.cc

@@ -26,6 +26,7 @@
 #include <time.h>
 #include <time.h>
 #include <unistd.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <algorithm>
 #include <iostream>
 #include <iostream>
 #include <vector>
 #include <vector>
 #include <limits>
 #include <limits>
@@ -50,7 +51,12 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
    if (Progress != NULL)
    if (Progress != NULL)
       Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
       Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver"));
    unsigned long p = 0;
    unsigned long p = 0;
+   std::vector<std::string> archs = APT::Configuration::getArchitectures();
    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
    for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+   {
+      std::string const arch = Pkg.Arch();
+      if (std::find(archs.begin(), archs.end(), arch) == archs.end())
+	 continue;
       for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
       for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p)
       {
       {
 	 WriteScenarioVersion(Cache, output, Pkg, Ver);
 	 WriteScenarioVersion(Cache, output, Pkg, Ver);
@@ -59,6 +65,7 @@ bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress)
 	 if (Progress != NULL && p % 100 == 0)
 	 if (Progress != NULL && p % 100 == 0)
 	    Progress->Progress(p);
 	    Progress->Progress(p);
       }
       }
+   }
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 6 - 0
apt-pkg/upgrade.cc

@@ -143,6 +143,12 @@ static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache)
  */
  */
 static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache)
 static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache)
 {
 {
+   std::string const solver = _config->Find("APT::Solver", "internal");
+   if (solver != "internal") {
+      OpTextProgress Prog(*_config);
+      return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog);
+   }
+
    pkgDepCache::ActionGroup group(Cache);
    pkgDepCache::ActionGroup group(Cache);
 
 
    pkgProblemResolver Fix(&Cache);
    pkgProblemResolver Fix(&Cache);

+ 16 - 7
apt-private/private-install.cc

@@ -19,7 +19,7 @@
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
-#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/upgrade.h>
 #include <apt-pkg/install-progress.h>
 #include <apt-pkg/install-progress.h>
 
 
 #include <errno.h>
 #include <errno.h>
@@ -527,15 +527,14 @@ static bool DoAutomaticRemove(CacheFile &Cache)
 static const unsigned short MOD_REMOVE = 1;
 static const unsigned short MOD_REMOVE = 1;
 static const unsigned short MOD_INSTALL = 2;
 static const unsigned short MOD_INSTALL = 2;
 
 
-bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache)
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode)
 {
 {
    std::map<unsigned short, APT::VersionSet> verset;
    std::map<unsigned short, APT::VersionSet> verset;
-   return DoCacheManipulationFromCommandLine(CmdL, Cache, verset);
+   return DoCacheManipulationFromCommandLine(CmdL, Cache, verset, UpgradeMode);
 }
 }
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
-                                        std::map<unsigned short, APT::VersionSet> &verset)
+                                        std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode)
 {
 {
-
    // Enter the special broken fixing mode if the user specified arguments
    // Enter the special broken fixing mode if the user specified arguments
    bool BrokenFix = false;
    bool BrokenFix = false;
    if (Cache->BrokenCount() != 0)
    if (Cache->BrokenCount() != 0)
@@ -620,7 +619,17 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
       if (Fix != NULL)
       if (Fix != NULL)
       {
       {
 	 // Call the scored problem resolver
 	 // Call the scored problem resolver
-	 if (Fix->Resolve(true) == false && Cache->BrokenCount() == 0)
+	 bool resolver_fail = false;
+	 if (UpgradeMode == 0)
+	 {
+	    if (strcmp(CmdL.FileList[0], "dist-upgrade") == 0 || strcmp(CmdL.FileList[0], "full-upgrade") == 0)
+	       resolver_fail = APT::Upgrade::Upgrade(Cache, 0);
+	    else
+	       resolver_fail = Fix->Resolve(true);
+	 } else
+	    resolver_fail = APT::Upgrade::Upgrade(Cache, UpgradeMode);
+
+	 if (resolver_fail == false && Cache->BrokenCount() == 0)
 	    return false;
 	    return false;
       }
       }
 
 
@@ -703,7 +712,7 @@ bool DoInstall(CommandLine &CmdL)
    
    
    std::map<unsigned short, APT::VersionSet> verset;
    std::map<unsigned short, APT::VersionSet> verset;
 
 
-   if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset))
+   if(!DoCacheManipulationFromCommandLine(CmdL, Cache, verset, 0))
       return false;
       return false;
 
 
    /* Print out a list of packages that are going to be installed extra
    /* Print out a list of packages that are going to be installed extra

+ 2 - 2
apt-private/private-install.h

@@ -21,8 +21,8 @@ class pkgProblemResolver;
 APT_PUBLIC bool DoInstall(CommandLine &Cmd);
 APT_PUBLIC bool DoInstall(CommandLine &Cmd);
 
 
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
 bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
-                                        std::map<unsigned short, APT::VersionSet> &verset);
-bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache);
+                                        std::map<unsigned short, APT::VersionSet> &verset, int UpgradeMode);
+bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache, int UpgradeMode);
 
 
 APT_PUBLIC bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
 APT_PUBLIC bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
                         bool Safety = true);
                         bool Safety = true);

+ 108 - 96
apt-private/private-output.cc

@@ -344,129 +344,141 @@ bool ShowList(ostream &out,string Title,string List,string VersionsList)
            Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
            Depends: libldap2 (>= 2.0.2-2) but it is not going to be installed
            Depends: libsasl7 but it is not going to be installed   
            Depends: libsasl7 but it is not going to be installed   
  */
  */
-void ShowBroken(ostream &out,CacheFile &Cache,bool Now)
+static void ShowBrokenPackage(ostream &out, pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg, bool const Now)
 {
 {
-   if (Cache->BrokenCount() == 0)
+   if (Now == true)
+   {
+      if ((*Cache)[Pkg].NowBroken() == false)
+	 return;
+   }
+   else
+   {
+      if ((*Cache)[Pkg].InstBroken() == false)
+	 return;
+   }
+
+   // Print out each package and the failed dependencies
+   out << " " << Pkg.FullName(true) << " :";
+   unsigned const Indent = Pkg.FullName(true).size() + 3;
+   bool First = true;
+   pkgCache::VerIterator Ver;
+
+   if (Now == true)
+      Ver = Pkg.CurrentVer();
+   else
+      Ver = (*Cache)[Pkg].InstVerIter(*Cache);
+
+   if (Ver.end() == true)
+   {
+      out << endl;
       return;
       return;
+   }
 
 
-   out << _("The following packages have unmet dependencies:") << endl;
-   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
    {
    {
-      pkgCache::PkgIterator I(Cache,Cache.List[J]);
-      
+      // Compute a single dependency element (glob or)
+      pkgCache::DepIterator Start;
+      pkgCache::DepIterator End;
+      D.GlobOr(Start,End); // advances D
+
+      if ((*Cache)->IsImportantDep(End) == false)
+	 continue;
+
       if (Now == true)
       if (Now == true)
       {
       {
-	 if (Cache[I].NowBroken() == false)
+	 if (((*Cache)[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
 	    continue;
 	    continue;
       }
       }
       else
       else
       {
       {
-	 if (Cache[I].InstBroken() == false)
+	 if (((*Cache)[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
 	    continue;
 	    continue;
       }
       }
-      
-      // Print out each package and the failed dependencies
-      out << " " << I.FullName(true) << " :";
-      unsigned const Indent = I.FullName(true).size() + 3;
-      bool First = true;
-      pkgCache::VerIterator Ver;
-      
-      if (Now == true)
-	 Ver = I.CurrentVer();
-      else
-	 Ver = Cache[I].InstVerIter(Cache);
-      
-      if (Ver.end() == true)
-      {
-	 out << endl;
-	 continue;
-      }
-      
-      for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;)
+
+      bool FirstOr = true;
+      while (1)
       {
       {
-	 // Compute a single dependency element (glob or)
-	 pkgCache::DepIterator Start;
-	 pkgCache::DepIterator End;
-	 D.GlobOr(Start,End); // advances D
+	 if (First == false)
+	    for (unsigned J = 0; J != Indent; J++)
+	       out << ' ';
+	 First = false;
 
 
-	 if (Cache->IsImportantDep(End) == false)
-	    continue;
-	 
-	 if (Now == true)
+	 if (FirstOr == false)
 	 {
 	 {
-	    if ((Cache[End] & pkgDepCache::DepGNow) == pkgDepCache::DepGNow)
-	       continue;
+	    for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
+	       out << ' ';
 	 }
 	 }
 	 else
 	 else
+	    out << ' ' << End.DepType() << ": ";
+	 FirstOr = false;
+
+	 out << Start.TargetPkg().FullName(true);
+
+	 // Show a quick summary of the version requirements
+	 if (Start.TargetVer() != 0)
+	    out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
+
+	 /* Show a summary of the target package if possible. In the case
+	    of virtual packages we show nothing */
+	 pkgCache::PkgIterator Targ = Start.TargetPkg();
+	 if (Targ->ProvidesList == 0)
 	 {
 	 {
-	    if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
-	       continue;
-	 }
-	 
-	 bool FirstOr = true;
-	 while (1)
-	 {
-	    if (First == false)
-	       for (unsigned J = 0; J != Indent; J++)
-		  out << ' ';
-	    First = false;
+	    out << ' ';
+	    pkgCache::VerIterator Ver = (*Cache)[Targ].InstVerIter(*Cache);
+	    if (Now == true)
+	       Ver = Targ.CurrentVer();
 
 
-	    if (FirstOr == false)
+	    if (Ver.end() == false)
 	    {
 	    {
-	       for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++)
-		  out << ' ';
+	       if (Now == true)
+		  ioprintf(out,_("but %s is installed"),Ver.VerStr());
+	       else
+		  ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
 	    }
 	    }
 	    else
 	    else
-	       out << ' ' << End.DepType() << ": ";
-	    FirstOr = false;
-	    
-	    out << Start.TargetPkg().FullName(true);
-	 
-	    // Show a quick summary of the version requirements
-	    if (Start.TargetVer() != 0)
-	       out << " (" << Start.CompType() << " " << Start.TargetVer() << ")";
-	    
-	    /* Show a summary of the target package if possible. In the case
-	       of virtual packages we show nothing */	 
-	    pkgCache::PkgIterator Targ = Start.TargetPkg();
-	    if (Targ->ProvidesList == 0)
 	    {
 	    {
-	       out << ' ';
-	       pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache);
-	       if (Now == true)
-		  Ver = Targ.CurrentVer();
-	       	    
-	       if (Ver.end() == false)
+	       if ((*Cache)[Targ].CandidateVerIter(*Cache).end() == true)
 	       {
 	       {
-		  if (Now == true)
-		     ioprintf(out,_("but %s is installed"),Ver.VerStr());
+		  if (Targ->ProvidesList == 0)
+		     out << _("but it is not installable");
 		  else
 		  else
-		     ioprintf(out,_("but %s is to be installed"),Ver.VerStr());
-	       }	       
+		     out << _("but it is a virtual package");
+	       }
 	       else
 	       else
-	       {
-		  if (Cache[Targ].CandidateVerIter(Cache).end() == true)
-		  {
-		     if (Targ->ProvidesList == 0)
-			out << _("but it is not installable");
-		     else
-			out << _("but it is a virtual package");
-		  }		  
-		  else
-		     out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
-	       }	       
+		  out << (Now?_("but it is not installed"):_("but it is not going to be installed"));
 	    }
 	    }
-	    
-	    if (Start != End)
-	       out << _(" or");
-	    out << endl;
-	    
-	    if (Start == End)
-	       break;
-	    ++Start;
-	 }	 
-      }	    
-   }   
+	 }
+
+	 if (Start != End)
+	    out << _(" or");
+	 out << endl;
+
+	 if (Start == End)
+	    break;
+	 ++Start;
+      }
+   }
+}
+void ShowBroken(ostream &out, CacheFile &Cache, bool const Now)
+{
+   if (Cache->BrokenCount() == 0)
+      return;
+
+   out << _("The following packages have unmet dependencies:") << endl;
+   for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+   {
+      pkgCache::PkgIterator const I(Cache,Cache.List[J]);
+      ShowBrokenPackage(out, &Cache, I, Now);
+   }
+}
+void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
+{
+   if (Cache->BrokenCount() == 0)
+      return;
+
+   out << _("The following packages have unmet dependencies:") << endl;
+   for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
+      ShowBrokenPackage(out, &Cache, Pkg, Now);
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ShowNew - Show packages to newly install				/*{{{*/
 // ShowNew - Show packages to newly install				/*{{{*/

+ 2 - 1
apt-private/private-output.h

@@ -28,7 +28,8 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
 
 
 
 
 // helper to describe global state
 // helper to describe global state
-APT_PUBLIC void ShowBroken(std::ostream &out,CacheFile &Cache,bool Now);
+APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now);
+APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now);
 
 
 APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List,
 APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List,
               std::string VersionsList);
               std::string VersionsList);

+ 5 - 2
apt-private/private-update.cc

@@ -86,11 +86,14 @@ bool DoUpdate(CommandLine &CmdL)
          if (I->CurrentVer != 0 && state.Upgradable())
          if (I->CurrentVer != 0 && state.Upgradable())
             upgradable++;
             upgradable++;
       }
       }
-      const char *msg = ngettext(
+      const char *msg = P_(
          "%i package can be upgraded. Run 'apt list --upgradable' to see it.\n",
          "%i package can be upgraded. Run 'apt list --upgradable' to see it.\n",
          "%i packages can be upgraded. Run 'apt list --upgradable' to see them.\n",
          "%i packages can be upgraded. Run 'apt list --upgradable' to see them.\n",
          upgradable);
          upgradable);
-      ioprintf(c1out, msg, upgradable);
+      if (upgradable == 0)
+         c1out << _("All packages are up to date.") << std::endl;
+      else
+         ioprintf(c1out, msg, upgradable);
    }
    }
 
 
    return true;
    return true;

+ 2 - 10
apt-private/private-upgrade.cc

@@ -23,18 +23,10 @@ static bool UpgradeHelper(CommandLine &CmdL, int UpgradeFlags)
       return false;
       return false;
 
 
    c0out << _("Calculating upgrade... ") << std::flush;
    c0out << _("Calculating upgrade... ") << std::flush;
-   if (APT::Upgrade::Upgrade(Cache, UpgradeFlags) == false)
-   {
-      c0out << _("Failed") << std::endl;
-      ShowBroken(c1out,Cache,false);
-      return _error->Error(_("Internal error, Upgrade broke stuff"));
-   }
+   if(!DoCacheManipulationFromCommandLine(CmdL, Cache, UpgradeFlags))
+      return false;
    c0out << _("Done") << std::endl;
    c0out << _("Done") << std::endl;
 
 
-   // parse additional cmdline pkg manipulation switches
-   if(!DoCacheManipulationFromCommandLine(CmdL, Cache))
-      return false;
-   
    return InstallPackages(Cache,true);
    return InstallPackages(Cache,true);
 }
 }
 
 

+ 14 - 10
cmdline/apt-internal-solver.cc

@@ -24,9 +24,11 @@
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-private/private-output.h>
 
 
 #include <string.h>
 #include <string.h>
 #include <iostream>
 #include <iostream>
+#include <sstream>
 #include <list>
 #include <list>
 #include <string>
 #include <string>
 #include <unistd.h>
 #include <unistd.h>
@@ -171,18 +173,20 @@ int main(int argc,const char *argv[])					/*{{{*/
 
 
 	EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output);
 	EDSP::WriteProgress(60, "Call problemresolver on current scenario…", output);
 
 
+	std::string failure;
 	if (upgrade == true) {
 	if (upgrade == true) {
-		if (pkgAllUpgrade(CacheFile) == false) {
-			EDSP::WriteError("ERR_UNSOLVABLE_UPGRADE", "An upgrade error occurred", output);
-			return 0;
-		}
+		if (pkgAllUpgrade(CacheFile) == false)
+			failure = "ERR_UNSOLVABLE_UPGRADE";
 	} else if (distUpgrade == true) {
 	} else if (distUpgrade == true) {
-		if (pkgDistUpgrade(CacheFile) == false) {
-			EDSP::WriteError("ERR_UNSOLVABLE_DIST_UPGRADE", "An dist-upgrade error occurred", output);
-			return 0;
-		}
-	} else if (Fix.Resolve() == false) {
-		EDSP::WriteError("ERR_UNSOLVABLE", "An error occurred", output);
+		if (pkgDistUpgrade(CacheFile) == false)
+			failure = "ERR_UNSOLVABLE_DIST_UPGRADE";
+	} else if (Fix.Resolve() == false)
+		failure = "ERR_UNSOLVABLE";
+
+	if (failure.empty() == false) {
+		std::ostringstream broken;
+		ShowBroken(broken, CacheFile, false);
+		EDSP::WriteError(failure.c_str(), broken.str(), output);
 		return 0;
 		return 0;
 	}
 	}
 
 

+ 10 - 10
cmdline/makefile

@@ -8,49 +8,49 @@ include ../buildlib/defaults.mak
 # The apt program
 # The apt program
 PROGRAM=apt
 PROGRAM=apt
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt.cc
 SOURCE = apt.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-cache program
 # The apt-cache program
 PROGRAM=apt-cache
 PROGRAM=apt-cache
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-cache.cc
 SOURCE = apt-cache.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-get program
 # The apt-get program
 PROGRAM=apt-get
 PROGRAM=apt-get
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-get.cc 
 SOURCE = apt-get.cc 
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-config program
 # The apt-config program
 PROGRAM=apt-config
 PROGRAM=apt-config
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-config.cc
 SOURCE = apt-config.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-cdrom program
 # The apt-cdrom program
 PROGRAM=apt-cdrom
 PROGRAM=apt-cdrom
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-cdrom.cc 
 SOURCE = apt-cdrom.cc 
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-mark program
 # The apt-mark program
 PROGRAM=apt-mark
 PROGRAM=apt-mark
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-mark.cc
 SOURCE = apt-mark.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The apt-helper
 # The apt-helper
 PROGRAM=apt-helper
 PROGRAM=apt-helper
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-helper.cc
 SOURCE = apt-helper.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
@@ -75,14 +75,14 @@ include $(PROGRAM_H)
 # The apt-extracttemplates program
 # The apt-extracttemplates program
 PROGRAM=apt-extracttemplates
 PROGRAM=apt-extracttemplates
 SLIBS = -lapt-pkg -lapt-inst $(INTLLIBS)
 SLIBS = -lapt-pkg -lapt-inst $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+LIB_MAKES = apt-pkg/makefile apt-inst/makefile
 SOURCE = apt-extracttemplates.cc 
 SOURCE = apt-extracttemplates.cc 
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 
 # The internal solver acting as an external
 # The internal solver acting as an external
 PROGRAM=apt-internal-solver
 PROGRAM=apt-internal-solver
-SLIBS = -lapt-pkg $(INTLLIBS)
-LIB_MAKES = apt-pkg/makefile
+SLIBS = -lapt-pkg -lapt-private $(INTLLIBS)
+LIB_MAKES = apt-pkg/makefile apt-private/makefile
 SOURCE = apt-internal-solver.cc
 SOURCE = apt-internal-solver.cc
 include $(PROGRAM_H)
 include $(PROGRAM_H)
 
 

+ 1 - 1
doc/apt-secure.8.xml

@@ -193,7 +193,7 @@
 <refsect1><title>See Also</title> 
 <refsect1><title>See Also</title> 
 <para> 
 <para> 
 &apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;,
 &apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;,
-&debsign; &debsig-verify;, &gpg;
+&debsign;, &debsig-verify;, &gpg;
 </para>
 </para>
 
 
 <para>For more background information you might want to review the
 <para>For more background information you might want to review the

+ 19 - 9
doc/external-dependency-solver-protocol.txt

@@ -5,6 +5,14 @@ external dependency solvers. The protocol is called APT EDSP, for "APT
 External Dependency Solver Protocol".
 External Dependency Solver Protocol".
 
 
 
 
+## Terminology
+
+In the following we use the term **architecture qualified package name**
+(or *arch-qualified package names* for short) to refer to package
+identifiers of the form "package:arch" where "package" is a package name
+and "arch" a dpkg architecture.
+
+
 ## Components
 ## Components
 
 
 - **APT**: we know this one.
 - **APT**: we know this one.
@@ -62,6 +70,7 @@ configuration documentation for more, and more up to date, information.
 - **Dir::Bin::Solvers**: absolute path of the directory where to look for
 - **Dir::Bin::Solvers**: absolute path of the directory where to look for
   external solvers. Defaults to `/usr/lib/apt/solvers`.
   external solvers. Defaults to `/usr/lib/apt/solvers`.
 
 
+
 ## Protocol
 ## Protocol
 
 
 When configured to use an external solver, APT will resort to it to
 When configured to use an external solver, APT will resort to it to
@@ -132,9 +141,9 @@ The following **configuration fields** are supported in request stanzas:
 The following **action fields** are supported in request stanzas:
 The following **action fields** are supported in request stanzas:
 
 
 - **Install:** (optional, defaults to the empty string) A space
 - **Install:** (optional, defaults to the empty string) A space
-  separated list of package names, with *no version attached*, to
-  install. This field denotes a list of packages that the user wants to
-  install, usually via an APT `install` request.
+  separated list of arch-qualified package names, with *no version
+  attached*, to install. This field denotes a list of packages that the
+  user wants to install, usually via an APT `install` request.
 
 
 - **Remove:** (optional, defaults to the empty string) Same syntax of
 - **Remove:** (optional, defaults to the empty string) Same syntax of
   Install. This field denotes a list of packages that the user wants to
   Install. This field denotes a list of packages that the user wants to
@@ -201,7 +210,7 @@ field. The following fields are supported in package stanzas:
 - **APT-Candidate:** (optional, defaults to `no`). Allowed values:
 - **APT-Candidate:** (optional, defaults to `no`). Allowed values:
   `yes`, `no`. When set to `yes`, the corresponding package is the APT
   `yes`, `no`. When set to `yes`, the corresponding package is the APT
   candidate for installation among all available packages with the same
   candidate for installation among all available packages with the same
-  name.
+  name and architecture.
 
 
 - **APT-Automatic:** (optional, defaults to `no`). Allowed values:
 - **APT-Automatic:** (optional, defaults to `no`). Allowed values:
   `yes`, `no`. When set to `yes`, the corresponding package is marked by
   `yes`, `no`. When set to `yes`, the corresponding package is marked by
@@ -218,6 +227,7 @@ field. The following fields are supported in package stanzas:
   Release file entry (Origin, Label, Codename, etc.) in the format of
   Release file entry (Origin, Label, Codename, etc.) in the format of
   APT_PREFERENCES(5).
   APT_PREFERENCES(5).
 
 
+
 ### Answer
 ### Answer
 
 
 An answer from the external solver to APT is either a *solution* or an
 An answer from the external solver to APT is either a *solution* or an
@@ -226,11 +236,11 @@ An answer from the external solver to APT is either a *solution* or an
 The following invariant on **exit codes** must hold true. When the
 The following invariant on **exit codes** must hold true. When the
 external solver is *able to find a solution*, it will write the solution
 external solver is *able to find a solution*, it will write the solution
 to standard output and then exit with an exit code of 0. When the
 to standard output and then exit with an exit code of 0. When the
-external solver is *unable to find a solution* (and s aware of that), it
-will write an error to standard output and then exit with an exit code
-of 0. An exit code other than 0 will be interpreted as a solver crash
-with no meaningful error about dependency resolution to convey to the
-user.
+external solver is *unable to find a solution* (and is aware of that),
+it will write an error to standard output and then exit with an exit
+code of 0. An exit code other than 0 will be interpreted as a solver
+crash with no meaningful error about dependency resolution to convey to
+the user.
 
 
 
 
 #### Solution
 #### Solution

+ 1 - 1
doc/po/apt-doc.pot

@@ -2153,7 +2153,7 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>

+ 4 - 4
doc/po/de.po

@@ -726,7 +726,7 @@ msgid ""
 "installed instead of removed."
 "installed instead of removed."
 msgstr ""
 msgstr ""
 "<literal>remove</literal> ist identisch mit <literal>install</literal>, mit "
 "<literal>remove</literal> ist identisch mit <literal>install</literal>, mit "
-"der Ausnahme, dass Pakte entfernt anstatt installiert werden. Beachten Sie, "
+"der Ausnahme, dass Pakete entfernt anstatt installiert werden. Beachten Sie, "
 "dass das Entfernen von Paketen deren Konfigurationsdateien im System "
 "dass das Entfernen von Paketen deren Konfigurationsdateien im System "
 "belässt. Wenn ein Pluszeichen an den Paketnamen angehängt wird (ohne "
 "belässt. Wenn ein Pluszeichen an den Paketnamen angehängt wird (ohne "
 "Leerzeichen dazwischen) wird das erkannte Paket installiert anstatt entfernt."
 "Leerzeichen dazwischen) wird das erkannte Paket installiert anstatt entfernt."
@@ -1051,7 +1051,7 @@ msgid ""
 "you wish to upgrade, and if a newer version is available, it (and its "
 "you wish to upgrade, and if a newer version is available, it (and its "
 "dependencies, as described above) will be downloaded and installed."
 "dependencies, as described above) will be downloaded and installed."
 msgstr ""
 msgstr ""
-"Dies ist außerdem die bevorzugt zu benutzende Art, wenn Sie Sie ein Upgrade "
+"Dies ist außerdem die bevorzugt zu benutzende Art, wenn Sie ein Upgrade "
 "eines oder mehrerer bereits installierter Pakete durchführen möchten, ohne "
 "eines oder mehrerer bereits installierter Pakete durchführen möchten, ohne "
 "ein Upgrade aller Pakete, die Sie auf Ihrem System haben, durchzuführen. "
 "ein Upgrade aller Pakete, die Sie auf Ihrem System haben, durchzuführen. "
 "Anders als das Ziel von »upgrade«, das die neusten Versionen aller aktuell "
 "Anders als das Ziel von »upgrade«, das die neusten Versionen aller aktuell "
@@ -3010,10 +3010,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/es.po

@@ -3098,10 +3098,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/fr.po

@@ -3022,10 +3022,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/it.po

@@ -3033,10 +3033,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/ja.po

@@ -2963,10 +2963,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/pl.po

@@ -3131,10 +3131,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 2 - 2
doc/po/pt.po

@@ -3042,10 +3042,10 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>
 #: apt-secure.8.xml:199
 #: apt-secure.8.xml:199

+ 1 - 1
doc/po/pt_BR.po

@@ -2159,7 +2159,7 @@ msgstr ""
 #: apt-secure.8.xml:195
 #: apt-secure.8.xml:195
 msgid ""
 msgid ""
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
 "&apt-conf;, &apt-get;, &sources-list;, &apt-key;, &apt-ftparchive;, "
-"&debsign; &debsig-verify;, &gpg;"
+"&debsign;, &debsig-verify;, &gpg;"
 msgstr ""
 msgstr ""
 
 
 #. type: Content of: <refentry><refsect1><para>
 #. type: Content of: <refentry><refsect1><para>

+ 6 - 0
test/integration/test-external-dependency-solver-protocol

@@ -51,6 +51,12 @@ rm -f /tmp/dump.edsp
 testfailure aptget install --solver dump awesomecoolstuff:i386 -s
 testfailure aptget install --solver dump awesomecoolstuff:i386 -s
 testsuccess test -s /tmp/dump.edsp
 testsuccess test -s /tmp/dump.edsp
 
 
+testsuccess aptget dist-upgrade -s
+testsuccess aptget dist-upgrade -s --solver apt
+
+testsuccess aptget upgrade -s
+testsuccess aptget upgrade -s --solver apt
+
 configarchitecture 'armel'
 configarchitecture 'armel'
 msgtest 'Test direct calling is okay for' 'apt-internal-solver'
 msgtest 'Test direct calling is okay for' 'apt-internal-solver'
 cat /tmp/dump.edsp | aptinternalsolver > solver.result 2>&1 || true
 cat /tmp/dump.edsp | aptinternalsolver > solver.result 2>&1 || true

+ 35 - 0
test/libapt/strutil_test.cc

@@ -70,3 +70,38 @@ TEST(StrUtilTest,EndsWith)
    EXPECT_FALSE(Endswith("abcd", "x"));
    EXPECT_FALSE(Endswith("abcd", "x"));
    EXPECT_FALSE(Endswith("abcd", "abcndefg"));
    EXPECT_FALSE(Endswith("abcd", "abcndefg"));
 }
 }
+TEST(StrUtilTest,SubstVar)
+{
+   EXPECT_EQ("", SubstVar("", "fails", "passes"));
+   EXPECT_EQ("test ", SubstVar("test fails", "fails", ""));
+   EXPECT_EQ("test passes", SubstVar("test passes", "", "fails"));
+
+   EXPECT_EQ("test passes", SubstVar("test passes", "fails", "passes"));
+   EXPECT_EQ("test passes", SubstVar("test fails", "fails", "passes"));
+
+   EXPECT_EQ("starts with", SubstVar("beginnt with", "beginnt", "starts"));
+   EXPECT_EQ("beginnt with", SubstVar("starts with", "starts", "beginnt"));
+   EXPECT_EQ("is in middle", SubstVar("is in der middle", "in der", "in"));
+   EXPECT_EQ("is in der middle", SubstVar("is in middle", "in", "in der"));
+   EXPECT_EQ("does end", SubstVar("does enden", "enden", "end"));
+   EXPECT_EQ("does enden", SubstVar("does end", "end", "enden"));
+
+   EXPECT_EQ("abc", SubstVar("abc", "d", "a"));
+   EXPECT_EQ("abc", SubstVar("abd", "d", "c"));
+   EXPECT_EQ("abc", SubstVar("adc", "d", "b"));
+   EXPECT_EQ("abc", SubstVar("dbc", "d", "a"));
+
+   EXPECT_EQ("b", SubstVar("b", "aa", "a"));
+   EXPECT_EQ("bb", SubstVar("bb", "aa", "a"));
+   EXPECT_EQ("bbb", SubstVar("bbb", "aa", "a"));
+
+   EXPECT_EQ("aa", SubstVar("aaaa", "aa", "a"));
+   EXPECT_EQ("aaaa", SubstVar("aa", "a", "aa"));
+   EXPECT_EQ("aaaa", SubstVar("aaaa", "a", "a"));
+   EXPECT_EQ("a a a a ", SubstVar("aaaa", "a", "a "));
+
+   EXPECT_EQ(" bb bb bb bb ", SubstVar(" a a a a ", "a", "bb"));
+   EXPECT_EQ(" bb bb bb bb ", SubstVar(" aaa aaa aaa aaa ", "aaa", "bb"));
+   EXPECT_EQ(" bb a bb a bb a bb ", SubstVar(" aaa a aaa a aaa a aaa ", "aaa", "bb"));
+
+}