diff options
-rw-r--r-- | apt-pkg/deb/deblistparser.cc | 30 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.cc | 112 | ||||
-rw-r--r-- | apt-pkg/pkgcachegen.h | 5 | ||||
-rwxr-xr-x | test/integration/test-apt-cache | 15 | ||||
-rwxr-xr-x | test/integration/test-bug-590041-prefer-non-virtual-packages | 2 | ||||
-rwxr-xr-x | test/integration/test-multiarch-allowed | 7 |
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... |