| 1 | // -*- mode: cpp; mode: fold -*- |
| 2 | // Description /*{{{*/ |
| 3 | // $Id: orderlist.h,v 1.9 2001/02/20 07:03:17 jgg Exp $ |
| 4 | /* ###################################################################### |
| 5 | |
| 6 | Order List - Represents and Manipulates an ordered list of packages. |
| 7 | |
| 8 | A list of packages can be ordered by a number of conflicting criteria |
| 9 | each given a specific priority. Each package also has a set of flags |
| 10 | indicating some useful things about it that are derived in the |
| 11 | course of sorting. The pkgPackageManager class uses this class for |
| 12 | all of it's installation ordering needs. |
| 13 | |
| 14 | ##################################################################### */ |
| 15 | /*}}}*/ |
| 16 | #ifndef PKGLIB_ORDERLIST_H |
| 17 | #define PKGLIB_ORDERLIST_H |
| 18 | |
| 19 | #include <apt-pkg/pkgcache.h> |
| 20 | #include <apt-pkg/cacheiterators.h> |
| 21 | #include <apt-pkg/macros.h> |
| 22 | |
| 23 | #include <string> |
| 24 | |
| 25 | class pkgDepCache; |
| 26 | class pkgOrderList : protected pkgCache::Namespace |
| 27 | { |
| 28 | protected: |
| 29 | |
| 30 | pkgDepCache &Cache; |
| 31 | typedef bool (pkgOrderList::*DepFunc)(DepIterator D); |
| 32 | |
| 33 | // These are the currently selected ordering functions |
| 34 | DepFunc Primary; |
| 35 | DepFunc Secondary; |
| 36 | DepFunc RevDepends; |
| 37 | DepFunc Remove; |
| 38 | |
| 39 | // State |
| 40 | Package **End; |
| 41 | Package **List; |
| 42 | Package **AfterEnd; |
| 43 | std::string *FileList; |
| 44 | DepIterator Loops[20]; |
| 45 | int LoopCount; |
| 46 | int Depth; |
| 47 | unsigned short *Flags; |
| 48 | bool Debug; |
| 49 | |
| 50 | // Main visit function |
| 51 | APT_DEPRECATED bool VisitNode(PkgIterator Pkg) { return VisitNode(Pkg, "UNKNOWN"); }; |
| 52 | bool VisitNode(PkgIterator Pkg, char const* from); |
| 53 | bool VisitDeps(DepFunc F,PkgIterator Pkg); |
| 54 | bool VisitRDeps(DepFunc F,PkgIterator Pkg); |
| 55 | bool VisitRProvides(DepFunc F,VerIterator Ver); |
| 56 | bool VisitProvides(DepIterator Pkg,bool Critical); |
| 57 | |
| 58 | // Dependency checking functions. |
| 59 | bool DepUnPackCrit(DepIterator D); |
| 60 | bool DepUnPackPreD(DepIterator D); |
| 61 | bool DepUnPackPre(DepIterator D); |
| 62 | bool DepUnPackDep(DepIterator D); |
| 63 | bool DepConfigure(DepIterator D); |
| 64 | bool DepRemove(DepIterator D); |
| 65 | |
| 66 | // Analysis helpers |
| 67 | bool AddLoop(DepIterator D); |
| 68 | bool CheckDep(DepIterator D); |
| 69 | bool DoRun(); |
| 70 | |
| 71 | // For pre sorting |
| 72 | static pkgOrderList *Me; |
| 73 | static int OrderCompareA(const void *a, const void *b) APT_PURE; |
| 74 | static int OrderCompareB(const void *a, const void *b) APT_PURE; |
| 75 | int FileCmp(PkgIterator A,PkgIterator B) APT_PURE; |
| 76 | |
| 77 | public: |
| 78 | |
| 79 | typedef Package **iterator; |
| 80 | |
| 81 | /* State flags |
| 82 | The Loop flag can be set on a package that is currently being processed by either SmartConfigure or |
| 83 | SmartUnPack. This allows the package manager to tell when a loop has been formed as it will try to |
| 84 | SmartUnPack or SmartConfigure a package with the Loop flag set. It will then either stop (as it knows |
| 85 | that the operation is unnecessary as its already in process), or in the case of the conflicts resolution |
| 86 | in SmartUnPack, use EarlyRemove to resolve the situation. */ |
| 87 | enum Flags {Added = (1 << 0), AddPending = (1 << 1), |
| 88 | Immediate = (1 << 2), Loop = (1 << 3), |
| 89 | UnPacked = (1 << 4), Configured = (1 << 5), |
| 90 | Removed = (1 << 6), // Early Remove |
| 91 | InList = (1 << 7), |
| 92 | After = (1 << 8), |
| 93 | States = (UnPacked | Configured | Removed)}; |
| 94 | |
| 95 | // Flag manipulators |
| 96 | inline bool IsFlag(PkgIterator Pkg,unsigned long F) {return (Flags[Pkg->ID] & F) == F;}; |
| 97 | inline bool IsFlag(Package *Pkg,unsigned long F) {return (Flags[Pkg->ID] & F) == F;}; |
| 98 | void Flag(PkgIterator Pkg,unsigned long State, unsigned long F) {Flags[Pkg->ID] = (Flags[Pkg->ID] & (~F)) | State;}; |
| 99 | inline void Flag(PkgIterator Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; |
| 100 | inline void Flag(Package *Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; |
| 101 | // RmFlag removes a flag from a package |
| 102 | inline void RmFlag(Package *Pkg,unsigned long F) {Flags[Pkg->ID] &= ~F;}; |
| 103 | // IsNow will return true if the Pkg has been not been either configured or unpacked |
| 104 | inline bool IsNow(PkgIterator Pkg) {return (Flags[Pkg->ID] & (States & (~Removed))) == 0;}; |
| 105 | bool IsMissing(PkgIterator Pkg) APT_PURE; |
| 106 | void WipeFlags(unsigned long F); |
| 107 | void SetFileList(std::string *FileList) {this->FileList = FileList;}; |
| 108 | |
| 109 | // Accessors |
| 110 | inline iterator begin() {return List;}; |
| 111 | inline iterator end() {return End;}; |
| 112 | inline void push_back(Package *Pkg) {*(End++) = Pkg;}; |
| 113 | inline void push_back(PkgIterator Pkg) {*(End++) = Pkg;}; |
| 114 | inline void pop_back() {End--;}; |
| 115 | inline bool empty() {return End == List;}; |
| 116 | inline unsigned int size() {return End - List;}; |
| 117 | |
| 118 | // Ordering modes |
| 119 | bool OrderCritical(); |
| 120 | bool OrderUnpack(std::string *FileList = 0); |
| 121 | bool OrderConfigure(); |
| 122 | |
| 123 | int Score(PkgIterator Pkg); |
| 124 | |
| 125 | pkgOrderList(pkgDepCache *Cache); |
| 126 | ~pkgOrderList(); |
| 127 | }; |
| 128 | |
| 129 | #endif |