]>
git.saurik.com Git - apt.git/blob - cmdline/cacheset.cc
1 // -*- mode: cpp; mode: fold -*-
3 /* ######################################################################
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.
9 ##################################################################### */
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 #include <apt-pkg/versionmatch.h>
25 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
26 PackageSet
PackageSet::FromRegEx(pkgCacheFile
&Cache
, std::string pattern
, std::ostream
&out
) {
28 std::string arch
= "native";
29 static const char * const isregex
= ".?+*|[^$";
31 if (pattern
.find_first_of(isregex
) == std::string::npos
)
34 size_t archfound
= pattern
.find_last_of(':');
35 if (archfound
!= std::string::npos
) {
36 arch
= pattern
.substr(archfound
+1);
37 if (arch
.find_first_of(isregex
) == std::string::npos
)
38 pattern
.erase(archfound
);
45 if ((Res
= regcomp(&Pattern
, pattern
.c_str() , REG_EXTENDED
| REG_ICASE
| REG_NOSUB
)) != 0) {
47 regerror(Res
, &Pattern
, Error
, sizeof(Error
));
48 _error
->Error(_("Regex compilation error - %s"), Error
);
52 for (pkgCache::GrpIterator Grp
= Cache
.GetPkgCache()->GrpBegin(); Grp
.end() == false; ++Grp
)
54 if (regexec(&Pattern
, Grp
.Name(), 0, 0, 0) != 0)
56 pkgCache::PkgIterator Pkg
= Grp
.FindPkg(arch
);
57 if (Pkg
.end() == true) {
58 if (archfound
== std::string::npos
) {
59 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
60 for (std::vector
<std::string
>::const_iterator a
= archs
.begin();
61 a
!= archs
.end() && Pkg
.end() != true; ++a
)
62 Pkg
= Grp
.FindPkg(*a
);
64 if (Pkg
.end() == true)
68 ioprintf(out
, _("Note, selecting %s for regex '%s'\n"),
69 Pkg
.FullName(true).c_str(), pattern
.c_str());
79 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
80 std::map
<unsigned short, PackageSet
> PackageSet::GroupedFromCommandLine(
81 pkgCacheFile
&Cache
, const char **cmdline
,
82 std::list
<PackageSet::Modifier
> const &mods
,
83 unsigned short const &fallback
, std::ostream
&out
) {
84 std::map
<unsigned short, PackageSet
> pkgsets
;
85 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
86 unsigned short modID
= fallback
;
88 for (std::list
<PackageSet::Modifier
>::const_iterator mod
= mods
.begin();
89 mod
!= mods
.end(); ++mod
) {
90 size_t const alength
= strlen(mod
->Alias
);
92 case PackageSet::Modifier::POSTFIX
:
93 if (str
.compare(str
.length() - alength
, alength
,
94 mod
->Alias
, 0, alength
) != 0)
96 str
.erase(str
.length() - alength
);
99 case PackageSet::Modifier::PREFIX
:
101 case PackageSet::Modifier::NONE
:
106 PackageSet pset
= PackageSet::FromString(Cache
, str
, out
);
107 pkgsets
[modID
].insert(pset
.begin(), pset
.end());
112 // FromCommandLine - Return all packages specified on commandline /*{{{*/
113 PackageSet
PackageSet::FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
, std::ostream
&out
) {
115 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
116 PackageSet pset
= FromString(Cache
, *I
, out
);
117 pkgset
.insert(pset
.begin(), pset
.end());
122 // FromString - Return all packages matching a specific string /*{{{*/
123 PackageSet
PackageSet::FromString(pkgCacheFile
&Cache
, std::string
const &str
, std::ostream
&out
) {
124 std::string pkg
= str
;
125 size_t archfound
= pkg
.find_last_of(':');
127 if (archfound
!= std::string::npos
) {
128 arch
= pkg
.substr(archfound
+1);
129 pkg
.erase(archfound
);
132 pkgCache::PkgIterator Pkg
;
133 if (arch
.empty() == true) {
134 pkgCache::GrpIterator Grp
= Cache
.GetPkgCache()->FindGrp(pkg
);
135 if (Grp
.end() == false)
136 Pkg
= Grp
.FindPreferredPkg();
138 Pkg
= Cache
.GetPkgCache()->FindPkg(pkg
, arch
);
140 if (Pkg
.end() == false) {
145 PackageSet regex
= FromRegEx(Cache
, str
, out
);
146 if (regex
.empty() == true)
147 _error
->Warning(_("Unable to locate package %s"), str
.c_str());
151 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
152 std::map
<unsigned short, VersionSet
> VersionSet::GroupedFromCommandLine(
153 pkgCacheFile
&Cache
, const char **cmdline
,
154 std::list
<VersionSet::Modifier
> const &mods
,
155 unsigned short const &fallback
, std::ostream
&out
) {
156 std::map
<unsigned short, VersionSet
> versets
;
157 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
158 unsigned short modID
= fallback
;
159 VersionSet::Version select
= VersionSet::NEWEST
;
160 std::string str
= *I
;
161 for (std::list
<VersionSet::Modifier
>::const_iterator mod
= mods
.begin();
162 mod
!= mods
.end(); ++mod
) {
163 if (modID
== fallback
&& mod
->ID
== fallback
)
164 select
= mod
->SelectVersion
;
165 size_t const alength
= strlen(mod
->Alias
);
167 case VersionSet::Modifier::POSTFIX
:
168 if (str
.compare(str
.length() - alength
, alength
,
169 mod
->Alias
, 0, alength
) != 0)
171 str
.erase(str
.length() - alength
);
173 select
= mod
->SelectVersion
;
175 case VersionSet::Modifier::PREFIX
:
177 case VersionSet::Modifier::NONE
:
182 VersionSet vset
= VersionSet::FromString(Cache
, str
, select
, out
);
183 versets
[modID
].insert(vset
.begin(), vset
.end());
188 // FromCommandLine - Return all versions specified on commandline /*{{{*/
189 APT::VersionSet
VersionSet::FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
,
190 APT::VersionSet::Version
const &fallback
, std::ostream
&out
) {
192 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
193 VersionSet vset
= VersionSet::FromString(Cache
, *I
, fallback
, out
);
194 verset
.insert(vset
.begin(), vset
.end());
199 // FromString - Returns all versions spedcified by a string /*{{{*/
200 APT::VersionSet
VersionSet::FromString(pkgCacheFile
&Cache
, std::string pkg
,
201 APT::VersionSet::Version
const &fallback
, std::ostream
&out
) {
203 bool verIsRel
= false;
204 size_t const vertag
= pkg
.find_last_of("/=");
205 if (vertag
!= string::npos
) {
206 ver
= pkg
.substr(vertag
+1);
207 verIsRel
= (pkg
[vertag
] == '/');
210 PackageSet pkgset
= PackageSet::FromString(Cache
, pkg
.c_str(), out
);
212 for (PackageSet::const_iterator P
= pkgset
.begin();
213 P
!= pkgset
.end(); ++P
) {
214 if (vertag
== string::npos
) {
215 AddSelectedVersion(Cache
, verset
, P
, fallback
);
218 pkgCache::VerIterator V
;
219 if (ver
== "installed")
220 V
= getInstalledVer(Cache
, P
);
221 else if (ver
== "candidate")
222 V
= getCandidateVer(Cache
, P
);
224 pkgVersionMatch
Match(ver
, (verIsRel
== true ? pkgVersionMatch::Release
:
225 pkgVersionMatch::Version
));
227 if (V
.end() == true) {
228 if (verIsRel
== true)
229 _error
->Error(_("Release '%s' for '%s' was not found"),
230 ver
.c_str(), P
.FullName(true).c_str());
232 _error
->Error(_("Version '%s' for '%s' was not found"),
233 ver
.c_str(), P
.FullName(true).c_str());
239 if (ver
== V
.VerStr())
240 ioprintf(out
, _("Selected version '%s' (%s) for '%s'\n"),
241 V
.VerStr(), V
.RelStr().c_str(), P
.FullName(true).c_str());
247 // AddSelectedVersion - add version from package based on fallback /*{{{*/
248 bool VersionSet::AddSelectedVersion(pkgCacheFile
&Cache
, VersionSet
&verset
,
249 pkgCache::PkgIterator
const &P
, VersionSet::Version
const &fallback
,
250 bool const &AllowError
) {
251 pkgCache::VerIterator V
;
253 case VersionSet::ALL
:
254 if (P
->VersionList
!= 0)
255 for (V
= P
.VersionList(); V
.end() != true; ++V
)
257 else if (AllowError
== false)
258 return _error
->Error(_("Can't select versions from package '%s' as it purely virtual"), P
.FullName(true).c_str());
262 case VersionSet::CANDANDINST
:
263 verset
.insert(getInstalledVer(Cache
, P
, AllowError
));
264 verset
.insert(getCandidateVer(Cache
, P
, AllowError
));
266 case VersionSet::CANDIDATE
:
267 verset
.insert(getCandidateVer(Cache
, P
, AllowError
));
269 case VersionSet::INSTALLED
:
270 verset
.insert(getInstalledVer(Cache
, P
, AllowError
));
272 case VersionSet::CANDINST
:
273 V
= getCandidateVer(Cache
, P
, true);
275 V
= getInstalledVer(Cache
, P
, true);
276 if (V
.end() == false)
278 else if (AllowError
== false)
279 return _error
->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P
.FullName(true).c_str());
283 case VersionSet::INSTCAND
:
284 V
= getInstalledVer(Cache
, P
, true);
286 V
= getCandidateVer(Cache
, P
, true);
287 if (V
.end() == false)
289 else if (AllowError
== false)
290 return _error
->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P
.FullName(true).c_str());
294 case VersionSet::NEWEST
:
295 if (P
->VersionList
!= 0)
296 verset
.insert(P
.VersionList());
297 else if (AllowError
== false)
298 return _error
->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P
.FullName(true).c_str());
306 // getCandidateVer - Returns the candidate version of the given package /*{{{*/
307 pkgCache::VerIterator
VersionSet::getCandidateVer(pkgCacheFile
&Cache
,
308 pkgCache::PkgIterator
const &Pkg
, bool const &AllowError
) {
309 pkgCache::VerIterator Cand
;
310 if (Cache
.IsDepCacheBuilt() == true)
311 Cand
= Cache
[Pkg
].CandidateVerIter(Cache
);
313 if (unlikely(Cache
.BuildPolicy() == false))
314 return pkgCache::VerIterator(*Cache
);
315 Cand
= Cache
.GetPolicy()->GetCandidateVer(Pkg
);
317 if (AllowError
== false && Cand
.end() == true)
318 _error
->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg
.FullName(true).c_str());
322 // getInstalledVer - Returns the installed version of the given package /*{{{*/
323 pkgCache::VerIterator
VersionSet::getInstalledVer(pkgCacheFile
&Cache
,
324 pkgCache::PkgIterator
const &Pkg
, bool const &AllowError
) {
325 if (AllowError
== false && Pkg
->CurrentVer
== 0)
326 _error
->Error(_("Can't select installed version from package %s as it is not installed"), Pkg
.FullName(true).c_str());
327 return Pkg
.CurrentVer();