Browse Source

merge MultiArch-ABI. We don't support MultiArch yet (as most other tools),

but we support the usage of the new ABI so libapt users
can start to prepare for MultiArch (Closes: #536029)
tags/debian/0.8.0
David Kalnischkies 11 years ago
parent
commit
c67dc114ea
32 changed files with 1982 additions and 949 deletions
  1. +113
    -0
      README.MultiArch
  2. +53
    -9
      apt-pkg/algorithms.cc
  3. +24
    -0
      apt-pkg/aptconfiguration.cc
  4. +16
    -0
      apt-pkg/aptconfiguration.h
  5. +344
    -378
      apt-pkg/cacheiterators.h
  6. +13
    -21
      apt-pkg/cdrom.cc
  7. +3
    -3
      apt-pkg/clean.cc
  8. +16
    -16
      apt-pkg/contrib/macros.h
  9. +11
    -4
      apt-pkg/deb/debindexfile.cc
  10. +3
    -1
      apt-pkg/deb/debindexfile.h
  11. +165
    -45
      apt-pkg/deb/deblistparser.cc
  12. +3
    -1
      apt-pkg/deb/deblistparser.h
  13. +186
    -112
      apt-pkg/deb/debmetaindex.cc
  14. +16
    -12
      apt-pkg/deb/debmetaindex.h
  15. +308
    -64
      apt-pkg/depcache.cc
  16. +12
    -6
      apt-pkg/depcache.h
  17. +2
    -2
      apt-pkg/metaindex.h
  18. +9
    -4
      apt-pkg/orderlist.cc
  19. +24
    -8
      apt-pkg/packagemanager.cc
  20. +206
    -41
      apt-pkg/pkgcache.cc
  21. +40
    -14
      apt-pkg/pkgcache.h
  22. +209
    -56
      apt-pkg/pkgcachegen.cc
  23. +12
    -5
      apt-pkg/pkgcachegen.h
  24. +22
    -19
      apt-pkg/policy.cc
  25. +45
    -36
      apt-pkg/sourcelist.cc
  26. +5
    -3
      apt-pkg/sourcelist.h
  27. +7
    -1
      apt-pkg/versionmatch.cc
  28. +2
    -0
      apt-pkg/versionmatch.h
  29. +57
    -42
      cmdline/apt-cache.cc
  30. +48
    -38
      cmdline/apt-get.cc
  31. +2
    -1
      debian/apt-doc.docs
  32. +6
    -7
      debian/changelog

+ 113
- 0
README.MultiArch View File

@@ -0,0 +1,113 @@
Before we start with this topic: Note that MultiArch is not yet ready for
prime time and/or for the casual user. The implementation is so far widely
untested and only useful for developers of packagemanagment tools which
use APT and his friends and maintainers of (upcoming) MultiArch packages.
This README is especially NOT written for the casual user and is NOT a
usage guide - you have been warned. It is assumed that the reader has
at least a bit of knowledge about APT internals, dependency relations
and the MultiArch spec [0].

Note also that the toolchain isn't ready yet, e.g. while you can simulate
the installation of MultiArch packages they will more sooner than later
cause enormous problems if really installed as dpkg can't handle MultiArch
yet (no, --force-{overwrite,architecture} aren't good options here).
Other parts of the big picture are missing and/or untested too.
You have been warned!


The implementation is focused on NOT breaking existing singleArch-only
applications and/or systems as this is the current status-quo for all
systems. Also, many systems don't need (or can't make use of) MultiArch,
so APT will proceed in thinking SingleArch as long as it is not explicitly
told to handle MultiArch:
To activate MultiArch handling you need to specify architectures you
want to be considered by APT with the config list APT::Architectures
(Insert architectures in order of preference).
APT will download Packages files for all these architectures in the
update step. Exception: In the sourcelist is the optionfield used:
deb [ arch=amd64,i386 ] http://example.org/ experimental main
(This optionfield is a NOP in previous apt versions)

Internally in APT a package is represented as a PkgIterator -
before MultiArch this PkgIterator was architecture unaware,
only VerIterators include the architecture they came from.
This is/was a big problem as all versions in a package are
considered for dependency resolution, so pinning will not work in all cases.

The problem is solved by a conceptional change:
A PkgIterator is now architecture aware, so the packages
of foobar for amd64 and for i386 are now for apt internal totally
different packages. That is a good thing for e.g. pinning, but
sometimes you need the information that such packages are belonging together:
All these foobar packages therefore form a Group accessible with GrpIterators.
Note that the GrpIterator has the same name as all the packages in this group,
so e.g. apt-cache pkgnames iterates over GrpIterator to get the package names:
This is compatible to SingleArch as a Group consists only of a single package
and also to MultiArch as a Group consists of possible many packages which
all have the same name and are therefore out of interest for pkgnames.


Caused by the paragraph "Dependencies involving Architecture: all packages"
in the MultiArch spec we have a second major conceptional change
which could even break existing applications, but we hope for the best…
An Architecture: all package is internally split into pseudo packages
for all MultiArch Architectures and additional a package with the
architecture "all" with no dependencies which is a dependency of all
these architecture depending packages. While the architecture depending
packages are mainly used for dependency resolution (a package of arch A which
depends on an arch all package assumes that the dependencies of this package
are also from arch A. Packages also sometimes change from any to all or v.v.)
the arch "all" package is used for scheduling download/installation of the
underlying "real" package. Note that the architecture depending packages can
be detected with Pseudo() while the "all" package reports exactly this arch
as package architecture and as pseudo architecture of the versions of this pkg.
Beware: All versions of a "real" architecture all package will be report "all"
as their architecture if asked with Arch() regardless if they are the "all" or
the architecture depending packages. If you want to know the architecture this
pseudo package was created for call Arch(true). Also, while the spec say that
arch:all packages are not allowed to have a MultiArch flag APT assigns a
special value to them: MultiArch: all.


As you might guess this arch:all handling has a few problems (but we think so
far that the problems are minor compared to the problems we would have with
other implementations.)
APT doesn't know which pseudo packages of such an arch all package are
"installed" (to satisfy dependencies), so APT will generate a Cache in which
all these pseudo packages are installed (e.g. apt-cache policy will display
them all as installed). Later in the DepCache step it will "remove"
all pseudo packages whose dependencies are not satisfied.
The expense is that if the package state is broken APT could come to the
conclusion to "remove" too many pseudo packages, but in a stable environment
APT should never end up in a broken system state…


Given all these internal changes it is quite interesting that the actual
implementation of MultiArch is trivial: Some implicit dependencies and a few
more provides are all changes needed to get it working. Especially noteworthy
is that it wasn't needed to change the resolver in any way and other parts only
need to be told about ignoring pseudo packages or using GrpIterator instead of
PkgIterator, so chances are good that libapt-applications will proceed to work
without or at least only require minor changes, but your mileage may vary…


Known Issues and/or noteworthy stuff:
* The implementation is mostly untested, so it is very likely that APT will
eat your kids if you aren't as lucky as the author of these patches.
* the (install)size of a pseudo package is always NULL - if you want to know
the (install)size you need to get the info from the arch "all" package.
* It is maybe confusing, but the arch "all" package does have the same versions
and in general roughly the same information with one subtil difference:
It doesn't have any dependency, regardless of the type. The pseudo packages
depend on this package.
* apt-cache policy foobar on installed architecture all package foobar will
report all architecture depending packages as installed. Displaying here the
correct information would require to build the complete DepCache…
* [BUG] An installed package which changes the architecture from any to all
(and v.v.) shows up in the NEW packages section instead of UPGRADE.
* [TODO] Investigate the DepCache pseudo-package killer heuristic:
e.g. add more safety guards…
* [FIXME] a few corner cases/missing features marked as FIXME in the code


[0] https://wiki.ubuntu.com/MultiarchSpec

+ 53
- 9
apt-pkg/algorithms.cc View File

@@ -83,13 +83,28 @@ void pkgSimulate::Describe(PkgIterator Pkg,ostream &out,bool Current,bool Candid
bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
Flags[Pkg->ID] = 1;
cout << "Inst ";
Describe(Pkg,cout,true,true);
Sim.MarkInstall(Pkg,false);

if (strcmp(Pkg.Arch(),"all") == 0)
{
pkgCache::GrpIterator G = Pkg.Group();
pkgCache::GrpIterator iG = iPkg.Group();
for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
{
if (strcmp(P.Arch(), "all") == 0)
continue;
if (iG.FindPkg(P.Arch())->CurrentVer == 0)
continue;
Flags[P->ID] = 1;
Sim.MarkInstall(P, false);
}
}

// Look for broken conflicts+predepends.
for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++)
{
@@ -131,9 +146,22 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
bool pkgSimulate::Configure(PkgIterator iPkg)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());
Flags[Pkg->ID] = 2;

if (strcmp(Pkg.Arch(),"all") == 0)
{
pkgCache::GrpIterator G = Pkg.Group();
for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
{
if (strcmp(P.Arch(), "all") == 0)
continue;
if (Flags[P->ID] == 1)
Flags[P->ID] = 2;
}
}

// Sim.MarkInstall(Pkg,false);
if (Sim[Pkg].InstBroken() == true)
{
@@ -181,10 +209,26 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge)
{
// Adapt the iterator
PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch());

Flags[Pkg->ID] = 3;
Sim.MarkDelete(Pkg);

if (strcmp(Pkg.Arch(),"all") == 0)
{
pkgCache::GrpIterator G = Pkg.Group();
pkgCache::GrpIterator iG = iPkg.Group();
for (pkgCache::PkgIterator P = G.FindPkg("any"); P.end() != true; P = G.NextPkg(P))
{
if (strcmp(P.Arch(), "all") == 0)
continue;
if (iG.FindPkg(P.Arch())->CurrentVer == 0)
continue;
Flags[P->ID] = 3;
Sim.MarkDelete(P);
}
}

if (Purge == true)
cout << "Purg ";
else
@@ -491,11 +535,11 @@ void pkgProblemResolver::MakeScores()
// Important Required Standard Optional Extra
signed short PrioMap[] = {
0,
_config->FindI("pkgProblemResolver::Scores::Important",3),
_config->FindI("pkgProblemResolver::Scores::Required",2),
_config->FindI("pkgProblemResolver::Scores::Standard",1),
_config->FindI("pkgProblemResolver::Scores::Optional",-1),
_config->FindI("pkgProblemResolver::Scores::Extra",-2)
(signed short) _config->FindI("pkgProblemResolver::Scores::Important",3),
(signed short) _config->FindI("pkgProblemResolver::Scores::Required",2),
(signed short) _config->FindI("pkgProblemResolver::Scores::Standard",1),
(signed short) _config->FindI("pkgProblemResolver::Scores::Optional",-1),
(signed short) _config->FindI("pkgProblemResolver::Scores::Extra",-2)
};
signed short PrioEssentials = _config->FindI("pkgProblemResolver::Scores::Essentials",100);
signed short PrioInstalledAndNotObsolete = _config->FindI("pkgProblemResolver::Scores::NotObsolete",1);


+ 24
- 0
apt-pkg/aptconfiguration.cc View File

@@ -319,4 +319,28 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
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 View File

@@ -66,6 +66,22 @@ public: /*{{{*/
std::vector<std::string> static const getLanguages(bool const &All = false,
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);

/*}}}*/
};
/*}}}*/


