]> git.saurik.com Git - apt.git/commitdiff
support <libc>-<kernel>-<cpu> in architecture specs
authorDavid Kalnischkies <david@kalnischkies.de>
Sun, 31 Jan 2016 21:32:45 +0000 (22:32 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Sun, 31 Jan 2016 22:24:59 +0000 (23:24 +0100)
APT has a different understanding than dpkg (#748936) what matches and
what doesn't match an architecture specification as it isn't converting
back (and forward) to Debian triplets. That has to eventually be solved
some way or the other, but until that happens we change the matching in
apt so that porters can continue their work on non-gnu libc-ports even
if policy doesn't specify that yet (and dpkg just supporting it "by
accident" via triplets).

The initial patch was reformatted, fixed in terms of patterns containing
"any-any", dealing with expanding an arch without libc to gnu while a
pattern expands libc to any, the parsedepends test was fixed (the new
if's were inserted one step too early) and another test just for the
specifications added.

Closes: #812212
Thanks: Bálint Réczey for initial patch

apt-pkg/cachefilter.cc
apt-pkg/cachefilter.h
test/libapt/cachefilter_test.cc [new file with mode: 0644]
test/libapt/parsedepends_test.cc

index 4362f43e3ce9305a77a221c3958fe8ce31c26ae2..b1adf5de3d071670d532dbb65e9b98ca658ed4f2 100644 (file)
@@ -68,28 +68,47 @@ bool PackageNameMatchesFnmatch::operator() (pkgCache::GrpIterator const &Grp) {
    return fnmatch(Pattern.c_str(), Grp.Name(), FNM_CASEFOLD) == 0;
 }
                                                                        /*}}}*/
-// Architecture matches <kernel>-<cpu> specification                   /*{{{*/
+// Architecture matches <libc>-<kernel>-<cpu> specification            /*{{{*/
 //----------------------------------------------------------------------
-/* The complete architecture, consisting of <kernel>-<cpu>. */
-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 == "any")                 return "*-*";
-       else                                    return "linux-" + arch;
-}
-PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const isPattern) :
-                                       literal(pattern), complete(CompleteArch(pattern)), isPattern(isPattern) {
+/* The complete architecture, consisting of <libc>-<kernel>-<cpu>. */
+static std::string CompleteArch(std::string const &arch, bool const isPattern) {
+   auto const found = arch.find('-');
+   if (found != std::string::npos)
+   {
+      // ensure that only -any- is replaced and not something like company-
+      std::string complete = std::string("-").append(arch).append("-");
+      size_t pos = 0;
+      char const * const search = "-any-";
+      auto const search_len = strlen(search) - 2;
+      while((pos = complete.find(search, pos)) != std::string::npos) {
+        complete.replace(pos + 1, search_len, "*");
+        pos += 2;
+      }
+      complete = complete.substr(1, complete.size()-2);
+      if (arch.find('-', found+1) != std::string::npos)
+        // <libc>-<kernel>-<cpu> format
+        return complete;
+      // <kernel>-<cpu> format
+      else if (isPattern)
+        return "*-" + complete;
+      else
+        return "gnu-" + complete;
+   }
+   else if (arch == "any")
+      return "*-*-*";
+   else if (isPattern)
+      return "*-linux-" + arch;
+   else
+      return "gnu-linux-" + arch;
+}
+PackageArchitectureMatchesSpecification::PackageArchitectureMatchesSpecification(std::string const &pattern, bool const pisPattern) :
+                                       literal(pattern), complete(CompleteArch(pattern, pisPattern)), isPattern(pisPattern) {
 }
 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);
+       std::string const pkgarch = CompleteArch(arch, !isPattern);
        if (isPattern == true)
                return fnmatch(complete.c_str(), pkgarch.c_str(), 0) == 0;
        return fnmatch(pkgarch.c_str(), complete.c_str(), 0) == 0;
