Browse Source

merge Goswin Brederlow "support download of index files for different archs"
patch which includes the following big changes:
- Declare the unused [vendor] field in sources.list as option field,
e.g. deb [arch=amd64,i386 lang=en_GB have=fun] http://example.org
- When fetching index files download them for all APT::Architectures
(overrideable with the options field above)
- Allow all architectures of APT::Architectures to be in the Cache
- Add the architecture to status and progress informations
- Add b= (Binary architecture) to policy

This commit doesn't incude the "pin-hack" as the Group structure will take
care of this (and does it already to some extend).

David Kalnischkies 16 years ago
parent
commit
5dd4c8b811

+ 25 - 0
apt-pkg/aptconfiguration.cc

@@ -11,6 +11,7 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
+#include <system.h>
 
 
 #include <vector>
 #include <vector>
 #include <string>
 #include <string>
@@ -223,4 +224,28 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
 		return codes;
 		return codes;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// getArchitectures - Return Vector of prefered Architectures		/*{{{*/
+std::vector<std::string> const Configuration::getArchitectures(bool const &Cached) {
+	using std::string;
+
+	std::vector<string> static archs;
+	if (likely(Cached == true) && archs.empty() == false)
+		return archs;
+
+	string const arch = _config->Find("APT::Architecture");
+	archs = _config->FindVector("APT::Architectures");
+	if (archs.empty() == true ||
+	    std::find(archs.begin(), archs.end(), arch) == archs.end())
+		archs.push_back(arch);
+	return archs;
+}
+									/*}}}*/
+// checkArchitecture - are we interested in the given Architecture?	/*{{{*/
+bool const Configuration::checkArchitecture(std::string const &Arch) {
+	if (Arch == "all")
+		return true;
+	std::vector<std::string> const archs = getArchitectures(true);
+	return (std::find(archs.begin(), archs.end(), Arch) != archs.end());
+}
+									/*}}}*/
 }
 }

+ 16 - 0
apt-pkg/aptconfiguration.h

@@ -66,6 +66,22 @@ public:									/*{{{*/
 	std::vector<std::string> static const getLanguages(bool const &All = false,
 	std::vector<std::string> static const getLanguages(bool const &All = false,
 			bool const &Cached = true, char const * const Locale = 0);
 			bool const &Cached = true, char const * const Locale = 0);
 
 
+	/** \brief Returns a vector of Architectures we support
+	 *
+	 *  \param Cached saves the result so we need to calculated it only once
+	 *                this parameter should ony be used for testing purposes.
+	 *
+	 *  \return a vector of Architectures in prefered order
+	 */
+	std::vector<std::string> static const getArchitectures(bool const &Cached = true);
+
+	/** \brief Are we interested in the given Architecture?
+	 *
+	 *  \param Arch we want to check
+	 *  \return true if we are interested, false otherwise
+	 */
+	bool static const checkArchitecture(std::string const &Arch);
+
 									/*}}}*/
 									/*}}}*/
 };
 };
 									/*}}}*/
 									/*}}}*/

+ 13 - 21
apt-pkg/cdrom.cc

@@ -6,6 +6,8 @@
 #include<apt-pkg/cdromutl.h>
 #include<apt-pkg/cdromutl.h>
 #include<apt-pkg/strutl.h>
 #include<apt-pkg/strutl.h>
 #include<apt-pkg/cdrom.h>
 #include<apt-pkg/cdrom.h>
+#include<apt-pkg/aptconfiguration.h>
+
 #include<sstream>
 #include<sstream>
 #include<fstream>
 #include<fstream>
 #include<config.h>
 #include<config.h>