+ 344
- 378
apt-pkg/cacheiterators.h View File

@@ -1,6 +1,5 @@
// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: cacheiterators.h,v 1.18.2.1 2004/05/08 22:44:27 mdz Exp $
/* ######################################################################
Cache Iterators - Iterators for navigating the cache structure
@@ -30,417 +29,384 @@
/*}}}*/
#ifndef PKGLIB_CACHEITERATORS_H
#define PKGLIB_CACHEITERATORS_H
// abstract Iterator template /*{{{*/
/* This template provides the very basic iterator methods we
need to have for doing some walk-over-the-cache magic */
template<typename Str, typename Itr> class pkgCache::Iterator {
protected:
Str *S;
pkgCache *Owner;

/** \brief Returns the Pointer for this struct in the owner
* The implementation of this method should be pretty short
* as it will only return the Pointer into the mmap stored
* in the owner but the name of this pointer is different for
* each stucture and we want to abstract here at least for the
* basic methods from the actual structure.
* \return Pointer to the first structure of this type
*/
virtual Str* OwnerPointer() const = 0;

public:
// Iteration
virtual void operator ++(int) = 0;
virtual void operator ++() = 0; // Should be {operator ++(0);};
inline bool end() const {return Owner == 0 || S == OwnerPointer();};

// Comparison
inline bool operator ==(const Itr &B) const {return S == B.S;};
inline bool operator !=(const Itr &B) const {return S != B.S;};

// Accessors
inline Str *operator ->() {return S;};
inline Str const *operator ->() const {return S;};
inline operator Str *() {return S == OwnerPointer() ? 0 : S;};
inline operator Str const *() const {return S == OwnerPointer() ? 0 : S;};
inline Str const &operator *() const {return *S;};
inline pkgCache *Cache() {return Owner;};

// Mixed stuff
inline void operator =(const Itr &B) {S = B.S; Owner = B.Owner;};
inline bool IsGood() const { return S && Owner && ! end();};
inline unsigned long Index() const {return S - OwnerPointer();};

// Constructors - look out for the variable assigning
inline Iterator() : S(0), Owner(0) {};
inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {};
};
/*}}}*/
// Group Iterator /*{{{*/
/* Packages with the same name are collected in a Group so someone only
interest in package names can iterate easily over the names, so the
different architectures can be treated as of the "same" package
(apt internally treat them as totally different packages) */
class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
long HashIndex;

