]>
git.saurik.com Git - apt.git/blob - apt-pkg/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/cachefilter.h>
14 #include <apt-pkg/cacheset.h>
15 #include <apt-pkg/error.h>
16 #include <apt-pkg/strutl.h>
17 #include <apt-pkg/versionmatch.h>
26 // FromTask - Return all packages in the cache from a specific task /*{{{*/
27 PackageSet
PackageSet::FromTask(pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
) {
28 size_t const archfound
= pattern
.find_last_of(':');
29 std::string arch
= "native";
30 if (archfound
!= std::string::npos
) {
31 arch
= pattern
.substr(archfound
+1);
32 pattern
.erase(archfound
);
35 if (pattern
[pattern
.length() -1] != '^')
36 return APT::PackageSet(TASK
);
37 pattern
.erase(pattern
.length()-1);
39 if (unlikely(Cache
.GetPkgCache() == 0 || Cache
.GetDepCache() == 0))
40 return APT::PackageSet(TASK
);
42 PackageSet
pkgset(TASK
);
44 pkgRecords
Recs(Cache
);
46 // build regexp for the task
49 snprintf(S
, sizeof(S
), "^Task:.*[, ]%s([, ]|$)", pattern
.c_str());
50 if(regcomp(&Pattern
,S
, REG_EXTENDED
| REG_NOSUB
| REG_NEWLINE
) != 0) {
51 _error
->Error("Failed to compile task regexp");
55 for (pkgCache::GrpIterator Grp
= Cache
->GrpBegin(); Grp
.end() == false; ++Grp
) {
56 pkgCache::PkgIterator Pkg
= Grp
.FindPkg(arch
);
57 if (Pkg
.end() == true)
59 pkgCache::VerIterator ver
= Cache
[Pkg
].CandidateVerIter(Cache
);
63 pkgRecords::Parser
&parser
= Recs
.Lookup(ver
.FileList());
64 const char *start
, *end
;
65 parser
.GetRec(start
,end
);
66 unsigned int const length
= end
- start
;
68 strncpy(buf
, start
, length
);
70 if (regexec(&Pattern
, buf
, 0, 0, 0) != 0)
77 if (pkgset
.empty() == true)
78 return helper
.canNotFindTask(Cache
, pattern
);
80 helper
.showTaskSelection(pkgset
, pattern
);
84 // FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
85 PackageSet
PackageSet::FromRegEx(pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
) {
86 static const char * const isregex
= ".?+*|[^$";
87 if (pattern
.find_first_of(isregex
) == std::string::npos
)
88 return PackageSet(REGEX
);
90 size_t archfound
= pattern
.find_last_of(':');
91 std::string arch
= "native";
92 if (archfound
!= std::string::npos
) {
93 arch
= pattern
.substr(archfound
+1);
94 if (arch
.find_first_of(isregex
) == std::string::npos
)
95 pattern
.erase(archfound
);
100 if (unlikely(Cache
.GetPkgCache() == 0))
101 return PackageSet(REGEX
);
103 APT::CacheFilter::PackageNameMatchesRegEx
regexfilter(pattern
);
105 PackageSet
pkgset(REGEX
);
106 for (pkgCache::GrpIterator Grp
= Cache
.GetPkgCache()->GrpBegin(); Grp
.end() == false; ++Grp
) {
107 if (regexfilter(Grp
) == false)
109 pkgCache::PkgIterator Pkg
= Grp
.FindPkg(arch
);
110 if (Pkg
.end() == true) {
111 if (archfound
== std::string::npos
) {
112 std::vector
<std::string
> archs
= APT::Configuration::getArchitectures();
113 for (std::vector
<std::string
>::const_iterator a
= archs
.begin();
114 a
!= archs
.end() && Pkg
.end() != true; ++a
)
115 Pkg
= Grp
.FindPkg(*a
);
117 if (Pkg
.end() == true)
124 if (pkgset
.empty() == true)
125 return helper
.canNotFindRegEx(Cache
, pattern
);
127 helper
.showRegExSelection(pkgset
, pattern
);
131 // FromName - Returns the package defined by this string /*{{{*/
132 pkgCache::PkgIterator
PackageSet::FromName(pkgCacheFile
&Cache
,
133 std::string
const &str
, CacheSetHelper
&helper
) {
134 std::string pkg
= str
;
135 size_t archfound
= pkg
.find_last_of(':');
137 if (archfound
!= std::string::npos
) {
138 arch
= pkg
.substr(archfound
+1);
139 pkg
.erase(archfound
);
142 if (Cache
.GetPkgCache() == 0)
143 return pkgCache::PkgIterator(Cache
, 0);
145 pkgCache::PkgIterator
Pkg(Cache
, 0);
146 if (arch
.empty() == true) {
147 pkgCache::GrpIterator Grp
= Cache
.GetPkgCache()->FindGrp(pkg
);
148 if (Grp
.end() == false)
149 Pkg
= Grp
.FindPreferredPkg();
151 Pkg
= Cache
.GetPkgCache()->FindPkg(pkg
, arch
);
153 if (Pkg
.end() == true)
154 return helper
.canNotFindPkgName(Cache
, str
);
158 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
159 std::map
<unsigned short, PackageSet
> PackageSet::GroupedFromCommandLine(
160 pkgCacheFile
&Cache
, const char **cmdline
,
161 std::list
<PackageSet::Modifier
> const &mods
,
162 unsigned short const &fallback
, CacheSetHelper
&helper
) {
163 std::map
<unsigned short, PackageSet
> pkgsets
;
164 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
165 unsigned short modID
= fallback
;
166 std::string str
= *I
;
167 bool modifierPresent
= false;
168 for (std::list
<PackageSet::Modifier
>::const_iterator mod
= mods
.begin();
169 mod
!= mods
.end(); ++mod
) {
170 size_t const alength
= strlen(mod
->Alias
);
172 case PackageSet::Modifier::POSTFIX
:
173 if (str
.compare(str
.length() - alength
, alength
,
174 mod
->Alias
, 0, alength
) != 0)
176 str
.erase(str
.length() - alength
);
179 case PackageSet::Modifier::PREFIX
:
181 case PackageSet::Modifier::NONE
:
184 modifierPresent
= true;
187 if (modifierPresent
== true) {
188 bool const errors
= helper
.showErrors(false);
189 pkgCache::PkgIterator Pkg
= FromName(Cache
, *I
, helper
);
190 helper
.showErrors(errors
);
191 if (Pkg
.end() == false) {
192 pkgsets
[fallback
].insert(Pkg
);
196 pkgsets
[modID
].insert(PackageSet::FromString(Cache
, str
, helper
));
201 // FromCommandLine - Return all packages specified on commandline /*{{{*/
202 PackageSet
PackageSet::FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
, CacheSetHelper
&helper
) {
204 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
205 PackageSet pset
= FromString(Cache
, *I
, helper
);
206 pkgset
.insert(pset
.begin(), pset
.end());
211 // FromString - Return all packages matching a specific string /*{{{*/
212 PackageSet
PackageSet::FromString(pkgCacheFile
&Cache
, std::string
const &str
, CacheSetHelper
&helper
) {
213 _error
->PushToStack();
216 pkgCache::PkgIterator Pkg
= FromName(Cache
, str
, helper
);
217 if (Pkg
.end() == false)
220 pkgset
= FromTask(Cache
, str
, helper
);
221 if (pkgset
.empty() == true) {
222 pkgset
= FromRegEx(Cache
, str
, helper
);
223 if (pkgset
.empty() == true)
224 pkgset
= helper
.canNotFindPackage(Cache
, str
);
228 if (pkgset
.empty() == false)
229 _error
->RevertToStack();
231 _error
->MergeWithStack();
235 // GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
236 std::map
<unsigned short, VersionSet
> VersionSet::GroupedFromCommandLine(
237 pkgCacheFile
&Cache
, const char **cmdline
,
238 std::list
<VersionSet::Modifier
> const &mods
,
239 unsigned short const &fallback
, CacheSetHelper
&helper
) {
240 std::map
<unsigned short, VersionSet
> versets
;
241 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
242 unsigned short modID
= fallback
;
243 VersionSet::Version select
= VersionSet::NEWEST
;
244 std::string str
= *I
;
245 bool modifierPresent
= false;
246 for (std::list
<VersionSet::Modifier
>::const_iterator mod
= mods
.begin();
247 mod
!= mods
.end(); ++mod
) {
248 if (modID
== fallback
&& mod
->ID
== fallback
)
249 select
= mod
->SelectVersion
;
250 size_t const alength
= strlen(mod
->Alias
);
252 case VersionSet::Modifier::POSTFIX
:
253 if (str
.compare(str
.length() - alength
, alength
,
254 mod
->Alias
, 0, alength
) != 0)
256 str
.erase(str
.length() - alength
);
258 select
= mod
->SelectVersion
;
260 case VersionSet::Modifier::PREFIX
:
262 case VersionSet::Modifier::NONE
:
265 modifierPresent
= true;
269 if (modifierPresent
== true) {
270 bool const errors
= helper
.showErrors(false);
271 VersionSet
const vset
= VersionSet::FromString(Cache
, std::string(*I
), select
, helper
, true);
272 helper
.showErrors(errors
);
273 if (vset
.empty() == false) {
274 versets
[fallback
].insert(vset
);
278 versets
[modID
].insert(VersionSet::FromString(Cache
, str
, select
, helper
));
283 // FromCommandLine - Return all versions specified on commandline /*{{{*/
284 APT::VersionSet
VersionSet::FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
,
285 APT::VersionSet::Version
const &fallback
, CacheSetHelper
&helper
) {
287 for (const char **I
= cmdline
; *I
!= 0; ++I
)
288 verset
.insert(VersionSet::FromString(Cache
, *I
, fallback
, helper
));
292 // FromString - Returns all versions spedcified by a string /*{{{*/
293 APT::VersionSet
VersionSet::FromString(pkgCacheFile
&Cache
, std::string pkg
,
294 APT::VersionSet::Version
const &fallback
, CacheSetHelper
&helper
,
295 bool const &onlyFromName
) {
297 bool verIsRel
= false;
298 size_t const vertag
= pkg
.find_last_of("/=");
299 if (vertag
!= string::npos
) {
300 ver
= pkg
.substr(vertag
+1);
301 verIsRel
= (pkg
[vertag
] == '/');
305 if (onlyFromName
== false)
306 pkgset
= PackageSet::FromString(Cache
, pkg
, helper
);
308 pkgset
.insert(PackageSet::FromName(Cache
, pkg
, helper
));
313 if (pkgset
.getConstructor() != PackageSet::UNKNOWN
)
314 errors
= helper
.showErrors(false);
315 for (PackageSet::const_iterator P
= pkgset
.begin();
316 P
!= pkgset
.end(); ++P
) {
317 if (vertag
== string::npos
) {
318 verset
.insert(VersionSet::FromPackage(Cache
, P
, fallback
, helper
));
321 pkgCache::VerIterator V
;
322 if (ver
== "installed")
323 V
= getInstalledVer(Cache
, P
, helper
);
324 else if (ver
== "candidate")
325 V
= getCandidateVer(Cache
, P
, helper
);
326 else if (ver
== "newest") {
327 if (P
->VersionList
!= 0)
330 V
= helper
.canNotFindNewestVer(Cache
, P
);
332 pkgVersionMatch
Match(ver
, (verIsRel
== true ? pkgVersionMatch::Release
:
333 pkgVersionMatch::Version
));
335 if (V
.end() == true) {
336 if (verIsRel
== true)
337 _error
->Error(_("Release '%s' for '%s' was not found"),
338 ver
.c_str(), P
.FullName(true).c_str());
340 _error
->Error(_("Version '%s' for '%s' was not found"),
341 ver
.c_str(), P
.FullName(true).c_str());
347 helper
.showSelectedVersion(P
, V
, ver
, verIsRel
);
350 if (pkgset
.getConstructor() != PackageSet::UNKNOWN
)
351 helper
.showErrors(errors
);
355 // FromPackage - versions from package based on fallback /*{{{*/
356 VersionSet
VersionSet::FromPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &P
,
357 VersionSet::Version
const &fallback
, CacheSetHelper
&helper
) {
359 pkgCache::VerIterator V
;
362 case VersionSet::ALL
:
363 if (P
->VersionList
!= 0)
364 for (V
= P
.VersionList(); V
.end() != true; ++V
)
367 verset
.insert(helper
.canNotFindAllVer(Cache
, P
));
369 case VersionSet::CANDANDINST
:
370 verset
.insert(getInstalledVer(Cache
, P
, helper
));
371 verset
.insert(getCandidateVer(Cache
, P
, helper
));
373 case VersionSet::CANDIDATE
:
374 verset
.insert(getCandidateVer(Cache
, P
, helper
));
376 case VersionSet::INSTALLED
:
377 verset
.insert(getInstalledVer(Cache
, P
, helper
));
379 case VersionSet::CANDINST
:
380 showErrors
= helper
.showErrors(false);
381 V
= getCandidateVer(Cache
, P
, helper
);
383 V
= getInstalledVer(Cache
, P
, helper
);
384 helper
.showErrors(showErrors
);
385 if (V
.end() == false)
388 verset
.insert(helper
.canNotFindInstCandVer(Cache
, P
));
390 case VersionSet::INSTCAND
:
391 showErrors
= helper
.showErrors(false);
392 V
= getInstalledVer(Cache
, P
, helper
);
394 V
= getCandidateVer(Cache
, P
, helper
);
395 helper
.showErrors(showErrors
);
396 if (V
.end() == false)
399 verset
.insert(helper
.canNotFindInstCandVer(Cache
, P
));
401 case VersionSet::NEWEST
:
402 if (P
->VersionList
!= 0)
403 verset
.insert(P
.VersionList());
405 verset
.insert(helper
.canNotFindNewestVer(Cache
, P
));
411 // getCandidateVer - Returns the candidate version of the given package /*{{{*/
412 pkgCache::VerIterator
VersionSet::getCandidateVer(pkgCacheFile
&Cache
,
413 pkgCache::PkgIterator
const &Pkg
, CacheSetHelper
&helper
) {
414 pkgCache::VerIterator Cand
;
415 if (Cache
.IsPolicyBuilt() == true || Cache
.IsDepCacheBuilt() == false)
417 if (unlikely(Cache
.GetPolicy() == 0))
418 return pkgCache::VerIterator(Cache
);
419 Cand
= Cache
.GetPolicy()->GetCandidateVer(Pkg
);
421 Cand
= Cache
[Pkg
].CandidateVerIter(Cache
);
423 if (Cand
.end() == true)
424 return helper
.canNotFindCandidateVer(Cache
, Pkg
);
428 // getInstalledVer - Returns the installed version of the given package /*{{{*/
429 pkgCache::VerIterator
VersionSet::getInstalledVer(pkgCacheFile
&Cache
,
430 pkgCache::PkgIterator
const &Pkg
, CacheSetHelper
&helper
) {
431 if (Pkg
->CurrentVer
== 0)
432 return helper
.canNotFindInstalledVer(Cache
, Pkg
);
433 return Pkg
.CurrentVer();
436 // canNotFindPkgName - handle the case no package has this name /*{{{*/
437 pkgCache::PkgIterator
CacheSetHelper::canNotFindPkgName(pkgCacheFile
&Cache
,
438 std::string
const &str
) {
439 if (ShowError
== true)
440 _error
->Error(_("Unable to locate package %s"), str
.c_str());
441 return pkgCache::PkgIterator(Cache
, 0);
444 // canNotFindTask - handle the case no package is found for a task /*{{{*/
445 PackageSet
CacheSetHelper::canNotFindTask(pkgCacheFile
&Cache
, std::string pattern
) {
446 if (ShowError
== true)
447 _error
->Error(_("Couldn't find task '%s'"), pattern
.c_str());
451 // canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
452 PackageSet
CacheSetHelper::canNotFindRegEx(pkgCacheFile
&Cache
, std::string pattern
) {
453 if (ShowError
== true)
454 _error
->Error(_("Couldn't find any package by regex '%s'"), pattern
.c_str());
458 // canNotFindPackage - handle the case no package is found from a string/*{{{*/
459 PackageSet
CacheSetHelper::canNotFindPackage(pkgCacheFile
&Cache
, std::string
const &str
) {
463 // canNotFindAllVer /*{{{*/
464 VersionSet
CacheSetHelper::canNotFindAllVer(pkgCacheFile
&Cache
,
465 pkgCache::PkgIterator
const &Pkg
) {
466 if (ShowError
== true)
467 _error
->Error(_("Can't select versions from package '%s' as it purely virtual"), Pkg
.FullName(true).c_str());
471 // canNotFindInstCandVer /*{{{*/
472 VersionSet
CacheSetHelper::canNotFindInstCandVer(pkgCacheFile
&Cache
,
473 pkgCache::PkgIterator
const &Pkg
) {
474 if (ShowError
== true)
475 _error
->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg
.FullName(true).c_str());
479 // canNotFindInstCandVer /*{{{*/
480 VersionSet
CacheSetHelper::canNotFindCandInstVer(pkgCacheFile
&Cache
,
481 pkgCache::PkgIterator
const &Pkg
) {
482 if (ShowError
== true)
483 _error
->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg
.FullName(true).c_str());
487 // canNotFindNewestVer /*{{{*/
488 pkgCache::VerIterator
CacheSetHelper::canNotFindNewestVer(pkgCacheFile
&Cache
,
489 pkgCache::PkgIterator
const &Pkg
) {
490 if (ShowError
== true)
491 _error
->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg
.FullName(true).c_str());
492 return pkgCache::VerIterator(Cache
, 0);
495 // canNotFindCandidateVer /*{{{*/
496 pkgCache::VerIterator
CacheSetHelper::canNotFindCandidateVer(pkgCacheFile
&Cache
,
497 pkgCache::PkgIterator
const &Pkg
) {
498 if (ShowError
== true)
499 _error
->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg
.FullName(true).c_str());
500 return pkgCache::VerIterator(Cache
, 0);
503 // canNotFindInstalledVer /*{{{*/
504 pkgCache::VerIterator
CacheSetHelper::canNotFindInstalledVer(pkgCacheFile
&Cache
,
505 pkgCache::PkgIterator
const &Pkg
) {
506 if (ShowError
== true)
507 _error
->Error(_("Can't select installed version from package %s as it is not installed"), Pkg
.FullName(true).c_str());
508 return pkgCache::VerIterator(Cache
, 0);