@@ -216,33 +218,23 @@ int pkgCdrom::Score(string Path)
 /* Here we drop everything that is not this machines arch */
 /* Here we drop everything that is not this machines arch */
 bool pkgCdrom::DropBinaryArch(vector<string> &List)
 bool pkgCdrom::DropBinaryArch(vector<string> &List)
 {
 {
-   char S[300];
-   snprintf(S,sizeof(S),"/binary-%s/",
-	    _config->Find("Apt::Architecture").c_str());
-   
+
    for (unsigned int I = 0; I < List.size(); I++)
    for (unsigned int I = 0; I < List.size(); I++)
    {
    {
       const char *Str = List[I].c_str();
       const char *Str = List[I].c_str();
-      
-      const char *Res;
-      if ((Res = strstr(Str,"/binary-")) == 0)
+      const char *Start, *End;
+      if ((Start = strstr(Str,"/binary-")) == 0)
 	 continue;
 	 continue;
 
 
-      // Weird, remove it.
-      if (strlen(Res) < strlen(S))
-      {
-	 List.erase(List.begin() + I);
-	 I--;
-	 continue;
-      }
-	  
-      // See if it is our arch
-      if (stringcmp(Res,Res + strlen(S),S) == 0)
-	 continue;
-      
-      // Erase it
+      // Between Start and End is the architecture
+      Start += 8;
+      if ((End = strstr(Start,"/")) != 0 && Start != End &&
+          APT::Configuration::checkArchitecture(string(Start, --End)) == true)
+	 continue; // okay, architecture is accepted
+
+      // not accepted -> Erase it
       List.erase(List.begin() + I);
       List.erase(List.begin() + I);
-      I--;
+      --I; // the next entry is at the same index after the erase
    }
    }
    
    
    return true;
    return true;

+ 3 - 3
apt-pkg/clean.cc

@@ -12,6 +12,7 @@
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
 
 
 #include <apti18n.h>    
 #include <apti18n.h>    
 
 
@@ -26,7 +27,6 @@
 bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
 bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
 {
 {
    bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
    bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
-   string MyArch = _config->Find("APT::Architecture");
       
       
    DIR *D = opendir(Dir.c_str());
    DIR *D = opendir(Dir.c_str());
    if (D == 0)
    if (D == 0)
@@ -75,9 +75,9 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
       for (I = Start; *I != 0 && *I != '.' ;I++);
       for (I = Start; *I != 0 && *I != '.' ;I++);
       if (*I != '.')
       if (*I != '.')
 	 continue;
 	 continue;
-      string Arch = DeQuoteString(string(Start,I-Start));
+      string const Arch = DeQuoteString(string(Start,I-Start));
       
       
-      if (Arch != "all" && Arch != MyArch)
+      if (APT::Configuration::checkArchitecture(Arch) == false)
 	 continue;
 	 continue;
       
       
       // Lookup the package
       // Lookup the package

+ 17 - 0
apt-pkg/contrib/strutl.cc

@@ -983,6 +983,23 @@ bool TokSplitString(char Tok,char *Input,char **List,
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
+// ExplodeString - Split a string up into a vector			/*{{{*/
+// ---------------------------------------------------------------------
+/* This can be used to split a given string up into a vector, so the
+   propose is the same as in the method above and this one is a bit slower
+   also, but the advantage is that we an iteratable vector */
+vector<string> ExplodeString(string const &haystack, char const &split) {
+	string::const_iterator start = haystack.begin();
+	string::const_iterator end = start;
+	vector<string> exploded;
+	do {
+		for (; end != haystack.end() && *end != split; ++end);
+		exploded.push_back(string(start, end));
+		start = end;
+	} while (end != haystack.end() && (++end) != haystack.end());
+	return exploded;
+}
+									/*}}}*/
 // RegexChoice - Simple regex list/list matcher				/*{{{*/
 // RegexChoice - Simple regex list/list matcher				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */

+ 1 - 0
apt-pkg/contrib/strutl.h

@@ -59,6 +59,7 @@ bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0)
 bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
 bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
 bool TokSplitString(char Tok,char *Input,char **List,
 bool TokSplitString(char Tok,char *Input,char **List,
 		    unsigned long ListMax);
 		    unsigned long ListMax);
+vector<string> ExplodeString(string const &haystack, char const &split=',');
 void ioprintf(ostream &out,const char *format,...) APT_FORMAT2;
 void ioprintf(ostream &out,const char *format,...) APT_FORMAT2;
 void strprintf(string &out,const char *format,...) APT_FORMAT2;
 void strprintf(string &out,const char *format,...) APT_FORMAT2;
 char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3;
 char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3;

+ 11 - 4
apt-pkg/deb/debindexfile.cc

@@ -149,9 +149,12 @@ unsigned long debSourcesIndex::Size() const
 // PackagesIndex::debPackagesIndex - Contructor				/*{{{*/
 // PackagesIndex::debPackagesIndex - Contructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* */
 /* */
-debPackagesIndex::debPackagesIndex(string URI,string Dist,string Section,bool Trusted) : 
-                  pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section)
+debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string const &Section,
+					bool const &Trusted, string const &Arch) :
+                  pkgIndexFile(Trusted), URI(URI), Dist(Dist), Section(Section), Architecture(Arch)
 {
 {
+	if (Architecture == "native")
+		Architecture = _config->Find("APT::Architecture");
 }
 }
 									/*}}}*/
 									/*}}}*/
 // PackagesIndex::ArchiveInfo - Short version of the archive url	/*{{{*/
 // PackagesIndex::ArchiveInfo - Short version of the archive url	/*{{{*/
@@ -171,6 +174,8 @@ string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
    Res += " ";
    Res += " ";
    Res += Ver.ParentPkg().Name();
    Res += Ver.ParentPkg().Name();
    Res += " ";
    Res += " ";
+   Res += Ver.Arch();
+   Res += " ";
    Res += Ver.VerStr();
    Res += Ver.VerStr();
    return Res;
    return Res;
 }
 }
@@ -204,6 +209,8 @@ string debPackagesIndex::Info(const char *Type) const
    else
    else
       Info += Dist + '/' + Section;   
       Info += Dist + '/' + Section;   
    Info += " ";
    Info += " ";
+   Info += Architecture;
+   Info += " ";
    Info += Type;
    Info += Type;
    return Info;
    return Info;
 }
 }
@@ -227,7 +234,7 @@ string debPackagesIndex::IndexURI(const char *Type) const
    }
    }
    else
    else
       Res = URI + "dists/" + Dist + '/' + Section +
       Res = URI + "dists/" + Dist + '/' + Section +
-      "/binary-" + _config->Find("APT::Architecture") + '/';
+      "/binary-" + Architecture + '/';
    
    
    Res += Type;
    Res += Type;
    return Res;
    return Res;
@@ -259,7 +266,7 @@ bool debPackagesIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
 {
 {
    string PackageFile = IndexFile("Packages");
    string PackageFile = IndexFile("Packages");
    FileFd Pkg(PackageFile,FileFd::ReadOnly);
    FileFd Pkg(PackageFile,FileFd::ReadOnly);
-   debListParser Parser(&Pkg);
+   debListParser Parser(&Pkg, Architecture);
    if (_error->PendingError() == true)
    if (_error->PendingError() == true)
       return _error->Error("Problem opening %s",PackageFile.c_str());
       return _error->Error("Problem opening %s",PackageFile.c_str());
    
    

+ 3 - 1
apt-pkg/deb/debindexfile.h

@@ -46,6 +46,7 @@ class debPackagesIndex : public pkgIndexFile
    string URI;
    string URI;
    string Dist;
    string Dist;
    string Section;
    string Section;
+   string Architecture;
 
 
    string Info(const char *Type) const;
    string Info(const char *Type) const;
    string IndexFile(const char *Type) const;
    string IndexFile(const char *Type) const;
@@ -69,7 +70,8 @@ class debPackagesIndex : public pkgIndexFile
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const;
    virtual bool Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
    virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
 
 
-   debPackagesIndex(string URI,string Dist,string Section,bool Trusted);
+   debPackagesIndex(string const &URI, string const &Dist, string const &Section,
+			bool const &Trusted, string const &Arch = "native");
 };
 };
 
 
 class debTranslationsIndex : public pkgIndexFile
 class debTranslationsIndex : public pkgIndexFile