protected:
inline Group* OwnerPointer() const {
return Owner->GrpP;
};

public:
// This constructor is the 'begin' constructor, never use it.
inline GrpIterator(pkgCache &Owner) : Iterator<Group, GrpIterator>(Owner), HashIndex(-1) {
S = OwnerPointer();
operator ++(0);
};

virtual void operator ++(int);
virtual void operator ++() {operator ++(0);};

inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
inline PkgIterator PackageList() const;
PkgIterator FindPkg(string Arch = "any");
PkgIterator NextPkg(PkgIterator const &Pkg);

// Constructors
inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
if (S == 0)
S = OwnerPointer();
};
inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {};


};
/*}}}*/
// Package Iterator /*{{{*/
class pkgCache::PkgIterator
{
friend class pkgCache;
Package *Pkg;
pkgCache *Owner;
long HashIndex;

protected:
// This constructor is the 'begin' constructor, never use it.
inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1)
{
Pkg = Owner.PkgP;
operator ++(0);
};
public:

enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};
// Iteration
void operator ++(int);
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;};

// Comparison
inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;};
inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;};
// Accessors
inline Package *operator ->() {return Pkg;};
inline Package const *operator ->() const {return Pkg;};
inline Package const &operator *() const {return *Pkg;};
inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;};
inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;};
inline pkgCache *Cache() {return Owner;};
inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;};
inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;};
inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge ||
(Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);};
inline VerIterator VersionList() const;
inline VerIterator CurrentVer() const;
inline DepIterator RevDependsList() const;
inline PrvIterator ProvidesList() const;
inline unsigned long Index() const {return Pkg - Owner->PkgP;};
OkState State() const;

//Nice printable representation
friend std::ostream& operator<<(std::ostream& out, pkgCache::PkgIterator Pkg);

const char *CandVersion() const;
const char *CurVersion() const;

// Constructors
inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner),
HashIndex(0)
{
if (Pkg == 0)
Pkg = Owner.PkgP;
};
inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {};
class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
long HashIndex;

protected:
inline Package* OwnerPointer() const {
return Owner->PkgP;
};

public:
// This constructor is the 'begin' constructor, never use it.
inline PkgIterator(pkgCache &Owner) : Iterator<Package, PkgIterator>(Owner), HashIndex(-1) {
S = OwnerPointer();
operator ++(0);
};

virtual void operator ++(int);
virtual void operator ++() {operator ++(0);};

enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure};

// Accessors
inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
(S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);};
inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;};
inline GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);};

inline VerIterator VersionList() const;
inline VerIterator CurrentVer() const;
inline DepIterator RevDependsList() const;
inline PrvIterator ProvidesList() const;
OkState State() const;
const char *CandVersion() const;
const char *CurVersion() const;

//Nice printable representation
friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
std::string FullName(bool const &Pretty = false) const;

// Constructors
inline PkgIterator(pkgCache &Owner,Package *Trg) : Iterator<Package, PkgIterator>(Owner, Trg), HashIndex(0) {
if (S == 0)
S = OwnerPointer();
};
inline PkgIterator() : Iterator<Package, PkgIterator>(), HashIndex(0) {};
};
/*}}}*/
// Version Iterator /*{{{*/
class pkgCache::VerIterator
{
Version *Ver;
pkgCache *Owner;

void _dummy();
public:

// Iteration
void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || (Ver == Owner->VerP?true:false);};
inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;};
// Comparison
inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;};
inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;};
int CompareVer(const VerIterator &B) const;

