summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheiterators.h2
-rw-r--r--apt-pkg/makefile2
-rw-r--r--apt-pkg/packageset.cc62
-rw-r--r--apt-pkg/packageset.h24
-rw-r--r--cmdline/apt-get.cc42
-rw-r--r--debian/changelog1
6 files changed, 96 insertions, 37 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 3d58f7ec0..ee852f594 100644
--- a/apt-pkg/cacheiterators.h
+++ b/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;};
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index d4537859d..968275c5c 100644
--- a/apt-pkg/makefile
+++ b/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 \
diff --git a/apt-pkg/packageset.cc b/apt-pkg/packageset.cc
new file mode 100644
index 000000000..f452bc052
--- /dev/null
+++ b/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;
+}
+ /*}}}*/
+}
diff --git a/apt-pkg/packageset.h b/apt-pkg/packageset.h
index d80536942..cd1430a2a 100644
--- a/apt-pkg/packageset.h
+++ b/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);
+ }
+
/*}}}*/
};
/*}}}*/
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 44235e358..1cffd6730 100644
--- a/cmdline/apt-get.cc
+++ b/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);
}
diff --git a/debian/changelog b/debian/changelog
index 6980e5fcf..023d513be 100644
--- a/debian/changelog
+++ b/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