+ 38 - 19
apt-pkg/deb/deblistparser.cc

@@ -32,10 +32,13 @@ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Impor
 
 
 // ListParser::debListParser - Constructor				/*{{{*/
 // ListParser::debListParser - Constructor				/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
-/* */
-debListParser::debListParser(FileFd *File) : Tags(File)
-{
-   Arch = _config->Find("APT::architecture");
+/* 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) : Tags(File),
+				Arch(Arch) {
+	if (Arch == "native")
+		this->Arch = _config->Find("APT::Architecture");
 }
 }
 									/*}}}*/
 									/*}}}*/
 // ListParser::UniqFindTagWrite - Find the tag and write a unq string	/*{{{*/
 // ListParser::UniqFindTagWrite - Find the tag and write a unq string	/*{{{*/
@@ -64,13 +67,19 @@ string debListParser::Package() {
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* This will return the Architecture of the package this section describes
 /* This will return the Architecture of the package this section describes
    Note that architecture "all" packages will get the architecture of the
    Note that architecture "all" packages will get the architecture of the
-   Packages file parsed here */
+   Packages file parsed here. */
 string debListParser::Architecture() {
 string debListParser::Architecture() {
 	string const Result = Section.FindS("Architecture");
 	string const Result = Section.FindS("Architecture");
-	if (Result.empty() == true)
-		return Arch;
-	if (Result == "all")
-		return Arch;
+	if (Result.empty() == true || Result == "all") {
+		if (Arch.empty() == true)
+			/* FIXME: this is a problem for installed arch all
+			   packages as we don't know from which arch this
+			   package was installed - and therefore which
+			   dependency this package resolves. */
+			return _config->Find("APT::Architecture");
+		else
+			return Arch;
+	}
 	return Result;
 	return Result;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -199,8 +208,12 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
 {
 {
    if (Pkg->Section == 0)
    if (Pkg->Section == 0)
       Pkg->Section = UniqFindTagWrite("Section");
       Pkg->Section = UniqFindTagWrite("Section");
-   if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
-      return false;
+
+   // Packages which are not from "our" arch doesn't get the essential flag
+   string const static myArch = _config->Find("APT::Architecture");
+   if (Pkg->Arch != 0 && myArch == Pkg.Arch())
+      if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false)
+	 return false;
    if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
    if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
       return false;
       return false;
 
 
@@ -630,17 +643,23 @@ bool debListParser::Step()
       /* See if this is the correct Architecture, if it isn't then we
       /* 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)
          drop the whole section. A missing arch tag only happens (in theory)
          inside the Status file, so that is a positive return */
          inside the Status file, so that is a positive return */
-      const char *Start;
-      const char *Stop;
-      if (Section.Find("Architecture",Start,Stop) == false)
+      string const Architecture = Section.FindS("Architecture");
+      if (Architecture.empty() == true)
 	 return true;
 	 return true;
 
 
-      //FIXME: Accept different Architectures here
-      if (stringcmp(Arch,Start,Stop) == 0)
-	 return true;
+      if (Arch.empty() == true)
+      {
+	 if (APT::Configuration::checkArchitecture(Architecture) == true)
+	    return true;
+      }
+      else
+      {
+	 if (Architecture == Arch)
+	    return true;
 
 
-      if (stringcmp(Start,Stop,"all") == 0)
-	 return true;
+	 if (Architecture == "all")
+	    return true;
+      }
 
 
       iOffset = Tags.Offset();
       iOffset = Tags.Offset();
    }   
    }   

+ 1 - 1
apt-pkg/deb/deblistparser.h

@@ -69,7 +69,7 @@ class debListParser : public pkgCacheGenerator::ListParser
 			    bool const &StripMultiArch = false);
 			    bool const &StripMultiArch = false);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
    static const char *ConvertRelation(const char *I,unsigned int &Op);
 
 
-   debListParser(FileFd *File);
+   debListParser(FileFd *File, string const &Arch = "");
 };
 };
 
 
 #endif
 #endif

+ 183 - 109
apt-pkg/deb/debmetaindex.cc

@@ -8,9 +8,11 @@
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/aptconfiguration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/error.h>
 
 
+#include <set>
+
 using namespace std;
 using namespace std;
 
 
-string debReleaseIndex::Info(const char *Type, const string Section) const
+string debReleaseIndex::Info(const char *Type, string const &Section, string const &Arch) const
 {
 {
    string Info = ::URI::SiteOnly(URI) + ' ';
    string Info = ::URI::SiteOnly(URI) + ' ';
    if (Dist[Dist.size() - 1] == '/')
    if (Dist[Dist.size() - 1] == '/')
@@ -19,7 +21,11 @@ string debReleaseIndex::Info(const char *Type, const string Section) const
          Info += Dist;
          Info += Dist;
    }
    }
    else
    else
-      Info += Dist + '/' + Section;   
+   {
+      Info += Dist + '/' + Section;
+      if (Arch.empty() == true)
+	 Info += " " + Arch;
+   }
    Info += " ";
    Info += " ";
    Info += Type;
    Info += Type;
    return Info;
    return Info;
@@ -61,16 +67,21 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const
    return Res;
    return Res;
 }
 }
 
 
-string debReleaseIndex::IndexURISuffix(const char *Type, const string Section) const
+string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const
 {
 {
    string Res ="";
    string Res ="";
    if (Dist[Dist.size() - 1] != '/')
    if (Dist[Dist.size() - 1] != '/')
-      Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/';
+   {
+      if (Arch == "native")
+	 Res += Section + "/binary-" + _config->Find("APT::Architecture") + '/';
+      else
+	 Res += Section + "/binary-" + Arch + '/';
+   }
    return Res + Type;
    return Res + Type;
 }
 }
    
    
 
 