// Testing
inline bool IsGood() const { return Ver && Owner && ! end();};

// Accessors
inline Version *operator ->() {return Ver;};
inline Version const *operator ->() const {return Ver;};
inline Version &operator *() {return *Ver;};
inline Version const &operator *() const {return *Ver;};
inline operator Version *() {return Ver == Owner->VerP?0:Ver;};
inline operator Version const *() const {return Ver == Owner->VerP?0:Ver;};
inline pkgCache *Cache() {return Owner;};
inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;};
inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;};
inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;};
inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);};
inline DescIterator DescriptionList() const;
DescIterator TranslatedDescription() const;
inline DepIterator DependsList() const;
inline PrvIterator ProvidesList() const;
inline VerFileIterator FileList() const;
inline unsigned long Index() const {return Ver - Owner->VerP;};
bool Downloadable() const;
inline const char *PriorityType() {return Owner->Priority(Ver->Priority);};
string RelStr();
bool Automatic() const;
VerFileIterator NewestFile() const;

inline VerIterator() : Ver(0), Owner(0) {};
inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Ver(Trg),
Owner(&Owner)
{
if (Ver == 0)
Ver = Owner.VerP;
};
class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
protected:
inline Version* OwnerPointer() const {
return Owner->VerP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->VerP) S = Owner->VerP + S->NextVer;};
inline void operator ++() {operator ++(0);};

// Comparison
int CompareVer(const VerIterator &B) const;

// Accessors
inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;};
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
inline const char *Arch() const {
if(S->MultiArch == pkgCache::Version::All)
return "all";
return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
};
inline const char *Arch(bool const pseudo) const {
if(pseudo == false)
return Arch();
return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch;
};
inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);};

inline DescIterator DescriptionList() const;
DescIterator TranslatedDescription() const;
inline DepIterator DependsList() const;
inline PrvIterator ProvidesList() const;
inline VerFileIterator FileList() const;
bool Downloadable() const;
inline const char *PriorityType() {return Owner->Priority(S->Priority);};
string RelStr();

bool Automatic() const;
bool Pseudo() const;
VerFileIterator NewestFile() const;

inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) {
if (S == 0)
S = OwnerPointer();
};
inline VerIterator() : Iterator<Version, VerIterator>() {};
};
/*}}}*/
// Description Iterator /*{{{*/
class pkgCache::DescIterator
{
Description *Desc;
pkgCache *Owner;
void _dummy();
public:

// Iteration
void operator ++(int) {if (Desc != Owner->DescP) Desc = Owner->DescP + Desc->NextDesc;};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || Desc == Owner->DescP?true:false;};
inline void operator =(const DescIterator &B) {Desc = B.Desc; Owner = B.Owner;};
// Comparison
inline bool operator ==(const DescIterator &B) const {return Desc == B.Desc;};
inline bool operator !=(const DescIterator &B) const {return Desc != B.Desc;};
int CompareDesc(const DescIterator &B) const;
// Accessors
inline Description *operator ->() {return Desc;};
inline Description const *operator ->() const {return Desc;};
inline Description &operator *() {return *Desc;};
inline Description const &operator *() const {return *Desc;};
inline operator Description *() {return Desc == Owner->DescP?0:Desc;};
inline operator Description const *() const {return Desc == Owner->DescP?0:Desc;};
inline pkgCache *Cache() {return Owner;};
inline const char *LanguageCode() const {return Owner->StrP + Desc->language_code;};
inline const char *md5() const {return Owner->StrP + Desc->md5sum;};
inline DescFileIterator FileList() const;
inline unsigned long Index() const {return Desc - Owner->DescP;};

inline DescIterator() : Desc(0), Owner(0) {};
inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Desc(Trg),
Owner(&Owner)
{
if (Desc == 0)
Desc = Owner.DescP;
};
class pkgCache::DescIterator : public Iterator<Description, DescIterator> {
protected:
inline Description* OwnerPointer() const {
return Owner->DescP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->DescP) S = Owner->DescP + S->NextDesc;};
inline void operator ++() {operator ++(0);};

// Comparison
int CompareDesc(const DescIterator &B) const;

// Accessors
inline const char *LanguageCode() const {return Owner->StrP + S->language_code;};
inline const char *md5() const {return Owner->StrP + S->md5sum;};
inline DescFileIterator FileList() const;

inline DescIterator() : Iterator<Description, DescIterator>() {};
inline DescIterator(pkgCache &Owner,Description *Trg = 0) : Iterator<Description, DescIterator>(Owner, Trg) {
if (S == 0)
S = Owner.DescP;
};
};
/*}}}*/
// Dependency iterator /*{{{*/
class pkgCache::DepIterator
{
Dependency *Dep;
enum {DepVer, DepRev} Type;
pkgCache *Owner;
void _dummy();
public:

// Iteration
void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP +
(Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;};
// Comparison
inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;};
inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;};

// Accessors
inline Dependency *operator ->() {return Dep;};
inline Dependency const *operator ->() const {return Dep;};
inline Dependency &operator *() {return *Dep;};
inline Dependency const &operator *() const {return *Dep;};
inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;};
inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;};
inline pkgCache *Cache() {return Owner;};
inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;};
inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);};
inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner,0);SmartTargetPkg(R);return R;};
inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);};
inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);};
inline bool Reverse() {return Type == DepRev;};
inline unsigned long Index() const {return Dep - Owner->DepP;};
bool IsCritical();
void GlobOr(DepIterator &Start,DepIterator &End);
Version **AllTargets();
bool SmartTargetPkg(PkgIterator &Result);
inline const char *CompType() {return Owner->CompType(Dep->CompareOp);};
inline const char *DepType() {return Owner->DepType(Dep->Type);};
inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) :
Dep(Trg), Type(DepVer), Owner(&Owner)
{
if (Dep == 0)
Dep = Owner.DepP;
};
inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) :
Dep(Trg), Type(DepRev), Owner(&Owner)
{
if (Dep == 0)
Dep = Owner.DepP;
};
inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {};
class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
enum {DepVer, DepRev} Type;

