]> git.saurik.com Git - apt.git/commitdiff
implement BuildProfileSpec support as dpkg has in 1.17.2
authorJohannes Schauer <j.schauer@email.de>
Mon, 24 Feb 2014 23:12:20 +0000 (00:12 +0100)
committerDavid Kalnischkies <david@kalnischkies.de>
Thu, 13 Mar 2014 12:57:34 +0000 (13:57 +0100)
Build-dependencies are now able to include a <profile.foo …>
specification limiting usage similar to already supported [arch …].
More details: https://wiki.debian.org/BuildProfileSpec

Closes: 661537
apt-pkg/deb/deblistparser.cc
apt-pkg/deb/deblistparser.h
apt-pkg/deb/debsrcrecords.cc
test/libapt/parsedepends_test.cc

index acdcc45541d9190cccbcf12d488eb7a2a2196ea2..a4795f15d95923ec722185da230a7c35efc38316 100644 (file)
@@ -474,18 +474,31 @@ const char *debListParser::ConvertRelation(const char *I,unsigned int &Op)
 // ---------------------------------------------------------------------
 /* This parses the dependency elements out of a standard string in place,
    bit by bit. */
+const char *debListParser::ParseDepends(const char *Start,const char *Stop,
+               std::string &Package,std::string &Ver,unsigned int &Op)
+   { return ParseDepends(Start, Stop, Package, Ver, Op, false, true, false); }
+const char *debListParser::ParseDepends(const char *Start,const char *Stop,
+               std::string &Package,std::string &Ver,unsigned int &Op,
+               bool const &ParseArchFlags)
+   { return ParseDepends(Start, Stop, Package, Ver, Op, ParseArchFlags, true, false); }
+const char *debListParser::ParseDepends(const char *Start,const char *Stop,
+               std::string &Package,std::string &Ver,unsigned int &Op,
+               bool const &ParseArchFlags, bool const &StripMultiArch)
+   { return ParseDepends(Start, Stop, Package, Ver, Op, ParseArchFlags, StripMultiArch, false); }
 const char *debListParser::ParseDepends(const char *Start,const char *Stop,
                                        string &Package,string &Ver,
                                        unsigned int &Op, bool const &ParseArchFlags,
-                                       bool const &StripMultiArch)
+                                       bool const &StripMultiArch,
+                                       bool const &ParseRestrictionsList)
 {
    // Strip off leading space
-   for (;Start != Stop && isspace(*Start) != 0; Start++);
+   for (;Start != Stop && isspace(*Start) != 0; ++Start);
    
    // Parse off the package name
    const char *I = Start;
    for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' &&
-       *I != ',' && *I != '|' && *I != '[' && *I != ']'; I++);
+       *I != ',' && *I != '|' && *I != '[' && *I != ']' &&
+       *I != '<' && *I != '>'; ++I);
    
    // Malformed, no '('
    if (I != Stop && *I == ')')
@@ -602,6 +615,76 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop,
       for (;I != Stop && isspace(*I) != 0; I++);
    }
 
+   if (ParseRestrictionsList == true)
+   {
+      // Parse a restrictions list
+      if (I != Stop && *I == '<')
+      {
+        ++I;
+        // malformed
+        if (unlikely(I == Stop))
+           return 0;
+
+        std::vector<string> const profiles = _config->FindVector("APT::Build-Profiles");
+
+        const char *End = I;
+        bool Found = false;
+        bool NegRestriction = false;
+        while (I != Stop)
+        {
+           // look for whitespace or ending '>'
+           for (;End != Stop && !isspace(*End) && *End != '>'; ++End);
+
+           if (unlikely(End == Stop))
+              return 0;
+
+           if (*I == '!')
+           {
+              NegRestriction = true;
+              ++I;
+           }
+
+           std::string restriction(I, End);
+
+           std::string prefix = "profile.";
+           // only support for "profile" prefix, ignore others
+           if (restriction.size() > prefix.size() &&
+                 restriction.substr(0, prefix.size()) == prefix)
+           {
+              // get the name of the profile
+              restriction = restriction.substr(prefix.size());
+
+              if (restriction.empty() == false && profiles.empty() == false &&
+                    std::find(profiles.begin(), profiles.end(), restriction) != profiles.end())
+              {
+                 Found = true;
+                 if (I[-1] != '!')
+                    NegRestriction = false;
+                 // we found a match, so fast-forward to the end of the wildcards
+                 for (; End != Stop && *End != '>'; ++End);
+              }
+           }
+
+           if (*End++ == '>') {
+              I = End;
+              break;
+           }
+
+           I = End;
+           for (;I != Stop && isspace(*I) != 0; I++);
+        }
+
+        if (NegRestriction == true)
+           Found = !Found;
+
+        if (Found == false)
+           Package = ""; /* not for this restriction */
+      }
+
+      // Skip whitespace
+      for (;I != Stop && isspace(*I) != 0; I++);
+   }
+
    if (I != Stop && *I == '|')
       Op |= pkgCache::Dep::Or;
    
