From 424ff669be2d1871592247907d977ed9fba3229f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 14 Jun 2012 18:48:23 +0200 Subject: [PATCH] * apt-pkg/deb/deblistparser.cc: - use PackageArchitectureMatchesSpecification filter * apt-pkg/cachefilter.cc: - add PackageArchitectureMatchesSpecification (Closes: #672603) --- apt-pkg/cachefilter.cc | 51 ++++++++++++++++++++++++++++++++++++ apt-pkg/cachefilter.h | 30 +++++++++++++++++++++ apt-pkg/deb/deblistparser.cc | 32 ++++------------------ debian/changelog | 5 +++- 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/apt-pkg/cachefilter.cc b/apt-pkg/cachefilter.cc index fb444208c..35f95fe22 100644 --- a/apt-pkg/cachefilter.cc +++ b/apt-pkg/cachefilter.cc @@ -9,10 +9,12 @@ #include #include #include +#include #include #include +#include #include /*}}}*/ @@ -52,5 +54,54 @@ PackageNameMatchesRegEx::~PackageNameMatchesRegEx() { /*{{{*/ delete pattern; } /*}}}*/ + +// CompleteArch to - tuple /*{{{*/ +//---------------------------------------------------------------------- +/* The complete architecture, consisting of -. */ +static std::string CompleteArch(std::string const &arch) { + if (arch.find('-') != std::string::npos) { + // ensure that only -any- is replaced and not something like company- + std::string complete = std::string("-").append(arch).append("-"); + complete = SubstVar(complete, "-any-", "-*-"); + complete = complete.substr(1, complete.size()-2); + return complete; + } + else if (arch == "armel") return "linux-arm"; + else if (arch == "armhf") return "linux-arm"; + else if (arch == "lpia") return "linux-i386"; + else if (arch == "powerpcspe") return "linux-powerpc"; + else if (arch == "uclibc-linux-armel") return "linux-arm"; + else if (arch == "uclinux-armel") return "uclinux-arm"; + else if (arch == "any") return "*-*"; + else return "linux-" + arch; +} + /*}}}*/ +PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern) :/*{{{*/ + literal(pattern), isPattern(isPattern), d(NULL) { + complete = CompleteArch(pattern); +} + /*}}}*/ +bool PackageArchitectureMatchesSpecification::operator() (char const * const &arch) {/*{{{*/ + if (strcmp(literal.c_str(), arch) == 0 || + strcmp(complete.c_str(), arch) == 0) + return true; + std::string const pkgarch = CompleteArch(arch); + if (isPattern == true) + return fnmatch(complete.c_str(), pkgarch.c_str(), 0) == 0; + return fnmatch(pkgarch.c_str(), complete.c_str(), 0) == 0; +} + /*}}}*/ +bool PackageArchitectureMatchesSpecification::operator() (pkgCache::PkgIterator const &Pkg) {/*{{{*/ + return (*this)(Pkg.Arch()); +} + /*}}}*/ +bool PackageArchitectureMatchesSpecification::operator() (pkgCache::VerIterator const &Ver) {/*{{{*/ + return (*this)(Ver.ParentPkg()); +} + /*}}}*/ +PackageArchitectureMatchesSpecification::~PackageArchitectureMatchesSpecification() { /*{{{*/ +} + /*}}}*/ + } } diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h index 5d426008b..25cd43f47 100644 --- a/apt-pkg/cachefilter.h +++ b/apt-pkg/cachefilter.h @@ -26,6 +26,36 @@ public: ~PackageNameMatchesRegEx(); }; /*}}}*/ +// PackageArchitectureMatchesSpecification /*{{{*/ +/** \class PackageArchitectureMatchesSpecification + \brief matching against architecture specification strings + + The strings are of the format - where either component, + or the whole string, can be the wildcard "any" as defined in + debian-policy §11.1 "Architecture specification strings". + + Examples: i386, mipsel, linux-any, any-amd64, any */ +class PackageArchitectureMatchesSpecification { + std::string literal; + std::string complete; + bool isPattern; + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; +public: + /** \brief matching against architecture specification strings + * + * @param pattern is the architecture specification string + * @param isPattern defines if the given \b pattern is a + * architecture specification pattern to match others against + * or if it is the fixed string and matched against patterns + */ + PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern = true); + bool operator() (char const * const &arch); + bool operator() (pkgCache::PkgIterator const &Pkg); + bool operator() (pkgCache::VerIterator const &Ver); + ~PackageArchitectureMatchesSpecification(); +}; + /*}}}*/ } } #endif diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index d29b28d48..efb76ef54 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,6 @@ #include #include -#include #include /*}}}*/ @@ -464,22 +464,6 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op) } return I; } - -/* - * CompleteArch: - * - * The complete architecture, consisting of -. - */ -static string CompleteArch(std::string const &arch) { - if (arch == "armel") return "linux-arm"; - if (arch == "armhf") return "linux-arm"; - if (arch == "lpia") return "linux-i386"; - if (arch == "powerpcspe") return "linux-powerpc"; - if (arch == "uclibc-linux-armel") return "linux-arm"; - if (arch == "uclinux-armel") return "uclinux-arm"; - - return (arch.find("-") != string::npos) ? arch : "linux-" + arch; -} /*}}}*/ // ListParser::ParseDepends - Parse a dependency element /*{{{*/ // --------------------------------------------------------------------- @@ -556,7 +540,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (ParseArchFlags == true) { - string completeArch = CompleteArch(arch); + APT::CacheFilter::PackageArchitectureMatchesSpecification matchesArch(arch, false); // Parse an architecture if (I != Stop && *I == '[') @@ -583,16 +567,10 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, ++I; } - if (stringcmp(arch,I,End) == 0) { - Found = true; - } else { - std::string wildcard = SubstVar(string(I, End), "any", "*"); - if (fnmatch(wildcard.c_str(), completeArch.c_str(), 0) == 0) - Found = true; - } - - if (Found == true) + std::string arch(I, End); + if (arch.empty() == false && matchesArch(arch.c_str()) == true) { + Found = true; if (I[-1] != '!') NegArch = false; // we found a match, so fast-forward to the end of the wildcards diff --git a/debian/changelog b/debian/changelog index 2fb1b50d4..0f6dceb86 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,12 @@ apt (0.9.6.1) UNRELEASED; urgency=low [ David Kalnischkies ] - * deb/deblistparser.cc: + * apt-pkg/deb/deblistparser.cc: - ensure that mixed positive/negative architecture wildcards are handled in the same way as dpkg handles them + - use PackageArchitectureMatchesSpecification filter + * apt-pkg/cachefilter.cc: + - add PackageArchitectureMatchesSpecification (Closes: #672603) -- David Kalnischkies Thu, 14 Jun 2012 15:45:13 +0200 -- 2.45.2