protected:
inline Dependency* OwnerPointer() const {
return Owner->DepP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->DepP) S = Owner->DepP +
(Type == DepVer ? S->NextDepends : S->NextRevDepends);};
inline void operator ++() {operator ++(0);};

// 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();
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);};

inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer) {
if (S == 0)
S = Owner.DepP;
};
inline DepIterator(pkgCache &Owner, Dependency *Trg, Package*) :
Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepRev) {
if (S == 0)
S = Owner.DepP;
};
inline DepIterator() : Iterator<Dependency, DepIterator>(), Type(DepVer) {};
};
/*}}}*/
// Provides iterator /*{{{*/
class pkgCache::PrvIterator
{
Provides *Prv;
enum {PrvVer, PrvPkg} Type;
pkgCache *Owner;
void _dummy();
public:

// Iteration
void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP +
(Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || Prv == Owner->ProvideP?true:false;};
// Comparison
inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;};
inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;};

// Accessors
inline Provides *operator ->() {return Prv;};
inline Provides const *operator ->() const {return Prv;};
inline Provides &operator *() {return *Prv;};
inline Provides const &operator *() const {return *Prv;};
inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;};
inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;};
inline pkgCache *Cache() {return Owner;};

inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;};
inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;};
inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);};
inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);};
inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);};
inline unsigned long Index() const {return Prv - Owner->ProvideP;};

inline PrvIterator() : Prv(0), Type(PrvVer), Owner(0) {};

inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) :
Prv(Trg), Type(PrvVer), Owner(&Owner)
{
if (Prv == 0)
Prv = Owner.ProvideP;
};
inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) :
Prv(Trg), Type(PrvPkg), Owner(&Owner)
{
if (Prv == 0)
Prv = Owner.ProvideP;
};
class pkgCache::PrvIterator : public Iterator<Provides, PrvIterator> {
enum {PrvVer, PrvPkg} Type;

protected:
inline Provides* OwnerPointer() const {
return Owner->ProvideP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->ProvideP) S = Owner->ProvideP +
(Type == PrvVer?S->NextPkgProv:S->NextProvides);};
inline void operator ++() {operator ++(0);};

// 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 PrvIterator() : Iterator<Provides, PrvIterator>(), Type(PrvVer) {};

inline PrvIterator(pkgCache &Owner, Provides *Trg, Version*) :
Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvVer) {
if (S == 0)
S = Owner.ProvideP;
};
inline PrvIterator(pkgCache &Owner, Provides *Trg, Package*) :
Iterator<Provides, PrvIterator>(Owner, Trg), Type(PrvPkg) {
if (S == 0)
S = Owner.ProvideP;
};
};
/*}}}*/
// Package file /*{{{*/
class pkgCache::PkgFileIterator
{
pkgCache *Owner;
PackageFile *File;

public:

// Iteration
void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || File == Owner->PkgFileP?true:false;};

// Comparison
inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;};
inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;};
// Accessors
inline PackageFile *operator ->() {return File;};
inline PackageFile const *operator ->() const {return File;};
inline PackageFile const &operator *() const {return *File;};
inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;};
inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;};
inline pkgCache *Cache() {return Owner;};

inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;};
inline const char *Archive() const {return File->Archive == 0?0:Owner->StrP + File->Archive;};
inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;};
inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;};
inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;};
inline const char *Codename() const {return File->Codename ==0?0:Owner->StrP + File->Codename;};
inline const char *Label() const {return File->Label == 0?0:Owner->StrP + File->Label;};
inline const char *Site() const {return File->Site == 0?0:Owner->StrP + File->Site;};
inline const char *Architecture() const {return File->Architecture == 0?0:Owner->StrP + File->Architecture;};
inline const char *IndexType() const {return File->IndexType == 0?0:Owner->StrP + File->IndexType;};

inline unsigned long Index() const {return File - Owner->PkgFileP;};

bool IsOk();
string RelStr();
// Constructors
inline PkgFileIterator() : Owner(0), File(0) {};
inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP) {};
inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {};
class pkgCache::PkgFileIterator : public Iterator<PackageFile, PkgFileIterator> {
protected:
inline PackageFile* OwnerPointer() const {
return Owner->PkgFileP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->PkgFileP) S = Owner->PkgFileP + S->NextFile;};
inline void operator ++() {operator ++(0);};

// Accessors
inline const char *FileName() const {return S->FileName == 0?0:Owner->StrP + S->FileName;};
inline const char *Archive() const {return S->Archive == 0?0:Owner->StrP + S->Archive;};
inline const char *Component() const {return S->Component == 0?0:Owner->StrP + S->Component;};
inline const char *Version() const {return S->Version == 0?0:Owner->StrP + S->Version;};
inline const char *Origin() const {return S->Origin == 0?0:Owner->StrP + S->Origin;};
inline const char *Codename() const {return S->Codename ==0?0:Owner->StrP + S->Codename;};
inline const char *Label() const {return S->Label == 0?0:Owner->StrP + S->Label;};
inline const char *Site() const {return S->Site == 0?0:Owner->StrP + S->Site;};
inline const char *Architecture() const {return S->Architecture == 0?0:Owner->StrP + S->Architecture;};
inline const char *IndexType() const {return S->IndexType == 0?0:Owner->StrP + S->IndexType;};

bool IsOk();
string RelStr();

