]> git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.cc
b49b365393a8d69b69d2743a6cd43e4f1d54a973
[apt.git] / apt-pkg / cacheset.cc
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 cache structures as to the complete set of all structures
7 in the pkgCache. Currently only Package is supported.
8
9 ##################################################################### */
10 /*}}}*/
11 // Include Files /*{{{*/
12 #include <apt-pkg/aptconfiguration.h>
13 #include <apt-pkg/error.h>
14 #include <apt-pkg/cacheset.h>
15 #include <apt-pkg/strutl.h>
16
17 #include <apti18n.h>
18
19 #include <vector>
20
21 #include <regex.h>
22 /*}}}*/
23 namespace APT {
24 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
25 PackageSet PackageSet::FromRegEx(pkgCache &Cache, std::string pattern, std::ostream &out) {
26 PackageSet pkgset;
27 std::string arch = "native";
28 static const char * const isregex = ".?+*|[^$";
29
30 if (pattern.find_first_of(isregex) == std::string::npos)
31 return pkgset;
32
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
42 regex_t Pattern;
43 int Res;
44 if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
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;
55 pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
56 if (Pkg.end() == true) {
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);
62 }
63 if (Pkg.end() == true)
64 continue;
65 }
66
67 ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
68 Pkg.FullName(true).c_str(), pattern.c_str());
69
70 pkgset.insert(Pkg);
71 }
72
73 regfree(&Pattern);
74
75 return pkgset;
76 }
77 /*}}}*/
78 // FromCommandLine - Return all packages specified on commandline /*{{{*/
79 PackageSet 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 }
100 return pkgset;
101 }
102 /*}}}*/
103 }