From 856d3b06a6eb6a7f455294c69fc13604e099fd56 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 5 Jun 2010 09:20:29 +0200 Subject: Add a method to get a VersionSet from the Commandline and refactor the existing methods a bit to reuse them easier intern --- apt-pkg/cacheset.cc | 140 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 121 insertions(+), 19 deletions(-) (limited to 'apt-pkg/cacheset.cc') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index b49b36539..7372c909e 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -22,7 +23,7 @@ /*}}}*/ namespace APT { // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ -PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) { +PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; std::string arch = "native"; static const char * const isregex = ".?+*|[^$"; @@ -48,7 +49,7 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostr return pkgset; } - for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp) + for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp) { if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0) continue; @@ -76,28 +77,129 @@ PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostr } /*}}}*/ // FromCommandLine - Return all packages specified on commandline /*{{{*/ -PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) { +PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) { PackageSet pkgset; for (const char **I = cmdline + 1; *I != 0; I++) { - pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); - if (Pkg.end() == true) { - std::vector archs = APT::Configuration::getArchitectures(); - for (std::vector::const_iterator a = archs.begin(); - a != archs.end() || Pkg.end() != true; ++a) { - Pkg = Cache.FindPkg(*I, *a); - } - if (Pkg.end() == true) { - PackageSet regex = FromRegEx(Cache, *I, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"),*I); - else - pkgset.insert(regex.begin(), regex.end()); - continue; + PackageSet pset = FromString(Cache, *I, out); + pkgset.insert(pset.begin(), pset.end()); + } + return pkgset; +} + /*}}}*/ +// 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 pkgset; + pkgset.insert(Pkg); + return pkgset; + } + PackageSet regex = FromRegEx(Cache, str, out); + if (regex.empty() == true) + _error->Warning(_("Unable to locate package %s"), str); + return regex; +} + /*}}}*/ +// FromCommandLine - Return all versions specified on commandline /*{{{*/ +APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, + APT::VersionSet::Version const &fallback, std::ostream &out) { + VersionSet verset; + for (const char **I = cmdline + 1; *I != 0; I++) { + std::string pkg = *I; + std::string ver; + bool verIsRel = false; + size_t const vertag = pkg.find_last_of("/="); + if (vertag != string::npos) { + ver = pkg.substr(vertag+1); + verIsRel = (pkg[vertag] == '/'); + pkg.erase(vertag); + } + PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out); + for (PackageSet::const_iterator P = pkgset.begin(); + P != pkgset.end(); ++P) { + if (vertag != string::npos) { + pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release : + pkgVersionMatch::Version)); + pkgCache::VerIterator V = Match.Find(P); + if (V.end() == true) { + if (verIsRel == true) + _error->Error(_("Release '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + else + _error->Error(_("Version '%s' for '%s' was not found"), + ver.c_str(), P.FullName(true).c_str()); + continue; + } + if (strcmp(ver.c_str(), V.VerStr()) != 0) + ioprintf(out, _("Selected version %s (%s) for %s\n"), + V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); + verset.insert(V); + } else { + pkgCache::VerIterator V; + switch(fallback) { + case VersionSet::ALL: + for (V = P.VersionList(); V.end() != true; ++V) + verset.insert(V); + break; + case VersionSet::CANDANDINST: + verset.insert(getInstalledVer(Cache, P)); + verset.insert(getCandidateVer(Cache, P)); + break; + case VersionSet::CANDIDATE: + verset.insert(getCandidateVer(Cache, P)); + break; + case VersionSet::INSTALLED: + verset.insert(getInstalledVer(Cache, P)); + break; + case VersionSet::CANDINST: + V = getCandidateVer(Cache, P, true); + if (V.end() == true) + V = getInstalledVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else + _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); + break; + case VersionSet::INSTCAND: + V = getInstalledVer(Cache, P, true); + if (V.end() == true) + V = getCandidateVer(Cache, P, true); + if (V.end() == false) + verset.insert(V); + else + _error->Error(_("Can't select installed nor candidate version from package %s as it has neither of them"), P.FullName(true).c_str()); + break; + case VersionSet::NEWEST: + if (P->VersionList != 0) + verset.insert(P.VersionList()); + else + _error->Error(_("Can't select newest version from package %s as it is purely virtual"), P.FullName(true).c_str()); + break; + } } } - pkgset.insert(Pkg); } - return pkgset; + return verset; +} + /*}}}*/ +// getCandidateVer - Returns the candidate version of the given package /*{{{*/ +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); + 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; +} + /*}}}*/ +// getInstalledVer - Returns the installed version of the given package /*{{{*/ +pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache, + pkgCache::PkgIterator const &Pkg, bool const &AllowError) { + if (AllowError == false && Pkg->CurrentVer == 0) + _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str()); + return Pkg.CurrentVer(); } /*}}}*/ } -- cgit v1.2.3