// Constructors
inline PkgFileIterator() : Iterator<PackageFile, PkgFileIterator>() {};
inline PkgFileIterator(pkgCache &Owner) : Iterator<PackageFile, PkgFileIterator>(Owner, Owner.PkgFileP) {};
inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Iterator<PackageFile, PkgFileIterator>(Owner, Trg) {};
};
/*}}}*/
// Version File /*{{{*/
class pkgCache::VerFileIterator
{
pkgCache *Owner;
VerFile *FileP;

public:

// Iteration
void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || FileP == Owner->VerFileP?true:false;};

// Comparison
inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;};
inline bool operator !=(const VerFileIterator &B) const {return FileP != B.FileP;};
// Accessors
inline VerFile *operator ->() {return FileP;};
inline VerFile const *operator ->() const {return FileP;};
inline VerFile const &operator *() const {return *FileP;};
inline operator VerFile *() {return FileP == Owner->VerFileP?0:FileP;};
inline operator VerFile const *() const {return FileP == Owner->VerFileP?0:FileP;};
inline pkgCache *Cache() {return Owner;};
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);};
inline unsigned long Index() const {return FileP - Owner->VerFileP;};
inline VerFileIterator() : Owner(0), FileP(0) {};
inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {};
class pkgCache::VerFileIterator : public pkgCache::Iterator<VerFile, VerFileIterator> {
protected:
inline VerFile* OwnerPointer() const {
return Owner->VerFileP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->VerFileP) S = Owner->VerFileP + S->NextFile;};
inline void operator ++() {operator ++(0);};

// Accessors
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};

inline VerFileIterator() : Iterator<VerFile, VerFileIterator>() {};
inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Iterator<VerFile, VerFileIterator>(Owner, Trg) {};
};
/*}}}*/
// Description File /*{{{*/
class pkgCache::DescFileIterator
{
pkgCache *Owner;
DescFile *FileP;

public:

// Iteration
void operator ++(int) {if (FileP != Owner->DescFileP) FileP = Owner->DescFileP + FileP->NextFile;};
inline void operator ++() {operator ++(0);};
inline bool end() const {return Owner == 0 || FileP == Owner->DescFileP?true:false;};

// Comparison
inline bool operator ==(const DescFileIterator &B) const {return FileP == B.FileP;};
inline bool operator !=(const DescFileIterator &B) const {return FileP != B.FileP;};
// Accessors
inline DescFile *operator ->() {return FileP;};
inline DescFile const *operator ->() const {return FileP;};
inline DescFile const &operator *() const {return *FileP;};
inline operator DescFile *() {return FileP == Owner->DescFileP?0:FileP;};
inline operator DescFile const *() const {return FileP == Owner->DescFileP?0:FileP;};
inline pkgCache *Cache() {return Owner;};
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);};
inline unsigned long Index() const {return FileP - Owner->DescFileP;};
inline DescFileIterator() : Owner(0), FileP(0) {};
inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Owner(&Owner), FileP(Trg) {};
class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
protected:
inline DescFile* OwnerPointer() const {
return Owner->DescFileP;
};

public:
// Iteration
void operator ++(int) {if (S != Owner->DescFileP) S = Owner->DescFileP + S->NextFile;};
inline void operator ++() {operator ++(0);};

// Accessors
inline PkgFileIterator File() const {return PkgFileIterator(*Owner,S->File + Owner->PkgFileP);};

inline DescFileIterator() : Iterator<DescFile, DescFileIterator>() {};
inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator<DescFile, DescFileIterator>(Owner, Trg) {};
};
/*}}}*/
// Inlined Begin functions cant be in the class because of order problems /*{{{*/
inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
{return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
{return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);};
{return VerIterator(*Owner,Owner->VerP + S->VersionList);};
inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
{return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);};
{return VerIterator(*Owner,Owner->VerP + S->CurrentVer);};
inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const
{return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);};
{return DepIterator(*Owner,Owner->DepP + S->RevDepends,S);};
inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const
{return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);};
{return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
inline pkgCache::DescIterator pkgCache::VerIterator::DescriptionList() const
{return DescIterator(*Owner,Owner->DescP + Ver->DescriptionList);};
{return DescIterator(*Owner,Owner->DescP + S->DescriptionList);};
inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const
{return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);};
{return PrvIterator(*Owner,Owner->ProvideP + S->ProvidesList,S);};
inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const
{return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);};
{return DepIterator(*Owner,Owner->DepP + S->DependsList,S);};
inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const
{return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);};
{return VerFileIterator(*Owner,Owner->VerFileP + S->FileList);};
inline pkgCache::DescFileIterator pkgCache::DescIterator::FileList() const
{return DescFileIterator(*Owner,Owner->DescFileP + Desc->FileList);};
{return DescFileIterator(*Owner,Owner->DescFileP + S->FileList);};
/*}}}*/
#endif

+ 13
- 21
apt-pkg/cdrom.cc View File

@@ -6,6 +6,8 @@
#include<apt-pkg/cdromutl.h>
#include<apt-pkg/strutl.h>
#include<apt-pkg/cdrom.h>
#include<apt-pkg/aptconfiguration.h>

#include<sstream>
#include<fstream>
#include<config.h>
@@ -216,33 +218,23 @@ int pkgCdrom::Score(string Path)
/* Here we drop everything that is not this machines arch */
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++)
{
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;

// 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);
I--;
--I; // the next entry is at the same index after the erase
}
return true;


+ 3
- 3
apt-pkg/clean.cc View File

@@ -12,6 +12,7 @@
#include <apt-pkg/strutl.h>
#include <apt-pkg/error.h>
#include <apt-pkg/configuration.h>
#include <apt-pkg/aptconfiguration.h>

#include <apti18n.h>

@@ -26,7 +27,6 @@
bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
{
bool CleanInstalled = _config->FindB("APT::Clean-Installed",true);
string MyArch = _config->Find("APT::Architecture");
DIR *D = opendir(Dir.c_str());
if (D == 0)
@@ -75,9 +75,9 @@ bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache)
for (I = Start; *I != 0 && *I != '.' ;I++);
if (*I != '.')
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;
// Lookup the package