-string debReleaseIndex::IndexURI(const char *Type, const string Section) const
+string debReleaseIndex::IndexURI(const char *Type, string const &Section, string const &Arch) const
 {
 {
    if (Dist[Dist.size() - 1] == '/')
    if (Dist[Dist.size() - 1] == '/')
    {
    {
@@ -82,10 +93,10 @@ string debReleaseIndex::IndexURI(const char *Type, const string Section) const
       return Res + Type;
       return Res + Type;
    }
    }
    else
    else
-      return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section);
+      return URI + "dists/" + Dist + '/' + IndexURISuffix(Type, Section, Arch);
  }
  }
 
 
-string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Section) const
+string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string &Section) const
 {
 {
    string Res ="";
    string Res ="";
    if (Dist[Dist.size() - 1] != '/')
    if (Dist[Dist.size() - 1] != '/')
@@ -93,7 +104,7 @@ string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Sect
    return Res + Type;
    return Res + Type;
 }
 }
 
 
-string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) const
+string debReleaseIndex::SourceIndexURI(const char *Type, const string &Section) const
 {
 {
    string Res;
    string Res;
    if (Dist[Dist.size() - 1] == '/')
    if (Dist[Dist.size() - 1] == '/')
@@ -108,44 +119,61 @@ string debReleaseIndex::SourceIndexURI(const char *Type, const string Section) c
       return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
       return URI + "dists/" + Dist + "/" + SourceIndexURISuffix(Type, Section);
 }
 }
 
 
-debReleaseIndex::debReleaseIndex(string URI,string Dist)
-{
-   this->URI = URI;
-   this->Dist = Dist;
-   this->Indexes = NULL;
-   this->Type = "deb";
+debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) {
+	this->URI = URI;
+	this->Dist = Dist;
+	this->Indexes = NULL;
+	this->Type = "deb";
 }
 }
 
 
-debReleaseIndex::~debReleaseIndex()
-{
-   for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin();
-	I != SectionEntries.end(); I++)
-      delete *I;
+debReleaseIndex::~debReleaseIndex() {
+	for (map<string, vector<debSectionEntry const*> >::const_iterator A = ArchEntries.begin();
+	     A != ArchEntries.end(); ++A)
+		for (vector<const debSectionEntry *>::const_iterator S = A->second.begin();
+		     S != A->second.end(); ++S)
+			delete *S;
 }
 }
 
 
-vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const
-{
-   vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
-   for (vector <const debSectionEntry *>::const_iterator I = SectionEntries.begin();
-	I != SectionEntries.end();
-	I++)
-   {
-      IndexTarget * Target = new IndexTarget();
-      Target->ShortDesc = (*I)->IsSrc ? "Sources" : "Packages";
-      Target->MetaKey
-	= (*I)->IsSrc ? SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section)
-	              : IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
-      Target->URI 
-	= (*I)->IsSrc ? SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section)
-	              : IndexURI(Target->ShortDesc.c_str(), (*I)->Section);
-      
-      Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
-      IndexTargets->push_back (Target);
-   }
-   return IndexTargets;
+vector <struct IndexTarget *>* debReleaseIndex::ComputeIndexTargets() const {
+	vector <struct IndexTarget *>* IndexTargets = new vector <IndexTarget *>;
+
+	map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
+	if (src != ArchEntries.end()) {
+		vector<debSectionEntry const*> const SectionEntries = src->second;
+		for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
+		     I != SectionEntries.end(); ++I) {
+			IndexTarget * Target = new IndexTarget();
+			Target->ShortDesc = "Sources";
+			Target->MetaKey = SourceIndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section);
+			Target->URI = SourceIndexURI(Target->ShortDesc.c_str(), (*I)->Section);
+			Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section);
+			IndexTargets->push_back (Target);
+		}
+	}
+
+	// Only source release
+	if (IndexTargets->empty() == false && ArchEntries.size() == 1)
+		return IndexTargets;
+
+	for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
+	     a != ArchEntries.end(); ++a) {
+		if (a->first == "source")
+			continue;
+		for (vector <const debSectionEntry *>::const_iterator I = a->second.begin();
+		     I != a->second.end(); ++I) {
+			IndexTarget * Target = new IndexTarget();
+			Target->ShortDesc = "Packages";
+			Target->MetaKey = IndexURISuffix(Target->ShortDesc.c_str(), (*I)->Section, a->first);
+			Target->URI = IndexURI(Target->ShortDesc.c_str(), (*I)->Section, a->first);
+			Target->Description = Info (Target->ShortDesc.c_str(), (*I)->Section, a->first);
+			IndexTargets->push_back (Target);
+		}
+	}
+
+	return IndexTargets;
 }
 }
 									/*}}}*/
 									/*}}}*/
-bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const
+bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const
 {
 {
    // special case for --print-uris
    // special case for --print-uris
    if (GetAll) {
    if (GetAll) {
@@ -170,23 +198,27 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const
 		     ComputeIndexTargets(),
 		     ComputeIndexTargets(),
 		     new indexRecords (Dist));
 		     new indexRecords (Dist));
 
 
-   // Queue the translations
-   std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
-   for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); 
-	I != SectionEntries.end(); I++) {
-
-      if((*I)->IsSrc)
-	 continue;
-
-      for (vector<string>::const_iterator l = lang.begin();
-		l != lang.end(); l++)
-      {
-	debTranslationsIndex i = debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str());
-	i.GetIndexes(Owner);
-      }
-   }
-
-   return true;
+	// Queue the translations
+	std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+	map<string, set<string> > sections;
+	for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
+	     a != ArchEntries.end(); ++a) {
+		if (a->first == "source")
+			continue;
+		for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
+		     I != a->second.end(); I++)
+			sections[(*I)->Section].insert(lang.begin(), lang.end());
+	}
+
+	for (map<string, set<string> >::const_iterator s = sections.begin();
+	     s != sections.end(); ++s)
+		for (set<string>::const_iterator l = s->second.begin();
+		     l != s->second.end(); l++) {
+			debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str());
+			i.GetIndexes(Owner);
+		}
+
+	return true;
 }
 }
 
 
 bool debReleaseIndex::IsTrusted() const
 bool debReleaseIndex::IsTrusted() const
