Преглед изворни кода

move regex magic from apt-get to new FromRegEx method

David Kalnischkies пре 16 година
родитељ
комит
ffee1c2bed
6 измењених фајлова са 96 додато и 37 уклоњено
  1. 1 1
      apt-pkg/cacheiterators.h
  2. 1 1
      apt-pkg/makefile
  3. 62 0
      apt-pkg/packageset.cc
  4. 23 1
      apt-pkg/packageset.h
  5. 8 34
      cmdline/apt-get.cc
  6. 1 0
      debian/changelog

+ 1 - 1
apt-pkg/cacheiterators.h

@@ -66,7 +66,7 @@ template<typename Str, typename Itr> class pkgCache::Iterator :
 	inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;};
 	inline Str &operator *() {return *S;};
 	inline Str const &operator *() const {return *S;};
-	inline pkgCache *Cache() {return Owner;};
+	inline pkgCache *Cache() const {return Owner;};
 
 	// Mixed stuff
 	inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;};

+ 1 - 1
apt-pkg/makefile

@@ -35,7 +35,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
 	 srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
 	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
 	 indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
-	 aptconfiguration.cc
+	 aptconfiguration.cc packageset.cc
 HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
 	  orderlist.h sourcelist.h packagemanager.h tagfile.h \
 	  init.h pkgcache.h version.h progress.h pkgrecords.h \

+ 62 - 0
apt-pkg/packageset.cc

@@ -0,0 +1,62 @@
+// -*- mode: cpp; mode: fold -*-
+// Description								/*{{{*/
+/* ######################################################################
+
+   Simple wrapper around a std::set to provide a similar interface to
+   a set of packages as to the complete set of all packages in the
+   pkgCache.
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <apt-pkg/error.h>
+#include <apt-pkg/packageset.h>
+#include <apt-pkg/strutl.h>
+
+#include <apti18n.h>
+
+#include <regex.h>
+									/*}}}*/
+namespace APT {
+// FromRegEx - Return all packages in the cache matching a pattern	/*{{{*/
+PackageSet PackageSet::FromRegEx(pkgCache &Cache, const char * const pattern, std::ostream &out) {
+	PackageSet pkgset;
+
+	const char * I;
+	for (I = pattern; *I != 0; I++)
+		if (*I == '.' || *I == '?' || *I == '+' || *I == '*' ||
+		    *I == '|' || *I == '[' || *I == '^' || *I == '$')
+			break;
+	if (*I == 0)
+		return pkgset;
+
+	regex_t Pattern;
+	int Res;
+	if ((Res = regcomp(&Pattern, pattern , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
+		char Error[300];
+		regerror(Res, &Pattern, Error, sizeof(Error));
+		_error->Error(_("Regex compilation error - %s"), Error);
+		return pkgset;
+	}
+
+	for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp)
+	{
+		if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
+			continue;
+		pkgCache::PkgIterator Pkg = Grp.FindPkg("native");
+		if (unlikely(Pkg.end() == true))
+			// FIXME: Fallback to different architectures here?
+			continue;
+
+		ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
+			 Pkg.Name(), pattern);
+
+		pkgset.insert(Pkg);
+	}
+
+	regfree(&Pattern);
+
+	return pkgset;
+}
+									/*}}}*/
+}

+ 23 - 1
apt-pkg/packageset.h

@@ -10,7 +10,11 @@
 #ifndef APT_PACKAGESET_H
 #define APT_PACKAGESET_H
 // Include Files							/*{{{*/
+#include <iostream>
+#include <fstream>
+#include <set>
 #include <string>
+
 #include <apt-pkg/pkgcache.h>
 									/*}}}*/
 namespace APT {
@@ -22,6 +26,8 @@ public:									/*{{{*/
 		const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) :
 			 std::set<pkgCache::PkgIterator>::const_iterator(x) {}
 
+		operator pkgCache::PkgIterator(void) { return **this; }
+
 		inline const char *Name() const {return (*this)->Name(); }
 		inline std::string FullName(bool const &Pretty) const { return (*this)->FullName(Pretty); }
 		inline std::string FullName() const { return (*this)->FullName(); }
