summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-07-20 12:32:46 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:27:59 +0200
commit7f8c0eed6983db7b8959f1498fc8bc80c98d719e (patch)
treeafa7f6890867867cecbe84b4993d7d5026d79436 /apt-pkg
parent1d3eea5caf65aacd7f112d14030a0499f32b9c75 (diff)
parse packages from all architectures into the cache
Now that we can dynamically create dependencies and provides as needed rather than requiring to know with which architectures we will deal before running we can allow the listparser to parse all records rather than skipping records of "unknown" architectures. This can e.g. happen if a user has foreign architecture packages in his status file without dpkg knowing about this architecture (or apt configured in this way). A sideeffect is that now arch:all packages are (correctly) recorded as available from any Packages file, not just from the native one – which has its downsides for the resolver as mixed-arch source packages can appear in different architectures at different times, but that is the problem of the resolver and dealing with it in the parser is at best a hack (and also depends on a helpful repository). Another sideeffect is that his allows :none packages to appear in Packages files again as we don't do any kind of checks now, but given that they aren't really supported (anymore) by anyone we can live with that.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/deb/deblistparser.cc39
-rw-r--r--apt-pkg/deb/deblistparser.h9
-rw-r--r--apt-pkg/edsp/edsplistparser.cc2
-rw-r--r--apt-pkg/edsp/edsplistparser.h2
-rw-r--r--apt-pkg/indexfile.cc2
-rw-r--r--apt-pkg/pkgcache.cc87
6 files changed, 47 insertions, 94 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index cb2b15668..c7c4ffe77 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -50,13 +50,9 @@ static debListParser::WordList PrioList[] = {
/* Provide an architecture and only this one and "all" will be accepted
in Step(), if no Architecture is given we will accept every arch
we would accept in general with checkArchitecture() */
-debListParser::debListParser(FileFd *File, string const &Arch) :
- pkgCacheListParser(), d(NULL), Tags(File), Arch(Arch)
+debListParser::debListParser(FileFd *File) :
+ pkgCacheListParser(), d(NULL), Tags(File)
{
- if (Arch == "native")
- this->Arch = _config->Find("APT::Architecture");
- Architectures = APT::Configuration::getArchitectures();
- MultiArchEnabled = Architectures.size() > 1;
}
/*}}}*/
// ListParser::Package - Return the package name /*{{{*/
@@ -887,34 +883,7 @@ bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out)
bool debListParser::Step()
{
iOffset = Tags.Offset();
- while (Tags.Step(Section) == true)
- {
- /* See if this is the correct Architecture, if it isn't then we
- drop the whole section. A missing arch tag only happens (in theory)
- inside the Status file, so that is a positive return */
- string const Architecture = Section.FindS("Architecture");
-
- if (Arch.empty() == true || Arch == "any" || MultiArchEnabled == false)
- {
- if (APT::Configuration::checkArchitecture(Architecture) == true)
- return true;
- /* parse version stanzas without an architecture only in the status file
- (and as misfortune bycatch flat-archives) */
- if ((Arch.empty() == true || Arch == "any") && Architecture.empty() == true)
- return true;
- }
- else
- {
- if (Architecture == Arch)
- return true;
-
- if (Architecture == "all" && Arch == _config->Find("APT::Architecture"))
- return true;
- }
-
- iOffset = Tags.Offset();
- }
- return false;
+ return Tags.Step(Section);
}
/*}}}*/
// ListParser::GetPrio - Convert the priority from a string /*{{{*/
@@ -950,7 +919,7 @@ bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/
/*}}}*/
debDebFileParser::debDebFileParser(FileFd *File, std::string const &DebFile)
- : debListParser(File, ""), DebFile(DebFile)
+ : debListParser(File), DebFile(DebFile)
{
}
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 975620070..747e022d8 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -45,9 +45,6 @@ class APT_HIDDEN debListParser : public pkgCacheListParser
pkgTagFile Tags;
pkgTagSection Section;
map_filesize_t iOffset;
- std::string Arch;
- std::vector<std::string> Architectures;
- bool MultiArchEnabled;
virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver);
bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag,
@@ -96,7 +93,7 @@ class APT_HIDDEN debListParser : public pkgCacheListParser
APT_PUBLIC static const char *ConvertRelation(const char *I,unsigned int &Op);
- debListParser(FileFd *File, std::string const &Arch = "");
+ debListParser(FileFd *File);
virtual ~debListParser();
};
@@ -118,8 +115,8 @@ class APT_HIDDEN debTranslationsParser : public debListParser
virtual std::string Architecture() APT_OVERRIDE { return ""; }
virtual std::string Version() APT_OVERRIDE { return ""; }
- debTranslationsParser(FileFd *File, std::string const &Arch = "")
- : debListParser(File, Arch) {};
+ debTranslationsParser(FileFd *File)
+ : debListParser(File) {};
};
#endif
diff --git a/apt-pkg/edsp/edsplistparser.cc b/apt-pkg/edsp/edsplistparser.cc
index 63f006628..a54a46b1e 100644
--- a/apt-pkg/edsp/edsplistparser.cc
+++ b/apt-pkg/edsp/edsplistparser.cc
@@ -22,7 +22,7 @@
/*}}}*/
// ListParser::edspListParser - Constructor /*{{{*/
-edspListParser::edspListParser(FileFd *File, std::string const &Arch) : debListParser(File, Arch), d(NULL)
+edspListParser::edspListParser(FileFd *File) : debListParser(File), d(NULL)
{}
/*}}}*/
// ListParser::NewVersion - Fill in the version structure /*{{{*/
diff --git a/apt-pkg/edsp/edsplistparser.h b/apt-pkg/edsp/edsplistparser.h
index 2a09e8c47..221229302 100644
--- a/apt-pkg/edsp/edsplistparser.h
+++ b/apt-pkg/edsp/edsplistparser.h
@@ -38,7 +38,7 @@ class APT_HIDDEN edspListParser : public debListParser
bool LoadReleaseInfo(pkgCache::RlsFileIterator &FileI,FileFd &File,
std::string const &section);
- edspListParser(FileFd *File, std::string const &Arch = "");
+ edspListParser(FileFd *File);
virtual ~edspListParser();
protected:
diff --git a/apt-pkg/indexfile.cc b/apt-pkg/indexfile.cc
index b592ae5a0..06312c173 100644
--- a/apt-pkg/indexfile.cc
+++ b/apt-pkg/indexfile.cc
@@ -316,7 +316,7 @@ pkgCacheListParser * pkgDebianIndexFile::CreateListParser(FileFd &Pkg)
if (Pkg.IsOpen() == false)
return NULL;
_error->PushToStack();
- pkgCacheListParser * const Parser = new debListParser(&Pkg, GetArchitecture());
+ pkgCacheListParser * const Parser = new debListParser(&Pkg);
bool const newError = _error->PendingError();
_error->MergeWithStack();
return newError ? NULL : Parser;
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index e8c95738e..045d7b41e 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -35,6 +35,8 @@
#include <stddef.h>
#include <string.h>
#include <ostream>
+#include <sstream>
+#include <algorithm>
#include <vector>
#include <string>
#include <sys/stat.h>
@@ -866,10 +868,32 @@ pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const
// ---------------------------------------------------------------------
/* This describes the version from a release-centric manner. The output is a
list of Label:Version/Archive */
+static std::string PkgFileIteratorToRelString(pkgCache::PkgFileIterator const &File)
+{
+ std::string Res;
+ if (File.Label() != 0)
+ Res = Res + File.Label() + ':';
+
+ if (File.Archive() != 0)
+ {
+ if (File.Version() == 0)
+ Res += File.Archive();
+ else
+ Res = Res + File.Version() + '/' + File.Archive();
+ }
+ else
+ {
+ // No release file, print the host name that this came from
+ if (File.Site() == 0 || File.Site()[0] == 0)
+ Res += "localhost";
+ else
+ Res += File.Site();
+ }
+ return Res;
+}
string pkgCache::VerIterator::RelStr() const
{
- bool First = true;
- string Res;
+ std::vector<std::string> RelStrs;
for (pkgCache::VerFileIterator I = this->FileList(); I.end() == false; ++I)
{
// Do not print 'not source' entries'
@@ -877,58 +901,21 @@ string pkgCache::VerIterator::RelStr() const
if (File.Flagged(pkgCache::Flag::NotSource))
continue;
- // See if we have already printed this out..
- bool Seen = false;
- for (pkgCache::VerFileIterator J = this->FileList(); I != J; ++J)
- {
- pkgCache::PkgFileIterator const File2 = J.File();
- if (File2.Label() == 0 || File.Label() == 0)
- continue;
-
- if (strcmp(File.Label(),File2.Label()) != 0)
- continue;
-
- if (File2.Version() == File.Version())
- {
- Seen = true;
- break;
- }
- if (File2.Version() == 0 || File.Version() == 0)
- break;
- if (strcmp(File.Version(),File2.Version()) == 0)
- Seen = true;
- }
-
- if (Seen == true)
+ std::string const RS = PkgFileIteratorToRelString(File);
+ if (std::find(RelStrs.begin(), RelStrs.end(), RS) != RelStrs.end())
continue;
-
- if (First == false)
- Res += ", ";
- else
- First = false;
-
- if (File.Label() != 0)
- Res = Res + File.Label() + ':';
- if (File.Archive() != 0)
- {
- if (File.Version() == 0)
- Res += File.Archive();
- else
- Res = Res + File.Version() + '/' + File.Archive();
- }
- else
- {
- // No release file, print the host name that this came from
- if (File.Site() == 0 || File.Site()[0] == 0)
- Res += "localhost";
- else
- Res += File.Site();
- }
+ RelStrs.push_back(RS);
+ }
+ std::ostringstream os;
+ if (likely(RelStrs.empty() == false))
+ {
+ std::copy(RelStrs.begin(), RelStrs.end()-1, std::ostream_iterator<std::string>(os, ", "));
+ os << *RelStrs.rbegin();
}
if (S->ParentPkg != 0)
- Res.append(" [").append(Arch()).append("]");
- return Res;
+ os << " [" << Arch() << "]";
+ return os.str();
}
/*}}}*/
// VerIterator::MultiArchType - string representing MultiArch flag /*{{{*/