summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/deblistparser.cc76
1 files changed, 60 insertions, 16 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 602e96e26..b51ee815e 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -803,13 +803,12 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
}
else
{
- string Arch = Package.substr(found+1, string::npos);
- Package = Package.substr(0, found);
// Such dependencies are not supposed to be accepted …
// … but this is probably the best thing to do anyway
- if (Arch == "native")
- Arch = _config->Find("APT::Architecture");
- if (NewDepends(Ver,Package,Arch,Version,Op | pkgCache::Dep::ArchSpecific,Type) == false)
+ if (Package.substr(found + 1) == "native")
+ Package = Package.substr(0, found) + ':' + Ver.Cache()->NativeArch();
+
+ if (NewDepends(Ver, Package, "any", Version, Op | pkgCache::Dep::ArchSpecific, Type) == false)
return false;
}
@@ -824,6 +823,22 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
/* */
bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
{
+ /* it is unlikely, but while parsing dependencies, we might have already
+ picked up multi-arch implicit provides which we do not want to duplicate here */
+ bool hasProvidesAlready = false;
+ std::string const spzName = Ver.ParentPkg().FullName(false);
+ {
+ for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv)
+ {
+ if (Prv.IsMultiArchImplicit() == false || (Prv->Flags & pkgCache::Flag::ArchSpecific) == 0)
+ continue;
+ if (spzName != Prv.OwnerPkg().FullName(false))
+ continue;
+ hasProvidesAlready = true;
+ break;
+ }
+ }
+
string const Arch = Ver.Arch();
const char *Start;
const char *Stop;
@@ -833,31 +848,47 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
string Version;
unsigned int Op;
- while (1)
+ do
{
- Start = ParseDepends(Start,Stop,Package,Version,Op);
+ Start = ParseDepends(Start,Stop,Package,Version,Op, false, false, false);
const size_t archfound = Package.rfind(':');
if (Start == 0)
return _error->Error("Problem parsing Provides line");
if (Op != pkgCache::Dep::NoOp && Op != pkgCache::Dep::Equals) {
_error->Warning("Ignoring Provides line with non-equal DepCompareOp for package %s", Package.c_str());
} else if (archfound != string::npos) {
- string OtherArch = Package.substr(archfound+1, string::npos);
- Package = Package.substr(0, archfound);
- if (NewProvides(Ver, Package, OtherArch, Version, pkgCache::Flag::ArchSpecific) == false)
+ std::string spzArch = Package.substr(archfound + 1);
+ if (spzArch != "any")
+ {
+ if (NewProvides(Ver, Package.substr(0, archfound), spzArch, Version, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+ return false;
+ }
+ if (NewProvides(Ver, Package, "any", Version, pkgCache::Flag::ArchSpecific) == false)
return false;
} else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) {
if (APT::Configuration::checkArchitecture(Arch))
if (NewProvidesAllArch(Ver, Package, Version, 0) == false)
return false;
} else {
+ if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
+ {
+ if (NewProvides(Ver, Package + ":any", "any", Version, pkgCache::Flag::MultiArchImplicit) == false)
+ return false;
+ }
if (NewProvides(Ver, Package, Arch, Version, 0) == false)
return false;
}
-
- if (Start == Stop)
- break;
- }
+ if (archfound == std::string::npos)
+ {
+ std::string const spzName = Package + ':' + Ver.ParentPkg().Arch();
+ pkgCache::PkgIterator const spzPkg = Ver.Cache()->FindPkg(spzName, "any");
+ if (spzPkg.end() == false)
+ {
+ if (NewProvides(Ver, spzName, "any", Version, pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+ return false;
+ }
+ }
+ } while (Start != Stop);
}
if (APT::Configuration::checkArchitecture(Arch))
@@ -865,12 +896,25 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver)
if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
{
string const Package = string(Ver.ParentPkg().Name()).append(":").append("any");
- return NewProvides(Ver, Package, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit);
+ if (NewProvides(Ver, Package, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit) == false)
+ return false;
}
else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
- return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit);
+ {
+ if (NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr(), pkgCache::Flag::MultiArchImplicit) == false)
+ return false;
+ }
}
+ if (hasProvidesAlready == false)
+ {
+ pkgCache::PkgIterator const spzPkg = Ver.Cache()->FindPkg(spzName, "any");
+ if (spzPkg.end() == false)
+ {
+ if (NewProvides(Ver, spzName, "any", Ver.VerStr(), pkgCache::Flag::MultiArchImplicit | pkgCache::Flag::ArchSpecific) == false)
+ return false;
+ }
+ }
return true;
}
/*}}}*/