Parcourir la source

get packages by task^ with FromTask()

David Kalnischkies il y a 16 ans
Parent
commit
dc0f01f7cb
3 fichiers modifiés avec 88 ajouts et 9 suppressions
  1. 69 7
      cmdline/cacheset.cc
  2. 18 2
      cmdline/cacheset.h
  3. 1 0
      debian/changelog

+ 69 - 7
cmdline/cacheset.cc

@@ -11,27 +11,83 @@
 // Include Files							/*{{{*/
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/cacheset.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/versionmatch.h>
 
 #include <apti18n.h>
 
+#include "cacheset.h"
+
 #include <vector>
 
 #include <regex.h>
 									/*}}}*/
 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);

+ 18 - 2
cmdline/cacheset.h

@@ -28,7 +28,7 @@ class PackageSet : public std::set<pkgCache::PkgIterator> {		/*{{{*/
     pkgCache. */
 public:									/*{{{*/
 	/** \brief smell like a pkgCache::PkgIterator */
-	class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {
+	class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {/*{{{*/
 	public:
 		const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) :
 			 std::set<pkgCache::PkgIterator>::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<pkgCache::PkgIterator>::insert;
 	inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set<pkgCache::PkgIterator>::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::VerIterator> {		/*{{{*/
     pkgCache. */
 public:									/*{{{*/
 	/** \brief smell like a pkgCache::VerIterator */
-	class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {
+	class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {/*{{{*/
 	public:
 		const_iterator(std::set<pkgCache::VerIterator>::const_iterator x) :
 			 std::set<pkgCache::VerIterator>::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;
 

+ 1 - 0
debian/changelog

@@ -4,6 +4,7 @@ apt (0.7.26~exp8) UNRELEASED; urgency=low
     - doesn't include it in the library for now as it is too volatile
     - get the candidate either from an already built depcache
       or use the policy which is a bit faster than depcache generation
+    - get packages by task^ with FromTask()
   * apt-pkg/orderlist.cc:
     - untouched packages are never missing
   * apt-pkg/packagemanager.cc: