aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-17 21:12:45 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-12-17 21:12:45 +0000
commit7045e87a387b78a97ec4352729527ce0174d4c60 (patch)
treec84672df83e150fdf8073a274fd8193b2ede1224
parent5b0b77894361ac4ca7cc68a5d1915cac4f5a15e1 (diff)
downloadpaludis-7045e87a387b78a97ec4352729527ce0174d4c60.tar.gz
paludis-7045e87a387b78a97ec4352729527ce0174d4c60.tar.xz
Make [.k=v] deps work on spec trees
-rw-r--r--NEWS8
-rw-r--r--doc/configuration/specs.html.part6
-rw-r--r--paludis/user_dep_spec.cc154
-rw-r--r--paludis/util/accept_visitor.hh43
4 files changed, 197 insertions, 14 deletions
diff --git a/NEWS b/NEWS
index fd420f7..7afa9de 100644
--- a/NEWS
+++ b/NEWS
@@ -21,10 +21,10 @@ 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.
+ * The [.key=value] syntax for user dep specs now works with sets, sequences
+ and spec trees. If < is used instead of =, a less than comparison is used
+ for numeric values, and for compound values, a match succeeds if any item
+ of the key is equal to the specified pattern.
* Various large code cleanups and build system cleanups.
diff --git a/doc/configuration/specs.html.part b/doc/configuration/specs.html.part
index eeeafd3..b08121e 100644
--- a/doc/configuration/specs.html.part
+++ b/doc/configuration/specs.html.part
@@ -33,9 +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, 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>
+ simple values, sets, sequences and spec trees, not other 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, sequences and spec trees,
+ 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 6e2a48e..7c95b70 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -28,6 +28,7 @@
#include <paludis/filter.hh>
#include <paludis/package_id.hh>
#include <paludis/metadata_key.hh>
+#include <paludis/dep_label.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/options.hh>
#include <paludis/util/log.hh>
@@ -401,6 +402,89 @@ namespace
}
};
+ struct SpecTreeSearcher
+ {
+ const std::string pattern;
+
+ SpecTreeSearcher(const std::string & p) :
+ pattern(p)
+ {
+ }
+
+ bool visit(const GenericSpecTree::NodeType<AllDepSpec>::Type & n) const
+ {
+ return indirect_iterator(n.end()) != std::find_if(indirect_iterator(n.begin()), indirect_iterator(n.end()),
+ accept_visitor_returning<bool>(*this));
+ }
+
+ bool visit(const GenericSpecTree::NodeType<AnyDepSpec>::Type & n) const
+ {
+ return indirect_iterator(n.end()) != std::find_if(indirect_iterator(n.begin()), indirect_iterator(n.end()),
+ accept_visitor_returning<bool>(*this));
+ }
+
+ bool visit(const GenericSpecTree::NodeType<ConditionalDepSpec>::Type & n) const
+ {
+ if (n.spec()->condition_met())
+ return indirect_iterator(n.end()) != std::find_if(indirect_iterator(n.begin()), indirect_iterator(n.end()),
+ accept_visitor_returning<bool>(*this));
+ else
+ return false;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<NamedSetDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<PlainTextDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<PackageDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<BlockDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<LicenseDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<SimpleURIDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<FetchableURIDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+
+ bool visit(const GenericSpecTree::NodeType<DependenciesLabelsDepSpec>::Type & n) const
+ {
+ return indirect_iterator(n.spec()->end()) != std::find_if(indirect_iterator(n.spec()->begin()),
+ indirect_iterator(n.spec()->end()), StringifyEqual(pattern));
+ }
+
+ bool visit(const GenericSpecTree::NodeType<URILabelsDepSpec>::Type & n) const
+ {
+ return indirect_iterator(n.spec()->end()) != std::find_if(indirect_iterator(n.spec()->begin()),
+ indirect_iterator(n.spec()->end()), StringifyEqual(pattern));
+ }
+
+ bool visit(const GenericSpecTree::NodeType<PlainTextLabelDepSpec>::Type & n) const
+ {
+ return stringify(*n.spec()) == pattern;
+ }
+ };
+
struct KeyComparator
{
const std::string pattern;
@@ -495,38 +579,94 @@ namespace
return pattern == stringify(*k.value());
}
- bool visit(const MetadataSpecTreeKey<DependencySpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<DependencySpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<SetSpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<SetSpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<PlainTextSpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<PlainTextSpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<ProvideSpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<ProvideSpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<SimpleURISpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<SimpleURISpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<FetchableURISpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<FetchableURISpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
- bool visit(const MetadataSpecTreeKey<LicenseSpecTree> &) const
+ bool visit(const MetadataSpecTreeKey<LicenseSpecTree> & s) const
{
+ switch (op)
+ {
+ case '=':
+ return false;
+ case '<':
+ return s.value()->root()->accept_returning<bool>(SpecTreeSearcher(pattern));
+ }
+
return false;
}
diff --git a/paludis/util/accept_visitor.hh b/paludis/util/accept_visitor.hh
index bccb0fe..d68ead1 100644
--- a/paludis/util/accept_visitor.hh
+++ b/paludis/util/accept_visitor.hh
@@ -57,6 +57,38 @@ namespace paludis
};
/**
+ * Used by accept_visitor.
+ *
+ * \nosubgrouping
+ * \ingroup g_visitors
+ */
+ template <typename Visitor_, typename Returning_>
+ class PALUDIS_VISIBLE AcceptVisitorReturning
+ {
+ private:
+ Visitor_ & _v;
+
+ public:
+ typedef Returning_ result_type;
+
+ ///\name Visitor operations
+ ///\{
+
+ AcceptVisitorReturning(Visitor_ & v) :
+ _v(v)
+ {
+ }
+
+ template <typename T_>
+ Returning_ operator() (T_ & t) const
+ {
+ return t.template accept_returning<Returning_>(_v);
+ }
+
+ ///\}
+ };
+
+ /**
* Convenience function for using a visitor with a standard algorithm.
*
* \ingroup g_visitors
@@ -66,6 +98,17 @@ namespace paludis
{
return AcceptVisitor<Visitor_>(v);
}
+
+ /**
+ * Convenience function for using a visitor with a standard algorithm.
+ *
+ * \ingroup g_visitors
+ */
+ template <typename Returning_, typename Visitor_>
+ AcceptVisitorReturning<Visitor_, Returning_> PALUDIS_VISIBLE accept_visitor_returning(Visitor_ & v)
+ {
+ return AcceptVisitorReturning<Visitor_, Returning_>(v);
+ }
}
#endif