+ 16
- 16
apt-pkg/contrib/macros.h View File

@@ -56,33 +56,33 @@

// some nice optional GNUC features
#if __GNUC__ >= 3
#define __must_check __attribute__ ((warn_unused_result))
#define __deprecated __attribute__ ((deprecated))
/* likely() and unlikely() can be used to mark boolean expressions
as (not) likely true which will help the compiler to optimise */
#define likely(x) __builtin_expect (!!(x), 1)
#define unlikely(x) __builtin_expect (!!(x), 0)
#define __must_check __attribute__ ((warn_unused_result))
#define __deprecated __attribute__ ((deprecated))
/* likely() and unlikely() can be used to mark boolean expressions
as (not) likely true which will help the compiler to optimise */
#define likely(x) __builtin_expect (!!(x), 1)
#define unlikely(x) __builtin_expect (!!(x), 0)
#else
#define __must_check /* no warn_unused_result */
#define __deprecated /* no deprecated */
#define likely(x) (x)
#define unlikely(x) (x)
#define __must_check /* no warn_unused_result */
#define __deprecated /* no deprecated */
#define likely(x) (x)
#define unlikely(x) (x)
#endif

// cold functions are unlikely() to be called
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
#define __cold __attribute__ ((__cold__))
#define __cold __attribute__ ((__cold__))
#else
#define __cold /* no cold marker */
#define __cold /* no cold marker */
#endif

#ifdef __GNUG__
// Methods have a hidden this parameter that is visible to this attribute
#define __like_printf_1 __attribute__ ((format (printf, 2, 3)))
#define __like_printf_2 __attribute__ ((format (printf, 3, 4)))
#define __like_printf_1 __attribute__ ((format (printf, 2, 3)))
#define __like_printf_2 __attribute__ ((format (printf, 3, 4)))
#else
#define __like_printf_1
#define __like_printf_2
#define __like_printf_1 /* no like-printf */
#define __like_printf_2 /* no like-printf */
#endif

#endif

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

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


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

@@ -46,6 +46,7 @@ class debPackagesIndex : public pkgIndexFile
string URI;
string Dist;
string Section;
string Architecture;

