Browse Source

implement BuildProfileSpec support as dpkg has in 1.17.2

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
tags/debian/0.9.16
Johannes Schauer David Kalnischkies 7 years ago
parent
commit
565ded7b65
4 changed files with 162 additions and 36 deletions
  1. +87
    -4
      apt-pkg/deb/deblistparser.cc
  2. +13
    -4
      apt-pkg/deb/deblistparser.h
  3. +1
    -1
      apt-pkg/deb/debsrcrecords.cc
  4. +61
    -27
      test/libapt/parsedepends_test.cc

+ 87
- 4
apt-pkg/deb/deblistparser.cc View 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(':');


+ 13
- 4
apt-pkg/deb/deblistparser.h View 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 = "");


+ 1
- 1
apt-pkg/deb/debsrcrecords.cc View 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]);


+ 61
- 27
test/libapt/parsedepends_test.cc View 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;


Loading…
Cancel
Save