aboutsummaryrefslogtreecommitdiff
path: root/paludis
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 /paludis
parent984050842f2dd81d34cd2de19cf58709a5e90b15 (diff)
downloadpaludis-57229d3c88a580548406b10198088698421f7967.tar.gz
paludis-57229d3c88a580548406b10198088698421f7967.tar.xz
Add AtMostOneDepSpec
Diffstat (limited to 'paludis')
-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
11 files changed, 115 insertions, 0 deletions
diff --git a/paludis/dep_spec-fwd.hh b/paludis/dep_spec-fwd.hh
index 51128b675..7b1bfeaaf 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 f6acb350b..29a31422b 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 9f8254345..3fc076af1 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 593881cd3..6c55c742d 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 a193c38d1..7b6689635 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 da9996a59..d0437c270 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 373a7affb..5451ef119 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 fb4bcf9a0..831cf4e78 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 c67fbf801..0adb27f8d 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 9629fd9c9..95b33b23d 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 4e810d0d6..f810e4c24 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))