@@ -203,71 +235,111 @@ bool debReleaseIndex::IsTrusted() const
    return false;
    return false;
 }
 }
 
 
-vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles()
-{
-   if (Indexes != NULL)
-      return Indexes;
-
-   Indexes = new vector <pkgIndexFile*>;
-   std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
-   for (vector<const debSectionEntry *>::const_iterator I = SectionEntries.begin(); 
-	I != SectionEntries.end(); I++) {
-      if ((*I)->IsSrc)
-         Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
-      else 
-      {
-         Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted()));
-
-	 for (vector<string>::const_iterator l = lang.begin();
-		l != lang.end(); l++)
-	    Indexes->push_back(new debTranslationsIndex(URI,Dist,(*I)->Section,(*l).c_str()));
-      }
-   }
+vector <pkgIndexFile *> *debReleaseIndex::GetIndexFiles() {
+	if (Indexes != NULL)
+		return Indexes;
+
+	Indexes = new vector <pkgIndexFile*>;
+	map<string, vector<debSectionEntry const*> >::const_iterator const src = ArchEntries.find("source");
+	if (src != ArchEntries.end()) {
+		vector<debSectionEntry const*> const SectionEntries = src->second;
+		for (vector<debSectionEntry const*>::const_iterator I = SectionEntries.begin();
+		     I != SectionEntries.end(); I++)
+			Indexes->push_back(new debSourcesIndex (URI, Dist, (*I)->Section, IsTrusted()));
+	}
+
+	// Only source release
+	if (Indexes->empty() == false && ArchEntries.size() == 1)
+		return Indexes;
+
+	std::vector<std::string> const lang = APT::Configuration::getLanguages(true);
+	map<string, set<string> > sections;
+	for (map<string, vector<debSectionEntry const*> >::const_iterator a = ArchEntries.begin();
+	     a != ArchEntries.end(); ++a) {
+		if (a->first == "source")
+			continue;
+		for (vector<debSectionEntry const*>::const_iterator I = a->second.begin();
+		     I != a->second.end(); I++) {
+			Indexes->push_back(new debPackagesIndex (URI, Dist, (*I)->Section, IsTrusted(), a->first));
+			sections[(*I)->Section].insert(lang.begin(), lang.end());
+		}
+	}
+
+	for (map<string, set<string> >::const_iterator s = sections.begin();
+	     s != sections.end(); ++s)
+		for (set<string>::const_iterator l = s->second.begin();
+		     l != s->second.end(); l++)
+			Indexes->push_back(new debTranslationsIndex(URI,Dist,s->first,(*l).c_str()));
+
+	return Indexes;
+}
 
 
-   return Indexes;
+void debReleaseIndex::PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry) {
+	for (vector<string>::const_iterator a = Archs.begin();
+	     a != Archs.end(); ++a)
+		ArchEntries[*a].push_back(new debSectionEntry(Entry->Section, Entry->IsSrc));
+	delete Entry;
 }
 }
 
 
-void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry)
-{
-   SectionEntries.push_back(Entry);
+void debReleaseIndex::PushSectionEntry(string const &Arch, const debSectionEntry *Entry) {
+	ArchEntries[Arch].push_back(Entry);
 }
 }
 
 
-debReleaseIndex::debSectionEntry::debSectionEntry (string Section, bool IsSrc): Section(Section)
-{
-   this->IsSrc = IsSrc;
+void debReleaseIndex::PushSectionEntry(const debSectionEntry *Entry) {
+	if (Entry->IsSrc == true)
+		PushSectionEntry("source", Entry);
+	else {
+		for (map<string, vector<const debSectionEntry *> >::iterator a = ArchEntries.begin();
+		     a != ArchEntries.end(); ++a) {
+			a->second.push_back(Entry);
+		}
+	}
 }
 }
 
 
