#include <apt-pkg/cacheiterators.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/versionmatch.h>
+#include <apt-pkg/version.h>
#include <ctype.h>
#include <stddef.h>
// ---------------------------------------------------------------------
/* Set the defaults for operation. The default mode with no loaded policy
file matches the V0 policy engine. */
-pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner)
+pkgPolicy::pkgPolicy(pkgCache *Owner) : Pins(0), PFPriority(0), Cache(Owner), d(NULL)
{
if (Owner == 0)
return;
best package is. */
pkgCache::VerIterator pkgPolicy::GetCandidateVer(pkgCache::PkgIterator const &Pkg)
{
+ if (_config->FindI("APT::Policy", 1) >= 1) {
+ return GetCandidateVerNew(Pkg);
+ }
+
// Look for a package pin and evaluate it.
signed Max = GetPriority(Pkg);
pkgCache::VerIterator Pref = GetMatch(Pkg);
return Pref;
}
+
+// Policy::GetCandidateVer - Get the candidate install version /*{{{*/
+// ---------------------------------------------------------------------
+/* Evaluate the package pins and the default list to deteremine what the
+ best package is. */
+pkgCache::VerIterator pkgPolicy::GetCandidateVerNew(pkgCache::PkgIterator const &Pkg)
+{
+ // TODO: Replace GetCandidateVer()
+ pkgCache::VerIterator cand;
+ pkgCache::VerIterator cur = Pkg.CurrentVer();
+ int candPriority = -1;
+ pkgVersioningSystem *vs = Cache->VS;
+
+ for (pkgCache::VerIterator ver = Pkg.VersionList(); ver.end() == false; ver++) {
+ int priority = GetPriority(ver);
+
+ if (priority == 0 || priority <= candPriority)
+ continue;
+
+ // TODO: Maybe optimize to not compare versions
+ if (!cur.end() && priority < 1000
+ && (vs->CmpVersion(ver.VerStr(), cur.VerStr()) < 0))
+ continue;
+
+ candPriority = priority;
+ cand = ver;
+ }
+
+ return cand;
+}
/*}}}*/
// Policy::CreatePin - Create an entry in the pin table.. /*{{{*/
// ---------------------------------------------------------------------
P->Priority = Priority;
P->Data = Data;
matched = true;
+
+ // Find matching version(s) and copy the pin into it
+ pkgVersionMatch Match(P->Data,P->Type);
+ for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() != true; Ver++)
+ {
+ if (Match.VersionMatches(Ver)) {
+ Pin *VP = VerPins + Ver->ID;
+ if (VP->Type == pkgVersionMatch::None)
+ *VP = *P;
+ }
+ }
}
}
{
if (VerPins[Ver->ID].Type != pkgVersionMatch::None)
return VerPins[Ver->ID].Priority;
- return 0;
+
+
+ int priority = INT_MIN;
+ for (pkgCache::VerFileIterator file = Ver.FileList(); file.end() == false; file++)
+ {
+ /* If this is the status file, and the current version is not the
+ version in the status file (ie it is not installed, or somesuch)
+ then it is not a candidate for installation, ever. This weeds
+ out bogus entries that may be due to config-file states, or
+ other. */
+ if (file.File().Flagged(pkgCache::Flag::NotSource) && Ver.ParentPkg().CurrentVer() != Ver) {
+ if (priority < 0)
+ priority = 0;
+ } else if (GetPriority(file.File()) > priority) {
+ priority = GetPriority(file.File());
+ }
+ }
+
+ return priority == INT_MIN ? 0 : priority;
}
APT_PURE signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &File)
{
return PFPriority[File->ID];
}
/*}}}*/
-// PreferenceSection class - Overriding the default TrimRecord method /*{{{*/
-// ---------------------------------------------------------------------
-/* The preference file is a user generated file so the parser should
- therefore be a bit more friendly by allowing comments and new lines
- all over the place rather than forcing a special format */
-class PreferenceSection : public pkgTagSection
-{
- void TrimRecord(bool /*BeforeRecord*/, const char* &End)
- {
- for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r' || Stop[0] == '#'); Stop++)
- if (Stop[0] == '#')
- Stop = (const char*) memchr(Stop,'\n',End-Stop);
- }
-};
- /*}}}*/
// ReadPinDir - Load the pin files from this dir into a Policy /*{{{*/
// ---------------------------------------------------------------------
/* This will load each pin file in the given dir into a Policy. If the
pkgTagFile TF(&Fd);
if (_error->PendingError() == true)
return false;
-
- PreferenceSection Tags;
+
+ pkgUserTagSection Tags;
while (TF.Step(Tags) == true)
{
// can happen when there are only comments in a record