summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2010-07-09 19:10:28 +0200
committerMichael Vogt <mvo@debian.org>2010-07-09 19:10:28 +0200
commit358f10d9d47a88cbf0568f042caccfef8678cbc8 (patch)
tree711c7ddc538476e8b88dfb8b6d76361db5754c1e
parentfd3b761e8cba6ed626639b50b1221246098c7b3a (diff)
parenta9fe592842bfa17d91f4904d7fb0e3af3adebb17 (diff)
merged from donkult
-rw-r--r--apt-pkg/algorithms.h2
-rw-r--r--apt-pkg/aptconfiguration.cc4
-rw-r--r--apt-pkg/cachefile.cc2
-rw-r--r--apt-pkg/cachefile.h8
-rw-r--r--apt-pkg/cacheiterators.h47
-rw-r--r--apt-pkg/cacheset.cc280
-rw-r--r--apt-pkg/contrib/configuration.cc43
-rw-r--r--apt-pkg/contrib/configuration.h19
-rw-r--r--apt-pkg/contrib/error.cc367
-rw-r--r--apt-pkg/contrib/error.h263
-rw-r--r--apt-pkg/contrib/fileutl.cc4
-rw-r--r--apt-pkg/contrib/mmap.cc29
-rw-r--r--apt-pkg/deb/debindexfile.cc1
-rw-r--r--apt-pkg/deb/deblistparser.cc39
-rw-r--r--apt-pkg/deb/deblistparser.h18
-rw-r--r--apt-pkg/depcache.cc88
-rw-r--r--apt-pkg/depcache.h30
-rw-r--r--apt-pkg/init.cc5
-rw-r--r--apt-pkg/makefile5
-rw-r--r--apt-pkg/orderlist.cc3
-rw-r--r--apt-pkg/packagemanager.cc3
-rw-r--r--apt-pkg/pkgcache.cc17
-rw-r--r--apt-pkg/pkgcache.h2
-rw-r--r--apt-pkg/pkgcachegen.cc246
-rw-r--r--apt-pkg/pkgcachegen.h46
-rw-r--r--apt-pkg/policy.h2
-rw-r--r--cmdline/apt-cache.cc21
-rw-r--r--cmdline/apt-cdrom.cc14
-rw-r--r--cmdline/apt-get.cc709
-rw-r--r--cmdline/cacheset.cc515
-rw-r--r--cmdline/cacheset.h (renamed from apt-pkg/cacheset.h)202
-rw-r--r--cmdline/makefile4
-rw-r--r--debian/changelog46
-rw-r--r--debian/control2
-rw-r--r--doc/apt.conf.5.xml9
-rw-r--r--test/libapt/globalerror_test.cc77
-rw-r--r--test/libapt/makefile10
-rw-r--r--test/libapt/parsedepends_test.cc68
38 files changed, 2097 insertions, 1153 deletions
diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h
index cee30b679..cf4a98c4f 100644
--- a/apt-pkg/algorithms.h
+++ b/apt-pkg/algorithms.h
@@ -48,7 +48,7 @@ class pkgSimulate : public pkgPackageManager /*{{{*/
pkgDepCache *Cache;
public:
- virtual VerIterator GetCandidateVer(PkgIterator Pkg)
+ virtual VerIterator GetCandidateVer(PkgIterator const &Pkg)
{
return (*Cache)[Pkg].CandidateVerIter(*Cache);
}
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 0c050d9dc..44f1f318a 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -10,6 +10,7 @@
// Include Files /*{{{*/
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
#include <apt-pkg/fileutl.h>
#include <apt-pkg/macros.h>
#include <apt-pkg/strutl.h>
@@ -196,6 +197,9 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
// it was undocumented and so it should be not very widthly used
string const oldAcquire = _config->Find("APT::Acquire::Translation","");
if (oldAcquire.empty() == false && oldAcquire != "environment") {
+ // TRANSLATORS: the two %s are APT configuration options
+ _error->Notice("Option '%s' is deprecated. Please use '%s' instead, see 'man 5 apt.conf' for details.",
+ "APT::Acquire::Translation", "Acquire::Languages");
if (oldAcquire != "none")
codes.push_back(oldAcquire);
codes.push_back("en");
diff --git a/apt-pkg/cachefile.cc b/apt-pkg/cachefile.cc
index 01598386c..964c5bd8b 100644
--- a/apt-pkg/cachefile.cc
+++ b/apt-pkg/cachefile.cc
@@ -28,7 +28,7 @@
// ---------------------------------------------------------------------
/* */
pkgCacheFile::pkgCacheFile() : Map(NULL), Cache(NULL), DCache(NULL),
- Policy(NULL), SrcList(NULL)
+ SrcList(NULL), Policy(NULL)
{
}
/*}}}*/
diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h
index 63bc3de47..09d3ec267 100644
--- a/apt-pkg/cachefile.h
+++ b/apt-pkg/cachefile.h
@@ -20,10 +20,9 @@
#include <apt-pkg/depcache.h>
#include <apt-pkg/acquire.h>
+#include <apt-pkg/policy.h>
#include <apt-pkg/sourcelist.h>
-class pkgPolicy;
-class pkgSourceList;
class pkgCacheFile
{
protected:
@@ -65,6 +64,11 @@ class pkgCacheFile
inline pkgPolicy* GetPolicy() { BuildPolicy(); return Policy; };
inline pkgSourceList* GetSourceList() { BuildSourceList(); return SrcList; };
+ inline bool IsPkgCacheBuilt() const { return (Cache != NULL); };
+ inline bool IsDepCacheBuilt() const { return (DCache != NULL); };
+ inline bool IsPolicyBuilt() const { return (Policy != NULL); };
+ inline bool IsSrcListBuilt() const { return (SrcList != NULL); };
+
pkgCacheFile();
virtual ~pkgCacheFile();
};
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index f0b40dbb5..eb8dee5e3 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -30,6 +30,8 @@
#ifndef PKGLIB_CACHEITERATORS_H
#define PKGLIB_CACHEITERATORS_H
#include<iterator>
+
+#include<string.h>
// abstract Iterator template /*{{{*/
/* This template provides the very basic iterator methods we
need to have for doing some walk-over-the-cache magic */
@@ -73,6 +75,12 @@ template<typename Str, typename Itr> class pkgCache::Iterator :
inline bool IsGood() const { return S && Owner && ! end();};
inline unsigned long Index() const {return S - OwnerPointer();};
+ void ReOwn(pkgCache &newOwner, void const * const oldMap, void const * const newMap) {
+ if (S == 0)
+ return;
+ S += (Str*)(newMap) - (Str*)(oldMap);
+ }
+
// Constructors - look out for the variable assigning
inline Iterator() : S(0), Owner(0) {};
inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {};
@@ -103,13 +111,13 @@ class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
inline PkgIterator PackageList() const;
- PkgIterator FindPkg(string Arch = "any");
+ PkgIterator FindPkg(string Arch = "any") const;
/** \brief find the package with the "best" architecture
The best architecture is either the "native" or the first
in the list of Architectures which is not an end-Pointer */
- PkgIterator FindPreferredPkg();
- PkgIterator NextPkg(PkgIterator const &Pkg);
+ PkgIterator FindPreferredPkg() const;
+ PkgIterator NextPkg(PkgIterator const &Pkg) const;
// Constructors
inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
@@ -183,6 +191,13 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
// Comparison
int CompareVer(const VerIterator &B) const;
+ /** \brief compares two version and returns if they are similar
+
+ This method should be used to identify if two pseudo versions are
+ refering to the same "real" version */
+ inline bool SimilarVer(const VerIterator &B) const {
+ return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0);
+ };
// Accessors
inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
@@ -263,17 +278,17 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
// Accessors
inline const char *TargetVer() const {return S->Version == 0?0:Owner->StrP + S->Version;};
- inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
- inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
- inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
- inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
- inline bool Reverse() {return Type == DepRev;};
- bool IsCritical();
+ inline PkgIterator TargetPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->Package);};
+ inline PkgIterator SmartTargetPkg() const {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
+ inline VerIterator ParentVer() const {return VerIterator(*Owner,Owner->VerP + S->ParentVer);};
+ inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->ParentVer].ParentPkg);};
+ inline bool Reverse() const {return Type == DepRev;};
+ bool IsCritical() const;
void GlobOr(DepIterator &Start,DepIterator &End);
- Version **AllTargets();
- bool SmartTargetPkg(PkgIterator &Result);
- inline const char *CompType() {return Owner->CompType(S->CompareOp);};
- inline const char *DepType() {return Owner->DepType(S->Type);};
+ Version **AllTargets() const;
+ bool SmartTargetPkg(PkgIterator &Result) const;
+ inline const char *CompType() const {return Owner->CompType(S->CompareOp);};
+ inline const char *DepType() const {return Owner->DepType(S->Type);};
inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
@@ -306,9 +321,9 @@ class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
// Accessors
inline const char *Name() const {return Owner->StrP + Owner->PkgP[S->ParentPkg].Name;};
inline const char *ProvideVersion() const {return S->ProvideVersion == 0?0:Owner->StrP + S->ProvideVersion;};
- inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
- inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + S->Version);};
- inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
+ inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};
+ inline VerIterator OwnerVer() const {return VerIterator(*Owner,Owner->VerP + S->Version);};
+ inline PkgIterator OwnerPkg() const {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[S->Version].ParentPkg);};
inline PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
deleted file mode 100644
index 43ade4b4e..000000000
--- a/apt-pkg/cacheset.cc
+++ /dev/null
@@ -1,280 +0,0 @@
-// -*- mode: cpp; mode: fold -*-
-// Description /*{{{*/
-/* ######################################################################
-
- Simple wrapper around a std::set to provide a similar interface to
- a set of cache structures as to the complete set of all structures
- in the pkgCache. Currently only Package is supported.
-
- ##################################################################### */
- /*}}}*/
-// Include Files /*{{{*/
-#include <apt-pkg/aptconfiguration.h>
-#include <apt-pkg/error.h>
-#include <apt-pkg/cacheset.h>
-#include <apt-pkg/strutl.h>
-#include <apt-pkg/versionmatch.h>
-
-#include <apti18n.h>
-
-#include <vector>
-
-#include <regex.h>
- /*}}}*/
-namespace APT {
-// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
-PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out) {
- PackageSet pkgset;
- std::string arch = "native";
- static const char * const isregex = ".?+*|[^$";
-
- if (pattern.find_first_of(isregex) == std::string::npos)
- return pkgset;
-
- size_t archfound = pattern.find_last_of(':');
- if (archfound != std::string::npos) {
- arch = pattern.substr(archfound+1);
- if (arch.find_first_of(isregex) == std::string::npos)
- pattern.erase(archfound);
- else
- arch = "native";
- }
-
- regex_t Pattern;
- int Res;
- if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
- char Error[300];
- regerror(Res, &Pattern, Error, sizeof(Error));
- _error->Error(_("Regex compilation error - %s"), Error);
- return pkgset;
- }
-
- for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp)
- {
- if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
- continue;
- pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
- if (Pkg.end() == true) {
- if (archfound == std::string::npos) {
- std::vector<std::string> archs = APT::Configuration::getArchitectures();
- for (std::vector<std::string>::const_iterator a = archs.begin();
- a != archs.end() && Pkg.end() != true; ++a)
- Pkg = Grp.FindPkg(*a);
- }
- if (Pkg.end() == true)
- continue;
- }
-
- ioprintf(out, _("Note, selecting %s for regex '%s'\n"),
- Pkg.FullName(true).c_str(), pattern.c_str());
-
- pkgset.insert(Pkg);
- }
-
- regfree(&Pattern);
-
- return pkgset;
-}
- /*}}}*/
-// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
-std::map<unsigned short, PackageSet> PackageSet::GroupedFromCommandLine(
- pkgCacheFile &Cache, const char **cmdline,
- std::list<PackageSet::Modifier> const &mods,
- unsigned short const &fallback, std::ostream &out) {
- std::map<unsigned short, PackageSet> pkgsets;
- for (const char **I = cmdline; *I != 0; ++I) {
- unsigned short modID = fallback;
- std::string str = *I;
- for (std::list<PackageSet::Modifier>::const_iterator mod = mods.begin();
- mod != mods.end(); ++mod) {
- size_t const alength = strlen(mod->Alias);
- switch(mod->Pos) {
- case PackageSet::Modifier::POSTFIX:
- if (str.compare(str.length() - alength, alength,
- mod->Alias, 0, alength) != 0)
- continue;
- str.erase(str.length() - alength);
- modID = mod->ID;
- break;
- case PackageSet::Modifier::PREFIX:
- continue;
- case PackageSet::Modifier::NONE:
- continue;
- }
- break;
- }
- PackageSet pset = PackageSet::FromString(Cache, str, out);
- pkgsets[modID].insert(pset.begin(), pset.end());
- }
- return pkgsets;
-}
- /*}}}*/
-// FromCommandLine - Return all packages specified on commandline /*{{{*/
-PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out) {
- PackageSet pkgset;
- for (const char **I = cmdline; *I != 0; ++I) {
- PackageSet pset = FromString(Cache, *I, out);
- pkgset.insert(pset.begin(), pset.end());
- }
- return pkgset;
-}
- /*}}}*/
-// FromString - Return all packages matching a specific string /*{{{*/
-PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, std::ostream &out) {
- std::string pkg = str;
- size_t archfound = pkg.find_last_of(':');
- std::string arch;
- if (archfound != std::string::npos) {
- arch = pkg.substr(archfound+1);
- pkg.erase(archfound);
- }
-
- pkgCache::PkgIterator Pkg;
- if (arch.empty() == true) {
- pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg);
- if (Grp.end() == false)
- Pkg = Grp.FindPreferredPkg();
- } else
- Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch);
-
- if (Pkg.end() == false) {
- PackageSet pkgset;
- pkgset.insert(Pkg);
- return pkgset;
- }
- PackageSet regex = FromRegEx(Cache, str, out);
- if (regex.empty() == true)
- _error->Warning(_("Unable to locate package %s"), str.c_str());
- return regex;
-}
- /*}}}*/
-// FromCommandLine - Return all versions specified on commandline /*{{{*/
-APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
- APT::VersionSet::Version const &fallback, std::ostream &out) {
- VersionSet verset;
- for (const char **I = cmdline; *I != 0; ++I) {
- std::string pkg = *I;
- std::string ver;
- bool verIsRel = false;
- size_t const vertag = pkg.find_last_of("/=");
- if (vertag != string::npos) {
- ver = pkg.substr(vertag+1);
- verIsRel = (pkg[vertag] == '/');
- pkg.erase(vertag);
- }
- PackageSet pkgset = PackageSet::FromString(Cache, pkg.c_str(), out);
- for (PackageSet::const_iterator P = pkgset.begin();
- P != pkgset.end(); ++P) {
- if (vertag == string::npos) {
- AddSelectedVersion(Cache, verset, P, fallback);
- continue;
- }
- pkgCache::VerIterator V;
- if (ver == "installed")
- V = getInstalledVer(Cache, P);
- else if (ver == "candidate")
- V = getCandidateVer(Cache, P);
- else {
- pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release :
- pkgVersionMatch::Version));
- V = Match.Find(P);
- if (V.end() == true) {
- if (verIsRel == true)
- _error->Error(_("Release '%s' for '%s' was not found"),
- ver.c_str(), P.FullName(true).c_str());
- else
- _error->Error(_("Version '%s' for '%s' was not found"),
- ver.c_str(), P.FullName(true).c_str());
- continue;
- }
- }
- if (V.end() == true)
- continue;
- if (ver == V.VerStr())
- ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
- V.VerStr(), V.RelStr().c_str(), P.FullName(true).c_str());
- verset.insert(V);
- }
- }
- return verset;
-}
- /*}}}*/
-// AddSelectedVersion - add version from package based on fallback /*{{{*/
-bool VersionSet::AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset,
- pkgCache::PkgIterator const &P, VersionSet::Version const &fallback,
- bool const &AllowError) {
- pkgCache::VerIterator V;
- switch(fallback) {
- case VersionSet::ALL:
- if (P->VersionList != 0)
- for (V = P.VersionList(); V.end() != true; ++V)
- verset.insert(V);
- else if (AllowError == false)
- return _error->Error(_("Can't select versions from package '%s' as it purely virtual"), P.FullName(true).c_str());
- else
- return false;
- break;
- case VersionSet::CANDANDINST:
- verset.insert(getInstalledVer(Cache, P, AllowError));
- verset.insert(getCandidateVer(Cache, P, AllowError));
- break;
- case VersionSet::CANDIDATE:
- verset.insert(getCandidateVer(Cache, P, AllowError));
- break;
- case VersionSet::INSTALLED:
- verset.insert(getInstalledVer(Cache, P, AllowError));
- break;
- case VersionSet::CANDINST:
- V = getCandidateVer(Cache, P, true);
- if (V.end() == true)
- V = getInstalledVer(Cache, P, true);
- if (V.end() == false)
- verset.insert(V);
- else if (AllowError == false)
- return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str());
- else
- return false;
- break;
- case VersionSet::INSTCAND:
- V = getInstalledVer(Cache, P, true);
- if (V.end() == true)
- V = getCandidateVer(Cache, P, true);
- if (V.end() == false)
- verset.insert(V);
- else if (AllowError == false)
- return _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), P.FullName(true).c_str());
- else
- return false;
- break;
- case VersionSet::NEWEST:
- if (P->VersionList != 0)
- verset.insert(P.VersionList());
- else if (AllowError == false)
- return _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), P.FullName(true).c_str());
- else
- return false;
- break;
- }
- return true;
-}
- /*}}}*/
-// getCandidateVer - Returns the candidate version of the given package /*{{{*/
-pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
- pkgCache::PkgIterator const &Pkg, bool const &AllowError) {
- if (unlikely(Cache.BuildDepCache() == false))
- return pkgCache::VerIterator(*Cache);
- pkgCache::VerIterator Cand = Cache[Pkg].CandidateVerIter(Cache);
- if (AllowError == false && Cand.end() == true)
- _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str());
- return Cand;
-}
- /*}}}*/
-// getInstalledVer - Returns the installed version of the given package /*{{{*/
-pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache,
- pkgCache::PkgIterator const &Pkg, bool const &AllowError) {
- if (AllowError == false && Pkg->CurrentVer == 0)
- _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str());
- return Pkg.CurrentVer();
-}
- /*}}}*/
-}
diff --git a/apt-pkg/contrib/configuration.cc b/apt-pkg/contrib/configuration.cc
index 9129d92f0..81cc87d15 100644
--- a/apt-pkg/contrib/configuration.cc
+++ b/apt-pkg/contrib/configuration.cc
@@ -843,3 +843,46 @@ bool ReadConfigDir(Configuration &Conf,const string &Dir,
return true;
}
/*}}}*/
+// MatchAgainstConfig Constructor /*{{{*/
+Configuration::MatchAgainstConfig::MatchAgainstConfig(char const * Config)
+{
+ std::vector<std::string> const strings = _config->FindVector(Config);
+ for (std::vector<std::string>::const_iterator s = strings.begin();
+ s != strings.end(); ++s)
+ {
+ regex_t *p = new regex_t;
+ if (regcomp(p, s->c_str(), REG_EXTENDED | REG_ICASE | REG_NOSUB) == 0)
+ patterns.push_back(p);
+ else
+ {
+ regfree(p);
+ delete p;
+ _error->Warning("Regex compilation error for '%s' in configuration option '%s'",
+ s->c_str(), Config);
+ }
+ }
+
+}
+ /*}}}*/
+// MatchAgainstConfig Destructor /*{{{*/
+Configuration::MatchAgainstConfig::~MatchAgainstConfig()
+{
+ for(std::vector<regex_t *>::const_iterator p = patterns.begin();
+ p != patterns.end(); ++p)
+ {
+ regfree(*p);
+ delete *p;
+ }
+}
+ /*}}}*/
+// MatchAgainstConfig::Match - returns true if a pattern matches /*{{{*/
+bool Configuration::MatchAgainstConfig::Match(char const * str) const
+{
+ for(std::vector<regex_t *>::const_iterator p = patterns.begin();
+ p != patterns.end(); ++p)
+ if (regexec(*p, str, 0, 0, 0) == 0)
+ return true;
+
+ return false;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/configuration.h b/apt-pkg/contrib/configuration.h
index 2494c1d7c..cbe18e4e5 100644
--- a/apt-pkg/contrib/configuration.h
+++ b/apt-pkg/contrib/configuration.h
@@ -28,7 +28,7 @@
#ifndef PKGLIB_CONFIGURATION_H
#define PKGLIB_CONFIGURATION_H
-
+#include <regex.h>
#include <string>
#include <vector>
@@ -104,6 +104,23 @@ class Configuration
Configuration(const Item *Root);
Configuration();
~Configuration();
+
+ /** \brief match a string against a configurable list of patterns */
+ class MatchAgainstConfig
+ {
+ std::vector<regex_t *> patterns;
+
+ public:
+ MatchAgainstConfig(char const * Config);
+ virtual ~MatchAgainstConfig();
+
+ /** \brief Returns \b true for a string matching one of the patterns */
+ bool Match(char const * str) const;
+ bool Match(std::string const &str) const { return Match(str.c_str()); };
+
+ /** \brief returns if the matcher setup was successful */
+ bool wasConstructedSuccessfully() const { return patterns.empty() == false; }
+ };
};
extern Configuration *_config;
diff --git a/apt-pkg/contrib/error.cc b/apt-pkg/contrib/error.cc
index 927b7e05c..8cee21c9c 100644
--- a/apt-pkg/contrib/error.cc
+++ b/apt-pkg/contrib/error.cc
@@ -1,16 +1,15 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: error.cc,v 1.11 2002/03/26 07:38:58 jgg Exp $
/* ######################################################################
-
- Global Erorr Class - Global error mechanism
+
+ Global Error Class - Global error mechanism
We use a simple STL vector to store each error record. A PendingFlag
is kept which indicates when the vector contains a Sever error.
-
+
This source is placed in the Public Domain, do with it what you will
It was originally written by Jason Gunthorpe.
-
+
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
@@ -19,7 +18,6 @@
#include <iostream>
#include <errno.h>
#include <stdio.h>
-#include <stdarg.h>
#include <unistd.h>
#include <string>
@@ -28,209 +26,218 @@
#include "config.h"
/*}}}*/
-using namespace std;
-
// Global Error Object /*{{{*/
/* If the implementation supports posix threads then the accessor function
is compiled to be thread safe otherwise a non-safe version is used. A
Per-Thread error object is maintained in much the same manner as libc
manages errno */
#if defined(_POSIX_THREADS) && defined(HAVE_PTHREAD)
- #include <pthread.h>
-
- static pthread_key_t ErrorKey;
- static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;};
- static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);};
-
- GlobalError *_GetErrorObj()
- {
- static pthread_once_t Once = PTHREAD_ONCE_INIT;
- pthread_once(&Once,KeyAlloc);
-
- void *Res = pthread_getspecific(ErrorKey);
- if (Res == 0)
- pthread_setspecific(ErrorKey,Res = new GlobalError);
- return (GlobalError *)Res;
- }
+ #include <pthread.h>
+
+ static pthread_key_t ErrorKey;
+ static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;};
+ static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);};
+
+ GlobalError *_GetErrorObj() {
+ static pthread_once_t Once = PTHREAD_ONCE_INIT;
+ pthread_once(&Once,KeyAlloc);
+
+ void *Res = pthread_getspecific(ErrorKey);
+ if (Res == 0)
+ pthread_setspecific(ErrorKey,Res = new GlobalError);
+ return (GlobalError *)Res;
+ }
#else
- GlobalError *_GetErrorObj()
- {
- static GlobalError *Obj = new GlobalError;
- return Obj;
- }
+ GlobalError *_GetErrorObj() {
+ static GlobalError *Obj = new GlobalError;
+ return Obj;
+ }
#endif
/*}}}*/
-
// GlobalError::GlobalError - Constructor /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-GlobalError::GlobalError() : List(0), PendingFlag(false)
-{
+GlobalError::GlobalError() : PendingFlag(false) {}
+ /*}}}*/
+// GlobalError::FatalE - Get part of the error string from errno /*{{{*/
+bool GlobalError::FatalE(const char *Function,const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return InsertErrno(FATAL, Function, Description, args);
}
/*}}}*/
// GlobalError::Errno - Get part of the error string from errno /*{{{*/
-// ---------------------------------------------------------------------
-/* Function indicates the stdlib function that failed and Description is
- a user string that leads the text. Form is:
- Description - Function (errno: strerror)
- Carefull of the buffer overrun, sprintf.
- */
-bool GlobalError::Errno(const char *Function,const char *Description,...)
-{
- va_list args;
- va_start(args,Description);
-
- // sprintf the description
- char S[400];
- vsnprintf(S,sizeof(S),Description,args);
- snprintf(S + strlen(S),sizeof(S) - strlen(S),
- " - %s (%i: %s)",Function,errno,strerror(errno));
-
- // Put it on the list
- Item *Itm = new Item;
- Itm->Text = S;
- Itm->Error = true;
- Insert(Itm);
-
- PendingFlag = true;
-
- return false;
-}
- /*}}}*/
-// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/
-// ---------------------------------------------------------------------
-/* Function indicates the stdlib function that failed and Description is
- a user string that leads the text. Form is:
- Description - Function (errno: strerror)
- Carefull of the buffer overrun, sprintf.
- */
-bool GlobalError::WarningE(const char *Function,const char *Description,...)
-{
- va_list args;
- va_start(args,Description);
-
- // sprintf the description
- char S[400];
- vsnprintf(S,sizeof(S),Description,args);
- snprintf(S + strlen(S),sizeof(S) - strlen(S),
- " - %s (%i: %s)",Function,errno,strerror(errno));
-
- // Put it on the list
- Item *Itm = new Item;
- Itm->Text = S;
- Itm->Error = false;
- Insert(Itm);
-
- return false;
+bool GlobalError::Errno(const char *Function,const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return InsertErrno(ERROR, Function, Description, args);
+}
+ /*}}}*/
+// GlobalError::WarningE - Get part of the warning string from errno /*{{{*/
+bool GlobalError::WarningE(const char *Function,const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return InsertErrno(WARNING, Function, Description, args);
+}
+ /*}}}*/
+// GlobalError::NoticeE - Get part of the notice string from errno /*{{{*/
+bool GlobalError::NoticeE(const char *Function,const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return InsertErrno(NOTICE, Function, Description, args);
+}
+ /*}}}*/
+// GlobalError::DebugE - Get part of the debug string from errno /*{{{*/
+bool GlobalError::DebugE(const char *Function,const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return InsertErrno(DEBUG, Function, Description, args);
+}
+ /*}}}*/
+// GlobalError::InsertErrno - formats an error message with the errno /*{{{*/
+bool GlobalError::InsertErrno(MsgType type, const char* Function,
+ const char* Description, va_list const &args) {
+ char S[400];
+ vsnprintf(S,sizeof(S),Description,args);
+ snprintf(S + strlen(S),sizeof(S) - strlen(S),
+ " - %s (%i: %s)", Function, errno, strerror(errno));
+ return Insert(type, S, args);
+}
+ /*}}}*/
+// GlobalError::Fatal - Add a fatal error to the list /*{{{*/
+bool GlobalError::Fatal(const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return Insert(FATAL, Description, args);
}
/*}}}*/
// GlobalError::Error - Add an error to the list /*{{{*/
-// ---------------------------------------------------------------------
-/* Just vsprintfs and pushes */
-bool GlobalError::Error(const char *Description,...)
-{
- va_list args;
- va_start(args,Description);
-
- // sprintf the description
- char S[400];
- vsnprintf(S,sizeof(S),Description,args);
-
- // Put it on the list
- Item *Itm = new Item;
- Itm->Text = S;
- Itm->Error = true;
- Insert(Itm);
-
- PendingFlag = true;
-
- return false;
+bool GlobalError::Error(const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return Insert(ERROR, Description, args);
}
/*}}}*/
// GlobalError::Warning - Add a warning to the list /*{{{*/
-// ---------------------------------------------------------------------
-/* This doesn't set the pending error flag */
-bool GlobalError::Warning(const char *Description,...)
+bool GlobalError::Warning(const char *Description,...) {
+ va_list args;
+ va_start(args,Description);
+ return Insert(WARNING, Description, args);
+}
+ /*}}}*/
+// GlobalError::Notice - Add a notice to the list /*{{{*/
+bool GlobalError::Notice(const char *Description,...)
{
- va_list args;
- va_start(args,Description);
+ va_list args;
+ va_start(args,Description);
+ return Insert(NOTICE, Description, args);
+}
+ /*}}}*/
+// GlobalError::Debug - Add a debug to the list /*{{{*/
+bool GlobalError::Debug(const char *Description,...)
+{
+ va_list args;
+ va_start(args,Description);
+ return Insert(DEBUG, Description, args);
+}
+ /*}}}*/
+// GlobalError::Insert - Insert a new item at the end /*{{{*/
+bool GlobalError::Insert(MsgType type, const char* Description,
+ va_list const &args) {
+ char S[400];
+ vsnprintf(S,sizeof(S),Description,args);
+
+ Item const m(S, type);
+ Messages.push_back(m);
+
+ if (type == ERROR || type == FATAL)
+ PendingFlag = true;
- // sprintf the description
- char S[400];
- vsnprintf(S,sizeof(S),Description,args);
+ if (type == FATAL || type == DEBUG)
+ std::clog << m << std::endl;
- // Put it on the list
- Item *Itm = new Item;
- Itm->Text = S;
- Itm->Error = false;
- Insert(Itm);
-
- return false;
+ return false;
}
/*}}}*/
// GlobalError::PopMessage - Pulls a single message out /*{{{*/
-// ---------------------------------------------------------------------
-/* This should be used in a loop checking empty() each cycle. It returns
- true if the message is an error. */
-bool GlobalError::PopMessage(string &Text)
-{
- if (List == 0)
- return false;
-
- bool Ret = List->Error;
- Text = List->Text;
- Item *Old = List;
- List = List->Next;
- delete Old;
-
- // This really should check the list to see if only warnings are left..
- if (List == 0)
- PendingFlag = false;
-
- return Ret;
+bool GlobalError::PopMessage(std::string &Text) {
+ if (Messages.empty() == true)
+ return false;
+
+ Item const msg = Messages.front();
+ Messages.pop_front();
+
+ bool const Ret = (msg.Type == ERROR || msg.Type == FATAL);
+ Text = msg.Text;
+ if (PendingFlag == false || Ret == false)
+ return Ret;
+
+ // check if another error message is pending
+ for (std::list<Item>::const_iterator m = Messages.begin();
+ m != Messages.end(); m++)
+ if (m->Type == ERROR || m->Type == FATAL)
+ return Ret;
+
+ PendingFlag = false;
+ return Ret;
}
/*}}}*/
// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void GlobalError::DumpErrors()
-{
- // Print any errors or warnings found
- string Err;
- while (empty() == false)
- {
- bool Type = PopMessage(Err);
- if (Type == true)
- cerr << "E: " << Err << endl;
- else
- cerr << "W: " << Err << endl;
- }
-}
- /*}}}*/
-// GlobalError::Discard - Discard /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void GlobalError::Discard()
-{
- while (List != 0)
- {
- Item *Old = List;
- List = List->Next;
- delete Old;
- }
-
- PendingFlag = false;
+void GlobalError::DumpErrors(std::ostream &out, MsgType const &trashhold,
+ bool const &mergeStack) {
+ if (mergeStack == true)
+ for (std::list<MsgStack>::const_reverse_iterator s = Stacks.rbegin();
+ s != Stacks.rend(); ++s)
+ Messages.insert(Messages.begin(), s->Messages.begin(), s->Messages.end());
+
+ for (std::list<Item>::const_iterator m = Messages.begin();
+ m != Messages.end(); m++)
+ if (m->Type >= trashhold)
+ out << (*m) << std::endl;
+ Discard();
+}
+ /*}}}*/
+// GlobalError::Discard - Discard /*{{{*/
+void GlobalError::Discard() {
+ Messages.clear();
+ PendingFlag = false;
};
/*}}}*/
-// GlobalError::Insert - Insert a new item at the end /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void GlobalError::Insert(Item *Itm)
-{
- Item **End = &List;
- for (Item *I = List; I != 0; I = I->Next)
- End = &I->Next;
- Itm->Next = *End;
- *End = Itm;
+// GlobalError::empty - does our error list include anything? /*{{{*/
+bool GlobalError::empty(MsgType const &trashhold) const {
+ if (PendingFlag == true)
+ return false;
+
+ if (Messages.empty() == true)
+ return true;
+
+ for (std::list<Item>::const_iterator m = Messages.begin();
+ m != Messages.end(); m++)
+ if (m->Type >= trashhold)
+ return false;
+
+ return true;
+}
+ /*}}}*/
+// GlobalError::PushToStack /*{{{*/
+void GlobalError::PushToStack() {
+ MsgStack pack(Messages, PendingFlag);
+ Stacks.push_back(pack);
+ Discard();
+}
+ /*}}}*/
+// GlobalError::RevertToStack /*{{{*/
+void GlobalError::RevertToStack() {
+ Discard();
+ MsgStack pack = Stacks.back();
+ Messages = pack.Messages;
+ PendingFlag = pack.PendingFlag;
+ Stacks.pop_back();
+}
+ /*}}}*/
+// GlobalError::MergeWithStack /*{{{*/
+void GlobalError::MergeWithStack() {
+ MsgStack pack = Stacks.back();
+ Messages.insert(Messages.begin(), pack.Messages.begin(), pack.Messages.end());
+ PendingFlag = PendingFlag || pack.PendingFlag;
+ Stacks.pop_back();
}
/*}}}*/
diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h
index 8d5ec05ea..73735162d 100644
--- a/apt-pkg/contrib/error.h
+++ b/apt-pkg/contrib/error.h
@@ -42,43 +42,248 @@
#include <apt-pkg/macros.h>
+#include <iostream>
+#include <list>
#include <string>
-class GlobalError
+#include <stdarg.h>
+
+class GlobalError /*{{{*/
{
- struct Item
- {
- std::string Text;
- bool Error;
- Item *Next;
- };
-
- Item *List;
- bool PendingFlag;
- void Insert(Item *I);
-
- public:
+public: /*{{{*/
+ /** \brief a message can have one of following severity */
+ enum MsgType {
+ /** \brief Message will be printed instantly as it is likely that
+ this error will lead to a complete crash */
+ FATAL = 40,
+ /** \brief An error does hinder the correct execution and should be corrected */
+ ERROR = 30,
+ /** \brief indicates problem that can lead to errors later on */
+ WARNING = 20,
+ /** \brief deprecation warnings, old fallback behavior, … */
+ NOTICE = 10,
+ /** \brief for developers only in areas it is hard to print something directly */
+ DEBUG = 0
+ };
- // Call to generate an error from a library call.
- bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold;
- bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+ /** \brief add a fatal error message with errno to the list
+ *
+ * \param Function name of the function generating the error
+ * \param Description format string for the error message
+ *
+ * \return \b false
+ */
+ bool FatalE(const char *Function,const char *Description,...) __like_printf(3) __cold;
- /* A warning should be considered less severe than an error, and may be
- ignored by the client. */
- bool Error(const char *Description,...) __like_printf(2) __cold;
- bool Warning(const char *Description,...) __like_printf(2) __cold;
+ /** \brief add an Error message with errno to the list
+ *
+ * \param Function name of the function generating the error
+ * \param Description format string for the error message
+ *
+ * \return \b false
+ */
+ bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold;
- // Simple accessors
- inline bool PendingError() {return PendingFlag;};
- inline bool empty() {return List == 0;};
- bool PopMessage(std::string &Text);
- void Discard();
+ /** \brief add a warning message with errno to the list
+ *
+ * A warning should be considered less severe than an error and
+ * may be ignored by the client.
+ *
+ * \param Function Name of the function generates the warning.
+ * \param Description Format string for the warning message.
+ *
+ * \return \b false
+ */
+ bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold;
- // Usefull routine to dump to cerr
- void DumpErrors();
-
- GlobalError();
+ /** \brief add a notice message with errno to the list
+ *
+ * \param Function name of the function generating the error
+ * \param Description format string for the error message
+ *
+ * \return \b false
+ */
+ bool NoticeE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+
+ /** \brief add a debug message with errno to the list
+ *
+ * \param Function name of the function generating the error
+ * \param Description format string for the error message
+ *
+ * \return \b false
+ */
+ bool DebugE(const char *Function,const char *Description,...) __like_printf(3) __cold;
+
+ /** \brief add an fatal error message to the list
+ *
+ * Most of the stuff we consider as "error" is also "fatal" for
+ * the user as the application will not have the expected result,
+ * but a fatal message here means that it gets printed directly
+ * to stderr in addiction to adding it to the list as the error
+ * leads sometimes to crashes and a maybe duplicated message
+ * is better than "Segfault" as the only displayed text
+ *
+ * \param Description Format string for the fatal error message.
+ *
+ * \return \b false
+ */
+ bool Fatal(const char *Description,...) __like_printf(2) __cold;
+
+ /** \brief add an Error message to the list
+ *
+ * \param Description Format string for the error message.
+ *
+ * \return \b false
+ */
+ bool Error(const char *Description,...) __like_printf(2) __cold;
+
+ /** \brief add a warning message to the list
+ *
+ * A warning should be considered less severe than an error and
+ * may be ignored by the client.
+ *
+ * \param Description Format string for the message
+ *
+ * \return \b false
+ */
+ bool Warning(const char *Description,...) __like_printf(2) __cold;
+
+ /** \brief add a notice message to the list
+ *
+ * A notice should be considered less severe than an error or a
+ * warning and can be ignored by the client without further problems
+ * for some times, but he should consider fixing the problem.
+ * This error type can be used for e.g. deprecation warnings of options.
+ *
+ * \param Description Format string for the message
+ *
+ * \return \b false
+ */
+ bool Notice(const char *Description,...) __like_printf(2) __cold;
+
+ /** \brief add a debug message to the list
+ *
+ * \param Description Format string for the message
+ *
+ * \return \b false
+ */
+ bool Debug(const char *Description,...) __like_printf(2) __cold;
+
+ /** \brief is an error in the list?
+ *
+ * \return \b true if an error is included in the list, \b false otherwise
+ */
+ inline bool PendingError() const {return PendingFlag;};
+
+ /** \brief is the list empty?
+ *
+ * The default checks if the list is empty or contains only notices,
+ * if you want to check if also no notices happend set the parameter
+ * flag to \b false.
+ *
+ * \param WithoutNotice does notices count, default is \b true, so no
+ *
+ * \return \b true if an the list is empty, \b false otherwise
+ */
+ bool empty(MsgType const &trashhold = WARNING) const;
+
+ /** \brief returns and removes the first (or last) message in the list
+ *
+ * \param[out] Text message of the first/last item
+ *
+ * \return \b true if the message was an error, \b false otherwise
+ */
+ bool PopMessage(std::string &Text);
+
+ /** \brief clears the list of messages */
+ void Discard();
+
+ /** \brief outputs the list of messages to the given stream
+ *
+ * Note that all messages are discarded, also the notices
+ * displayed or not.
+ *
+ * \param[out] out output stream to write the messages in
+ * \param WithoutNotice output notices or not
+ */
+ void DumpErrors(std::ostream &out, MsgType const &trashhold = WARNING,
+ bool const &mergeStack = true);
+
+ /** \brief dumps the list of messages to std::cerr
+ *
+ * Note that all messages are discarded, also the notices
+ * displayed or not.
+ *
+ * \param WithoutNotice print notices or not
+ */
+ void inline DumpErrors(MsgType const &trashhold = WARNING) {
+ DumpErrors(std::cerr, trashhold);
+ }
+
+ /** \brief put the current Messages into the stack
+ *
+ * All "old" messages will be pushed into a stack to
+ * them later back, but for now the Message query will be
+ * empty and performs as no messages were present before.
+ *
+ * The stack can be as deep as you want - all stack operations
+ * will only operate on the last element in the stack.
+ */
+ void PushToStack();
+
+ /** \brief throw away all current messages */
+ void RevertToStack();
+
+ /** \brief merge current and stack together */
+ void MergeWithStack();
+
+ /** \brief return the deep of the stack */
+ size_t StackCount() const {
+ return Stacks.size();
+ }
+
+ GlobalError();
+ /*}}}*/
+private: /*{{{*/
+ struct Item {
+ std::string Text;
+ MsgType Type;
+
+ Item(char const *Text, MsgType const &Type) :
+ Text(Text), Type(Type) {};
+
+ friend std::ostream& operator<< (std::ostream &out, Item i) {
+ switch(i.Type) {
+ case FATAL:
+ case ERROR: out << "E"; break;
+ case WARNING: out << "W"; break;
+ case NOTICE: out << "N"; break;
+ case DEBUG: out << "D"; break;
+ }
+ return out << ": " << i.Text;
+ }
+ };
+
+ std::list<Item> Messages;
+ bool PendingFlag;
+
+ struct MsgStack {
+ std::list<Item> const Messages;
+ bool const PendingFlag;
+
+ MsgStack(std::list<Item> const &Messages, bool const &Pending) :
+ Messages(Messages), PendingFlag(Pending) {};
+ };
+
+ std::list<MsgStack> Stacks;
+
+ bool InsertErrno(MsgType type, const char* Function,
+ const char* Description, va_list const &args);
+ bool Insert(MsgType type, const char* Description,
+ va_list const &args);
+ /*}}}*/
};
+ /*}}}*/
// The 'extra-ansi' syntax is used to help with collisions.
GlobalError *_GetErrorObj();
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index 0b62d1bd8..62d42e4da 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -282,6 +282,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
}
std::vector<string> List;
+ Configuration::MatchAgainstConfig SilentIgnore("Dir::Ignore-Files-Silently");
DIR *D = opendir(Dir.c_str());
if (D == 0)
{
@@ -307,6 +308,7 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
{
if (Debug == true)
std::clog << "Bad file: " << Ent->d_name << " → no extension" << std::endl;
+ _error->Notice("Ignoring file '%s' in directory '%s' as it has no filename extension", Ent->d_name, Dir.c_str());
continue;
}
}
@@ -314,6 +316,8 @@ std::vector<string> GetListOfFilesInDir(string const &Dir, std::vector<string> c
{
if (Debug == true)
std::clog << "Bad file: " << Ent->d_name << " → bad extension »" << flExtension(Ent->d_name) << "«" << std::endl;
+ if (SilentIgnore.Match(Ent->d_name) == false)
+ _error->Notice("Ignoring file '%s' in directory '%s' as it has an invalid filename extension", Ent->d_name, Dir.c_str());
continue;
}
}
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index d233e51bc..aa184b130 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -225,22 +225,22 @@ DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long const &WorkSpace,
// disable Moveable if we don't grow
if (Grow == 0)
- Flags &= ~Moveable;
+ this->Flags &= ~Moveable;
#ifndef __linux__
// kfreebsd doesn't have mremap, so we use the fallback
- if ((Flags & Moveable) == Moveable)
- Flags |= Fallback;
+ if ((this->Flags & Moveable) == Moveable)
+ this->Flags |= Fallback;
#endif
#ifdef _POSIX_MAPPED_FILES
- if ((Flags & Fallback) != Fallback) {
+ if ((this->Flags & Fallback) != Fallback) {
// Set the permissions.
int Prot = PROT_READ;
int Map = MAP_PRIVATE | MAP_ANONYMOUS;
- if ((Flags & ReadOnly) != ReadOnly)
+ if ((this->Flags & ReadOnly) != ReadOnly)
Prot |= PROT_WRITE;
- if ((Flags & Public) == Public)
+ if ((this->Flags & Public) == Public)
Map = MAP_SHARED | MAP_ANONYMOUS;
// use anonymous mmap() to get the memory
@@ -297,7 +297,7 @@ unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln)
{
if(!Grow())
{
- _error->Error(_("Dynamic MMap ran out of room. Please increase the size "
+ _error->Fatal(_("Dynamic MMap ran out of room. Please increase the size "
"of APT::Cache-Limit. Current value: %lu. (man 5 apt.conf)"), WorkSpace);
return 0;
}
@@ -314,7 +314,7 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
// Look for a matching pool entry
Pool *I;
Pool *Empty = 0;
- for (I = Pools; I != Pools + PoolCount; I++)
+ for (I = Pools; I != Pools + PoolCount; ++I)
{
if (I->ItemSize == 0)
Empty = I;
@@ -342,7 +342,11 @@ unsigned long DynamicMMap::Allocate(unsigned long ItemSize)
{
const unsigned long size = 20*1024;
I->Count = size/ItemSize;
+ Pool* oldPools = Pools;
Result = RawAllocate(size,ItemSize);
+ if (Pools != oldPools)
+ I += Pools - oldPools;
+
// Does the allocation failed ?
if (Result == 0 && _error->PendingError())
return 0;
@@ -365,7 +369,7 @@ unsigned long DynamicMMap::WriteString(const char *String,
if (Len == (unsigned long)-1)
Len = strlen(String);
- unsigned long Result = RawAllocate(Len+1,0);
+ unsigned long const Result = RawAllocate(Len+1,0);
if (Result == 0 && _error->PendingError())
return 0;
@@ -395,16 +399,20 @@ bool DynamicMMap::Grow() {
return _error->Error(_("Unable to increase the size of the MMap as the "
"limit of %lu bytes is already reached."), Limit);
- unsigned long const newSize = WorkSpace + 1024*1024;
+ unsigned long const newSize = WorkSpace + GrowFactor;
if(Fd != 0) {
Fd->Seek(newSize - 1);
char C = 0;
Fd->Write(&C,sizeof(C));
}
+
+ unsigned long const poolOffset = Pools - ((Pool*) Base);
+
if ((Flags & Fallback) != Fallback) {
#if defined(_POSIX_MAPPED_FILES) && defined(__linux__)
#ifdef MREMAP_MAYMOVE
+
if ((Flags & Moveable) == Moveable)
Base = mremap(Base, WorkSpace, newSize, MREMAP_MAYMOVE);
else
@@ -425,6 +433,7 @@ bool DynamicMMap::Grow() {
return false;
}
+ Pools =(Pool*) Base + poolOffset;
WorkSpace = newSize;
return true;
}
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 6d9e99497..5e6db3f38 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -277,6 +277,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
// Store the IMS information
pkgCache::PkgFileIterator File = Gen.GetCurFile();
+ pkgCacheGenerator::Dynamic<pkgCache::PkgFileIterator> DynFile(File);
struct stat St;
if (fstat(Pkg.Fd(),&St) != 0)
return _error->Errno("fstat","Failed to stat");
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 6ede14c4d..2cfeb23e9 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -39,6 +39,8 @@ debListParser::debListParser(FileFd *File, string const &Arch) : Tags(File),
Arch(Arch) {
if (Arch == "native")
this->Arch = _config->Find("APT::Architecture");
+ Architectures = APT::Configuration::getArchitectures();
+ MultiArchEnabled = Architectures.size() > 1;
}
/*}}}*/
// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/
@@ -104,7 +106,7 @@ string debListParser::Version()
// ListParser::NewVersion - Fill in the version structure /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool debListParser::NewVersion(pkgCache::VerIterator Ver)
+bool debListParser::NewVersion(pkgCache::VerIterator &Ver)
{
// Parse the section
Ver->Section = UniqFindTagWrite("Section");
@@ -156,10 +158,9 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
to a NOP in the download/install step - this package will ensure that
it is downloaded only one time and installed only one time -- even if
the architecture bound versions coming in and out on regular basis. */
- bool const static multiArch = APT::Configuration::getArchitectures().size() > 1;
if (strcmp(Ver.Arch(true),"all") == 0)
return true;
- else if (multiArch == true)
+ else if (MultiArchEnabled == true)
{
// our pseudo packages have no size to not confuse the fetcher
Ver->Size = 0;
@@ -250,8 +251,8 @@ MD5SumValue debListParser::Description_md5()
// ---------------------------------------------------------------------
/* This is called to update the package with any new information
that might be found in the section */
-bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
- pkgCache::VerIterator Ver)
+bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver)
{
if (Pkg->Section == 0)
Pkg->Section = UniqFindTagWrite("Section");
@@ -331,8 +332,8 @@ unsigned short debListParser::VersionHash()
Some of the above are obsolete (I think?) flag = hold-* and
status = post-inst-failed, removal-failed at least.
*/
-bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg,
- pkgCache::VerIterator Ver)
+bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver)
{
const char *Start;
const char *Stop;
@@ -633,7 +634,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
// ---------------------------------------------------------------------
/* This is the higher level depends parser. It takes a tag and generates
a complete depends tree for the given version. */
-bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
+bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
const char *Tag,unsigned int Type)
{
const char *Start;
@@ -641,9 +642,6 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
if (Section.Find(Tag,Start,Stop) == false)
return true;
- static std::vector<std::string> const archs = APT::Configuration::getArchitectures();
- static bool const multiArch = archs.size() <= 1;
-
string Package;
string const pkgArch = Ver.Arch(true);
string Version;
@@ -655,13 +653,13 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
if (Start == 0)
return _error->Error("Problem parsing dependency %s",Tag);
- if (multiArch == true &&
+ if (MultiArchEnabled == true &&
(Type == pkgCache::Dep::Conflicts ||
Type == pkgCache::Dep::DpkgBreaks ||
Type == pkgCache::Dep::Replaces))
{
- for (std::vector<std::string>::const_iterator a = archs.begin();
- a != archs.end(); ++a)
+ for (std::vector<std::string>::const_iterator a = Architectures.begin();
+ a != Architectures.end(); ++a)
if (NewDepends(Ver,Package,*a,Version,Op,Type) == false)
return false;
}
@@ -676,7 +674,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
// ListParser::ParseProvides - Parse the provides list /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
+bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
{
const char *Start;
const char *Stop;
@@ -713,14 +711,13 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
if (Ver->MultiArch != pkgCache::Version::Foreign)
return true;
- std::vector<string> const archs = APT::Configuration::getArchitectures();
- if (archs.size() <= 1)
+ if (MultiArchEnabled == false)
return true;
string const Package = Ver.ParentPkg().Name();
string const Version = Ver.VerStr();
- for (std::vector<string>::const_iterator a = archs.begin();
- a != archs.end(); ++a)
+ for (std::vector<string>::const_iterator a = Architectures.begin();
+ a != Architectures.end(); ++a)
{
if (NewProvides(Ver, Package, *a, Version) == false)
return false;
@@ -760,7 +757,7 @@ bool debListParser::Step()
if (Architecture.empty() == true)
return true;
- if (Arch.empty() == true)
+ if (Arch.empty() == true || MultiArchEnabled == false)
{
if (APT::Configuration::checkArchitecture(Architecture) == true)
return true;
@@ -782,7 +779,7 @@ bool debListParser::Step()
// ListParser::LoadReleaseInfo - Load the release information /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
+bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
FileFd &File, string component)
{
pkgTagFile Tags(&File, File.Size() + 256); // XXX
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 8da051530..4bc1bd93c 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -32,12 +32,14 @@ class debListParser : public pkgCacheGenerator::ListParser
pkgTagSection Section;
unsigned long iOffset;
string Arch;
-
+ std::vector<std::string> Architectures;
+ bool MultiArchEnabled;
+
unsigned long UniqFindTagWrite(const char *Tag);
- bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver);
- bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag,
+ bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
+ bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
unsigned int Type);
- bool ParseProvides(pkgCache::VerIterator Ver);
+ bool ParseProvides(pkgCache::VerIterator &Ver);
static bool GrabWord(string Word,WordList *List,unsigned char &Out);
public:
@@ -49,19 +51,19 @@ class debListParser : public pkgCacheGenerator::ListParser
virtual string Architecture();
virtual bool ArchitectureAll();
virtual string Version();
- virtual bool NewVersion(pkgCache::VerIterator Ver);
+ virtual bool NewVersion(pkgCache::VerIterator &Ver);
virtual string Description();
virtual string DescriptionLanguage();
virtual MD5SumValue Description_md5();
virtual unsigned short VersionHash();
- virtual bool UsePackage(pkgCache::PkgIterator Pkg,
- pkgCache::VerIterator Ver);
+ virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver);
virtual unsigned long Offset() {return iOffset;};
virtual unsigned long Size() {return Section.size();};
virtual bool Step();
- bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File,
+ bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
string section);
static const char *ParseDepends(const char *Start,const char *Stop,
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 3ae5f5953..05127fe18 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -1255,6 +1255,10 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
Update(Pkg);
AddSizes(Pkg);
+ // always trigger the install of the all package for a pseudo package
+ if (P.CandidateVerIter(*Cache).Pseudo() == true)
+ MarkInstall(Pkg.Group().FindPkg("all"), AutoInst, Depth, FromUser, ForceImportantDeps);
+
if (AutoInst == false)
return;
@@ -1453,6 +1457,9 @@ bool pkgDepCache::IsInstallOk(PkgIterator const &Pkg,bool AutoInst,
/* */
void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
{
+ if (unlikely(Pkg.end() == true))
+ return;
+
ActionGroup group(*this);
RemoveSizes(Pkg);
@@ -1466,12 +1473,17 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
AddStates(Pkg);
AddSizes(Pkg);
+
+ if (unlikely(Pkg.CurrentVer().end() == true) || Pkg.CurrentVer().Pseudo() == false)
+ return;
+
+ SetReInstall(Pkg.Group().FindPkg("all"), To);
}
/*}}}*/
// DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
// ---------------------------------------------------------------------
/* */
-void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
+void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo)
{
ActionGroup group(*this);
@@ -1489,6 +1501,28 @@ void pkgDepCache::SetCandidateVersion(VerIterator TargetVer)
AddStates(Pkg);
Update(Pkg);
AddSizes(Pkg);
+
+ if (TargetVer.Pseudo() == false || Pseudo == false)
+ return;
+
+ // the version was pseudo: set all other pseudos also
+ pkgCache::GrpIterator Grp = Pkg.Group();
+ for (Pkg = Grp.FindPkg("any"); Pkg.end() == false; ++Pkg)
+ {
+ StateCache &P = PkgState[Pkg->ID];
+ if (TargetVer.SimilarVer(P.CandidateVerIter(*this)) == true ||
+ (P.CandidateVerIter(*this).Pseudo() == false &&
+ strcmp(Pkg.Arch(), "all") != 0))
+ continue;
+
+ for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver)
+ {
+ if (TargetVer.SimilarVer(Ver) == false)
+ continue;
+ SetCandidateVersion(Ver, false);
+ break;
+ }
+ }
}
void pkgDepCache::MarkAuto(const PkgIterator &Pkg, bool Auto)
@@ -1551,7 +1585,7 @@ const char *pkgDepCache::StateCache::StripEpoch(const char *Ver)
// ---------------------------------------------------------------------
/* The default just returns the highest available version that is not
a source and automatic. */
-pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
+pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator const &Pkg)
{
/* Not source/not automatic versions cannot be a candidate version
unless they are already installed */
@@ -1586,7 +1620,7 @@ pkgCache::VerIterator pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg)
// Policy::IsImportantDep - True if the dependency is important /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
+bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep)
{
if(Dep.IsCritical())
return true;
@@ -1608,54 +1642,6 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep)
return false;
}
/*}}}*/
-pkgDepCache::DefaultRootSetFunc::DefaultRootSetFunc() /*{{{*/
- : constructedSuccessfully(false)
-{
- Configuration::Item const *Opts;
- Opts = _config->Tree("APT::NeverAutoRemove");
- if (Opts != 0 && Opts->Child != 0)
- {
- Opts = Opts->Child;
- for (; Opts != 0; Opts = Opts->Next)
- {
- if (Opts->Value.empty() == true)
- continue;
-
- regex_t *p = new regex_t;
- if(regcomp(p,Opts->Value.c_str(),
- REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
- {
- regfree(p);
- delete p;
- _error->Error("Regex compilation error for APT::NeverAutoRemove");
- return;
- }
-
- rootSetRegexp.push_back(p);
- }
- }
-
- constructedSuccessfully = true;
-}
- /*}}}*/
-pkgDepCache::DefaultRootSetFunc::~DefaultRootSetFunc() /*{{{*/
-{
- for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
- {
- regfree(rootSetRegexp[i]);
- delete rootSetRegexp[i];
- }
-}
- /*}}}*/
-bool pkgDepCache::DefaultRootSetFunc::InRootSet(const pkgCache::PkgIterator &pkg) /*{{{*/
-{
- for(unsigned int i = 0; i < rootSetRegexp.size(); i++)
- if (regexec(rootSetRegexp[i], pkg.Name(), 0, 0, 0) == 0)
- return true;
-
- return false;
-}
- /*}}}*/
pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() /*{{{*/
{
DefaultRootSetFunc *f = new DefaultRootSetFunc;
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index c6f245a80..45276dc95 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -38,11 +38,10 @@
#ifndef PKGLIB_DEPCACHE_H
#define PKGLIB_DEPCACHE_H
-
+#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/progress.h>
-
-#include <regex.h>
+#include <apt-pkg/error.h>
#include <vector>
#include <memory>
@@ -184,22 +183,13 @@ class pkgDepCache : protected pkgCache::Namespace
/** \brief Returns \b true for packages matching a regular
* expression in APT::NeverAutoRemove.
*/
- class DefaultRootSetFunc : public InRootSetFunc
+ class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig
{
- std::vector<regex_t *> rootSetRegexp;
- bool constructedSuccessfully;
-
public:
- DefaultRootSetFunc();
- ~DefaultRootSetFunc();
-
- /** \return \b true if the class initialized successfully, \b
- * false otherwise. Used to avoid throwing an exception, since
- * APT classes generally don't.
- */
- bool wasConstructedSuccessfully() const { return constructedSuccessfully; }
+ DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverRemove") {};
+ virtual ~DefaultRootSetFunc() {};
- bool InRootSet(const pkgCache::PkgIterator &pkg);
+ bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == true && Match(pkg.Name()); };
};
struct StateCache
@@ -266,8 +256,8 @@ class pkgDepCache : protected pkgCache::Namespace
{
public:
- virtual VerIterator GetCandidateVer(PkgIterator Pkg);
- virtual bool IsImportantDep(DepIterator Dep);
+ virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
+ virtual bool IsImportantDep(DepIterator const &Dep);
virtual ~Policy() {};
};
@@ -344,7 +334,7 @@ class pkgDepCache : protected pkgCache::Namespace
inline pkgVersioningSystem &VS() {return *Cache->VS;};
// Policy implementation
- inline VerIterator GetCandidateVer(PkgIterator Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
+ inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
inline Policy &GetPolicy() {return *LocalPolicy;};
@@ -405,7 +395,7 @@ class pkgDepCache : protected pkgCache::Namespace
bool ForceImportantDeps = false);
void SetReInstall(PkgIterator const &Pkg,bool To);
- void SetCandidateVersion(VerIterator TargetVer);
+ void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true);
/** Set the "is automatically installed" flag of Pkg. */
void MarkAuto(const PkgIterator &Pkg, bool Auto);
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index 21472eb3b..7a332c86e 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -78,6 +78,11 @@ bool pkgInitConfig(Configuration &Cnf)
Cnf.Set("Dir::Log::Terminal","term.log");
Cnf.Set("Dir::Log::History","history.log");
+ Cnf.Set("Dir::Ignore-Files-Silently::", "~$");
+ Cnf.Set("Dir::Ignore-Files-Silently::", "\\.disabled$");
+ Cnf.Set("Dir::Ignore-Files-Silently::", "\\.bak$");
+ Cnf.Set("Dir::Ignore-Files-Silently::", "\\.dpkg-[a-z]+$");
+
// Translation
Cnf.Set("APT::Acquire::Translation", "environment");
diff --git a/apt-pkg/makefile b/apt-pkg/makefile
index 1a7078693..a5be462ce 100644
--- a/apt-pkg/makefile
+++ b/apt-pkg/makefile
@@ -35,15 +35,14 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \
- aptconfiguration.cc cacheset.cc
+ aptconfiguration.cc
HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
orderlist.h sourcelist.h packagemanager.h tagfile.h \
init.h pkgcache.h version.h progress.h pkgrecords.h \
acquire.h acquire-worker.h acquire-item.h acquire-method.h \
clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
- vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \
- cacheset.h
+ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h
# Source code for the debian specific components
# In theory the deb headers do not need to be exported..
diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc
index 7c950292a..55f9cb9cc 100644
--- a/apt-pkg/orderlist.cc
+++ b/apt-pkg/orderlist.cc
@@ -117,7 +117,8 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg)
return false;
// Skip Packages that need configure only.
- if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure &&
+ if ((Pkg.State() == pkgCache::PkgIterator::NeedsConfigure ||
+ Pkg.State() == pkgCache::PkgIterator::NeedsNothing) &&
Cache[Pkg].Keep() == true)
return false;
diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc
index eef79cccd..49776aac7 100644
--- a/apt-pkg/packagemanager.cc
+++ b/apt-pkg/packagemanager.cc
@@ -602,7 +602,8 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg)
// configured we don't need to unpack it again…
PkgIterator const P = Pkg.Group().FindPkg("all");
if (List->IsFlag(P,pkgOrderList::UnPacked) != true &&
- List->IsFlag(P,pkgOrderList::Configured) != true) {
+ List->IsFlag(P,pkgOrderList::Configured) != true &&
+ P.State() != pkgCache::PkgIterator::NeedsNothing) {
if (SmartUnPack(P) == false)
return false;
}
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 30bb41470..8af8ef7de 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -119,7 +119,7 @@ pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
// Cache::ReMap - Reopen the cache file /*{{{*/
// ---------------------------------------------------------------------
/* If the file is already closed then this will open it open it. */
-bool pkgCache::ReMap()
+bool pkgCache::ReMap(bool const &Errorchecks)
{
// Apply the typecasts.
HeaderP = (Header *)Map.Data();
@@ -135,6 +135,9 @@ bool pkgCache::ReMap()
StringItemP = (StringItem *)Map.Data();
StrP = (char *)Map.Data();
+ if (Errorchecks == false)
+ return true;
+
if (Map.Size() == 0 || HeaderP == 0)
return _error->Error(_("Empty package cache"));
@@ -307,7 +310,7 @@ const char *pkgCache::Priority(unsigned char Prio)
// GrpIterator::FindPkg - Locate a package by arch /*{{{*/
// ---------------------------------------------------------------------
/* Returns an End-Pointer on error, pointer to the package otherwise */
-pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) {
+pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
if (unlikely(IsGood() == false || S->FirstPackage == 0))
return PkgIterator(*Owner, 0);
@@ -346,7 +349,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) {
// GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/
// ---------------------------------------------------------------------
/* Returns an End-Pointer on error, pointer to the package otherwise */
-pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() {
+pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() const {
pkgCache::PkgIterator Pkg = FindPkg("native");
if (Pkg.end() == false)
return Pkg;
@@ -367,7 +370,7 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() {
/* Returns an End-Pointer on error, pointer to the package otherwise.
We can't simply ++ to the next as the next package of the last will
be from a different group (with the same hash value) */
-pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) {
+pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) const {
if (unlikely(IsGood() == false || S->FirstPackage == 0 ||
LastPkg.end() == true))
return PkgIterator(*Owner, 0);
@@ -504,7 +507,7 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
// ---------------------------------------------------------------------
/* Currently critical deps are defined as depends, predepends and
conflicts (including dpkg's Breaks fields). */
-bool pkgCache::DepIterator::IsCritical()
+bool pkgCache::DepIterator::IsCritical() const
{
if (S->Type == pkgCache::Dep::Conflicts ||
S->Type == pkgCache::Dep::DpkgBreaks ||
@@ -528,7 +531,7 @@ bool pkgCache::DepIterator::IsCritical()
In Conjunction with the DepCache the value of Result may not be
super-good since the policy may have made it uninstallable. Using
AllTargets is better in this case. */
-bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
+bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) const
{
Result = TargetPkg();
@@ -577,7 +580,7 @@ bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
provides. It includes every possible package-version that could satisfy
the dependency. The last item in the list has a 0. The resulting pointer
must be delete [] 'd */
-pkgCache::Version **pkgCache::DepIterator::AllTargets()
+pkgCache::Version **pkgCache::DepIterator::AllTargets() const
{
Version **Res = 0;
unsigned long Size =0;
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 426bb9f13..799521784 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -174,7 +174,7 @@ class pkgCache /*{{{*/
StringItem *StringItemP;
char *StrP;
- virtual bool ReMap();
+ virtual bool ReMap(bool const &Errorchecks = true);
inline bool Sync() {return Map.Sync();};
inline MMap &GetMap() {return Map;};
inline void *DataEnd() {return ((unsigned char *)Map.Data()) + Map.Size();};
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 5649cd6f8..18bad6727 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -36,6 +36,7 @@
#include <stdio.h>
/*}}}*/
typedef vector<pkgIndexFile *>::iterator FileIterator;
+template <typename Iter> std::set<Iter*> pkgCacheGenerator::Dynamic<Iter>::toReMap;
// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
// ---------------------------------------------------------------------
@@ -61,8 +62,12 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
// Starting header
*Cache.HeaderP = pkgCache::Header();
- Cache.HeaderP->VerSysName = Map.WriteString(_system->VS->Label);
- Cache.HeaderP->Architecture = Map.WriteString(_config->Find("APT::Architecture"));
+ map_ptrloc const idxVerSysName = WriteStringInMap(_system->VS->Label);
+ Cache.HeaderP->VerSysName = idxVerSysName;
+ map_ptrloc const idxArchitecture = WriteStringInMap(_config->Find("APT::Architecture"));
+ Cache.HeaderP->Architecture = idxArchitecture;
+ if (unlikely(idxVerSysName == 0 || idxArchitecture == 0))
+ return;
Cache.ReMap();
}
else
@@ -96,6 +101,67 @@ pkgCacheGenerator::~pkgCacheGenerator()
Map.Sync(0,sizeof(pkgCache::Header));
}
/*}}}*/
+void pkgCacheGenerator::ReMap(void const * const oldMap, void const * const newMap) {/*{{{*/
+ if (oldMap == newMap)
+ return;
+
+ Cache.ReMap(false);
+
+ CurrentFile += (pkgCache::PackageFile*) newMap - (pkgCache::PackageFile*) oldMap;
+
+ for (size_t i = 0; i < _count(UniqHash); ++i)
+ if (UniqHash[i] != 0)
+ UniqHash[i] += (pkgCache::StringItem*) newMap - (pkgCache::StringItem*) oldMap;
+
+ for (std::set<pkgCache::GrpIterator*>::const_iterator i = Dynamic<pkgCache::GrpIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::GrpIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::PkgIterator*>::const_iterator i = Dynamic<pkgCache::PkgIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::PkgIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::VerIterator*>::const_iterator i = Dynamic<pkgCache::VerIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::VerIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::DepIterator*>::const_iterator i = Dynamic<pkgCache::DepIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::DepIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::DescIterator*>::const_iterator i = Dynamic<pkgCache::DescIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::DescIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::PrvIterator*>::const_iterator i = Dynamic<pkgCache::PrvIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::PrvIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+ for (std::set<pkgCache::PkgFileIterator*>::const_iterator i = Dynamic<pkgCache::PkgFileIterator>::toReMap.begin();
+ i != Dynamic<pkgCache::PkgFileIterator>::toReMap.end(); ++i)
+ (*i)->ReOwn(Cache, oldMap, newMap);
+} /*}}}*/
+// CacheGenerator::WriteStringInMap /*{{{*/
+map_ptrloc pkgCacheGenerator::WriteStringInMap(const char *String,
+ const unsigned long &Len) {
+ void const * const oldMap = Map.Data();
+ map_ptrloc const index = Map.WriteString(String, Len);
+ if (index != 0)
+ ReMap(oldMap, Map.Data());
+ return index;
+}
+ /*}}}*/
+// CacheGenerator::WriteStringInMap /*{{{*/
+map_ptrloc pkgCacheGenerator::WriteStringInMap(const char *String) {
+ void const * const oldMap = Map.Data();
+ map_ptrloc const index = Map.WriteString(String);
+ if (index != 0)
+ ReMap(oldMap, Map.Data());
+ return index;
+}
+ /*}}}*/
+map_ptrloc pkgCacheGenerator::AllocateInMap(const unsigned long &size) {/*{{{*/
+ void const * const oldMap = Map.Data();
+ map_ptrloc const index = Map.Allocate(size);
+ if (index != 0)
+ ReMap(oldMap, Map.Data());
+ return index;
+}
+ /*}}}*/
// CacheGenerator::MergeList - Merge the package list /*{{{*/
// ---------------------------------------------------------------------
/* This provides the generation of the entries in the cache. Each loop
@@ -127,6 +193,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
{
// Get a pointer to the package structure
pkgCache::PkgIterator Pkg;
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
if (NewPackage(Pkg, PackageName, *arch) == false)
return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str());
Counter++;
@@ -142,18 +209,20 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
// we first process the package, then the descriptions
// (this has the bonus that we get MMap error when we run out
// of MMap space)
- if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false)
+ pkgCache::VerIterator Ver(Cache);
+ Dynamic<pkgCache::VerIterator> DynVer(Ver);
+ if (List.UsePackage(Pkg, Ver) == false)
return _error->Error(_("Error occurred while processing %s (UsePackage1)"),
PackageName.c_str());
// Find the right version to write the description
MD5SumValue CurMd5 = List.Description_md5();
- pkgCache::VerIterator Ver = Pkg.VersionList();
- map_ptrloc *LastVer = &Pkg->VersionList;
+ Ver = Pkg.VersionList();
- for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
+ for (; Ver.end() == false; ++Ver)
{
pkgCache::DescIterator Desc = Ver.DescriptionList();
+ Dynamic<pkgCache::DescIterator> DynDesc(Desc);
map_ptrloc *LastDesc = &Ver->DescriptionList;
bool duplicate=false;
@@ -173,7 +242,11 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
if (MD5SumValue(Desc.md5()) == CurMd5)
{
// Add new description
- *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
+ void const * const oldMap = Map.Data();
+ map_ptrloc const descindex = NewDescription(Desc, List.DescriptionLanguage(), CurMd5, *LastDesc);
+ if (oldMap != Map.Data())
+ LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
+ *LastDesc = descindex;
Desc->ParentPkg = Pkg.Index();
if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
@@ -187,7 +260,9 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
}
pkgCache::VerIterator Ver = Pkg.VersionList();
+ Dynamic<pkgCache::VerIterator> DynVer(Ver);
map_ptrloc *LastVer = &Pkg->VersionList;
+ void const * oldMap = Map.Data();
int Res = 1;
unsigned long const Hash = List.VersionHash();
for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
@@ -226,21 +301,28 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
}
// Add a new version
- *LastVer = NewVersion(Ver,Version,*LastVer);
+ map_ptrloc const verindex = NewVersion(Ver,Version,*LastVer);
+ if (verindex == 0 && _error->PendingError())
+ return _error->Error(_("Error occurred while processing %s (NewVersion%d)"),
+ PackageName.c_str(), 1);
+
+ if (oldMap != Map.Data())
+ LastVer += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
+ *LastVer = verindex;
Ver->ParentPkg = Pkg.Index();
Ver->Hash = Hash;
- if ((*LastVer == 0 && _error->PendingError()) || List.NewVersion(Ver) == false)
- return _error->Error(_("Error occurred while processing %s (NewVersion1)"),
- PackageName.c_str());
+ if (List.NewVersion(Ver) == false)
+ return _error->Error(_("Error occurred while processing %s (NewVersion%d)"),
+ PackageName.c_str(), 2);
if (List.UsePackage(Pkg,Ver) == false)
return _error->Error(_("Error occurred while processing %s (UsePackage3)"),
PackageName.c_str());
if (NewFileVer(Ver,List) == false)
- return _error->Error(_("Error occurred while processing %s (NewVersion2)"),
- PackageName.c_str());
+ return _error->Error(_("Error occurred while processing %s (NewVersion%d)"),
+ PackageName.c_str(), 3);
// Read only a single record and return
if (OutVer != 0)
@@ -253,13 +335,18 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
/* Record the Description data. Description data always exist in
Packages and Translation-* files. */
pkgCache::DescIterator Desc = Ver.DescriptionList();
+ Dynamic<pkgCache::DescIterator> DynDesc(Desc);
map_ptrloc *LastDesc = &Ver->DescriptionList;
-
+
// Skip to the end of description set
for (; Desc.end() == false; LastDesc = &Desc->NextDesc, Desc++);
// Add new description
- *LastDesc = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
+ oldMap = Map.Data();
+ map_ptrloc const descindex = NewDescription(Desc, List.DescriptionLanguage(), List.Description_md5(), *LastDesc);
+ if (oldMap != Map.Data())
+ LastDesc += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
+ *LastDesc = descindex;
Desc->ParentPkg = Pkg.Index();
if ((*LastDesc == 0 && _error->PendingError()) || NewFileDesc(Desc,List) == false)
@@ -306,6 +393,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List)
continue;
pkgCache::PkgIterator Pkg = Cache.FindPkg(PackageName);
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
if (Pkg.end() == true)
return _error->Error(_("Error occurred while processing %s (FindPkg)"),
PackageName.c_str());
@@ -315,6 +403,7 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List)
unsigned long Hash = List.VersionHash();
pkgCache::VerIterator Ver = Pkg.VersionList();
+ Dynamic<pkgCache::VerIterator> DynVer(Ver);
for (; Ver.end() == false; Ver++)
{
if (Ver->Hash == Hash && Version.c_str() == Ver.VerStr())
@@ -342,14 +431,15 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name)
return true;
// Get a structure
- unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group));
+ map_ptrloc const Group = AllocateInMap(sizeof(pkgCache::Group));
if (unlikely(Group == 0))
return false;
Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group);
- Grp->Name = Map.WriteString(Name);
- if (unlikely(Grp->Name == 0))
+ map_ptrloc const idxName = WriteStringInMap(Name);
+ if (unlikely(idxName == 0))
return false;
+ Grp->Name = idxName;
// Insert it into the hash table
unsigned long const Hash = Cache.Hash(Name);
@@ -366,6 +456,7 @@ bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name)
bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name,
const string &Arch) {
pkgCache::GrpIterator Grp;
+ Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
if (unlikely(NewGroup(Grp, Name) == false))
return false;
@@ -374,7 +465,7 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
return true;
// Get a structure
- unsigned long const Package = Map.Allocate(sizeof(pkgCache::Package));
+ map_ptrloc const Package = AllocateInMap(sizeof(pkgCache::Package));
if (unlikely(Package == 0))
return false;
Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package);
@@ -400,9 +491,10 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
// Set the name, arch and the ID
Pkg->Name = Grp->Name;
Pkg->Group = Grp.Index();
- Pkg->Arch = WriteUniqString(Arch.c_str());
- if (unlikely(Pkg->Arch == 0))
+ map_ptrloc const idxArch = WriteUniqString(Arch.c_str());
+ if (unlikely(idxArch == 0))
return false;
+ Pkg->Arch = idxArch;
Pkg->ID = Cache.HeaderP->PackageCount++;
return true;
@@ -418,7 +510,7 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver,
return true;
// Get a structure
- unsigned long VerFile = Map.Allocate(sizeof(pkgCache::VerFile));
+ map_ptrloc const VerFile = AllocateInMap(sizeof(pkgCache::VerFile));
if (VerFile == 0)
return 0;
@@ -449,7 +541,7 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
unsigned long Next)
{
// Get a structure
- unsigned long Version = Map.Allocate(sizeof(pkgCache::Version));
+ map_ptrloc const Version = AllocateInMap(sizeof(pkgCache::Version));
if (Version == 0)
return 0;
@@ -457,9 +549,10 @@ unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver,
Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version);
Ver->NextVer = Next;
Ver->ID = Cache.HeaderP->VersionCount++;
- Ver->VerStr = Map.WriteString(VerStr);
- if (Ver->VerStr == 0)
+ map_ptrloc const idxVerStr = WriteStringInMap(VerStr);
+ if (unlikely(idxVerStr == 0))
return 0;
+ Ver->VerStr = idxVerStr;
return Version;
}
@@ -474,7 +567,7 @@ bool pkgCacheGenerator::NewFileDesc(pkgCache::DescIterator &Desc,
return true;
// Get a structure
- unsigned long DescFile = Map.Allocate(sizeof(pkgCache::DescFile));
+ map_ptrloc const DescFile = AllocateInMap(sizeof(pkgCache::DescFile));
if (DescFile == 0)
return false;
@@ -507,7 +600,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
map_ptrloc Next)
{
// Get a structure
- map_ptrloc Description = Map.Allocate(sizeof(pkgCache::Description));
+ map_ptrloc const Description = AllocateInMap(sizeof(pkgCache::Description));
if (Description == 0)
return 0;
@@ -515,10 +608,12 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
Desc = pkgCache::DescIterator(Cache,Cache.DescP + Description);
Desc->NextDesc = Next;
Desc->ID = Cache.HeaderP->DescriptionCount++;
- Desc->language_code = Map.WriteString(Lang);
- Desc->md5sum = Map.WriteString(md5sum.Value());
- if (Desc->language_code == 0 || Desc->md5sum == 0)
+ map_ptrloc const idxlanguage_code = WriteStringInMap(Lang);
+ map_ptrloc const idxmd5sum = WriteStringInMap(md5sum.Value());
+ if (unlikely(idxlanguage_code == 0 || idxmd5sum == 0))
return 0;
+ Desc->language_code = idxlanguage_code;
+ Desc->md5sum = idxmd5sum;
return Description;
}
@@ -534,15 +629,22 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
if (archs.size() > 1)
{
// Create Conflicts in between the group
- for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++)
+ pkgCache::GrpIterator G = GetCache().GrpBegin();
+ Dynamic<pkgCache::GrpIterator> DynG(G);
+ for (; G.end() != true; G++)
{
string const PkgName = G.Name();
- for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P))
+ pkgCache::PkgIterator P = G.PackageList();
+ Dynamic<pkgCache::PkgIterator> DynP(P);
+ for (; P.end() != true; P = G.NextPkg(P))
{
if (strcmp(P.Arch(),"all") == 0)
continue;
pkgCache::PkgIterator allPkg;
- for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++)
+ Dynamic<pkgCache::PkgIterator> DynallPkg(allPkg);
+ pkgCache::VerIterator V = P.VersionList();
+ Dynamic<pkgCache::VerIterator> DynV(V);
+ for (; V.end() != true; V++)
{
string const Arch = V.Arch(true);
map_ptrloc *OldDepLast = NULL;
@@ -562,6 +664,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
per group, therefore each group member conflicts
with all other group members */
pkgCache::PkgIterator D = G.FindPkg(*A);
+ Dynamic<pkgCache::PkgIterator> DynD(D);
if (D.end() == true)
continue;
if (coInstall == true)
@@ -572,10 +675,7 @@ bool pkgCacheGenerator::FinishCache(OpProgress *Progress)
OldDepLast);
// Breaks: ${self}:other (!= ${binary:Version})
NewDepends(D, V, V.VerStr(),
- pkgCache::Dep::Less, pkgCache::Dep::DpkgBreaks,
- OldDepLast);
- NewDepends(D, V, V.VerStr(),
- pkgCache::Dep::Greater, pkgCache::Dep::DpkgBreaks,
+ pkgCache::Dep::NotEquals, pkgCache::Dep::DpkgBreaks,
OldDepLast);
if (V->MultiArch == pkgCache::Version::All)
{
@@ -609,13 +709,15 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
unsigned int const &Type,
map_ptrloc *OldDepLast)
{
+ void const * const oldMap = Map.Data();
// Get a structure
- unsigned long const Dependency = Map.Allocate(sizeof(pkgCache::Dependency));
+ map_ptrloc const Dependency = AllocateInMap(sizeof(pkgCache::Dependency));
if (unlikely(Dependency == 0))
return false;
// Fill it in
pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency);
+ Dynamic<pkgCache::DepIterator> DynDep(Dep);
Dep->ParentVer = Ver.Index();
Dep->Type = Type;
Dep->CompareOp = Op;
@@ -627,9 +729,12 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
/* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++)
if (I->Version != 0 && I.TargetVer() == Version)
Dep->Version = I->Version;*/
- if (Dep->Version == 0)
- if (unlikely((Dep->Version = Map.WriteString(Version)) == 0))
+ if (Dep->Version == 0) {
+ map_ptrloc const index = WriteStringInMap(Version);
+ if (unlikely(index == 0))
return false;
+ Dep->Version = index;
+ }
}
// Link it to the package
@@ -643,7 +748,8 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
OldDepLast = &Ver->DependsList;
for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
OldDepLast = &D->NextDepends;
- }
+ } else if (oldMap != Map.Data())
+ OldDepLast += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
Dep->NextDepends = *OldDepLast;
*OldDepLast = Dep.Index();
@@ -656,7 +762,7 @@ bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
// ---------------------------------------------------------------------
/* This creates a Group and the Package to link this dependency to if
needed and handles also the caching of the old endpoint */
-bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
+bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver,
const string &PackageName,
const string &Arch,
const string &Version,
@@ -664,11 +770,13 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
unsigned int Type)
{
pkgCache::GrpIterator Grp;
+ Dynamic<pkgCache::GrpIterator> DynGrp(Grp);
if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
return false;
// Locate the target package
pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch);
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
if (Pkg.end() == true) {
if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false))
return false;
@@ -690,7 +798,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
// ListParser::NewProvides - Create a Provides element /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
+bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
const string &PkgName,
const string &PkgArch,
const string &Version)
@@ -702,13 +810,14 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
return true;
// Get a structure
- unsigned long const Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides));
+ map_ptrloc const Provides = Owner->AllocateInMap(sizeof(pkgCache::Provides));
if (unlikely(Provides == 0))
return false;
Cache.HeaderP->ProvidesCount++;
// Fill it in
pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP);
+ Dynamic<pkgCache::PrvIterator> DynPrv(Prv);
Prv->Version = Ver.Index();
Prv->NextPkgProv = Ver->ProvidesList;
Ver->ProvidesList = Prv.Index();
@@ -717,6 +826,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
// Locate the target package
pkgCache::PkgIterator Pkg;
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false))
return false;
@@ -737,24 +847,29 @@ bool pkgCacheGenerator::SelectFile(const string &File,const string &Site,
unsigned long Flags)
{
// Get some space for the structure
- CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile));
- if (CurrentFile == Cache.PkgFileP)
+ map_ptrloc const idxFile = AllocateInMap(sizeof(*CurrentFile));
+ if (unlikely(idxFile == 0))
return false;
-
+ CurrentFile = Cache.PkgFileP + idxFile;
+
// Fill it in
- CurrentFile->FileName = Map.WriteString(File);
- CurrentFile->Site = WriteUniqString(Site);
+ map_ptrloc const idxFileName = WriteStringInMap(File);
+ map_ptrloc const idxSite = WriteUniqString(Site);
+ if (unlikely(idxFileName == 0 || idxSite == 0))
+ return false;
+ CurrentFile->FileName = idxFileName;
+ CurrentFile->Site = idxSite;
CurrentFile->NextFile = Cache.HeaderP->FileList;
CurrentFile->Flags = Flags;
CurrentFile->ID = Cache.HeaderP->PackageFileCount;
- CurrentFile->IndexType = WriteUniqString(Index.GetType()->Label);
+ map_ptrloc const idxIndexType = WriteUniqString(Index.GetType()->Label);
+ if (unlikely(idxIndexType == 0))
+ return false;
+ CurrentFile->IndexType = idxIndexType;
PkgFileName = File;
Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP;
Cache.HeaderP->PackageFileCount++;
- if (CurrentFile->FileName == 0)
- return false;
-
if (Progress != 0)
Progress->SubProgress(Index.Size());
return true;
@@ -794,18 +909,25 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S,
}
// Get a structure
- unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem));
+ void const * const oldMap = Map.Data();
+ map_ptrloc const Item = AllocateInMap(sizeof(pkgCache::StringItem));
if (Item == 0)
return 0;
+ map_ptrloc const idxString = WriteStringInMap(S,Size);
+ if (unlikely(idxString == 0))
+ return 0;
+ if (oldMap != Map.Data()) {
+ Last += (map_ptrloc*) Map.Data() - (map_ptrloc*) oldMap;
+ I += (pkgCache::StringItem*) Map.Data() - (pkgCache::StringItem*) oldMap;
+ }
+ *Last = Item;
+
// Fill in the structure
pkgCache::StringItem *ItemP = Cache.StringItemP + Item;
ItemP->NextItem = I - Cache.StringItemP;
- *Last = Item;
- ItemP->String = Map.WriteString(S,Size);
- if (ItemP->String == 0)
- return 0;
-
+ ItemP->String = idxString;
+
Bucket = ItemP;
return ItemP->String;
}
@@ -1059,7 +1181,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
unlink(CacheFile.c_str());
CacheF = new FileFd(CacheFile,FileFd::WriteEmpty);
fchmod(CacheF->Fd(),0644);
- Map = new DynamicMMap(*CacheF,MMap::Public,MapSize);
+ Map = new DynamicMMap(*CacheF,MMap::Public | MMap::Moveable, MapSize);
if (_error->PendingError() == true)
return false;
if (Debug == true)
@@ -1068,7 +1190,7 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
else
{
// Just build it in memory..
- Map = new DynamicMMap(0,MapSize);
+ Map = new DynamicMMap(MMap::Moveable, MapSize);
if (Debug == true)
std::clog << "Open memory Map (not filebased)" << std::endl;
}
@@ -1181,7 +1303,7 @@ bool pkgCacheGenerator::MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **O
if (_system->AddStatusFiles(Files) == false)
return false;
- SPtr<DynamicMMap> Map = new DynamicMMap(0,MapSize);
+ SPtr<DynamicMMap> Map = new DynamicMMap(MMap::Moveable, MapSize);
unsigned long CurrentSize = 0;
unsigned long TotalSize = 0;
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index ff0941e0c..3bee1f958 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -23,6 +23,8 @@
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/md5.h>
+#include <set>
+
class pkgSourceList;
class OpProgress;
class MMap;
@@ -31,16 +33,34 @@ class pkgIndexFile;
class pkgCacheGenerator /*{{{*/
{
private:
-
+
pkgCache::StringItem *UniqHash[26];
-
+ map_ptrloc WriteStringInMap(std::string const &String) { return WriteStringInMap(String.c_str()); };
+ map_ptrloc WriteStringInMap(const char *String);
+ map_ptrloc WriteStringInMap(const char *String, const unsigned long &Len);
+ map_ptrloc AllocateInMap(const unsigned long &size);
+
public:
class ListParser;
friend class ListParser;
-
+
+ template<typename Iter> class Dynamic {
+ Iter *I;
+
+ public:
+ static std::set<Iter*> toReMap;
+ Dynamic(Iter &It) : I(&It) {
+ toReMap.insert(I);
+ }
+
+ ~Dynamic() {
+ toReMap.erase(I);
+ }
+ };
+
protected:
-
+
DynamicMMap &Map;
pkgCache Cache;
OpProgress *Progress;
@@ -82,6 +102,8 @@ class pkgCacheGenerator /*{{{*/
MMap **OutMap = 0,bool AllowMem = false);
static bool MakeOnlyStatusCache(OpProgress *Progress,DynamicMMap **OutMap);
+ void ReMap(void const * const oldMap, void const * const newMap);
+
pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
~pkgCacheGenerator();
};
@@ -103,12 +125,12 @@ class pkgCacheGenerator::ListParser
inline unsigned long WriteUniqString(string S) {return Owner->WriteUniqString(S);};
inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);};
- inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);};
- inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);};
- bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch,
+ inline unsigned long WriteString(const string &S) {return Owner->WriteStringInMap(S);};
+ inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->WriteStringInMap(S,Size);};
+ bool NewDepends(pkgCache::VerIterator &Ver,const string &Package, const string &Arch,
const string &Version,unsigned int Op,
unsigned int Type);
- bool NewProvides(pkgCache::VerIterator Ver,const string &PkgName,
+ bool NewProvides(pkgCache::VerIterator &Ver,const string &PkgName,
const string &PkgArch, const string &Version);
public:
@@ -118,13 +140,13 @@ class pkgCacheGenerator::ListParser
virtual string Architecture() = 0;
virtual bool ArchitectureAll() = 0;
virtual string Version() = 0;
- virtual bool NewVersion(pkgCache::VerIterator Ver) = 0;
+ virtual bool NewVersion(pkgCache::VerIterator &Ver) = 0;
virtual string Description() = 0;
virtual string DescriptionLanguage() = 0;
virtual MD5SumValue Description_md5() = 0;
virtual unsigned short VersionHash() = 0;
- virtual bool UsePackage(pkgCache::PkgIterator Pkg,
- pkgCache::VerIterator Ver) = 0;
+ virtual bool UsePackage(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver) = 0;
virtual unsigned long Offset() = 0;
virtual unsigned long Size() = 0;
@@ -132,7 +154,7 @@ class pkgCacheGenerator::ListParser
inline bool HasFileDeps() {return FoundFileDeps;};
virtual bool CollectFileProvides(pkgCache &Cache,
- pkgCache::VerIterator Ver) {return true;};
+ pkgCache::VerIterator &Ver) {return true;};
ListParser() : FoundFileDeps(false) {};
virtual ~ListParser() {};
diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h
index 28cb3ccbb..f8b2678de 100644
--- a/apt-pkg/policy.h
+++ b/apt-pkg/policy.h
@@ -76,7 +76,7 @@ class pkgPolicy : public pkgDepCache::Policy
// Things for the cache interface.
virtual pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator const &Pkg);
- virtual bool IsImportantDep(pkgCache::DepIterator Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);};
+ virtual bool IsImportantDep(pkgCache::DepIterator const &Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);};
bool InitDefaults();
pkgPolicy(pkgCache *Owner);
diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc
index 7cb95b3f8..c790559e7 100644
--- a/cmdline/apt-cache.cc
+++ b/cmdline/apt-cache.cc
@@ -29,7 +29,8 @@
#include <apt-pkg/tagfile.h>
#include <apt-pkg/algorithms.h>
#include <apt-pkg/sptr.h>
-#include <apt-pkg/cacheset.h>
+
+#include "cacheset.h"
#include <config.h>
#include <apti18n.h>
@@ -1867,21 +1868,21 @@ int main(int argc,const char *argv[]) /*{{{*/
}
// Deal with stdout not being a tty
- if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
-// if (_config->FindB("APT::Cache::Generate",true) == false)
+ if (_config->Exists("APT::Cache::Generate") == true)
+ _config->Set("pkgCacheFile::Generate", _config->FindB("APT::Cache::Generate", true));
+
if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false)
CmdL.DispatchArg(CmdsB);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc
index 8b9eacae6..d1268edf9 100644
--- a/cmdline/apt-cdrom.cc
+++ b/cmdline/apt-cdrom.cc
@@ -266,20 +266,18 @@ int main(int argc,const char *argv[]) /*{{{*/
return ShowHelp();
// Deal with stdout not being a tty
- if (isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Match the operation
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 0ada46c73..7cf760c27 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -40,12 +40,12 @@
#include <apt-pkg/sptr.h>
#include <apt-pkg/md5.h>
#include <apt-pkg/versionmatch.h>
-#include <apt-pkg/cacheset.h>
#include <config.h>
#include <apti18n.h>
#include "acqprogress.h"
+#include "cacheset.h"
#include <set>
#include <locale.h>
@@ -609,6 +609,253 @@ void Stats(ostream &out,pkgDepCache &Dep)
Dep.BadCount());
}
/*}}}*/
+// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
+class CacheSetHelperAPTGet : public APT::CacheSetHelper {
+ /** \brief stream message should be printed to */
+ std::ostream &out;
+ /** \brief were things like Task or RegEx used to select packages? */
+ bool explicitlyNamed;
+
+ APT::PackageSet virtualPkgs;
+
+public:
+ CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
+ explicitlyNamed = true;
+ }
+
+ virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ string const &ver, bool const &verIsRel) {
+ if (ver != Ver.VerStr())
+ ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
+ Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
+ }
+
+ bool showVirtualPackageErrors(pkgCacheFile &Cache) {
+ if (virtualPkgs.empty() == true)
+ return true;
+ for (APT::PackageSet::const_iterator Pkg = virtualPkgs.begin();
+ Pkg != virtualPkgs.end(); ++Pkg) {
+ if (Pkg->ProvidesList != 0) {
+ ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
+ Pkg.FullName(true).c_str());
+
+ pkgCache::PrvIterator I = Pkg.ProvidesList();
+ unsigned short provider = 0;
+ for (; I.end() == false; ++I) {
+ pkgCache::PkgIterator Pkg = I.OwnerPkg();
+
+ if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) {
+ out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
+ if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
+ out << _(" [Installed]");
+ out << endl;
+ ++provider;
+ }
+ }
+ // if we found no candidate which provide this package, show non-candidates
+ if (provider == 0)
+ for (I = Pkg.ProvidesList(); I.end() == false; I++)
+ out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
+ << _(" [Not candidate version]") << endl;
+ else
+ out << _("You should explicitly select one to install.") << endl;
+ } else {
+ ioprintf(out,
+ _("Package %s is not available, but is referred to by another package.\n"
+ "This may mean that the package is missing, has been obsoleted, or\n"
+ "is only available from another source\n"),Pkg.FullName(true).c_str());
+
+ string List;
+ string VersionsList;
+ SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
+ memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
+ for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
+ Dep.end() == false; Dep++) {
+ if (Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ if (Seen[Dep.ParentPkg()->ID] == true)
+ continue;
+ Seen[Dep.ParentPkg()->ID] = true;
+ List += Dep.ParentPkg().FullName(true) + " ";
+ //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
+ }
+ ShowList(out,_("However the following packages replace it:"),List,VersionsList);
+ }
+ out << std::endl;
+ }
+ return false;
+ }
+
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDIDATE);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true) {
+ _error->Error(_("Package '%s' has no installation candidate"),Pkg.FullName(true).c_str());
+ virtualPkgs.insert(Pkg);
+ }
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ APT::VersionSet const verset = tryVirtualPackage(Cache, Pkg, APT::VersionSet::NEWEST);
+ if (verset.empty() == false)
+ return *(verset.begin());
+ if (ShowError == true)
+ ioprintf(out, _("Virtual packages like '%s' can't be removed\n"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+ }
+
+ APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+ APT::VersionSet::Version const &select) {
+ /* This is a pure virtual package and there is a single available
+ candidate providing it. */
+ if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0)
+ return APT::VersionSet();
+
+ pkgCache::PkgIterator Prov;
+ bool found_one = false;
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+ pkgCache::VerIterator const PVer = P.OwnerVer();
+ pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+ /* Ignore versions that are not a candidate. */
+ if (Cache[PPkg].CandidateVer != PVer)
+ continue;
+
+ if (found_one == false) {
+ Prov = PPkg;
+ found_one = true;
+ } else if (PPkg != Prov) {
+ found_one = false; // we found at least two
+ break;
+ }
+ }
+
+ if (found_one == true) {
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+ }
+ return APT::VersionSet();
+ }
+
+ inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
+
+};
+ /*}}}*/
+// TryToInstall - Mark a package for installation /*{{{*/
+struct TryToInstall {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+ APT::PackageSet doAutoInstallLater;
+
+ TryToInstall(pkgCacheFile &Cache, pkgProblemResolver &PM, bool const &FixBroken) : Cache(&Cache), Fix(&PM),
+ FixBroken(FixBroken), AutoMarkChanged(0) {};
+
+ void operator() (pkgCache::VerIterator const &Ver) {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Cache->GetDepCache()->SetCandidateVersion(Ver);
+ pkgDepCache::StateCache &State = (*Cache)[Pkg];
+
+ // Handle the no-upgrade case
+ if (_config->FindB("APT::Get::upgrade",true) == false && Pkg->CurrentVer != 0)
+ ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
+ Pkg.FullName(true).c_str());
+ // Ignore request for install if package would be new
+ else if (_config->FindB("APT::Get::Only-Upgrade", false) == true && Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
+ Pkg.FullName(true).c_str());
+ else {
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Cache->GetDepCache()->MarkInstall(Pkg,false);
+
+ if (State.Install() == false) {
+ if (_config->FindB("APT::Get::ReInstall",false) == true) {
+ if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
+ ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
+ Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->SetReInstall(Pkg, true);
+ } else
+ ioprintf(c1out,_("%s is already the newest version.\n"),
+ Pkg.FullName(true).c_str());
+ }
+
+ // Install it with autoinstalling enabled (if we not respect the minial
+ // required deps or the policy)
+ if (FixBroken == false)
+ doAutoInstallLater.insert(Pkg);
+ }
+
+ // see if we need to fix the auto-mark flag
+ // e.g. apt-get install foo
+ // where foo is marked automatic
+ if (State.Install() == false &&
+ (State.Flags & pkgCache::Flag::Auto) &&
+ _config->FindB("APT::Get::ReInstall",false) == false &&
+ _config->FindB("APT::Get::Only-Upgrade",false) == false &&
+ _config->FindB("APT::Get::Download-Only",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually installed.\n"),
+ Pkg.FullName(true).c_str());
+ Cache->GetDepCache()->MarkAuto(Pkg,false);
+ AutoMarkChanged++;
+ }
+ }
+
+ void doAutoInstall() {
+ for (APT::PackageSet::const_iterator P = doAutoInstallLater.begin();
+ P != doAutoInstallLater.end(); ++P) {
+ pkgDepCache::StateCache &State = (*Cache)[P];
+ if (State.InstBroken() == false && State.InstPolicyBroken() == false)
+ continue;
+ Cache->GetDepCache()->MarkInstall(P, true);
+ }
+ doAutoInstallLater.clear();
+ }
+};
+ /*}}}*/
+// TryToRemove - Mark a package for removal /*{{{*/
+struct TryToRemove {
+ pkgCacheFile* Cache;
+ pkgProblemResolver* Fix;
+ bool FixBroken;
+ unsigned long AutoMarkChanged;
+
+ TryToRemove(pkgCacheFile &Cache, pkgProblemResolver &PM) : Cache(&Cache), Fix(&PM) {};
+
+ void operator() (pkgCache::VerIterator const &Ver)
+ {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+
+ Fix->Clear(Pkg);
+ Fix->Protect(Pkg);
+ Fix->Remove(Pkg);
+
+ if (Pkg->CurrentVer == 0)
+ ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
+ else
+ Cache->GetDepCache()->MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
+ }
+};
+ /*}}}*/
// CacheFile::NameComp - QSort compare by name /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -1073,219 +1320,35 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true,
return true;
}
/*}}}*/
-// TryToInstall - Try to install a single package /*{{{*/
+// TryToInstallBuildDep - Try to install a single package /*{{{*/
// ---------------------------------------------------------------------
/* This used to be inlined in DoInstall, but with the advent of regex package
name matching it was split out.. */
-bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
+bool TryToInstallBuildDep(pkgCache::PkgIterator Pkg,pkgCacheFile &Cache,
pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
- unsigned int &ExpectedInst,bool AllowFail = true)
+ bool AllowFail = true)
{
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
{
- pkgCache::PkgIterator Prov;
- bool found_one = false;
-
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
- {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false)
- {
- Prov = PPkg;
- found_one = true;
- }
- else if (PPkg != Prov)
- {
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true)
- {
- ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
- Prov.FullName(true).c_str(),Pkg.FullName(true).c_str());
- Pkg = Prov;
- }
+ CacheSetHelperAPTGet helper(c1out);
+ helper.showErrors(AllowFail == false);
+ pkgCache::VerIterator Ver = helper.canNotFindNewestVer(Cache, Pkg);
+ if (Ver.end() == false)
+ Pkg = Ver.ParentPkg();
+ else if (helper.showVirtualPackageErrors(Cache) == false)
+ return AllowFail;
}
- // Handle the no-upgrade case
- if (_config->FindB("APT::Get::upgrade",true) == false &&
- Pkg->CurrentVer != 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is already installed and upgrade is not set.\n"),
- Pkg.FullName(true).c_str());
- return true;
- }
-
- // Ignore request for install if package would be new
- if (_config->FindB("APT::Get::Only-Upgrade", false) == true &&
- Pkg->CurrentVer == 0)
- {
- if (AllowFail == true)
- ioprintf(c1out,_("Skipping %s, it is not installed and only upgrades are requested.\n"),
- Pkg.Name());
- return true;
- }
-
- // Check if there is something at all to install
- pkgDepCache::StateCache &State = Cache[Pkg];
- if (Remove == true && Pkg->CurrentVer == 0)
- {
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
- Fix.Remove(Pkg);
-
- /* We want to continue searching for regex hits, so we return false here
- otherwise this is not really an error. */
- if (AllowFail == false)
- return false;
-
- ioprintf(c1out,_("Package %s is not installed, so not removed\n"),Pkg.FullName(true).c_str());
- return true;
- }
-
- if (State.CandidateVer == 0 && Remove == false)
- {
- if (AllowFail == false)
- return false;
-
- if (Pkg->ProvidesList != 0)
- {
- ioprintf(c1out,_("Package %s is a virtual package provided by:\n"),
- Pkg.FullName(true).c_str());
-
- pkgCache::PrvIterator I = Pkg.ProvidesList();
- unsigned short provider = 0;
- for (; I.end() == false; I++)
- {
- pkgCache::PkgIterator Pkg = I.OwnerPkg();
-
- if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer())
- {
- c1out << " " << Pkg.FullName(true) << " " << I.OwnerVer().VerStr();
- if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false)
- c1out << _(" [Installed]");
- c1out << endl;
- ++provider;
- }
- }
- // if we found no candidate which provide this package, show non-candidates
- if (provider == 0)
- for (I = Pkg.ProvidesList(); I.end() == false; I++)
- c1out << " " << I.OwnerPkg().FullName(true) << " " << I.OwnerVer().VerStr()
- << _(" [Not candidate version]") << endl;
- else
- c1out << _("You should explicitly select one to install.") << endl;
- }
- else
- {
- ioprintf(c1out,
- _("Package %s is not available, but is referred to by another package.\n"
- "This may mean that the package is missing, has been obsoleted, or\n"
- "is only available from another source\n"),Pkg.FullName(true).c_str());
-
- string List;
- string VersionsList;
- SPtrArray<bool> Seen = new bool[Cache.Head().PackageCount];
- memset(Seen,0,Cache.Head().PackageCount*sizeof(*Seen));
- pkgCache::DepIterator Dep = Pkg.RevDependsList();
- for (; Dep.end() == false; Dep++)
- {
- if (Dep->Type != pkgCache::Dep::Replaces)
- continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
- continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += Dep.ParentPkg().FullName(true) + " ";
- //VersionsList += string(Dep.ParentPkg().CurVersion) + "\n"; ???
- }
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
- }
-
- _error->Error(_("Package %s has no installation candidate"),Pkg.FullName(true).c_str());
- return false;
- }
-
- Fix.Clear(Pkg);
- Fix.Protect(Pkg);
if (Remove == true)
{
- Fix.Remove(Pkg);
- Cache.MarkDelete(Pkg,_config->FindB("APT::Get::Purge",false));
- return true;
- }
-
- // Install it
- Cache.MarkInstall(Pkg,false);
- if (State.Install() == false)
- {
- if (_config->FindB("APT::Get::ReInstall",false) == true)
- {
- if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false)
- ioprintf(c1out,_("Reinstallation of %s is not possible, it cannot be downloaded.\n"),
- Pkg.FullName(true).c_str());
- else
- Cache.SetReInstall(Pkg,true);
- }
- else
- {
- if (AllowFail == true)
- ioprintf(c1out,_("%s is already the newest version.\n"),
- Pkg.FullName(true).c_str());
- }
- }
- else
- ExpectedInst++;
-
- // Install it with autoinstalling enabled (if we not respect the minial
- // required deps or the policy)
- if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
- Cache.MarkInstall(Pkg,true);
-
- return true;
-}
- /*}}}*/
-// TryToChangeVer - Try to change a candidate version /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool TryToChangeVer(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
- const char *VerTag,bool IsRel)
-{
- pkgVersionMatch Match(VerTag,(IsRel == true?pkgVersionMatch::Release :
- pkgVersionMatch::Version));
-
- pkgCache::VerIterator Ver = Match.Find(Pkg);
-
- if (Ver.end() == true)
- {
- if (IsRel == true)
- return _error->Error(_("Release '%s' for '%s' was not found"),
- VerTag,Pkg.FullName(true).c_str());
- return _error->Error(_("Version '%s' for '%s' was not found"),
- VerTag,Pkg.FullName(true).c_str());
- }
-
- if (strcmp(VerTag,Ver.VerStr()) != 0)
- {
- ioprintf(c1out,_("Selected version %s (%s) for %s\n"),
- Ver.VerStr(),Ver.RelStr().c_str(),Pkg.FullName(true).c_str());
- }
-
- Cache.SetCandidateVersion(Ver);
-
- // Set the all package to the same candidate
- if (Ver.Pseudo() == true)
- Cache.SetCandidateVersion(Match.Find(Pkg.Group().FindPkg("all")));
+ TryToRemove RemoveAction(Cache, Fix);
+ RemoveAction(Pkg.VersionList());
+ } else if (Cache[Pkg].CandidateVer != 0) {
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ InstallAction(Cache[Pkg].CandidateVerIter(Cache));
+ InstallAction.doAutoInstall();
+ } else
+ return AllowFail;
return true;
}
@@ -1624,61 +1687,6 @@ bool DoUpgrade(CommandLine &CmdL)
return InstallPackages(Cache,true);
}
/*}}}*/
-// DoInstallTask - Install task from the command line /*{{{*/
-// ---------------------------------------------------------------------
-/* Install named task */
-bool TryInstallTask(pkgDepCache &Cache, pkgProblemResolver &Fix,
- bool BrokenFix,
- unsigned int& ExpectedInst,
- const char *taskname,
- bool Remove)
-{
- const char *start, *end;
- pkgCache::PkgIterator Pkg;
- char buf[64*1024];
- regex_t Pattern;
-
- // get the records
- pkgRecords Recs(Cache);
-
- // build regexp for the task
- char S[300];
- snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", taskname);
- if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0)
- return _error->Error("Failed to compile task regexp");
-
- bool found = false;
- bool res = true;
-
- // two runs, first ignore dependencies, second install any missing
- for(int IgnoreBroken=1; IgnoreBroken >= 0; IgnoreBroken--)
- {
- for (Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++)
- {
- pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
- if(ver.end())
- continue;
- pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
- parser.GetRec(start,end);
- strncpy(buf, start, end-start);
- buf[end-start] = 0x0;
- if (regexec(&Pattern,buf,0,0,0) != 0)
- continue;
- res &= TryToInstall(Pkg,Cache,Fix,Remove,IgnoreBroken,ExpectedInst);
- found = true;
- }
- }
-
- // now let the problem resolver deal with any issues
- Fix.Resolve(true);
-
- if(!found)
- _error->Error(_("Couldn't find task %s"),taskname);
-
- regfree(&Pattern);
- return res;
-}
- /*}}}*/
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
@@ -1694,140 +1702,69 @@ bool DoInstall(CommandLine &CmdL)
if (Cache->BrokenCount() != 0)
BrokenFix = true;
- unsigned int AutoMarkChanged = 0;
- unsigned int ExpectedInst = 0;
- unsigned int Packages = 0;
pkgProblemResolver Fix(Cache);
-
- bool DefRemove = false;
+
+ static const unsigned short MOD_REMOVE = 1;
+ static const unsigned short MOD_INSTALL = 2;
+
+ unsigned short fallback = MOD_INSTALL;
if (strcasecmp(CmdL.FileList[0],"remove") == 0)
- DefRemove = true;
+ fallback = MOD_REMOVE;
else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
{
_config->Set("APT::Get::Purge", true);
- DefRemove = true;
+ fallback = MOD_REMOVE;
}
else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
{
_config->Set("APT::Get::AutomaticRemove", "true");
- DefRemove = true;
+ fallback = MOD_REMOVE;
}
- // new scope for the ActionGroup
- {
- pkgDepCache::ActionGroup group(Cache);
- for (const char **I = CmdL.FileList + 1; *I != 0; I++)
- {
- // Duplicate the string
- unsigned int Length = strlen(*I);
- char S[300];
- if (Length >= sizeof(S))
- continue;
- strcpy(S,*I);
-
- // See if we are removing and special indicators..
- bool Remove = DefRemove;
- char *VerTag = 0;
- bool VerIsRel = false;
- // this is a task!
- if (Length >= 1 && S[Length - 1] == '^')
- {
- S[--Length] = 0;
- // tasks must always be confirmed
- ExpectedInst += 1000;
- // see if we can install it
- TryInstallTask(Cache, Fix, BrokenFix, ExpectedInst, S, Remove);
- continue;
- }
+ std::list<APT::VersionSet::Modifier> mods;
+ mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDIDATE));
+ mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
+ APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::NEWEST));
+ CacheSetHelperAPTGet helper(c0out);
+ std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
+ CmdL.FileList + 1, mods, fallback, helper);
- while (Cache->FindPkg(S).end() == true)
- {
- // Handle an optional end tag indicating what to do
- if (Length >= 1 && S[Length - 1] == '-')
- {
- Remove = true;
- S[--Length] = 0;
- continue;
- }
-
- if (Length >= 1 && S[Length - 1] == '+')
- {
- Remove = false;
- S[--Length] = 0;
- continue;
- }
-
- char *Slash = strchr(S,'=');
- if (Slash != 0)
- {
- VerIsRel = false;
- *Slash = 0;
- VerTag = Slash + 1;
- }
-
- Slash = strchr(S,'/');
- if (Slash != 0)
- {
- VerIsRel = true;
- *Slash = 0;
- VerTag = Slash + 1;
- }
-
- break;
- }
-
- // Locate the package
- pkgCache::PkgIterator Pkg = Cache->FindPkg(S);
- Packages++;
- if (Pkg.end() == true)
- {
- APT::PackageSet pkgset = APT::PackageSet::FromRegEx(Cache, S, c1out);
- if (pkgset.empty() == true)
- return _error->Error(_("Couldn't find package %s"),S);
+ if (_error->PendingError() == true)
+ {
+ helper.showVirtualPackageErrors(Cache);
+ return false;
+ }
- // Regexs must always be confirmed
- ExpectedInst += 1000;
+ unsigned short order[] = { 0, 0, 0 };
+ if (fallback == MOD_INSTALL) {
+ order[0] = MOD_INSTALL;
+ order[1] = MOD_REMOVE;
+ } else {
+ order[0] = MOD_REMOVE;
+ order[1] = MOD_INSTALL;
+ }
- bool Hit = false;
- for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
- {
- if (VerTag != 0)
- if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
- return false;
+ TryToInstall InstallAction(Cache, Fix, BrokenFix);
+ TryToRemove RemoveAction(Cache, Fix);
- Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,
- ExpectedInst,false);
- }
+ // new scope for the ActionGroup
+ {
+ pkgDepCache::ActionGroup group(Cache);
- if (Hit == false)
- return _error->Error(_("Couldn't find package %s"),S);
+ for (unsigned short i = 0; order[i] != 0; ++i)
+ {
+ if (order[i] == MOD_INSTALL) {
+ InstallAction = std::for_each(verset[MOD_INSTALL].begin(), verset[MOD_INSTALL].end(), InstallAction);
+ InstallAction.doAutoInstall();
}
- else
- {
- if (VerTag != 0)
- if (TryToChangeVer(Pkg,Cache,VerTag,VerIsRel) == false)
- return false;
- if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false)
- return false;
-
- // see if we need to fix the auto-mark flag
- // e.g. apt-get install foo
- // where foo is marked automatic
- if(!Remove &&
- Cache[Pkg].Install() == false &&
- (Cache[Pkg].Flags & pkgCache::Flag::Auto) &&
- _config->FindB("APT::Get::ReInstall",false) == false &&
- _config->FindB("APT::Get::Only-Upgrade",false) == false &&
- _config->FindB("APT::Get::Download-Only",false) == false)
- {
- ioprintf(c1out,_("%s set to manually installed.\n"),
- Pkg.FullName(true).c_str());
- Cache->MarkAuto(Pkg,false);
- AutoMarkChanged++;
- }
- }
+ else if (order[i] == MOD_REMOVE)
+ RemoveAction = std::for_each(verset[MOD_REMOVE].begin(), verset[MOD_REMOVE].end(), RemoveAction);
}
+ if (_error->PendingError() == true)
+ return false;
+
/* If we are in the Broken fixing mode we do not attempt to fix the
problems. This is if the user invoked install without -f and gave
packages */
@@ -1874,7 +1811,7 @@ bool DoInstall(CommandLine &CmdL)
/* Print out a list of packages that are going to be installed extra
to what the user asked */
- if (Cache->InstCount() != ExpectedInst)
+ if (Cache->InstCount() != verset[MOD_INSTALL].size())
{
string List;
string VersionsList;
@@ -1993,14 +1930,15 @@ bool DoInstall(CommandLine &CmdL)
// if nothing changed in the cache, but only the automark information
// we write the StateFile here, otherwise it will be written in
// cache.commit()
- if (AutoMarkChanged > 0 &&
+ if (InstallAction.AutoMarkChanged > 0 &&
Cache->DelCount() == 0 && Cache->InstCount() == 0 &&
Cache->BadCount() == 0 &&
_config->FindB("APT::Get::Simulate",false) == false)
Cache->writeStateFile(NULL);
// See if we need to prompt
- if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
+ // FIXME: check if really the packages in the set are going to be installed
+ if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
return InstallPackages(Cache,false,false);
return InstallPackages(Cache,false);
@@ -2584,7 +2522,6 @@ bool DoBuildDep(CommandLine &CmdL)
}
// Install the requested packages
- unsigned int ExpectedInst = 0;
vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
pkgProblemResolver Fix(Cache);
bool skipAlternatives = false; // skip remaining alternatives in an or group
@@ -2615,7 +2552,7 @@ bool DoBuildDep(CommandLine &CmdL)
*/
if (IV.end() == false &&
Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
- TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
+ TryToInstallBuildDep(Pkg,Cache,Fix,true,false);
}
else // BuildDep || BuildDepIndep
{
@@ -2731,7 +2668,7 @@ bool DoBuildDep(CommandLine &CmdL)
if (_config->FindB("Debug::BuildDeps",false) == true)
cout << " Trying to install " << (*D).Package << endl;
- if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true)
+ if (TryToInstallBuildDep(Pkg,Cache,Fix,false,false) == true)
{
// We successfully installed something; skip remaining alternatives
skipAlternatives = hasAlternatives;
@@ -3021,7 +2958,7 @@ int main(int argc,const char *argv[]) /*{{{*/
}
// Deal with stdout not being a tty
- if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Setup the output streams
@@ -3042,13 +2979,11 @@ int main(int argc,const char *argv[]) /*{{{*/
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/
diff --git a/cmdline/cacheset.cc b/cmdline/cacheset.cc
new file mode 100644
index 000000000..78c9d3f6c
--- /dev/null
+++ b/cmdline/cacheset.cc
@@ -0,0 +1,515 @@
+// -*- mode: cpp; mode: fold -*-
+// Description /*{{{*/
+/* ######################################################################
+
+ Simple wrapper around a std::set to provide a similar interface to
+ a set of cache structures as to the complete set of all structures
+ in the pkgCache. Currently only Package is supported.
+
+ ##################################################################### */
+ /*}}}*/
+// Include Files /*{{{*/
+#include <apt-pkg/aptconfiguration.h>
+#include <apt-pkg/error.h>
+#include <apt-pkg/strutl.h>
+#include <apt-pkg/versionmatch.h>
+
+#include <apti18n.h>
+
+#include "cacheset.h"
+
+#include <vector>
+
+#include <regex.h>
+ /*}}}*/
+namespace APT {
+// FromTask - Return all packages in the cache from a specific task /*{{{*/
+PackageSet PackageSet::FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ size_t const archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ pattern.erase(archfound);
+ }
+
+ if (pattern[pattern.length() -1] != '^')
+ return APT::PackageSet(TASK);
+ pattern.erase(pattern.length()-1);
+
+ if (unlikely(Cache.GetPkgCache() == 0 || Cache.GetDepCache() == 0))
+ return APT::PackageSet(TASK);
+
+ PackageSet pkgset(TASK);
+ // get the records
+ pkgRecords Recs(Cache);
+
+ // build regexp for the task
+ regex_t Pattern;
+ char S[300];
+ snprintf(S, sizeof(S), "^Task:.*[, ]%s([, ]|$)", pattern.c_str());
+ if(regcomp(&Pattern,S, REG_EXTENDED | REG_NOSUB | REG_NEWLINE) != 0) {
+ _error->Error("Failed to compile task regexp");
+ return pkgset;
+ }
+
+ for (pkgCache::GrpIterator Grp = Cache->GrpBegin(); Grp.end() == false; ++Grp) {
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true)
+ continue;
+ pkgCache::VerIterator ver = Cache[Pkg].CandidateVerIter(Cache);
+ if(ver.end() == true)
+ continue;
+
+ pkgRecords::Parser &parser = Recs.Lookup(ver.FileList());
+ const char *start, *end;
+ parser.GetRec(start,end);
+ unsigned int const length = end - start;
+ char buf[length];
+ strncpy(buf, start, length);
+ buf[length-1] = '\0';
+ if (regexec(&Pattern, buf, 0, 0, 0) != 0)
+ continue;
+
+ pkgset.insert(Pkg);
+ }
+ regfree(&Pattern);
+
+ if (pkgset.empty() == true)
+ return helper.canNotFindTask(Cache, pattern);
+
+ helper.showTaskSelection(pkgset, pattern);
+ return pkgset;
+}
+ /*}}}*/
+// FromRegEx - Return all packages in the cache matching a pattern /*{{{*/
+PackageSet PackageSet::FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper) {
+ static const char * const isregex = ".?+*|[^$";
+ if (pattern.find_first_of(isregex) == std::string::npos)
+ return PackageSet(REGEX);
+
+ size_t archfound = pattern.find_last_of(':');
+ std::string arch = "native";
+ if (archfound != std::string::npos) {
+ arch = pattern.substr(archfound+1);
+ if (arch.find_first_of(isregex) == std::string::npos)
+ pattern.erase(archfound);
+ else
+ arch = "native";
+ }
+
+ regex_t Pattern;
+ int Res;
+ if ((Res = regcomp(&Pattern, pattern.c_str() , REG_EXTENDED | REG_ICASE | REG_NOSUB)) != 0) {
+ char Error[300];
+ regerror(Res, &Pattern, Error, sizeof(Error));
+ _error->Error(_("Regex compilation error - %s"), Error);
+ return PackageSet(REGEX);
+ }
+
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return PackageSet(REGEX);
+
+ PackageSet pkgset(REGEX);
+ for (pkgCache::GrpIterator Grp = Cache.GetPkgCache()->GrpBegin(); Grp.end() == false; ++Grp)
+ {
+ if (regexec(&Pattern, Grp.Name(), 0, 0, 0) != 0)
+ continue;
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(arch);
+ if (Pkg.end() == true) {
+ if (archfound == std::string::npos) {
+ std::vector<std::string> archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end() && Pkg.end() != true; ++a)
+ Pkg = Grp.FindPkg(*a);
+ }
+ if (Pkg.end() == true)
+ continue;
+ }
+
+ pkgset.insert(Pkg);
+ }
+ regfree(&Pattern);
+
+ if (pkgset.empty() == true)
+ return helper.canNotFindRegEx(Cache, pattern);
+
+ helper.showRegExSelection(pkgset, pattern);
+ return pkgset;
+}
+ /*}}}*/
+// FromName - Returns the package defined by this string /*{{{*/
+pkgCache::PkgIterator PackageSet::FromName(pkgCacheFile &Cache,
+ std::string const &str, CacheSetHelper &helper) {
+ std::string pkg = str;
+ size_t archfound = pkg.find_last_of(':');
+ std::string arch;
+ if (archfound != std::string::npos) {
+ arch = pkg.substr(archfound+1);
+ pkg.erase(archfound);
+ }
+
+ if (Cache.GetPkgCache() == 0)
+ return pkgCache::PkgIterator(Cache, 0);
+
+ pkgCache::PkgIterator Pkg(Cache, 0);
+ if (arch.empty() == true) {
+ pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg);
+ if (Grp.end() == false)
+ Pkg = Grp.FindPreferredPkg();
+ } else
+ Pkg = Cache.GetPkgCache()->FindPkg(pkg, arch);
+
+ if (Pkg.end() == true)
+ return helper.canNotFindPkgName(Cache, str);
+ return Pkg;
+}
+ /*}}}*/
+// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
+std::map<unsigned short, PackageSet> PackageSet::GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<PackageSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper) {
+ std::map<unsigned short, PackageSet> pkgsets;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ unsigned short modID = fallback;
+ std::string str = *I;
+ bool modifierPresent = false;
+ for (std::list<PackageSet::Modifier>::const_iterator mod = mods.begin();
+ mod != mods.end(); ++mod) {
+ size_t const alength = strlen(mod->Alias);
+ switch(mod->Pos) {
+ case PackageSet::Modifier::POSTFIX:
+ if (str.compare(str.length() - alength, alength,
+ mod->Alias, 0, alength) != 0)
+ continue;
+ str.erase(str.length() - alength);
+ modID = mod->ID;
+ break;
+ case PackageSet::Modifier::PREFIX:
+ continue;
+ case PackageSet::Modifier::NONE:
+ continue;
+ }
+ modifierPresent = true;
+ break;
+ }
+ if (modifierPresent == true) {
+ bool const errors = helper.showErrors(false);
+ pkgCache::PkgIterator Pkg = FromName(Cache, *I, helper);
+ helper.showErrors(errors);
+ if (Pkg.end() == false) {
+ pkgsets[fallback].insert(Pkg);
+ continue;
+ }
+ }
+ pkgsets[modID].insert(PackageSet::FromString(Cache, str, helper));
+ }
+ return pkgsets;
+}
+ /*}}}*/
+// FromCommandLine - Return all packages specified on commandline /*{{{*/
+PackageSet PackageSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper) {
+ PackageSet pkgset;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ PackageSet pset = FromString(Cache, *I, helper);
+ pkgset.insert(pset.begin(), pset.end());
+ }
+ return pkgset;
+}
+ /*}}}*/
+// FromString - Return all packages matching a specific string /*{{{*/
+PackageSet PackageSet::FromString(pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) {
+ _error->PushToStack();
+
+ PackageSet pkgset;
+ pkgCache::PkgIterator Pkg = FromName(Cache, str, helper);
+ if (Pkg.end() == false)
+ pkgset.insert(Pkg);
+ else {
+ pkgset = FromTask(Cache, str, helper);
+ if (pkgset.empty() == true) {
+ pkgset = FromRegEx(Cache, str, helper);
+ if (pkgset.empty() == true)
+ pkgset = helper.canNotFindPackage(Cache, str);
+ }
+ }
+
+ if (pkgset.empty() == false)
+ _error->RevertToStack();
+ else
+ _error->MergeWithStack();
+ return pkgset;
+}
+ /*}}}*/
+// GroupedFromCommandLine - Return all versions specified on commandline/*{{{*/
+std::map<unsigned short, VersionSet> VersionSet::GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper) {
+ std::map<unsigned short, VersionSet> versets;
+ for (const char **I = cmdline; *I != 0; ++I) {
+ unsigned short modID = fallback;
+ VersionSet::Version select = VersionSet::NEWEST;
+ std::string str = *I;
+ bool modifierPresent = false;
+ for (std::list<VersionSet::Modifier>::const_iterator mod = mods.begin();
+ mod != mods.end(); ++mod) {
+ if (modID == fallback && mod->ID == fallback)
+ select = mod->SelectVersion;
+ size_t const alength = strlen(mod->Alias);
+ switch(mod->Pos) {
+ case VersionSet::Modifier::POSTFIX:
+ if (str.compare(str.length() - alength, alength,
+ mod->Alias, 0, alength) != 0)
+ continue;
+ str.erase(str.length() - alength);
+ modID = mod->ID;
+ select = mod->SelectVersion;
+ break;
+ case VersionSet::Modifier::PREFIX:
+ continue;
+ case VersionSet::Modifier::NONE:
+ continue;
+ }
+ modifierPresent = true;
+ break;
+ }
+
+ if (modifierPresent == true) {
+ bool const errors = helper.showErrors(false);
+ VersionSet const vset = VersionSet::FromString(Cache, std::string(*I), select, helper, true);
+ helper.showErrors(errors);
+ if (vset.empty() == false) {
+ versets[fallback].insert(vset);
+ continue;
+ }
+ }
+ versets[modID].insert(VersionSet::FromString(Cache, str, select , helper));
+ }
+ return versets;
+}
+ /*}}}*/
+// FromCommandLine - Return all versions specified on commandline /*{{{*/
+APT::VersionSet VersionSet::FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper) {
+ VersionSet verset;
+ for (const char **I = cmdline; *I != 0; ++I)
+ verset.insert(VersionSet::FromString(Cache, *I, fallback, helper));
+ return verset;
+}
+ /*}}}*/
+// FromString - Returns all versions spedcified by a string /*{{{*/
+APT::VersionSet VersionSet::FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
+ bool const &onlyFromName) {
+ std::string ver;
+ bool verIsRel = false;
+ size_t const vertag = pkg.find_last_of("/=");
+ if (vertag != string::npos) {
+ ver = pkg.substr(vertag+1);
+ verIsRel = (pkg[vertag] == '/');
+ pkg.erase(vertag);
+ }
+ PackageSet pkgset;
+ if (onlyFromName == false)
+ pkgset = PackageSet::FromString(Cache, pkg, helper);
+ else {
+ pkgset.insert(PackageSet::FromName(Cache, pkg, helper));
+ }
+
+ VersionSet verset;
+ bool errors = true;
+ if (pkgset.getConstructor() != PackageSet::UNKNOWN)
+ errors = helper.showErrors(false);
+ for (PackageSet::const_iterator P = pkgset.begin();
+ P != pkgset.end(); ++P) {
+ if (vertag == string::npos) {
+ verset.insert(VersionSet::FromPackage(Cache, P, fallback, helper));
+ continue;
+ }
+ pkgCache::VerIterator V;
+ if (ver == "installed")
+ V = getInstalledVer(Cache, P, helper);
+ else if (ver == "candidate")
+ V = getCandidateVer(Cache, P, helper);
+ else {
+ pkgVersionMatch Match(ver, (verIsRel == true ? pkgVersionMatch::Release :
+ pkgVersionMatch::Version));
+ V = Match.Find(P);
+ if (V.end() == true) {
+ if (verIsRel == true)
+ _error->Error(_("Release '%s' for '%s' was not found"),
+ ver.c_str(), P.FullName(true).c_str());
+ else
+ _error->Error(_("Version '%s' for '%s' was not found"),
+ ver.c_str(), P.FullName(true).c_str());
+ continue;
+ }
+ }
+ if (V.end() == true)
+ continue;
+ helper.showSelectedVersion(P, V, ver, verIsRel);
+ verset.insert(V);
+ }
+ if (pkgset.getConstructor() != PackageSet::UNKNOWN)
+ helper.showErrors(errors);
+ return verset;
+}
+ /*}}}*/
+// FromPackage - versions from package based on fallback /*{{{*/
+VersionSet VersionSet::FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ VersionSet::Version const &fallback, CacheSetHelper &helper) {
+ VersionSet verset;
+ pkgCache::VerIterator V;
+ bool showErrors;
+ switch(fallback) {
+ case VersionSet::ALL:
+ if (P->VersionList != 0)
+ for (V = P.VersionList(); V.end() != true; ++V)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindAllVer(Cache, P));
+ break;
+ case VersionSet::CANDANDINST:
+ verset.insert(getInstalledVer(Cache, P, helper));
+ verset.insert(getCandidateVer(Cache, P, helper));
+ break;
+ case VersionSet::CANDIDATE:
+ verset.insert(getCandidateVer(Cache, P, helper));
+ break;
+ case VersionSet::INSTALLED:
+ verset.insert(getInstalledVer(Cache, P, helper));
+ break;
+ case VersionSet::CANDINST:
+ showErrors = helper.showErrors(false);
+ V = getCandidateVer(Cache, P, helper);
+ if (V.end() == true)
+ V = getInstalledVer(Cache, P, helper);
+ helper.showErrors(showErrors);
+ if (V.end() == false)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindInstCandVer(Cache, P));
+ break;
+ case VersionSet::INSTCAND:
+ showErrors = helper.showErrors(false);
+ V = getInstalledVer(Cache, P, helper);
+ if (V.end() == true)
+ V = getCandidateVer(Cache, P, helper);
+ helper.showErrors(showErrors);
+ if (V.end() == false)
+ verset.insert(V);
+ else
+ verset.insert(helper.canNotFindInstCandVer(Cache, P));
+ break;
+ case VersionSet::NEWEST:
+ if (P->VersionList != 0)
+ verset.insert(P.VersionList());
+ else
+ verset.insert(helper.canNotFindNewestVer(Cache, P));
+ break;
+ }
+ return verset;
+}
+ /*}}}*/
+// getCandidateVer - Returns the candidate version of the given package /*{{{*/
+pkgCache::VerIterator VersionSet::getCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
+ pkgCache::VerIterator Cand;
+ if (Cache.IsPolicyBuilt() == true || Cache.IsDepCacheBuilt() == false)
+ {
+ if (unlikely(Cache.GetPolicy() == 0))
+ return pkgCache::VerIterator(Cache);
+ Cand = Cache.GetPolicy()->GetCandidateVer(Pkg);
+ } else {
+ Cand = Cache[Pkg].CandidateVerIter(Cache);
+ }
+ if (Cand.end() == true)
+ return helper.canNotFindCandidateVer(Cache, Pkg);
+ return Cand;
+}
+ /*}}}*/
+// getInstalledVer - Returns the installed version of the given package /*{{{*/
+pkgCache::VerIterator VersionSet::getInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper) {
+ if (Pkg->CurrentVer == 0)
+ return helper.canNotFindInstalledVer(Cache, Pkg);
+ return Pkg.CurrentVer();
+}
+ /*}}}*/
+// canNotFindPkgName - handle the case no package has this name /*{{{*/
+pkgCache::PkgIterator CacheSetHelper::canNotFindPkgName(pkgCacheFile &Cache,
+ std::string const &str) {
+ if (ShowError == true)
+ _error->Error(_("Unable to locate package %s"), str.c_str());
+ return pkgCache::PkgIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindTask - handle the case no package is found for a task /*{{{*/
+PackageSet CacheSetHelper::canNotFindTask(pkgCacheFile &Cache, std::string pattern) {
+ if (ShowError == true)
+ _error->Error(_("Couldn't find task '%s'"), pattern.c_str());
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindRegEx - handle the case no package is found by a regex /*{{{*/
+PackageSet CacheSetHelper::canNotFindRegEx(pkgCacheFile &Cache, std::string pattern) {
+ if (ShowError == true)
+ _error->Error(_("Couldn't find any package by regex '%s'"), pattern.c_str());
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindPackage - handle the case no package is found from a string/*{{{*/
+PackageSet CacheSetHelper::canNotFindPackage(pkgCacheFile &Cache, std::string const &str) {
+ return PackageSet();
+}
+ /*}}}*/
+// canNotFindAllVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindAllVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select versions from package '%s' as it purely virtual"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindInstCandVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindInstCandVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindInstCandVer /*{{{*/
+VersionSet CacheSetHelper::canNotFindCandInstVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed nor candidate version from package '%s' as it has neither of them"), Pkg.FullName(true).c_str());
+ return VersionSet();
+}
+ /*}}}*/
+// canNotFindNewestVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindNewestVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select newest version from package '%s' as it is purely virtual"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindCandidateVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select candidate version from package %s as it has no candidate"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+// canNotFindInstalledVer /*{{{*/
+pkgCache::VerIterator CacheSetHelper::canNotFindInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg) {
+ if (ShowError == true)
+ _error->Error(_("Can't select installed version from package %s as it is not installed"), Pkg.FullName(true).c_str());
+ return pkgCache::VerIterator(Cache, 0);
+}
+ /*}}}*/
+}
diff --git a/apt-pkg/cacheset.h b/cmdline/cacheset.h
index 668d8039e..c8c3dd096 100644
--- a/apt-pkg/cacheset.h
+++ b/cmdline/cacheset.h
@@ -20,6 +20,48 @@
#include <apt-pkg/pkgcache.h>
/*}}}*/
namespace APT {
+class PackageSet;
+class VersionSet;
+class CacheSetHelper { /*{{{*/
+/** \class APT::CacheSetHelper
+ Simple base class with a lot of virtual methods which can be overridden
+ to alter the behavior or the output of the CacheSets.
+
+ This helper is passed around by the static methods in the CacheSets and
+ used every time they hit an error condition or something could be
+ printed out.
+*/
+public: /*{{{*/
+ CacheSetHelper(bool const &ShowError = true) : ShowError(ShowError) {};
+ virtual ~CacheSetHelper() {};
+
+ virtual void showTaskSelection(PackageSet const &pkgset, string const &pattern) {};
+ virtual void showRegExSelection(PackageSet const &pkgset, string const &pattern) {};
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ string const &ver, bool const &verIsRel) {};
+
+ virtual pkgCache::PkgIterator canNotFindPkgName(pkgCacheFile &Cache, std::string const &str);
+ virtual PackageSet canNotFindTask(pkgCacheFile &Cache, std::string pattern);
+ virtual PackageSet canNotFindRegEx(pkgCacheFile &Cache, std::string pattern);
+ virtual PackageSet canNotFindPackage(pkgCacheFile &Cache, std::string const &str);
+ virtual VersionSet canNotFindAllVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg);
+ virtual VersionSet canNotFindInstCandVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual VersionSet canNotFindCandInstVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindNewestVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindCandidateVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+ virtual pkgCache::VerIterator canNotFindInstalledVer(pkgCacheFile &Cache,
+ pkgCache::PkgIterator const &Pkg);
+
+ bool showErrors() const { return ShowError; };
+ bool showErrors(bool const &newValue) { if (ShowError == newValue) return ShowError; else return ((ShowError = newValue) == false); };
+ /*}}}*/
+protected:
+ bool ShowError;
+}; /*}}}*/
class PackageSet : public std::set<pkgCache::PkgIterator> { /*{{{*/
/** \class APT::PackageSet
@@ -28,7 +70,7 @@ class PackageSet : public std::set<pkgCache::PkgIterator> { /*{{{*/
pkgCache. */
public: /*{{{*/
/** \brief smell like a pkgCache::PkgIterator */
- class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {
+ class const_iterator : public std::set<pkgCache::PkgIterator>::const_iterator {/*{{{*/
public:
const_iterator(std::set<pkgCache::PkgIterator>::const_iterator x) :
std::set<pkgCache::PkgIterator>::const_iterator(x) {}
@@ -62,9 +104,25 @@ public: /*{{{*/
};
// 103. set::iterator is required to be modifiable, but this allows modification of keys
typedef APT::PackageSet::const_iterator iterator;
+ /*}}}*/
using std::set<pkgCache::PkgIterator>::insert;
inline void insert(pkgCache::PkgIterator const &P) { if (P.end() == false) std::set<pkgCache::PkgIterator>::insert(P); };
+ inline void insert(PackageSet const &pkgset) { insert(pkgset.begin(), pkgset.end()); };
+
+ /** \brief returns all packages in the cache who belong to the given task
+
+ A simple helper responsible for search for all members of a task
+ in the cache. Optional it prints a a notice about the
+ packages chosen cause of the given task.
+ \param Cache the packages are in
+ \param pattern name of the task
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
+ static APT::PackageSet FromTask(pkgCacheFile &Cache, std::string const &pattern) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromTask(Cache, pattern, helper);
+ }
/** \brief returns all packages in the cache whose name matchs a given pattern
@@ -73,22 +131,33 @@ public: /*{{{*/
packages chosen cause of the given package.
\param Cache the packages are in
\param pattern regular expression for package names
- \param out stream to print the notice to */
- static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, std::ostream &out);
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static APT::PackageSet FromRegEx(pkgCacheFile &Cache, std::string const &pattern) {
- std::ostream out (std::ofstream("/dev/null").rdbuf());
- return APT::PackageSet::FromRegEx(Cache, pattern, out);
+ CacheSetHelper helper;
+ return APT::PackageSet::FromRegEx(Cache, pattern, helper);
}
/** \brief returns all packages specified by a string
\param Cache the packages are in
\param string String the package name(s) should be extracted from
- \param out stream to print various notices to */
- static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, std::ostream &out);
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
static APT::PackageSet FromString(pkgCacheFile &Cache, std::string const &string) {
- std::ostream out (std::ofstream("/dev/null").rdbuf());
- return APT::PackageSet::FromString(Cache, string, out);
+ CacheSetHelper helper;
+ return APT::PackageSet::FromString(Cache, string, helper);
+ }
+
+ /** \brief returns a package specified by a string
+
+ \param Cache the package is in
+ \param string String the package name should be extracted from
+ \param helper responsible for error and message handling */
+ static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string, CacheSetHelper &helper);
+ static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &string) {
+ CacheSetHelper helper;
+ return APT::PackageSet::FromName(Cache, string, helper);
}
/** \brief returns all packages specified on the commandline
@@ -97,11 +166,11 @@ public: /*{{{*/
No special package command is supported, just plain names.
\param Cache the packages are in
\param cmdline Command line the package names should be extracted from
- \param out stream to print various notices to */
- static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, std::ostream &out);
+ \param helper responsible for error and message handling */
+ static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
static APT::PackageSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
- std::ostream out (std::ofstream("/dev/null").rdbuf());
- return APT::PackageSet::FromCommandLine(Cache, cmdline, out);
+ CacheSetHelper helper;
+ return APT::PackageSet::FromCommandLine(Cache, cmdline, helper);
}
struct Modifier {
@@ -112,18 +181,38 @@ public: /*{{{*/
Modifier (unsigned short const &id, const char * const alias, Position const &pos) : ID(id), Alias(alias), Pos(pos) {};
};
+ /** \brief group packages by a action modifiers
+
+ At some point it is needed to get from the same commandline
+ different package sets grouped by a modifier. Take
+ apt-get install apt awesome-
+ as an example.
+ \param Cache the packages are in
+ \param cmdline Command line the package names should be extracted from
+ \param mods list of modifiers the method should accept
+ \param fallback the default modifier group for a package
+ \param helper responsible for error and message handling */
static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
pkgCacheFile &Cache, const char **cmdline,
std::list<PackageSet::Modifier> const &mods,
- unsigned short const &fallback, std::ostream &out);
+ unsigned short const &fallback, CacheSetHelper &helper);
static std::map<unsigned short, PackageSet> GroupedFromCommandLine(
pkgCacheFile &Cache, const char **cmdline,
std::list<PackageSet::Modifier> const &mods,
unsigned short const &fallback) {
- std::ostream out (std::ofstream("/dev/null").rdbuf());
+ CacheSetHelper helper;
return APT::PackageSet::GroupedFromCommandLine(Cache, cmdline,
- mods, fallback, out);
+ mods, fallback, helper);
}
+
+ enum Constructor { UNKNOWN, REGEX, TASK };
+ Constructor getConstructor() const { return ConstructedBy; };
+
+ PackageSet() : ConstructedBy(UNKNOWN) {};
+ PackageSet(Constructor const &by) : ConstructedBy(by) {};
+ /*}}}*/
+private: /*{{{*/
+ Constructor ConstructedBy;
/*}}}*/
}; /*}}}*/
class VersionSet : public std::set<pkgCache::VerIterator> { /*{{{*/
@@ -134,7 +223,7 @@ class VersionSet : public std::set<pkgCache::VerIterator> { /*{{{*/
pkgCache. */
public: /*{{{*/
/** \brief smell like a pkgCache::VerIterator */
- class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {
+ class const_iterator : public std::set<pkgCache::VerIterator>::const_iterator {/*{{{*/
public:
const_iterator(std::set<pkgCache::VerIterator>::const_iterator x) :
std::set<pkgCache::VerIterator>::const_iterator(x) {}
@@ -168,11 +257,13 @@ public: /*{{{*/
inline bool Pseudo() const { return (**this).Pseudo(); };
inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); };
};
+ /*}}}*/
// 103. set::iterator is required to be modifiable, but this allows modification of keys
typedef APT::VersionSet::const_iterator iterator;
using std::set<pkgCache::VerIterator>::insert;
inline void insert(pkgCache::VerIterator const &V) { if (V.end() == false) std::set<pkgCache::VerIterator>::insert(V); };
+ inline void insert(VersionSet const &verset) { insert(verset.begin(), verset.end()); };
/** \brief specifies which version(s) will be returned if non is given */
enum Version {
@@ -198,41 +289,86 @@ public: /*{{{*/
non specifically requested and executes regex's if needed on names.
\param Cache the packages and versions are in
\param cmdline Command line the versions should be extracted from
- \param out stream to print various notices to */
+ \param helper responsible for error and message handling */
static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
- APT::VersionSet::Version const &fallback, std::ostream &out);
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper);
static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline,
APT::VersionSet::Version const &fallback) {
- std::ostream out (std::ofstream("/dev/null").rdbuf());
- return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, out);
+ CacheSetHelper helper;
+ return APT::VersionSet::FromCommandLine(Cache, cmdline, fallback, helper);
}
static APT::VersionSet FromCommandLine(pkgCacheFile &Cache, const char **cmdline) {
return APT::VersionSet::FromCommandLine(Cache, cmdline, CANDINST);
}
+
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback, CacheSetHelper &helper,
+ bool const &onlyFromName = false);
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg,
+ APT::VersionSet::Version const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::FromString(Cache, pkg, fallback, helper);
+ }
+ static APT::VersionSet FromString(pkgCacheFile &Cache, std::string pkg) {
+ return APT::VersionSet::FromString(Cache, pkg, CANDINST);
+ }
+
+ /** \brief returns all versions specified for the package
+
+ \param Cache the package and versions are in
+ \param P the package in question
+ \param fallback the version(s) you want to get
+ \param helper the helper used for display and error handling */
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ VersionSet::Version const &fallback, CacheSetHelper &helper);
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P,
+ APT::VersionSet::Version const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::FromPackage(Cache, P, fallback, helper);
+ }
+ static APT::VersionSet FromPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &P) {
+ return APT::VersionSet::FromPackage(Cache, P, CANDINST);
+ }
+
+ struct Modifier {
+ enum Position { NONE, PREFIX, POSTFIX };
+ unsigned short ID;
+ const char * const Alias;
+ Position Pos;
+ VersionSet::Version SelectVersion;
+ Modifier (unsigned short const &id, const char * const alias, Position const &pos,
+ VersionSet::Version const &select) : ID(id), Alias(alias), Pos(pos),
+ SelectVersion(select) {};
+ };
+
+ static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback, CacheSetHelper &helper);
+ static std::map<unsigned short, VersionSet> GroupedFromCommandLine(
+ pkgCacheFile &Cache, const char **cmdline,
+ std::list<VersionSet::Modifier> const &mods,
+ unsigned short const &fallback) {
+ CacheSetHelper helper;
+ return APT::VersionSet::GroupedFromCommandLine(Cache, cmdline,
+ mods, fallback, helper);
+ }
/*}}}*/
protected: /*{{{*/
/** \brief returns the candidate version of the package
\param Cache to be used to query for information
- \param Pkg we want the candidate version from this package
- \param AllowError add an error to the stack if not */
+ \param Pkg we want the candidate version from this package */
static pkgCache::VerIterator getCandidateVer(pkgCacheFile &Cache,
- pkgCache::PkgIterator const &Pkg, bool const &AllowError = false);
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
/** \brief returns the installed version of the package
\param Cache to be used to query for information
- \param Pkg we want the installed version from this package
- \param AllowError add an error to the stack if not */
+ \param Pkg we want the installed version from this package */
static pkgCache::VerIterator getInstalledVer(pkgCacheFile &Cache,
- pkgCache::PkgIterator const &Pkg, bool const &AllowError = false);
-
-
- static bool AddSelectedVersion(pkgCacheFile &Cache, VersionSet &verset,
- pkgCache::PkgIterator const &P, VersionSet::Version const &fallback,
- bool const &AllowError = false);
-
+ pkgCache::PkgIterator const &Pkg, CacheSetHelper &helper);
/*}}}*/
}; /*}}}*/
}
diff --git a/cmdline/makefile b/cmdline/makefile
index 917ccc96a..4ffe49ee0 100644
--- a/cmdline/makefile
+++ b/cmdline/makefile
@@ -9,14 +9,14 @@ include ../buildlib/defaults.mak
PROGRAM=apt-cache
SLIBS = -lapt-pkg $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-cache.cc
+SOURCE = apt-cache.cc cacheset.cc
include $(PROGRAM_H)
# The apt-get program
PROGRAM=apt-get
SLIBS = -lapt-pkg -lutil $(INTLLIBS)
LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-get.cc acqprogress.cc
+SOURCE = apt-get.cc acqprogress.cc cacheset.cc
include $(PROGRAM_H)
# The apt-config program
diff --git a/debian/changelog b/debian/changelog
index 1bf6815a5..dab703c6b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,47 @@
-apt (0.7.26~exp8) experimental; urgency=low
+apt (0.7.26~exp8) UNRELEASED; urgency=low
+ [ David Kalnischkies ]
+ * cmdline/cacheset.cc:
+ - doesn't include it in the library for now as it is too volatile
+ - get the candidate either from an already built depcache
+ or use the policy which is a bit faster than depcache generation
+ - get packages by task^ with FromTask()
+ - only print errors if all tries to get a package by string failed
+ - factor out code to get a single package FromName()
+ - check in Grouped* first without modifier interpretation
+ * cmdline/apt-get.cc:
+ - use the cachsets in the install commands
+ - make the specify order of packages irrelevant (Closes: #196021)
+ * apt-pkg/orderlist.cc:
+ - untouched packages are never missing
+ * apt-pkg/packagemanager.cc:
+ - packages that are not touched doesn't need to be unpacked
+ * debian/control:
+ - remove intltool's dependency as it is an ubuntu artefact
+ * apt-pkg/depcache.cc:
+ - SetCandidateVer for all pseudo packages
+ - SetReInstall for the "all" package of a pseudo package
+ - use the new MatchAgainstConfig for the DefaultRootSetFunc
+ - always mark the all package if a pseudo package is marked for install
+ * apt-pkg/contrib/error.{cc,h}:
+ - complete rewrite but use the same API
+ - add NOTICE and DEBUG as new types of a message
+ - add a simple stack handling to be able to delay error handling
+ * apt-pkg/aptconfiguration.cc:
+ - show a deprecation notice for APT::Acquire::Translation
+ * apt-pkg/contrib/configuration.{cc,h}:
+ - add a wrapper to match strings against configurable regex patterns
+ * apt-pkg/contrib/fileutl.cc:
+ - show notice about ignored file instead of being always silent
+ - add a Dir::Ignore-Files-Silently list option to control the notice
+ * apt-pkg/policy.h:
+ - add another round of const& madness as the previous round accidentally
+ NOT overrides the virtual GetCandidateVer() method (Closes: #587725)
+ * apt-pkg/pkgcachegen.{cc,h}:
+ - make the used MMap moveable (and therefore dynamic resizeable) by
+ applying (some) mad pointer magic (Closes: #195018)
+
+ [ Julian Andres Klode ]
* methods/ftp.h:
- Handle different logins on the same server (Closes: #586904).
* apt-pkg/deb/deblistparser.cc:
@@ -13,7 +55,7 @@ apt (0.7.26~exp8) experimental; urgency=low
* debian/control:
- Set Standards-Version to 3.9.0
- -- Julian Andres Klode <jak@debian.org> Thu, 24 Jun 2010 10:56:39 +0200
+ -- David Kalnischkies <kalnischkies@gmail.com> Mon, 05 Jul 2010 12:05:30 +0200
apt (0.7.26~exp7) experimental; urgency=low
diff --git a/debian/control b/debian/control
index 8bc43568f..d482f2d0b 100644
--- a/debian/control
+++ b/debian/control
@@ -6,7 +6,7 @@ Uploaders: Michael Vogt <mvo@debian.org>, Otavio Salvador <otavio@debian.org>,
Christian Perrier <bubulle@debian.org>, Daniel Burrows <dburrows@debian.org>,
Luca Bruno <lethalman88@gmail.com>, Julian Andres Klode <jak@debian.org>
Standards-Version: 3.9.0
-Build-Depends: debhelper (>= 5.0), libdb-dev, gettext (>= 0.12), libcurl4-gnutls-dev | libcurl3-gnutls-dev (>= 7.15.5), debiandoc-sgml, xsltproc, docbook-xsl, po4a (>= 0.34-2), autotools-dev, autoconf, automake, doxygen, intltool
+Build-Depends: debhelper (>= 5.0), libdb-dev, gettext (>= 0.12), libcurl4-gnutls-dev | libcurl3-gnutls-dev (>= 7.15.5), debiandoc-sgml, xsltproc, docbook-xsl, po4a (>= 0.34-2), autotools-dev, autoconf, automake, doxygen
Build-Conflicts: autoconf2.13, automake1.4
Package: apt
diff --git a/doc/apt.conf.5.xml b/doc/apt.conf.5.xml
index 0cf4bb663..39e2c8e6b 100644
--- a/doc/apt.conf.5.xml
+++ b/doc/apt.conf.5.xml
@@ -507,6 +507,15 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
will be looked up in
<filename>/tmp/staging/var/lib/dpkg/status</filename>.
</para>
+
+ <para>
+ The <literal>Ignore-Files-Silently</literal> list can be used to specify
+ which files APT should silently ignore while parsing the files in the
+ fragment directories. Per default a file which end with <literal>.disabled</literal>,
+ <literal>~</literal>, <literal>.bak</literal> or <literal>.dpkg-[a-z]+</literal>
+ is silently ignored. As seen in the last default value these patterns can use regular
+ expression syntax.
+ </para>
</refsect1>
<refsect1><title>APT in DSelect</title>
diff --git a/test/libapt/globalerror_test.cc b/test/libapt/globalerror_test.cc
new file mode 100644
index 000000000..b2752255f
--- /dev/null
+++ b/test/libapt/globalerror_test.cc
@@ -0,0 +1,77 @@
+#include <apt-pkg/error.h>
+
+#include "assert.h"
+#include <string>
+
+int main(int argc,char *argv[])
+{
+ equals(_error->empty(), true);
+ equals(_error->PendingError(), false);
+ equals(_error->Notice("%s Notice", "A"), false);
+ equals(_error->empty(), true);
+ equals(_error->empty(GlobalError::DEBUG), false);
+ equals(_error->PendingError(), false);
+ equals(_error->Error("%s horrible %s %d times", "Something", "happend", 2), false);
+ equals(_error->PendingError(), true);
+ std::string text;
+ equals(_error->PopMessage(text), false);
+ equals(_error->PendingError(), true);
+ equals(text, "A Notice");
+ equals(_error->PopMessage(text), true);
+ equals(text, "Something horrible happend 2 times");
+ equals(_error->empty(GlobalError::DEBUG), true);
+ equals(_error->PendingError(), false);
+ equals(_error->Error("%s horrible %s %d times", "Something", "happend", 2), false);
+ equals(_error->PendingError(), true);
+ equals(_error->empty(GlobalError::FATAL), false);
+ _error->Discard();
+
+ equals(_error->empty(), true);
+ equals(_error->PendingError(), false);
+ equals(_error->Notice("%s Notice", "A"), false);
+ equals(_error->Error("%s horrible %s %d times", "Something", "happend", 2), false);
+ equals(_error->PendingError(), true);
+ equals(_error->empty(GlobalError::NOTICE), false);
+ _error->PushToStack();
+ equals(_error->empty(GlobalError::NOTICE), true);
+ equals(_error->PendingError(), false);
+ equals(_error->Warning("%s Warning", "A"), false);
+ equals(_error->empty(GlobalError::ERROR), true);
+ equals(_error->PendingError(), false);
+ _error->RevertToStack();
+ equals(_error->empty(GlobalError::ERROR), false);
+ equals(_error->PendingError(), true);
+ equals(_error->PopMessage(text), false);
+ equals(_error->PendingError(), true);
+ equals(text, "A Notice");
+ equals(_error->PopMessage(text), true);
+ equals(text, "Something horrible happend 2 times");
+ equals(_error->PendingError(), false);
+ equals(_error->empty(), true);
+
+ equals(_error->Notice("%s Notice", "A"), false);
+ equals(_error->Error("%s horrible %s %d times", "Something", "happend", 2), false);
+ equals(_error->PendingError(), true);
+ equals(_error->empty(GlobalError::NOTICE), false);
+ _error->PushToStack();
+ equals(_error->empty(GlobalError::NOTICE), true);
+ equals(_error->PendingError(), false);
+ equals(_error->Warning("%s Warning", "A"), false);
+ equals(_error->empty(GlobalError::ERROR), true);
+ equals(_error->PendingError(), false);
+ _error->MergeWithStack();
+ equals(_error->empty(GlobalError::ERROR), false);
+ equals(_error->PendingError(), true);
+ equals(_error->PopMessage(text), false);
+ equals(_error->PendingError(), true);
+ equals(text, "A Notice");
+ equals(_error->PopMessage(text), true);
+ equals(text, "Something horrible happend 2 times");
+ equals(_error->PendingError(), false);
+ equals(_error->empty(), false);
+ equals(_error->PopMessage(text), false);
+ equals(text, "A Warning");
+ equals(_error->empty(), true);
+
+ return 0;
+}
diff --git a/test/libapt/makefile b/test/libapt/makefile
index ee3401b35..50058262e 100644
--- a/test/libapt/makefile
+++ b/test/libapt/makefile
@@ -30,13 +30,19 @@ SOURCE = getlistoffilesindir_test.cc
include $(PROGRAM_H)
# Program for testing CommandLine reconstruction
-PROGRAM = commandlineasstring${BASENAME}
+PROGRAM = CommandlineAsString${BASENAME}
SLIBS = -lapt-pkg
SOURCE = commandlineasstring_test.cc
include $(PROGRAM_H)
# Program for testing debians version comparing
-PROGRAM = compareversion${BASENAME}
+PROGRAM = CompareVersion${BASENAME}
SLIBS = -lapt-pkg
SOURCE = compareversion_test.cc
include $(PROGRAM_H)
+
+# test the GlobalError stack class
+PROGRAM = GlobalError${BASENAME}
+SLIBS = -lapt-pkg
+SOURCE = globalerror_test.cc
+include $(PROGRAM_H)
diff --git a/test/libapt/parsedepends_test.cc b/test/libapt/parsedepends_test.cc
index b7befa561..7b496878d 100644
--- a/test/libapt/parsedepends_test.cc
+++ b/test/libapt/parsedepends_test.cc
@@ -21,6 +21,12 @@ int main(int argc,char *argv[]) {
"apt (>= 0.7.25), "
"not-for-me [ !dsk ], "
"only-for-me [ dsk ], "
+ "any-for-me [ any ], "
+ "not-for-darwin [ !darwin-any ], "
+ "cpu-for-me [ any-dsk ], "
+ "os-for-me [ linux-any ], "
+ "cpu-not-for-me [ any-amd64 ], "
+ "os-not-for-me [ kfreebsd-any ], "
"overlord-dev:any (= 7.15.3~) | overlord-dev:native (>> 7.15.5), "
;
@@ -100,6 +106,68 @@ test:
Start++;
}
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("any-for-me", Package);
+ equals("", Version);
+ equals(Null | pkgCache::Dep::NoOp, Op);
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("not-for-darwin", Package);
+ equals("", Version);
+ equals(Null | pkgCache::Dep::NoOp, Op);
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("cpu-for-me", Package);
+ equals("", Version);
+ equals(Null | pkgCache::Dep::NoOp, Op);
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("os-for-me", Package);
+ equals("", Version);
+ equals(Null | pkgCache::Dep::NoOp, Op);
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("", Package); // cpu-not-for-me
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
+ if (ParseArchFlags == true) {
+ Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+ equals("", Package); // os-not-for-me
+ } else {
+ equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+ Start = strstr(Start, ",");
+ Start++;
+ }
+
Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
if (StripMultiArch == true)
equals("overlord-dev", Package);