+debReleaseIndex::debSectionEntry::debSectionEntry (string const &Section,
+		bool const &IsSrc): Section(Section), IsSrc(IsSrc)
+{}
+
 class debSLTypeDebian : public pkgSourceList::Type
 class debSLTypeDebian : public pkgSourceList::Type
 {
 {
    protected:
    protected:
 
 
-   bool CreateItemInternal(vector<metaIndex *> &List,string URI,
-			   string Dist,string Section,
-			   bool IsSrc) const
+   bool CreateItemInternal(vector<metaIndex *> &List, string const &URI,
+			   string const &Dist, string const &Section,
+			   bool const &IsSrc, map<string, string> const &Options) const
    {
    {
-      for (vector<metaIndex *>::const_iterator I = List.begin(); 
+      map<string, string>::const_iterator const arch = Options.find("arch");
+      vector<string> const Archs =
+		(arch != Options.end()) ? ExplodeString(arch->second) :
+				APT::Configuration::getArchitectures();
+
+      for (vector<metaIndex *>::const_iterator I = List.begin();
 	   I != List.end(); I++)
 	   I != List.end(); I++)
       {
       {
-	 // This check insures that there will be only one Release file
-	 // queued for all the Packages files and Sources files it
-	 // corresponds to.
-		if (strcmp((*I)->GetType(), "deb") == 0)
+	 // We only worry about debian entries here
+	 if (strcmp((*I)->GetType(), "deb") != 0)
+	    continue;
+
+	 debReleaseIndex *Deb = (debReleaseIndex *) (*I);
+	 /* This check insures that there will be only one Release file
+	    queued for all the Packages files and Sources files it
+	    corresponds to. */
+	 if (Deb->GetURI() == URI && Deb->GetDist() == Dist)
 	 {
 	 {
-	    debReleaseIndex *Deb = (debReleaseIndex *) (*I);
-	    // This check insures that there will be only one Release file
-	    // queued for all the Packages files and Sources files it
-	    // corresponds to.
-	    if (Deb->GetURI() == URI && Deb->GetDist() == Dist)
-	    {
-	       Deb->PushSectionEntry(new debReleaseIndex::debSectionEntry(Section, IsSrc));
-	       return true;
-	    }
+	    if (IsSrc == true)
+	       Deb->PushSectionEntry("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
+	    else
+	       Deb->PushSectionEntry(Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
+	    return true;
 	 }
 	 }
       }
       }
       // No currently created Release file indexes this entry, so we create a new one.
       // No currently created Release file indexes this entry, so we create a new one.
       // XXX determine whether this release is trusted or not
       // XXX determine whether this release is trusted or not
-      debReleaseIndex *Deb = new debReleaseIndex(URI,Dist);
-      Deb->PushSectionEntry (new debReleaseIndex::debSectionEntry(Section, IsSrc));
+      debReleaseIndex *Deb = new debReleaseIndex(URI, Dist);
+      if (IsSrc == true)
+	 Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc));
+      else
+	 Deb->PushSectionEntry (Archs, new debReleaseIndex::debSectionEntry(Section, IsSrc));
       List.push_back(Deb);
       List.push_back(Deb);
       return true;
       return true;
    }
    }
@@ -277,10 +349,11 @@ class debSLTypeDeb : public debSLTypeDebian
 {
 {
    public:
    public:
 
 
-   bool CreateItem(vector<metaIndex *> &List,string URI,
-		   string Dist,string Section) const
+   bool CreateItem(vector<metaIndex *> &List, string const &URI,
+		   string const &Dist, string const &Section,
+		   std::map<string, string> const &Options) const
    {
    {
-      return CreateItemInternal(List, URI, Dist, Section, false);
+      return CreateItemInternal(List, URI, Dist, Section, false, Options);
    }
    }
 
 
    debSLTypeDeb()
    debSLTypeDeb()
@@ -294,10 +367,11 @@ class debSLTypeDebSrc : public debSLTypeDebian
 {
 {
    public:
    public:
 
 
-   bool CreateItem(vector<metaIndex *> &List,string URI,
-		   string Dist,string Section) const 
+   bool CreateItem(vector<metaIndex *> &List, string const &URI,
+		   string const &Dist, string const &Section,
+		   std::map<string, string> const &Options) const
    {
    {
-      return CreateItemInternal(List, URI, Dist, Section, true);
+      return CreateItemInternal(List, URI, Dist, Section, true, Options);
    }
    }
    
    
    debSLTypeDebSrc()
    debSLTypeDebSrc()

+ 16 - 12
apt-pkg/deb/debmetaindex.h

@@ -5,40 +5,44 @@
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/sourcelist.h>
 #include <apt-pkg/sourcelist.h>
 
 
+#include <map>
+
 class debReleaseIndex : public metaIndex {
 class debReleaseIndex : public metaIndex {
    public:
    public:
 
 
    class debSectionEntry
    class debSectionEntry
    {
    {
       public:
       public:
-      debSectionEntry (string Section, bool IsSrc);
-      bool IsSrc;
-      string Section;
+      debSectionEntry (string const &Section, bool const &IsSrc);
+      string const Section;
+      bool const IsSrc;
    };
    };
 
 
    private:
    private:
-   vector <const debSectionEntry *> SectionEntries;
+   std::map<string, vector<debSectionEntry const*> > ArchEntries;
 
 
    public:
    public:
 
 
-   debReleaseIndex(string URI, string Dist);
+   debReleaseIndex(string const &URI, string const &Dist);
    ~debReleaseIndex();
    ~debReleaseIndex();
 
 
-   virtual string ArchiveURI(string File) const {return URI + File;};
-   virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const;
+   virtual string ArchiveURI(string const &File) const {return URI + File;};
+   virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const;
    vector <struct IndexTarget *>* ComputeIndexTargets() const;
    vector <struct IndexTarget *>* ComputeIndexTargets() const;
-   string Info(const char *Type, const string Section) const;
+   string Info(const char *Type, string const &Section, string const &Arch="") const;
    string MetaIndexInfo(const char *Type) const;
    string MetaIndexInfo(const char *Type) const;
    string MetaIndexFile(const char *Types) const;
    string MetaIndexFile(const char *Types) const;
    string MetaIndexURI(const char *Type) const;
    string MetaIndexURI(const char *Type) const;
-   string IndexURI(const char *Type, const string Section) const;
-   string IndexURISuffix(const char *Type, const string Section) const;
-   string SourceIndexURI(const char *Type, const string Section) const;
-   string SourceIndexURISuffix(const char *Type, const string Section) const;
+   string IndexURI(const char *Type, string const &Section, string const &Arch="native") const;
+   string IndexURISuffix(const char *Type, string const &Section, string const &Arch="native") const;
+   string SourceIndexURI(const char *Type, const string &Section) const;
+   string SourceIndexURISuffix(const char *Type, const string &Section) const;
    virtual vector <pkgIndexFile *> *GetIndexFiles();
    virtual vector <pkgIndexFile *> *GetIndexFiles();
 
 
    virtual bool IsTrusted() const;
    virtual bool IsTrusted() const;
 
 
+   void PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry);
+   void PushSectionEntry(string const &Arch, const debSectionEntry *Entry);
    void PushSectionEntry(const debSectionEntry *Entry);
    void PushSectionEntry(const debSectionEntry *Entry);
 };
 };
 
 

+ 2 - 2
apt-pkg/metaindex.h

@@ -33,8 +33,8 @@ class metaIndex
    virtual const char* GetType() const {return Type;}
    virtual const char* GetType() const {return Type;}
 
 
    // Interface for acquire
    // Interface for acquire
-   virtual string ArchiveURI(string /*File*/) const = 0;
-   virtual bool GetIndexes(pkgAcquire *Owner, bool GetAll=false) const = 0;
+   virtual string ArchiveURI(string const& /*File*/) const = 0;
+   virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0;
    
    
    virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; 
    virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; 
    virtual bool IsTrusted() const = 0;
    virtual bool IsTrusted() const = 0;

+ 6 - 2
apt-pkg/pkgcache.cc

@@ -406,7 +406,7 @@ operator<<(ostream& out, pkgCache::PkgIterator Pkg)
    string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
    string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
    string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
    string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
 
 
-   out << Pkg.Name() << " < " << current;
+   out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current;
    if (current != candidate)
    if (current != candidate)
       out << " -> " << candidate;
       out << " -> " << candidate;
    if ( newest != "none" && candidate != newest)
    if ( newest != "none" && candidate != newest)
@@ -699,7 +699,9 @@ string pkgCache::VerIterator::RelStr()
 	 else
 	 else
 	    Res += File.Site();
 	    Res += File.Site();
       }      
       }      
-   }   
+   }
+   if (S->Arch != 0)
+      Res.append(" [").append(Arch()).append("]");
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/
@@ -738,6 +740,8 @@ string pkgCache::PkgFileIterator::RelStr()
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
       Res = Res + (Res.empty() == true?"l=":",l=")  + Label();
    if (Component() != 0)
    if (Component() != 0)
       Res = Res + (Res.empty() == true?"c=":",c=")  + Component();
       Res = Res + (Res.empty() == true?"c=":",c=")  + Component();
+   if (Architecture() != 0)
+      Res = Res + (Res.empty() == true?"b=":",b=")  + Architecture();
    return Res;
    return Res;
 }
 }
 									/*}}}*/
 									/*}}}*/

