X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/076b71228a1439b7c871246c8cc29066ac2aaa70..e844b947ab5c988fb6d6f8e5ebfa4e0eda856541:/apt-pkg/policy.cc diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 3d6ec1cdc..bd213e0ce 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -210,50 +210,71 @@ void pkgPolicy::CreatePin(pkgVersionMatch::MatchType Type,string Name, { if (Name.empty() == true) { - Pin *P = &*Defaults.insert(Defaults.end(),PkgPin()); + Pin *P = &*Defaults.insert(Defaults.end(),Pin()); P->Type = Type; P->Priority = Priority; P->Data = Data; return; } - + + size_t found = Name.rfind(':'); + string Arch; + if (found != string::npos) { + Arch = Name.substr(found+1); + Name.erase(found); + } + // Allow pinning by wildcards // TODO: Maybe we should always prefer specific pins over non- // specific ones. - if (Name.find("*") != string::npos || Name.find("[") != string::npos - || Name.find("?") != string::npos || Name[0] == '/') { - pkgVersionMatch match(Data, Type); - for (pkgCache::PkgIterator P = Cache->PkgBegin(); - P != Cache->PkgEnd(); P++) { - if (match.ExpressionMatches(Name, P.Name())) { - CreatePin(Type, P.Name(), Data, Priority); - } - } + if (Name[0] == '/' || Name.find_first_of("*[?") != string::npos) + { + pkgVersionMatch match(Data, Type); + for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() != true; ++G) + if (match.ExpressionMatches(Name, G.Name())) + { + if (Arch.empty() == false) + CreatePin(Type, string(G.Name()).append(":").append(Arch), Data, Priority); + else + CreatePin(Type, G.Name(), Data, Priority); + } return; } - // Get a spot to put the pin - pkgCache::GrpIterator Grp = Cache->FindGrp(Name); - for (pkgCache::PkgIterator Pkg = Grp.FindPkg("any"); - Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) + // find the package (group) this pin applies to + pkgCache::GrpIterator Grp; + pkgCache::PkgIterator Pkg; + if (Arch.empty() == false) + Pkg = Cache->FindPkg(Name, Arch); + else { + Grp = Cache->FindGrp(Name); + if (Grp.end() == false) + Pkg = Grp.PackageList(); + } + + if (Pkg.end() == true) { - Pin *P = 0; - if (Pkg.end() == false) - P = Pins + Pkg->ID; - else - { - // Check the unmatched table - for (vector::iterator I = Unmatched.begin(); - I != Unmatched.end() && P == 0; I++) - if (I->Pkg == Name) - P = &*I; + PkgPin *P = &*Unmatched.insert(Unmatched.end(),PkgPin(Name)); + if (Arch.empty() == false) + P->Pkg.append(":").append(Arch); + P->Type = Type; + P->Priority = Priority; + P->Data = Data; + return; + } - if (P == 0) - P = &*Unmatched.insert(Unmatched.end(),PkgPin()); - } + for (; Pkg.end() != true; Pkg = Grp.NextPkg(Pkg)) + { + Pin *P = Pins + Pkg->ID; + // the first specific stanza for a package is the ruler, + // all others need to be ignored + if (P->Type != pkgVersionMatch::None) + P = &*Unmatched.insert(Unmatched.end(),PkgPin(Pkg.FullName())); P->Type = Type; P->Priority = Priority; P->Data = Data; + if (Grp.end() == true) + break; } } /*}}}*/