aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-10 19:51:18 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-10 20:21:04 +0000
commitb8c496e6a94bb6add2bfc94b0d1616f8aae904a9 (patch)
tree69a8e346cd08b049b3a4fe55bf5334251b22216c
parent7ba273785c74fad8d813d91302793a9fc4767703 (diff)
downloadpaludis-b8c496e6a94bb6add2bfc94b0d1616f8aae904a9.tar.gz
paludis-b8c496e6a94bb6add2bfc94b0d1616f8aae904a9.tar.xz
Implicitly annotate blocks
-rw-r--r--paludis/dep_spec_annotations-fwd.hh5
-rw-r--r--paludis/dep_spec_annotations.cc41
-rw-r--r--paludis/dep_spec_annotations.se3
-rw-r--r--paludis/repositories/e/dep_parser.cc88
4 files changed, 132 insertions, 5 deletions
diff --git a/paludis/dep_spec_annotations-fwd.hh b/paludis/dep_spec_annotations-fwd.hh
index a021672..2403ff6 100644
--- a/paludis/dep_spec_annotations-fwd.hh
+++ b/paludis/dep_spec_annotations-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2010 Ciaran McCreesh
+ * Copyright (c) 2010, 2011 Ciaran McCreesh
*
* This file is part of the Paludis package manager. Paludis is free software;
* you can redistribute it and/or modify it under the terms of the GNU General
@@ -22,6 +22,7 @@
#include <paludis/util/attributes.hh>
#include <iosfwd>
+#include <memory>
namespace paludis
{
@@ -30,6 +31,8 @@ namespace paludis
#include <paludis/dep_spec_annotations-se.hh>
+ DepSpecAnnotationRole find_blocker_role_in_annotations(
+ const std::shared_ptr<const DepSpecAnnotations> & maybe_annotations) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
}
#endif
diff --git a/paludis/dep_spec_annotations.cc b/paludis/dep_spec_annotations.cc
index 3c87620..d86cd2d 100644
--- a/paludis/dep_spec_annotations.cc
+++ b/paludis/dep_spec_annotations.cc
@@ -100,6 +100,47 @@ DepSpecAnnotations::add(const DepSpecAnnotation & a)
_imp->annotations.push_back(a);
}
+DepSpecAnnotationRole
+paludis::find_blocker_role_in_annotations(
+ const std::shared_ptr<const DepSpecAnnotations> & maybe_annotations)
+{
+ if (! maybe_annotations)
+ return dsar_none;
+
+ for (auto i(maybe_annotations->begin()), i_end(maybe_annotations->end()) ;
+ i != i_end ; ++i)
+ {
+ switch (i->role())
+ {
+ case dsar_blocker_manual:
+ case dsar_blocker_uninstall_blocked_after:
+ case dsar_blocker_uninstall_blocked_before:
+ case dsar_blocker_upgrade_blocked_before:
+ case dsar_blocker_weak:
+ case dsar_blocker_strong:
+ return i->role();
+
+ case dsar_none:
+ case dsar_general_description:
+ case dsar_general_url:
+ case dsar_general_note:
+ case dsar_general_lang:
+ case dsar_general_defined_in:
+ case dsar_myoptions_requires:
+ case dsar_myoptions_n_at_least_one:
+ case dsar_myoptions_n_at_most_one:
+ case dsar_myoptions_n_exactly_one:
+ case dsar_suggestions_group_name:
+ break;
+
+ case last_dsar:
+ throw InternalError(PALUDIS_HERE, "bad dsar");
+ }
+ }
+
+ return dsar_none;
+}
+
template class Pimp<DepSpecAnnotations>;
template class WrappedForwardIterator<DepSpecAnnotations::ConstIteratorTag, const DepSpecAnnotation>;
diff --git a/paludis/dep_spec_annotations.se b/paludis/dep_spec_annotations.se
index 02c83ae..ebe5537 100644
--- a/paludis/dep_spec_annotations.se
+++ b/paludis/dep_spec_annotations.se
@@ -13,10 +13,13 @@ make_enum_DepSpecAnnotationRole()
key dsar_general_lang "A language"
key dsar_general_defined_in "Defined in"
+ # update find_blocker_role_in_annotations when adding here
key dsar_blocker_manual "Blocker, resolve manually"
key dsar_blocker_uninstall_blocked_after "Blocker, uninstall blocked after"
key dsar_blocker_uninstall_blocked_before "Blocker, uninstall blocked before"
key dsar_blocker_upgrade_blocked_before "Blocker, upgrade blocked before"
+ key dsar_blocker_weak "Blocker, weak (generally implicit)"
+ key dsar_blocker_strong "Blocker, strong (generally implicit)"
key dsar_myoptions_requires "MYOPTIONS, requires"
key dsar_myoptions_n_at_least_one "MYOPTIONS, at least one"
diff --git a/paludis/repositories/e/dep_parser.cc b/paludis/repositories/e/dep_parser.cc
index 9906942..2d811f0 100644
--- a/paludis/repositories/e/dep_parser.cc
+++ b/paludis/repositories/e/dep_parser.cc
@@ -52,6 +52,8 @@
#include <list>
#include <set>
#include <ostream>
+#include <algorithm>
+#include <functional>
using namespace paludis;
using namespace paludis::erepository;
@@ -125,10 +127,18 @@ namespace
call_annotations_go_here(annotations_go_here, spec);
}
+ enum BlockFixOp
+ {
+ bfo_explicit_strong,
+ bfo_implicit_strong,
+ bfo_implicit_weak
+ };
+
template <typename T_>
void package_or_block_dep_spec_string_handler(
const typename ParseStackTypes<T_>::Stack & h,
const typename ParseStackTypes<T_>::AnnotationsGoHere & annotations_go_here,
+ BlockFixOp & block_fix_op,
const std::string & s,
const EAPI & eapi)
{
@@ -142,11 +152,17 @@ namespace
throw EDepParseError(s, "Double-! blocks not allowed in this EAPI");
specstart = 2;
strong = true;
+ block_fix_op = bfo_explicit_strong;
}
else
{
if (eapi.supported()->dependency_spec_tree_parse_options()[dstpo_single_bang_block_is_hard])
+ {
strong = true;
+ block_fix_op = bfo_implicit_strong;
+ }
+ else
+ block_fix_op = bfo_implicit_weak;
}
std::shared_ptr<BlockDepSpec> spec(std::make_shared<BlockDepSpec>(
@@ -352,6 +368,68 @@ namespace
spec = s;
block = b;
}
+
+ void fix_block_annotations(
+ const std::shared_ptr<BlockDepSpec> & if_block_spec,
+ const BlockFixOp & block_fix_op)
+ {
+ if (! if_block_spec)
+ return;
+
+ DepSpecAnnotationRole current_role(dsar_none);
+ if (if_block_spec->maybe_annotations())
+ current_role = find_blocker_role_in_annotations(if_block_spec->maybe_annotations());
+ if (dsar_none != current_role)
+ return;
+
+ std::shared_ptr<DepSpecAnnotations> annotations(std::make_shared<DepSpecAnnotations>());
+ if (if_block_spec->maybe_annotations())
+ std::for_each(if_block_spec->maybe_annotations()->begin(), if_block_spec->maybe_annotations()->end(),
+ std::bind(&DepSpecAnnotations::add, annotations, std::placeholders::_1));
+
+ switch (block_fix_op)
+ {
+ case bfo_explicit_strong:
+ annotations->add(make_named_values<DepSpecAnnotation>(
+ n::key() = "<resolution>",
+ n::kind() = dsak_synthetic,
+ n::role() = dsar_blocker_strong,
+ n::value() = "<explicit-strong>"
+ ));
+ break;
+
+ case bfo_implicit_strong:
+ annotations->add(make_named_values<DepSpecAnnotation>(
+ n::key() = "<resolution>",
+ n::kind() = dsak_synthetic,
+ n::role() = dsar_blocker_strong,
+ n::value() = "<implicit-strong>"
+ ));
+ break;
+
+ case bfo_implicit_weak:
+ annotations->add(make_named_values<DepSpecAnnotation>(
+ n::key() = "<resolution>",
+ n::kind() = dsak_synthetic,
+ n::role() = dsar_blocker_weak,
+ n::value() = "<implicit-weak>"
+ ));
+ break;
+ }
+
+ if_block_spec->set_annotations(annotations);
+ }
+
+ void apply_annotations_then_fixup(
+ const EAPI & eapi,
+ const std::shared_ptr<DepSpec> & spec,
+ const std::shared_ptr<BlockDepSpec> & if_block_spec,
+ const BlockFixOp & block_fix_op,
+ const std::shared_ptr<const Map<std::string, std::string> > & m)
+ {
+ apply_annotations(eapi, spec, if_block_spec, m);
+ fix_block_annotations(if_block_spec, block_fix_op);
+ }
}
std::shared_ptr<DependencySpecTree>
@@ -363,6 +441,7 @@ paludis::erepository::parse_depend(const std::string & s, const Environment * co
std::shared_ptr<AllDepSpec> spec(std::make_shared<AllDepSpec>());
std::shared_ptr<DepSpec> thing_to_annotate(spec);
std::shared_ptr<BlockDepSpec> thing_to_annotate_if_block;
+ BlockFixOp block_fix_op;
std::shared_ptr<DependencySpecTree> top(std::make_shared<DependencySpecTree>(spec));
stack.push_front(make_named_values<ParseStackTypes<DependencySpecTree>::Item>(
n::item() = top->top(),
@@ -372,8 +451,8 @@ paludis::erepository::parse_depend(const std::string & s, const Environment * co
ELikeDepParserCallbacks callbacks(
make_named_values<ELikeDepParserCallbacks>(
n::on_all() = std::bind(&any_all_handler<DependencySpecTree, AllDepSpec>, std::ref(stack)),
- n::on_annotations() = std::bind(&apply_annotations, std::cref(eapi), std::ref(thing_to_annotate),
- std::ref(thing_to_annotate_if_block), _1),
+ n::on_annotations() = std::bind(&apply_annotations_then_fixup, std::cref(eapi), std::cref(thing_to_annotate),
+ std::cref(thing_to_annotate_if_block), std::cref(block_fix_op), _1),
n::on_any() = std::bind(&any_all_handler<DependencySpecTree, AnyDepSpec>, std::ref(stack)),
n::on_arrow() = std::bind(&arrows_not_allowed_handler, s, _1, _2),
n::on_error() = std::bind(&error_handler, s, _1),
@@ -383,14 +462,15 @@ paludis::erepository::parse_depend(const std::string & s, const Environment * co
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
&set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)),
_1, std::cref(eapi)),
- n::on_no_annotations() = &do_nothing,
+ n::on_no_annotations() = std::bind(&fix_block_annotations, std::cref(thing_to_annotate_if_block), std::cref(block_fix_op)),
n::on_pop() = std::bind(&pop_handler<DependencySpecTree>, std::ref(stack),
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
&set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)), s),
n::on_should_be_empty() = std::bind(&should_be_empty_handler<DependencySpecTree>, std::ref(stack), s),
n::on_string() = std::bind(&package_or_block_dep_spec_string_handler<DependencySpecTree>, std::ref(stack),
ParseStackTypes<DependencySpecTree>::AnnotationsGoHere(std::bind(
- &set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)), _1, eapi),
+ &set_thing_to_annotate_maybe_block, std::ref(thing_to_annotate), _1, std::ref(thing_to_annotate_if_block), _2)),
+ std::ref(block_fix_op), _1, eapi),
n::on_use() = std::bind(&use_handler<DependencySpecTree>, std::ref(stack), _1, env, std::cref(eapi), is_installed),
n::on_use_under_any() = std::bind(&use_under_any_handler, s, std::cref(eapi))
));