move regex magic from apt-get to new FromRegEx method
authorDavid Kalnischkies <kalnischkies@gmail.com>
Sun, 30 May 2010 21:12:41 +0000 (23:12 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Sun, 30 May 2010 21:12:41 +0000 (23:12 +0200)
apt-pkg/cacheiterators.h
apt-pkg/makefile
apt-pkg/packageset.cc [new file with mode: 0644]
apt-pkg/packageset.h
cmdline/apt-get.cc
debian/changelog

index 3d58f7e..ee852f5 100644 (file)
@@ -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;};
index d453785..968275c 100644 (file)
@@ -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 \
diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc
new file mode 100644 (file)
index 0000000..f452bc0
--- /dev/null
@@ -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;
+}
+                                                                       /*}}}*/
+}
index d805369..cd1430a 100644 (file)
 #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);
+       }
+
                                                                        /*}}}*/
 };
                                                                        /*}}}*/
index 44235e3..1cffd67 100644 (file)
@@ -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);
         }
index 6980e5f..023d513 100644 (file)
@@ -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