summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/deb/deblistparser.cc30
-rw-r--r--apt-pkg/pkgcachegen.cc112
-rw-r--r--apt-pkg/pkgcachegen.h5
-rwxr-xr-xtest/integration/test-apt-cache15
-rwxr-xr-xtest/integration/test-bug-590041-prefer-non-virtual-packages2
-rwxr-xr-xtest/integration/test-multiarch-allowed7
6 files changed, 83 insertions, 88 deletions
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 87aa99c6e..1154016a9 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -790,43 +790,23 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
return _error->Error("Problem parsing dependency %s",Tag);
size_t const found = Package.rfind(':');
- // If negative is unspecific it needs to apply on all architectures
- if (MultiArchEnabled == true && found == string::npos &&
- (Type == pkgCache::Dep::Conflicts ||
- Type == pkgCache::Dep::DpkgBreaks ||
- Type == pkgCache::Dep::Replaces))
+ if (found == string::npos || strcmp(Package.c_str() + found, ":any") == 0)
{
- for (std::vector<std::string>::const_iterator a = Architectures.begin();
- a != Architectures.end(); ++a)
- if (NewDepends(Ver,Package,*a,Version,Op,Type) == false)
- return false;
- if (NewDepends(Ver,Package,"none",Version,Op,Type) == false)
+ if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false)
return false;
}
- else if (found != string::npos &&
- strcmp(Package.c_str() + found, ":any") != 0)
+ 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.
+ // … 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)
return false;
}
- else
- {
- if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false)
- return false;
- if ((Type == pkgCache::Dep::Conflicts ||
- Type == pkgCache::Dep::DpkgBreaks ||
- Type == pkgCache::Dep::Replaces) &&
- NewDepends(Ver, Package,
- (pkgArch != "none") ? "none" : _config->Find("APT::Architecture"),
- Version,Op,Type) == false)
- return false;
- }
+
if (Start == Stop)
break;
}
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index c04320555..26a5e60a6 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -695,6 +695,23 @@ bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name
if (NewProvides(Ver, Pkg, Ver->VerStr, pkgCache::Flag::MultiArchImplicit) == false)
return false;
}
+ // and negative dependencies, don't forget negative dependencies
+ {
+ pkgCache::PkgIterator const M = Grp.FindPreferredPkg(false);
+ if (M.end() == false)
+ for (pkgCache::DepIterator Dep = M.RevDependsList(); Dep.end() == false; ++Dep)
+ {
+ if ((Dep->CompareOp & (pkgCache::Dep::ArchSpecific | pkgCache::Dep::MultiArchImplicit)) != 0)
+ continue;
+ if (Dep->Type != pkgCache::Dep::DpkgBreaks && Dep->Type != pkgCache::Dep::Conflicts &&
+ Dep->Type != pkgCache::Dep::Replaces)
+ continue;
+ pkgCache::VerIterator Ver = Dep.ParentVer();
+ map_pointer_t * unused = NULL;
+ if (NewDepends(Pkg, Ver, Dep->Version, Dep->CompareOp, Dep->Type, unused) == false)
+ return false;
+ }
+ }
// this package is the new last package
pkgCache::PkgIterator LastPkg(Cache, Cache.PkgP + Grp->LastPackage);
@@ -935,33 +952,6 @@ map_pointer_t pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
version and to the package that it is pointing to. */
bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
pkgCache::VerIterator &Ver,
- string const &Version,
- uint8_t const Op,
- uint8_t const Type,
- map_stringitem_t* &OldDepLast)
-{
- map_stringitem_t index = 0;
- if (Version.empty() == false)
- {
- int const CmpOp = Op & 0x0F;
- // =-deps are used (79:1) for lockstep on same-source packages (e.g. data-packages)
- if (CmpOp == pkgCache::Dep::Equals && strcmp(Version.c_str(), Ver.VerStr()) == 0)
- index = Ver->VerStr;
-
- if (index == 0)
- {
- void const * const oldMap = Map.Data();
- index = StoreString(VERSIONNUMBER, Version);
- if (unlikely(index == 0))
- return false;
- if (OldDepLast != 0 && oldMap != Map.Data())
- OldDepLast += (map_pointer_t const * const) Map.Data() - (map_pointer_t const * const) oldMap;
- }
- }
- return NewDepends(Pkg, Ver, index, Op, Type, OldDepLast);
-}
-bool pkgCacheGenerator::NewDepends(pkgCache::PkgIterator &Pkg,
- pkgCache::VerIterator &Ver,
map_pointer_t const Version,
uint8_t const Op,
uint8_t const Type,
@@ -1071,28 +1061,64 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver,
if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
return false;
- // Locate the target package
- pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch);
- // we don't create 'none' packages and their dependencies if we can avoid it …
- if (Pkg.end() == true && Arch == "none" && strcmp(Ver.ParentPkg().Arch(), "none") != 0)
- return true;
- Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
- 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;
+ map_stringitem_t idxVersion = 0;
+ if (Version.empty() == false)
+ {
+ int const CmpOp = Op & 0x0F;
+ // =-deps are used (79:1) for lockstep on same-source packages (e.g. data-packages)
+ if (CmpOp == pkgCache::Dep::Equals && strcmp(Version.c_str(), Ver.VerStr()) == 0)
+ idxVersion = Ver->VerStr;
+
+ if (idxVersion == 0)
+ {
+ idxVersion = StoreString(VERSIONNUMBER, Version);
+ if (unlikely(idxVersion == 0))
+ return false;
+ }
+ }
+
+ bool const isNegative = (Type == pkgCache::Dep::DpkgBreaks ||
+ Type == pkgCache::Dep::Conflicts ||
+ Type == pkgCache::Dep::Replaces);
+
+ pkgCache::PkgIterator Pkg;
+ Dynamic<pkgCache::PkgIterator> DynPkg(Pkg);
+ if (isNegative == false || (Op & pkgCache::Dep::ArchSpecific) == pkgCache::Dep::ArchSpecific || Grp->FirstPackage == 0)
+ {
+ // Locate the target package
+ Pkg = Grp.FindPkg(Arch);
+ if (Pkg.end() == true) {
+ if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false))
+ return false;
+ }
+
+ /* Caching the old end point speeds up generation substantially */
+ if (OldDepVer != Ver) {
+ OldDepLast = NULL;
+ OldDepVer = Ver;
+ }
+
+ return Owner->NewDepends(Pkg, Ver, idxVersion, Op, Type, OldDepLast);
}
+ else
+ {
+ /* 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);
+ for (Pkg = Grp.PackageList(); Pkg.end() == false; Pkg = Grp.NextPkg(Pkg))
+ {
+ if (Owner->NewDepends(Pkg, Ver, idxVersion, Op, Type, OldDepLast) == false)
+ return false;
+ }
+ }
+ return true;
}
/*}}}*/
// ListParser::NewProvides - Create a Provides element /*{{{*/
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 34dc6fead..0d0fb893f 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -76,15 +76,12 @@ class APT_HIDDEN pkgCacheGenerator /*{{{*/
// Flag file dependencies
bool FoundFileDeps;
-
+
bool NewGroup(pkgCache::GrpIterator &Grp,const std::string &Name);
bool NewPackage(pkgCache::PkgIterator &Pkg,const std::string &Name, const std::string &Arch);
bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
- std::string const &Version, uint8_t const Op,
- uint8_t const Type, map_pointer_t* &OldDepLast);
- bool NewDepends(pkgCache::PkgIterator &Pkg, pkgCache::VerIterator &Ver,
map_pointer_t const Version, uint8_t const Op,
uint8_t const Type, map_pointer_t* &OldDepLast);
map_pointer_t NewVersion(pkgCache::VerIterator &Ver,const std::string &VerStr,map_pointer_t const Next) APT_DEPRECATED
diff --git a/test/integration/test-apt-cache b/test/integration/test-apt-cache
index a8ddfd889..1d90eed5c 100755
--- a/test/integration/test-apt-cache
+++ b/test/integration/test-apt-cache
@@ -66,7 +66,6 @@ testsuccessequal 'foo
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>
|Recommends: <cool>
Recommends: <cooler>' aptcache depends foo --implicit
testsuccessequal 'foo
@@ -76,7 +75,6 @@ testsuccessequal 'foo
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>
Recommends: <cool>' aptcache depends foo -o APT::Cache::ShowOnlyFirstOr=1 --implicit
testsuccessequal 'foo
Depends: bar
@@ -86,7 +84,6 @@ testsuccessequal 'foo
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>
|Recommends: <cool> (>= 2)
Recommends: <cooler> (<< 5)' aptcache depends foo -o APT::Cache::ShowVersion=1 --implicit
testsuccessequal 'foo
@@ -94,15 +91,13 @@ testsuccessequal 'foo
Conflicts: <foobar>' aptcache depends foo --no-recommends
testsuccessequal 'foo
Depends: bar
- Conflicts: <foobar>
- Conflicts: <foobar:i386>' aptcache depends foo --no-recommends --implicit
+ Conflicts: <foobar>' aptcache depends foo --no-recommends --implicit
testsuccessequal 'foo
Depends: bar' aptcache depends foo --important --implicit
testsuccessequal 'foo
Conflicts: <foobar>' aptcache depends foo --important --no-depends --conflicts
testsuccessequal 'foo
- Conflicts: <foobar>
- Conflicts: <foobar:i386>' aptcache depends foo --important --no-depends --conflicts --implicit
+ Conflicts: <foobar>' aptcache depends foo --important --no-depends --conflicts --implicit
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
@@ -118,17 +113,15 @@ bar
testsuccessequal 'foo
Depends: bar
Conflicts: <foobar>
- Conflicts: <foobar:i386>
|Recommends: <cool>
Recommends: <cooler>
bar
Depends: bar
Breaks: foo
- Breaks: <foo:i386>
Replaces: foo
+ Breaks: <foo:i386>
Replaces: <foo:i386>
<foobar>
-<foobar:i386>
<cool>
<cooler>
<foo:i386>' aptcache depends foo --recurse --implicit
@@ -151,8 +144,8 @@ testsuccessequal 'bar
testsuccessequal 'bar
Depends: bar
Breaks: foo
- Breaks: <foo:i386>
Replaces: foo
+ Breaks: <foo:i386>
Replaces: <foo:i386>' aptcache depends bar --implicit
testsuccessequal 'specific
Depends: <bar:i386>
diff --git a/test/integration/test-bug-590041-prefer-non-virtual-packages b/test/integration/test-bug-590041-prefer-non-virtual-packages
index 3bd7d436e..4e2a5142c 100755
--- a/test/integration/test-bug-590041-prefer-non-virtual-packages
+++ b/test/integration/test-bug-590041-prefer-non-virtual-packages
@@ -45,7 +45,7 @@ EOF
setupaptarchive
-testshowvirtual libc6:i386
+testnopackage libc6:i386
testsuccessequal "$pkglibc6" aptcache show libc6:armel
testsuccessequal "$pkglibc6" aptcache show libc6
testsuccessequal "$pkglibdb1" aptcache show libdb1:i386
diff --git a/test/integration/test-multiarch-allowed b/test/integration/test-multiarch-allowed
index a643cd2dc..2c791ca19 100755
--- a/test/integration/test-multiarch-allowed
+++ b/test/integration/test-multiarch-allowed
@@ -138,10 +138,8 @@ solveableinsinglearch2() {
The following packages have unmet dependencies:
hatesfoo : Conflicts: foo but 1 is to be installed
E: Unable to correct problems, you have held broken packages." aptget install foo hatesfoo -s
- testfailureequal "$BADPREFIX
-The following packages have unmet dependencies:
- hatesfooany : Conflicts: foo:any
-E: Unable to correct problems, you have held broken packages." aptget install foo hatesfooany -s
+ # the message differs slightly between single and multiarch
+ testfailuremsg 'E: Unable to correct problems, you have held broken packages.' aptget install foo hatesfooany -s
testfailureequal "$BADPREFIX
The following packages have unmet dependencies:
hatesfoonative : Conflicts: foo but 1 is to be installed
@@ -155,6 +153,7 @@ E: Unable to correct problems, you have held broken packages." aptget install fo
testfailureequal "$BADPREFIX
The following packages have unmet dependencies:
hatesfooany : Conflicts: foo:any
+ Conflicts: foo:any:i386
E: Unable to correct problems, you have held broken packages." aptget install foo:i386 hatesfooany -s
testsuccessequal 'Reading package lists...
Building dependency tree...