From fe870febbfc1145d4a2a6b86985b0253419d52a8 Mon Sep 17 00:00:00 2001
From: David Kalnischkies <kalnischkies@gmail.com>
Date: Sat, 5 Jun 2010 15:47:16 +0200
Subject: [PATCH] handle :arch modifier in PackageSet::FromString correctly

---
 apt-pkg/cacheset.cc | 26 ++++++++++++++++++++------
 apt-pkg/cacheset.h  |  4 ++--
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index 5dbd1a4df..8fcffaf9a 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -87,17 +87,31 @@ PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline
 }
 									/*}}}*/
 // FromString - Return all packages matching a specific string		/*{{{*/
-PackageSet PackageSet::FromString(pkgCacheFile &Cache, const char * const str, std::ostream &out) {
-	pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(str);
-	if (Grp.end() == false) {
-		pkgCache::PkgIterator Pkg = Grp.FindPreferredPkg();
+PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) {
+	std::string pkg = str;
+	size_t archfound = pkg.find_last_of(':');
+	std::string arch;
+	if (archfound != std::string::npos) {
+		arch = pkg.substr(archfound+1);
+		pkg.erase(archfound);
+	}
+
+	pkgCache::PkgIterator Pkg;
+	if (arch.empty() == true) {
+		pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg);
+		if (Grp.end() == false)
+			Pkg = Grp.FindPreferredPkg();
+	} else
+		Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch);
+
+	if (Pkg.end() == false) {
 		PackageSet pkgset;
 		pkgset.insert(Pkg);
 		return pkgset;
 	}
 	PackageSet regex = FromRegEx(Cache, str, out);
 	if (regex.empty() == true)
-		_error->Warning(_("Unable to locate package %s"), str);
+		_error->Warning(_("Unable to locate package %s"), str.c_str());
 	return regex;
 }
 									/*}}}*/
@@ -188,7 +202,7 @@ pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
 		pkgCache::PkgIterator const &Pkg, bool const &AllowError) {
 	if (unlikely(Cache.BuildDepCache() == false))
 		return pkgCache::VerIterator(*Cache);
-	pkgCache::VerIterator Cand = Cache[Pkg].InstVerIter(Cache);
+	pkgCache::VerIterator Cand = Cache[Pkg].CandidateVerIter(Cache);
 	if (AllowError == false && Cand.end() == true)
 		_error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str());
 	return Cand;
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index b65e053e6..4f7be4caa 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -83,8 +83,8 @@ public:									/*{{{*/
 	    \param Cache the packages are in
 	    \param string String the package name(s) should be extracted from
 	    \param out stream to print various notices to */
-	static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string, std::ostream &out);
-	static APT::PackageSet FromString(pkgCacheFile &Cache, const char * const string) {
+	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out);
+	static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) {
 		std::ostream out (std::ofstream("/dev/null").rdbuf());
 		return APT::PackageSet::FromString(Cache, string, out);
 	}
-- 
2.47.2