summaryrefslogtreecommitdiff
path: root/apt-pkg/pkgcachegen.cc
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-07-16 19:41:45 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-08-10 17:27:59 +0200
commitecc138f858fab61e0b888d3d13854d1422c3432b (patch)
treeb7bd372c9ee7630a157afeeaab52d04efb72a4dc /apt-pkg/pkgcachegen.cc
parent8c7af4d4c95d0423fbd0f3baa979792504f4f45f (diff)
just-in-time creation for (implicit) Provides
Expecting the worst is easy to code, but has its disadvantages e.g. by creating package structures which otherwise would have never existed. By creating the provides instead at the time a package structure is added we are well prepared for the introduction of partial architectures, massive amounts of M-A:foreign (and :allowed) and co as far as provides are concerned at least. We have something relatively similar for dependencies already. Many tests are added for both M-A states and the code cleaned to properly support implicit provides for foreign architectures and architectures we 'just' happen to parse. Git-Dch: Ignore
Diffstat (limited to 'apt-pkg/pkgcachegen.cc')
-rw-r--r--apt-pkg/pkgcachegen.cc123
1 files changed, 92 insertions, 31 deletions
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 9acb2563a..c04320555 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -648,6 +648,16 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
return false;
Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package);
+ // Set the name, arch and the ID
+ APT_IGNORE_DEPRECATED(Pkg->Name = Grp->Name;)
+ Pkg->Group = Grp.Index();
+ // all is mapped to the native architecture
+ map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : StoreString(MIXED, Arch);
+ if (unlikely(idxArch == 0))
+ return false;
+ Pkg->Arch = idxArch;
+ Pkg->ID = Cache.HeaderP->PackageCount++;
+
// Insert the package into our package list
if (Grp->FirstPackage == 0) // the group is new
{
@@ -662,23 +672,36 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
}
else // Group the Packages together
{
+ // but first get implicit provides done
+ if (APT::Configuration::checkArchitecture(Pkg.Arch()) == true)
+ {
+ pkgCache::PkgIterator const M = Grp.FindPreferredPkg(false); // native or any foreign pkg will do
+ if (M.end() == false)
+ for (pkgCache::PrvIterator Prv = M.ProvidesList(); Prv.end() == false; ++Prv)
+ {
+ if ((Prv->Flags & pkgCache::Flag::ArchSpecific) != 0)
+ continue;
+ pkgCache::VerIterator Ver = Prv.OwnerVer();
+ if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed ||
+ ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign &&
+ (Prv->Flags & pkgCache::Flag::MultiArchImplicit) == 0))
+ if (NewProvides(Ver, Pkg, Prv->ProvideVersion, Prv->Flags) == false)
+ return false;
+ }
+
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() == false; P = Grp.NextPkg(P))
+ for (pkgCache::VerIterator Ver = P.VersionList(); Ver.end() == false; ++Ver)
+ if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
+ if (NewProvides(Ver, Pkg, Ver->VerStr, pkgCache::Flag::MultiArchImplicit) == false)
+ return false;
+ }
+
// this package is the new last package
pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
Pkg->NextPackage = LastPkg->NextPackage;
LastPkg->NextPackage = Package;
}
Grp->LastPackage = Package;
-
- // Set the name, arch and the ID
- APT_IGNORE_DEPRECATED(Pkg->Name = Grp->Name;)
- Pkg->Group = Grp.Index();
- // all is mapped to the native architecture
- map_stringitem_t const idxArch = (Arch == "all") ? Cache.HeaderP->Architecture : StoreString(MIXED, Arch);
- if (unlikely(idxArch == 0))
- return false;
- Pkg->Arch = idxArch;
- Pkg->ID = Cache.HeaderP->PackageCount++;
-
return true;
}
/*}}}*/
@@ -1079,44 +1102,82 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator &Ver,
const string &Version,
uint8_t const Flags)
{
- pkgCache &Cache = Owner->Cache;
+ pkgCache const &Cache = Owner->Cache;
// We do not add self referencing provides
if (Ver.ParentPkg().Name() == PkgName && (PkgArch == Ver.ParentPkg().Arch() ||
(PkgArch == "all" && strcmp((Cache.StrP + Cache.HeaderP->Architecture), Ver.ParentPkg().Arch()) == 0)))
return true;
-
+
+ // Locate the target package
+ pkgCache::PkgIterator Pkg;
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
+ if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false))
+ return false;
+
+ map_stringitem_t idxProvideVersion = 0;
+ if (Version.empty() == false) {
+ idxProvideVersion = StoreString(VERSIONNUMBER, Version);
+ if (unlikely(idxProvideVersion == 0))
+ return false;
+ }
+ return Owner->NewProvides(Ver, Pkg, idxProvideVersion, Flags);
+}
+bool pkgCacheGenerator::NewProvides(pkgCache::VerIterator &Ver,
+ pkgCache::PkgIterator &Pkg,
+ map_pointer_t const ProvideVersion,
+ uint8_t const Flags)
+{
// Get a structure
- map_pointer_t const Provides = Owner->AllocateInMap(sizeof(pkgCache::Provides));
+ map_pointer_t const Provides = AllocateInMap(sizeof(pkgCache::Provides));
if (unlikely(Provides == 0))
return false;
- Cache.HeaderP->ProvidesCount++;
-
+ ++Cache.HeaderP->ProvidesCount;
+
// Fill it in
pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP);
- Dynamic<pkgCache::PrvIterator> DynPrv(Prv);
Prv->Version = Ver.Index();
+ Prv->ProvideVersion = ProvideVersion;
Prv->Flags = Flags;
Prv->NextPkgProv = Ver->ProvidesList;
Ver->ProvidesList = Prv.Index();
- if (Version.empty() == false) {
- map_stringitem_t const idxProvideVersion = WriteString(Version);
- Prv->ProvideVersion = idxProvideVersion;
- if (unlikely(idxProvideVersion == 0))
- return false;
- }
-
- // Locate the target package
- pkgCache::PkgIterator Pkg;
- Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
- if (unlikely(Owner->NewPackage(Pkg,PkgName, PkgArch) == false))
- return false;
-
+
// Link it to the package
Prv->ParentPkg = Pkg.Index();
Prv->NextProvides = Pkg->ProvidesList;
Pkg->ProvidesList = Prv.Index();
-
+ return true;
+}
+ /*}}}*/
+// ListParser::NewProvidesAllArch - add provides for all architectures /*{{{*/
+bool pkgCacheGenerator::ListParser::NewProvidesAllArch(pkgCache::VerIterator &Ver, string const &Package,
+ string const &Version, uint8_t const Flags) {
+ pkgCache &Cache = Owner->Cache;
+ pkgCache::GrpIterator const Grp = Cache.FindGrp(Package);
+ if (Grp.end() == true)
+ return NewProvides(Ver, Package, Cache.NativeArch(), Version, Flags);
+ else
+ {
+ map_stringitem_t idxProvideVersion = 0;
+ if (Version.empty() == false) {
+ idxProvideVersion = StoreString(VERSIONNUMBER, Version);
+ if (unlikely(idxProvideVersion == 0))
+ return false;
+ }
+
+ bool const isImplicit = (Flags & pkgCache::Flag::MultiArchImplicit) == pkgCache::Flag::MultiArchImplicit;
+ bool const isArchSpecific = (Flags & pkgCache::Flag::ArchSpecific) == pkgCache::Flag::ArchSpecific;
+ pkgCache::PkgIterator const OwnerPkg = Ver.ParentPkg();
+ for (pkgCache::PkgIterator Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+ {
+ if (isImplicit && OwnerPkg == Pkg)
+ continue;
+ if (isArchSpecific == false && APT::Configuration::checkArchitecture(OwnerPkg.Arch()) == false)
+ continue;
+ if (Owner->NewProvides(Ver, Pkg, idxProvideVersion, Flags) == false)
+ return false;
+ }
+ }
return true;
}
/*}}}*/