]> git.saurik.com Git - apt.git/blame - apt-pkg/packageset.cc
improve the handling of regex together with the architecture modifier
[apt.git] / apt-pkg / packageset.cc
CommitLineData
ffee1c2b
DK
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
3/* ######################################################################
4
5 Simple wrapper around a std::set to provide a similar interface to
6 a set of packages as to the complete set of all packages in the
7 pkgCache.
8
9 ##################################################################### */
10 /*}}}*/
11// Include Files /*{{{*/
78c32596 12#include <apt-pkg/aptconfiguration.h>
ffee1c2b
DK
13#include <apt-pkg/error.h>
14#include <apt-pkg/packageset.h>
15#include <apt-pkg/strutl.h>
16
17#include <apti18n.h>
18
78c32596
DK
19#include <vector>
20
ffee1c2b
DK
21#include <regex.h>
22 /*}}}*/
23namespace APT {
24// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
6e235c66 25PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) {
ffee1c2b 26 PackageSet pkgset;
6e235c66
DK
27 std::string arch = "native";
28 static const char * const isregex = ".?+*|[^$";
ffee1c2b 29
6e235c66 30 if (pattern.find_first_of(isregex) == std::string::npos)
ffee1c2b
DK
31 return pkgset;
32
6e235c66
DK
33 size_t archfound = pattern.find_last_of(':');
34 if (archfound != std::string::npos) {
35 arch = pattern.substr(archfound+1);
36 if (arch.find_first_of(isregex) == std::string::npos)
37 pattern.erase(archfound);
38 else
39 arch = "native";
40 }
41
ffee1c2b
DK
42 regex_t Pattern;
43 int Res;
6e235c66 44 if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
ffee1c2b
DK
45 char Error[300];
46 regerror(Res, &Pattern, Error, sizeof(Error));
47 _error->Error(_("Regex compilation error - %s"), Error);
48 return pkgset;
49 }
50
51 for (pkgCache::GrpIterator Grp = Cache.GrpBegin(); Grp.end() == false; ++Grp)
52 {
53 if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
54 continue;
6e235c66 55 pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
78c32596 56 if (Pkg.end() == true) {
6e235c66
DK
57 if (archfound == std::string::npos) {
58 std::vector<std::string> archs = APT::Configuration::getArchitectures();
59 for (std::vector<std::string>::const_iterator a = archs.begin();
60 a != archs.end() && Pkg.end() != true; ++a)
61 Pkg = Grp.FindPkg(*a);
78c32596
DK
62 }
63 if (Pkg.end() == true)
64 continue;
65 }
ffee1c2b
DK
66
67 ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
6e235c66 68 Pkg.FullName(true).c_str(), pattern.c_str());
ffee1c2b
DK
69
70 pkgset.insert(Pkg);
71 }
72
73 regfree(&Pattern);
74
78c32596
DK
75 return pkgset;
76}
77 /*}}}*/
78// FromCommandLine - Return all packages specified on commandline /*{{{*/
79PackageSet PackageSet::FromCommandLine(pkgCache &Cache, const char **cmdline, std::ostream &out) {
80 PackageSet pkgset;
81 for (const char **I = cmdline + 1; *I != 0; I++) {
82 pkgCache::PkgIterator Pkg = Cache.FindPkg(*I);
83 if (Pkg.end() == true) {
84 std::vector<std::string> archs = APT::Configuration::getArchitectures();
85 for (std::vector<std::string>::const_iterator a = archs.begin();
86 a != archs.end() || Pkg.end() != true; ++a) {
87 Pkg = Cache.FindPkg(*I, *a);
88 }
89 if (Pkg.end() == true) {
90 PackageSet regex = FromRegEx(Cache, *I, out);
91 if (regex.empty() == true)
92 _error->Warning(_("Unable to locate package %s"),*I);
93 else
94 pkgset.insert(regex.begin(), regex.end());
95 continue;
96 }
97 }
98 pkgset.insert(Pkg);
99 }
ffee1c2b
DK
100 return pkgset;
101}
102 /*}}}*/
103}