From 565ded7b65240b25ad8551789ac388c8ce72b1f4 Mon Sep 17 00:00:00 2001 From: Johannes Schauer Date: Tue, 25 Feb 2014 00:12:20 +0100 Subject: implement BuildProfileSpec support as dpkg has in 1.17.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build-dependencies are now able to include a specification limiting usage similar to already supported [arch …]. More details: https://wiki.debian.org/BuildProfileSpec Closes: 661537 --- apt-pkg/deb/deblistparser.cc | 91 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index acdcc4554..a4795f15d 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -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 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(':'); -- cgit v1.2.3 From ce7f128c020e1347f91c6074238fc5da58c5df71 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 25 Feb 2014 14:26:18 +0100 Subject: support DEB_BUILD_PROFILES and -P for build profiles Inspired by the rest of the patch in 661537, but abstract the parsing of various ways of setting the build profiles more so it can potentially be reused and all apt parts have the same behaviour. Especially config options, cmdline options and environment will not be combined as proposed as this isn't APTs usual behaviour and dpkg doesn't do it either, so one overrides the other as it normally does. --- apt-pkg/deb/deblistparser.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index a4795f15d..89f3514c9 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -625,7 +625,7 @@ const char *debListParser::ParseDepends(const char *Start,const char *Stop, if (unlikely(I == Stop)) return 0; - std::vector const profiles = _config->FindVector("APT::Build-Profiles"); + std::vector const profiles = APT::Configuration::getBuildProfiles(); const char *End = I; bool Found = false; -- cgit v1.2.3 From 67c3067f1a615fd6ff0b332c2a526d052442913d Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 25 Feb 2014 22:22:41 +0100 Subject: fix -Wmissing-field-initializers warnings Reported-By: gcc Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 89f3514c9..3374865ac 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -34,7 +34,7 @@ static debListParser::WordList PrioList[] = { {"standard",pkgCache::State::Standard}, {"optional",pkgCache::State::Optional}, {"extra",pkgCache::State::Extra}, - {}}; + {NULL, 0}}; // ListParser::debListParser - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -354,7 +354,7 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, {"hold",pkgCache::State::Hold}, {"deinstall",pkgCache::State::DeInstall}, {"purge",pkgCache::State::Purge}, - {}}; + {NULL, 0}}; if (GrabWord(string(Start,I-Start),WantList,Pkg->SelectedState) == false) return _error->Error("Malformed 1st word in the Status line"); @@ -370,7 +370,7 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, {"reinstreq",pkgCache::State::ReInstReq}, {"hold",pkgCache::State::HoldInst}, {"hold-reinstreq",pkgCache::State::HoldReInstReq}, - {}}; + {NULL, 0}}; if (GrabWord(string(Start,I-Start),FlagList,Pkg->InstState) == false) return _error->Error("Malformed 2nd word in the Status line"); @@ -392,7 +392,7 @@ bool debListParser::ParseStatus(pkgCache::PkgIterator &Pkg, {"triggers-pending",pkgCache::State::TriggersPending}, {"post-inst-failed",pkgCache::State::HalfConfigured}, {"removal-failed",pkgCache::State::HalfInstalled}, - {}}; + {NULL, 0}}; if (GrabWord(string(Start,I-Start),StatusList,Pkg->CurrentState) == false) return _error->Error("Malformed 3rd word in the Status line"); -- cgit v1.2.3 From 453b82a388013e522b3a1b9fcd6ed0810dab1f4f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 5 Mar 2014 22:11:25 +0100 Subject: cleanup headers and especially #includes everywhere Beside being a bit cleaner it hopefully also resolves oddball problems I have with high levels of parallel jobs. Git-Dch: Ignore Reported-By: iwyu (include-what-you-use) --- apt-pkg/deb/deblistparser.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 3374865ac..7777d654e 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -21,8 +21,17 @@ #include #include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include #include /*}}}*/ -- cgit v1.2.3 From e33dbfe5cea09b2124be8db5a6ae0eb82ad7e9c5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 12 Mar 2014 16:53:44 +0100 Subject: factor out parsing of MultiArch flag Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 47 ++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 7777d654e..18b8b931d 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -104,44 +104,49 @@ string debListParser::Version() return Section.FindS("Version"); } /*}}}*/ -// ListParser::NewVersion - Fill in the version structure /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool debListParser::NewVersion(pkgCache::VerIterator &Ver) +unsigned char debListParser::ParseMultiArch(bool const showErrors) /*{{{*/ { - // Parse the section - Ver->Section = UniqFindTagWrite("Section"); - - // Parse multi-arch + unsigned char MA; string const MultiArch = Section.FindS("Multi-Arch"); if (MultiArch.empty() == true) - Ver->MultiArch = pkgCache::Version::None; + MA = pkgCache::Version::None; else if (MultiArch == "same") { - // Parse multi-arch if (ArchitectureAll() == true) { - /* Arch all packages can't be Multi-Arch: same */ - _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same", - Section.FindS("Package").c_str()); - Ver->MultiArch = pkgCache::Version::None; + if (showErrors == true) + _error->Warning("Architecture: all package '%s' can't be Multi-Arch: same", + Section.FindS("Package").c_str()); + MA = pkgCache::Version::None; } else - Ver->MultiArch = pkgCache::Version::Same; + MA = pkgCache::Version::Same; } else if (MultiArch == "foreign") - Ver->MultiArch = pkgCache::Version::Foreign; + MA = pkgCache::Version::Foreign; else if (MultiArch == "allowed") - Ver->MultiArch = pkgCache::Version::Allowed; + MA = pkgCache::Version::Allowed; else { - _error->Warning("Unknown Multi-Arch type '%s' for package '%s'", - MultiArch.c_str(), Section.FindS("Package").c_str()); - Ver->MultiArch = pkgCache::Version::None; + if (showErrors == true) + _error->Warning("Unknown Multi-Arch type '%s' for package '%s'", + MultiArch.c_str(), Section.FindS("Package").c_str()); + MA = pkgCache::Version::None; } if (ArchitectureAll() == true) - Ver->MultiArch |= pkgCache::Version::All; + MA |= pkgCache::Version::All; + return MA; +} + /*}}}*/ +// ListParser::NewVersion - Fill in the version structure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::NewVersion(pkgCache::VerIterator &Ver) +{ + // Parse the section + Ver->Section = UniqFindTagWrite("Section"); + Ver->MultiArch = ParseMultiArch(true); // Archive Size Ver->Size = Section.FindULL("Size"); // Unpacked Size (in K) -- cgit v1.2.3 From 68134bda8868a8614edf137aad7e9be61cd2a6ee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 12 Mar 2014 17:55:08 +0100 Subject: abstract version hash comparison a bit In #737085 we see that apt can be confused if informations about versions only differ slightly. This commit adds a way of at least adding a few more data points with the next abi break to help a bit with it. Git-Dch: Ignore --- apt-pkg/deb/deblistparser.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'apt-pkg/deb/deblistparser.cc') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 18b8b931d..a1bcfb710 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -938,3 +938,24 @@ unsigned char debListParser::GetPrio(string Str) return Out; } /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +bool debListParser::SameVersion(unsigned short const Hash, /*{{{*/ + pkgCache::VerIterator const &Ver) +{ + if (pkgCacheGenerator::ListParser::SameVersion(Hash, Ver) == false) + return false; + // status file has no (Download)Size, but all others are fair game + // status file is parsed last, so the first version we encounter is + // probably also the version we have downloaded + unsigned long long const Size = Section.FindULL("Size"); + if (Size != 0 && Size != Ver->Size) + return false; + // available everywhere, but easier to check here than to include in VersionHash + unsigned char MultiArch = ParseMultiArch(false); + if (MultiArch != Ver->MultiArch) + return false; + // for all practical proposes (we can check): same version + return true; +} + /*}}}*/ +#endif -- cgit v1.2.3