aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2012-05-06 20:51:28 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2012-05-12 11:33:35 +0100
commit57229d3c88a580548406b10198088698421f7967 (patch)
treeef3986438029cddae3f2f19ab1e5000048851ffd
parent984050842f2dd81d34cd2de19cf58709a5e90b15 (diff)
downloadpaludis-57229d3c88a580548406b10198088698421f7967.tar.gz
paludis-57229d3c88a580548406b10198088698421f7967.tar.xz
Add AtMostOneDepSpec
-rw-r--r--paludis/dep_spec-fwd.hh1
-rw-r--r--paludis/dep_spec.cc12
-rw-r--r--paludis/dep_spec.hh21
-rw-r--r--paludis/repositories/e/required_use_verifier.cc19
-rw-r--r--paludis/repositories/e/required_use_verifier.hh1
-rw-r--r--paludis/repositories/e/spec_tree_pretty_printer.cc40
-rw-r--r--paludis/repositories/e/spec_tree_pretty_printer.hh1
-rw-r--r--paludis/spec_tree-fwd.hh2
-rw-r--r--paludis/spec_tree.cc10
-rw-r--r--paludis/spec_tree.hh2
-rw-r--r--paludis/user_dep_spec.cc6
-rw-r--r--python/dep_spec.cc43
-rw-r--r--python/dep_spec.hh14
-rw-r--r--python/nice_names.nn1
-rw-r--r--ruby/dep_spec.cc19
-rw-r--r--ruby/nice_names.nn1
-rw-r--r--src/clients/cave/cmd_match.cc5
17 files changed, 198 insertions, 0 deletions
diff --git a/paludis/dep_spec-fwd.hh b/paludis/dep_spec-fwd.hh
index 51128b6..7b1bfea 100644
--- a/paludis/dep_spec-fwd.hh
+++ b/paludis/dep_spec-fwd.hh
@@ -41,6 +41,7 @@ namespace paludis
class AllDepSpec;
class ExactlyOneDepSpec;
class AnyDepSpec;
+ class AtMostOneDepSpec;
class ConditionalDepSpec;
class BlockDepSpec;
class StringDepSpec;
diff --git a/paludis/dep_spec.cc b/paludis/dep_spec.cc
index f6acb35..29a3142 100644
--- a/paludis/dep_spec.cc
+++ b/paludis/dep_spec.cc
@@ -110,6 +110,18 @@ ExactlyOneDepSpec::clone() const
return result;
}
+AtMostOneDepSpec::AtMostOneDepSpec()
+{
+}
+
+std::shared_ptr<DepSpec>
+AtMostOneDepSpec::clone() const
+{
+ std::shared_ptr<AtMostOneDepSpec> result(std::make_shared<AtMostOneDepSpec>());
+ result->set_annotations(maybe_annotations());
+ return result;
+}
+
namespace paludis
{
template <>
diff --git a/paludis/dep_spec.hh b/paludis/dep_spec.hh
index 9f82543..3fc076a 100644
--- a/paludis/dep_spec.hh
+++ b/paludis/dep_spec.hh
@@ -170,6 +170,27 @@ namespace paludis
};
/**
+ * Represents a ?? ( first second third ) group of requirements.
+ *
+ * \ingroup g_dep_spec
+ * \nosubgrouping
+ * \since 0.56
+ */
+ class PALUDIS_VISIBLE AtMostOneDepSpec :
+ public DepSpec
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ AtMostOneDepSpec();
+
+ ///\}
+
+ virtual std::shared_ptr<DepSpec> clone() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ /**
* Represents a dependency spec whose children should only be considered
* upon a certain condition (for example, a use dependency block).
*
diff --git a/paludis/repositories/e/required_use_verifier.cc b/paludis/repositories/e/required_use_verifier.cc
index 593881c..6c55c74 100644
--- a/paludis/repositories/e/required_use_verifier.cc
+++ b/paludis/repositories/e/required_use_verifier.cc
@@ -176,6 +176,25 @@ RequiredUseVerifier::visit(const RequiredUseSpecTree::NodeType<ExactlyOneDepSpec
}
void
+RequiredUseVerifier::visit(const RequiredUseSpecTree::NodeType<AtMostOneDepSpec>::Type & node)
+{
+ _imp->stack.push_front(Met{0, false});
+ std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this));
+
+ Met met(*_imp->stack.begin());
+ _imp->stack.pop_front();
+
+ if (met.number_met <= 1)
+ ++_imp->stack.begin()->number_met;
+ else if (met.number_met > 1)
+ _imp->stack.begin()->any_unmet = true;
+ else if (met.any_unmet)
+ _imp->stack.begin()->any_unmet = true;
+ else
+ ++_imp->stack.begin()->number_met;
+}
+
+void
RequiredUseVerifier::visit(const RequiredUseSpecTree::NodeType<ConditionalDepSpec>::Type & node)
{
if (! node.spec()->condition_met(_imp->env, _imp->id))
diff --git a/paludis/repositories/e/required_use_verifier.hh b/paludis/repositories/e/required_use_verifier.hh
index a193c38..7b66896 100644
--- a/paludis/repositories/e/required_use_verifier.hh
+++ b/paludis/repositories/e/required_use_verifier.hh
@@ -51,6 +51,7 @@ namespace paludis
void visit(const RequiredUseSpecTree::NodeType<AllDepSpec>::Type & node);
void visit(const RequiredUseSpecTree::NodeType<AnyDepSpec>::Type & node);
void visit(const RequiredUseSpecTree::NodeType<ExactlyOneDepSpec>::Type & node);
+ void visit(const RequiredUseSpecTree::NodeType<AtMostOneDepSpec>::Type & node);
void visit(const RequiredUseSpecTree::NodeType<ConditionalDepSpec>::Type & node);
};
}
diff --git a/paludis/repositories/e/spec_tree_pretty_printer.cc b/paludis/repositories/e/spec_tree_pretty_printer.cc
index da9996a..d0437c2 100644
--- a/paludis/repositories/e/spec_tree_pretty_printer.cc
+++ b/paludis/repositories/e/spec_tree_pretty_printer.cc
@@ -139,6 +139,10 @@ namespace
{
}
+ void visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type &)
+ {
+ }
+
void visit(const GenericSpecTree::NodeType<AnyDepSpec>::Type &)
{
}
@@ -275,6 +279,42 @@ SpecTreePrettyPrinter::visit(const GenericSpecTree::NodeType<ExactlyOneDepSpec>:
}
void
+SpecTreePrettyPrinter::visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type & node)
+{
+ Save<bool> old_outer(&_imp->outer_block, false);
+ Save<bool> old_needs_parens(&_imp->all_needs_parens, true);
+
+ if (_imp->use_newlines)
+ _imp->s << _imp->pretty_printer.indentify(_imp->indent);
+ else if (_imp->need_space)
+ _imp->s << " ";
+ _imp->s << "?? (";
+ if (_imp->use_newlines)
+ _imp->s << _imp->pretty_printer.newline();
+ else
+ _imp->need_space = true;
+
+ {
+ Save<unsigned> old_indent(&_imp->indent, _imp->indent + 1);
+ Save<bool> extra_label_indent(&_imp->extra_label_indent, false);
+ std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this));
+ }
+
+ if (_imp->use_newlines)
+ _imp->s << _imp->pretty_printer.indentify(_imp->indent);
+ else if (_imp->need_space)
+ _imp->s << " ";
+ _imp->s << ")";
+
+ do_annotations(*node.spec());
+
+ if (_imp->use_newlines)
+ _imp->s << _imp->pretty_printer.newline();
+ else
+ _imp->need_space = true;
+}
+
+void
SpecTreePrettyPrinter::visit(const GenericSpecTree::NodeType<ConditionalDepSpec>::Type & node)
{
Save<bool> old_outer(&_imp->outer_block, false);
diff --git a/paludis/repositories/e/spec_tree_pretty_printer.hh b/paludis/repositories/e/spec_tree_pretty_printer.hh
index 373a7af..5451ef1 100644
--- a/paludis/repositories/e/spec_tree_pretty_printer.hh
+++ b/paludis/repositories/e/spec_tree_pretty_printer.hh
@@ -53,6 +53,7 @@ namespace paludis
void visit(const GenericSpecTree::NodeType<AllDepSpec>::Type & node);
void visit(const GenericSpecTree::NodeType<AnyDepSpec>::Type & node);
void visit(const GenericSpecTree::NodeType<ExactlyOneDepSpec>::Type & node);
+ void visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type & node);
void visit(const GenericSpecTree::NodeType<ConditionalDepSpec>::Type & node);
void visit(const GenericSpecTree::NodeType<PackageDepSpec>::Type & node);
void visit(const GenericSpecTree::NodeType<BlockDepSpec>::Type & node);
diff --git a/paludis/spec_tree-fwd.hh b/paludis/spec_tree-fwd.hh
index fb4bcf9..831cf4e 100644
--- a/paludis/spec_tree-fwd.hh
+++ b/paludis/spec_tree-fwd.hh
@@ -84,6 +84,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec> GenericSpecTree;
@@ -112,6 +113,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec> RequiredUseSpecTree;
diff --git a/paludis/spec_tree.cc b/paludis/spec_tree.cc
index c67fbf8..0adb27f 100644
--- a/paludis/spec_tree.cc
+++ b/paludis/spec_tree.cc
@@ -192,6 +192,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec>;
@@ -233,6 +234,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec>;
@@ -287,6 +289,7 @@ namespace paludis
template class PALUDIS_VISIBLE InnerNode<GenericSpecTree, AllDepSpec>;
template class PALUDIS_VISIBLE InnerNode<GenericSpecTree, AnyDepSpec>;
template class PALUDIS_VISIBLE InnerNode<GenericSpecTree, ExactlyOneDepSpec>;
+ template class PALUDIS_VISIBLE InnerNode<GenericSpecTree, AtMostOneDepSpec>;
template class PALUDIS_VISIBLE InnerNode<GenericSpecTree, ConditionalDepSpec>;
}
}
@@ -435,6 +438,11 @@ template const std::shared_ptr<RequiredUseSpecTree::NodeType<ExactlyOneDepSpec>:
template const std::shared_ptr<RequiredUseSpecTree::NodeType<ExactlyOneDepSpec>::Type>
BasicInnerNode<RequiredUseSpecTree>::append<ExactlyOneDepSpec>(const std::shared_ptr<ExactlyOneDepSpec> &);
+template const std::shared_ptr<RequiredUseSpecTree::NodeType<AtMostOneDepSpec>::Type>
+ BasicInnerNode<RequiredUseSpecTree>::append<AtMostOneDepSpec>(const std::shared_ptr<const AtMostOneDepSpec> &);
+template const std::shared_ptr<RequiredUseSpecTree::NodeType<AtMostOneDepSpec>::Type>
+ BasicInnerNode<RequiredUseSpecTree>::append<AtMostOneDepSpec>(const std::shared_ptr<AtMostOneDepSpec> &);
+
template const std::shared_ptr<RequiredUseSpecTree::NodeType<ConditionalDepSpec>::Type>
BasicInnerNode<RequiredUseSpecTree>::append<ConditionalDepSpec>(const std::shared_ptr<const ConditionalDepSpec> &);
template const std::shared_ptr<RequiredUseSpecTree::NodeType<ConditionalDepSpec>::Type>
@@ -452,6 +460,7 @@ namespace paludis
template class PALUDIS_VISIBLE InnerNode<RequiredUseSpecTree, AllDepSpec>;
template class PALUDIS_VISIBLE InnerNode<RequiredUseSpecTree, AnyDepSpec>;
template class PALUDIS_VISIBLE InnerNode<RequiredUseSpecTree, ExactlyOneDepSpec>;
+ template class PALUDIS_VISIBLE InnerNode<RequiredUseSpecTree, AtMostOneDepSpec>;
template class PALUDIS_VISIBLE InnerNode<RequiredUseSpecTree, ConditionalDepSpec>;
}
}
@@ -615,6 +624,7 @@ template LeafNode<PlainTextSpecTree, PlainTextLabelDepSpec>::operator LeafNode<G
template InnerNode<RequiredUseSpecTree, AllDepSpec>::operator InnerNode<GenericSpecTree, AllDepSpec> () const;
template InnerNode<RequiredUseSpecTree, AnyDepSpec>::operator InnerNode<GenericSpecTree, AnyDepSpec> () const;
template InnerNode<RequiredUseSpecTree, ExactlyOneDepSpec>::operator InnerNode<GenericSpecTree, ExactlyOneDepSpec> () const;
+template InnerNode<RequiredUseSpecTree, AtMostOneDepSpec>::operator InnerNode<GenericSpecTree, AtMostOneDepSpec> () const;
template InnerNode<RequiredUseSpecTree, ConditionalDepSpec>::operator InnerNode<GenericSpecTree, ConditionalDepSpec> () const;
template LeafNode<RequiredUseSpecTree, PlainTextDepSpec>::operator LeafNode<GenericSpecTree, PlainTextDepSpec> () const;
diff --git a/paludis/spec_tree.hh b/paludis/spec_tree.hh
index 9629fd9..95b33b2 100644
--- a/paludis/spec_tree.hh
+++ b/paludis/spec_tree.hh
@@ -191,6 +191,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec>;
@@ -232,6 +233,7 @@ namespace paludis
SpecTreeInnerNodeType<AllDepSpec>,
SpecTreeInnerNodeType<AnyDepSpec>,
SpecTreeInnerNodeType<ExactlyOneDepSpec>,
+ SpecTreeInnerNodeType<AtMostOneDepSpec>,
SpecTreeInnerNodeType<ConditionalDepSpec>
>::Type, AllDepSpec>;
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index 4e810d0..f810e4c 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -505,6 +505,12 @@ namespace
accept_visitor_returning<bool>(*this));
}
+ bool visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::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(env, id))
diff --git a/python/dep_spec.cc b/python/dep_spec.cc
index 9f54492..7e10916 100644
--- a/python/dep_spec.cc
+++ b/python/dep_spec.cc
@@ -152,6 +152,14 @@ PythonExactlyOneDepSpec::PythonExactlyOneDepSpec(const ExactlyOneDepSpec &)
{
}
+PythonAtMostOneDepSpec::PythonAtMostOneDepSpec()
+{
+}
+
+PythonAtMostOneDepSpec::PythonAtMostOneDepSpec(const AtMostOneDepSpec &)
+{
+}
+
PythonAllDepSpec::PythonAllDepSpec()
{
}
@@ -539,6 +547,15 @@ SpecTreeToPython::visit(const GenericSpecTree::NodeType<ExactlyOneDepSpec>::Type
}
void
+SpecTreeToPython::visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type & node)
+{
+ std::shared_ptr<PythonAtMostOneDepSpec> py_cds(std::make_shared<PythonAtMostOneDepSpec>(*node.spec()));
+ _current_parent->add_child(py_cds);
+ Save<std::shared_ptr<PythonCompositeDepSpec> > old_parent(&_current_parent, py_cds);
+ std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this));
+}
+
+void
SpecTreeToPython::visit(const GenericSpecTree::NodeType<ConditionalDepSpec>::Type & node)
{
std::shared_ptr<PythonConditionalDepSpec> py_cds(std::make_shared<PythonConditionalDepSpec>(*node.spec()));
@@ -657,6 +674,7 @@ struct AllowedTypes<RequiredUseSpecTree>
AllowedTypes(const AllDepSpec &) {};
AllowedTypes(const AnyDepSpec &) {};
AllowedTypes(const ExactlyOneDepSpec &) {};
+ AllowedTypes(const AtMostOneDepSpec &) {};
AllowedTypes(const ConditionalDepSpec &) {};
AllowedTypes(const PlainTextDepSpec &) {};
};
@@ -758,6 +776,13 @@ SpecTreeFromPython<H_>::visit(const PythonExactlyOneDepSpec & d)
template <typename H_>
void
+SpecTreeFromPython<H_>::visit(const PythonAtMostOneDepSpec & d)
+{
+ dispatch<H_, AtMostOneDepSpec>(this, d);
+}
+
+template <typename H_>
+void
SpecTreeFromPython<H_>::visit(const PythonConditionalDepSpec & d)
{
dispatch<H_, ConditionalDepSpec>(this, d);
@@ -859,6 +884,14 @@ SpecTreeFromPython<H_>::real_visit(const PythonExactlyOneDepSpec & d)
template <typename H_>
void
+SpecTreeFromPython<H_>::real_visit(const PythonAtMostOneDepSpec & d)
+{
+ Save<std::shared_ptr<typename H_::BasicInnerNode> > old_add_to(&_add_to, _add_to->append(std::make_shared<AtMostOneDepSpec>()));
+ std::for_each(indirect_iterator(d.begin()), indirect_iterator(d.end()), accept_visitor(*this));
+}
+
+template <typename H_>
+void
SpecTreeFromPython<H_>::real_visit(const PythonConditionalDepSpec & d)
{
Save<std::shared_ptr<typename H_::BasicInnerNode> > old_add_to(&_add_to, _add_to->append(std::make_shared<ConditionalDepSpec>(d.data())));
@@ -1123,6 +1156,16 @@ void expose_dep_spec()
);
/**
+ * AtMostOneDepSpec
+ */
+ bp::class_<PythonAtMostOneDepSpec, bp::bases<PythonCompositeDepSpec>, boost::noncopyable>
+ (
+ "AtMostOneDepSpec",
+ "Represents a \"?? ( )\" dependency block.",
+ bp::init<>("__init__()")
+ );
+
+ /**
* AllDepSpec
*/
bp::class_<PythonAllDepSpec, bp::bases<PythonCompositeDepSpec>, boost::noncopyable>
diff --git a/python/dep_spec.hh b/python/dep_spec.hh
index 1a10fc1..bd48251 100644
--- a/python/dep_spec.hh
+++ b/python/dep_spec.hh
@@ -33,6 +33,7 @@ namespace paludis
class PythonAllDepSpec;
class PythonAnyDepSpec;
class PythonExactlyOneDepSpec;
+ class PythonAtMostOneDepSpec;
class PythonConditionalDepSpec;
class PythonStringDepSpec;
class PythonPlainTextDepSpec;
@@ -50,6 +51,7 @@ namespace paludis
public virtual DeclareAbstractAcceptMethods<PythonDepSpec, MakeTypeList<
PythonAnyDepSpec,
PythonExactlyOneDepSpec,
+ PythonAtMostOneDepSpec,
PythonAllDepSpec,
PythonConditionalDepSpec,
PythonBlockDepSpec,
@@ -115,6 +117,15 @@ namespace paludis
PythonExactlyOneDepSpec(const ExactlyOneDepSpec &);
};
+ class PALUDIS_VISIBLE PythonAtMostOneDepSpec :
+ public PythonCompositeDepSpec,
+ public ImplementAcceptMethods<PythonDepSpec, PythonAtMostOneDepSpec>
+ {
+ public:
+ PythonAtMostOneDepSpec();
+ PythonAtMostOneDepSpec(const AtMostOneDepSpec &);
+ };
+
class PALUDIS_VISIBLE PythonAllDepSpec :
public PythonCompositeDepSpec,
public ImplementAcceptMethods<PythonDepSpec, PythonAllDepSpec>
@@ -302,6 +313,7 @@ namespace paludis
void visit(const GenericSpecTree::NodeType<AllDepSpec>::Type &);
void visit(const GenericSpecTree::NodeType<AnyDepSpec>::Type &);
void visit(const GenericSpecTree::NodeType<ExactlyOneDepSpec>::Type &);
+ void visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type &);
void visit(const GenericSpecTree::NodeType<ConditionalDepSpec>::Type &);
void visit(const GenericSpecTree::NodeType<PackageDepSpec>::Type &);
@@ -339,6 +351,7 @@ namespace paludis
void visit(const PythonAllDepSpec &);
void visit(const PythonAnyDepSpec &);
void visit(const PythonExactlyOneDepSpec &);
+ void visit(const PythonAtMostOneDepSpec &);
void visit(const PythonConditionalDepSpec &);
void visit(const PythonPackageDepSpec &);
void visit(const PythonPlainTextDepSpec &);
@@ -354,6 +367,7 @@ namespace paludis
void real_visit(const PythonAllDepSpec &);
void real_visit(const PythonAnyDepSpec &);
void real_visit(const PythonExactlyOneDepSpec &);
+ void real_visit(const PythonAtMostOneDepSpec &);
void real_visit(const PythonConditionalDepSpec &);
void real_visit(const PythonPackageDepSpec &);
void real_visit(const PythonPlainTextDepSpec &);
diff --git a/python/nice_names.nn b/python/nice_names.nn
index 8494d26..da23337 100644
--- a/python/nice_names.nn
+++ b/python/nice_names.nn
@@ -28,6 +28,7 @@ make_nn_NiceNames() {
name "AllDepSpec"
name "AnyDepSpec"
name "ExactlyOneDepSpec"
+ name "AtMostOneDepSpec"
name "ConditionalDepSpec"
name "BlockDepSpec"
name "StringDepSpec"
diff --git a/ruby/dep_spec.cc b/ruby/dep_spec.cc
index 91766cc..32d07b0 100644
--- a/ruby/dep_spec.cc
+++ b/ruby/dep_spec.cc
@@ -59,6 +59,7 @@ namespace
static VALUE c_all_dep_spec;
static VALUE c_any_dep_spec;
static VALUE c_exactly_one_dep_spec;
+ static VALUE c_at_most_one;
static VALUE c_conditional_dep_spec;
static VALUE c_version_requirements_mode;
@@ -131,6 +132,7 @@ namespace
WrappedSpec<AllDepSpec>,
WrappedSpec<AnyDepSpec>,
WrappedSpec<ExactlyOneDepSpec>,
+ WrappedSpec<AtMostOneDepSpec>,
WrappedSpec<ConditionalDepSpec>
>::Type>
{
@@ -272,6 +274,12 @@ namespace
wrapped.reset((new WrappedSpec<ExactlyOneDepSpec>(std::static_pointer_cast<ExactlyOneDepSpec>(node.spec()->clone())))->add_children(node.begin(), node.end()));
klass = c_exactly_one_dep_spec;
}
+
+ void visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type & node)
+ {
+ wrapped.reset((new WrappedSpec<AtMostOneDepSpec>(std::static_pointer_cast<AtMostOneDepSpec>(node.spec()->clone())))->add_children(node.begin(), node.end()));
+ klass = c_at_most_one;
+ }
};
template <typename T_>
@@ -1017,6 +1025,17 @@ namespace
rb_define_method(c_exactly_one_dep_spec, "each", RUBY_FUNC_CAST((&Composite<AllDepSpec>::each)), 0);
/*
+ * Document-class: Paludis::AtMostOneDepSpec
+ *
+ * Represents a "?? ( )" dependency block. Includes
+ * Enumerable[http://www.ruby-doc.org/core/classes/Enumerable.html].
+ */
+ c_at_most_one = rb_define_class_under(paludis_module(), "AtMostOneDepSpec", c_dep_spec);
+ rb_funcall(c_at_most_one, rb_intern("private_class_method"), 1, rb_str_new2("new"));
+ rb_include_module(c_at_most_one, rb_mEnumerable);
+ rb_define_method(c_at_most_one, "each", RUBY_FUNC_CAST((&Composite<AllDepSpec>::each)), 0);
+
+ /*
* Document-class: Paludis::ConditionalDepSpec
*
* Represents a use? ( ) dependency spec. Includes
diff --git a/ruby/nice_names.nn b/ruby/nice_names.nn
index c90f18f..60dab85 100644
--- a/ruby/nice_names.nn
+++ b/ruby/nice_names.nn
@@ -24,6 +24,7 @@ make_nn_NiceNames() {
name "SimpleURIDepSpec"
name "AllDepSpec"
name "AnyDepSpec"
+ name "AtMostOneDepSpec"
name "ExactlyOneDepSpec"
name "ConditionalDepSpec"
name "BlockDepSpec"
diff --git a/src/clients/cave/cmd_match.cc b/src/clients/cave/cmd_match.cc
index 129f6d4..f422ae6 100644
--- a/src/clients/cave/cmd_match.cc
+++ b/src/clients/cave/cmd_match.cc
@@ -190,6 +190,11 @@ namespace
std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this));
}
+ void visit(const GenericSpecTree::NodeType<AtMostOneDepSpec>::Type & node)
+ {
+ std::for_each(indirect_iterator(node.begin()), indirect_iterator(node.end()), accept_visitor(*this));
+ }
+
void visit(const GenericSpecTree::NodeType<SimpleURIDepSpec>::Type & node)
{
texts.push_back(stringify(*node.spec()));