+ 45 - 36
apt-pkg/sourcelist.cc

@@ -79,13 +79,51 @@ bool pkgSourceList::Type::FixupURI(string &URI) const
    Weird types may override this. */
    Weird types may override this. */
 bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
 bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
 				    const char *Buffer,
 				    const char *Buffer,
-				    unsigned long CurLine,
-				    string File) const
+				    unsigned long const &CurLine,
+				    string const &File) const
 {
 {
+   for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
+
+   // Parse option field if it exists
+   // e.g.: [ option1=value1 option2=value2 ]
+   map<string, string> Options;
+   if (Buffer != 0 && Buffer[0] == '[')
+   {
+      ++Buffer; // ignore the [
+      for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
+      while (*Buffer != ']')
+      {
+	 // get one option, e.g. option1=value1
+	 string option;
+	 if (ParseQuoteWord(Buffer,option) == false)
+	    return _error->Error(_("Malformed line %lu in source list %s ([option] unparseable)"),CurLine,File.c_str());
+
+	 if (option.length() < 3)
+	    return _error->Error(_("Malformed line %lu in source list %s ([option] too short)"),CurLine,File.c_str());
+
+	 size_t const needle = option.find('=');
+	 if (needle == string::npos)
+	    return _error->Error(_("Malformed line %lu in source list %s ([%s] is not an assignment)"),CurLine,File.c_str(), option.c_str());
+
+	 string const key = string(option, 0, needle);
+	 string const value = string(option, needle + 1, option.length());
+
+	 if (key.empty() == true)
+	    return _error->Error(_("Malformed line %lu in source list %s ([%s] has no key)"),CurLine,File.c_str(), option.c_str());
+
+	 if (value.empty() == true)
+	    return _error->Error(_("Malformed line %lu in source list %s ([%s] key %s has no value)"),CurLine,File.c_str(),option.c_str(),key.c_str());
+
+	 Options[key] = value;
+      }
+      ++Buffer; // ignore the ]
+      for (;Buffer != 0 && isspace(*Buffer); ++Buffer); // Skip whitespaces
+   }
+
    string URI;
    string URI;
    string Dist;
    string Dist;
-   string Section;   
-   
+   string Section;
+
    if (ParseQuoteWord(Buffer,URI) == false)
    if (ParseQuoteWord(Buffer,URI) == false)
       return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
       return _error->Error(_("Malformed line %lu in source list %s (URI)"),CurLine,File.c_str());
    if (ParseQuoteWord(Buffer,Dist) == false)
    if (ParseQuoteWord(Buffer,Dist) == false)
@@ -100,7 +138,7 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
       if (ParseQuoteWord(Buffer,Section) == true)
       if (ParseQuoteWord(Buffer,Section) == true)
 	 return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
 	 return _error->Error(_("Malformed line %lu in source list %s (absolute dist)"),CurLine,File.c_str());
       Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
       Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture"));
-      return CreateItem(List,URI,Dist,Section);
+      return CreateItem(List, URI, Dist, Section, Options);
    }
    }
    
    
    // Grab the rest of the dists
    // Grab the rest of the dists