@@ -635,7 +718,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver,
       string Version;
       unsigned int Op;
 
-      Start = ParseDepends(Start, Stop, Package, Version, Op, false, false);
+      Start = ParseDepends(Start, Stop, Package, Version, Op, false, false, false);
       if (Start == 0)
         return _error->Error("Problem parsing dependency %s",Tag);
       size_t const found = Package.rfind(':');
index 386d291a2e1378a260a977e03db9137f04fe4748..0531b20f364276738e8470df9652ef1c3bb1db0a 100644 (file)
@@ -72,11 +72,20 @@ class debListParser : public pkgCacheGenerator::ListParser
    
    bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File,
                        std::string section);
-   
+
+   static const char *ParseDepends(const char *Start,const char *Stop,
+        std::string &Package,std::string &Ver,unsigned int &Op);
    static const char *ParseDepends(const char *Start,const char *Stop,
-                           std::string &Package,std::string &Ver,unsigned int &Op,
-                           bool const &ParseArchFlags = false,
-                           bool const &StripMultiArch = true);
+        std::string &Package,std::string &Ver,unsigned int &Op,
+        bool const &ParseArchFlags);
+   static const char *ParseDepends(const char *Start,const char *Stop,
+        std::string &Package,std::string &Ver,unsigned int &Op,
+        bool const &ParseArchFlags, bool const &StripMultiArch);
+   static const char *ParseDepends(const char *Start,const char *Stop,
+        std::string &Package,std::string &Ver,unsigned int &Op,
+        bool const &ParseArchFlags, bool const &StripMultiArch,
+        bool const &ParseRestrictionsList);
+
    static const char *ConvertRelation(const char *I,unsigned int &Op);
 
    debListParser(FileFd *File, std::string const &Arch = "");
