From dc0f01f7cbe2ed8ae6a1d2dbc0e00c19bb04679d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 19 Jun 2010 11:49:38 +0200 Subject: get packages by task^ with FromTask() --- cmdline/cacheset.cc | 76 ++++++++++++++++++++++++++++++++++++++++++++++++----- cmdline/cacheset.h | 20 ++++++++++++-- 2 files changed, 87 insertions(+), 9 deletions(-) (limited to 'cmdline') diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc index fde52168a..55ab26780 100644 --- a/cmdline/cacheset.cc +++ b/cmdline/cacheset.cc @@ -11,27 +11,83 @@ // Include Files /*{{{*/ #include #include -#include #include #include #include +#include "cacheset.h" + #include #include /*}}}*/ namespace APT { +// FromTask - Return all packages in the cache from a specific task /*{{{*/ +PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { + PackageSet pkgset; + if (Cache.BuildCaches() == false || Cache.BuildDepCache() == false) + return pkgset; + + size_t archfound = pattern.find_last_of(':'); + std::string arch = "native"; + if (archfound != std::string::npos) { + arch = pattern.substr(archfound+1); + pattern.erase(archfound); + } + + if (pattern[pattern.length() -1] != '^') + return pkgset; + pattern.erase(pattern.length()-1); + + // get the records + pkgRecords Recs(Cache); + + // build regexp for the task + regex_t Pattern; + char S[300]; + snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str()); + if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) { + _error->Error("Failed to compile task regexp"); + return pkgset; + } + + for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) { + pkgCache::PkgIterator Pkg = Grp.FindPkg(arch); + if (Pkg.end() == true) + continue; + pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache); + if(ver.end() == true) + continue; + + pkgRecords::Parser &parser = Recs.Lookup(ver.FileList()); + const char *start, *end; + parser.GetRec(start,end); + unsigned int const length = end - start; + char buf[length]; + strncpy(buf, start, length); + buf[length-1] = '\0'; + if (regexec(&Pattern, buf, 0, 0, 0) == 0) + pkgset.insert(Pkg); + } + + if (pkgset.empty() == true) + _error->Error(_("Couldn't find task %s"), pattern.c_str()); + + regfree(&Pattern); + return pkgset; +} + /*}}}*/ // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/ PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) { PackageSet pkgset; - std::string arch = "native"; static const char * const isregex = ".?+*|[^$"; if (pattern.find_first_of(isregex) == std::string::npos) return pkgset; size_t archfound = pattern.find_last_of(':'); + std::string arch = "native"; if (archfound != std::string::npos) { arch = pattern.substr(archfound+1); if (arch.find_first_of(isregex) == std::string::npos) @@ -142,10 +198,16 @@ PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, s pkgset.insert(Pkg); return pkgset; } - PackageSet regex = FromRegEx(Cache, str, out); - if (regex.empty() == true) - _error->Warning(_("Unable to locate package %s"), str.c_str()); - return regex; + PackageSet pset = FromTask(Cache, str, out); + if (pset.empty() == false) + return pset; + + pset = FromRegEx(Cache, str, out); + if (pset.empty() == false) + return pset; + + _error->Warning(_("Unable to locate package %s"), str.c_str()); + return pset; } /*}}}*/ // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/ @@ -236,7 +298,7 @@ APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg, } if (V.end() == true) continue; - if (ver == V.VerStr()) + if (ver != V.VerStr()) ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"), V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str()); verset.insert(V); diff --git a/cmdline/cacheset.h b/cmdline/cacheset.h index 2bc268380..64a72e758 100644 --- a/cmdline/cacheset.h +++ b/cmdline/cacheset.h @@ -28,7 +28,7 @@ class PackageSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::PkgIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -62,10 +62,25 @@ public: /*{{{*/ }; // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef APT::PackageSet::const_iterator iterator; + /*}}}*/ using std::set::insert; inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set::insert(P); }; + /** \brief returns all packages in the cache who belong to the given task + + A simple helper responsible for search for all members of a task + in the cache. Optional it prints a a notice about the + packages chosen cause of the given task. + \param Cache the packages are in + \param pattern name of the task + \param out stream to print the notice to */ + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, std::ostream &out); + static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) { + std::ostream out (std::ofstream("/dev/null").rdbuf()); + return APT::PackageSet::FromTask(Cache, pattern, out); + } + /** \brief returns all packages in the cache whose name matchs a given pattern A simple helper responsible for executing a regular expression on all @@ -134,7 +149,7 @@ class VersionSet : public std::set { /*{{{*/ pkgCache. */ public: /*{{{*/ /** \brief smell like a pkgCache::VerIterator */ - class const_iterator : public std::set::const_iterator { + class const_iterator : public std::set::const_iterator {/*{{{*/ public: const_iterator(std::set::const_iterator x) : std::set::const_iterator(x) {} @@ -168,6 +183,7 @@ public: /*{{{*/ inline bool Pseudo() const { return (**this).Pseudo(); }; inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; }; + /*}}}*/ // 103. set::iterator is required to be modifiable, but this allows modification of keys typedef APT::VersionSet::const_iterator iterator; -- cgit v1.2.3