aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-15 17:06:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2011-03-15 17:06:51 +0000
commit81a164c94912d9f650ff352110ee47839de8edea (patch)
treeb621ef1d8679029302af0d34e0ef527e3e86da0e
parent96f7b4bd29618d66f346fc18e38c3c53ecfe6210 (diff)
downloadpaludis-81a164c94912d9f650ff352110ee47839de8edea.tar.gz
paludis-81a164c94912d9f650ff352110ee47839de8edea.tar.xz
Common blocker splitting up code
-rw-r--r--paludis/elike_blocker-fwd.hh36
-rw-r--r--paludis/elike_blocker.cc48
-rw-r--r--paludis/elike_blocker.hh25
-rw-r--r--paludis/elike_blocker.se15
-rw-r--r--paludis/files.m41
-rw-r--r--paludis/repositories/e/dep_parser.cc68
-rw-r--r--paludis/resolver/spec_rewriter.cc8
-rw-r--r--src/clients/cave/cmd_execute_resolution.cc32
-rw-r--r--src/clients/cave/resolve_common.cc10
9 files changed, 193 insertions, 50 deletions
diff --git a/paludis/elike_blocker-fwd.hh b/paludis/elike_blocker-fwd.hh
new file mode 100644
index 0000000..b630068
--- /dev/null
+++ b/paludis/elike_blocker-fwd.hh
@@ -0,0 +1,36 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ELIKE_BLOCKER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_BLOCKER_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <tuple>
+#include <string>
+#include <iosfwd>
+
+namespace paludis
+{
+#include <paludis/elike_blocker-se.hh>
+
+ std::tuple<ELikeBlockerKind, std::string, std::string> split_elike_blocker(
+ const std::string &) PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+}
+
+#endif
diff --git a/paludis/elike_blocker.cc b/paludis/elike_blocker.cc
new file mode 100644
index 0000000..1204f66
--- /dev/null
+++ b/paludis/elike_blocker.cc
@@ -0,0 +1,48 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/elike_blocker.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <istream>
+#include <ostream>
+
+using namespace paludis;
+
+#include <paludis/elike_blocker-se.cc>
+
+std::tuple<ELikeBlockerKind, std::string, std::string>
+paludis::split_elike_blocker(const std::string & s)
+{
+ if ((! s.empty()) && '!' == s.at(0))
+ {
+ if (s.length() >= 2)
+ {
+ if ('!' == s.at(1))
+ return std::make_tuple(ebk_double_bang, s.substr(0, 2), s.substr(2));
+ if ('?' == s.at(1))
+ return std::make_tuple(ebk_bang_question, s.substr(0, 2), s.substr(2));
+ }
+
+ return std::make_tuple(ebk_single_bang, s.substr(0, 1), s.substr(1));
+ }
+ else
+ return std::make_tuple(ebk_no_block, "", s);
+}
+
diff --git a/paludis/elike_blocker.hh b/paludis/elike_blocker.hh
new file mode 100644
index 0000000..c2e9506
--- /dev/null
+++ b/paludis/elike_blocker.hh
@@ -0,0 +1,25 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 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
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_ELIKE_BLOCKER_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_BLOCKER_HH 1
+
+#include <paludis/elike_blocker-fwd.hh>
+
+#endif
diff --git a/paludis/elike_blocker.se b/paludis/elike_blocker.se
new file mode 100644
index 0000000..ce86565
--- /dev/null
+++ b/paludis/elike_blocker.se
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_ELikeBlockerKind()
+{
+ prefix ebk
+
+ key ebk_no_block "No block"
+ key ebk_single_bang "Single !"
+ key ebk_double_bang "Double !!"
+ key ebk_bang_question "Synthetic !?"
+
+ want_destringify
+}
+
diff --git a/paludis/files.m4 b/paludis/files.m4
index d56179f..69ebb3b 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -33,6 +33,7 @@ add(`dep_spec_data', `hh', `cc', `fwd')
add(`dep_spec_flattener', `hh', `cc')
add(`distribution', `hh', `cc', `impl', `fwd')
add(`elf_linkage_checker', `hh', `cc')
+add(`elike_blocker', `hh', `cc', `fwd', `se')
add(`elike_choices', `hh', `cc', `fwd', `se')
add(`elike_dep_parser', `hh', `cc', `fwd', `test')
add(`elike_conditional_dep_spec', `hh', `cc', `fwd')
diff --git a/paludis/repositories/e/dep_parser.cc b/paludis/repositories/e/dep_parser.cc
index 9f37d71..878b5cc 100644
--- a/paludis/repositories/e/dep_parser.cc
+++ b/paludis/repositories/e/dep_parser.cc
@@ -48,6 +48,7 @@
#include <paludis/metadata_key.hh>
#include <paludis/package_database.hh>
#include <paludis/always_enabled_dependency_label.hh>
+#include <paludis/elike_blocker.hh>
#include <map>
#include <list>
#include <set>
@@ -123,37 +124,50 @@ namespace
const std::string & s,
const EAPI & eapi)
{
- if ((! s.empty()) && ('!' == s.at(0)))
- {
- BlockFixOp op(bfo_implicit_weak);
+ auto p(split_elike_blocker(s));
- std::string::size_type specstart(1);
- if (2 <= s.length() && '!' == s.at(1))
- {
- if (! eapi.supported()->dependency_spec_tree_parse_options()[dstpo_double_bang_blocks])
- throw EDepParseError(s, "Double-! blocks not allowed in this EAPI");
- specstart = 2;
- op = bfo_explicit_strong;
- }
- else
- {
- if (eapi.supported()->dependency_spec_tree_parse_options()[dstpo_single_bang_block_is_hard])
- op = bfo_implicit_strong;
- }
+ switch (std::get<0>(p))
+ {
+ case ebk_no_block:
+ package_dep_spec_string_handler<T_>(h, annotations_go_here, s, eapi);
+ break;
- std::shared_ptr<BlockDepSpec> spec(std::make_shared<BlockDepSpec>(
- s,
- parse_elike_package_dep_spec(s.substr(specstart),
- eapi.supported()->package_dep_spec_parse_options(),
- eapi.supported()->version_spec_options())));
- h.begin()->item()->append(spec);
- h.begin()->block_children().push_back(std::make_pair(spec, op));
- h.begin()->children().push_back(spec);
+ case ebk_bang_question:
+ throw EDepParseError(s, "!? blocks not allowed here");
+
+ case ebk_single_bang:
+ case ebk_double_bang:
+ {
+ BlockFixOp op(bfo_implicit_weak);
+
+ if (std::get<0>(p) == ebk_double_bang)
+ {
+ if (! eapi.supported()->dependency_spec_tree_parse_options()[dstpo_double_bang_blocks])
+ throw EDepParseError(s, "Double-! blocks not allowed in this EAPI");
+ op = bfo_explicit_strong;
+ }
+ else
+ {
+ if (eapi.supported()->dependency_spec_tree_parse_options()[dstpo_single_bang_block_is_hard])
+ op = bfo_implicit_strong;
+ }
+
+ std::shared_ptr<BlockDepSpec> spec(std::make_shared<BlockDepSpec>(
+ s,
+ parse_elike_package_dep_spec(std::get<2>(p),
+ eapi.supported()->package_dep_spec_parse_options(),
+ eapi.supported()->version_spec_options())));
+ h.begin()->item()->append(spec);
+ h.begin()->block_children().push_back(std::make_pair(spec, op));
+ h.begin()->children().push_back(spec);
+
+ annotations_go_here(spec);
+ }
+ break;
- annotations_go_here(spec);
+ case last_ebk:
+ throw InternalError(PALUDIS_HERE, "unhandled ebk");
}
- else
- package_dep_spec_string_handler<T_>(h, annotations_go_here, s, eapi);
}
template <typename T_>
diff --git a/paludis/resolver/spec_rewriter.cc b/paludis/resolver/spec_rewriter.cc
index 716a80e..d41bd38 100644
--- a/paludis/resolver/spec_rewriter.cc
+++ b/paludis/resolver/spec_rewriter.cc
@@ -37,6 +37,7 @@
#include <paludis/package_id.hh>
#include <paludis/metadata_key.hh>
#include <paludis/partially_made_package_dep_spec.hh>
+#include <paludis/elike_blocker.hh>
#include <map>
#include <set>
@@ -132,11 +133,8 @@ SpecRewriter::rewrite_if_special(const PackageOrBlockDepSpec & s, const std::sha
continue;
PackageDepSpec spec(PartiallyMadePackageDepSpec(s.if_block()->blocking()).package(*n));
- std::string prefix(s.if_block()->text());
- std::string::size_type p(prefix.find_first_not_of('!'));
- if (std::string::npos != p)
- prefix.erase(p);
- BlockDepSpec b(prefix + stringify(spec), spec);
+ auto p(split_elike_blocker(s.if_block()->text()));
+ BlockDepSpec b(std::get<1>(p) + stringify(spec), spec);
b.set_annotations(s.if_block()->maybe_annotations());
result->specs()->push_back(b);
}
diff --git a/src/clients/cave/cmd_execute_resolution.cc b/src/clients/cave/cmd_execute_resolution.cc
index 4e14b80..e1bdc14 100644
--- a/src/clients/cave/cmd_execute_resolution.cc
+++ b/src/clients/cave/cmd_execute_resolution.cc
@@ -79,6 +79,7 @@
#include <paludis/filtered_generator.hh>
#include <paludis/filter.hh>
#include <paludis/package_database.hh>
+#include <paludis/elike_blocker.hh>
#include <set>
#include <iterator>
@@ -658,23 +659,26 @@ namespace
a_end(cmdline.a_world_specs.end_args()) ;
a != a_end ; ++a)
{
- std::string aa(*a);
- if (aa.empty())
- continue;
-
- if ('!' == aa.at(0))
- {
- if (! removes)
- continue;
- aa.erase(0, 1);
- }
- else
+ auto p(split_elike_blocker(*a));
+ switch (std::get<0>(p))
{
- if (removes)
- continue;
+ case ebk_no_block:
+ if (removes)
+ continue;
+ break;
+
+ case ebk_single_bang:
+ case ebk_bang_question:
+ case ebk_double_bang:
+ if (! removes)
+ continue;
+ break;
+
+ case last_ebk:
+ throw InternalError(PALUDIS_HERE, "unhandled ebk");
}
- PackageDepSpec spec(parse_user_package_dep_spec(aa, env.get(), { updso_no_disambiguation }));
+ PackageDepSpec spec(parse_user_package_dep_spec(std::get<2>(p), env.get(), { updso_no_disambiguation }));
if (package_dep_spec_has_properties(spec, make_named_values<PackageDepSpecProperties>(
n::has_additional_requirements() = false,
n::has_category_name_part() = false,
diff --git a/src/clients/cave/resolve_common.cc b/src/clients/cave/resolve_common.cc
index df6193d..98d193c 100644
--- a/src/clients/cave/resolve_common.cc
+++ b/src/clients/cave/resolve_common.cc
@@ -106,6 +106,7 @@
#include <paludis/filter.hh>
#include <paludis/generator.hh>
#include <paludis/selection.hh>
+#include <paludis/elike_blocker.hh>
#include <algorithm>
#include <iostream>
@@ -147,19 +148,20 @@ namespace
std::string p_suggesion(p->first);
try
{
+ auto b(split_elike_blocker(p->first));
- if ('!' == p->first.at(0))
+ if (ebk_no_block != std::get<0>(b))
{
- p_suggesion.erase(0, 1);
+ p_suggesion = std::get<2>(b);
seen_packages = true;
- PackageDepSpec s(parse_spec_with_nice_error(p->first.substr(1), env.get(), { }, filter::All()));
+ PackageDepSpec s(parse_spec_with_nice_error(std::get<2>(b), env.get(), { }, filter::All()));
BlockDepSpec bs(make_uninstall_blocker(s));
result->push_back(stringify(bs));
resolver->add_target(bs, p->second);
}
else
{
- PackageDepSpec s(parse_spec_with_nice_error(p->first, env.get(), { updso_throw_if_set }, filter::All()));
+ PackageDepSpec s(parse_spec_with_nice_error(std::get<2>(b), env.get(), { updso_throw_if_set }, filter::All()));
result->push_back(stringify(s));
resolver->add_target(s, p->second);
seen_packages = true;