string Info(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 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


+ 165
- 45
apt-pkg/deb/deblistparser.cc View File

@@ -31,10 +31,13 @@ static debListParser::WordList PrioList[] = {{"important",pkgCache::State::Impor

// 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 /*{{{*/
@@ -52,12 +55,38 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag)
// ListParser::Package - Return the package name /*{{{*/
// ---------------------------------------------------------------------
/* This is to return the name of the package this section describes */
string debListParser::Package()
{
string Result = Section.FindS("Package");
if (Result.empty() == true)
_error->Error("Encountered a section with no Package: header");
return Result;
string debListParser::Package() {
string const Result = Section.FindS("Package");
if(unlikely(Result.empty() == true))
_error->Error("Encountered a section with no Package: header");
return Result;
}
/*}}}*/
// ListParser::Architecture - Return the package arch /*{{{*/
// ---------------------------------------------------------------------
/* This will return the Architecture of the package this section describes
Note that architecture "all" packages will get the architecture of the
Packages file parsed here. */
string debListParser::Architecture() {
string const Result = Section.FindS("Architecture");
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;
}
/*}}}*/
// ListParser::ArchitectureAll /*{{{*/
// ---------------------------------------------------------------------
/* */
bool debListParser::ArchitectureAll() {
return Section.FindS("Architecture") == "all";
}
/*}}}*/
// ListParser::Version - Return the version string /*{{{*/
@@ -77,8 +106,31 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
{
// Parse the section
Ver->Section = UniqFindTagWrite("Section");
Ver->Arch = UniqFindTagWrite("Architecture");

// Parse multi-arch
if (Section.FindS("Architecture") == "all")
/* Arch all packages can't have a Multi-Arch field,
but we need a special treatment for them nonetheless */
Ver->MultiArch = pkgCache::Version::All;
else
{
string const MultiArch = Section.FindS("Multi-Arch");
if (MultiArch.empty() == true)
Ver->MultiArch = pkgCache::Version::None;
else if (MultiArch == "same")
Ver->MultiArch = pkgCache::Version::Same;
else if (MultiArch == "foreign")
Ver->MultiArch = pkgCache::Version::Foreign;
else if (MultiArch == "allowed")
Ver->MultiArch = pkgCache::Version::Allowed;
else
{
_error->Warning("Unknown Multi-Arch type »%s« for package »%s«",
MultiArch.c_str(), Section.FindS("Package").c_str());
Ver->MultiArch = pkgCache::Version::None;
}
}

// Archive Size
Ver->Size = (unsigned)Section.FindI("Size");
@@ -95,6 +147,25 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
Ver->Priority = pkgCache::State::Extra;
}

if (Ver->MultiArch == pkgCache::Version::All)
{
/* We maintain a "pseudo" arch=all package for architecture all versions
on which these versions can depend on. This pseudo package is many used
for downloading/installing: The other pseudo-packages will degenerate
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)
{
// our pseudo packages have no size to not confuse the fetcher
Ver->Size = 0;
Ver->InstalledSize = 0;
}
}

if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false)
return false;
if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false)
@@ -183,8 +254,12 @@ bool debListParser::UsePackage(pkgCache::PkgIterator Pkg,
{
if (Pkg->Section == 0)
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)
return false;

@@ -534,8 +609,12 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
const char *Stop;
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;
unsigned int Op;

@@ -544,8 +623,18 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
Start = ParseDepends(Start,Stop,Package,Version,Op);
if (Start == 0)
return _error->Error("Problem parsing dependency %s",Tag);
if (NewDepends(Ver,Package,Version,Op,Type) == false)

if (multiArch == 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)
if (NewDepends(Ver,Package,*a,Version,Op,Type) == false)
return false;
}
else if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false)
return false;
if (Start == Stop)
break;
@@ -560,29 +649,52 @@ bool debListParser::ParseProvides(pkgCache::VerIterator Ver)
{
const char *Start;
const char *Stop;
if (Section.Find("Provides",Start,Stop) == false)
return true;
string Package;
string Version;
unsigned int Op;

while (1)
if (Section.Find("Provides",Start,Stop) == true)
{
Start = ParseDepends(Start,Stop,Package,Version,Op);
if (Start == 0)
return _error->Error("Problem parsing Provides line");
if (Op != pkgCache::Dep::NoOp) {
_error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
} else {
if (NewProvides(Ver,Package,Version) == false)
return false;
string Package;
string Version;
string const Arch = Ver.Arch(true);
unsigned int Op;

while (1)
{
Start = ParseDepends(Start,Stop,Package,Version,Op);
if (Start == 0)
return _error->Error("Problem parsing Provides line");
if (Op != pkgCache::Dep::NoOp) {
_error->Warning("Ignoring Provides line with DepCompareOp for package %s", Package.c_str());
} else {
if (NewProvides(Ver, Package, Arch, Version) == false)
return false;
}

if (Start == Stop)
break;
}
}

if (Start == Stop)
break;
if (Ver->MultiArch == pkgCache::Version::Allowed)
{
string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
NewProvides(Ver, Package, "any", Ver.VerStr());
}

if (Ver->MultiArch != pkgCache::Version::Foreign)
return true;

std::vector<string> const archs = APT::Configuration::getArchitectures();
if (archs.size() <= 1)
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)
{
if (NewProvides(Ver, Package, *a, Version) == false)
return false;
}

return true;
}
/*}}}*/
@@ -613,16 +725,23 @@ bool debListParser::Step()
/* 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 */
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;

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();
}
@@ -640,8 +759,9 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
if (Tags.Step(Section) == false)
return false;

//mvo: I don't think we need to fill that in (it's unused since apt-0.6)
//FileI->Architecture = WriteUniqString(Arch);
// FIXME: Do we need it now for multi-arch?
// mvo: I don't think we need to fill that in (it's unused since apt-0.6)
// FileI->Architecture = WriteUniqString(Arch);
// apt-secure does no longer download individual (per-section) Release
// file. to provide Component pinning we use the section name now


+ 3
- 1
apt-pkg/deb/deblistparser.h View File

@@ -46,6 +46,8 @@ class debListParser : public pkgCacheGenerator::ListParser
// These all operate against the current section
virtual string Package();
virtual string Architecture();
virtual bool ArchitectureAll();
virtual string Version();
virtual bool NewVersion(pkgCache::VerIterator Ver);
virtual string Description();
@@ -68,7 +70,7 @@ class debListParser : public pkgCacheGenerator::ListParser
bool const &StripMultiArch = false);
static const char *ConvertRelation(const char *I,unsigned int &Op);

debListParser(FileFd *File);
debListParser(FileFd *File, string const &Arch = "");
};

#endif

+ 186
- 112
apt-pkg/deb/debmetaindex.cc View File

@@ -8,9 +8,11 @@
#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/error.h>

#include <set>

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) + ' ';
if (Dist[Dist.size() - 1] == '/')
@@ -19,7 +21,11 @@ string debReleaseIndex::Info(const char *Type, const string Section) const
Info += Dist;
}
else
Info += Dist + '/' + Section;
{
Info += Dist + '/' + Section;
if (Arch.empty() == true)
Info += " " + Arch;
}
Info += " ";
Info += Type;
return Info;
@@ -61,16 +67,21 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const
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 ="";
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;
}

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] == '/')
{
@@ -82,10 +93,10 @@ string debReleaseIndex::IndexURI(const char *Type, const string Section) const
return Res + Type;
}
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 ="";
if (Dist[Dist.size() - 1] != '/')
@@ -93,7 +104,7 @@ string debReleaseIndex::SourceIndexURISuffix(const char *Type, const string Sect
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;
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);
}

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
if (GetAll) {
@@ -170,24 +198,28 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool GetAll) const
ComputeIndexTargets(),
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++)
{
if (*l == "none") continue;
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++) {
if (*l == "none") continue;
debTranslationsIndex i = debTranslationsIndex(URI,Dist,s->first,(*l).c_str());
i.GetIndexes(Owner);
}

return true;
}

bool debReleaseIndex::IsTrusted() const
@@ -204,73 +236,113 @@ bool debReleaseIndex::IsTrusted() const
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++) {
if (*l == "none") continue;
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++) {
if (*l == "none") continue;
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
{
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++)
{
// 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.
// 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);
return true;
}
@@ -280,10 +352,11 @@ class debSLTypeDeb : public debSLTypeDebian
{
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()
@@ -297,10 +370,11 @@ class debSLTypeDebSrc : public debSLTypeDebian
{
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()


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

@@ -5,40 +5,44 @@
#include <apt-pkg/metaindex.h>
#include <apt-pkg/sourcelist.h>

#include <map>

class debReleaseIndex : public metaIndex {
public:

class debSectionEntry
{
public:
debSectionEntry (string Section, bool IsSrc);
bool IsSrc;
string Section;
debSectionEntry (string const &Section, bool const &IsSrc);
string const Section;
bool const IsSrc;
};

private:
vector <const debSectionEntry *> SectionEntries;
std::map<string, vector<debSectionEntry const*> > ArchEntries;

public:

debReleaseIndex(string URI, string Dist);
debReleaseIndex(string const &URI, string const &Dist);
~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;
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 MetaIndexFile(const char *Types) 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;