@@ -36,7 +42,8 @@ public:									/*{{{*/
 		inline pkgCache::PkgIterator::OkState State() const { return (*this)->State(); }
 		inline const char *CandVersion() const { return (*this)->CandVersion(); }
 		inline const char *CurVersion() const { return (*this)->CurVersion(); }
-		inline pkgCache *Cache() {return (*this)->Cache();};
+		inline pkgCache *Cache() const { return (*this)->Cache(); };
+		inline unsigned long Index() const {return (*this)->Index();};
 
 		friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, (*i)); }
 
@@ -46,6 +53,21 @@ public:									/*{{{*/
 	};
 	// 103. set::iterator is required to be modifiable, but this allows modification of keys
 	typedef typename APT::PackageSet::const_iterator iterator;
+
+	/** \brief returns all packages in the cache whose name matchs a given pattern
+
+	    A simple helper responsible for executing a regular expression on all
+	    package names in the cache. Optional it prints a a notice about the
+	    packages chosen cause of the given package.
+	    \param Cache the packages are in
+	    \param pattern regular expression for package names
+	    \param out stream to print the notice to */
+	static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern, std::ostream &out);
+	static APT::PackageSet FromRegEx(pkgCache &Cache, const char *pattern) {
+		std::ostream out (std::ofstream("/dev/null").rdbuf());
+		return APT::PackageSet::FromRegEx(Cache, pattern, out);
+	}
+
 									/*}}}*/
 };
 									/*}}}*/

+ 8 - 34
cmdline/apt-get.cc

@@ -40,7 +40,8 @@
 #include <apt-pkg/sptr.h>
 #include <apt-pkg/md5.h>
 #include <apt-pkg/versionmatch.h>
-    
+#include <apt-pkg/packageset.h>
+
 #include <config.h>
 #include <apti18n.h>
 
@@ -1780,51 +1781,24 @@ bool DoInstall(CommandLine &CmdL)
 	 Packages++;
 	 if (Pkg.end() == true)
 	 {
-	    // Check if the name is a regex
-	    const char *I;
-	    for (I = S; *I != 0; I++)
-	       if (*I == '?' || *I == '*' || *I == '|' ||
-		   *I == '[' || *I == '^' || *I == '$')
-		  break;
-	    if (*I == 0)
+	    APT::PackageSet pkgset = APT::PackageSet::FromRegEx(Cache, S, c1out);
+	    if (pkgset.empty() == true)
 	       return _error->Error(_("Couldn't find package %s"),S);
 
 	    // Regexs must always be confirmed
 	    ExpectedInst += 1000;
-	 
-	    // Compile the regex pattern
-	    regex_t Pattern;
-	    int Res;
-	    if ((Res = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE |
-			       REG_NOSUB)) != 0)
-	    {
-	       char Error[300];	    
-	       regerror(Res,&Pattern,Error,sizeof(Error));
-	       return _error->Error(_("Regex compilation error - %s"),Error);
-	    }
-	 
-	    // Run over the matches
+
 	    bool Hit = false;
-	    for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp)
+	    for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
 	    {
-	       if (regexec(&Pattern,Grp.Name(),0,0,0) != 0)
-		  continue;
-	       Pkg = Grp.FindPkg("native");
-	       if (unlikely(Pkg.end() == true))
-		  continue;
-
-	       ioprintf(c1out,_("Note, selecting %s for regex '%s'\n"),
-			Pkg.Name(),S);
-	    
 	       if (VerTag != 0)
 		  if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
 		     return false;
-	    
+
 	       Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
 				   ExpectedInst,false);
 	    }
-	    regfree(&Pattern);
-	 
+
 	    if (Hit == false)
 	       return _error->Error(_("Couldn't find package %s"),S);
 	 }

+ 1 - 0
debian/changelog

@@ -24,6 +24,7 @@ apt (0.7.26~exp6) UNRELEASED; urgency=low
     - add a virtual destructor to FTWScanner class (for cppcheck)
   * apt-pkg/packageset.h:
     - add a simple wrapper around std::set for packages with it
+    - move regex magic from apt-get to new FromRegEx method
 
  -- David Kalnischkies <kalnischkies@gmail.com>  Sat, 29 May 2010 19:09:05 +0200