@@ -109,7 +147,7 @@ bool pkgSourceList::Type::ParseLine(vector<metaIndex *> &List,
    
    
    do
    do
    {
    {
-      if (CreateItem(List,URI,Dist,Section) == false)
+      if (CreateItem(List, URI, Dist, Section, Options) == false)
 	 return false;
 	 return false;
    }
    }
    while (ParseQuoteWord(Buffer,Section) == true);
    while (ParseQuoteWord(Buffer,Section) == true);
@@ -246,36 +284,7 @@ bool pkgSourceList::ReadAppend(string File)
       if (Parse == 0)
       if (Parse == 0)
 	 return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
 	 return _error->Error(_("Type '%s' is not known on line %u in source list %s"),LineType.c_str(),CurLine,File.c_str());
       
       
-      // Vendor name specified
-      if (C[0] == '[')
-      {
-	 string VendorID;
-	 
-	 if (ParseQuoteWord(C,VendorID) == false)
-	     return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
-
-	 if (VendorID.length() < 2 || VendorID.end()[-1] != ']')
-	     return _error->Error(_("Malformed line %u in source list %s (vendor id)"),CurLine,File.c_str());
-	 VendorID = string(VendorID,1,VendorID.size()-2);
-	 
-// 	 for (vector<const Vendor *>::const_iterator iter = VendorList.begin();
-// 	      iter != VendorList.end(); iter++) 
-// 	 {
-// 	    if ((*iter)->GetVendorID() == VendorID)
-// 	    {
-// 	      if (_config->FindB("Debug::sourceList", false)) 
-// 		std::cerr << "Comparing VendorID \"" << VendorID << "\" with \"" << (*iter)->GetVendorID() << '"' << std::endl;
-// 	       Verifier = *iter;
-// 	       break;
-// 	    }
-// 	 }
-
-// 	 if (Verifier == 0)
-// 	    return _error->Error(_("Unknown vendor ID '%s' in line %u of source list %s"),
-// 				 VendorID.c_str(),CurLine,File.c_str());
-      }
-
-      if (Parse->ParseLine(SrcList,C,CurLine,File) == false)
+      if (Parse->ParseLine(SrcList, C, CurLine, File) == false)
 	 return false;
 	 return false;
    }
    }
    return true;
    return true;

+ 5 - 3
apt-pkg/sourcelist.h

@@ -29,6 +29,7 @@
 
 
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
+#include <map>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/metaindex.h>
 #include <apt-pkg/metaindex.h>
 
 
@@ -57,9 +58,10 @@ class pkgSourceList
       bool FixupURI(string &URI) const;
       bool FixupURI(string &URI) const;
       virtual bool ParseLine(vector<metaIndex *> &List,
       virtual bool ParseLine(vector<metaIndex *> &List,
 			     const char *Buffer,
 			     const char *Buffer,
-			     unsigned long CurLine,string File) const;
-      virtual bool CreateItem(vector<metaIndex *> &List,string URI,
-			      string Dist,string Section) const = 0;
+			     unsigned long const &CurLine,string const &File) const;
+      virtual bool CreateItem(vector<metaIndex *> &List,string const &URI,
+			      string const &Dist,string const &Section,
+			      std::map<string, string> const &Options) const = 0;
       Type();
       Type();
       virtual ~Type() {};
       virtual ~Type() {};
    };
    };

+ 7 - 1
apt-pkg/versionmatch.cc

@@ -100,6 +100,8 @@ pkgVersionMatch::pkgVersionMatch(string Data,MatchType Type) : Type(Type)
 	    RelLabel = Fragments[J]+2;
 	    RelLabel = Fragments[J]+2;
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
 	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"c=") == 0)
 	    RelComponent = Fragments[J]+2;
 	    RelComponent = Fragments[J]+2;
+	 else if (stringcasecmp(Fragments[J],Fragments[J]+2,"b=") == 0)
+	    RelArchitecture = Fragments[J]+2;
       }
       }
 
 
       if (RelVerStr.end()[-1] == '*')
       if (RelVerStr.end()[-1] == '*')
@@ -178,7 +180,7 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
       if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
       if (RelVerStr.empty() == true && RelOrigin.empty() == true &&
 	  RelArchive.empty() == true && RelLabel.empty() == true &&
 	  RelArchive.empty() == true && RelLabel.empty() == true &&
 	  RelRelease.empty() == true && RelCodename.empty() == true &&
 	  RelRelease.empty() == true && RelCodename.empty() == true &&
-	  RelComponent.empty() == true)
+	  RelComponent.empty() == true && RelArchitecture.empty() == true)
 	 return false;
 	 return false;
 
 
       if (RelVerStr.empty() == false)
       if (RelVerStr.empty() == false)
@@ -211,6 +213,10 @@ bool pkgVersionMatch::FileMatch(pkgCache::PkgFileIterator File)
 	 if (File->Component == 0 ||
 	 if (File->Component == 0 ||
 	     stringcasecmp(RelComponent,File.Component()) != 0)
 	     stringcasecmp(RelComponent,File.Component()) != 0)
 	    return false;
 	    return false;
+      if (RelArchitecture.empty() == false)
+	 if (File->Architecture == 0 ||
+	     stringcasecmp(RelArchitecture,File.Architecture()) != 0)
+	    return false;
       return true;
       return true;
    }
    }
 
 

+ 2 - 0
apt-pkg/versionmatch.h

@@ -23,6 +23,7 @@
       Codename (n=) e.g. etch, lenny, squeeze, sid
       Codename (n=) e.g. etch, lenny, squeeze, sid
       Label (l=)
       Label (l=)
       Component (c=)
       Component (c=)
+      Binary Architecture (b=)
    If there are no equals signs in the string then it is scanned in short
    If there are no equals signs in the string then it is scanned in short
    form - if it starts with a number it is Version otherwise it is an
    form - if it starts with a number it is Version otherwise it is an
    Archive or a Codename.
    Archive or a Codename.
@@ -55,6 +56,7 @@ class pkgVersionMatch
    string RelArchive;
    string RelArchive;
    string RelLabel;
    string RelLabel;
    string RelComponent;
    string RelComponent;
+   string RelArchitecture;
    bool MatchAll;
    bool MatchAll;
    
    
    // Origin Matching
    // Origin Matching