+ 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[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;
+ }
+
+ // 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)
+ {
+ 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;
+ }
+
+ 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;
+ }
+}
+ /*}}}*/
+// Policy::GetMatch - Get the matching version for a package pin /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+pkgCache::VerIterator pkgPolicy::GetMatch(pkgCache::PkgIterator const &Pkg)
+{
+ const Pin &PPkg = Pins[Pkg->ID];
+ if (PPkg.Type == pkgVersionMatch::None)
+ return pkgCache::VerIterator(*Pkg.Cache());
+
+ pkgVersionMatch Match(PPkg.Data,PPkg.Type);
+ return Match.Find(Pkg);
+}
+ /*}}}*/
+// Policy::GetPriority - Get the priority of the package pin /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg)
+{
+ if (Pins[Pkg->ID].Type != pkgVersionMatch::None)
+ {
+ // In this case 0 means default priority
+ if (Pins[Pkg->ID].Priority == 0)
+ return 989;
+ return Pins[Pkg->ID].Priority;