index ce55ccd1f03e298b8f9e1fba8a3130bc5e22f61b..90182b4a4bf64b283c5e317379db997359b0786e 100644 (file)
@@ -90,7 +90,7 @@ bool debSrcRecordParser::BuildDepends(std::vector<pkgSrcRecords::Parser::BuildDe
       while (1)
       {
          Start = debListParser::ParseDepends(Start, Stop, 
-                    rec.Package,rec.Version,rec.Op,true, StripMultiArch);
+                    rec.Package,rec.Version,rec.Op,true,StripMultiArch,true);
         
          if (Start == 0) 
             return _error->Error("Problem parsing dependency: %s", fields[I]);
index e95016240cabd24c71dfe2cc876c413e03bd615e..67dbab82363014f9a37a88594d364624e7e9b88f 100644 (file)
@@ -10,7 +10,9 @@ int main(int argc,char *argv[]) {
        unsigned int Null = 0;
        bool StripMultiArch = true;
        bool ParseArchFlags = false;
+       bool ParseRestrictionsList = false;
        _config->Set("APT::Architecture","amd64");
+       _config->Set("APT::Build-Profiles","stage1");
 
        const char* Depends =
                "debhelper:any (>= 5.0), "
@@ -27,6 +29,9 @@ int main(int argc,char *argv[]) {
                "os-for-me [ linux-any ], "
                "cpu-not-for-me [ any-armel ], "
                "os-not-for-me [ kfreebsd-any ], "
+               "not-in-stage1 <!profile.stage1>, "
+               "not-in-stage1-or-nodoc <!profile.nodoc !profile.stage1>, "
+               "only-in-stage1 <unknown.unknown profile.stage1>, "
                "overlord-dev:any (= 7.15.3~) | overlord-dev:native (>> 7.15.5), "
        ;
 
@@ -39,7 +44,7 @@ test:
        const char* Start = Depends;
        const char* End = Depends + strlen(Depends);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("debhelper", Package);
        else
@@ -47,7 +52,7 @@ test:
        equals("5.0", Version);
        equals(Null | pkgCache::Dep::GreaterEq, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("libdb-dev", Package);
        else
@@ -55,7 +60,7 @@ test:
        equals("", Version);
        equals(Null | pkgCache::Dep::NoOp, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("gettext", Package);
        else
@@ -63,7 +68,7 @@ test:
        equals("0.12", Version);
        equals(Null | pkgCache::Dep::LessEq, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("libcurl4-gnutls-dev", Package);
        else
@@ -71,104 +76,131 @@ test:
        equals("", Version);
        equals(Null | pkgCache::Dep::Or, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        equals("libcurl3-gnutls-dev", Package);
        equals("7.15.5", Version);
        equals(Null | pkgCache::Dep::Greater, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        equals("debiandoc-sgml", Package);
        equals("", Version);
        equals(Null | pkgCache::Dep::NoOp, Op);
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        equals("apt", Package);
        equals("0.7.25", Version);
        equals(Null | pkgCache::Dep::GreaterEq, Op);
 
        if (ParseArchFlags == true) {
-               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("", Package); // not-for-me
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("only-for-me", Package);
                equals("", Version);
                equals(Null | pkgCache::Dep::NoOp, Op);
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("any-for-me", Package);
                equals("", Version);
                equals(Null | pkgCache::Dep::NoOp, Op);
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("not-for-darwin", Package);
                equals("", Version);
                equals(Null | pkgCache::Dep::NoOp, Op);
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("cpu-for-me", Package);
                equals("", Version);
                equals(Null | pkgCache::Dep::NoOp, Op);
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("os-for-me", Package);
                equals("", Version);
                equals(Null | pkgCache::Dep::NoOp, Op);
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("", Package); // cpu-not-for-me
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(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);
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
                equals("", Package); // os-not-for-me
        } else {
-               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch));
+               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
                Start = strstr(Start, ",");
                Start++;
        }
 
-       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       if (ParseRestrictionsList == true) {
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+               equals("", Package); // not-in-stage1
+       } else {
+               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+               Start = strstr(Start, ",");
+               Start++;
+       }
+
+       if (ParseRestrictionsList == true) {
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+               equals("", Package); // not-in-stage1-or-in-nodoc
+       } else {
+               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+               Start = strstr(Start, ",");
+               Start++;
+       }
+
+       if (ParseRestrictionsList == true) {
+               Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
+               equals("only-in-stage1", Package);
+       } else {
+               equals(true, 0 == debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList));
+               Start = strstr(Start, ",");
+               Start++;
+       }
+
+       Start = debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("overlord-dev", Package);
        else
@@ -176,7 +208,7 @@ test:
        equals("7.15.3~", Version);
        equals(Null | pkgCache::Dep::Equals | pkgCache::Dep::Or, Op);
 
-       debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch);
+       debListParser::ParseDepends(Start, End, Package, Version, Op, ParseArchFlags, StripMultiArch, ParseRestrictionsList);
        if (StripMultiArch == true)
                equals("overlord-dev", Package);
        else
@@ -185,11 +217,13 @@ test:
        equals(Null | pkgCache::Dep::Greater, Op);
 
        if (StripMultiArch == false)
-               ParseArchFlags = true;
+               if (ParseArchFlags == false)
+                       ParseRestrictionsList = !ParseRestrictionsList;
+               ParseArchFlags = !ParseArchFlags;
        StripMultiArch = !StripMultiArch;
 
        runner++;
-       if (runner < 4)
+       if (runner < 8)
                goto test; // this is the prove: tests are really evil ;)
 
        return 0;