]> git.saurik.com Git - apt.git/blob - apt-pkg/cacheset.h
2656727d4db5bbe7a4b4787ae8be869b9911482c
[apt.git] / apt-pkg / cacheset.h
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /** \file cacheset.h
4 Wrappers around std::set to have set::iterators which behave
5 similar to the Iterators of the cache structures.
6
7 Provides also a few helper methods which work with these sets */
8 /*}}}*/
9 #ifndef APT_CACHESET_H
10 #define APT_CACHESET_H
11 // Include Files /*{{{*/
12 #include <fstream>
13 #include <map>
14 #include <set>
15 #include <list>
16 #include <vector>
17 #include <string>
18 #include <iterator>
19 #include <algorithm>
20
21 #include <stddef.h>
22
23 #include <apt-pkg/error.h>
24 #include <apt-pkg/pkgcache.h>
25 #include <apt-pkg/cacheiterators.h>
26
27 #ifndef APT_8_CLEANER_HEADERS
28 #include <apt-pkg/cachefile.h>
29 #endif
30 #ifndef APT_10_CLEANER_HEADERS
31 #include <iostream>
32 #endif
33 /*}}}*/
34
35 class pkgCacheFile;
36
37 namespace APT {
38 class PackageContainerInterface;
39 class VersionContainerInterface;
40
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.
45
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
48 printed out.
49 */
50 public: /*{{{*/
51 CacheSetHelper(bool const ShowError = true,
52 GlobalError::MsgType ErrorType = GlobalError::ERROR) :
53 ShowError(ShowError), ErrorType(ErrorType) {}
54 virtual ~CacheSetHelper() {}
55
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);
60 #endif
61 virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
62 std::string const &ver, bool const verIsRel);
63
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);
68 #endif
69 virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str);
70
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,
75 pkgCacheFile &Cache,
76 pkgCache::PkgIterator const &Pkg);
77
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);
85
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)
90 {
91 if (ErrorType == newValue) return ErrorType;
92 else {
93 GlobalError::MsgType const &oldValue = ErrorType;
94 ErrorType = newValue;
95 return oldValue;
96 }
97 }
98
99 /*}}}*/
100 protected:
101 bool ShowError;
102 GlobalError::MsgType ErrorType;
103 }; /*}}}*/
104
105 class PackageContainerInterface { /*{{{*/
106 /** \class PackageContainerInterface
107
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
111 * are nicer to use.
112
113 * This class mostly protects use from the need to write all implementation
114 * of the methods working on containers in the template */
115 public:
116 class const_iterator { /*{{{*/
117 public:
118 virtual pkgCache::PkgIterator getPkg() const = 0;
119 operator pkgCache::PkgIterator(void) const { return getPkg(); }
120
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 {
125 #if __GNUC__ >= 4
126 #pragma GCC diagnostic push
127 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
128 #endif
129 return getPkg().Section();
130 #if __GNUC__ >= 4
131 #pragma GCC diagnostic pop
132 #endif
133 }
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; }
148
149 inline pkgCache::Package const * operator->() const {return &*getPkg();}
150 };
151 /*}}}*/
152
153 virtual bool insert(pkgCache::PkgIterator const &P) = 0;
154 virtual bool empty() const = 0;
155 virtual void clear() = 0;
156
157 enum Constructor { UNKNOWN, REGEX, TASK, FNMATCH };
158 virtual void setConstructor(Constructor const &con) = 0;
159 virtual Constructor getConstructor() const = 0;
160
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);
168
169 struct Modifier {
170 enum Position { NONE, PREFIX, POSTFIX };
171 unsigned short ID;
172 const char * const Alias;
173 Position Pos;
174 Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {}
175 };
176
177 static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
178 pkgCacheFile &Cache, const char * cmdline,
179 std::list<Modifier> const &mods, CacheSetHelper &helper);
180 };
181 /*}}}*/
182 template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
183 /** \class APT::PackageContainer
184
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
187 pkgCache. */
188 Container _cont;
189 public: /*{{{*/
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;
194 public:
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); }
204 };
205 class iterator : public PackageContainerInterface::const_iterator,
206 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
207 typename Container::iterator _iter;
208 public:
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); }
221 };
222 /*}}}*/
223
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); }
227
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(); }
236
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)); }
242
243 void setConstructor(Constructor const &by) { ConstructedBy = by; }
244 Constructor getConstructor() const { return ConstructedBy; }
245
246 PackageContainer() : ConstructedBy(UNKNOWN) {}
247 PackageContainer(Constructor const &by) : ConstructedBy(by) {}
248
249 /** \brief sort all included versions with given comparer
250
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
257
258 \return \b true if the set was sorted, \b false if not. */
259 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
260
261 /** \brief returns all packages in the cache who belong to the given task
262
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);
272 return cont;
273 }
274 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) {
275 CacheSetHelper helper;
276 return FromTask(Cache, pattern, helper);
277 }
278
279 /** \brief returns all packages in the cache whose name matchs a given pattern
280
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);
290 return cont;
291 }
292
293 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
294 CacheSetHelper helper;
295 return FromRegEx(Cache, pattern, helper);
296 }
297
298 static PackageContainer FromFnmatch(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
299 PackageContainer cont(FNMATCH);
300 PackageContainerInterface::FromFnmatch(&cont, Cache, pattern, helper);
301 return cont;
302 }
303 static PackageContainer FromFnMatch(pkgCacheFile &Cache, std::string const &pattern) {
304 CacheSetHelper helper;
305 return FromFnmatch(Cache, pattern, helper);
306 }
307
308 /** \brief returns a package specified by a string
309
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);
315 }
316 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) {
317 CacheSetHelper helper;
318 return PackageContainerInterface::FromName(Cache, pattern, helper);
319 }
320
321 /** \brief returns all packages specified by a string
322
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);
329 return cont;
330 }
331 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) {
332 CacheSetHelper helper;
333 return FromString(Cache, pattern, helper);
334 }
335
336 /** \brief returns all packages specified on the commandline
337
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);
346 return cont;
347 }
348 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
349 CacheSetHelper helper;
350 return FromCommandLine(Cache, cmdline, helper);
351 }
352
353 /** \brief group packages by a action modifiers
354
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-
358 as an example.
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(
365 pkgCacheFile &Cache,
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);
376 }
377 return pkgsets;
378 }
379 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
380 pkgCacheFile &Cache,
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);
387 }
388 /*}}}*/
389 private: /*{{{*/
390 Constructor ConstructedBy;
391 /*}}}*/
392 }; /*}}}*/
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)
396 _cont.push_back(*p);
397 }
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)
400 _cont.push_back(*p);
401 }
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) {
405 if (P.end() == true)
406 return false;
407 _cont.push_back(P);
408 return true;
409 }
410 template<> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
411 if (P.end() == true)
412 return false;
413 _cont.push_back(P);
414 return true;
415 }
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)
418 _cont.push_back(*p);
419 }
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)
422 _cont.push_back(*p);
423 }
424 /*}}}*/
425
426 template<> template<class Compare> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::sort(Compare Comp) {
427 std::sort(_cont.begin(), _cont.end(), Comp);
428 return true;
429 }
430
431 // class PackageUniverse - pkgCache as PackageContainerInterface /*{{{*/
432 /** \class PackageUniverse
433
434 Wraps around our usual pkgCache, so that it can be stuffed into methods
435 expecting a PackageContainer.
436
437 The wrapping is read-only in practice modeled by making erase and co
438 private methods. */
439 class PackageUniverse : public PackageContainerInterface {
440 pkgCache * const _cont;
441 public:
442 typedef pkgCache::PkgIterator iterator;
443 typedef pkgCache::PkgIterator const_iterator;
444
445 bool empty() const { return false; }
446 size_t size() const { return _cont->Head().PackageCount; }
447
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(); }
452
453 PackageUniverse(pkgCache * const Owner) : _cont(Owner) { }
454
455 private:
456 bool insert(pkgCache::PkgIterator const &) { return true; }
457 template<class Cont> void insert(PackageContainer<Cont> const &) { }
458 void insert(const_iterator, const_iterator) { }
459
460 void clear() { }
461 iterator& erase(iterator &iter) { return iter; }
462 size_t erase(const pkgCache::PkgIterator) { return 0; }
463 void erase(iterator, iterator) { }
464
465 void setConstructor(Constructor const &) { }
466 Constructor getConstructor() const { return UNKNOWN; }
467 };
468 /*}}}*/
469 typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
470 typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
471 typedef PackageContainer<std::vector<pkgCache::PkgIterator> > PackageVector;
472
473 class VersionContainerInterface { /*{{{*/
474 /** \class APT::VersionContainerInterface
475
476 Same as APT::PackageContainerInterface, just for Versions */
477 public:
478 /** \brief smell like a pkgCache::VerIterator */
479 class const_iterator { /*{{{*/
480 public:
481 virtual pkgCache::VerIterator getVer() const = 0;
482 operator pkgCache::VerIterator(void) { return getVer(); }
483
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; }
503
504 inline pkgCache::Version const * operator->() const { return &*getVer(); }
505 };
506 /*}}}*/
507
508 virtual bool insert(pkgCache::VerIterator const &V) = 0;
509 virtual bool empty() const = 0;
510 virtual void clear() = 0;
511
512 /** \brief specifies which version(s) will be returned if non is given */
513 enum Version {
514 /** All versions */
515 ALL,
516 /** Candidate and installed version */
517 CANDANDINST,
518 /** Candidate version */
519 CANDIDATE,
520 /** Installed version */
521 INSTALLED,
522 /** Candidate or if non installed version */
523 CANDINST,
524 /** Installed or if non candidate version */
525 INSTCAND,
526 /** Newest version */
527 NEWEST
528 };
529
530 struct Modifier {
531 enum Position { NONE, PREFIX, POSTFIX };
532 unsigned short ID;
533 const char * const Alias;
534 Position Pos;
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) {}
539 };
540
541 static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
542 const char **cmdline, Version const &fallback,
543 CacheSetHelper &helper);
544
545 static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
546 std::string pkg, Version const &fallback, CacheSetHelper &helper,
547 bool const onlyFromName = false);
548
549 static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
550 pkgCache::PkgIterator const &P, Version const &fallback,
551 CacheSetHelper &helper);
552
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);
558
559
560 static bool FromDependency(VersionContainerInterface * const vci,
561 pkgCacheFile &Cache,
562 pkgCache::DepIterator const &D,
563 Version const &selector,
564 CacheSetHelper &helper);
565
566 protected: /*{{{*/
567
568 /** \brief returns the candidate version of the package
569
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);
575
576 /** \brief returns the installed version of the package
577
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);
583 /*}}}*/
584 };
585 /*}}}*/
586 template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
587 /** \class APT::VersionContainer
588
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
591 pkgCache. */
592 Container _cont;
593 public: /*{{{*/
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;
598 public:
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); }
608 };
609 class iterator : public VersionContainerInterface::const_iterator,
610 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
611 typename Container::iterator _iter;
612 public:
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); }
625 };
626 /*}}}*/
627
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(); }
639
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)); }
645
646 /** \brief sort all included versions with given comparer
647
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
654
655 \return \b true if the set was sorted, \b false if not. */
656 template<class Compare> bool sort(Compare /*Comp*/) { return false; }
657
658 /** \brief returns all versions specified on the commandline
659
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);
670 return vercon;
671 }
672 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
673 Version const &fallback) {
674 CacheSetHelper helper;
675 return FromCommandLine(Cache, cmdline, fallback, helper);
676 }
677 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
678 return FromCommandLine(Cache, cmdline, CANDINST);
679 }
680
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);
686 return vercon;
687 }
688 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
689 Version const &fallback) {
690 CacheSetHelper helper;
691 return FromString(Cache, pkg, fallback, helper);
692 }
693 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
694 return FromString(Cache, pkg, CANDINST);
695 }
696
697 /** \brief returns all versions specified for the package
698
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);
707 return vercon;
708 }
709 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
710 Version const &fallback) {
711 CacheSetHelper helper;
712 return FromPackage(Cache, P, fallback, helper);
713 }
714 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
715 return FromPackage(Cache, P, CANDIDATE);
716 }
717
718 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
719 pkgCacheFile &Cache,
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);
730 }
731 return versets;
732
733 }
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);
741 }
742
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);
747 return vercon;
748 }
749 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
750 Version const &selector) {
751 CacheSetHelper helper;
752 return FromPackage(Cache, D, selector, helper);
753 }
754 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
755 return FromPackage(Cache, D, CANDIDATE);
756 }
757 /*}}}*/
758 }; /*}}}*/
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)
762 _cont.push_back(*v);
763 }
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)
766 _cont.push_back(*v);
767 }
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) {
771 if (V.end() == true)
772 return false;
773 _cont.push_back(V);
774 return true;
775 }
776 template<> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
777 if (V.end() == true)
778 return false;
779 _cont.push_back(V);
780 return true;
781 }
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)
784 _cont.push_back(*v);
785 }
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)
788 _cont.push_back(*v);
789 }
790 /*}}}*/
791
792 template<> template<class Compare> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::sort(Compare Comp) {
793 std::sort(_cont.begin(), _cont.end(), Comp);
794 return true;
795 }
796
797 typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
798 typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
799 typedef VersionContainer<std::vector<pkgCache::VerIterator> > VersionVector;
800 }
801 #endif