1 // -*- mode: cpp; mode: fold -*-
4 Wrappers around std::set to have set::iterators which behave
5 similar to the Iterators of the cache structures.
7 Provides also a few helper methods which work with these sets */
10 #define APT_CACHESET_H
11 // Include Files /*{{{*/
23 #include <apt-pkg/error.h>
24 #include <apt-pkg/pkgcache.h>
25 #include <apt-pkg/cacheiterators.h>
27 #ifndef APT_8_CLEANER_HEADERS
28 #include <apt-pkg/cachefile.h>
30 #ifndef APT_10_CLEANER_HEADERS
38 class PackageContainerInterface
;
39 class VersionContainerInterface
;
41 class CacheSetHelper
{ /*{{{*/
42 /** \class APT::CacheSetHelper
43 Simple base class with a lot of virtual methods which can be overridden
44 to alter the behavior or the output of the CacheSets.
46 This helper is passed around by the static methods in the CacheSets and
47 used every time they hit an error condition or something could be
51 CacheSetHelper(bool const ShowError
= true,
52 GlobalError::MsgType ErrorType
= GlobalError::ERROR
) :
53 ShowError(ShowError
), ErrorType(ErrorType
) {}
54 virtual ~CacheSetHelper() {}
56 virtual void showTaskSelection(pkgCache::PkgIterator
const &pkg
, std::string
const &pattern
);
57 virtual void showRegExSelection(pkgCache::PkgIterator
const &pkg
, std::string
const &pattern
);
58 #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
59 virtual void showFnmatchSelection(pkgCache::PkgIterator
const &pkg
, std::string
const &pattern
);
61 virtual void showSelectedVersion(pkgCache::PkgIterator
const &Pkg
, pkgCache::VerIterator
const Ver
,
62 std::string
const &ver
, bool const verIsRel
);
64 virtual void canNotFindTask(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
);
65 virtual void canNotFindRegEx(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
);
66 #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13)
67 virtual void canNotFindFnmatch(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
);
69 virtual void canNotFindPackage(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string
const &str
);
71 virtual void canNotFindAllVer(VersionContainerInterface
* const vci
, pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &Pkg
);
72 virtual void canNotFindInstCandVer(VersionContainerInterface
* const vci
, pkgCacheFile
&Cache
,
73 pkgCache::PkgIterator
const &Pkg
);
74 virtual void canNotFindCandInstVer(VersionContainerInterface
* const vci
,
76 pkgCache::PkgIterator
const &Pkg
);
78 virtual pkgCache::PkgIterator
canNotFindPkgName(pkgCacheFile
&Cache
, std::string
const &str
);
79 virtual pkgCache::VerIterator
canNotFindNewestVer(pkgCacheFile
&Cache
,
80 pkgCache::PkgIterator
const &Pkg
);
81 virtual pkgCache::VerIterator
canNotFindCandidateVer(pkgCacheFile
&Cache
,
82 pkgCache::PkgIterator
const &Pkg
);
83 virtual pkgCache::VerIterator
canNotFindInstalledVer(pkgCacheFile
&Cache
,
84 pkgCache::PkgIterator
const &Pkg
);
86 bool showErrors() const { return ShowError
; }
87 bool showErrors(bool const newValue
) { if (ShowError
== newValue
) return ShowError
; else return ((ShowError
= newValue
) == false); }
88 GlobalError::MsgType
errorType() const { return ErrorType
; }
89 GlobalError::MsgType
errorType(GlobalError::MsgType
const &newValue
)
91 if (ErrorType
== newValue
) return ErrorType
;
93 GlobalError::MsgType
const &oldValue
= ErrorType
;
102 GlobalError::MsgType ErrorType
;
105 class PackageContainerInterface
{ /*{{{*/
106 /** \class PackageContainerInterface
108 * Interface ensuring that all operations can be executed on the yet to
109 * define concrete PackageContainer - access to all methods is possible,
110 * but in general the wrappers provided by the PackageContainer template
113 * This class mostly protects use from the need to write all implementation
114 * of the methods working on containers in the template */
116 class const_iterator
{ /*{{{*/
118 virtual pkgCache::PkgIterator
getPkg() const = 0;
119 operator pkgCache::PkgIterator(void) const { return getPkg(); }
121 inline const char *Name() const {return getPkg().Name(); }
122 inline std::string
FullName(bool const Pretty
) const { return getPkg().FullName(Pretty
); }
123 inline std::string
FullName() const { return getPkg().FullName(); }
124 APT_DEPRECATED
inline const char *Section() const {
126 #pragma GCC diagnostic push
127 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
129 return getPkg().Section();
131 #pragma GCC diagnostic pop
134 inline bool Purge() const {return getPkg().Purge(); }
135 inline const char *Arch() const {return getPkg().Arch(); }
136 inline pkgCache::GrpIterator
Group() const { return getPkg().Group(); }
137 inline pkgCache::VerIterator
VersionList() const { return getPkg().VersionList(); }
138 inline pkgCache::VerIterator
CurrentVer() const { return getPkg().CurrentVer(); }
139 inline pkgCache::DepIterator
RevDependsList() const { return getPkg().RevDependsList(); }
140 inline pkgCache::PrvIterator
ProvidesList() const { return getPkg().ProvidesList(); }
141 inline pkgCache::PkgIterator::OkState
State() const { return getPkg().State(); }
142 inline const char *CandVersion() const { return getPkg().CandVersion(); }
143 inline const char *CurVersion() const { return getPkg().CurVersion(); }
144 inline pkgCache
*Cache() const { return getPkg().Cache(); }
145 inline unsigned long Index() const {return getPkg().Index();}
146 // we have only valid iterators here
147 inline bool end() const { return false; }
149 inline pkgCache::Package
const * operator->() const {return &*getPkg();}
153 virtual bool insert(pkgCache::PkgIterator
const &P
) = 0;
154 virtual bool empty() const = 0;
155 virtual void clear() = 0;
157 enum Constructor
{ UNKNOWN
, REGEX
, TASK
, FNMATCH
};
158 virtual void setConstructor(Constructor
const &con
) = 0;
159 virtual Constructor
getConstructor() const = 0;
161 static bool FromTask(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
);
162 static bool FromRegEx(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
);
163 static pkgCache::PkgIterator
FromName(pkgCacheFile
&Cache
, std::string
const &pattern
, CacheSetHelper
&helper
);
164 static bool FromFnmatch(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
);
165 static bool FromGroup(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
);
166 static bool FromString(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, std::string
const &pattern
, CacheSetHelper
&helper
);
167 static bool FromCommandLine(PackageContainerInterface
* const pci
, pkgCacheFile
&Cache
, const char **cmdline
, CacheSetHelper
&helper
);
170 enum Position
{ NONE
, PREFIX
, POSTFIX
};
172 const char * const Alias
;
174 Modifier (unsigned short const &id
, const char * const alias
, Position
const &pos
) : ID(id
), Alias(alias
), Pos(pos
) {}
177 static bool FromModifierCommandLine(unsigned short &modID
, PackageContainerInterface
* const pci
,
178 pkgCacheFile
&Cache
, const char * cmdline
,
179 std::list
<Modifier
> const &mods
, CacheSetHelper
&helper
);
182 template<class Container
> class PackageContainer
: public PackageContainerInterface
{/*{{{*/
183 /** \class APT::PackageContainer
185 Simple wrapper around a container class like std::set to provide a similar
186 interface to a set of packages as to the complete set of all packages in the
190 /** \brief smell like a pkgCache::PkgIterator */
191 class const_iterator
: public PackageContainerInterface::const_iterator
,/*{{{*/
192 public std::iterator
<std::forward_iterator_tag
, typename
Container::const_iterator
> {
193 typename
Container::const_iterator _iter
;
195 const_iterator(typename
Container::const_iterator i
) : _iter(i
) {}
196 pkgCache::PkgIterator
getPkg(void) const { return *_iter
; }
197 inline pkgCache::PkgIterator
operator*(void) const { return *_iter
; }
198 operator typename
Container::const_iterator(void) const { return _iter
; }
199 inline const_iterator
& operator++() { ++_iter
; return *this; }
200 inline const_iterator
operator++(int) { const_iterator
tmp(*this); operator++(); return tmp
; }
201 inline bool operator!=(const_iterator
const &i
) const { return _iter
!= i
._iter
; }
202 inline bool operator==(const_iterator
const &i
) const { return _iter
== i
._iter
; }
203 friend std::ostream
& operator<<(std::ostream
& out
, const_iterator i
) { return operator<<(out
, *i
); }
205 class iterator
: public PackageContainerInterface::const_iterator
,
206 public std::iterator
<std::forward_iterator_tag
, typename
Container::iterator
> {
207 typename
Container::iterator _iter
;
209 iterator(typename
Container::iterator i
) : _iter(i
) {}
210 pkgCache::PkgIterator
getPkg(void) const { return *_iter
; }
211 inline pkgCache::PkgIterator
operator*(void) const { return *_iter
; }
212 operator typename
Container::iterator(void) const { return _iter
; }
213 operator typename PackageContainer
<Container
>::const_iterator() { return typename PackageContainer
<Container
>::const_iterator(_iter
); }
214 inline iterator
& operator++() { ++_iter
; return *this; }
215 inline iterator
operator++(int) { iterator
tmp(*this); operator++(); return tmp
; }
216 inline bool operator!=(iterator
const &i
) const { return _iter
!= i
._iter
; }
217 inline bool operator==(iterator
const &i
) const { return _iter
== i
._iter
; }
218 inline iterator
& operator=(iterator
const &i
) { _iter
= i
._iter
; return *this; }
219 inline iterator
& operator=(typename
Container::iterator
const &i
) { _iter
= i
; return *this; }
220 friend std::ostream
& operator<<(std::ostream
& out
, iterator i
) { return operator<<(out
, *i
); }
224 bool insert(pkgCache::PkgIterator
const &P
) { if (P
.end() == true) return false; _cont
.insert(P
); return true; }
225 template<class Cont
> void insert(PackageContainer
<Cont
> const &pkgcont
) { _cont
.insert((typename
Cont::const_iterator
)pkgcont
.begin(), (typename
Cont::const_iterator
)pkgcont
.end()); }
226 void insert(const_iterator begin
, const_iterator end
) { _cont
.insert(begin
, end
); }
228 bool empty() const { return _cont
.empty(); }
229 void clear() { return _cont
.clear(); }
230 //FIXME: on ABI break, replace the first with the second without bool
231 void erase(iterator position
) { _cont
.erase((typename
Container::iterator
)position
); }
232 iterator
& erase(iterator
&position
, bool) { return position
= _cont
.erase((typename
Container::iterator
)position
); }
233 size_t erase(const pkgCache::PkgIterator x
) { return _cont
.erase(x
); }
234 void erase(iterator first
, iterator last
) { _cont
.erase(first
, last
); }
235 size_t size() const { return _cont
.size(); }
237 const_iterator
begin() const { return const_iterator(_cont
.begin()); }
238 const_iterator
end() const { return const_iterator(_cont
.end()); }
239 iterator
begin() { return iterator(_cont
.begin()); }
240 iterator
end() { return iterator(_cont
.end()); }
241 const_iterator
find(pkgCache::PkgIterator
const &P
) const { return const_iterator(_cont
.find(P
)); }
243 void setConstructor(Constructor
const &by
) { ConstructedBy
= by
; }
244 Constructor
getConstructor() const { return ConstructedBy
; }
246 PackageContainer() : ConstructedBy(UNKNOWN
) {}
247 PackageContainer(Constructor
const &by
) : ConstructedBy(by
) {}
249 /** \brief sort all included versions with given comparer
251 Some containers are sorted by default, some are not and can't be,
252 but a few like std::vector can be sorted if need be, so this can be
253 specialized in later on. The default is that this will fail though.
254 Specifically, already sorted containers like std::set will return
255 false as well as there is no easy way to check that the given comparer
256 would sort in the same way the set is currently sorted
258 \return \b true if the set was sorted, \b false if not. */
259 template<class Compare
> bool sort(Compare
/*Comp*/) { return false; }
261 /** \brief returns all packages in the cache who belong to the given task
263 A simple helper responsible for search for all members of a task
264 in the cache. Optional it prints a a notice about the
265 packages chosen cause of the given task.
266 \param Cache the packages are in
267 \param pattern name of the task
268 \param helper responsible for error and message handling */
269 static PackageContainer
FromTask(pkgCacheFile
&Cache
, std::string
const &pattern
, CacheSetHelper
&helper
) {
270 PackageContainer
cont(TASK
);
271 PackageContainerInterface::FromTask(&cont
, Cache
, pattern
, helper
);
274 static PackageContainer
FromTask(pkgCacheFile
&Cache
, std::string
const &pattern
) {
275 CacheSetHelper helper
;
276 return FromTask(Cache
, pattern
, helper
);
279 /** \brief returns all packages in the cache whose name matchs a given pattern
281 A simple helper responsible for executing a regular expression on all
282 package names in the cache. Optional it prints a a notice about the
283 packages chosen cause of the given package.
284 \param Cache the packages are in
285 \param pattern regular expression for package names
286 \param helper responsible for error and message handling */
287 static PackageContainer
FromRegEx(pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
) {
288 PackageContainer
cont(REGEX
);
289 PackageContainerInterface::FromRegEx(&cont
, Cache
, pattern
, helper
);
293 static PackageContainer
FromRegEx(pkgCacheFile
&Cache
, std::string
const &pattern
) {
294 CacheSetHelper helper
;
295 return FromRegEx(Cache
, pattern
, helper
);
298 static PackageContainer
FromFnmatch(pkgCacheFile
&Cache
, std::string pattern
, CacheSetHelper
&helper
) {
299 PackageContainer
cont(FNMATCH
);
300 PackageContainerInterface::FromFnmatch(&cont
, Cache
, pattern
, helper
);
303 static PackageContainer
FromFnMatch(pkgCacheFile
&Cache
, std::string
const &pattern
) {
304 CacheSetHelper helper
;
305 return FromFnmatch(Cache
, pattern
, helper
);
308 /** \brief returns a package specified by a string
310 \param Cache the package is in
311 \param pattern String the package name should be extracted from
312 \param helper responsible for error and message handling */
313 static pkgCache::PkgIterator
FromName(pkgCacheFile
&Cache
, std::string
const &pattern
, CacheSetHelper
&helper
) {
314 return PackageContainerInterface::FromName(Cache
, pattern
, helper
);
316 static pkgCache::PkgIterator
FromName(pkgCacheFile
&Cache
, std::string
const &pattern
) {
317 CacheSetHelper helper
;
318 return PackageContainerInterface::FromName(Cache
, pattern
, helper
);
321 /** \brief returns all packages specified by a string
323 \param Cache the packages are in
324 \param pattern String the package name(s) should be extracted from
325 \param helper responsible for error and message handling */
326 static PackageContainer
FromString(pkgCacheFile
&Cache
, std::string
const &pattern
, CacheSetHelper
&helper
) {
327 PackageContainer cont
;
328 PackageContainerInterface::FromString(&cont
, Cache
, pattern
, helper
);
331 static PackageContainer
FromString(pkgCacheFile
&Cache
, std::string
const &pattern
) {
332 CacheSetHelper helper
;
333 return FromString(Cache
, pattern
, helper
);
336 /** \brief returns all packages specified on the commandline
338 Get all package names from the commandline and executes regex's if needed.
339 No special package command is supported, just plain names.
340 \param Cache the packages are in
341 \param cmdline Command line the package names should be extracted from
342 \param helper responsible for error and message handling */
343 static PackageContainer
FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
, CacheSetHelper
&helper
) {
344 PackageContainer cont
;
345 PackageContainerInterface::FromCommandLine(&cont
, Cache
, cmdline
, helper
);
348 static PackageContainer
FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
) {
349 CacheSetHelper helper
;
350 return FromCommandLine(Cache
, cmdline
, helper
);
353 /** \brief group packages by a action modifiers
355 At some point it is needed to get from the same commandline
356 different package sets grouped by a modifier. Take
357 apt-get install apt awesome-
359 \param Cache the packages are in
360 \param cmdline Command line the package names should be extracted from
361 \param mods list of modifiers the method should accept
362 \param fallback the default modifier group for a package
363 \param helper responsible for error and message handling */
364 static std::map
<unsigned short, PackageContainer
> GroupedFromCommandLine(
366 const char **cmdline
,
367 std::list
<Modifier
> const &mods
,
368 unsigned short const &fallback
,
369 CacheSetHelper
&helper
) {
370 std::map
<unsigned short, PackageContainer
> pkgsets
;
371 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
372 unsigned short modID
= fallback
;
373 PackageContainer pkgset
;
374 PackageContainerInterface::FromModifierCommandLine(modID
, &pkgset
, Cache
, *I
, mods
, helper
);
375 pkgsets
[modID
].insert(pkgset
);
379 static std::map
<unsigned short, PackageContainer
> GroupedFromCommandLine(
381 const char **cmdline
,
382 std::list
<Modifier
> const &mods
,
383 unsigned short const &fallback
) {
384 CacheSetHelper helper
;
385 return GroupedFromCommandLine(Cache
, cmdline
,
386 mods
, fallback
, helper
);
390 Constructor ConstructedBy
;
393 // specialisations for push_back containers: std::list & std::vector /*{{{*/
394 template<> template<class Cont
> void PackageContainer
<std::list
<pkgCache::PkgIterator
> >::insert(PackageContainer
<Cont
> const &pkgcont
) {
395 for (typename PackageContainer
<Cont
>::const_iterator p
= pkgcont
.begin(); p
!= pkgcont
.end(); ++p
)
398 template<> template<class Cont
> void PackageContainer
<std::vector
<pkgCache::PkgIterator
> >::insert(PackageContainer
<Cont
> const &pkgcont
) {
399 for (typename PackageContainer
<Cont
>::const_iterator p
= pkgcont
.begin(); p
!= pkgcont
.end(); ++p
)
402 // these two are 'inline' as otherwise the linker has problems with seeing these untemplated
403 // specializations again and again - but we need to see them, so that library users can use them
404 template<> inline bool PackageContainer
<std::list
<pkgCache::PkgIterator
> >::insert(pkgCache::PkgIterator
const &P
) {
410 template<> inline bool PackageContainer
<std::vector
<pkgCache::PkgIterator
> >::insert(pkgCache::PkgIterator
const &P
) {
416 template<> inline void PackageContainer
<std::list
<pkgCache::PkgIterator
> >::insert(const_iterator begin
, const_iterator end
) {
417 for (const_iterator p
= begin
; p
!= end
; ++p
)
420 template<> inline void PackageContainer
<std::vector
<pkgCache::PkgIterator
> >::insert(const_iterator begin
, const_iterator end
) {
421 for (const_iterator p
= begin
; p
!= end
; ++p
)
426 template<> template<class Compare
> inline bool PackageContainer
<std::vector
<pkgCache::PkgIterator
> >::sort(Compare Comp
) {
427 std::sort(_cont
.begin(), _cont
.end(), Comp
);
431 // class PackageUniverse - pkgCache as PackageContainerInterface /*{{{*/
432 /** \class PackageUniverse
434 Wraps around our usual pkgCache, so that it can be stuffed into methods
435 expecting a PackageContainer.
437 The wrapping is read-only in practice modeled by making erase and co
439 class PackageUniverse
: public PackageContainerInterface
{
440 pkgCache
* const _cont
;
442 typedef pkgCache::PkgIterator iterator
;
443 typedef pkgCache::PkgIterator const_iterator
;
445 bool empty() const { return false; }
446 size_t size() const { return _cont
->Head().PackageCount
; }
448 const_iterator
begin() const { return _cont
->PkgBegin(); }
449 const_iterator
end() const { return _cont
->PkgEnd(); }
450 iterator
begin() { return _cont
->PkgBegin(); }
451 iterator
end() { return _cont
->PkgEnd(); }
453 PackageUniverse(pkgCache
* const Owner
) : _cont(Owner
) { }
456 bool insert(pkgCache::PkgIterator
const &) { return true; }
457 template<class Cont
> void insert(PackageContainer
<Cont
> const &) { }
458 void insert(const_iterator
, const_iterator
) { }
461 iterator
& erase(iterator
&iter
) { return iter
; }
462 size_t erase(const pkgCache::PkgIterator
) { return 0; }
463 void erase(iterator
, iterator
) { }
465 void setConstructor(Constructor
const &) { }
466 Constructor
getConstructor() const { return UNKNOWN
; }
469 typedef PackageContainer
<std::set
<pkgCache::PkgIterator
> > PackageSet
;
470 typedef PackageContainer
<std::list
<pkgCache::PkgIterator
> > PackageList
;
471 typedef PackageContainer
<std::vector
<pkgCache::PkgIterator
> > PackageVector
;
473 class VersionContainerInterface
{ /*{{{*/
474 /** \class APT::VersionContainerInterface
476 Same as APT::PackageContainerInterface, just for Versions */
478 /** \brief smell like a pkgCache::VerIterator */
479 class const_iterator
{ /*{{{*/
481 virtual pkgCache::VerIterator
getVer() const = 0;
482 operator pkgCache::VerIterator(void) { return getVer(); }
484 inline pkgCache
*Cache() const { return getVer().Cache(); }
485 inline unsigned long Index() const {return getVer().Index();}
486 inline int CompareVer(const pkgCache::VerIterator
&B
) const { return getVer().CompareVer(B
); }
487 inline const char *VerStr() const { return getVer().VerStr(); }
488 inline const char *Section() const { return getVer().Section(); }
489 inline const char *Arch() const { return getVer().Arch(); }
490 inline pkgCache::PkgIterator
ParentPkg() const { return getVer().ParentPkg(); }
491 inline pkgCache::DescIterator
DescriptionList() const { return getVer().DescriptionList(); }
492 inline pkgCache::DescIterator
TranslatedDescription() const { return getVer().TranslatedDescription(); }
493 inline pkgCache::DepIterator
DependsList() const { return getVer().DependsList(); }
494 inline pkgCache::PrvIterator
ProvidesList() const { return getVer().ProvidesList(); }
495 inline pkgCache::VerFileIterator
FileList() const { return getVer().FileList(); }
496 inline bool Downloadable() const { return getVer().Downloadable(); }
497 inline const char *PriorityType() const { return getVer().PriorityType(); }
498 inline std::string
RelStr() const { return getVer().RelStr(); }
499 inline bool Automatic() const { return getVer().Automatic(); }
500 inline pkgCache::VerFileIterator
NewestFile() const { return getVer().NewestFile(); }
501 // we have only valid iterators here
502 inline bool end() const { return false; }
504 inline pkgCache::Version
const * operator->() const { return &*getVer(); }
508 virtual bool insert(pkgCache::VerIterator
const &V
) = 0;
509 virtual bool empty() const = 0;
510 virtual void clear() = 0;
512 /** \brief specifies which version(s) will be returned if non is given */
516 /** Candidate and installed version */
518 /** Candidate version */
520 /** Installed version */
522 /** Candidate or if non installed version */
524 /** Installed or if non candidate version */
526 /** Newest version */
531 enum Position
{ NONE
, PREFIX
, POSTFIX
};
533 const char * const Alias
;
535 Version SelectVersion
;
536 Modifier (unsigned short const &id
, const char * const alias
, Position
const &pos
,
537 Version
const &select
) : ID(id
), Alias(alias
), Pos(pos
),
538 SelectVersion(select
) {}
541 static bool FromCommandLine(VersionContainerInterface
* const vci
, pkgCacheFile
&Cache
,
542 const char **cmdline
, Version
const &fallback
,
543 CacheSetHelper
&helper
);
545 static bool FromString(VersionContainerInterface
* const vci
, pkgCacheFile
&Cache
,
546 std::string pkg
, Version
const &fallback
, CacheSetHelper
&helper
,
547 bool const onlyFromName
= false);
549 static bool FromPackage(VersionContainerInterface
* const vci
, pkgCacheFile
&Cache
,
550 pkgCache::PkgIterator
const &P
, Version
const &fallback
,
551 CacheSetHelper
&helper
);
553 static bool FromModifierCommandLine(unsigned short &modID
,
554 VersionContainerInterface
* const vci
,
555 pkgCacheFile
&Cache
, const char * cmdline
,
556 std::list
<Modifier
> const &mods
,
557 CacheSetHelper
&helper
);
560 static bool FromDependency(VersionContainerInterface
* const vci
,
562 pkgCache::DepIterator
const &D
,
563 Version
const &selector
,
564 CacheSetHelper
&helper
);
568 /** \brief returns the candidate version of the package
570 \param Cache to be used to query for information
571 \param Pkg we want the candidate version from this package
572 \param helper used in this container instance */
573 static pkgCache::VerIterator
getCandidateVer(pkgCacheFile
&Cache
,
574 pkgCache::PkgIterator
const &Pkg
, CacheSetHelper
&helper
);
576 /** \brief returns the installed version of the package
578 \param Cache to be used to query for information
579 \param Pkg we want the installed version from this package
580 \param helper used in this container instance */
581 static pkgCache::VerIterator
getInstalledVer(pkgCacheFile
&Cache
,
582 pkgCache::PkgIterator
const &Pkg
, CacheSetHelper
&helper
);
586 template<class Container
> class VersionContainer
: public VersionContainerInterface
{/*{{{*/
587 /** \class APT::VersionContainer
589 Simple wrapper around a container class like std::set to provide a similar
590 interface to a set of versions as to the complete set of all versions in the
594 /** \brief smell like a pkgCache::VerIterator */
595 class const_iterator
: public VersionContainerInterface::const_iterator
,
596 public std::iterator
<std::forward_iterator_tag
, typename
Container::const_iterator
> {/*{{{*/
597 typename
Container::const_iterator _iter
;
599 const_iterator(typename
Container::const_iterator i
) : _iter(i
) {}
600 pkgCache::VerIterator
getVer(void) const { return *_iter
; }
601 inline pkgCache::VerIterator
operator*(void) const { return *_iter
; }
602 operator typename
Container::const_iterator(void) const { return _iter
; }
603 inline const_iterator
& operator++() { ++_iter
; return *this; }
604 inline const_iterator
operator++(int) { const_iterator
tmp(*this); operator++(); return tmp
; }
605 inline bool operator!=(const_iterator
const &i
) const { return _iter
!= i
._iter
; }
606 inline bool operator==(const_iterator
const &i
) const { return _iter
== i
._iter
; }
607 friend std::ostream
& operator<<(std::ostream
& out
, const_iterator i
) { return operator<<(out
, *i
); }
609 class iterator
: public VersionContainerInterface::const_iterator
,
610 public std::iterator
<std::forward_iterator_tag
, typename
Container::iterator
> {
611 typename
Container::iterator _iter
;
613 iterator(typename
Container::iterator i
) : _iter(i
) {}
614 pkgCache::VerIterator
getVer(void) const { return *_iter
; }
615 inline pkgCache::VerIterator
operator*(void) const { return *_iter
; }
616 operator typename
Container::iterator(void) const { return _iter
; }
617 operator typename VersionContainer
<Container
>::const_iterator() { return typename VersionContainer
<Container
>::const_iterator(_iter
); }
618 inline iterator
& operator++() { ++_iter
; return *this; }
619 inline iterator
operator++(int) { iterator
tmp(*this); operator++(); return tmp
; }
620 inline bool operator!=(iterator
const &i
) const { return _iter
!= i
._iter
; }
621 inline bool operator==(iterator
const &i
) const { return _iter
== i
._iter
; }
622 inline iterator
& operator=(iterator
const &i
) { _iter
= i
._iter
; return *this; }
623 inline iterator
& operator=(typename
Container::iterator
const &i
) { _iter
= i
; return *this; }
624 friend std::ostream
& operator<<(std::ostream
& out
, iterator i
) { return operator<<(out
, *i
); }
628 bool insert(pkgCache::VerIterator
const &V
) { if (V
.end() == true) return false; _cont
.insert(V
); return true; }
629 template<class Cont
> void insert(VersionContainer
<Cont
> const &vercont
) { _cont
.insert((typename
Cont::const_iterator
)vercont
.begin(), (typename
Cont::const_iterator
)vercont
.end()); }
630 void insert(const_iterator begin
, const_iterator end
) { _cont
.insert(begin
, end
); }
631 bool empty() const { return _cont
.empty(); }
632 void clear() { return _cont
.clear(); }
633 //FIXME: on ABI break, replace the first with the second without bool
634 void erase(iterator position
) { _cont
.erase((typename
Container::iterator
)position
); }
635 iterator
& erase(iterator
&position
, bool) { return position
= _cont
.erase((typename
Container::iterator
)position
); }
636 size_t erase(const pkgCache::VerIterator x
) { return _cont
.erase(x
); }
637 void erase(iterator first
, iterator last
) { _cont
.erase(first
, last
); }
638 size_t size() const { return _cont
.size(); }
640 const_iterator
begin() const { return const_iterator(_cont
.begin()); }
641 const_iterator
end() const { return const_iterator(_cont
.end()); }
642 iterator
begin() { return iterator(_cont
.begin()); }
643 iterator
end() { return iterator(_cont
.end()); }
644 const_iterator
find(pkgCache::VerIterator
const &V
) const { return const_iterator(_cont
.find(V
)); }
646 /** \brief sort all included versions with given comparer
648 Some containers are sorted by default, some are not and can't be,
649 but a few like std::vector can be sorted if need be, so this can be
650 specialized in later on. The default is that this will fail though.
651 Specifically, already sorted containers like std::set will return
652 false as well as there is no easy way to check that the given comparer
653 would sort in the same way the set is currently sorted
655 \return \b true if the set was sorted, \b false if not. */
656 template<class Compare
> bool sort(Compare
/*Comp*/) { return false; }
658 /** \brief returns all versions specified on the commandline
660 Get all versions from the commandline, uses given default version if
661 non specifically requested and executes regex's if needed on names.
662 \param Cache the packages and versions are in
663 \param cmdline Command line the versions should be extracted from
664 \param fallback version specification
665 \param helper responsible for error and message handling */
666 static VersionContainer
FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
,
667 Version
const &fallback
, CacheSetHelper
&helper
) {
668 VersionContainer vercon
;
669 VersionContainerInterface::FromCommandLine(&vercon
, Cache
, cmdline
, fallback
, helper
);
672 static VersionContainer
FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
,
673 Version
const &fallback
) {
674 CacheSetHelper helper
;
675 return FromCommandLine(Cache
, cmdline
, fallback
, helper
);
677 static VersionContainer
FromCommandLine(pkgCacheFile
&Cache
, const char **cmdline
) {
678 return FromCommandLine(Cache
, cmdline
, CANDINST
);
681 static VersionContainer
FromString(pkgCacheFile
&Cache
, std::string
const &pkg
,
682 Version
const &fallback
, CacheSetHelper
&helper
,
683 bool const /*onlyFromName = false*/) {
684 VersionContainer vercon
;
685 VersionContainerInterface::FromString(&vercon
, Cache
, pkg
, fallback
, helper
);
688 static VersionContainer
FromString(pkgCacheFile
&Cache
, std::string pkg
,
689 Version
const &fallback
) {
690 CacheSetHelper helper
;
691 return FromString(Cache
, pkg
, fallback
, helper
);
693 static VersionContainer
FromString(pkgCacheFile
&Cache
, std::string pkg
) {
694 return FromString(Cache
, pkg
, CANDINST
);
697 /** \brief returns all versions specified for the package
699 \param Cache the package and versions are in
700 \param P the package in question
701 \param fallback the version(s) you want to get
702 \param helper the helper used for display and error handling */
703 static VersionContainer
FromPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &P
,
704 Version
const &fallback
, CacheSetHelper
&helper
) {
705 VersionContainer vercon
;
706 VersionContainerInterface::FromPackage(&vercon
, Cache
, P
, fallback
, helper
);
709 static VersionContainer
FromPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &P
,
710 Version
const &fallback
) {
711 CacheSetHelper helper
;
712 return FromPackage(Cache
, P
, fallback
, helper
);
714 static VersionContainer
FromPackage(pkgCacheFile
&Cache
, pkgCache::PkgIterator
const &P
) {
715 return FromPackage(Cache
, P
, CANDIDATE
);
718 static std::map
<unsigned short, VersionContainer
> GroupedFromCommandLine(
720 const char **cmdline
,
721 std::list
<Modifier
> const &mods
,
722 unsigned short const fallback
,
723 CacheSetHelper
&helper
) {
724 std::map
<unsigned short, VersionContainer
> versets
;
725 for (const char **I
= cmdline
; *I
!= 0; ++I
) {
726 unsigned short modID
= fallback
;
727 VersionContainer verset
;
728 VersionContainerInterface::FromModifierCommandLine(modID
, &verset
, Cache
, *I
, mods
, helper
);
729 versets
[modID
].insert(verset
);
734 static std::map
<unsigned short, VersionContainer
> GroupedFromCommandLine(
735 pkgCacheFile
&Cache
, const char **cmdline
,
736 std::list
<Modifier
> const &mods
,
737 unsigned short const fallback
) {
738 CacheSetHelper helper
;
739 return GroupedFromCommandLine(Cache
, cmdline
,
740 mods
, fallback
, helper
);
743 static VersionContainer
FromDependency(pkgCacheFile
&Cache
, pkgCache::DepIterator
const &D
,
744 Version
const &selector
, CacheSetHelper
&helper
) {
745 VersionContainer vercon
;
746 VersionContainerInterface::FromDependency(&vercon
, Cache
, D
, selector
, helper
);
749 static VersionContainer
FromDependency(pkgCacheFile
&Cache
, pkgCache::DepIterator
const &D
,
750 Version
const &selector
) {
751 CacheSetHelper helper
;
752 return FromPackage(Cache
, D
, selector
, helper
);
754 static VersionContainer
FromDependency(pkgCacheFile
&Cache
, pkgCache::DepIterator
const &D
) {
755 return FromPackage(Cache
, D
, CANDIDATE
);
759 // specialisations for push_back containers: std::list & std::vector /*{{{*/
760 template<> template<class Cont
> void VersionContainer
<std::list
<pkgCache::VerIterator
> >::insert(VersionContainer
<Cont
> const &vercont
) {
761 for (typename VersionContainer
<Cont
>::const_iterator v
= vercont
.begin(); v
!= vercont
.end(); ++v
)
764 template<> template<class Cont
> void VersionContainer
<std::vector
<pkgCache::VerIterator
> >::insert(VersionContainer
<Cont
> const &vercont
) {
765 for (typename VersionContainer
<Cont
>::const_iterator v
= vercont
.begin(); v
!= vercont
.end(); ++v
)
768 // these two are 'inline' as otherwise the linker has problems with seeing these untemplated
769 // specializations again and again - but we need to see them, so that library users can use them
770 template<> inline bool VersionContainer
<std::list
<pkgCache::VerIterator
> >::insert(pkgCache::VerIterator
const &V
) {
776 template<> inline bool VersionContainer
<std::vector
<pkgCache::VerIterator
> >::insert(pkgCache::VerIterator
const &V
) {
782 template<> inline void VersionContainer
<std::list
<pkgCache::VerIterator
> >::insert(const_iterator begin
, const_iterator end
) {
783 for (const_iterator v
= begin
; v
!= end
; ++v
)
786 template<> inline void VersionContainer
<std::vector
<pkgCache::VerIterator
> >::insert(const_iterator begin
, const_iterator end
) {
787 for (const_iterator v
= begin
; v
!= end
; ++v
)
792 template<> template<class Compare
> inline bool VersionContainer
<std::vector
<pkgCache::VerIterator
> >::sort(Compare Comp
) {
793 std::sort(_cont
.begin(), _cont
.end(), Comp
);
797 typedef VersionContainer
<std::set
<pkgCache::VerIterator
> > VersionSet
;
798 typedef VersionContainer
<std::list
<pkgCache::VerIterator
> > VersionList
;
799 typedef VersionContainer
<std::vector
<pkgCache::VerIterator
> > VersionVector
;