index 9970b5b22a1251619e1cf81f1c6ef0fd2bcfdcff..30a3368e59df64bdca83f4bec7cff1e81c502f4e 100644 (file)
@@ -115,11 +115,11 @@ class PackageArchitectureMatchesSpecification : public PackageMatcher {   /*{{{*/
 /** \class PackageArchitectureMatchesSpecification
    \brief matching against architecture specification strings
 
-   The strings are of the format <kernel>-<cpu> where either component,
+   The strings are of the format <libc>-<kernel>-<cpu> 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 */
+   Examples: i386, mipsel, musl-linux-amd64, linux-any, any-amd64, any */
        std::string literal;
        std::string complete;
        bool isPattern;
diff --git a/test/libapt/cachefilter_test.cc b/test/libapt/cachefilter_test.cc
new file mode 100644 (file)
index 0000000..28924b7
--- /dev/null
@@ -0,0 +1,66 @@
+#include <config.h>
+
+#include <apt-pkg/cachefilter.h>
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+TEST(CacheFilterTest, ArchitectureSpecification)
+{
+   {
+      SCOPED_TRACE("Pattern is any-armhf");
+      APT::CacheFilter::PackageArchitectureMatchesSpecification ams("any-armhf");
+      EXPECT_TRUE(ams("armhf"));
+      EXPECT_FALSE(ams("armel"));
+      EXPECT_TRUE(ams("linux-armhf"));
+      EXPECT_FALSE(ams("linux-armel"));
+      EXPECT_TRUE(ams("kfreebsd-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armhf"));
+      EXPECT_FALSE(ams("gnu-linux-armel"));
+      EXPECT_TRUE(ams("gnu-kfreebsd-armhf"));
+      EXPECT_TRUE(ams("musl-linux-armhf"));
+   }
+   {
+      SCOPED_TRACE("Pattern is linux-any");
+      APT::CacheFilter::PackageArchitectureMatchesSpecification ams("linux-any");
+      EXPECT_TRUE(ams("armhf"));
+      EXPECT_TRUE(ams("armel"));
+      EXPECT_TRUE(ams("linux-armhf"));
+      EXPECT_TRUE(ams("linux-armel"));
+      EXPECT_FALSE(ams("kfreebsd-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armel"));
+      EXPECT_FALSE(ams("gnu-kfreebsd-armhf"));
+      EXPECT_TRUE(ams("musl-linux-armhf"));
+   }
+   {
+      SCOPED_TRACE("Pattern is gnu-any-any");
+      APT::CacheFilter::PackageArchitectureMatchesSpecification ams("gnu-any-any"); //really?
+      EXPECT_TRUE(ams("armhf"));
+      EXPECT_TRUE(ams("armel"));
+      EXPECT_TRUE(ams("linux-armhf"));
+      EXPECT_TRUE(ams("linux-armel"));
+      EXPECT_TRUE(ams("kfreebsd-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armel"));
+      EXPECT_TRUE(ams("gnu-kfreebsd-armhf"));
+      EXPECT_FALSE(ams("musl-linux-armhf"));
+   }
+   {
+      SCOPED_TRACE("Architecture is armhf");
+      APT::CacheFilter::PackageArchitectureMatchesSpecification ams("armhf", false);
+      EXPECT_TRUE(ams("armhf"));
+      EXPECT_FALSE(ams("armel"));
+      EXPECT_TRUE(ams("linux-any"));
+      EXPECT_FALSE(ams("kfreebsd-any"));
+      EXPECT_TRUE(ams("any-armhf"));
+      EXPECT_FALSE(ams("any-armel"));
+      EXPECT_TRUE(ams("linux-armhf"));
+      EXPECT_FALSE(ams("kfreebsd-armhf"));
+      EXPECT_TRUE(ams("gnu-linux-armhf"));
+      EXPECT_FALSE(ams("gnu-linux-armel"));
+      EXPECT_FALSE(ams("gnu-kfreebsd-armhf"));
+      EXPECT_FALSE(ams("musl-linux-armhf"));
+   }
+}
index f644599bd013ddbef9519b94b1856ee39c1b13e0..f537542b4b810b2c984cfbaf99c304f8ef57cdd1 100644 (file)
@@ -31,6 +31,8 @@ static void parseDependency(bool const StripMultiArch,  bool const ParseArchFlag
       "not-for-darwin [ !darwin-any ], "
       "cpu-for-me [ any-amd64 ], "
       "os-for-me [ linux-any ], "
+      "libc-for-me [ gnu-linux-any ], "
+      "libc-not-for-me [ musl-linux-any ], "
       "cpu-not-for-me [ any-armel ], "
       "os-not-for-me [ kfreebsd-any ], "
       "not-in-stage1 <!stage1>, "
@@ -156,6 +158,26 @@ static void parseDependency(bool const StripMultiArch,  bool const ParseArchFlag
       Start++;
    }
 
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("libc-for-me", Package);
+      EXPECT_EQ("", Version);
+      EXPECT_EQ(Null | pkgCache::Dep::NoOp, Op);
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
+   if (ParseArchFlags == true) {
+      Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+      EXPECT_EQ("", Package); // libc-not-for-me
+   } else {
+      EXPECT_EQ(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+      Start = strstr(Start, ",");
+      Start++;
+   }
+
    if (ParseArchFlags == true) {
       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
       EXPECT_EQ("", Package); // cpu-not-for-me