aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-17 17:24:56 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-17 17:24:56 +0000
commit5b0b77894361ac4ca7cc68a5d1915cac4f5a15e1 (patch)
tree3cffcba6f9f42bd7c5325cfcce29d70eed7f95d4
parentde9085446a97c8312196b59f46689dfe0d7e22c1 (diff)
downloadpaludis-5b0b77894361ac4ca7cc68a5d1915cac4f5a15e1.tar.gz
paludis-5b0b77894361ac4ca7cc68a5d1915cac4f5a15e1.tar.xz
More [.key=value] voodoo
-rw-r--r--NEWS5
-rw-r--r--doc/configuration/specs.html.part4
-rw-r--r--paludis/user_dep_spec.cc133
3 files changed, 128 insertions, 14 deletions
diff --git a/NEWS b/NEWS
index a999661..fd420f7 100644
--- a/NEWS
+++ b/NEWS
@@ -21,6 +21,11 @@ of every change, see the ChangeLog.
* Support for the new EAPI 3 is present but not installed, since the
specification has yet to be approved.
+ * The [.key=value] syntax for user dep specs now works with sets and
+ sequences. If < is used instead of =, a less than comparison is used for
+ numeric values, and for sets and sequences, a match succeeds if any item
+ of the key is equal to the specified value.
+
* Various large code cleanups and build system cleanups.
0.42.2:
diff --git a/doc/configuration/specs.html.part b/doc/configuration/specs.html.part
index 5a53b3c..eeeafd3 100644
--- a/doc/configuration/specs.html.part
+++ b/doc/configuration/specs.html.part
@@ -33,7 +33,9 @@ the following order:</p>
can be used. May be extended to ranged dependencies, using either <code>[=1.23|=1.24|=1.25]</code> for an or
dependency or <code>[&gt;=1.2&amp;&lt;2]</code> for an and dependency.</li>
<li><code>[.key=value]</code>: Match only if the specified metadata key has a particular exact value. Only works for
- simple values, not compound keys.</li>
+ simple values, sets and sequences, not complex compound keys. If <code>&lt;</code> is used in place of
+ <code>=</code>, for numeric values a less-than comparison is used, and for sets and sequences, a match occurs if any
+ member of the set or sequence is equal to the value.</li>
</ul>
<p>Repository requirements are in the form <code>to</code>, <code>from-&gt;</code> or <code>::from-&gt;to</code>. The
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index e416e7c..6e2a48e 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -37,6 +37,8 @@
#include <paludis/util/sequence.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <paludis/util/timestamp.hh>
+#include <paludis/util/destringify.hh>
+#include <algorithm>
using namespace paludis;
@@ -347,15 +349,17 @@ namespace paludis
{
std::string key;
std::string value;
+ char op;
Implementation(const std::string & s)
{
- std::string::size_type p(s.find('='));
+ std::string::size_type p(s.find_first_of("=<"));
if (std::string::npos == p)
- throw PackageDepSpecError("Expected an = inside '[." + s + "]'");
+ throw PackageDepSpecError("Expected an = or a < inside '[." + s + "]'");
key = s.substr(0, p);
value = s.substr(p + 1);
+ op = s.at(p);
}
};
}
@@ -371,15 +375,43 @@ UserKeyRequirement::~UserKeyRequirement()
namespace
{
- struct KeyComparator
+ std::string stringify_contents_entry(const ContentsEntry & e)
+ {
+ return stringify(e.location_key()->value());
+ }
+
+ struct StringifyEqual
{
const std::string pattern;
- KeyComparator(const std::string & p) :
+ StringifyEqual(const std::string & p) :
pattern(p)
{
}
+ template <typename T_>
+ bool operator() (const T_ & t) const
+ {
+ return stringify(t) == pattern;
+ }
+
+ bool operator() (const ContentsEntry & e) const
+ {
+ return stringify_contents_entry(e) == pattern;
+ }
+ };
+
+ struct KeyComparator
+ {
+ const std::string pattern;
+ const char op;
+
+ KeyComparator(const std::string & p, const char o) :
+ pattern(p),
+ op(o)
+ {
+ }
+
bool visit(const MetadataSectionKey &) const
{
return false;
@@ -387,7 +419,15 @@ namespace
bool visit(const MetadataTimeKey & k) const
{
- return pattern == stringify(k.value().seconds());
+ switch (op)
+ {
+ case '=':
+ return pattern == stringify(k.value().seconds());
+ case '<':
+ return k.value().seconds() < destringify<time_t>(pattern);
+ }
+
+ return false;
}
bool visit(const MetadataValueKey<std::string> & k) const
@@ -412,7 +452,15 @@ namespace
bool visit(const MetadataValueKey<long> & k) const
{
- return pattern == stringify(k.value());
+ switch (op)
+ {
+ case '=':
+ return pattern == stringify(k.value());
+ case '<':
+ return k.value() < destringify<long>(pattern);
+ }
+
+ return false;
}
bool visit(const MetadataValueKey<std::tr1::shared_ptr<const Choices> > &) const
@@ -425,8 +473,20 @@ namespace
return false;
}
- bool visit(const MetadataValueKey<std::tr1::shared_ptr<const Contents> > &) const
+ bool visit(const MetadataValueKey<std::tr1::shared_ptr<const Contents> > & s) const
{
+ switch (op)
+ {
+ case '=':
+ return pattern == join(indirect_iterator(s.value()->begin()), indirect_iterator(s.value()->end()), " ",
+ stringify_contents_entry);
+ case '<':
+ return indirect_iterator(s.value()->end()) != std::find_if(
+ indirect_iterator(s.value()->begin()),
+ indirect_iterator(s.value()->end()),
+ StringifyEqual(pattern));
+ }
+
return false;
}
@@ -472,27 +532,74 @@ namespace
bool visit(const MetadataCollectionKey<FSEntrySequence> & s) const
{
- return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ switch (op)
+ {
+ case '=':
+ return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ case '<':
+ return s.value()->end() != std::find_if(s.value()->begin(), s.value()->end(),
+ StringifyEqual(pattern));
+ }
+
+ return false;
}
bool visit(const MetadataCollectionKey<PackageIDSequence> & s) const
{
- return pattern == join(indirect_iterator(s.value()->begin()), indirect_iterator(s.value()->end()), " ");
+ switch (op)
+ {
+ case '=':
+ return pattern == join(indirect_iterator(s.value()->begin()), indirect_iterator(s.value()->end()), " ");
+ case '<':
+ return indirect_iterator(s.value()->end()) != std::find_if(
+ indirect_iterator(s.value()->begin()),
+ indirect_iterator(s.value()->end()),
+ StringifyEqual(pattern));
+ }
+
+ return false;
}
bool visit(const MetadataCollectionKey<Sequence<std::string> > & s) const
{
- return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ switch (op)
+ {
+ case '=':
+ return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ case '<':
+ return s.value()->end() != std::find_if(s.value()->begin(), s.value()->end(),
+ StringifyEqual(pattern));
+ }
+
+ return false;
}
bool visit(const MetadataCollectionKey<Set<std::string> > & s) const
{
- return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ switch (op)
+ {
+ case '=':
+ return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ case '<':
+ return s.value()->end() != std::find_if(s.value()->begin(), s.value()->end(),
+ StringifyEqual(pattern));
+ }
+
+ return false;
}
bool visit(const MetadataCollectionKey<KeywordNameSet> & s) const
{
- return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ switch (op)
+ {
+ case '=':
+ return pattern == join(s.value()->begin(), s.value()->end(), " ");
+ case '<':
+ return s.value()->end() != std::find_if(s.value()->begin(), s.value()->end(),
+ StringifyEqual(pattern));
+ }
+
+ return false;
}
};
}
@@ -506,7 +613,7 @@ UserKeyRequirement::requirement_met(const Environment * const, const PackageID &
if (m == id.end_metadata())
return false;
- KeyComparator c(_imp->value);
+ KeyComparator c(_imp->value, _imp->op);
return (*m)->accept_returning<bool>(c);
}