summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/cachefilter.cc51
-rw-r--r--apt-pkg/cachefilter.h30
-rw-r--r--apt-pkg/cacheset.cc54
-rw-r--r--apt-pkg/cacheset.h1
-rw-r--r--apt-pkg/deb/debindexfile.cc3
-rw-r--r--apt-pkg/deb/deblistparser.cc93
-rw-r--r--apt-pkg/edsp/edspindexfile.cc3
-rw-r--r--apt-pkg/pkgcache.cc2
-rw-r--r--apt-pkg/pkgcachegen.cc5
9 files changed, 180 insertions, 62 deletions
diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc
index fb444208c..35f95fe22 100644
--- a/apt-pkg/cachefilter.cc
+++ b/apt-pkg/cachefilter.cc
@@ -9,10 +9,12 @@
#include <apt-pkg/cachefilter.h>
#include <apt-pkg/error.h>
#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/strutl.h>
#include <string>
#include <regex.h>
+#include <fnmatch.h>
#include <apti18n.h>
/*}}}*/
@@ -52,5 +54,54 @@ PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/
delete pattern;
}
/*}}}*/
+
+// CompleteArch to <kernel>-<cpu> tuple /*{{{*/
+//----------------------------------------------------------------------
+/* The complete architecture, consisting of <kernel>-<cpu>. */
+static std::string CompleteArch(std::string const &arch) {
+ if (arch.find('-') != std::string::npos) {
+ // ensure that only -any- is replaced and not something like company-
+ std::string complete = std::string("-").append(arch).append("-");
+ complete = SubstVar(complete, "-any-", "-*-");
+ complete = complete.substr(1, complete.size()-2);
+ return complete;
+ }
+ else if (arch == "armel") return "linux-arm";
+ else if (arch == "armhf") return "linux-arm";
+ else if (arch == "lpia") return "linux-i386";
+ else if (arch == "powerpcspe") return "linux-powerpc";
+ else if (arch == "uclibc-linux-armel") return "linux-arm";
+ else if (arch == "uclinux-armel") return "uclinux-arm";
+ else if (arch == "any") return "*-*";
+ else return "linux-" + arch;
+}
+ /*}}}*/
+PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern) :/*{{{*/
+ literal(pattern), isPattern(isPattern), d(NULL) {
+ complete = CompleteArch(pattern);
+}
+ /*}}}*/
+bool PackageArchitectureMatchesSpecification::operator() (char const * const &arch) {/*{{{*/
+ if (strcmp(literal.c_str(), arch) == 0 ||
+ strcmp(complete.c_str(), arch) == 0)
+ return true;
+ std::string const pkgarch = CompleteArch(arch);
+ if (isPattern == true)
+ return fnmatch(complete.c_str(), pkgarch.c_str(), 0) == 0;
+ return fnmatch(pkgarch.c_str(), complete.c_str(), 0) == 0;
+}
+ /*}}}*/
+bool PackageArchitectureMatchesSpecification::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/
+ return (*this)(Pkg.Arch());
+}
+ /*}}}*/
+bool PackageArchitectureMatchesSpecification::operator() (pkgCache::VerIterator const &Ver) {/*{{{*/
+ return (*this)(Ver.ParentPkg());
+}
+ /*}}}*/
+PackageArchitectureMatchesSpecification::~PackageArchitectureMatchesSpecification() { /*{{{*/
+}
+ /*}}}*/
+
}
}
diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h
index 5d426008b..25cd43f47 100644
--- a/apt-pkg/cachefilter.h
+++ b/apt-pkg/cachefilter.h
@@ -26,6 +26,36 @@ public:
~PackageNameMatchesRegEx();
};
/*}}}*/
+// PackageArchitectureMatchesSpecification /*{{{*/
+/** \class PackageArchitectureMatchesSpecification
+ \brief matching against architecture specification strings
+
+ The strings are of the format <kernel>-<cpu> where either component,
+ or the whole string, can be the wildcard "any" as defined in
+ debian-policy ยง11.1 "Architecture specification strings".
+
+ Examples: i386, mipsel, linux-any, any-amd64, any */
+class PackageArchitectureMatchesSpecification {
+ std::string literal;
+ std::string complete;
+ bool isPattern;
+ /** \brief dpointer placeholder (for later in case we need it) */
+ void *d;
+public:
+ /** \brief matching against architecture specification strings
+ *
+ * @param pattern is the architecture specification string
+ * @param isPattern defines if the given \b pattern is a
+ * architecture specification pattern to match others against
+ * or if it is the fixed string and matched against patterns
+ */
+ PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern = true);
+ bool operator() (char const * const &arch);
+ bool operator() (pkgCache::PkgIterator const &Pkg);
+ bool operator() (pkgCache::VerIterator const &Ver);
+ ~PackageArchitectureMatchesSpecification();
+};
+ /*}}}*/
}
}
#endif
diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc
index e2dbe0e57..784d1f0bf 100644
--- a/apt-pkg/cacheset.cc
+++ b/apt-pkg/cacheset.cc
@@ -182,15 +182,61 @@ pkgCache::PkgIterator PackageContainerInterface::FromName(pkgCacheFile &Cache,
return Pkg;
}
/*}}}*/
+// FromGroup - Returns the package defined by this string /*{{{*/
+bool PackageContainerInterface::FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache,
+ std::string pkg, CacheSetHelper &helper) {
+ if (unlikely(Cache.GetPkgCache() == 0))
+ return false;
+
+ size_t const archfound = pkg.find_last_of(':');
+ std::string arch;
+ if (archfound != std::string::npos) {
+ arch = pkg.substr(archfound+1);
+ pkg.erase(archfound);
+ }
+
+ pkgCache::GrpIterator Grp = Cache.GetPkgCache()->FindGrp(pkg);
+ if (Grp.end() == false) {
+ if (arch.empty() == true) {
+ pkgCache::PkgIterator Pkg = Grp.FindPreferredPkg();
+ if (Pkg.end() == false)
+ {
+ pci->insert(Pkg);
+ return true;
+ }
+ } else {
+ bool found = false;
+ // for 'linux-any' return the first package matching, for 'linux-*' return all matches
+ bool const isGlobal = arch.find('*') != std::string::npos;
+ APT::CacheFilter::PackageArchitectureMatchesSpecification pams(arch);
+ for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg)) {
+ if (pams(Pkg) == false)
+ continue;
+ pci->insert(Pkg);
+ found = true;
+ if (isGlobal == false)
+ break;
+ }
+ if (found == true)
+ return true;
+ }
+ }
+
+ pkgCache::PkgIterator Pkg = helper.canNotFindPkgName(Cache, pkg);
+ if (Pkg.end() == true)
+ return false;
+
+ pci->insert(Pkg);
+ return true;
+}
+ /*}}}*/
// FromString - Return all packages matching a specific string /*{{{*/
bool PackageContainerInterface::FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str, CacheSetHelper &helper) {
bool found = true;
_error->PushToStack();
- pkgCache::PkgIterator Pkg = FromName(Cache, str, helper);
- if (Pkg.end() == false)
- pci->insert(Pkg);
- else if (FromTask(pci, Cache, str, helper) == false &&
+ if (FromGroup(pci, Cache, str, helper) == false &&
+ FromTask(pci, Cache, str, helper) == false &&
FromRegEx(pci, Cache, str, helper) == false)
{
helper.canNotFindPackage(pci, Cache, str);
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index 5b9900603..2a45910ba 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -139,6 +139,7 @@ public:
static bool FromTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static pkgCache::PkgIterator FromName(pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
+ static bool FromGroup(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern, CacheSetHelper &helper);
static bool FromString(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &pattern, CacheSetHelper &helper);
static bool FromCommandLine(PackageContainerInterface * const pci, pkgCacheFile &Cache, const char **cmdline, CacheSetHelper &helper);
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index 76c740341..de645bb6e 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -602,7 +602,8 @@ bool debStatusIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
CFile->Size = Pkg.FileSize();
CFile->mtime = Pkg.ModificationTime();
- CFile->Archive = Gen.WriteUniqString("now");
+ map_ptrloc const storage = Gen.WriteUniqString("now");
+ CFile->Archive = storage;
if (Gen.MergeList(Parser) == false)
return _error->Error("Problem with MergeList %s",File.c_str());
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 4948c9be4..e93e51af3 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -15,6 +15,7 @@
#include <apt-pkg/deblistparser.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/cachefilter.h>
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/fileutl.h>
@@ -22,7 +23,6 @@
#include <apt-pkg/md5.h>
#include <apt-pkg/macros.h>
-#include <fnmatch.h>
#include <ctype.h>
/*}}}*/
@@ -464,22 +464,6 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
}
return I;
}
-
-/*
- * CompleteArch:
- *
- * The complete architecture, consisting of <kernel>-<cpu>.
- */
-static string CompleteArch(std::string const &arch) {
- if (arch == "armel") return "linux-arm";
- if (arch == "armhf") return "linux-arm";
- if (arch == "lpia") return "linux-i386";
- if (arch == "powerpcspe") return "linux-powerpc";
- if (arch == "uclibc-linux-armel") return "linux-arm";
- if (arch == "uclinux-armel") return "uclinux-arm";
-
- return (arch.find("-") != string::npos) ? arch : "linux-" + arch;
-}
/*}}}*/
// ListParser::ParseDepends - Parse a dependency element /*{{{*/
// ---------------------------------------------------------------------
@@ -556,58 +540,59 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
if (ParseArchFlags == true)
{
- string completeArch = CompleteArch(arch);
+ APT::CacheFilter::PackageArchitectureMatchesSpecification matchesArch(arch, false);
// Parse an architecture
if (I != Stop && *I == '[')
{
+ ++I;
// malformed
- I++;
- if (I == Stop)
- return 0;
-
- const char *End = I;
- bool Found = false;
- bool NegArch = false;
- while (I != Stop)
+ if (unlikely(I == Stop))
+ return 0;
+
+ const char *End = I;
+ bool Found = false;
+ bool NegArch = false;
+ while (I != Stop)
{
- // look for whitespace or ending ']'
- while (End != Stop && !isspace(*End) && *End != ']')
- End++;
-
- if (End == Stop)
+ // look for whitespace or ending ']'
+ for (;End != Stop && !isspace(*End) && *End != ']'; ++End);
+
+ if (unlikely(End == Stop))
return 0;
if (*I == '!')
- {
+ {
NegArch = true;
- I++;
- }
+ ++I;
+ }
- if (stringcmp(arch,I,End) == 0) {
+ std::string arch(I, End);
+ if (arch.empty() == false && matchesArch(arch.c_str()) == true)
+ {
Found = true;
- } else {
- std::string wildcard = SubstVar(string(I, End), "any", "*");
- if (fnmatch(wildcard.c_str(), completeArch.c_str(), 0) == 0)
- Found = true;
+ if (I[-1] != '!')
+ NegArch = false;
+ // we found a match, so fast-forward to the end of the wildcards
+ for (; End != Stop && *End != ']'; ++End);
}
-
+
if (*End++ == ']') {
I = End;
break;
}
-
+
I = End;
for (;I != Stop && isspace(*I) != 0; I++);
- }
+ }
- if (NegArch)
+ if (NegArch == true)
Found = !Found;
-
- if (Found == false)
+
+ if (Found == false)
Package = ""; /* not for this arch */
}
-
+
// Skip whitespace
for (;I != Stop && isspace(*I) != 0; I++);
}
@@ -797,7 +782,8 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
{
// apt-secure does no longer download individual (per-section) Release
// file. to provide Component pinning we use the section name now
- FileI->Component = WriteUniqString(component);
+ map_ptrloc const storage = WriteUniqString(component);
+ FileI->Component = storage;
// FIXME: Code depends on the fact that Release files aren't compressed
FILE* release = fdopen(dup(File.Fd()), "r");
@@ -884,13 +870,14 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,
break;
*s = '\0';
}
+ map_ptrloc const storage = WriteUniqString(data);
switch (writeTo) {
- case Suite: FileI->Archive = WriteUniqString(data); break;
- case Component: FileI->Component = WriteUniqString(data); break;
- case Version: FileI->Version = WriteUniqString(data); break;
- case Origin: FileI->Origin = WriteUniqString(data); break;
- case Codename: FileI->Codename = WriteUniqString(data); break;
- case Label: FileI->Label = WriteUniqString(data); break;
+ case Suite: FileI->Archive = storage; break;
+ case Component: FileI->Component = storage; break;
+ case Version: FileI->Version = storage; break;
+ case Origin: FileI->Origin = storage; break;
+ case Codename: FileI->Codename = storage; break;
+ case Label: FileI->Label = storage; break;
case None: break;
}
}
diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc
index 482581979..98ce4497a 100644
--- a/apt-pkg/edsp/edspindexfile.cc
+++ b/apt-pkg/edsp/edspindexfile.cc
@@ -51,7 +51,8 @@ bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const
pkgCache::PkgFileIterator CFile = Gen.GetCurFile();
CFile->Size = Pkg.FileSize();
CFile->mtime = Pkg.ModificationTime();
- CFile->Archive = Gen.WriteUniqString("edsp::scenario");
+ map_ptrloc const storage = Gen.WriteUniqString("edsp::scenario");
+ CFile->Archive = storage;
if (Gen.MergeList(Parser) == false)
return _error->Error("Problem with MergeList %s",File.c_str());
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index f694a237e..9acb7da72 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -970,7 +970,7 @@ bool pkgCache::PrvIterator::IsMultiArchImplicit() const
{
pkgCache::PkgIterator const Owner = OwnerPkg();
pkgCache::PkgIterator const Parent = ParentPkg();
- if (Owner->Arch != Parent->Arch || Owner->Name == Parent->Name)
+ if (strcmp(Owner.Arch(), Parent.Arch()) != 0 || Owner->Name == Parent->Name)
return true;
return false;
}
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 538d10b35..f70cbd02a 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -1316,10 +1316,11 @@ bool pkgCacheGenerator::MakeStatusCache(pkgSourceList &List,OpProgress *Progress
}
_error->RevertToStack();
}
- else if (Debug == true)
+ else
{
_error->MergeWithStack();
- std::clog << "Open filebased MMap" << std::endl;
+ if (Debug == true)
+ std::clog << "Open filebased MMap" << std::endl;
}
}
if (Writeable == false || CacheFile.empty() == true)