summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2009-12-27 19:39:47 +0100
committerDavid Kalnischkies <kalnischkies@gmail.com>2009-12-27 19:39:47 +0100
commit25396fb06350344996a20d05423562f08a4165db (patch)
tree6d86e407c280333624b8f9949467f90612258282 /apt-pkg
parent5dd4c8b811d9c7bc33e50254811f5bc0fc37f872 (diff)
Split ListParser::NewDepends into two methods to use these new method
for creating the dependencies needed for our groups: For now for all groups only one package can be installed at the same time which conflicts with each other packages in the group. The exceptions are architecture all package. Also, the Multi-Arch field is now parsed, but not used for now.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/cacheiterators.h14
-rw-r--r--apt-pkg/deb/deblistparser.cc24
-rw-r--r--apt-pkg/pkgcache.cc27
-rw-r--r--apt-pkg/pkgcache.h12
-rw-r--r--apt-pkg/pkgcachegen.cc133
-rw-r--r--apt-pkg/pkgcachegen.h6
6 files changed, 176 insertions, 40 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 35d3aa228..33d2ed6be 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -81,13 +81,21 @@ template<typename Str, typename Itr> class pkgCache::Iterator {
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:
- void operator ++(int) {if (S != Owner->GrpP) S = Owner->GrpP + S->Next;};
+ // 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;};
@@ -96,11 +104,11 @@ class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
PkgIterator NextPkg(PkgIterator const &Pkg);
// Constructors
- inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg) {
+ inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg), HashIndex(0) {
if (S == 0)
S = OwnerPointer();
};
- inline GrpIterator() : Iterator<Group, GrpIterator>() {};
+ inline GrpIterator() : Iterator<Group, GrpIterator>(), HashIndex(0) {};
};
/*}}}*/
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index b57eca813..f683de423 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -104,6 +104,30 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
// Parse the architecture
Ver->Arch = WriteUniqString(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");
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index c945c59bf..1e4c7edb3 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -182,6 +182,16 @@ unsigned long pkgCache::sHash(const char *Str) const
// Cache::FindPkg - Locate a package by name /*{{{*/
// ---------------------------------------------------------------------
/* Returns 0 on error, pointer to the package otherwise */
+pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
+ size_t const found = Name.find(':');
+ if (found == string::npos)
+ return FindPkg(Name, "native");
+ return FindPkg(Name.substr(0, found), Name.substr(found+1, string::npos));
+}
+ /*}}}*/
+// Cache::FindPkg - Locate a package by name /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns 0 on error, pointer to the package otherwise */
pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) {
/* We make a detour via the GrpIterator here as
on a multi-arch environment a group is easier to
@@ -322,6 +332,23 @@ pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const
return PkgIterator(*Owner, 0);
}
/*}}}*/
+// GrpIterator::operator ++ - Postfix incr /*{{{*/
+// ---------------------------------------------------------------------
+/* This will advance to the next logical group in the hash table. */
+void pkgCache::GrpIterator::operator ++(int)
+{
+ // Follow the current links
+ if (S != Owner->GrpP)
+ S = Owner->GrpP + S->Next;
+
+ // Follow the hash table
+ while (S == Owner->GrpP && (HashIndex+1) < (signed)_count(Owner->HeaderP->GrpHashTable))
+ {
+ HashIndex++;
+ S = Owner->GrpP + Owner->HeaderP->GrpHashTable[HashIndex];
+ }
+};
+ /*}}}*/
// PkgIterator::operator ++ - Postfix incr /*{{{*/
// ---------------------------------------------------------------------
/* This will advance to the next logical package in the hash table. */
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index b3d2752d2..5f50001d0 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -125,9 +125,12 @@ class pkgCache /*{{{*/
// Accessors
GrpIterator FindGrp(const string &Name);
- PkgIterator FindPkg(const string &Name, string Arch = "native");
+ PkgIterator FindPkg(const string &Name);
+ PkgIterator FindPkg(const string &Name, string Arch);
Header &Head() {return *HeaderP;};
+ inline GrpIterator GrpBegin();
+ inline GrpIterator GrpEnd();
inline PkgIterator PkgBegin();
inline PkgIterator PkgEnd();
inline PkgFileIterator FileBegin();
@@ -274,7 +277,8 @@ struct pkgCache::Version /*{{{*/
map_ptrloc VerStr; // Stringtable
map_ptrloc Section; // StringTable (StringItem)
map_ptrloc Arch; // StringTable
-
+ enum {None, All, Foreign, Same, Allowed} MultiArch;
+
// Lists
map_ptrloc FileList; // VerFile
map_ptrloc NextVer; // Version
@@ -337,6 +341,10 @@ struct pkgCache::StringItem /*{{{*/
/*}}}*/
#include <apt-pkg/cacheiterators.h>
+inline pkgCache::GrpIterator pkgCache::GrpBegin()
+ {return GrpIterator(*this);};
+inline pkgCache::GrpIterator pkgCache::GrpEnd()
+ {return GrpIterator(*this,GrpP);};
inline pkgCache::PkgIterator pkgCache::PkgBegin()
{return PkgIterator(*this);};
inline pkgCache::PkgIterator pkgCache::PkgEnd()
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index c37f6f48e..2a4a30349 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -18,6 +18,7 @@
#include <apt-pkg/progress.h>
#include <apt-pkg/sourcelist.h>
#include <apt-pkg/configuration.h>
+#include <apt-pkg/aptconfiguration.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/pkgsystem.h>
@@ -38,7 +39,7 @@ typedef vector<pkgIndexFile *>::iterator FileIterator;
// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
// ---------------------------------------------------------------------
-/* We set the diry flag and make sure that is written to the disk */
+/* We set the dirty flag and make sure that is written to the disk */
pkgCacheGenerator::pkgCacheGenerator(DynamicMMap *pMap,OpProgress *Prog) :
Map(*pMap), Cache(pMap,false), Progress(Prog),
FoundFileDeps(0)
@@ -506,21 +507,58 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
return Description;
}
/*}}}*/
-// ListParser::NewDepends - Create a dependency element /*{{{*/
+// CacheGenerator::FinishCache - do various finish operations /*{{{*/
+// ---------------------------------------------------------------------
+/* This prepares the Cache for delivery */
+bool pkgCacheGenerator::FinishCache(OpProgress &Progress) {
+ // FIXME: add progress reporting for this operation
+ // Do we have different architectures in your groups ?
+ vector<string> archs = APT::Configuration::getArchitectures();
+ if (archs.size() > 1) {
+ // Create Conflicts in between the group
+ for (pkgCache::GrpIterator G = GetCache().GrpBegin(); G.end() != true; G++) {
+ string const PkgName = G.Name();
+ for (pkgCache::PkgIterator P = G.PackageList(); P.end() != true; P = G.NextPkg(P)) {
+ for (pkgCache::VerIterator V = P.VersionList(); V.end() != true; V++) {
+ // Arch all packages are "co-installable"
+ if (V->MultiArch == pkgCache::Version::All)
+ continue;
+ string const Arch = V.Arch();
+ map_ptrloc *OldDepLast = NULL;
+ for (vector<string>::const_iterator A = archs.begin(); A != archs.end(); ++A) {
+ if (*A == Arch)
+ continue;
+ /* We allow only one installed arch at the time
+ per group, therefore each group member conflicts
+ with all other group members */
+ pkgCache::PkgIterator D = G.FindPkg(*A);
+ if (D.end() == true)
+ continue;
+ // Conflicts: ${self}:other
+ NewDepends(D, V, "",
+ pkgCache::Dep::NoOp, pkgCache::Dep::Conflicts,
+ OldDepLast);
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+ /*}}}*/
+// CacheGenerator::NewDepends - Create a dependency element /*{{{*/
// ---------------------------------------------------------------------
/* This creates a dependency element in the tree. It is linked to the
version and to the package that it is pointing to. */
-bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
- const string &PackageName,
- const string &Arch,
- const string &Version,
- unsigned int Op,
- unsigned int Type)
+bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
+ pkgCache::VerIterator &Ver,
+ string const &Version,
+ unsigned int const &Op,
+ unsigned int const &Type,
+ map_ptrloc *OldDepLast)
{
- pkgCache &Cache = Owner->Cache;
-
// Get a structure
- unsigned long const Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency));
+ unsigned long const Dependency = Map.Allocate(sizeof(pkgCache::Dependency));
if (unlikely(Dependency == 0))
return false;
@@ -530,17 +568,6 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
Dep->Type = Type;
Dep->CompareOp = Op;
Dep->ID = Cache.HeaderP->DependsCount++;
-
- pkgCache::GrpIterator Grp;
- if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
- return false;
-
- // Locate the target package
- pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch);
- if (Pkg.end() == true) {
- if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false))
- return false;
- }
// Probe the reverse dependency list for a version string that matches
if (Version.empty() == false)
@@ -549,29 +576,23 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
if (I->Version != 0 && I.TargetVer() == Version)
Dep->Version = I->Version;*/
if (Dep->Version == 0)
- if (unlikely((Dep->Version = WriteString(Version)) == 0))
+ if (unlikely((Dep->Version = Map.WriteString(Version)) == 0))
return false;
}
-
+
// Link it to the package
Dep->Package = Pkg.Index();
Dep->NextRevDepends = Pkg->RevDepends;
Pkg->RevDepends = Dep.Index();
-
- /* Link it to the version (at the end of the list)
- Caching the old end point speeds up generation substantially */
- if (OldDepVer != Ver)
+
+ // Do we know where to link the Dependency to?
+ if (OldDepLast == NULL)
{
OldDepLast = &Ver->DependsList;
for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++)
OldDepLast = &D->NextDepends;
- OldDepVer = Ver;
}
- // Is it a file dependency?
- if (unlikely(PackageName[0] == '/'))
- FoundFileDeps = true;
-
Dep->NextDepends = *OldDepLast;
*OldDepLast = Dep.Index();
OldDepLast = &Dep->NextDepends;
@@ -579,6 +600,41 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
return true;
}
/*}}}*/
+// ListParser::NewDepends - Create the environment for a new dependency /*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a Group and the Package to link this dependency to if
+ needed and handles also the caching of the old endpoint */
+bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
+ const string &PackageName,
+ const string &Arch,
+ const string &Version,
+ unsigned int Op,
+ unsigned int Type)
+{
+ pkgCache::GrpIterator Grp;
+ if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
+ return false;
+
+ // Locate the target package
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch);
+ if (Pkg.end() == true) {
+ if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false))
+ return false;
+ }
+
+ // Is it a file dependency?
+ if (unlikely(PackageName[0] == '/'))
+ FoundFileDeps = true;
+
+ /* Caching the old end point speeds up generation substantially */
+ if (OldDepVer != Ver) {
+ OldDepLast = NULL;
+ OldDepVer = Ver;
+ }
+
+ return Owner->NewDepends(Pkg, Ver, Version, Op, Type, OldDepLast);
+}
+ /*}}}*/
// ListParser::NewProvides - Create a Provides element /*{{{*/
// ---------------------------------------------------------------------
/* */
@@ -925,6 +981,9 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
Files.begin()+EndOfSource,Files.end()) == false)
return false;
+
+ // FIXME: move me to a better place
+ Gen.FinishCache(Progress);
}
else
{
@@ -965,6 +1024,9 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress,
if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
Files.begin()+EndOfSource,Files.end()) == false)
return false;
+
+ // FIXME: move me to a better place
+ Gen.FinishCache(Progress);
}
if (_error->PendingError() == true)
@@ -1010,7 +1072,10 @@ bool pkgMakeOnlyStatusCache(OpProgress &Progress,DynamicMMap **OutMap)
if (BuildCache(Gen,Progress,CurrentSize,TotalSize,
Files.begin()+EndOfSource,Files.end()) == false)
return false;
-
+
+ // FIXME: move me to a better place
+ Gen.FinishCache(Progress);
+
if (_error->PendingError() == true)
return false;
*OutMap = Map.UnGuard();
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 4a2419b24..53f09b991 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -55,6 +55,9 @@ class pkgCacheGenerator /*{{{*/
bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, const string &Arch);
bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
+ bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
+ string const &Version, unsigned int const &Op,
+ unsigned int const &Type, map_ptrloc *OldDepLast);
unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next);
map_ptrloc NewDescription(pkgCache::DescIterator &Desc,const string &Lang,const MD5SumValue &md5sum,map_ptrloc Next);
@@ -73,7 +76,8 @@ class pkgCacheGenerator /*{{{*/
bool HasFileDeps() {return FoundFileDeps;};
bool MergeFileProvides(ListParser &List);
-
+ bool FinishCache(OpProgress &Progress);
+
pkgCacheGenerator(DynamicMMap *Map,OpProgress *Progress);
~pkgCacheGenerator();
};