]> git.saurik.com Git - apt.git/blame - apt-pkg/cacheset.h
Fix double free (closes: #711045)
[apt.git] / apt-pkg / cacheset.h
CommitLineData
e1dbde8d
DK
1// -*- mode: cpp; mode: fold -*-
2// Description /*{{{*/
7959c5ed
DK
3/** \file cacheset.h
4 Wrappers around std::set to have set::iterators which behave
5 similar to the Iterators of the cache structures.
e1dbde8d 6
7959c5ed 7 Provides also a few helper methods which work with these sets */
e1dbde8d 8 /*}}}*/
7959c5ed
DK
9#ifndef APT_CACHESET_H
10#define APT_CACHESET_H
e1dbde8d 11// Include Files /*{{{*/
ffee1c2b
DK
12#include <iostream>
13#include <fstream>
9cc83a6f
DK
14#include <list>
15#include <map>
ffee1c2b 16#include <set>
c4cca791 17#include <list>
e1dbde8d 18#include <string>
15fc8636 19#include <iterator>
ffee1c2b 20
472ff00e 21#include <apt-pkg/error.h>
e1dbde8d 22#include <apt-pkg/pkgcache.h>
b9dadc24
DK
23
24#ifndef APT_8_CLEANER_HEADERS
25#include <apt-pkg/cachefile.h>
26#endif
e1dbde8d 27 /*}}}*/
472ff00e
DK
28
29class pkgCacheFile;
30
e1dbde8d 31namespace APT {
15fc8636
DK
32class PackageContainerInterface;
33class VersionContainerInterface;
34
70e706ad
DK
35class CacheSetHelper { /*{{{*/
36/** \class APT::CacheSetHelper
37 Simple base class with a lot of virtual methods which can be overridden
38 to alter the behavior or the output of the CacheSets.
39
40 This helper is passed around by the static methods in the CacheSets and
41 used every time they hit an error condition or something could be
42 printed out.
43*/
44public: /*{{{*/
15fc8636 45 CacheSetHelper(bool const ShowError = true,
cd7bbc47
DK
46 GlobalError::MsgType ErrorType = GlobalError::ERROR) :
47 ShowError(ShowError), ErrorType(ErrorType) {};
70e706ad
DK
48 virtual ~CacheSetHelper() {};
49
15fc8636
DK
50 virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
51 virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern);
70e706ad 52 virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
15fc8636 53 std::string const &ver, bool const verIsRel);
70e706ad 54
15fc8636
DK
55 virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
56 virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern);
57 virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str);
58
59 virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
60 virtual void canNotFindInstCandVer(VersionContainerInterface * const vci, pkgCacheFile &Cache,
70e706ad 61 pkgCache::PkgIterator const &Pkg);
15fc8636
DK
62 virtual void canNotFindCandInstVer(VersionContainerInterface * const vci,
63 pkgCacheFile &Cache,
cf28bcad 64 pkgCache::PkgIterator const &Pkg);
15fc8636
DK
65
66 virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
70e706ad
DK
67 virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
68 pkgCache::PkgIterator const &Pkg);
69 virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
70 pkgCache::PkgIterator const &Pkg);
71 virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache,
72 pkgCache::PkgIterator const &Pkg);
73
74 bool showErrors() const { return ShowError; };
15fc8636 75 bool showErrors(bool const newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); };
cd7bbc47
DK
76 GlobalError::MsgType errorType() const { return ErrorType; };
77 GlobalError::MsgType errorType(GlobalError::MsgType const &newValue)
78 {
79 if (ErrorType == newValue) return ErrorType;
80 else {
81 GlobalError::MsgType const &oldValue = ErrorType;
82 ErrorType = newValue;
83 return oldValue;
84 }
85 };
86
70e706ad
DK
87 /*}}}*/
88protected:
89 bool ShowError;
cd7bbc47 90 GlobalError::MsgType ErrorType;
70e706ad 91}; /*}}}*/
15fc8636
DK
92class PackageContainerInterface { /*{{{*/
93/** \class PackageContainerInterface
94
95 * Interface ensuring that all operations can be executed on the yet to
96 * define concrete PackageContainer - access to all methods is possible,
97 * but in general the wrappers provided by the PackageContainer template
98 * are nicer to use.
99
100 * This class mostly protects use from the need to write all implementation
101 * of the methods working on containers in the template */
102public:
103 class const_iterator { /*{{{*/
e1dbde8d 104 public:
15fc8636
DK
105 virtual pkgCache::PkgIterator getPkg() const = 0;
106 operator pkgCache::PkgIterator(void) const { return getPkg(); }
107
108 inline const char *Name() const {return getPkg().Name(); }
109 inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); }
110 inline std::string FullName() const { return getPkg().FullName(); }
111 inline const char *Section() const {return getPkg().Section(); }
112 inline bool Purge() const {return getPkg().Purge(); }
113 inline const char *Arch() const {return getPkg().Arch(); }
114 inline pkgCache::GrpIterator Group() const { return getPkg().Group(); }
115 inline pkgCache::VerIterator VersionList() const { return getPkg().VersionList(); }
116 inline pkgCache::VerIterator CurrentVer() const { return getPkg().CurrentVer(); }
117 inline pkgCache::DepIterator RevDependsList() const { return getPkg().RevDependsList(); }
118 inline pkgCache::PrvIterator ProvidesList() const { return getPkg().ProvidesList(); }
119 inline pkgCache::PkgIterator::OkState State() const { return getPkg().State(); }
120 inline const char *CandVersion() const { return getPkg().CandVersion(); }
121 inline const char *CurVersion() const { return getPkg().CurVersion(); }
122 inline pkgCache *Cache() const { return getPkg().Cache(); };
123 inline unsigned long Index() const {return getPkg().Index();};
78c32596
DK
124 // we have only valid iterators here
125 inline bool end() const { return false; };
e1dbde8d 126
15fc8636
DK
127 inline pkgCache::Package const * operator->() const {return &*getPkg();};
128 };
129 /*}}}*/
130
131 virtual bool insert(pkgCache::PkgIterator const &P) = 0;
132 virtual bool empty() const = 0;
133 virtual void clear() = 0;
134
135 enum Constructor { UNKNOWN, REGEX, TASK };
136 virtual void setConstructor(Constructor const &con) = 0;
137 virtual Constructor getConstructor() const = 0;
138
139 static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
140 static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
141 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
2f0d4029 142 static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
15fc8636
DK
143 static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
144 static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
145
146 struct Modifier {
147 enum Position { NONE, PREFIX, POSTFIX };
148 unsigned short ID;
149 const char * const Alias;
150 Position Pos;
151 Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {};
152 };
153
154 static bool FromModifierCommandLine(unsigned short &modID, PackageContainerInterface * const pci,
155 pkgCacheFile &Cache, const char * cmdline,
156 std::list<Modifier> const &mods, CacheSetHelper &helper);
157};
158 /*}}}*/
159template<class Container> class PackageContainer : public PackageContainerInterface {/*{{{*/
160/** \class APT::PackageContainer
e1dbde8d 161
15fc8636
DK
162 Simple wrapper around a container class like std::set to provide a similar
163 interface to a set of packages as to the complete set of all packages in the
164 pkgCache. */
165 Container _cont;
166public: /*{{{*/
167 /** \brief smell like a pkgCache::PkgIterator */
c4cca791
DK
168 class const_iterator : public PackageContainerInterface::const_iterator,/*{{{*/
169 public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {
15fc8636
DK
170 typename Container::const_iterator _iter;
171 public:
172 const_iterator(typename Container::const_iterator i) : _iter(i) {}
173 pkgCache::PkgIterator getPkg(void) const { return *_iter; }
174 inline pkgCache::PkgIterator operator*(void) const { return *_iter; };
175 operator typename Container::const_iterator(void) const { return _iter; }
63b70b21
DK
176 inline const_iterator& operator++() { ++_iter; return *this; }
177 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
15fc8636
DK
178 inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; };
179 inline bool operator==(const_iterator const &i) const { return _iter == i._iter; };
180 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
e1dbde8d 181 };
c4cca791
DK
182 class iterator : public PackageContainerInterface::const_iterator,
183 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
184 typename Container::iterator _iter;
185 public:
186 iterator(typename Container::iterator i) : _iter(i) {}
187 pkgCache::PkgIterator getPkg(void) const { return *_iter; }
188 inline pkgCache::PkgIterator operator*(void) const { return *_iter; };
189 operator typename Container::iterator(void) const { return _iter; }
bce0e0ff 190 operator typename PackageContainer<Container>::const_iterator() { return typename PackageContainer<Container>::const_iterator(_iter); }
63b70b21
DK
191 inline iterator& operator++() { ++_iter; return *this; }
192 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
c4cca791
DK
193 inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
194 inline bool operator==(iterator const &i) const { return _iter == i._iter; };
5eb9a474
DK
195 inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
196 inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
c4cca791
DK
197 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
198 };
dc0f01f7 199 /*}}}*/
ffee1c2b 200
15fc8636
DK
201 bool insert(pkgCache::PkgIterator const &P) { if (P.end() == true) return false; _cont.insert(P); return true; };
202 template<class Cont> void insert(PackageContainer<Cont> const &pkgcont) { _cont.insert((typename Cont::const_iterator)pkgcont.begin(), (typename Cont::const_iterator)pkgcont.end()); };
203 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); };
c4cca791 204
15fc8636
DK
205 bool empty() const { return _cont.empty(); };
206 void clear() { return _cont.clear(); };
5eb9a474 207 //FIXME: on ABI break, replace the first with the second without bool
c4cca791 208 void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
5eb9a474 209 iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
15fc8636
DK
210 size_t erase(const pkgCache::PkgIterator x) { return _cont.erase(x); };
211 void erase(iterator first, iterator last) { _cont.erase(first, last); };
212 size_t size() const { return _cont.size(); };
213
214 const_iterator begin() const { return const_iterator(_cont.begin()); };
215 const_iterator end() const { return const_iterator(_cont.end()); };
c4cca791
DK
216 iterator begin() { return iterator(_cont.begin()); };
217 iterator end() { return iterator(_cont.end()); };
15fc8636
DK
218 const_iterator find(pkgCache::PkgIterator const &P) const { return const_iterator(_cont.find(P)); };
219
220 void setConstructor(Constructor const &by) { ConstructedBy = by; };
221 Constructor getConstructor() const { return ConstructedBy; };
222
223 PackageContainer() : ConstructedBy(UNKNOWN) {};
224 PackageContainer(Constructor const &by) : ConstructedBy(by) {};
c45f2d19 225
dc0f01f7
DK
226 /** \brief returns all packages in the cache who belong to the given task
227
228 A simple helper responsible for search for all members of a task
229 in the cache. Optional it prints a a notice about the
230 packages chosen cause of the given task.
231 \param Cache the packages are in
232 \param pattern name of the task
c8db3fff 233 \param helper responsible for error and message handling */
15fc8636
DK
234 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
235 PackageContainer cont(TASK);
236 PackageContainerInterface::FromTask(&cont, Cache, pattern, helper);
237 return cont;
238 }
239 static PackageContainer FromTask(pkgCacheFile &Cache, std::string const &pattern) {
70e706ad 240 CacheSetHelper helper;
446bbcf4 241 return FromTask(Cache, pattern, helper);
dc0f01f7
DK
242 }
243
ffee1c2b
DK
244 /** \brief returns all packages in the cache whose name matchs a given pattern
245
246 A simple helper responsible for executing a regular expression on all
247 package names in the cache. Optional it prints a a notice about the
248 packages chosen cause of the given package.
249 \param Cache the packages are in
250 \param pattern regular expression for package names
c8db3fff 251 \param helper responsible for error and message handling */
15fc8636
DK
252 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
253 PackageContainer cont(REGEX);
254 PackageContainerInterface::FromRegEx(&cont, Cache, pattern, helper);
255 return cont;
256 }
257
258 static PackageContainer FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
70e706ad 259 CacheSetHelper helper;
446bbcf4 260 return FromRegEx(Cache, pattern, helper);
ffee1c2b
DK
261 }
262
15fc8636 263 /** \brief returns a package specified by a string
856d3b06 264
15fc8636
DK
265 \param Cache the package is in
266 \param pattern String the package name should be extracted from
c8db3fff 267 \param helper responsible for error and message handling */
15fc8636
DK
268 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
269 return PackageContainerInterface::FromName(Cache, pattern, helper);
270 }
271 static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern) {
70e706ad 272 CacheSetHelper helper;
15fc8636 273 return PackageContainerInterface::FromName(Cache, pattern, helper);
856d3b06
DK
274 }
275
15fc8636 276 /** \brief returns all packages specified by a string
bd631595 277
15fc8636
DK
278 \param Cache the packages are in
279 \param pattern String the package name(s) should be extracted from
c8db3fff 280 \param helper responsible for error and message handling */
15fc8636
DK
281 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper) {
282 PackageContainer cont;
283 PackageContainerInterface::FromString(&cont, Cache, pattern, helper);
284 return cont;
285 }
286 static PackageContainer FromString(pkgCacheFile &Cache, std::string const &pattern) {
bd631595 287 CacheSetHelper helper;
15fc8636 288 return FromString(Cache, pattern, helper);
bd631595
DK
289 }
290
78c32596
DK
291 /** \brief returns all packages specified on the commandline
292
293 Get all package names from the commandline and executes regex's if needed.
294 No special package command is supported, just plain names.
295 \param Cache the packages are in
296 \param cmdline Command line the package names should be extracted from
c8db3fff 297 \param helper responsible for error and message handling */
15fc8636
DK
298 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
299 PackageContainer cont;
300 PackageContainerInterface::FromCommandLine(&cont, Cache, cmdline, helper);
301 return cont;
302 }
303 static PackageContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
70e706ad 304 CacheSetHelper helper;
446bbcf4 305 return FromCommandLine(Cache, cmdline, helper);
78c32596 306 }
9cc83a6f 307
c8db3fff
DK
308 /** \brief group packages by a action modifiers
309
310 At some point it is needed to get from the same commandline
311 different package sets grouped by a modifier. Take
312 apt-get install apt awesome-
313 as an example.
314 \param Cache the packages are in
315 \param cmdline Command line the package names should be extracted from
316 \param mods list of modifiers the method should accept
317 \param fallback the default modifier group for a package
318 \param helper responsible for error and message handling */
15fc8636
DK
319 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
320 pkgCacheFile &Cache,
321 const char **cmdline,
322 std::list<Modifier> const &mods,
323 unsigned short const &fallback,
324 CacheSetHelper &helper) {
325 std::map<unsigned short, PackageContainer> pkgsets;
326 for (const char **I = cmdline; *I != 0; ++I) {
327 unsigned short modID = fallback;
328 PackageContainer pkgset;
329 PackageContainerInterface::FromModifierCommandLine(modID, &pkgset, Cache, *I, mods, helper);
330 pkgsets[modID].insert(pkgset);
331 }
332 return pkgsets;
333 }
334 static std::map<unsigned short, PackageContainer> GroupedFromCommandLine(
335 pkgCacheFile &Cache,
336 const char **cmdline,
337 std::list<Modifier> const &mods,
338 unsigned short const &fallback) {
70e706ad 339 CacheSetHelper helper;
446bbcf4 340 return GroupedFromCommandLine(Cache, cmdline,
70e706ad 341 mods, fallback, helper);
9cc83a6f 342 }
c8db3fff
DK
343 /*}}}*/
344private: /*{{{*/
345 Constructor ConstructedBy;
d4489d49
DK
346 /*}}}*/
347}; /*}}}*/
c4cca791
DK
348
349template<> template<class Cont> void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
350 for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
351 _cont.push_back(*p);
352};
353// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
354// specializations again and again - but we need to see them, so that library users can use them
355template<> inline bool PackageContainer<std::list<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
356 if (P.end() == true)
357 return false;
358 _cont.push_back(P);
359 return true;
360};
361template<> inline void PackageContainer<std::list<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
362 for (const_iterator p = begin; p != end; ++p)
363 _cont.push_back(*p);
364};
15fc8636 365typedef PackageContainer<std::set<pkgCache::PkgIterator> > PackageSet;
c4cca791 366typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
78c32596 367
15fc8636
DK
368class VersionContainerInterface { /*{{{*/
369/** \class APT::VersionContainerInterface
370
371 Same as APT::PackageContainerInterface, just for Versions */
372public:
d4489d49 373 /** \brief smell like a pkgCache::VerIterator */
15fc8636 374 class const_iterator { /*{{{*/
d4489d49 375 public:
15fc8636
DK
376 virtual pkgCache::VerIterator getVer() const = 0;
377 operator pkgCache::VerIterator(void) { return getVer(); }
378
379 inline pkgCache *Cache() const { return getVer().Cache(); };
380 inline unsigned long Index() const {return getVer().Index();};
381 inline int CompareVer(const pkgCache::VerIterator &B) const { return getVer().CompareVer(B); };
382 inline const char *VerStr() const { return getVer().VerStr(); };
383 inline const char *Section() const { return getVer().Section(); };
384 inline const char *Arch() const { return getVer().Arch(); };
385 inline pkgCache::PkgIterator ParentPkg() const { return getVer().ParentPkg(); };
386 inline pkgCache::DescIterator DescriptionList() const { return getVer().DescriptionList(); };
387 inline pkgCache::DescIterator TranslatedDescription() const { return getVer().TranslatedDescription(); };
388 inline pkgCache::DepIterator DependsList() const { return getVer().DependsList(); };
389 inline pkgCache::PrvIterator ProvidesList() const { return getVer().ProvidesList(); };
390 inline pkgCache::VerFileIterator FileList() const { return getVer().FileList(); };
391 inline bool Downloadable() const { return getVer().Downloadable(); };
392 inline const char *PriorityType() const { return getVer().PriorityType(); };
393 inline std::string RelStr() const { return getVer().RelStr(); };
394 inline bool Automatic() const { return getVer().Automatic(); };
395 inline pkgCache::VerFileIterator NewestFile() const { return getVer().NewestFile(); };
d4489d49
DK
396 // we have only valid iterators here
397 inline bool end() const { return false; };
398
15fc8636 399 inline pkgCache::Version const * operator->() const { return &*getVer(); };
d4489d49 400 };
dc0f01f7 401 /*}}}*/
78c32596 402
15fc8636
DK
403 virtual bool insert(pkgCache::VerIterator const &V) = 0;
404 virtual bool empty() const = 0;
405 virtual void clear() = 0;
c45f2d19 406
856d3b06
DK
407 /** \brief specifies which version(s) will be returned if non is given */
408 enum Version {
409 /** All versions */
410 ALL,
411 /** Candidate and installed version */
412 CANDANDINST,
413 /** Candidate version */
414 CANDIDATE,
415 /** Installed version */
416 INSTALLED,
417 /** Candidate or if non installed version */
418 CANDINST,
419 /** Installed or if non candidate version */
420 INSTCAND,
421 /** Newest version */
422 NEWEST
423 };
424
15fc8636
DK
425 struct Modifier {
426 enum Position { NONE, PREFIX, POSTFIX };
427 unsigned short ID;
428 const char * const Alias;
429 Position Pos;
430 Version SelectVersion;
431 Modifier (unsigned short const &id, const char * const alias, Position const &pos,
432 Version const &select) : ID(id), Alias(alias), Pos(pos),
433 SelectVersion(select) {};
434 };
435
436 static bool FromCommandLine(VersionContainerInterface * const vci, pkgCacheFile &Cache,
437 const char **cmdline, Version const &fallback,
438 CacheSetHelper &helper);
439
440 static bool FromString(VersionContainerInterface * const vci, pkgCacheFile &Cache,
441 std::string pkg, Version const &fallback, CacheSetHelper &helper,
442 bool const onlyFromName = false);
443
444 static bool FromPackage(VersionContainerInterface * const vci, pkgCacheFile &Cache,
445 pkgCache::PkgIterator const &P, Version const &fallback,
446 CacheSetHelper &helper);
447
448 static bool FromModifierCommandLine(unsigned short &modID,
449 VersionContainerInterface * const vci,
450 pkgCacheFile &Cache, const char * cmdline,
451 std::list<Modifier> const &mods,
452 CacheSetHelper &helper);
453
c4cca791
DK
454
455 static bool FromDependency(VersionContainerInterface * const vci,
456 pkgCacheFile &Cache,
457 pkgCache::DepIterator const &D,
458 Version const &selector,
459 CacheSetHelper &helper);
460
15fc8636
DK
461protected: /*{{{*/
462
463 /** \brief returns the candidate version of the package
464
465 \param Cache to be used to query for information
466 \param Pkg we want the candidate version from this package */
467 static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
468 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
469
470 /** \brief returns the installed version of the package
471
472 \param Cache to be used to query for information
473 \param Pkg we want the installed version from this package */
474 static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
475 pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
476 /*}}}*/
477};
478 /*}}}*/
479template<class Container> class VersionContainer : public VersionContainerInterface {/*{{{*/
c4cca791 480/** \class APT::VersionContainer
15fc8636
DK
481
482 Simple wrapper around a container class like std::set to provide a similar
483 interface to a set of versions as to the complete set of all versions in the
484 pkgCache. */
485 Container _cont;
486public: /*{{{*/
487 /** \brief smell like a pkgCache::VerIterator */
488 class const_iterator : public VersionContainerInterface::const_iterator,
489 public std::iterator<std::forward_iterator_tag, typename Container::const_iterator> {/*{{{*/
490 typename Container::const_iterator _iter;
491 public:
492 const_iterator(typename Container::const_iterator i) : _iter(i) {}
493 pkgCache::VerIterator getVer(void) const { return *_iter; }
494 inline pkgCache::VerIterator operator*(void) const { return *_iter; };
495 operator typename Container::const_iterator(void) const { return _iter; }
63b70b21
DK
496 inline const_iterator& operator++() { ++_iter; return *this; }
497 inline const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
15fc8636
DK
498 inline bool operator!=(const_iterator const &i) const { return _iter != i._iter; };
499 inline bool operator==(const_iterator const &i) const { return _iter == i._iter; };
500 friend std::ostream& operator<<(std::ostream& out, const_iterator i) { return operator<<(out, *i); }
501 };
c4cca791
DK
502 class iterator : public VersionContainerInterface::const_iterator,
503 public std::iterator<std::forward_iterator_tag, typename Container::iterator> {
504 typename Container::iterator _iter;
505 public:
506 iterator(typename Container::iterator i) : _iter(i) {}
507 pkgCache::VerIterator getVer(void) const { return *_iter; }
508 inline pkgCache::VerIterator operator*(void) const { return *_iter; };
509 operator typename Container::iterator(void) const { return _iter; }
bce0e0ff 510 operator typename VersionContainer<Container>::const_iterator() { return typename VersionContainer<Container>::const_iterator(_iter); }
63b70b21
DK
511 inline iterator& operator++() { ++_iter; return *this; }
512 inline iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
c4cca791
DK
513 inline bool operator!=(iterator const &i) const { return _iter != i._iter; };
514 inline bool operator==(iterator const &i) const { return _iter == i._iter; };
5eb9a474
DK
515 inline iterator& operator=(iterator const &i) { _iter = i._iter; return *this; };
516 inline iterator& operator=(typename Container::iterator const &i) { _iter = i; return *this; };
c4cca791
DK
517 friend std::ostream& operator<<(std::ostream& out, iterator i) { return operator<<(out, *i); }
518 };
15fc8636
DK
519 /*}}}*/
520
521 bool insert(pkgCache::VerIterator const &V) { if (V.end() == true) return false; _cont.insert(V); return true; };
522 template<class Cont> void insert(VersionContainer<Cont> const &vercont) { _cont.insert((typename Cont::const_iterator)vercont.begin(), (typename Cont::const_iterator)vercont.end()); };
523 void insert(const_iterator begin, const_iterator end) { _cont.insert(begin, end); };
524 bool empty() const { return _cont.empty(); };
525 void clear() { return _cont.clear(); };
5eb9a474 526 //FIXME: on ABI break, replace the first with the second without bool
c4cca791 527 void erase(iterator position) { _cont.erase((typename Container::iterator)position); };
5eb9a474 528 iterator& erase(iterator &position, bool) { return position = _cont.erase((typename Container::iterator)position); };
c4cca791 529 size_t erase(const pkgCache::VerIterator x) { return _cont.erase(x); };
15fc8636
DK
530 void erase(iterator first, iterator last) { _cont.erase(first, last); };
531 size_t size() const { return _cont.size(); };
532
533 const_iterator begin() const { return const_iterator(_cont.begin()); };
534 const_iterator end() const { return const_iterator(_cont.end()); };
c4cca791
DK
535 iterator begin() { return iterator(_cont.begin()); };
536 iterator end() { return iterator(_cont.end()); };
15fc8636
DK
537 const_iterator find(pkgCache::VerIterator const &V) const { return const_iterator(_cont.find(V)); };
538
856d3b06
DK
539 /** \brief returns all versions specified on the commandline
540
541 Get all versions from the commandline, uses given default version if
542 non specifically requested and executes regex's if needed on names.
543 \param Cache the packages and versions are in
544 \param cmdline Command line the versions should be extracted from
c8db3fff 545 \param helper responsible for error and message handling */
15fc8636
DK
546 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
547 Version const &fallback, CacheSetHelper &helper) {
548 VersionContainer vercon;
549 VersionContainerInterface::FromCommandLine(&vercon, Cache, cmdline, fallback, helper);
550 return vercon;
551 }
552 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
553 Version const &fallback) {
70e706ad 554 CacheSetHelper helper;
446bbcf4 555 return FromCommandLine(Cache, cmdline, fallback, helper);
856d3b06 556 }
15fc8636 557 static VersionContainer FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
446bbcf4 558 return FromCommandLine(Cache, cmdline, CANDINST);
856d3b06 559 }
55c59998 560
15fc8636
DK
561 static VersionContainer FromString(pkgCacheFile &Cache, std::string const &pkg,
562 Version const &fallback, CacheSetHelper &helper,
563 bool const onlyFromName = false) {
564 VersionContainer vercon;
565 VersionContainerInterface::FromString(&vercon, Cache, pkg, fallback, helper);
566 return vercon;
567 }
568 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg,
569 Version const &fallback) {
70e706ad 570 CacheSetHelper helper;
446bbcf4 571 return FromString(Cache, pkg, fallback, helper);
55c59998 572 }
15fc8636 573 static VersionContainer FromString(pkgCacheFile &Cache, std::string pkg) {
446bbcf4 574 return FromString(Cache, pkg, CANDINST);
55c59998
DK
575 }
576
fb83c1d0
DK
577 /** \brief returns all versions specified for the package
578
579 \param Cache the package and versions are in
580 \param P the package in question
581 \param fallback the version(s) you want to get
582 \param helper the helper used for display and error handling */
15fc8636
DK
583 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
584 Version const &fallback, CacheSetHelper &helper) {
585 VersionContainer vercon;
586 VersionContainerInterface::FromPackage(&vercon, Cache, P, fallback, helper);
587 return vercon;
588 }
589 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
590 Version const &fallback) {
c8db3fff 591 CacheSetHelper helper;
446bbcf4 592 return FromPackage(Cache, P, fallback, helper);
c8db3fff 593 }
15fc8636 594 static VersionContainer FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
c4cca791 595 return FromPackage(Cache, P, CANDIDATE);
c8db3fff 596 }
fb83c1d0 597
15fc8636
DK
598 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
599 pkgCacheFile &Cache,
600 const char **cmdline,
601 std::list<Modifier> const &mods,
602 unsigned short const fallback,
603 CacheSetHelper &helper) {
604 std::map<unsigned short, VersionContainer> versets;
605 for (const char **I = cmdline; *I != 0; ++I) {
606 unsigned short modID = fallback;
607 VersionContainer verset;
608 VersionContainerInterface::FromModifierCommandLine(modID, &verset, Cache, *I, mods, helper);
609 versets[modID].insert(verset);
610 }
611 return versets;
55c59998 612
15fc8636
DK
613 }
614 static std::map<unsigned short, VersionContainer> GroupedFromCommandLine(
55c59998 615 pkgCacheFile &Cache, const char **cmdline,
15fc8636
DK
616 std::list<Modifier> const &mods,
617 unsigned short const fallback) {
70e706ad 618 CacheSetHelper helper;
446bbcf4 619 return GroupedFromCommandLine(Cache, cmdline,
70e706ad 620 mods, fallback, helper);
55c59998 621 }
c4cca791
DK
622
623 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
624 Version const &selector, CacheSetHelper &helper) {
625 VersionContainer vercon;
626 VersionContainerInterface::FromDependency(&vercon, Cache, D, selector, helper);
627 return vercon;
628 }
629 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D,
630 Version const &selector) {
631 CacheSetHelper helper;
632 return FromPackage(Cache, D, selector, helper);
633 }
634 static VersionContainer FromDependency(pkgCacheFile &Cache, pkgCache::DepIterator const &D) {
635 return FromPackage(Cache, D, CANDIDATE);
636 }
856d3b06 637 /*}}}*/
d4489d49 638}; /*}}}*/
c4cca791
DK
639
640template<> template<class Cont> void VersionContainer<std::list<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
641 for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
642 _cont.push_back(*v);
643};
644// these two are 'inline' as otherwise the linker has problems with seeing these untemplated
645// specializations again and again - but we need to see them, so that library users can use them
646template<> inline bool VersionContainer<std::list<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
647 if (V.end() == true)
648 return false;
649 _cont.push_back(V);
650 return true;
651};
652template<> inline void VersionContainer<std::list<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
653 for (const_iterator v = begin; v != end; ++v)
654 _cont.push_back(*v);
655};
15fc8636 656typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
c4cca791 657typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
e1dbde8d
DK
658}
659#endif