aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-05-10 10:41:11 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-05-10 10:41:11 +0000
commit52bfe9da687d079d44eca092c180f0159f1a95b8 (patch)
tree66316c086ff8653f797a5bb1035a0ca551c77257
parentc7eb0a7aabe10331f267f08e729a135180363c7b (diff)
downloadpaludis-52bfe9da687d079d44eca092c180f0159f1a95b8.tar.gz
paludis-52bfe9da687d079d44eca092c180f0159f1a95b8.tar.xz
new parser code
-rw-r--r--paludis/Makefile.am.m41
-rw-r--r--paludis/elike_conditional_dep_spec-fwd.hh (renamed from paludis/repositories/e/conditional_dep_spec.hh)24
-rw-r--r--paludis/elike_conditional_dep_spec.cc (renamed from paludis/repositories/e/conditional_dep_spec.cc)40
-rw-r--r--paludis/elike_conditional_dep_spec.hh36
-rw-r--r--paludis/elike_dep_parser-fwd.hh59
-rw-r--r--paludis/elike_dep_parser.cc154
-rw-r--r--paludis/elike_dep_parser.hh29
-rw-r--r--paludis/elike_dep_parser_TEST.cc99
-rw-r--r--paludis/elike_package_dep_spec-fwd.hh44
-rw-r--r--paludis/elike_package_dep_spec.cc (renamed from paludis/repositories/e/package_dep_spec.cc)202
-rw-r--r--paludis/elike_package_dep_spec.hh30
-rw-r--r--paludis/elike_package_dep_spec.se18
-rw-r--r--paludis/elike_slot_requirement-fwd.hh30
-rw-r--r--paludis/elike_slot_requirement.cc54
-rw-r--r--paludis/elike_slot_requirement.hh58
-rw-r--r--paludis/elike_use_requirement-fwd.hh44
-rw-r--r--paludis/elike_use_requirement.cc430
-rw-r--r--paludis/elike_use_requirement.hh36
-rw-r--r--paludis/elike_use_requirement.se11
-rw-r--r--paludis/files.m45
-rw-r--r--paludis/repositories/e/Makefile.am21
-rw-r--r--paludis/repositories/e/dep_lexer.cc114
-rw-r--r--paludis/repositories/e/dep_lexer.hh129
-rw-r--r--paludis/repositories/e/dep_lexer_TEST.cc244
-rw-r--r--paludis/repositories/e/dep_parser-fwd.hh7
-rw-r--r--paludis/repositories/e/dep_parser.cc957
-rw-r--r--paludis/repositories/e/dep_parser.hh29
-rw-r--r--paludis/repositories/e/dep_parser.se16
-rw-r--r--paludis/repositories/e/dep_parser_TEST.cc52
-rw-r--r--paludis/repositories/e/e_repository.cc12
-rw-r--r--paludis/repositories/e/e_repository_news.cc8
-rw-r--r--paludis/repositories/e/e_repository_profile.cc22
-rw-r--r--paludis/repositories/e/e_repository_sets.cc5
-rw-r--r--paludis/repositories/e/eapi-fwd.hh3
-rw-r--r--paludis/repositories/e/eapi.cc4
-rw-r--r--paludis/repositories/e/ebuild.cc1
-rw-r--r--paludis/repositories/e/fix_locked_dependencies.cc9
-rw-r--r--paludis/repositories/e/package_dep_spec.hh69
-rw-r--r--paludis/repositories/e/pipe_command_handler.cc10
-rw-r--r--paludis/repositories/e/qa/extractors.cc8
-rw-r--r--paludis/repositories/e/qa/spec_keys.cc22
-rw-r--r--paludis/repositories/e/qa/visibility.cc6
-rw-r--r--paludis/repositories/e/use_requirements.cc223
-rw-r--r--paludis/repositories/e/use_requirements.hh256
-rw-r--r--paludis/repositories/fake/Makefile.am21
-rw-r--r--paludis/repositories/fake/dep_parser.cc347
-rw-r--r--paludis/repositories/fake/dep_parser.hh77
-rw-r--r--paludis/repositories/fake/dep_parser_TEST.cc105
-rw-r--r--paludis/repositories/fake/fake_installed_repository.cc3
-rw-r--r--paludis/repositories/fake/fake_package_id.cc50
-rw-r--r--paludis/repositories/fake/fake_package_id.hh2
-rw-r--r--paludis/repositories/fake/fake_repository.cc12
-rw-r--r--paludis/repositories/fake/fake_repository.sr1
-rw-r--r--paludis/repositories/fake/fake_repository_base.cc15
-rw-r--r--paludis/repositories/fake/fake_repository_base.hh2
-rw-r--r--paludis/user_dep_spec-fwd.hh2
-rw-r--r--paludis/user_dep_spec.cc35
-rw-r--r--paludis/util/files.m41
-rw-r--r--paludis/util/keys.hh12
-rw-r--r--paludis/util/simple_parser.cc268
-rw-r--r--paludis/util/simple_parser.hh91
-rw-r--r--paludis/version_spec.cc218
62 files changed, 2675 insertions, 2218 deletions
diff --git a/paludis/Makefile.am.m4 b/paludis/Makefile.am.m4
index ebab107..22bb286 100644
--- a/paludis/Makefile.am.m4
+++ b/paludis/Makefile.am.m4
@@ -20,6 +20,7 @@ $1_TEST_LDADD = \
$(top_builddir)/paludis/util/test_extras.o \
$(top_builddir)/test/libtest.a \
$(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/e/libpaludiserepository.la \
$(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
$(top_builddir)/paludis/repositories/virtuals/libpaludisvirtualsrepository.la \
libpaludis.la \
diff --git a/paludis/repositories/e/conditional_dep_spec.hh b/paludis/elike_conditional_dep_spec-fwd.hh
index a5e567d..a37ae84 100644
--- a/paludis/repositories/e/conditional_dep_spec.hh
+++ b/paludis/elike_conditional_dep_spec-fwd.hh
@@ -17,25 +17,25 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_CONDITIONAL_DEP_SPEC_HH
-#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_CONDITIONAL_DEP_SPEC_HH 1
+#ifndef PALUDIS_GUARD_PALUDIS_ELIKE_CONDITIONAL_DEP_SPEC_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_CONDITIONAL_DEP_SPEC_FWD_HH 1
#include <paludis/dep_spec-fwd.hh>
#include <paludis/environment-fwd.hh>
-#include <paludis/name-fwd.hh>
#include <paludis/package_id-fwd.hh>
-#include <paludis/repositories/e/eapi-fwd.hh>
+#include <paludis/name-fwd.hh>
+#include <string>
namespace paludis
{
- namespace erepository
- {
- ConditionalDepSpec parse_e_conditional_dep_spec(const std::string &,
- const Environment * const, const std::tr1::shared_ptr<const PackageID> &, const EAPI &) PALUDIS_VISIBLE;
-
- UseFlagName conditional_dep_spec_flag(const ConditionalDepSpec &) PALUDIS_VISIBLE;
- bool conditional_dep_spec_is_inverse(const ConditionalDepSpec &) PALUDIS_VISIBLE;
- }
+ class ELikeConditionalDepSpecParseError;
+
+ ConditionalDepSpec parse_elike_conditional_dep_spec(const std::string &,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+
+ bool elike_conditional_dep_spec_is_inverse(const ConditionalDepSpec & spec) PALUDIS_VISIBLE;
+
+ UseFlagName elike_conditional_dep_spec_flag(const ConditionalDepSpec & spec) PALUDIS_VISIBLE;
}
#endif
diff --git a/paludis/repositories/e/conditional_dep_spec.cc b/paludis/elike_conditional_dep_spec.cc
index e716d46..d369085 100644
--- a/paludis/repositories/e/conditional_dep_spec.cc
+++ b/paludis/elike_conditional_dep_spec.cc
@@ -17,23 +17,30 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/repositories/e/conditional_dep_spec.hh>
-#include <paludis/repositories/e/dep_parser.hh>
-#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
+#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
-#include <paludis/util/log.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/visitor_cast.hh>
#include <paludis/util/destringify.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/name.hh>
+#include <paludis/literal_metadata_key.hh>
#include <paludis/environment.hh>
#include <paludis/package_id.hh>
-#include <paludis/dep_spec.hh>
#include <paludis/repository.hh>
-#include <paludis/literal_metadata_key.hh>
-#include <paludis/metadata_key_holder.hh>
+#include <ostream>
+#include <string>
using namespace paludis;
-using namespace paludis::erepository;
+
+ELikeConditionalDepSpecParseError::ELikeConditionalDepSpecParseError(const std::string & s, const std::string & m) throw () :
+ Exception("Error parsing conditional dep spec '" + s + "': " + m)
+{
+}
namespace
{
@@ -52,18 +59,15 @@ namespace
env(e),
id(i)
{
- if (! i)
- Log::get_instance()->message("e.conditional_dep_spec.no_id", ll_warning, lc_context) << "! i";
-
if (s.empty())
- throw DepStringParseError(s, "missing use flag name");
+ throw ELikeConditionalDepSpecParseError(s, "missing use flag name");
if (s.at(s.length() - 1) != '?')
- throw DepStringParseError(s, "missing ? on use conditional");
+ throw ELikeConditionalDepSpecParseError(s, "missing ? on use conditional");
inverse = '!' == s.at(0);
if (s.length() < (inverse ? 3 : 2))
- throw DepStringParseError(s, "missing flag name on use conditional");
+ throw ELikeConditionalDepSpecParseError(s, "missing flag name on use conditional");
flag = UseFlagName(s.substr(inverse ? 1 : 0, s.length() - (inverse ? 2 : 1)));
@@ -106,14 +110,14 @@ namespace
}
ConditionalDepSpec
-paludis::erepository::parse_e_conditional_dep_spec(const std::string & s,
- const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI &)
+paludis::parse_elike_conditional_dep_spec(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
{
return ConditionalDepSpec(make_shared_ptr(new EConditionalDepSpecData(s, env, id)));
}
UseFlagName
-paludis::erepository::conditional_dep_spec_flag(const ConditionalDepSpec & spec)
+paludis::elike_conditional_dep_spec_flag(const ConditionalDepSpec & spec)
{
ConditionalDepSpec::MetadataConstIterator i(spec.find_metadata("Flag"));
if (i == spec.end_metadata())
@@ -125,7 +129,7 @@ paludis::erepository::conditional_dep_spec_flag(const ConditionalDepSpec & spec)
}
bool
-paludis::erepository::conditional_dep_spec_is_inverse(const ConditionalDepSpec & spec)
+paludis::elike_conditional_dep_spec_is_inverse(const ConditionalDepSpec & spec)
{
ConditionalDepSpec::MetadataConstIterator i(spec.find_metadata("Inverse"));
if (i == spec.end_metadata())
diff --git a/paludis/elike_conditional_dep_spec.hh b/paludis/elike_conditional_dep_spec.hh
new file mode 100644
index 0000000..37ea34c
--- /dev/null
+++ b/paludis/elike_conditional_dep_spec.hh
@@ -0,0 +1,36 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_CONDITIONAL_DEP_SPEC_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_CONDITIONAL_DEP_SPEC_HH 1
+
+#include <paludis/elike_conditional_dep_spec-fwd.hh>
+#include <paludis/util/exception.hh>
+
+namespace paludis
+{
+ class ELikeConditionalDepSpecParseError :
+ public Exception
+ {
+ public:
+ ELikeConditionalDepSpecParseError(const std::string &, const std::string &) throw ();
+ };
+}
+
+#endif
diff --git a/paludis/elike_dep_parser-fwd.hh b/paludis/elike_dep_parser-fwd.hh
new file mode 100644
index 0000000..1ff49a6
--- /dev/null
+++ b/paludis/elike_dep_parser-fwd.hh
@@ -0,0 +1,59 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_DEP_PARSER_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_DEP_PARSER_FWD_HH 1
+
+#include <paludis/util/kc-fwd.hh>
+#include <paludis/util/keys.hh>
+#include <paludis/util/attributes.hh>
+#include <paludis/name-fwd.hh>
+#include <tr1/functional>
+
+namespace paludis
+{
+ typedef std::tr1::function<void (const std::string &)> ELikeDepParserStringFunction;
+ typedef std::tr1::function<void (const std::string &, const std::string &)> ELikeDepParserArrowFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserAnyFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserAllFunction;
+ typedef std::tr1::function<void (const std::string &)> ELikeDepParserUseFunction;
+ typedef std::tr1::function<void (const std::string &)> ELikeDepParserLabelFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserPushFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserPopFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserShouldBeEmptyFunction;
+ typedef std::tr1::function<void (const std::string &, const std::string::size_type &, const std::string &)> ELikeDepParserErrorFunction;
+ typedef std::tr1::function<void ()> ELikeDepParserUseUnderAnyFunction;
+
+ typedef kc::KeyedClass<
+ kc::Field<k::on_string, ELikeDepParserStringFunction>,
+ kc::Field<k::on_arrow, ELikeDepParserArrowFunction>,
+ kc::Field<k::on_any, ELikeDepParserAnyFunction>,
+ kc::Field<k::on_all, ELikeDepParserAllFunction>,
+ kc::Field<k::on_use, ELikeDepParserUseFunction>,
+ kc::Field<k::on_label, ELikeDepParserLabelFunction>,
+ kc::Field<k::on_pop, ELikeDepParserPopFunction>,
+ kc::Field<k::on_error, ELikeDepParserErrorFunction>,
+ kc::Field<k::on_should_be_empty, ELikeDepParserShouldBeEmptyFunction>,
+ kc::Field<k::on_use_under_any, ELikeDepParserUseUnderAnyFunction>
+ > ELikeDepParserCallbacks;
+
+ void parse_elike_dependencies(const std::string &, const ELikeDepParserCallbacks & callbacks) PALUDIS_VISIBLE;
+}
+
+#endif
diff --git a/paludis/elike_dep_parser.cc b/paludis/elike_dep_parser.cc
new file mode 100644
index 0000000..4c794ba
--- /dev/null
+++ b/paludis/elike_dep_parser.cc
@@ -0,0 +1,154 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_dep_parser.hh>
+#include <paludis/util/simple_parser.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/exception.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/name.hh>
+
+using namespace paludis;
+
+namespace
+{
+ void error(const SimpleParser &, const ELikeDepParserCallbacks &, const std::string &) PALUDIS_ATTRIBUTE((noreturn));
+
+ void error(const SimpleParser & parser, const ELikeDepParserCallbacks & callbacks, const std::string & msg)
+ {
+ callbacks[k::on_error()](parser.text(), parser.offset(), msg);
+ throw InternalError(PALUDIS_HERE, "Got error '" + msg + "' parsing '" + parser.text() +
+ "', but the error function returned");
+ }
+
+ void
+ parse(SimpleParser & parser, const ELikeDepParserCallbacks & callbacks, const bool end_with_close_paren,
+ const bool child_of_any)
+ {
+ while (true)
+ {
+ Context context("When parsing from offset '" + stringify(parser.offset()) + "':");
+ std::string word;
+
+ if (parser.eof())
+ {
+ if (end_with_close_paren)
+ error(parser, callbacks, "Reached end of text but wanted ')'");
+ else
+ return;
+ }
+ else if (parser.consume(simple_parser::exact("(")))
+ {
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after '('");
+
+ callbacks[k::on_all()]();
+ parse(parser, callbacks, true, false);
+ }
+ else if (parser.consume(+simple_parser::any_of(" \t\r\n")))
+ {
+ /* discard whitespace */
+ }
+ else if (parser.consume(simple_parser::exact(")")))
+ {
+ if (end_with_close_paren)
+ {
+ if (! parser.eof())
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space or end of text after ')'");
+ callbacks[k::on_pop()]();
+ return;
+ }
+ else
+ error(parser, callbacks, "Got ')' but expected end of text");
+ }
+ else if (parser.consume(simple_parser::exact("->")))
+ {
+ error(parser, callbacks, "Can't have '->' here");
+ }
+ else if (parser.consume(simple_parser::exact("||")))
+ {
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after '||'");
+
+ if (! parser.consume(simple_parser::exact("(")))
+ error(parser, callbacks, "Expected '(' after '||' then space");
+
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after '|| ('");
+
+ callbacks[k::on_any()]();
+ parse(parser, callbacks, true, true);
+ }
+ else if (parser.consume(+simple_parser::any_except(" \t\r\n") >> word))
+ {
+ if ('?' == word.at(word.length() - 1))
+ {
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after 'use?'");
+
+ if (! parser.consume(simple_parser::exact("(")))
+ error(parser, callbacks, "Expected '(' after 'use?' then space");
+
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after 'use? ('");
+
+ if (child_of_any)
+ callbacks[k::on_use_under_any()]();
+
+ callbacks[k::on_use()](word);
+ parse(parser, callbacks, true, false);
+ }
+ else if (':' == word.at(word.length() - 1))
+ {
+ callbacks[k::on_label()](word);
+ }
+ else if (parser.consume(+simple_parser::any_of(" \t\r\n") & simple_parser::exact("->")))
+ {
+ if (! parser.consume(+simple_parser::any_of(" \t\r\n")))
+ error(parser, callbacks, "Expected space after '->'");
+
+ std::string second;
+ if (! parser.consume(+simple_parser::any_except(" \t\r\n") >> second))
+ error(parser, callbacks, "Expected word after '->' then space");
+
+ if ("->" == second || "||" == second || "(" == second || ")" == second)
+ error(parser, callbacks, "Expected word after '->' then space");
+
+ callbacks[k::on_arrow()](word, second);
+ }
+ else
+ callbacks[k::on_string()](word);
+ }
+ else
+ error(parser, callbacks, "Unexpected trailing text");
+ }
+ }
+}
+
+void
+paludis::parse_elike_dependencies(const std::string & s, const ELikeDepParserCallbacks & callbacks)
+{
+ Context context("When parsing '" + s + "':");
+
+ SimpleParser parser(s);
+ parse(parser, callbacks, false, false);
+ callbacks[k::on_should_be_empty()]();
+}
+
diff --git a/paludis/elike_dep_parser.hh b/paludis/elike_dep_parser.hh
new file mode 100644
index 0000000..08b6b24
--- /dev/null
+++ b/paludis/elike_dep_parser.hh
@@ -0,0 +1,29 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_DEP_PARSER_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_DEP_PARSER_HH 1
+
+#include <paludis/elike_dep_parser-fwd.hh>
+
+namespace paludis
+{
+}
+
+#endif
diff --git a/paludis/elike_dep_parser_TEST.cc b/paludis/elike_dep_parser_TEST.cc
new file mode 100644
index 0000000..3852927
--- /dev/null
+++ b/paludis/elike_dep_parser_TEST.cc
@@ -0,0 +1,99 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_dep_parser.hh>
+#include <paludis/util/kc.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ void handler(std::string & s, const std::string & a1, const std::string & a2, const std::string & a3,
+ const std::string & a4, const std::string & a5)
+ {
+ s.append(a1);
+ s.append(a2);
+ s.append(a3);
+ s.append(a4);
+ s.append(a5);
+ }
+
+ void do_nothing()
+ {
+ }
+}
+
+namespace test_cases
+{
+ struct ELikeDepParserBasicTest : TestCase
+ {
+ ELikeDepParserBasicTest() : TestCase("basic") { }
+
+ void run()
+ {
+ using namespace std::tr1::placeholders;
+
+ std::string in("|| ( a b ( c d e ) )"), out;
+ ELikeDepParserCallbacks callbacks(ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&handler, std::tr1::ref(out), "s<", _1, ">", "", ""))
+ (k::on_arrow(), std::tr1::bind(&handler, std::tr1::ref(out), "a<", _1, ", ", _2, ">"))
+ (k::on_any(), std::tr1::bind(&handler, std::tr1::ref(out), "any<", "", "", "", ""))
+ (k::on_all(), std::tr1::bind(&handler, std::tr1::ref(out), "all<", "", "", "", ""))
+ (k::on_use(), std::tr1::bind(&handler, std::tr1::ref(out), "use<", _1, ", ", "", ""))
+ (k::on_label(), std::tr1::bind(&handler, std::tr1::ref(out), "label<", _1, "", "", ""))
+ (k::on_pop(), std::tr1::bind(&handler, std::tr1::ref(out), ">", "", "", "", ""))
+ (k::on_error(), std::tr1::bind(&handler, std::tr1::ref(out), "error<", _1, ">", "", ""))
+ (k::on_should_be_empty(), std::tr1::bind(&handler, std::tr1::ref(out), "EMPTY", "", "", "", ""))
+ (k::on_use_under_any(), &do_nothing)
+ );
+ parse_elike_dependencies(in, callbacks);
+ TEST_CHECK_EQUAL(out, "any<s<a>s<b>all<s<c>s<d>s<e>>>EMPTY");
+ }
+ } elike_dep_parser_basic_test;
+
+ struct ELikeDepParserEmptyBlocksTest : TestCase
+ {
+ ELikeDepParserEmptyBlocksTest() : TestCase("empty blocks") { }
+
+ void run()
+ {
+ using namespace std::tr1::placeholders;
+
+ std::string in("( ( ) )"), out;
+ ELikeDepParserCallbacks callbacks(ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&handler, std::tr1::ref(out), "s<", _1, ">", "", ""))
+ (k::on_arrow(), std::tr1::bind(&handler, std::tr1::ref(out), "a<", _1, ", ", _2, ">"))
+ (k::on_any(), std::tr1::bind(&handler, std::tr1::ref(out), "any<", "", "", "", ""))
+ (k::on_all(), std::tr1::bind(&handler, std::tr1::ref(out), "all<", "", "", "", ""))
+ (k::on_use(), std::tr1::bind(&handler, std::tr1::ref(out), "use<", _1, ", ", "", ""))
+ (k::on_label(), std::tr1::bind(&handler, std::tr1::ref(out), "label<", _1, "", "", ""))
+ (k::on_pop(), std::tr1::bind(&handler, std::tr1::ref(out), ">", "", "", "", ""))
+ (k::on_error(), std::tr1::bind(&handler, std::tr1::ref(out), "error<", _1, ">", "", ""))
+ (k::on_should_be_empty(), std::tr1::bind(&handler, std::tr1::ref(out), "EMPTY", "", "", "", ""))
+ (k::on_use_under_any(), &do_nothing)
+ );
+ parse_elike_dependencies(in, callbacks);
+ TEST_CHECK_EQUAL(out, "all<all<>>EMPTY");
+ }
+ } elike_dep_parser_test_empty_blocks;
+}
+
diff --git a/paludis/elike_package_dep_spec-fwd.hh b/paludis/elike_package_dep_spec-fwd.hh
new file mode 100644
index 0000000..2c05fbe
--- /dev/null
+++ b/paludis/elike_package_dep_spec-fwd.hh
@@ -0,0 +1,44 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_PACKAGE_DEP_SPEC_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_PACKAGE_DEP_SPEC_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/options-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <tr1/functional>
+#include <iosfwd>
+
+namespace paludis
+{
+
+#include <paludis/elike_package_dep_spec-se.hh>
+
+ typedef Options<ELikePackageDepSpecOption> ELikePackageDepSpecOptions;
+
+ PackageDepSpec parse_elike_package_dep_spec(const std::string &, const ELikePackageDepSpecOptions &,
+ const std::tr1::shared_ptr<const PackageID> &) PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;
+
+ PartiallyMadePackageDepSpec partial_parse_elike_package_dep_spec(const std::string &, const ELikePackageDepSpecOptions &,
+ const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+}
+
+#endif
diff --git a/paludis/repositories/e/package_dep_spec.cc b/paludis/elike_package_dep_spec.cc
index 61f9b74..ed81186 100644
--- a/paludis/repositories/e/package_dep_spec.cc
+++ b/paludis/elike_package_dep_spec.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007, 2008 Ciaran McCreesh
+ * Copyright (c) 2008 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
@@ -17,35 +17,30 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/repositories/e/package_dep_spec.hh>
-#include <paludis/repositories/e/eapi.hh>
-#include <paludis/repositories/e/use_requirements.hh>
-#include <paludis/util/stringify.hh>
+#include <paludis/elike_package_dep_spec.hh>
+#include <paludis/elike_use_requirement.hh>
+#include <paludis/elike_slot_requirement.hh>
+#include <paludis/util/options.hh>
#include <paludis/util/log.hh>
-#include <paludis/util/kc.hh>
#include <paludis/util/make_shared_ptr.hh>
-#include <paludis/util/visitor-impl.hh>
#include <paludis/dep_spec.hh>
#include <paludis/version_operator.hh>
#include <paludis/version_spec.hh>
#include <paludis/version_requirements.hh>
-#include <tr1/memory>
using namespace paludis;
-using namespace paludis::erepository;
+
+#include <paludis/elike_package_dep_spec-se.cc>
PartiallyMadePackageDepSpec
-paludis::erepository::partial_parse_e_package_dep_spec(
- const std::string & ss, const EAPI & eapi, const std::tr1::shared_ptr<const PackageID> & id)
+paludis::partial_parse_elike_package_dep_spec(
+ const std::string & ss, const ELikePackageDepSpecOptions & options, const std::tr1::shared_ptr<const PackageID> & id)
{
- Context context("When parsing package dep spec '" + ss + "' with eapi '" + stringify(eapi[k::name()]) + "':");
+ Context context("When parsing package dep spec '" + ss + "':");
if (ss.empty())
throw PackageDepSpecError("Got empty dep spec");
- if (! eapi[k::supported()])
- throw PackageDepSpecError("Don't know how to parse dep specs using EAPI '" + eapi[k::name()] + "'");
-
PartiallyMadePackageDepSpec result;
std::string s(ss);
bool had_bracket_version_requirements(false);
@@ -53,13 +48,13 @@ paludis::erepository::partial_parse_e_package_dep_spec(
std::string::size_type use_group_p;
while (std::string::npos != ((use_group_p = s.rfind('['))))
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_square_bracket_deps])
+ if (! options[epdso_allow_square_bracket_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("[] dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("[] dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.brackets_not_allowed", ll_warning, lc_context)
- << "[] dependencies not safe for use with this EAPI";
+ << "[] dependencies not safe for use here";
}
if (s.at(s.length() - 1) != ']')
@@ -140,74 +135,8 @@ paludis::erepository::partial_parse_e_package_dep_spec(
default:
{
- std::string raw_flag("[" + flag + "]");
-
- std::tr1::shared_ptr<const AdditionalPackageDepSpecRequirement> req;
- if ('=' == flag.at(flag.length() - 1))
- {
- if (! id)
- throw PackageDepSpecError("Cannot use [use=] without an associated ID");
-
- flag.erase(flag.length() - 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
- if ('!' == flag.at(flag.length() - 1))
- {
- flag.erase(flag.length() - 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
- req.reset(new NotEqualUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- else
- req.reset(new EqualUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- else if ('?' == flag.at(flag.length() - 1))
- {
- if (! id)
- throw PackageDepSpecError("Cannot use [use?] without an associated ID");
-
- flag.erase(flag.length() - 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
- if ('!' == flag.at(flag.length() - 1))
- {
- flag.erase(flag.length() - 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
- if ('-' == flag.at(0))
- {
- flag.erase(0, 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
-
- req.reset(new IfNotMineThenNotUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- else
- req.reset(new IfNotMineThenUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- else
- {
- if ('-' == flag.at(0))
- {
- flag.erase(0, 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
-
- req.reset(new IfMineThenNotUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- else
- req.reset(new IfMineThenUseRequirement(raw_flag, UseFlagName(flag), id));
- }
- }
- else if ('-' == flag.at(0))
- {
- flag.erase(0, 1);
- if (flag.empty())
- throw PackageDepSpecError("Invalid [] contents");
- req.reset(new DisabledUseRequirement(raw_flag, UseFlagName(flag)));
- }
- else
- req.reset(new EnabledUseRequirement(raw_flag, UseFlagName(flag)));
+ std::tr1::shared_ptr<const AdditionalPackageDepSpecRequirement> req(parse_elike_use_requirement(flag,
+ id, ELikeUseRequirementOptions() + euro_allow_self_deps));
result.additional_requirement(req);
}
break;
@@ -219,13 +148,13 @@ paludis::erepository::partial_parse_e_package_dep_spec(
std::string::size_type repo_p;
if (std::string::npos != ((repo_p = s.rfind("::"))))
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_repository_deps])
+ if (! options[epdso_allow_repository_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("Repository dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("Repository dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.repository_not_allowed", ll_warning, lc_context)
- << "Repository dependencies not safe for use with this EAPI";
+ << "Repository dependencies not safe for use here";
}
result.repository(RepositoryName(s.substr(repo_p + 2)));
@@ -241,43 +170,43 @@ paludis::erepository::partial_parse_e_package_dep_spec(
if ("*" == match)
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_slot_star_deps])
+ if (! options[epdso_allow_slot_star_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("Slot '*' dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("Slot '*' dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.slot_star_not_allowed", ll_warning, lc_context)
- << "Slot '*' dependencies not safe for use with this EAPI";
+ << "Slot '*' dependencies not safe for use here";
}
- result.slot_requirement(make_shared_ptr(new ESlotAnyUnlockedRequirement));
+ result.slot_requirement(make_shared_ptr(new ELikeSlotAnyUnlockedRequirement));
}
else if ('=' == match.at(0))
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_slot_equal_deps])
+ if (! options[epdso_allow_slot_equal_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("Slot '=' dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("Slot '=' dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.slot_equals_not_allowed", ll_warning, lc_context)
- << "Slot '=' dependencies not safe for use with this EAPI";
+ << "Slot '=' dependencies not safe for use here";
}
if (1 == match.length())
- result.slot_requirement(make_shared_ptr(new ESlotAnyLockedRequirement));
+ result.slot_requirement(make_shared_ptr(new ELikeSlotAnyLockedRequirement));
else
- result.slot_requirement(make_shared_ptr(new ESlotExactRequirement(SlotName(s.substr(slot_p + 2)), true)));
+ result.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(SlotName(s.substr(slot_p + 2)), true)));
}
else
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_slot_deps])
+ if (! options[epdso_allow_slot_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("Slot dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("Slot dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.slot_not_allowed", ll_warning, lc_context)
- << "Slot dependencies not safe for use with this EAPI";
+ << "Slot dependencies not safe for use here";
}
- result.slot_requirement(make_shared_ptr(new ESlotExactRequirement(SlotName(s.substr(slot_p + 1)), false)));
+ result.slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement(SlotName(s.substr(slot_p + 1)), false)));
}
s.erase(slot_p);
}
@@ -293,13 +222,13 @@ paludis::erepository::partial_parse_e_package_dep_spec(
VersionOperator op(s.substr(0, p));
if (op == vo_tilde_greater)
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_allow_tilde_greater_deps])
+ if (! options[epdso_allow_tilde_greater_deps])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
- throw PackageDepSpecError("~> dependencies not safe for use with this EAPI");
+ if (options[epdso_strict_parsing])
+ throw PackageDepSpecError("~> dependencies not safe for use here");
else
Log::get_instance()->message("e.package_dep_spec.tilde_greater_not_allowed", ll_warning, lc_context)
- << "~> dependencies not safe for use with this EAPI";
+ << "~> dependencies not safe for use here";
}
std::string::size_type q(p);
@@ -330,16 +259,14 @@ paludis::erepository::partial_parse_e_package_dep_spec(
std::string t(s.substr(p, q - p - 1));
if (t.length() >= 3 && (0 == t.compare(0, 2, "*/")))
{
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "' with eapi '"
- + stringify(eapi[k::name()]) + "'");
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
if (0 != t.compare(t.length() - 2, 2, "/*"))
result.package_name_part(PackageNamePart(t.substr(2)));
}
else if (t.length() >= 3 && (0 == t.compare(t.length() - 2, 2, "/*")))
{
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "' with eapi '"
- + stringify(eapi[k::name()]) + "'");
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
result.category_name_part(CategoryNamePart(t.substr(0, t.length() - 2)));
}
@@ -350,9 +277,9 @@ paludis::erepository::partial_parse_e_package_dep_spec(
{
if (op != vo_equal)
{
- if (! (*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_star_operator])
+ if (! options[epdso_strict_star_operator])
{
- if ((*eapi[k::supported()])[k::package_dep_spec_parse_options()][pdspo_strict_parsing])
+ if (options[epdso_strict_parsing])
throw PackageDepSpecError(
"Package dep spec '" + ss + "' uses * "
"with operator '" + stringify(op) + "'");
@@ -373,16 +300,14 @@ paludis::erepository::partial_parse_e_package_dep_spec(
{
if (s.length() >= 3 && (0 == s.compare(0, 2, "*/")))
{
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "' with parse eapi '"
- + stringify(eapi[k::name()]) + "'");
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
if (0 != s.compare(s.length() - 2, 2, "/*"))
result.package_name_part(PackageNamePart(s.substr(2)));
}
else if (s.length() >= 3 && (0 == s.compare(s.length() - 2, 2, "/*")))
{
- throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "' with EAPI '"
- + stringify(eapi[k::name()]) + "'");
+ throw PackageDepSpecError("Wildcard '*' not allowed in '" + stringify(ss) + "'");
result.category_name_part(CategoryNamePart(s.substr(0, s.length() - 2)));
}
@@ -394,38 +319,9 @@ paludis::erepository::partial_parse_e_package_dep_spec(
}
PackageDepSpec
-paludis::erepository::parse_e_package_dep_spec(const std::string & ss, const EAPI & eapi, const std::tr1::shared_ptr<const PackageID> & id)
-{
- return partial_parse_e_package_dep_spec(ss, eapi, id);
-}
-
-ESlotExactRequirement::ESlotExactRequirement(const SlotName & s, const bool e) :
- _s(s),
- _e(e)
-{
-}
-
-const std::string
-ESlotExactRequirement::as_string() const
-{
- return ":" + std::string(_e ? "=" : "") + stringify(_s);
-}
-
-const SlotName
-ESlotExactRequirement::slot() const
-{
- return _s;
-}
-
-const std::string
-ESlotAnyUnlockedRequirement::as_string() const
-{
- return ":*";
-}
-
-const std::string
-ESlotAnyLockedRequirement::as_string() const
+paludis::parse_elike_package_dep_spec(const std::string & ss, const ELikePackageDepSpecOptions & options,
+ const std::tr1::shared_ptr<const PackageID> & id)
{
- return ":=";
+ return partial_parse_elike_package_dep_spec(ss, options, id);
}
diff --git a/paludis/elike_package_dep_spec.hh b/paludis/elike_package_dep_spec.hh
new file mode 100644
index 0000000..2186d41
--- /dev/null
+++ b/paludis/elike_package_dep_spec.hh
@@ -0,0 +1,30 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_PACKAGE_DEP_SPEC_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_PACKAGE_DEP_SPEC_HH 1
+
+#include <paludis/elike_package_dep_spec-fwd.hh>
+
+namespace paludis
+{
+
+}
+
+#endif
diff --git a/paludis/elike_package_dep_spec.se b/paludis/elike_package_dep_spec.se
new file mode 100644
index 0000000..7e8734a
--- /dev/null
+++ b/paludis/elike_package_dep_spec.se
@@ -0,0 +1,18 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_ELikePackageDepSpecOption()
+{
+ prefix epdso
+ want_destringify
+
+ key epdso_allow_slot_deps "Allow :slot deps"
+ key epdso_allow_slot_star_deps "Allow :* slot deps"
+ key epdso_allow_slot_equal_deps "Allow := and :=blah slot deps"
+ key epdso_allow_repository_deps "Allow ::repo deps"
+ key epdso_allow_square_bracket_deps "Allow [use] and [opver] deps"
+ key epdso_allow_tilde_greater_deps "Allow ~> deps"
+ key epdso_strict_star_operator "* with an operator other than = is an error"
+ key epdso_strict_parsing "Error rather than warn for violations"
+}
+
diff --git a/paludis/elike_slot_requirement-fwd.hh b/paludis/elike_slot_requirement-fwd.hh
new file mode 100644
index 0000000..9ec1513
--- /dev/null
+++ b/paludis/elike_slot_requirement-fwd.hh
@@ -0,0 +1,30 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_SLOT_REQUIREMENT_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_SLOT_REQUIREMENT_FWD_HH 1
+
+namespace paludis
+{
+ class ELikeSlotExactRequirement;
+ class ELikeSlotAnyLockedRequirement;
+ class ELikeSlotAnyUnlockedRequirement;
+}
+
+#endif
diff --git a/paludis/elike_slot_requirement.cc b/paludis/elike_slot_requirement.cc
new file mode 100644
index 0000000..ea52fe4
--- /dev/null
+++ b/paludis/elike_slot_requirement.cc
@@ -0,0 +1,54 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_slot_requirement.hh>
+#include <paludis/util/stringify.hh>
+
+using namespace paludis;
+
+ELikeSlotExactRequirement::ELikeSlotExactRequirement(const SlotName & s, const bool e) :
+ _s(s),
+ _e(e)
+{
+}
+
+const std::string
+ELikeSlotExactRequirement::as_string() const
+{
+ return ":" + std::string(_e ? "=" : "") + stringify(_s);
+}
+
+const SlotName
+ELikeSlotExactRequirement::slot() const
+{
+ return _s;
+}
+
+const std::string
+ELikeSlotAnyUnlockedRequirement::as_string() const
+{
+ return ":*";
+}
+
+const std::string
+ELikeSlotAnyLockedRequirement::as_string() const
+{
+ return ":=";
+}
+
diff --git a/paludis/elike_slot_requirement.hh b/paludis/elike_slot_requirement.hh
new file mode 100644
index 0000000..ad33609
--- /dev/null
+++ b/paludis/elike_slot_requirement.hh
@@ -0,0 +1,58 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_SLOT_REQUIREMENT_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_SLOT_REQUIREMENT_HH 1
+
+#include <paludis/elike_slot_requirement-fwd.hh>
+#include <paludis/slot_requirement.hh>
+#include <paludis/name.hh>
+
+namespace paludis
+{
+ class PALUDIS_VISIBLE ELikeSlotExactRequirement :
+ public SlotExactRequirement
+ {
+ private:
+ const SlotName _s;
+ const bool _e;
+
+ public:
+ ELikeSlotExactRequirement(const SlotName &, const bool equals);
+
+ virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const SlotName slot() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE ELikeSlotAnyUnlockedRequirement :
+ public SlotAnyUnlockedRequirement
+ {
+ public:
+ virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE ELikeSlotAnyLockedRequirement :
+ public SlotAnyLockedRequirement
+ {
+ public:
+ virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+}
+
+#endif
diff --git a/paludis/elike_use_requirement-fwd.hh b/paludis/elike_use_requirement-fwd.hh
new file mode 100644
index 0000000..a0b3802
--- /dev/null
+++ b/paludis/elike_use_requirement-fwd.hh
@@ -0,0 +1,44 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_USE_REQUIREMENT_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_USE_REQUIREMENT_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/options-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/dep_spec-fwd.hh>
+#include <iosfwd>
+#include <string>
+#include <tr1/functional>
+
+namespace paludis
+{
+ class ELikeUseRequirementError;
+
+#include <paludis/elike_use_requirement-se.hh>
+
+ typedef Options<ELikeUseRequirementOption> ELikeUseRequirementOptions;
+
+ std::tr1::shared_ptr<const AdditionalPackageDepSpecRequirement> parse_elike_use_requirement(
+ const std::string &, const std::tr1::shared_ptr<const PackageID> &, const ELikeUseRequirementOptions &)
+ PALUDIS_ATTRIBUTE((warn_unused_result)) PALUDIS_VISIBLE;;
+}
+
+#endif
diff --git a/paludis/elike_use_requirement.cc b/paludis/elike_use_requirement.cc
new file mode 100644
index 0000000..5b9c34b
--- /dev/null
+++ b/paludis/elike_use_requirement.cc
@@ -0,0 +1,430 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_use_requirement.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/name.hh>
+#include <paludis/environment.hh>
+
+using namespace paludis;
+
+namespace
+{
+ class PALUDIS_VISIBLE UseRequirement :
+ public AdditionalPackageDepSpecRequirement
+ {
+ private:
+ const std::string _raw;
+ const UseFlagName _name;
+
+ public:
+ UseRequirement(const std::string &, const UseFlagName &);
+
+ const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _name;
+ }
+
+ virtual const std::string as_raw_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE EnabledUseRequirement :
+ public UseRequirement
+ {
+ public:
+ EnabledUseRequirement(const std::string &, const UseFlagName &);
+ ~EnabledUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE DisabledUseRequirement :
+ public UseRequirement
+ {
+ public:
+ DisabledUseRequirement(const std::string &, const UseFlagName &);
+ ~DisabledUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE ConditionalUseRequirement :
+ public UseRequirement
+ {
+ private:
+ const std::tr1::shared_ptr<const PackageID> _id;
+
+ public:
+ ConditionalUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~ConditionalUseRequirement();
+
+ const std::tr1::shared_ptr<const PackageID> package_id() const PALUDIS_ATTRIBUTE((warn_unused_result))
+ {
+ return _id;
+ }
+ };
+
+ class PALUDIS_VISIBLE IfMineThenUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ IfMineThenUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~IfMineThenUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE IfNotMineThenUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ IfNotMineThenUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~IfNotMineThenUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE IfMineThenNotUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ IfMineThenNotUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~IfMineThenNotUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE IfNotMineThenNotUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ IfNotMineThenNotUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~IfNotMineThenNotUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE EqualUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ EqualUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~EqualUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PALUDIS_VISIBLE NotEqualUseRequirement :
+ public ConditionalUseRequirement
+ {
+ public:
+ NotEqualUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
+ ~NotEqualUseRequirement();
+
+ virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+}
+
+UseRequirement::UseRequirement(const std::string & r, const UseFlagName & f) :
+ _raw(r),
+ _name(f)
+{
+}
+
+const std::string
+UseRequirement::as_raw_string() const
+{
+ return _raw;
+}
+
+EnabledUseRequirement::EnabledUseRequirement(const std::string & s, const UseFlagName & n) :
+ UseRequirement(s, n)
+{
+}
+
+EnabledUseRequirement::~EnabledUseRequirement()
+{
+}
+
+bool
+EnabledUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), pkg);
+}
+
+const std::string
+EnabledUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' enabled";
+}
+
+DisabledUseRequirement::DisabledUseRequirement(const std::string & s, const UseFlagName & n) :
+ UseRequirement(s, n)
+{
+}
+
+DisabledUseRequirement::~DisabledUseRequirement()
+{
+}
+
+bool
+DisabledUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return ! env->query_use(flag(), pkg);
+}
+
+const std::string
+DisabledUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' disabled";
+}
+
+ConditionalUseRequirement::ConditionalUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ UseRequirement(s, n),
+ _id(i)
+{
+}
+
+ConditionalUseRequirement::~ConditionalUseRequirement()
+{
+}
+
+IfMineThenUseRequirement::IfMineThenUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+IfMineThenUseRequirement::~IfMineThenUseRequirement()
+{
+}
+
+bool
+IfMineThenUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return ! env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
+}
+
+const std::string
+IfMineThenUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' enabled if it is enabled for '" + stringify(*package_id()) + "'";
+}
+
+IfNotMineThenUseRequirement::IfNotMineThenUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+IfNotMineThenUseRequirement::~IfNotMineThenUseRequirement()
+{
+}
+
+bool
+IfNotMineThenUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
+}
+
+const std::string
+IfNotMineThenUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' enabled if it is disabled for '" + stringify(*package_id()) + "'";
+}
+
+IfMineThenNotUseRequirement::IfMineThenNotUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+IfMineThenNotUseRequirement::~IfMineThenNotUseRequirement()
+{
+}
+
+const std::string
+IfMineThenNotUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' disabled if it is enabled for '" + stringify(*package_id()) + "'";
+}
+
+bool
+IfMineThenNotUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return ! env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
+}
+
+IfNotMineThenNotUseRequirement::IfNotMineThenNotUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+IfNotMineThenNotUseRequirement::~IfNotMineThenNotUseRequirement()
+{
+}
+
+bool
+IfNotMineThenNotUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
+}
+
+const std::string
+IfNotMineThenNotUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' disabled if it is disabled for '" + stringify(*package_id()) + "'";
+}
+
+EqualUseRequirement::EqualUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+EqualUseRequirement::~EqualUseRequirement()
+{
+}
+
+bool
+EqualUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), pkg) == env->query_use(flag(), *package_id());
+}
+
+const std::string
+EqualUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' enabled or disabled like it is for '" + stringify(*package_id()) + "'";
+}
+
+NotEqualUseRequirement::NotEqualUseRequirement(const std::string & s,
+ const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
+ ConditionalUseRequirement(s, n, i)
+{
+}
+
+NotEqualUseRequirement::~NotEqualUseRequirement()
+{
+}
+
+bool
+NotEqualUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
+{
+ return env->query_use(flag(), pkg) != env->query_use(flag(), *package_id());
+}
+
+const std::string
+NotEqualUseRequirement::as_human_string() const
+{
+ return "Flag '" + stringify(flag()) + "' enabled or disabled opposite to how it is for '" + stringify(*package_id()) + "'";
+}
+
+ELikeUseRequirementError::ELikeUseRequirementError(const std::string & s, const std::string & m) throw () :
+ Exception("Error parsing use requirement '" + s + "': " + m)
+{
+}
+
+std::tr1::shared_ptr<const AdditionalPackageDepSpecRequirement>
+paludis::parse_elike_use_requirement(const std::string & s,
+ const std::tr1::shared_ptr<const PackageID> & id, const ELikeUseRequirementOptions & options)
+{
+ Context context("When parsing use requirement '" + s + "':");
+
+ std::string flag(s), raw_flag("[" + s + "]");
+ if ('=' == flag.at(flag.length() - 1))
+ {
+ if ((! options[euro_allow_self_deps]) || (! id))
+ throw ELikeUseRequirementError(s, "Cannot use [use=] here");
+
+ flag.erase(flag.length() - 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+ if ('!' == flag.at(flag.length() - 1))
+ {
+ flag.erase(flag.length() - 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+ return make_shared_ptr(new NotEqualUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ else
+ return make_shared_ptr(new EqualUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ else if ('?' == flag.at(flag.length() - 1))
+ {
+ if ((! options[euro_allow_self_deps]) || (! id))
+ throw ELikeUseRequirementError(s, "Cannot use [use?] here");
+
+ flag.erase(flag.length() - 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+ if ('!' == flag.at(flag.length() - 1))
+ {
+ flag.erase(flag.length() - 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+ if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+
+ return make_shared_ptr(new IfNotMineThenNotUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ else
+ return make_shared_ptr(new IfNotMineThenUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ else
+ {
+ if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+
+ return make_shared_ptr(new IfMineThenNotUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ else
+ return make_shared_ptr(new IfMineThenUseRequirement(raw_flag, UseFlagName(flag), id));
+ }
+ }
+ else if ('-' == flag.at(0))
+ {
+ flag.erase(0, 1);
+ if (flag.empty())
+ throw ELikeUseRequirementError(s, "Invalid [] contents");
+ return make_shared_ptr(new DisabledUseRequirement(raw_flag, UseFlagName(flag)));
+ }
+ else
+ return make_shared_ptr(new EnabledUseRequirement(raw_flag, UseFlagName(flag)));
+}
+
diff --git a/paludis/elike_use_requirement.hh b/paludis/elike_use_requirement.hh
new file mode 100644
index 0000000..1c81f72
--- /dev/null
+++ b/paludis/elike_use_requirement.hh
@@ -0,0 +1,36 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_USE_REQUIREMENT_HH
+#define PALUDIS_GUARD_PALUDIS_ELIKE_USE_REQUIREMENT_HH 1
+
+#include <paludis/elike_use_requirement-fwd.hh>
+#include <paludis/util/exception.hh>
+
+namespace paludis
+{
+ class PALUDIS_VISIBLE ELikeUseRequirementError :
+ public Exception
+ {
+ public:
+ ELikeUseRequirementError(const std::string &, const std::string &) throw ();
+ };
+}
+
+#endif
diff --git a/paludis/elike_use_requirement.se b/paludis/elike_use_requirement.se
new file mode 100644
index 0000000..442c60c
--- /dev/null
+++ b/paludis/elike_use_requirement.se
@@ -0,0 +1,11 @@
+#!/bin/bash
+# vim: set sw=4 sts=4 et ft=sh :
+
+make_enum_ELikeUseRequirementOption()
+{
+ prefix euro
+ want_destringify
+
+ key euro_allow_self_deps "Allow self-dependent use deps"
+}
+
diff --git a/paludis/files.m4 b/paludis/files.m4
index 8cbd5b6..3366f79 100644
--- a/paludis/files.m4
+++ b/paludis/files.m4
@@ -21,6 +21,11 @@ add(`dep_spec_flattener', `hh', `cc')
add(`dep_tree', `hh', `cc', `fwd')
add(`dep_tag', `hh', `cc', `fwd', `sr')
add(`distribution', `hh', `cc', `fwd')
+add(`elike_dep_parser', `hh', `cc', `fwd', `test')
+add(`elike_conditional_dep_spec', `hh', `cc', `fwd')
+add(`elike_package_dep_spec', `hh', `cc', `fwd', `se')
+add(`elike_slot_requirement', `hh', `cc', `fwd')
+add(`elike_use_requirement', `hh', `cc', `fwd', `se')
add(`environment', `hh', `fwd', `cc')
add(`environment_implementation', `hh', `cc')
add(`environment_maker', `hh', `cc')
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index 68fa2f5..8a47f3d 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -34,8 +34,6 @@ libpaludiserepository_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_
paludis_repositories_e_include_HEADERS = \
aa_visitor.hh \
check_fetched_files_visitor.hh \
- conditional_dep_spec.hh \
- dep_lexer.hh \
dep_parser.hh \
dep_parser-se.hh \
dep_parser-fwd.hh \
@@ -81,12 +79,10 @@ paludis_repositories_e_include_HEADERS = \
make_ebuild_repository.hh \
manifest2_entry-sr.hh \
manifest2_reader.hh \
- package_dep_spec.hh \
pipe_command_handler.hh \
source_uri_finder.hh \
traditional_layout.hh \
use_desc.hh \
- use_requirements.hh \
vdb_contents_tokeniser.hh \
vdb_id.hh \
vdb_merger.hh \
@@ -96,9 +92,7 @@ paludis_repositories_e_include_HEADERS = \
libpaludiserepository_la_SOURCES = \
aa_visitor.cc \
- dep_lexer.cc \
check_fetched_files_visitor.cc \
- conditional_dep_spec.cc \
dep_parser.cc \
dep_spec_pretty_printer.cc \
dependencies_rewriter.cc \
@@ -134,13 +128,11 @@ libpaludiserepository_la_SOURCES = \
layout.cc \
make_ebuild_repository.cc \
manifest2_reader.cc \
- package_dep_spec.cc \
pipe_command_handler.cc \
registration.cc \
source_uri_finder.cc \
traditional_layout.cc \
use_desc.cc \
- use_requirements.cc \
vdb_id.cc \
vdb_merger.cc \
vdb_repository.cc \
@@ -247,17 +239,6 @@ dep_spec_pretty_printer_TEST_LDADD = \
$(top_builddir)/test/libtest.a \
$(DYNAMIC_LD_LIBS)
-dep_lexer_TEST_SOURCES = dep_lexer_TEST.cc
-
-dep_lexer_TEST_LDADD = \
- libpaludiserepository.la \
- $(top_builddir)/paludis/util/libpaludisutil.la \
- $(top_builddir)/paludis/util/test_extras.o \
- $(top_builddir)/paludis/libpaludis.la \
- $(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
- $(top_builddir)/test/libtest.a \
- $(DYNAMIC_LD_LIBS)
-
dep_parser_TEST_SOURCES = dep_parser_TEST.cc
dep_parser_TEST_LDADD = \
@@ -320,7 +301,6 @@ fix_locked_dependencies_TEST_LDADD = \
EXTRA_DIST = \
aa_visitor_TEST.cc \
- dep_lexer_TEST.cc \
dep_parser.se \
dep_parser-se.hh \
dep_parser-se.cc \
@@ -513,7 +493,6 @@ paludis_datadir = $(datadir)/paludis
dist_paludis_data_DATA = traditional.exclude ebuild_entries_suffixes.conf
TESTS = \
- dep_lexer_TEST \
dep_parser_TEST \
dep_spec_pretty_printer_TEST \
e_repository_TEST \
diff --git a/paludis/repositories/e/dep_lexer.cc b/paludis/repositories/e/dep_lexer.cc
deleted file mode 100644
index 81fbe02..0000000
--- a/paludis/repositories/e/dep_lexer.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2005, 2006, 2007 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/dep_spec.hh>
-#include <paludis/repositories/e/dep_lexer.hh>
-#include <paludis/util/wrapped_forward_iterator-impl.hh>
-#include <paludis/util/private_implementation_pattern-impl.hh>
-#include <paludis/util/exception.hh>
-#include <paludis/util/tokeniser.hh>
-#include <vector>
-#include <list>
-
-using namespace paludis;
-using namespace paludis::erepository;
-
-template class WrappedForwardIterator<DepLexer::ConstIteratorTag,
- const std::pair<DepLexerLexeme, std::string> >;
-
-namespace paludis
-{
- /**
- * Implementation data for DepLexer.
- *
- * \ingroup grpdeplexer
- */
- template<>
- struct Implementation<DepLexer>
- {
- std::list<std::pair<DepLexerLexeme, std::string> > tokens;
- };
-}
-
-DepStringLexError::DepStringLexError(const std::string & dep_string,
- const std::string & our_message) throw () :
- DepStringError(dep_string, "in lex phase: " + our_message)
-{
-}
-
-DepStringError::DepStringError(const std::string & d, const std::string & m) throw () :
- Exception("Bad dependency string '" + d + "': " + m)
-{
-}
-
-DepLexer::DepLexer(const std::string & s) :
- PrivateImplementationPattern<DepLexer>(new Implementation<DepLexer>)
-{
- Context context("When lexing dependency string '" + s + "':");
-
- std::vector<std::string> tokens;
- tokenise<delim_kind::AnyOfTag, delim_mode::BoundaryTag>(s, " \n\t", "", std::back_inserter(tokens));
-
- for (std::vector<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
- t != t_end ; ++t)
- {
- if (t->empty())
- continue;
-
- if (*t == "||")
- _imp->tokens.push_back(std::make_pair(dpl_double_bar, *t));
- else if ('|' == (*t)[0])
- throw DepStringLexError(s, "'|' should be followed by '|'");
- else if (*t == "->")
- _imp->tokens.push_back(std::make_pair(dpl_arrow, *t));
- else if (*t == "(")
- _imp->tokens.push_back(std::make_pair(dpl_open_paren, *t));
- else if ('(' == (*t)[0])
- throw DepStringLexError(s, "'(' should be followed by whitespace");
- else if (*t == ")")
- _imp->tokens.push_back(std::make_pair(dpl_close_paren, *t));
- else if (')' == (*t)[0])
- throw DepStringLexError(s, "')' should be followed by whitespace");
- else if (std::string::npos == t->find_first_not_of(" \t\n"))
- _imp->tokens.push_back(std::make_pair(dpl_whitespace, *t));
- else if (':' == (*t)[t->length() - 1])
- _imp->tokens.push_back(std::make_pair(dpl_label, *t));
- else if ('?' == (*t)[t->length() - 1])
- _imp->tokens.push_back(std::make_pair(dpl_use_flag, *t));
- else
- _imp->tokens.push_back(std::make_pair(dpl_text, *t));
- }
-}
-
-DepLexer::~DepLexer()
-{
-}
-
-DepLexer::ConstIterator
-DepLexer::begin() const
-{
- return ConstIterator(_imp->tokens.begin());
-}
-
-DepLexer::ConstIterator
-DepLexer::end() const
-{
- return ConstIterator(_imp->tokens.end());
-}
-
diff --git a/paludis/repositories/e/dep_lexer.hh b/paludis/repositories/e/dep_lexer.hh
deleted file mode 100644
index bfdb91d..0000000
--- a/paludis/repositories/e/dep_lexer.hh
+++ /dev/null
@@ -1,129 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2005, 2006, 2007 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_E_DEP_LEXER_HH
-#define PALUDIS_GUARD_PALUDIS_E_DEP_LEXER_HH 1
-
-#include <paludis/util/exception.hh>
-#include <paludis/util/instantiation_policy.hh>
-#include <paludis/util/private_implementation_pattern.hh>
-#include <paludis/util/wrapped_forward_iterator-fwd.hh>
-#include <string>
-
-/** \file
- * Declarations for the DepLexer class.
- *
- * \ingroup grpdeplexer
- */
-
-namespace paludis
-{
- namespace erepository
- {
- /**
- * A DepStringError descendent is thrown if an invalid depend string is
- * encountered.
- *
- * \ingroup grpdeplexer
- * \ingroup grpexceptions
- */
- class PALUDIS_VISIBLE DepStringError : public Exception
- {
- protected:
- /**
- * Constructor.
- */
- DepStringError(const std::string & dep_string,
- const std::string & message) throw ();
- };
-
- /**
- * A DepStringLexError is thrown if a lex-level error is encountered when
- * parsing a dependency string.
- *
- * \ingroup grpdeplexer
- * \ingroup grpexceptions
- */
- class PALUDIS_VISIBLE DepStringLexError : public DepStringError
- {
- public:
- /**
- * Constructor.
- */
- DepStringLexError(const std::string & dep_string,
- const std::string & message) throw ();
- };
-
- /**
- * Lexemes used by DepLexer.
- *
- * \see DepLexer
- *
- * \ingroup grpdeplexer
- */
- enum DepLexerLexeme
- {
- dpl_whitespace, ///< whitespace
- dpl_text, ///< a package or item name
- dpl_use_flag, ///< a use flag
- dpl_double_bar, ///< a double bar ('any' marker)
- dpl_open_paren, ///< open paren
- dpl_close_paren, ///< close paren
- dpl_arrow, ///< arrow
- dpl_label ///< a label
- };
-
- /**
- * Converts a dependency string into a sequence of tokens, which are
- * then handled by DepParser.
- *
- * \see DepParser
- * \ingroup grpdeplexer
- * \nosubgrouping
- */
- class PALUDIS_VISIBLE DepLexer :
- private InstantiationPolicy<DepLexer, instantiation_method::NonCopyableTag>,
- private PrivateImplementationPattern<DepLexer>
- {
- public:
- ///\name Iterate over our items
- ///\{
-
- struct ConstIteratorTag;
- typedef WrappedForwardIterator<ConstIteratorTag,
- const std::pair<DepLexerLexeme, std::string> > ConstIterator;
-
- ConstIterator begin() const;
-
- ConstIterator end() const;
-
- ///\}
-
- ///\name Basic operations
- ///\{
-
- DepLexer(const std::string &);
- ~DepLexer();
-
- ///\}
- };
- }
-}
-
-#endif
diff --git a/paludis/repositories/e/dep_lexer_TEST.cc b/paludis/repositories/e/dep_lexer_TEST.cc
deleted file mode 100644
index 0300b1e..0000000
--- a/paludis/repositories/e/dep_lexer_TEST.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2005, 2006, 2007 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/repositories/e/dep_lexer.hh>
-#include <paludis/util/wrapped_forward_iterator.hh>
-#include <sstream>
-#include <test/test_framework.hh>
-#include <test/test_runner.hh>
-
-using namespace test;
-using namespace paludis;
-using namespace paludis::erepository;
-
-/** \file
- * Test cases for DepLexer.
- *
- */
-
-namespace test_cases
-{
- /**
- * \test Test DepLexer with an empty input.
- *
- */
- struct DepLexerEmptyTest : TestCase
- {
- DepLexerEmptyTest() : TestCase("empty") { }
-
- void run()
- {
- DepLexer l("");
- DepLexer::ConstIterator i(l.begin());
- TEST_CHECK(i == l.end());
- }
- } test_dep_spec_parser_lexer_empty;
-
- /**
- * \test Test DepLexer with a blank input.
- *
- */
- struct DepLexerBlankTest : TestCase
- {
- DepLexerBlankTest() : TestCase("blank") { }
-
- void run()
- {
- DepLexer l(" \n \t");
- DepLexer::ConstIterator i(l.begin());
- TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " \n \t");
- TEST_CHECK(++i == l.end());
- }
- } test_dep_spec_parser_lexer_blank;
-
- /**
- * \test Test DepLexer with a package.
- *
- */
- struct DepLexerPackageTest : TestCase
- {
- DepLexerPackageTest() : TestCase("package") { }
-
- void run()
- {
- DepLexer l("app-editors/vim");
- DepLexer::ConstIterator i(l.begin());
- TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "app-editors/vim");
- TEST_CHECK(++i == l.end());
- }
- } test_dep_spec_parser_lexer_package;
-
- /**
- * \test Test DepParser with a sequence of packages.
- *
- */
- struct DepLexerPackagesTest : TestCase
- {
- DepLexerPackagesTest() : TestCase("packages") { }
-
- void run()
- {
- DepLexer l("app-editors/vim app-misc/hilite \nsys-apps/findutils");
- DepLexer::ConstIterator i(l.begin());
-
- TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "app-editors/vim");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "app-misc/hilite");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " \n");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "sys-apps/findutils");
-
- TEST_CHECK(++i == l.end());
- }
- } test_dep_spec_parser_lexer_packages;
-
- /**
- * \test Test DepLexer with an any group.
- *
- */
- struct DepLexerAnyTest : TestCase
- {
- DepLexerAnyTest() : TestCase("any") { }
-
- void run()
- {
- DepLexer l("|| ( one/one two/two )");
- DepLexer::ConstIterator i(l.begin());
-
- TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_double_bar);
- TEST_CHECK_EQUAL(i->second, "||");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_open_paren);
- TEST_CHECK_EQUAL(i->second, "(");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "one/one");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "two/two");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_close_paren);
- TEST_CHECK_EQUAL(i->second, ")");
-
- TEST_CHECK(++i == l.end());
- }
- } test_dep_spec_parser_lexer_any;
-
- /**
- * \test Test DepLexer with a use group.
- *
- */
- struct DepLexerUseTest : TestCase
- {
- DepLexerUseTest() : TestCase("use") { }
-
- void run()
- {
- DepLexer l("foo? ( one/one )");
- DepLexer::ConstIterator i(l.begin());
-
- TEST_CHECK(i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_use_flag);
- TEST_CHECK_EQUAL(i->second, "foo?");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_open_paren);
- TEST_CHECK_EQUAL(i->second, "(");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_text);
- TEST_CHECK_EQUAL(i->second, "one/one");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_whitespace);
- TEST_CHECK_EQUAL(i->second, " ");
-
- TEST_CHECK(++i != l.end());
- TEST_CHECK_EQUAL(i->first, dpl_close_paren);
- TEST_CHECK_EQUAL(i->second, ")");
-
- TEST_CHECK(++i == l.end());
- }
- } test_dep_spec_parser_lexer_use;
-
- /**
- * \test Test DepLexer with bad input.
- *
- */
- struct DepLexerBadTest : TestCase
- {
- DepLexerBadTest() : TestCase("bad") { }
-
- void run()
- {
- TEST_CHECK_THROWS(DepLexer("(moo)"), DepStringError);
- TEST_CHECK_THROWS(DepLexer("|foo"), DepStringError);
- TEST_CHECK_THROWS(DepLexer("( moo )bar"), DepStringError);
- }
- } test_dep_spec_parser_lexer_bad;
-
-}
-
-
diff --git a/paludis/repositories/e/dep_parser-fwd.hh b/paludis/repositories/e/dep_parser-fwd.hh
index c4bf91b..35e77ae 100644
--- a/paludis/repositories/e/dep_parser-fwd.hh
+++ b/paludis/repositories/e/dep_parser-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 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
@@ -28,14 +28,9 @@ namespace paludis
{
namespace erepository
{
- class DepStringNestingError;
- class DepStringParseError;
-
#include <paludis/repositories/e/dep_parser-se.hh>
- typedef Options<PackageDepSpecParseOption> PackageDepSpecParseOptions;
typedef Options<DependencySpecTreeParseOption> DependencySpecTreeParseOptions;
-
}
}
diff --git a/paludis/repositories/e/dep_parser.cc b/paludis/repositories/e/dep_parser.cc
index 47ead01..c69a0f3 100644
--- a/paludis/repositories/e/dep_parser.cc
+++ b/paludis/repositories/e/dep_parser.cc
@@ -17,725 +17,397 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <paludis/dep_spec.hh>
-#include <paludis/repositories/e/eapi.hh>
-#include <paludis/repositories/e/dep_lexer.hh>
#include <paludis/repositories/e/dep_parser.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
-#include <paludis/repositories/e/conditional_dep_spec.hh>
-#include <paludis/util/exception.hh>
+#include <paludis/repositories/e/eapi.hh>
#include <paludis/util/stringify.hh>
-#include <paludis/util/tokeniser.hh>
-#include <paludis/util/visitor-impl.hh>
-#include <paludis/util/make_shared_ptr.hh>
-#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/kc.hh>
-#include <tr1/memory>
-#include <stack>
+#include <paludis/util/keys.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/elike_dep_parser.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
+#include <paludis/elike_package_dep_spec.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/repository.hh>
+#include <paludis/package_id.hh>
+#include <list>
#include <set>
-
-/** \file
- * Implementation for dep_parser.hh things.
- *
- * \ingroup grpdepparser
- */
+#include <ostream>
using namespace paludis;
using namespace paludis::erepository;
#include <paludis/repositories/e/dep_parser-se.cc>
-DepStringParseError::DepStringParseError(const std::string & d,
- const std::string & m) throw () :
- DepStringError(d, "in parse phase: " + m)
-{
-}
-
-DepStringNestingError::DepStringNestingError(const std::string & dep_string) throw () :
- DepStringParseError(dep_string, "improperly balanced parentheses")
+EDepParseError::EDepParseError(const std::string & s, const std::string & t) throw () :
+ Exception("Error parsing '" + s + "': " + t)
{
}
namespace
{
- struct LabelsAreURI;
- struct LabelsAreDependency;
-
- enum DepParserState
+ template <typename T_>
+ struct ParseStackTypes
{
- dps_initial,
- dps_had_double_bar,
- dps_had_double_bar_space,
- dps_had_paren,
- dps_had_use_flag,
- dps_had_use_flag_space,
- dps_had_text_arrow,
- dps_had_text_arrow_space,
- dps_had_text_arrow_text,
- dps_had_label
- };
+ typedef std::tr1::function<void (const std::tr1::shared_ptr<const typename T_::ConstItem> &)> AddHandler;
- using namespace std::tr1::placeholders;
-
- struct ParsePackageDepSpec
- {
- const EAPI & _eapi;
- const std::tr1::shared_ptr<const PackageID> _id;
-
- ParsePackageDepSpec(const EAPI & e, const std::tr1::shared_ptr<const PackageID> & i) :
- _eapi(e),
- _id(i)
- {
- }
-
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- p(std::tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
- std::tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(parse_e_package_dep_spec(s, _eapi, _id))))));
- }
+ typedef kc::KeyedClass<
+ kc::Field<k::add_handler, AddHandler>,
+ kc::Field<k::item, const std::tr1::shared_ptr<const typename T_::ConstItem> >
+ > Item;
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
- {
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
- }
+ typedef std::list<Item> Stack;
};
- struct ParsePackageOrBlockDepSpec
+ template <typename T_>
+ void package_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const EAPI & eapi, const std::tr1::shared_ptr<const PackageID> & id)
{
- const EAPI & _eapi;
- const std::tr1::shared_ptr<const PackageID> _id;
-
- ParsePackageOrBlockDepSpec(const EAPI & e, const std::tr1::shared_ptr<const PackageID> & i) :
- _eapi(e),
- _id(i)
- {
- }
+ PackageDepSpec p(parse_elike_package_dep_spec(s, (*eapi[k::supported()])[k::package_dep_spec_parse_options()], id));
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, PackageDepSpec>(make_shared_ptr(new PackageDepSpec(p)))));
+ }
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
+ template <typename T_>
+ void package_or_block_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const EAPI & eapi, const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if ((! s.empty()) && ('!' == s.at(0)))
{
- if (s.empty() || '!' != s.at(0))
- p(std::tr1::shared_ptr<TreeLeaf<H_, PackageDepSpec> >(new TreeLeaf<H_, PackageDepSpec>(
- std::tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
- parse_e_package_dep_spec(s, _eapi, _id))))));
- else
- p(std::tr1::shared_ptr<TreeLeaf<H_, BlockDepSpec> >(new TreeLeaf<H_, BlockDepSpec>(
- std::tr1::shared_ptr<BlockDepSpec>(new BlockDepSpec(
- std::tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
- parse_e_package_dep_spec(s.substr(1), _eapi, _id))))))));
+ std::tr1::shared_ptr<BlockDepSpec> b(new BlockDepSpec(
+ make_shared_ptr(new PackageDepSpec(parse_elike_package_dep_spec(s.substr(1),
+ (*eapi[k::supported()])[k::package_dep_spec_parse_options()], id)))));
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, BlockDepSpec>(b)));
}
+ else
+ package_dep_spec_string_handler<T_>(h, s, eapi, id);
+ }
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
- {
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
- }
- };
+ template <typename T_>
+ void license_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
+ {
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, LicenseDepSpec>(make_shared_ptr(new LicenseDepSpec(s)))));
+ }
- struct ParseTextDepSpec
+ template <typename T_>
+ void restrict_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
{
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- p(std::tr1::shared_ptr<TreeLeaf<H_, PlainTextDepSpec> >(new TreeLeaf<H_, PlainTextDepSpec>(
- std::tr1::shared_ptr<PlainTextDepSpec>(new PlainTextDepSpec(s)))));
- }
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, PlainTextDepSpec>(make_shared_ptr(new PlainTextDepSpec(s)))));
+ }
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
- {
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
- }
- };
+ template <typename T_>
+ void simple_uri_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
+ {
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, SimpleURIDepSpec>(make_shared_ptr(new SimpleURIDepSpec(s)))));
+ }
- struct ParseLicenseDepSpec
+ template <typename T_>
+ void arrow_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s, const std::string & f, const std::string & t,
+ const EAPI & eapi)
{
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- p(std::tr1::shared_ptr<TreeLeaf<H_, LicenseDepSpec> >(new TreeLeaf<H_, LicenseDepSpec>(
- std::tr1::shared_ptr<LicenseDepSpec>(new LicenseDepSpec(s)))));
- }
+ if (t.empty() || ((*eapi[k::supported()])[k::dependency_spec_tree_parse_options()][dstpo_uri_supports_arrow]))
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, FetchableURIDepSpec>(make_shared_ptr(
+ new FetchableURIDepSpec(t.empty() ? f : f + " -> " + t)))));
+ else
+ throw EDepParseError(s, "arrows in this EAPI");
+ }
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
- {
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
- }
- };
+ void any_not_allowed_handler(const std::string & s) PALUDIS_ATTRIBUTE((noreturn));
- struct ParseFetchableURIDepSpec
+ void any_not_allowed_handler(const std::string & s)
{
- const bool _supports_arrow;
+ throw EDepParseError(s, "Any dep specs not allowed here");
+ }
- ParseFetchableURIDepSpec(bool a) :
- _supports_arrow(a)
- {
- }
+ void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- p(std::tr1::shared_ptr<TreeLeaf<H_, FetchableURIDepSpec> >(new TreeLeaf<H_, FetchableURIDepSpec>(
- std::tr1::shared_ptr<FetchableURIDepSpec>(new FetchableURIDepSpec(s)))));
- }
+ void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t)
+ {
+ throw EDepParseError(s, "Arrow '" + f + " -> " + t + "' not allowed here");
+ }
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- if (_supports_arrow)
- p(std::tr1::shared_ptr<TreeLeaf<H_, FetchableURIDepSpec> >(new TreeLeaf<H_, FetchableURIDepSpec>(
- std::tr1::shared_ptr<FetchableURIDepSpec>(new FetchableURIDepSpec(lhs + " -> " + rhs)))));
- else
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this EAPI");
- }
- };
+ void error_handler(const std::string & s, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
- struct ParseSimpleURIDepSpec
+ void error_handler(const std::string & s, const std::string & t)
{
- template <typename H_>
- void
- add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p) const
- {
- p(std::tr1::shared_ptr<TreeLeaf<H_, SimpleURIDepSpec> >(new TreeLeaf<H_, SimpleURIDepSpec>(
- std::tr1::shared_ptr<SimpleURIDepSpec>(new SimpleURIDepSpec(s)))));
- }
+ throw EDepParseError(s, t);
+ }
- template <typename H_>
- void
- add_arrow(const std::string & lhs, const std::string & rhs, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &) const
- {
- throw DepStringParseError(lhs + " -> " + rhs, "Arrows not allowed in this context");
- }
- };
+ void labels_not_allowed_handler(const std::string & s, const std::string & f) PALUDIS_ATTRIBUTE((noreturn));
- template <typename H_, bool>
- struct HandleUse
+ void labels_not_allowed_handler(const std::string & s, const std::string & f)
{
- static void handle(const std::string &, const std::string & i,
- const std::tr1::shared_ptr<const PackageID> & id, const Environment * const env,
- const EAPI & eapi, std::stack<std::pair<std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > & stack)
- {
- std::tr1::shared_ptr<ConstTreeSequence<H_, ConditionalDepSpec> > a(
- new ConstTreeSequence<H_, ConditionalDepSpec>(std::tr1::shared_ptr<ConditionalDepSpec>(
- new ConditionalDepSpec(parse_e_conditional_dep_spec(i, env, id, eapi)))));
- stack.top().first(a);
- stack.push(std::make_pair(std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
- std::tr1::bind(&ConstTreeSequence<H_, ConditionalDepSpec>::add, a.get(), _1)), false));
- }
- };
+ throw EDepParseError(s, "Label '" + f + "' not allowed here");
+ }
- template <typename H_>
- struct HandleUse<H_, false>
+ template <typename T_>
+ void dependency_label_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const EAPI & eapi)
{
- static void handle(const std::string & s, const std::string &,
- const std::tr1::shared_ptr<const PackageID> &, const Environment * const,
- const EAPI &, std::stack<std::pair<std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &)
- {
- throw DepStringParseError(s, "use? group is not allowed here");
- }
- };
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, DependencyLabelsDepSpec>(
+ parse_dependency_label(s, eapi))));
+ }
- template <typename H_, bool>
- struct HandleAny
+ template <typename T_>
+ void fetchable_label_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const EAPI & eapi)
{
- static void handle(const std::string &, std::stack<std::pair<std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &
- stack)
- {
- std::tr1::shared_ptr<ConstTreeSequence<H_, AnyDepSpec> > a(new ConstTreeSequence<H_, AnyDepSpec>(
- std::tr1::shared_ptr<AnyDepSpec>(new AnyDepSpec)));
- stack.top().first(a);
- stack.push(std::make_pair(std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
- std::tr1::bind(&ConstTreeSequence<H_, AnyDepSpec>::add, a.get(), _1)), true));
- }
- };
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, URILabelsDepSpec>(
+ parse_uri_label(s, eapi))));
+ }
- template <typename H_>
- struct HandleAny<H_, false>
+ template <typename T_, typename A_>
+ void any_all_handler(typename ParseStackTypes<T_>::Stack & stack)
{
- static void handle(const std::string & s, std::stack<std::pair<std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > &)
- {
- throw DepStringParseError(s, "|| is not allowed here");
- }
- };
+ using namespace std::tr1::placeholders;
+ std::tr1::shared_ptr<ConstTreeSequence<T_, A_> > item(
+ new ConstTreeSequence<T_, A_>(make_shared_ptr(new A_)));
+ (*stack.begin())[k::add_handler()](item);
+ stack.push_front(ParseStackTypes<T_>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<T_, A_>::add, item.get(), _1))
+ (k::item(), item)
+ );
+ }
- template <typename H_, typename K_>
- struct HandleLabel
+ template <typename T_>
+ void use_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & u,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
{
- static void add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> &,
- const EAPI &)
- {
- throw DepStringParseError(s, "label is not allowed here");
- }
- };
+ using namespace std::tr1::placeholders;
+ std::tr1::shared_ptr<ConstTreeSequence<T_, ConditionalDepSpec> > item(
+ new ConstTreeSequence<T_, ConditionalDepSpec>(make_shared_ptr(new ConditionalDepSpec(
+ parse_elike_conditional_dep_spec(u, env, id)))));
+ (*stack.begin())[k::add_handler()](item);
+ stack.push_front(ParseStackTypes<T_>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<T_, ConditionalDepSpec>::add, item.get(), _1))
+ (k::item(), item)
+ );
+ }
- template <typename H_>
- struct HandleLabel<H_, LabelsAreURI>
+ template <typename T_>
+ void pop_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
{
- static void add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p,
- const EAPI & e)
- {
- if (e[k::supported()])
- p(std::tr1::shared_ptr<TreeLeaf<H_, URILabelsDepSpec> >(
- new TreeLeaf<H_, URILabelsDepSpec>(parse_uri_label(s, e))));
- else
- throw DepStringParseError(s, "URI labels not allowed in this EAPI");
- }
- };
+ stack.pop_front();
+ if (stack.empty())
+ throw EDepParseError(s, "Too many ')'s");
+ }
- template <typename H_>
- struct HandleLabel<H_, LabelsAreDependency>
+ template <typename T_>
+ void should_be_empty_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
{
- static void add(const std::string & s, std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)> & p,
- const EAPI & e)
- {
- if (e[k::supported()])
- p(std::tr1::shared_ptr<TreeLeaf<H_, DependencyLabelsDepSpec> >(
- new TreeLeaf<H_, DependencyLabelsDepSpec>(parse_dependency_label(s, e))));
- else
- throw DepStringParseError(s, "Dependency labels not allowed in this EAPI");
- }
- };
-}
+ if (1 != stack.size())
+ throw EDepParseError(s, "Nesting error");
+ }
-namespace
-{
- template <typename H_, typename I_, bool any_, bool use_, typename Label_>
- std::tr1::shared_ptr<typename H_::ConstItem>
- parse(const std::string & s, bool disallow_any_use, const I_ & p, const Environment * const env,
- const EAPI & e, const std::tr1::shared_ptr<const PackageID> & id)
+ void use_under_any_handler(const std::string & s, const EAPI & eapi)
{
- Context context("When parsing dependency string '" + s + "':");
-
- if (! id)
- throw InternalError(PALUDIS_HERE, "! id");
-
- std::tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> > result(
- new ConstTreeSequence<H_, AllDepSpec>(std::tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
- std::stack<std::pair<std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>, bool> > stack;
- stack.push(std::make_pair(std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
- std::tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, result.get(), _1)), false));
-
- std::string arrow_lhs;
- DepParserState state(dps_initial);
- DepLexer lexer(s);
- DepLexer::ConstIterator i(lexer.begin()), i_end(lexer.end());
-
- for ( ; i != i_end ; ++i)
- {
- Context local_context("When handling lexer token '" + i->second +
- "' (" + stringify(i->first) + "):");
- do
- {
- switch (state)
- {
- case dps_initial:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- continue;
-
- case dpl_arrow:
- throw DepStringParseError(s, "Arrow not allowed here");
-
- case dpl_text:
- {
- if (i->second.empty())
- throw DepStringParseError(i->second, "Empty text entry");
-
- DepLexer::ConstIterator i_fwd(next(i));
- if (i_fwd != i_end && i_fwd->first == dpl_whitespace && ++i_fwd != i_end
- && i_fwd->first == dpl_arrow)
- {
- arrow_lhs = i->second;
- i = i_fwd;
- state = dps_had_text_arrow;
- }
- else
- p.template add<H_>(i->second, stack.top().first);
- }
- continue;
-
- case dpl_open_paren:
- {
- std::tr1::shared_ptr<ConstTreeSequence<H_, AllDepSpec> > a(new ConstTreeSequence<H_, AllDepSpec>(
- std::tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
- stack.top().first(a);
- stack.push(std::make_pair(std::tr1::function<void (std::tr1::shared_ptr<ConstAcceptInterface<H_> >)>(
- std::tr1::bind(&ConstTreeSequence<H_, AllDepSpec>::add, a.get(), _1)), false));
- state = dps_had_paren;
- }
- continue;
-
- case dpl_close_paren:
- if (stack.empty())
- throw DepStringNestingError(s);
- stack.pop();
- if (stack.empty())
- throw DepStringNestingError(s);
- state = dps_had_paren;
- continue;
-
- case dpl_double_bar:
- HandleAny<H_, any_>::handle(s, stack);
- state = dps_had_double_bar;
- continue;
-
- case dpl_use_flag:
- if (use_ && disallow_any_use && stack.top().second)
- throw DepStringParseError(s, "use? group is not allowed immediately under a || ( )");
- HandleUse<H_, use_>::handle(s, i->second, id, env, e, stack);
- state = dps_had_use_flag;
- continue;
-
- case dpl_label:
- HandleLabel<H_, Label_>::add(i->second, stack.top().first, e);
- state = dps_had_label;
- continue;
- }
- throw InternalError(PALUDIS_HERE,
- "dps_initial: i->first is " + stringify(i->first));
-
- } while (0);
- continue;
-
- case dps_had_double_bar:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_had_double_bar_space;
- continue;
-
- case dpl_text:
- case dpl_arrow:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_open_paren:
- case dpl_close_paren:
- case dpl_label:
- throw DepStringParseError(s, "Expected space after '||'");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_double_bar: i->first is " + stringify(i->first));
-
- } while (0);
- continue;
-
- case dps_had_double_bar_space:
- do
- {
- switch (i->first)
- {
- case dpl_open_paren:
- state = dps_initial;
- continue;
-
- case dpl_whitespace:
- case dpl_text:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected '(' after '|| '");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_double_bar_space: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_paren:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_initial;
- continue;
-
- case dpl_text:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_open_paren:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected space after '(' or ')'");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_paren: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_use_flag:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_had_use_flag_space;
- continue;
-
- case dpl_text:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_open_paren:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected space after use flag");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_use_flag: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_use_flag_space:
- do
- {
- switch (i->first)
- {
- case dpl_open_paren:
- state = dps_had_paren;
- continue;
-
- case dpl_whitespace:
- case dpl_text:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected '(' after use flag");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_use_flag_space: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_label:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_initial;
- continue;
-
- case dpl_text:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_open_paren:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected space after label");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_label: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_text_arrow:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_had_text_arrow_space;
- continue;
-
- case dpl_text:
- case dpl_open_paren:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected whitespace after arrow");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_text_arrow: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_text_arrow_space:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- continue;
-
- case dpl_text:
- state = dps_had_text_arrow_text;
- p.template add_arrow<H_>(arrow_lhs, i->second, stack.top().first);
- continue;
-
- case dpl_open_paren:
- case dpl_use_flag:
- case dpl_double_bar:
- case dpl_close_paren:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected text after whitespace after arrow");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_text_arrow_space: i->first is " + stringify(i->first));
- } while (0);
- continue;
-
- case dps_had_text_arrow_text:
- do
- {
- switch (i->first)
- {
- case dpl_whitespace:
- state = dps_initial;
- continue;
-
- case dpl_text:
- case dpl_open_paren:
- case dpl_use_flag:
- case dpl_close_paren:
- case dpl_double_bar:
- case dpl_arrow:
- case dpl_label:
- throw DepStringParseError(s, "Expected whitespace after text after whitespace after arrow");
- }
- throw InternalError(PALUDIS_HERE,
- "dps_had_text_arrow_text: i->first is " + stringify(i->first));
- }
- while (0);
- continue;
- }
- throw InternalError(PALUDIS_HERE,
- "state is " + stringify(state));
-
- } while (0);
- }
-
- if (stack.empty())
- throw DepStringNestingError(s);
-
- switch (state)
- {
- case dps_initial:
- case dps_had_paren:
- case dps_had_text_arrow_text:
- case dps_had_text_arrow_space:
- case dps_had_label:
- break;
-
- case dps_had_double_bar_space:
- case dps_had_double_bar:
- case dps_had_use_flag:
- case dps_had_use_flag_space:
- case dps_had_text_arrow:
- throw DepStringParseError(s, "Unexpected end of string");
- }
+ if ((*eapi[k::supported()])[k::dependency_spec_tree_parse_options()][dstpo_disallow_any_use])
+ throw EDepParseError(s, "use? not allowed under || ( ) in this EAPI");
+ }
- stack.pop();
- if (! stack.empty())
- throw DepStringNestingError(s);
- return result;
+ void do_nothing()
+ {
}
}
std::tr1::shared_ptr<DependencySpecTree::ConstItem>
-paludis::erepository::parse_depend(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
+paludis::erepository::parse_depend(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI & eapi)
{
- Context c("When parsing dependency string '" + s + "' using EAPI '" + e[k::name()] + "':");
-
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' dependencies");
+ using namespace std::tr1::placeholders;
- return parse<DependencySpecTree, ParsePackageOrBlockDepSpec, true, true, LabelsAreDependency>(s,
- (*e[k::supported()])[k::dependency_spec_tree_parse_options()][dstpo_disallow_any_use],
- ParsePackageOrBlockDepSpec(e, id), env, e, id);
+ ParseStackTypes<DependencySpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<DependencySpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<DependencySpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&package_or_block_dep_spec_string_handler<DependencySpecTree>, std::tr1::ref(stack), _1, eapi, id))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_all_handler<DependencySpecTree, AnyDepSpec>, std::tr1::ref(stack)))
+ (k::on_all(), std::tr1::bind(&any_all_handler<DependencySpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<DependencySpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&dependency_label_handler<DependencySpecTree>, std::tr1::ref(stack), _1, eapi))
+ (k::on_pop(), std::tr1::bind(&pop_handler<DependencySpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<DependencySpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), std::tr1::bind(&use_under_any_handler, s, eapi))
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
}
std::tr1::shared_ptr<ProvideSpecTree::ConstItem>
-paludis::erepository::parse_provide(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
-{
- Context c("When parsing provide string '" + s + "' using EAPI '" + e[k::name()] + "':");
-
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' provides");
-
- return parse<ProvideSpecTree, ParsePackageDepSpec, false, true, void>(s, false,
- ParsePackageDepSpec(e, std::tr1::shared_ptr<const PackageID>()), env, e, id);
-}
-
-std::tr1::shared_ptr<RestrictSpecTree::ConstItem>
-paludis::erepository::parse_restrict(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
+paludis::erepository::parse_provide(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI & eapi)
{
- Context c("When parsing restrict string '" + s + "' using EAPI '" + e[k::name()] + "':");
-
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' restrictions");
+ using namespace std::tr1::placeholders;
- return parse<RestrictSpecTree, ParseTextDepSpec, false, true, void>(s, false,
- ParseTextDepSpec(), env, e, id);
+ ParseStackTypes<ProvideSpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<ProvideSpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<ProvideSpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<ProvideSpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<ProvideSpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&package_dep_spec_string_handler<ProvideSpecTree>, std::tr1::ref(stack), _1, eapi, id))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<ProvideSpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<ProvideSpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<ProvideSpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<ProvideSpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), std::tr1::bind(&use_under_any_handler, s, eapi))
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
}
std::tr1::shared_ptr<FetchableURISpecTree::ConstItem>
-paludis::erepository::parse_fetchable_uri(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
+paludis::erepository::parse_fetchable_uri(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI & eapi)
{
- Context c("When parsing fetchable URI string '" + s + "' using EAPI '" + e[k::name()] + "':");
-
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' URIs");
+ using namespace std::tr1::placeholders;
- return parse<FetchableURISpecTree, ParseFetchableURIDepSpec, false, true, LabelsAreURI>(s, false,
- ParseFetchableURIDepSpec((*e[k::supported()])[k::dependency_spec_tree_parse_options()][dstpo_uri_supports_arrow]),
- env, e, id);
+ ParseStackTypes<FetchableURISpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<FetchableURISpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<FetchableURISpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<FetchableURISpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<FetchableURISpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&arrow_handler<FetchableURISpecTree>, std::tr1::ref(stack), s, _1, "", eapi))
+ (k::on_arrow(), std::tr1::bind(&arrow_handler<FetchableURISpecTree>, std::tr1::ref(stack), s, _1, _2, eapi))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<FetchableURISpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<FetchableURISpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&fetchable_label_handler<FetchableURISpecTree>, std::tr1::ref(stack), _1, eapi))
+ (k::on_pop(), std::tr1::bind(&pop_handler<FetchableURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<FetchableURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), std::tr1::bind(&use_under_any_handler, s, eapi))
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
}
std::tr1::shared_ptr<SimpleURISpecTree::ConstItem>
-paludis::erepository::parse_simple_uri(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
+paludis::erepository::parse_simple_uri(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI &)
{
- Context c("When parsing simple URI string '" + s + "' using EAPI '" + e[k::name()] + "':");
-
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' URIs");
+ using namespace std::tr1::placeholders;
- return parse<SimpleURISpecTree, ParseSimpleURIDepSpec, false, true, void>(s, false,
- ParseSimpleURIDepSpec(), env, e, id);
+ ParseStackTypes<SimpleURISpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<SimpleURISpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<SimpleURISpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<SimpleURISpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<SimpleURISpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&simple_uri_handler<SimpleURISpecTree>, std::tr1::ref(stack), _1))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<SimpleURISpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<SimpleURISpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<SimpleURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<SimpleURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
}
std::tr1::shared_ptr<LicenseSpecTree::ConstItem>
-paludis::erepository::parse_license(const std::string & s, const Environment * const env,
- const std::tr1::shared_ptr<const PackageID> & id, const EAPI & e)
+paludis::erepository::parse_license(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI & eapi)
{
- Context c("When parsing license string '" + s + "' using EAPI '" + e[k::name()] + "':");
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<LicenseSpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<LicenseSpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<LicenseSpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<LicenseSpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<LicenseSpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&license_handler<LicenseSpecTree>, std::tr1::ref(stack), _1))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_all_handler<LicenseSpecTree, AnyDepSpec>, std::tr1::ref(stack)))
+ (k::on_all(), std::tr1::bind(&any_all_handler<LicenseSpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<LicenseSpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<LicenseSpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<LicenseSpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), std::tr1::bind(&use_under_any_handler, s, eapi))
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
- if (! e[k::supported()])
- throw DepStringParseError(s, "Don't know how to parse EAPI '" + e[k::name()] + "' licenses");
+std::tr1::shared_ptr<RestrictSpecTree::ConstItem>
+paludis::erepository::parse_restrict(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id, const EAPI &)
+{
+ using namespace std::tr1::placeholders;
- return parse<LicenseSpecTree, ParseLicenseDepSpec, true, true, void>(s,
- true, ParseLicenseDepSpec(), env, e, id);
+ ParseStackTypes<RestrictSpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<RestrictSpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<RestrictSpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<RestrictSpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<RestrictSpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&restrict_handler<RestrictSpecTree>, std::tr1::ref(stack), _1))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<RestrictSpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<RestrictSpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<RestrictSpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<RestrictSpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
}
std::tr1::shared_ptr<URILabelsDepSpec>
@@ -744,11 +416,11 @@ paludis::erepository::parse_uri_label(const std::string & s, const EAPI & e)
Context context("When parsing label string '" + s + "' using EAPI '" + e[k::name()] + "':");
if (s.empty())
- throw DepStringParseError(s, "Empty label");
+ throw EDepParseError(s, "Empty label");
std::string c((*e[k::supported()])[k::uri_labels()].class_for_label(s.substr(0, s.length() - 1)));
if (c.empty())
- throw DepStringParseError(s, "Unknown label");
+ throw EDepParseError(s, "Unknown label");
std::tr1::shared_ptr<URILabelsDepSpec> l(new LabelsDepSpec<URILabelVisitorTypes>);
@@ -765,7 +437,7 @@ paludis::erepository::parse_uri_label(const std::string & s, const EAPI & e)
else if (c == "URIManualOnlyLabel")
l->add_label(make_shared_ptr(new URIManualOnlyLabel(s.substr(0, s.length() - 1))));
else
- throw DepStringParseError(s, "Label '" + s + "' maps to unknown class '" + c + "'");
+ throw EDepParseError(s, "Label '" + s + "' maps to unknown class '" + c + "'");
return l;
}
@@ -776,7 +448,7 @@ paludis::erepository::parse_dependency_label(const std::string & s, const EAPI &
Context context("When parsing label string '" + s + "' using EAPI '" + e[k::name()] + "':");
if (s.empty())
- throw DepStringParseError(s, "Empty label");
+ throw EDepParseError(s, "Empty label");
std::set<std::string> labels;
std::string label(s.substr(0, s.length() - 1));
@@ -788,7 +460,7 @@ paludis::erepository::parse_dependency_label(const std::string & s, const EAPI &
{
std::string c((*e[k::supported()])[k::dependency_labels()].class_for_label(*it));
if (c.empty())
- throw DepStringParseError(s, "Unknown label '" + *it + "'");
+ throw EDepParseError(s, "Unknown label '" + *it + "'");
if (c == "DependencyHostLabel")
l->add_label(make_shared_ptr(new DependencyHostLabel(*it)));
@@ -819,9 +491,8 @@ paludis::erepository::parse_dependency_label(const std::string & s, const EAPI &
else if (c == "DependencyABILabel")
l->add_label(make_shared_ptr(new DependencyABILabel(*it)));
else
- throw DepStringParseError(s, "Label '" + *it + "' maps to unknown class '" + c + "'");
+ throw EDepParseError(s, "Label '" + *it + "' maps to unknown class '" + c + "'");
}
return l;
}
-
diff --git a/paludis/repositories/e/dep_parser.hh b/paludis/repositories/e/dep_parser.hh
index fbdedba..20a46f2 100644
--- a/paludis/repositories/e/dep_parser.hh
+++ b/paludis/repositories/e/dep_parser.hh
@@ -23,7 +23,6 @@
#include <paludis/repositories/e/dep_parser-fwd.hh>
#include <paludis/dep_tree.hh>
#include <paludis/package_id-fwd.hh>
-#include <paludis/repositories/e/dep_lexer.hh>
#include <paludis/repositories/e/eapi-fwd.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/instantiation_policy.hh>
@@ -40,40 +39,18 @@ namespace paludis
{
namespace erepository
{
- /**
- * A DepStringParseError is thrown if an error is encountered when parsing
- * a dependency string.
- *
- * \ingroup grpexceptions
- * \ingroup grpdepparser
- */
- class PALUDIS_VISIBLE DepStringParseError : public DepStringError
+ class PALUDIS_VISIBLE EDepParseError :
+ public Exception
{
public:
/**
* Constructor.
*/
- DepStringParseError(const std::string & dep_string,
+ EDepParseError(const std::string & dep_string,
const std::string & message) throw ();
};
/**
- * A DepStringNestingError is thrown if a dependency string does not have
- * properly balanced parentheses.
- *
- * \ingroup grpexceptions
- * \ingroup grpdepparser
- */
- class PALUDIS_VISIBLE DepStringNestingError : public DepStringParseError
- {
- public:
- /**
- * Constructor.
- */
- DepStringNestingError(const std::string & dep_string) throw ();
- };
-
- /**
* Parse a dependency heirarchy.
*/
std::tr1::shared_ptr<DependencySpecTree::ConstItem> parse_depend(const std::string & s,
diff --git a/paludis/repositories/e/dep_parser.se b/paludis/repositories/e/dep_parser.se
index 81fe339..bf3c9eb 100644
--- a/paludis/repositories/e/dep_parser.se
+++ b/paludis/repositories/e/dep_parser.se
@@ -1,22 +1,6 @@
#!/bin/bash
# vim: set sw=4 sts=4 et ft=sh :
-make_enum_PackageDepSpecParseOption()
-{
- prefix pdspo
- want_destringify
- namespace paludis::erepository
-
- key pdspo_allow_slot_deps "Allow :slot deps"
- key pdspo_allow_slot_star_deps "Allow :* slot deps"
- key pdspo_allow_slot_equal_deps "Allow := and :=blah slot deps"
- key pdspo_allow_repository_deps "Allow ::repo deps"
- key pdspo_allow_square_bracket_deps "Allow [use] and [opver] deps"
- key pdspo_allow_tilde_greater_deps "Allow ~> deps"
- key pdspo_strict_star_operator "* with an operator other than = is an error"
- key pdspo_strict_parsing "Error rather than warn for violations"
-}
-
make_enum_DependencySpecTreeParseOption()
{
prefix dstpo
diff --git a/paludis/repositories/e/dep_parser_TEST.cc b/paludis/repositories/e/dep_parser_TEST.cc
index 50f4a08..5ff3560 100644
--- a/paludis/repositories/e/dep_parser_TEST.cc
+++ b/paludis/repositories/e/dep_parser_TEST.cc
@@ -203,7 +203,7 @@ namespace test_cases
TEST_CHECK_EQUAL(stringify(d), "|| ( one/one foo? ( two/two ) )");
TEST_CHECK_THROWS(parse_depend("|| ( one/one foo? ( two/two ) )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
DepSpecPrettyPrinter e(0, std::tr1::shared_ptr<const PackageID>(), ff, 0, false);
parse_depend("|| ( one/one ( foo? ( two/two ) ) )",
@@ -300,7 +300,7 @@ namespace test_cases
TEST_CHECK_EQUAL(stringify(e), "a->\nb\n");
TEST_CHECK_THROWS(parse_fetchable_uri("a -> b",
- &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), Exception);
}
} test_dep_spec_parser_uri;
@@ -322,15 +322,15 @@ namespace test_cases
DepSpecPrettyPrinter d(0, std::tr1::shared_ptr<const PackageID>(), ff, 0, false);
TEST_CHECK_THROWS(parse_depend("!foo? ( one/one",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("!foo? ( one/one ) )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("( ( ( ) )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("( ( ( ) ) ) )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend(")",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
}
} test_dep_spec_parser_bad_nesting;
@@ -352,40 +352,38 @@ namespace test_cases
DepSpecPrettyPrinter d(0, std::tr1::shared_ptr<const PackageID>(), ff, 0, false);
TEST_CHECK_THROWS(parse_depend("||",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("|| ",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("foo?",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("!? ( )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("!foo? ||",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("(((",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend(")",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_depend("(foo/bar)",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_license("a -> b",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("( -> )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("( -> )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("foo? -> bar",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("a ->",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("a -> ( )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("a -> )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
TEST_CHECK_THROWS(parse_fetchable_uri("a -> || ( )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
- TEST_CHECK_THROWS(parse_fetchable_uri("a -> foo? ( )",
- &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), DepStringError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("paludis-1"))->accept(d), Exception);
}
} test_dep_spec_parser_bad_values;
@@ -409,7 +407,7 @@ namespace test_cases
&env, id, *EAPIData::get_instance()->eapi_from_string("exheres-0"))->accept(d);
TEST_CHECK_EQUAL(stringify(d), "build: one/one");
TEST_CHECK_THROWS(parse_depend("build: one/one",
- &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), DepStringParseError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("0"))->accept(d), EDepParseError);
}
} test_dep_spec_parser_labels;
@@ -430,7 +428,7 @@ namespace test_cases
&env, id, *EAPIData::get_instance()->eapi_from_string("kdebuild-1"))->accept(d);
TEST_CHECK_EQUAL(stringify(d), "http://foo/bar manual: two");
TEST_CHECK_THROWS(parse_fetchable_uri("http://foo/bar monkey: two",
- &env, id, *EAPIData::get_instance()->eapi_from_string("kdebuild-1"))->accept(d), DepStringParseError);
+ &env, id, *EAPIData::get_instance()->eapi_from_string("kdebuild-1"))->accept(d), EDepParseError);
}
} test_dep_spec_parser_kdebuild_uri_labels;
}
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index bc5d8a7..716bf22 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -30,7 +30,6 @@
#include <paludis/repositories/e/e_repository_sets.hh>
#include <paludis/repositories/e/e_repository_exceptions.hh>
#include <paludis/repositories/e/e_repository_entries.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/use_desc.hh>
#include <paludis/repositories/e/layout.hh>
@@ -53,6 +52,7 @@
#include <paludis/action.hh>
#include <paludis/mask.hh>
#include <paludis/qa.hh>
+#include <paludis/elike_package_dep_spec.hh>
#include <paludis/util/fs_entry.hh>
#include <paludis/util/log.hh>
@@ -147,8 +147,9 @@ namespace
std::tr1::shared_ptr<MetadataKey> key;
std::tr1::shared_ptr<const PackageIDSequence> q(
_env->package_database()->query(
- query::Matches(erepository::parse_e_package_dep_spec(*i,
- *erepository::EAPIData::get_instance()->eapi_from_string(_p),
+ query::Matches(parse_elike_package_dep_spec(*i,
+ (*(*erepository::EAPIData::get_instance()->eapi_from_string(_p))
+ [k::supported()])[k::package_dep_spec_parse_options()],
std::tr1::shared_ptr<const PackageID>())) &
query::InstalledAtRoot(_env->root()),
qo_order_by_version));
@@ -582,9 +583,10 @@ ERepository::repository_masked(const PackageID & id) const
{
try
{
- std::tr1::shared_ptr<const PackageDepSpec> a(new PackageDepSpec(erepository::parse_e_package_dep_spec(
+ std::tr1::shared_ptr<const PackageDepSpec> a(new PackageDepSpec(parse_elike_package_dep_spec(
line->first,
- *erepository::EAPIData::get_instance()->eapi_from_string(_imp->params.profile_eapi),
+ (*(*erepository::EAPIData::get_instance()->eapi_from_string(_imp->params.profile_eapi))
+ [k::supported()])[k::package_dep_spec_parse_options()],
std::tr1::shared_ptr<const PackageID>())));
if (a->package_ptr())
_imp->repo_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second));
diff --git a/paludis/repositories/e/e_repository_news.cc b/paludis/repositories/e/e_repository_news.cc
index 1956070..71cba9f 100644
--- a/paludis/repositories/e/e_repository_news.cc
+++ b/paludis/repositories/e/e_repository_news.cc
@@ -20,7 +20,6 @@
#include <paludis/repositories/e/e_repository.hh>
#include <paludis/repositories/e/e_repository_news.hh>
#include <paludis/repositories/e/eapi.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/util/config_file.hh>
#include <paludis/environment.hh>
@@ -33,6 +32,7 @@
#include <paludis/util/options.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/query.hh>
+#include <paludis/elike_package_dep_spec.hh>
#include <set>
#include <ostream>
@@ -137,9 +137,9 @@ ERepositoryNews::update_news() const
for (NewsFile::DisplayIfInstalledConstIterator i(news.begin_display_if_installed()),
i_end(news.end_display_if_installed()) ; i != i_end ; ++i)
if (! _imp->environment->package_database()->query(
- query::Matches(PackageDepSpec(erepository::parse_e_package_dep_spec(*i,
- *erepository::EAPIData::get_instance()->eapi_from_string(
- _imp->e_repository->params().profile_eapi),
+ query::Matches(PackageDepSpec(parse_elike_package_dep_spec(*i,
+ (*(*erepository::EAPIData::get_instance()->eapi_from_string(
+ _imp->e_repository->params().profile_eapi))[k::supported()])[k::package_dep_spec_parse_options()],
std::tr1::shared_ptr<const PackageID>()))) &
query::SupportsAction<InstalledAction>(),
qo_whatever)->empty())
diff --git a/paludis/repositories/e/e_repository_profile.cc b/paludis/repositories/e/e_repository_profile.cc
index fa9044c..826e471 100644
--- a/paludis/repositories/e/e_repository_profile.cc
+++ b/paludis/repositories/e/e_repository_profile.cc
@@ -22,7 +22,6 @@
#include <paludis/repositories/e/e_repository_mask_file.hh>
#include <paludis/repositories/e/e_repository_exceptions.hh>
#include <paludis/repositories/e/e_repository.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/util/log.hh>
@@ -469,8 +468,10 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
Context context_spec("When parsing '" + *i + "':");
std::tr1::shared_ptr<PackageDepSpec> spec(new PackageDepSpec(
- erepository::parse_e_package_dep_spec(i->substr(1), *erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi), std::tr1::shared_ptr<const PackageID>())));
+ parse_elike_package_dep_spec(i->substr(1),
+ (*(*erepository::EAPIData::get_instance()->eapi_from_string(
+ repository->params().profile_eapi))[k::supported()])[k::package_dep_spec_parse_options()],
+ std::tr1::shared_ptr<const PackageID>())));
spec->set_tag(system_tag);
system_packages->add(std::tr1::shared_ptr<SetSpecTree::ConstItem>(new TreeLeaf<SetSpecTree, PackageDepSpec>(spec)));
@@ -501,8 +502,9 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
QualifiedPackageName v(tokens[0]);
virtuals.erase(v);
virtuals.insert(std::make_pair(v, std::tr1::shared_ptr<PackageDepSpec>(new PackageDepSpec(
- erepository::parse_e_package_dep_spec(tokens[1], *erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi), std::tr1::shared_ptr<const PackageID>())))));
+ parse_elike_package_dep_spec(tokens[1], (*(*erepository::EAPIData::get_instance()->eapi_from_string(
+ repository->params().profile_eapi))[k::supported()])[k::package_dep_spec_parse_options()],
+ std::tr1::shared_ptr<const PackageID>())))));
}
}
catch (const InternalError &)
@@ -524,8 +526,9 @@ Implementation<ERepositoryProfile>::make_vars_from_file_vars()
try
{
std::tr1::shared_ptr<const PackageDepSpec> a(new PackageDepSpec(
- erepository::parse_e_package_dep_spec(line->first, *erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi), std::tr1::shared_ptr<const PackageID>())));
+ parse_elike_package_dep_spec(line->first, (*(*erepository::EAPIData::get_instance()->eapi_from_string(
+ repository->params().profile_eapi))[k::supported()])[k::package_dep_spec_parse_options()],
+ std::tr1::shared_ptr<const PackageID>())));
if (a->package_ptr())
package_mask[*a->package_ptr()].push_back(std::make_pair(a, line->second));
@@ -606,8 +609,9 @@ Implementation<ERepositoryProfile>::load_spec_use_file(const FSEntry & file, Pac
try
{
std::tr1::shared_ptr<const PackageDepSpec> spec(new PackageDepSpec(
- erepository::parse_e_package_dep_spec(*tokens.begin(), *erepository::EAPIData::get_instance()->eapi_from_string(
- repository->params().profile_eapi), std::tr1::shared_ptr<const PackageID>())));
+ parse_elike_package_dep_spec(*tokens.begin(), (*(*erepository::EAPIData::get_instance()->eapi_from_string(
+ repository->params().profile_eapi))[k::supported()])[k::package_dep_spec_parse_options()],
+ std::tr1::shared_ptr<const PackageID>())));
PackageFlagStatusMapList::iterator n(m.insert(m.end(), std::make_pair(spec, FlagStatusMap())));
for (std::list<std::string>::const_iterator t(next(tokens.begin())), t_end(tokens.end()) ;
diff --git a/paludis/repositories/e/e_repository_sets.cc b/paludis/repositories/e/e_repository_sets.cc
index 9373836..1cfee89 100644
--- a/paludis/repositories/e/e_repository_sets.cc
+++ b/paludis/repositories/e/e_repository_sets.cc
@@ -22,7 +22,6 @@
#include <paludis/repositories/e/e_repository_sets.hh>
#include <paludis/repositories/e/glsa.hh>
#include <paludis/repositories/e/dep_parser.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/environment.hh>
#include <paludis/util/config_file.hh>
@@ -44,6 +43,8 @@
#include <paludis/util/set.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/elike_slot_requirement.hh>
#include <tr1/functional>
#include <algorithm>
#include <list>
@@ -296,7 +297,7 @@ ERepositorySets::security_set(bool insecurity) const
_imp->environment->package_database()->query(
query::Matches(make_package_dep_spec()
.package(glsa_pkg->name())
- .slot_requirement(make_shared_ptr(new erepository::ESlotExactRequirement((*c)->slot(), false)))) &
+ .slot_requirement(make_shared_ptr(new ELikeSlotExactRequirement((*c)->slot(), false)))) &
query::SupportsAction<InstallAction>() &
query::NotMasked(),
qo_order_by_version));
diff --git a/paludis/repositories/e/eapi-fwd.hh b/paludis/repositories/e/eapi-fwd.hh
index a108254..f5b779b 100644
--- a/paludis/repositories/e/eapi-fwd.hh
+++ b/paludis/repositories/e/eapi-fwd.hh
@@ -25,6 +25,7 @@
#include <paludis/repositories/e/dep_parser-fwd.hh>
#include <paludis/merger-fwd.hh>
#include <paludis/name-fwd.hh>
+#include <paludis/elike_package_dep_spec-fwd.hh>
#include <tr1/memory>
namespace paludis
@@ -74,7 +75,7 @@ namespace paludis
* \nosubgrouping
*/
typedef kc::KeyedClass<
- kc::Field<k::package_dep_spec_parse_options, erepository::PackageDepSpecParseOptions>,
+ kc::Field<k::package_dep_spec_parse_options, ELikePackageDepSpecOptions>,
kc::Field<k::dependency_spec_tree_parse_options, erepository::DependencySpecTreeParseOptions>,
kc::Field<k::iuse_flag_parse_options, IUseFlagParseOptions>,
kc::Field<k::merger_options, MergerOptions>,
diff --git a/paludis/repositories/e/eapi.cc b/paludis/repositories/e/eapi.cc
index 84fa22b..ffe2b6b 100644
--- a/paludis/repositories/e/eapi.cc
+++ b/paludis/repositories/e/eapi.cc
@@ -71,14 +71,14 @@ namespace paludis
predefined->insert("PALUDIS_EAPIS_DIR", stringify(d->dirname()));
KeyValueConfigFile k(*d, KeyValueConfigFileOptions(), predefined);
- PackageDepSpecParseOptions package_dep_spec_parse_options;
+ ELikePackageDepSpecOptions package_dep_spec_parse_options;
{
std::list<std::string> package_dep_spec_parse_options_tokens;
tokenise_whitespace(k.get("package_dep_spec_parse_options"), std::back_inserter(package_dep_spec_parse_options_tokens));
for (std::list<std::string>::const_iterator t(package_dep_spec_parse_options_tokens.begin()),
t_end(package_dep_spec_parse_options_tokens.end()) ;
t != t_end ; ++t)
- package_dep_spec_parse_options += destringify<PackageDepSpecParseOption>(*t);
+ package_dep_spec_parse_options += destringify<ELikePackageDepSpecOption>(*t);
}
DependencySpecTreeParseOptions dependency_spec_tree_parse_options;
diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc
index b1729a5..0c85ca1 100644
--- a/paludis/repositories/e/ebuild.cc
+++ b/paludis/repositories/e/ebuild.cc
@@ -22,7 +22,6 @@
#include <paludis/repositories/e/e_repository.hh>
#include <paludis/repositories/e/eapi.hh>
#include <paludis/repositories/e/dep_parser.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/repositories/e/pipe_command_handler.hh>
#include <paludis/repositories/e/dependencies_rewriter.hh>
diff --git a/paludis/repositories/e/fix_locked_dependencies.cc b/paludis/repositories/e/fix_locked_dependencies.cc
index 81f4994..f1bcadb 100644
--- a/paludis/repositories/e/fix_locked_dependencies.cc
+++ b/paludis/repositories/e/fix_locked_dependencies.cc
@@ -18,18 +18,20 @@
*/
#include <paludis/repositories/e/fix_locked_dependencies.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
+#include <paludis/repositories/e/eapi.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/util/visitor_cast.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/fs_entry.hh>
+#include <paludis/util/options.hh>
#include <paludis/dep_spec.hh>
#include <paludis/query.hh>
#include <paludis/environment.hh>
#include <paludis/package_database.hh>
#include <paludis/package_id.hh>
+#include <paludis/elike_slot_requirement.hh>
#include <tr1/functional>
#include <algorithm>
#include <list>
@@ -141,8 +143,9 @@ namespace
if (matches->empty())
break;
- PackageDepSpec new_s(partial_parse_e_package_dep_spec(stringify(s), eapi, id).slot_requirement(
- make_shared_ptr(new ESlotExactRequirement((*matches->last())->slot(), true))));
+ PackageDepSpec new_s(partial_parse_elike_package_dep_spec(stringify(s),
+ (*eapi[k::supported()])[k::package_dep_spec_parse_options()], id).slot_requirement(
+ make_shared_ptr(new ELikeSlotExactRequirement((*matches->last())->slot(), true))));
c.reset(new TreeLeaf<DependencySpecTree, PackageDepSpec>(std::tr1::static_pointer_cast<PackageDepSpec>(
PackageDepSpec(new_s).clone())));
diff --git a/paludis/repositories/e/package_dep_spec.hh b/paludis/repositories/e/package_dep_spec.hh
deleted file mode 100644
index 1f19641..0000000
--- a/paludis/repositories/e/package_dep_spec.hh
+++ /dev/null
@@ -1,69 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2007, 2008 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_REPOSITORIES_E_PACKAGE_DEP_SPEC_HH
-#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_PACKAGE_DEP_SPEC_HH 1
-
-#include <paludis/dep_spec-fwd.hh>
-#include <paludis/package_id-fwd.hh>
-#include <paludis/repositories/e/eapi-fwd.hh>
-#include <paludis/slot_requirement.hh>
-#include <paludis/name.hh>
-
-namespace paludis
-{
- namespace erepository
- {
- PackageDepSpec parse_e_package_dep_spec(const std::string &, const EAPI & eapi,
- const std::tr1::shared_ptr<const PackageID> & id) PALUDIS_VISIBLE;
-
- PartiallyMadePackageDepSpec partial_parse_e_package_dep_spec(const std::string &, const EAPI & eapi,
- const std::tr1::shared_ptr<const PackageID> & id) PALUDIS_VISIBLE;
-
- class ESlotExactRequirement :
- public SlotExactRequirement
- {
- private:
- const SlotName _s;
- const bool _e;
-
- public:
- ESlotExactRequirement(const SlotName &, const bool equals);
-
- virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const SlotName slot() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- class ESlotAnyUnlockedRequirement :
- public SlotAnyUnlockedRequirement
- {
- public:
- virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- class ESlotAnyLockedRequirement :
- public SlotAnyLockedRequirement
- {
- public:
- virtual const std::string as_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
- }
-}
-
-#endif
diff --git a/paludis/repositories/e/pipe_command_handler.cc b/paludis/repositories/e/pipe_command_handler.cc
index fe78f0d..09d268e 100644
--- a/paludis/repositories/e/pipe_command_handler.cc
+++ b/paludis/repositories/e/pipe_command_handler.cc
@@ -19,7 +19,6 @@
#include <paludis/repositories/e/pipe_command_handler.hh>
#include <paludis/repositories/e/eapi.hh>
-#include <paludis/repositories/e/package_dep_spec.hh>
#include <paludis/repositories/e/fix_locked_dependencies.hh>
#include <paludis/repositories/e/dep_parser.hh>
#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
@@ -104,7 +103,8 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
if (! (*eapi)[k::supported()])
return "EBEST_VERSION EAPI " + tokens[1] + " unsupported";
- PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, package_id));
+ PackageDepSpec spec(parse_elike_package_dep_spec(tokens[2], (*(*eapi)[k::supported()])[k::package_dep_spec_parse_options()],
+ package_id));
std::tr1::shared_ptr<const PackageIDSequence> entries(environment->package_database()->query(
query::Matches(spec) & query::InstalledAtRoot(environment->root()), qo_order_by_version));
if ((*(*eapi)[k::supported()])[k::pipe_commands()][k::rewrite_virtuals()] && (! entries->empty()) &&
@@ -143,7 +143,8 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
if (! (*eapi)[k::supported()])
return "EHAS_VERSION EAPI " + tokens[1] + " unsupported";
- PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, package_id));
+ PackageDepSpec spec(parse_elike_package_dep_spec(tokens[2], (*(*eapi)[k::supported()])[k::package_dep_spec_parse_options()],
+ package_id));
std::tr1::shared_ptr<const PackageIDSequence> entries(environment->package_database()->query(
query::Matches(spec) & query::InstalledAtRoot(environment->root()), qo_order_by_version));
if (entries->empty())
@@ -165,7 +166,8 @@ paludis::erepository::pipe_command_handler(const Environment * const environment
if (! (*eapi)[k::supported()])
return "EMATCH EAPI " + tokens[1] + " unsupported";
- PackageDepSpec spec(erepository::parse_e_package_dep_spec(tokens[2], *eapi, package_id));
+ PackageDepSpec spec(parse_elike_package_dep_spec(tokens[2], (*(*eapi)[k::supported()])[k::package_dep_spec_parse_options()],
+ package_id));
std::tr1::shared_ptr<const PackageIDSequence> entries(environment->package_database()->query(
query::Matches(spec) & query::InstalledAtRoot(environment->root()), qo_order_by_version));
if ((*(*eapi)[k::supported()])[k::pipe_commands()][k::rewrite_virtuals()] && (! entries->empty()))
diff --git a/paludis/repositories/e/qa/extractors.cc b/paludis/repositories/e/qa/extractors.cc
index 258da99..c916b59 100644
--- a/paludis/repositories/e/qa/extractors.cc
+++ b/paludis/repositories/e/qa/extractors.cc
@@ -31,7 +31,7 @@
#include <paludis/util/options.hh>
#include <paludis/util/log.hh>
#include <paludis/util/instantiation_policy-impl.hh>
-#include <paludis/repositories/e/conditional_dep_spec.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
#include <tr1/functional>
#include <algorithm>
#include <map>
@@ -118,7 +118,7 @@ namespace
GenericSpecTree::ConstSequenceIterator end)
{
Save<std::set<UseFlagName> > save_current(&current);
- current.insert(conditional_dep_spec_flag(u));
+ current.insert(elike_conditional_dep_spec_flag(u));
std::for_each(cur, end, accept_visitor(*this));
}
@@ -236,8 +236,8 @@ namespace
{
Save<std::map<UseFlagName, bool> > save_current(&current);
std::pair<std::map<UseFlagName, bool>::const_iterator, bool> p(current.insert(std::make_pair(
- conditional_dep_spec_flag(u), ! conditional_dep_spec_is_inverse(u))));
- if (p.second || (p.first->second == ! conditional_dep_spec_is_inverse(u)))
+ elike_conditional_dep_spec_flag(u), ! elike_conditional_dep_spec_is_inverse(u))));
+ if (p.second || (p.first->second == ! elike_conditional_dep_spec_is_inverse(u)))
std::for_each(cur, end, accept_visitor(*this));
}
diff --git a/paludis/repositories/e/qa/spec_keys.cc b/paludis/repositories/e/qa/spec_keys.cc
index 6954ad3..9a421e6 100644
--- a/paludis/repositories/e/qa/spec_keys.cc
+++ b/paludis/repositories/e/qa/spec_keys.cc
@@ -38,7 +38,7 @@
#include <paludis/util/log.hh>
#include <paludis/util/instantiation_policy-impl.hh>
#include <paludis/util/create_iterator-impl.hh>
-#include <paludis/repositories/e/conditional_dep_spec.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
#include <algorithm>
#include <map>
#include <set>
@@ -183,34 +183,34 @@ namespace
.with_associated_id(id)
.with_associated_key(id, key));
- if (uses.count(conditional_dep_spec_flag(u)))
+ if (uses.count(elike_conditional_dep_spec_flag(u)))
reporter.message(QAMessage(entry, qaml_normal, name,
- "Recursive use of flag '" + stringify(conditional_dep_spec_flag(u)) + "' in '"
+ "Recursive use of flag '" + stringify(elike_conditional_dep_spec_flag(u)) + "' in '"
+ stringify(key->raw_name()) + "'")
.with_associated_id(id)
.with_associated_key(id, key));
- if ((*id->repository())[k::use_interface()]->arch_flags()->count(conditional_dep_spec_flag(u)))
+ if ((*id->repository())[k::use_interface()]->arch_flags()->count(elike_conditional_dep_spec_flag(u)))
{
if (forbid_arch_flags)
reporter.message(QAMessage(entry, qaml_normal, name,
- "Arch flag '" + stringify(conditional_dep_spec_flag(u)) + "' in '" + stringify(key->raw_name()) + "'")
+ "Arch flag '" + stringify(elike_conditional_dep_spec_flag(u)) + "' in '" + stringify(key->raw_name()) + "'")
.with_associated_id(id)
.with_associated_key(id, key));
- else if (conditional_dep_spec_is_inverse(u) && forbid_inverse_arch_flags)
+ else if (elike_conditional_dep_spec_is_inverse(u) && forbid_inverse_arch_flags)
reporter.message(QAMessage(entry, qaml_maybe, name,
- "Inverse arch flag '" + stringify(conditional_dep_spec_flag(u)) + "' in '" + stringify(key->raw_name()) + "'")
+ "Inverse arch flag '" + stringify(elike_conditional_dep_spec_flag(u)) + "' in '" + stringify(key->raw_name()) + "'")
.with_associated_id(id)
.with_associated_key(id, key));
}
else
{
- if (iuse_flags.end() == iuse_flags.find(conditional_dep_spec_flag(u)))
+ if (iuse_flags.end() == iuse_flags.find(elike_conditional_dep_spec_flag(u)))
{
std::tr1::shared_ptr<const UseFlagNameSet> c(
(*id->repository())[k::use_interface()]->use_expand_hidden_prefixes());
- std::string flag(stringify(conditional_dep_spec_flag(u)));
+ std::string flag(stringify(elike_conditional_dep_spec_flag(u)));
bool is_hidden(false);
for (UseFlagNameSet::ConstIterator i(c->begin()), i_end(c->end()) ;
@@ -226,7 +226,7 @@ namespace
if (! is_hidden)
reporter.message(QAMessage(entry, qaml_normal, name,
- "Conditional flag '" + stringify(conditional_dep_spec_flag(u)) +
+ "Conditional flag '" + stringify(elike_conditional_dep_spec_flag(u)) +
"' in '" + stringify(key->raw_name()) + "' not in '" +
stringify(id->iuse_key()->raw_name()) + "'")
.with_associated_id(id)
@@ -238,7 +238,7 @@ namespace
Save<unsigned> save_level(&level, level + 1);
Save<bool> save_child_of_any(&child_of_any, false);
Save<std::set<UseFlagName> > save_uses(&uses, uses);
- uses.insert(conditional_dep_spec_flag(u));
+ uses.insert(elike_conditional_dep_spec_flag(u));
if (cur == end)
reporter.message(QAMessage(entry, qaml_normal, name,
"Empty 'use? ( )' in '" + stringify(key->raw_name()) + "'")
diff --git a/paludis/repositories/e/qa/visibility.cc b/paludis/repositories/e/qa/visibility.cc
index da00fc7..5652653 100644
--- a/paludis/repositories/e/qa/visibility.cc
+++ b/paludis/repositories/e/qa/visibility.cc
@@ -19,7 +19,6 @@
#include <paludis/repositories/e/qa/visibility.hh>
#include <paludis/repositories/e/dep_spec_pretty_printer.hh>
-#include <paludis/repositories/e/conditional_dep_spec.hh>
#include <paludis/util/exception.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/tokeniser.hh>
@@ -37,6 +36,7 @@
#include <paludis/version_requirements.hh>
#include <paludis/metadata_key.hh>
#include <paludis/stringify_formatter.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
#include <set>
#include <algorithm>
@@ -205,8 +205,8 @@ namespace
DependencySpecTree::ConstSequenceIterator end)
{
viable =
- ((! conditional_dep_spec_is_inverse(u)) && (! (*profile)[k::profile()]->use_masked(conditional_dep_spec_flag(u), *id))) ||
- ((conditional_dep_spec_is_inverse(u)) && (! (*profile)[k::profile()]->use_forced(conditional_dep_spec_flag(u), *id)));
+ ((! elike_conditional_dep_spec_is_inverse(u)) && (! (*profile)[k::profile()]->use_masked(elike_conditional_dep_spec_flag(u), *id))) ||
+ ((elike_conditional_dep_spec_is_inverse(u)) && (! (*profile)[k::profile()]->use_forced(elike_conditional_dep_spec_flag(u), *id)));
if (viable)
std::for_each(cur, end, accept_visitor(*this));
diff --git a/paludis/repositories/e/use_requirements.cc b/paludis/repositories/e/use_requirements.cc
deleted file mode 100644
index c315946..0000000
--- a/paludis/repositories/e/use_requirements.cc
+++ /dev/null
@@ -1,223 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2007, 2008 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/repositories/e/use_requirements.hh>
-#include <paludis/util/stringify.hh>
-#include <paludis/environment.hh>
-
-using namespace paludis;
-using namespace paludis::erepository;
-
-UseRequirement::UseRequirement(const std::string & r, const UseFlagName & f) :
- _raw(r),
- _name(f)
-{
-}
-
-const std::string
-UseRequirement::as_raw_string() const
-{
- return _raw;
-}
-
-EnabledUseRequirement::EnabledUseRequirement(const std::string & s, const UseFlagName & n) :
- UseRequirement(s, n)
-{
-}
-
-EnabledUseRequirement::~EnabledUseRequirement()
-{
-}
-
-bool
-EnabledUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return env->query_use(flag(), pkg);
-}
-
-const std::string
-EnabledUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' enabled";
-}
-
-DisabledUseRequirement::DisabledUseRequirement(const std::string & s, const UseFlagName & n) :
- UseRequirement(s, n)
-{
-}
-
-DisabledUseRequirement::~DisabledUseRequirement()
-{
-}
-
-bool
-DisabledUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return ! env->query_use(flag(), pkg);
-}
-
-const std::string
-DisabledUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' disabled";
-}
-
-ConditionalUseRequirement::ConditionalUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- UseRequirement(s, n),
- _id(i)
-{
-}
-
-ConditionalUseRequirement::~ConditionalUseRequirement()
-{
-}
-
-IfMineThenUseRequirement::IfMineThenUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-IfMineThenUseRequirement::~IfMineThenUseRequirement()
-{
-}
-
-bool
-IfMineThenUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return ! env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
-}
-
-const std::string
-IfMineThenUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' enabled if it is enabled for '" + stringify(*package_id()) + "'";
-}
-
-IfNotMineThenUseRequirement::IfNotMineThenUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-IfNotMineThenUseRequirement::~IfNotMineThenUseRequirement()
-{
-}
-
-bool
-IfNotMineThenUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return env->query_use(flag(), *package_id()) || env->query_use(flag(), pkg);
-}
-
-const std::string
-IfNotMineThenUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' enabled if it is disabled for '" + stringify(*package_id()) + "'";
-}
-
-IfMineThenNotUseRequirement::IfMineThenNotUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-IfMineThenNotUseRequirement::~IfMineThenNotUseRequirement()
-{
-}
-
-const std::string
-IfMineThenNotUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' disabled if it is enabled for '" + stringify(*package_id()) + "'";
-}
-
-bool
-IfMineThenNotUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return ! env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
-}
-
-IfNotMineThenNotUseRequirement::IfNotMineThenNotUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-IfNotMineThenNotUseRequirement::~IfNotMineThenNotUseRequirement()
-{
-}
-
-bool
-IfNotMineThenNotUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return env->query_use(flag(), *package_id()) || ! env->query_use(flag(), pkg);
-}
-
-const std::string
-IfNotMineThenNotUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' disabled if it is disabled for '" + stringify(*package_id()) + "'";
-}
-
-EqualUseRequirement::EqualUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-EqualUseRequirement::~EqualUseRequirement()
-{
-}
-
-bool
-EqualUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return env->query_use(flag(), pkg) == env->query_use(flag(), *package_id());
-}
-
-const std::string
-EqualUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' enabled or disabled like it is for '" + stringify(*package_id()) + "'";
-}
-
-NotEqualUseRequirement::NotEqualUseRequirement(const std::string & s,
- const UseFlagName & n, const std::tr1::shared_ptr<const PackageID> & i) :
- ConditionalUseRequirement(s, n, i)
-{
-}
-
-NotEqualUseRequirement::~NotEqualUseRequirement()
-{
-}
-
-bool
-NotEqualUseRequirement::requirement_met(const Environment * const env, const PackageID & pkg) const
-{
- return env->query_use(flag(), pkg) != env->query_use(flag(), *package_id());
-}
-
-const std::string
-NotEqualUseRequirement::as_human_string() const
-{
- return "Flag '" + stringify(flag()) + "' enabled or disabled opposite to how it is for '" + stringify(*package_id()) + "'";
-}
-
diff --git a/paludis/repositories/e/use_requirements.hh b/paludis/repositories/e/use_requirements.hh
deleted file mode 100644
index c041d42..0000000
--- a/paludis/repositories/e/use_requirements.hh
+++ /dev/null
@@ -1,256 +0,0 @@
-/* vim: set sw=4 sts=4 et foldmethod=syntax : */
-
-/*
- * Copyright (c) 2005, 2006, 2007, 2008 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_USE_REQUIREMENTS_HH
-#define PALUDIS_GUARD_PALUDIS_USE_REQUIREMENTS_HH 1
-
-#include <paludis/dep_spec.hh>
-#include <paludis/environment-fwd.hh>
-#include <paludis/package_id-fwd.hh>
-#include <paludis/name.hh>
-
-namespace paludis
-{
- namespace erepository
- {
- class PALUDIS_VISIBLE UseRequirement :
- public AdditionalPackageDepSpecRequirement
- {
- private:
- const std::string _raw;
- const UseFlagName _name;
-
- public:
- ///\name Basic operations
- ///\{
-
- UseRequirement(const std::string &, const UseFlagName &);
-
- ///\}
-
- /// Our use flag.
- const UseFlagName flag() const PALUDIS_ATTRIBUTE((warn_unused_result))
- {
- return _name;
- }
-
- virtual const std::string as_raw_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * An enabled requirement for a use flag.
- *
- * \since 0.26
- */
- class PALUDIS_VISIBLE EnabledUseRequirement :
- public UseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- EnabledUseRequirement(const std::string &, const UseFlagName &);
- ~EnabledUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- class PALUDIS_VISIBLE DisabledUseRequirement :
- public UseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- DisabledUseRequirement(const std::string &, const UseFlagName &);
- ~DisabledUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * A use requirement that depends on the use flags of the package
- * it appears in.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE ConditionalUseRequirement :
- public UseRequirement
- {
- private:
- const std::tr1::shared_ptr<const PackageID> _id;
-
- public:
- ///\name Basic operations
- ///\{
-
- ConditionalUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~ConditionalUseRequirement();
-
- ///\}
-
- /// Our package.
- const std::tr1::shared_ptr<const PackageID> package_id() const PALUDIS_ATTRIBUTE((warn_unused_result))
- {
- return _id;
- }
- };
-
- /**
- * An if-then requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE IfMineThenUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- IfMineThenUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~IfMineThenUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * An if-not-then requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE IfNotMineThenUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- IfNotMineThenUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~IfNotMineThenUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * An if-then-not requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE IfMineThenNotUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- IfMineThenNotUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~IfMineThenNotUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * An if-not-then-not requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE IfNotMineThenNotUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- IfNotMineThenNotUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~IfNotMineThenNotUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * An equal requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE EqualUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- EqualUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~EqualUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
-
- /**
- * A not equal requirement for a use flag.
- *
- * \since 0.26
- * \ingroup g_dep_spec
- */
- class PALUDIS_VISIBLE NotEqualUseRequirement :
- public ConditionalUseRequirement
- {
- public:
- ///\name Basic operations
- ///\{
-
- NotEqualUseRequirement(const std::string &, const UseFlagName &, const std::tr1::shared_ptr<const PackageID> &);
- ~NotEqualUseRequirement();
-
- ///\}
-
- virtual bool requirement_met(const Environment * const, const PackageID &) const PALUDIS_ATTRIBUTE((warn_unused_result));
- virtual const std::string as_human_string() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
- }
-}
-
-#endif
diff --git a/paludis/repositories/fake/Makefile.am b/paludis/repositories/fake/Makefile.am
index 35f60d6..38fd99d 100644
--- a/paludis/repositories/fake/Makefile.am
+++ b/paludis/repositories/fake/Makefile.am
@@ -22,7 +22,7 @@ TESTS_ENVIRONMENT = env \
$(top_srcdir)/paludis/repositories/e/ebuild/utils/canonicalise $(top_builddir)/paludis/repositories/gems/.libs/`" \
bash $(top_srcdir)/test/run_test.sh
-TESTS = fake_repository_TEST fake_installed_repository_TEST
+TESTS = fake_repository_TEST fake_installed_repository_TEST dep_parser_TEST
check_PROGRAMS = $(TESTS)
EXTRA_DIST = \
@@ -30,11 +30,11 @@ EXTRA_DIST = \
fake_installed_repository_TEST.cc \
fake_repository-sr.hh \
fake_repository-sr.cc \
- fake_repository.sr
+ fake_repository.sr \
+ dep_parser_TEST.cc
fake_repository_TEST_LDADD = \
libpaludisfakerepository.la \
- $(top_builddir)/paludis/repositories/e/libpaludiserepository.la \
$(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
$(top_builddir)/paludis/util/libpaludisutil.la \
$(top_builddir)/paludis/util/test_extras.o \
@@ -43,7 +43,14 @@ fake_repository_TEST_LDADD = \
fake_installed_repository_TEST_LDADD = \
libpaludisfakerepository.la \
- $(top_builddir)/paludis/repositories/e/libpaludiserepository.la \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/test/libtest.a
+
+dep_parser_TEST_LDADD = \
+ libpaludisfakerepository.la \
$(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
$(top_builddir)/paludis/util/libpaludisutil.la \
$(top_builddir)/paludis/util/test_extras.o \
@@ -56,16 +63,19 @@ fake_repository_TEST_SOURCES = \
fake_installed_repository_TEST_SOURCES = \
fake_installed_repository_TEST.cc
+dep_parser_TEST_SOURCES = \
+ dep_parser_TEST.cc
+
paludis_repositories_lib_LTLIBRARIES = libpaludisfakerepository.la
libpaludisfakerepository_la_SOURCES = \
+ dep_parser.cc dep_parser.hh \
fake_repository_base.cc fake_repository_base.hh \
fake_repository.cc fake_repository.hh \
fake_installed_repository.cc fake_installed_repository.hh \
fake_package_id.cc fake_package_id.hh
libpaludisfakerepository_la_LIBADD = \
- $(top_builddir)/paludis/repositories/e/libpaludiserepository.la \
$(top_builddir)/paludis/libpaludis.la \
$(top_builddir)/paludis/util/libpaludisutil.la
@@ -73,6 +83,7 @@ libpaludisfakerepository_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSI
paludis_repositories_fake_includedir = $(includedir)/paludis-$(PALUDIS_PC_SLOT)/paludis/repositories/fake/
paludis_repositories_fake_include_HEADERS = \
+ dep_parser.hh \
fake_repository.hh \
fake_repository_base.hh \
fake_installed_repository.hh \
diff --git a/paludis/repositories/fake/dep_parser.cc b/paludis/repositories/fake/dep_parser.cc
new file mode 100644
index 0000000..68c673b
--- /dev/null
+++ b/paludis/repositories/fake/dep_parser.cc
@@ -0,0 +1,347 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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/repositories/fake/dep_parser.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/keys.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/options.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/elike_dep_parser.hh>
+#include <paludis/elike_conditional_dep_spec.hh>
+#include <paludis/elike_package_dep_spec.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/environment.hh>
+#include <paludis/repository.hh>
+#include <paludis/package_id.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::fakerepository;
+
+FakeDepParseError::FakeDepParseError(const std::string & s, const std::string & t) throw () :
+ Exception("Error parsing '" + s + "': " + t)
+{
+}
+
+namespace
+{
+ template <typename T_>
+ struct ParseStackTypes
+ {
+ typedef std::tr1::function<void (const std::tr1::shared_ptr<const typename T_::ConstItem> &)> AddHandler;
+
+ typedef kc::KeyedClass<
+ kc::Field<k::add_handler, AddHandler>,
+ kc::Field<k::item, const std::tr1::shared_ptr<const typename T_::ConstItem> >
+ > Item;
+
+ typedef std::list<Item> Stack;
+ };
+
+ template <typename T_>
+ void package_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ PackageDepSpec p(parse_elike_package_dep_spec(s, ELikePackageDepSpecOptions() + epdso_allow_slot_deps
+ + epdso_allow_slot_star_deps + epdso_allow_slot_equal_deps + epdso_allow_repository_deps
+ + epdso_allow_square_bracket_deps + epdso_allow_tilde_greater_deps + epdso_strict_star_operator
+ + epdso_strict_parsing, id));
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, PackageDepSpec>(make_shared_ptr(new PackageDepSpec(p)))));
+ }
+
+ template <typename T_>
+ void package_or_block_dep_spec_string_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s,
+ const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ if ((! s.empty()) && ('!' == s.at(0)))
+ {
+ std::tr1::shared_ptr<BlockDepSpec> b(new BlockDepSpec(
+ make_shared_ptr(new PackageDepSpec(parse_elike_package_dep_spec(s.substr(1),
+ ELikePackageDepSpecOptions() + epdso_allow_slot_deps
+ + epdso_allow_slot_star_deps + epdso_allow_slot_equal_deps + epdso_allow_repository_deps
+ + epdso_allow_square_bracket_deps + epdso_allow_tilde_greater_deps + epdso_strict_star_operator
+ + epdso_strict_parsing, id)))));
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, BlockDepSpec>(b)));
+ }
+ else
+ package_dep_spec_string_handler<T_>(h, s, id);
+ }
+
+ template <typename T_>
+ void license_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
+ {
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, LicenseDepSpec>(make_shared_ptr(new LicenseDepSpec(s)))));
+ }
+
+ template <typename T_>
+ void simple_uri_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s)
+ {
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, SimpleURIDepSpec>(make_shared_ptr(new SimpleURIDepSpec(s)))));
+ }
+
+ template <typename T_>
+ void arrow_handler(const typename ParseStackTypes<T_>::Stack & h, const std::string & s, const std::string & t)
+ {
+ (*h.begin())[k::add_handler()](make_shared_ptr(new TreeLeaf<T_, FetchableURIDepSpec>(make_shared_ptr(
+ new FetchableURIDepSpec(t.empty() ? s : s + " -> " + t)))));
+ }
+
+ void any_not_allowed_handler(const std::string & s) PALUDIS_ATTRIBUTE((noreturn));
+
+ void any_not_allowed_handler(const std::string & s)
+ {
+ throw FakeDepParseError(s, "Any dep specs not allowed here");
+ }
+
+ void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
+
+ void arrows_not_allowed_handler(const std::string & s, const std::string & f, const std::string & t)
+ {
+ throw FakeDepParseError(s, "Arrow '" + f + " -> " + t + "' not allowed here");
+ }
+
+ void error_handler(const std::string & s, const std::string & t) PALUDIS_ATTRIBUTE((noreturn));
+
+ void error_handler(const std::string & s, const std::string & t)
+ {
+ throw FakeDepParseError(s, t);
+ }
+
+ void labels_not_allowed_handler(const std::string & s, const std::string & f) PALUDIS_ATTRIBUTE((noreturn));
+
+ void labels_not_allowed_handler(const std::string & s, const std::string & f)
+ {
+ throw FakeDepParseError(s, "Label '" + f + "' not allowed here");
+ }
+
+ template <typename T_, typename A_>
+ void any_all_handler(typename ParseStackTypes<T_>::Stack & stack)
+ {
+ using namespace std::tr1::placeholders;
+ std::tr1::shared_ptr<ConstTreeSequence<T_, A_> > item(
+ new ConstTreeSequence<T_, A_>(make_shared_ptr(new A_)));
+ (*stack.begin())[k::add_handler()](item);
+ stack.push_front(ParseStackTypes<T_>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<T_, A_>::add, item.get(), _1))
+ (k::item(), item)
+ );
+ }
+
+ template <typename T_>
+ void use_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & u,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+ {
+ using namespace std::tr1::placeholders;
+ std::tr1::shared_ptr<ConstTreeSequence<T_, ConditionalDepSpec> > item(
+ new ConstTreeSequence<T_, ConditionalDepSpec>(make_shared_ptr(new ConditionalDepSpec(
+ parse_elike_conditional_dep_spec(u, env, id)))));
+ (*stack.begin())[k::add_handler()](item);
+ stack.push_front(ParseStackTypes<T_>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<T_, ConditionalDepSpec>::add, item.get(), _1))
+ (k::item(), item)
+ );
+ }
+
+ template <typename T_>
+ void pop_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
+ {
+ stack.pop_front();
+ if (stack.empty())
+ throw FakeDepParseError(s, "Too many ')'s");
+ }
+
+ template <typename T_>
+ void should_be_empty_handler(typename ParseStackTypes<T_>::Stack & stack, const std::string & s)
+ {
+ if (1 != stack.size())
+ throw FakeDepParseError(s, "Nesting error");
+ }
+
+ void do_nothing()
+ {
+ }
+}
+
+std::tr1::shared_ptr<DependencySpecTree::ConstItem>
+paludis::fakerepository::parse_depend(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+{
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<DependencySpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<DependencySpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<DependencySpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<DependencySpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<DependencySpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&package_or_block_dep_spec_string_handler<DependencySpecTree>, std::tr1::ref(stack), _1, id))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_all_handler<DependencySpecTree, AnyDepSpec>, std::tr1::ref(stack)))
+ (k::on_all(), std::tr1::bind(&any_all_handler<DependencySpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<DependencySpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<DependencySpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<DependencySpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
+
+std::tr1::shared_ptr<ProvideSpecTree::ConstItem>
+paludis::fakerepository::parse_provide(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+{
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<ProvideSpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<ProvideSpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<ProvideSpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<ProvideSpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<ProvideSpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&package_dep_spec_string_handler<ProvideSpecTree>, std::tr1::ref(stack), _1, id))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<ProvideSpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<ProvideSpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<ProvideSpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<ProvideSpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
+
+std::tr1::shared_ptr<FetchableURISpecTree::ConstItem>
+paludis::fakerepository::parse_fetchable_uri(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+{
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<FetchableURISpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<FetchableURISpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<FetchableURISpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<FetchableURISpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<FetchableURISpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&arrow_handler<FetchableURISpecTree>, std::tr1::ref(stack), _1, ""))
+ (k::on_arrow(), std::tr1::bind(&arrow_handler<FetchableURISpecTree>, std::tr1::ref(stack), _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<FetchableURISpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<FetchableURISpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<FetchableURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<FetchableURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
+
+std::tr1::shared_ptr<SimpleURISpecTree::ConstItem>
+paludis::fakerepository::parse_simple_uri(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+{
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<SimpleURISpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<SimpleURISpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<SimpleURISpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<SimpleURISpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<SimpleURISpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&simple_uri_handler<SimpleURISpecTree>, std::tr1::ref(stack), _1))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_not_allowed_handler, s))
+ (k::on_all(), std::tr1::bind(&any_all_handler<SimpleURISpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<SimpleURISpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<SimpleURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<SimpleURISpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
+
+std::tr1::shared_ptr<LicenseSpecTree::ConstItem>
+paludis::fakerepository::parse_license(const std::string & s,
+ const Environment * const env, const std::tr1::shared_ptr<const PackageID> & id)
+{
+ using namespace std::tr1::placeholders;
+
+ ParseStackTypes<LicenseSpecTree>::Stack stack;
+ std::tr1::shared_ptr<ConstTreeSequence<LicenseSpecTree, AllDepSpec> > top(
+ new ConstTreeSequence<LicenseSpecTree, AllDepSpec>(make_shared_ptr(new AllDepSpec)));
+ stack.push_front(ParseStackTypes<LicenseSpecTree>::Item::named_create()
+ (k::add_handler(), std::tr1::bind(&ConstTreeSequence<LicenseSpecTree, AllDepSpec>::add, top.get(), _1))
+ (k::item(), top)
+ );
+
+ ELikeDepParserCallbacks callbacks(
+ ELikeDepParserCallbacks::named_create()
+ (k::on_string(), std::tr1::bind(&license_handler<LicenseSpecTree>, std::tr1::ref(stack), _1))
+ (k::on_arrow(), std::tr1::bind(&arrows_not_allowed_handler, s, _1, _2))
+ (k::on_any(), std::tr1::bind(&any_all_handler<LicenseSpecTree, AnyDepSpec>, std::tr1::ref(stack)))
+ (k::on_all(), std::tr1::bind(&any_all_handler<LicenseSpecTree, AllDepSpec>, std::tr1::ref(stack)))
+ (k::on_use(), std::tr1::bind(&use_handler<LicenseSpecTree>, std::tr1::ref(stack), _1, env, id))
+ (k::on_label(), std::tr1::bind(&labels_not_allowed_handler, s, _1))
+ (k::on_pop(), std::tr1::bind(&pop_handler<LicenseSpecTree>, std::tr1::ref(stack), s))
+ (k::on_error(), std::tr1::bind(&error_handler, s, _1))
+ (k::on_should_be_empty(), std::tr1::bind(&should_be_empty_handler<LicenseSpecTree>, std::tr1::ref(stack), s))
+ (k::on_use_under_any(), &do_nothing)
+ );
+
+ parse_elike_dependencies(s, callbacks);
+
+ return (*stack.begin())[k::item()];
+}
+
diff --git a/paludis/repositories/fake/dep_parser.hh b/paludis/repositories/fake/dep_parser.hh
new file mode 100644
index 0000000..537a80d
--- /dev/null
+++ b/paludis/repositories/fake/dep_parser.hh
@@ -0,0 +1,77 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_REPOSITORIES_FAKE_DEP_PARSER_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_FAKE_DEP_PARSER_HH 1
+
+#include <paludis/util/exception.hh>
+#include <paludis/dep_tree.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/environment-fwd.hh>
+#include <string>
+#include <tr1/functional>
+
+namespace paludis
+{
+ namespace fakerepository
+ {
+ class PALUDIS_VISIBLE FakeDepParseError :
+ public Exception
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ FakeDepParseError(const std::string & dep_string,
+ const std::string & message) throw ();
+ };
+
+ /**
+ * Parse a dependency heirarchy.
+ */
+ std::tr1::shared_ptr<DependencySpecTree::ConstItem> parse_depend(const std::string & s,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+
+ /**
+ * Parse a provide heirarchy.
+ */
+ std::tr1::shared_ptr<ProvideSpecTree::ConstItem> parse_provide(const std::string & s,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+
+ /**
+ * Parse a fetchable uri heirarchy.
+ */
+ std::tr1::shared_ptr<FetchableURISpecTree::ConstItem> parse_fetchable_uri(const std::string & s,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+
+ /**
+ * Parse a simple uri heirarchy.
+ */
+ std::tr1::shared_ptr<SimpleURISpecTree::ConstItem> parse_simple_uri(const std::string & s,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+
+ /**
+ * Parse a license heirarchy.
+ */
+ std::tr1::shared_ptr<LicenseSpecTree::ConstItem> parse_license(const std::string & s,
+ const Environment * const, const std::tr1::shared_ptr<const PackageID> &) PALUDIS_VISIBLE;
+ }
+}
+
+#endif
diff --git a/paludis/repositories/fake/dep_parser_TEST.cc b/paludis/repositories/fake/dep_parser_TEST.cc
new file mode 100644
index 0000000..a8888cc
--- /dev/null
+++ b/paludis/repositories/fake/dep_parser_TEST.cc
@@ -0,0 +1,105 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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/repositories/fake/dep_parser.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <sstream>
+#include <algorithm>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ struct QuickPrinter :
+ ConstVisitor<DependencySpecTree>
+ {
+ std::stringstream str;
+
+ void visit_leaf(const PackageDepSpec & s)
+ {
+ str << "p<" << stringify(s) << ">";
+ }
+
+ void visit_leaf(const NamedSetDepSpec & s)
+ {
+ str << "s<" << stringify(s) << ">";
+ }
+
+ void visit_leaf(const BlockDepSpec & s)
+ {
+ str << "b<" << stringify(s) << ">";
+ }
+
+ void visit_leaf(const DependencyLabelsDepSpec & s)
+ {
+ str << "l<" << stringify(s) << ">";
+ }
+
+ void visit_sequence(const AllDepSpec &,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+ {
+ str << "all<";
+ std::for_each(cur, end, accept_visitor(*this));
+ str << ">";
+ }
+
+ void visit_sequence(const AnyDepSpec &,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+ {
+ str << "any<";
+ std::for_each(cur, end, accept_visitor(*this));
+ str << ">";
+ }
+
+ void visit_sequence(const ConditionalDepSpec & s,
+ DependencySpecTree::ConstSequenceIterator cur,
+ DependencySpecTree::ConstSequenceIterator end)
+ {
+ str << "cond<" << s << ",";
+ std::for_each(cur, end, accept_visitor(*this));
+ str << ">";
+ }
+ };
+}
+
+namespace test_cases
+{
+ struct DepParserTest : TestCase
+ {
+ DepParserTest() : TestCase("dep parser") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<DependencySpecTree::ConstItem> d(fakerepository::parse_depend(
+ "( ( a/a b/b ) )", &env, std::tr1::shared_ptr<const PackageID>()));
+
+ QuickPrinter p;
+ d->accept(p);
+ TEST_CHECK_EQUAL(p.str.str(), "all<all<all<p<a/a>p<b/b>>>>");
+ }
+ } dep_parser_test;
+}
+
diff --git a/paludis/repositories/fake/fake_installed_repository.cc b/paludis/repositories/fake/fake_installed_repository.cc
index de63e86..b8409ce 100644
--- a/paludis/repositories/fake/fake_installed_repository.cc
+++ b/paludis/repositories/fake/fake_installed_repository.cc
@@ -66,8 +66,7 @@ FakeInstalledRepository::FakeInstalledRepository(const Environment * const e, co
(k::make_virtuals_interface(), static_cast<RepositoryMakeVirtualsInterface *>(0))
(k::qa_interface(), static_cast<RepositoryQAInterface *>(0))
(k::hook_interface(), static_cast<RepositoryHookInterface *>(0))
- (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0)),
- "0"),
+ (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0))),
PrivateImplementationPattern<FakeInstalledRepository>(new Implementation<FakeInstalledRepository>),
_imp(PrivateImplementationPattern<FakeInstalledRepository>::_imp)
{
diff --git a/paludis/repositories/fake/fake_package_id.cc b/paludis/repositories/fake/fake_package_id.cc
index 07e99dc..e6abafb 100644
--- a/paludis/repositories/fake/fake_package_id.cc
+++ b/paludis/repositories/fake/fake_package_id.cc
@@ -19,8 +19,7 @@
#include <paludis/repositories/fake/fake_package_id.hh>
#include <paludis/repositories/fake/fake_repository_base.hh>
-#include <paludis/repositories/e/dep_parser.hh>
-#include <paludis/repositories/e/eapi.hh>
+#include <paludis/repositories/fake/dep_parser.hh>
#include <paludis/name.hh>
#include <paludis/action.hh>
#include <paludis/environment.hh>
@@ -43,6 +42,7 @@
#include <sstream>
using namespace paludis;
+using namespace paludis::fakerepository;
namespace paludis
{
@@ -364,7 +364,6 @@ namespace paludis
const QualifiedPackageName name;
const VersionSpec version;
SlotName slot;
- std::string eapi;
mutable std::tr1::shared_ptr<DependencyLabelSequence> build_dependencies_labels;
mutable std::tr1::shared_ptr<DependencyLabelSequence> run_dependencies_labels;
@@ -388,22 +387,19 @@ namespace paludis
mutable bool has_masks;
Implementation(const Environment * const e, const std::tr1::shared_ptr<const FakeRepositoryBase> & r,
- const QualifiedPackageName & q, const VersionSpec & v, const PackageID * const id,
- const std::string & my_eapi) :
+ const QualifiedPackageName & q, const VersionSpec & v, const PackageID * const id) :
env(e),
repository(r),
name(q),
version(v),
slot("0"),
- eapi(my_eapi),
build_dependencies_labels(new DependencyLabelSequence),
run_dependencies_labels(new DependencyLabelSequence),
post_dependencies_labels(new DependencyLabelSequence),
suggested_dependencies_labels(new DependencyLabelSequence),
keywords(new FakeMetadataKeywordSetKey("KEYWORDS", "Keywords", "test", mkt_normal, id, env)),
iuse(new FakeMetadataIUseSetKey("IUSE", "Used USE flags", "",
- (*(*erepository::EAPIData::get_instance()->eapi_from_string(eapi))[k::supported()])[k::iuse_flag_parse_options()],
- mkt_normal, id, env)),
+ IUseFlagParseOptions() + iufpo_allow_iuse_defaults + iufpo_strict_parsing, mkt_normal, id, env)),
has_masks(false)
{
build_dependencies_labels->push_back(make_shared_ptr(new DependencyBuildLabel("DEPEND")));
@@ -416,8 +412,8 @@ namespace paludis
}
FakePackageID::FakePackageID(const Environment * const e, const std::tr1::shared_ptr<const FakeRepositoryBase> & r,
- const QualifiedPackageName & q, const VersionSpec & v, const std::string & eapi) :
- PrivateImplementationPattern<FakePackageID>(new Implementation<FakePackageID>(e, r, q, v, this, eapi)),
+ const QualifiedPackageName & q, const VersionSpec & v) :
+ PrivateImplementationPattern<FakePackageID>(new Implementation<FakePackageID>(e, r, q, v, this)),
_imp(PrivateImplementationPattern<FakePackageID>::_imp)
{
add_metadata_key(_imp->keywords);
@@ -677,40 +673,40 @@ FakePackageID::need_keys_added() const
using namespace std::tr1::placeholders;
_imp->build_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("DEPEND", "Build dependencies",
- "", std::tr1::bind(&erepository::parse_depend, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)),
+ "", std::tr1::bind(&parse_depend, _1, _imp->env,
+ shared_from_this()),
_imp->build_dependencies_labels, mkt_dependencies));
_imp->run_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("RDEPEND", "Run dependencies",
- "", std::tr1::bind(&erepository::parse_depend, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)),
+ "", std::tr1::bind(&parse_depend, _1, _imp->env,
+ shared_from_this()),
_imp->run_dependencies_labels, mkt_dependencies)),
_imp->post_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("PDEPEND", "Post dependencies",
- "", std::tr1::bind(&erepository::parse_depend, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)),
+ "", std::tr1::bind(&parse_depend, _1, _imp->env,
+ shared_from_this()),
_imp->post_dependencies_labels, mkt_dependencies)),
_imp->suggested_dependencies.reset(new FakeMetadataSpecTreeKey<DependencySpecTree>("SDEPEND", "Suggested dependencies",
- "", std::tr1::bind(&erepository::parse_depend, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)),
+ "", std::tr1::bind(&parse_depend, _1, _imp->env,
+ shared_from_this()),
_imp->suggested_dependencies_labels, mkt_dependencies)),
_imp->src_uri.reset(new FakeMetadataSpecTreeKey<FetchableURISpecTree>("SRC_URI", "Source URI",
- "", std::tr1::bind(&erepository::parse_fetchable_uri, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)), mkt_normal));
+ "", std::tr1::bind(&parse_fetchable_uri, _1, _imp->env,
+ shared_from_this()), mkt_normal));
_imp->homepage.reset(new FakeMetadataSpecTreeKey<SimpleURISpecTree>("HOMEPAGE", "Homepage",
- "", std::tr1::bind(&erepository::parse_simple_uri, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)), mkt_normal));
+ "", std::tr1::bind(&parse_simple_uri, _1, _imp->env,
+ shared_from_this()), mkt_normal));
_imp->license.reset(new FakeMetadataSpecTreeKey<LicenseSpecTree>("LICENSE", "License",
- "", std::tr1::bind(&erepository::parse_license, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)), mkt_normal));
+ "", std::tr1::bind(&parse_license, _1, _imp->env,
+ shared_from_this()), mkt_normal));
_imp->provide.reset(new FakeMetadataSpecTreeKey<ProvideSpecTree>("PROVIDE", "Provide",
- "", std::tr1::bind(&erepository::parse_provide, _1, _imp->env,
- shared_from_this(), *erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi)), mkt_normal));
+ "", std::tr1::bind(&parse_provide, _1, _imp->env,
+ shared_from_this()), mkt_normal));
add_metadata_key(_imp->build_dependencies);
add_metadata_key(_imp->run_dependencies);
@@ -965,7 +961,7 @@ FakePackageID::transient_key() const
char
FakePackageID::use_expand_separator() const
{
- return (*(*erepository::EAPIData::get_instance()->eapi_from_string(_imp->eapi))[k::supported()])[k::ebuild_options()].use_expand_separator;
+ return '_';
}
std::string
diff --git a/paludis/repositories/fake/fake_package_id.hh b/paludis/repositories/fake/fake_package_id.hh
index 2d68504..97c6b50 100644
--- a/paludis/repositories/fake/fake_package_id.hh
+++ b/paludis/repositories/fake/fake_package_id.hh
@@ -203,7 +203,7 @@ namespace paludis
FakePackageID(const Environment * const e,
const std::tr1::shared_ptr<const FakeRepositoryBase> &,
- const QualifiedPackageName &, const VersionSpec &, const std::string & eapi);
+ const QualifiedPackageName &, const VersionSpec &);
~FakePackageID();
///\}
diff --git a/paludis/repositories/fake/fake_repository.cc b/paludis/repositories/fake/fake_repository.cc
index d1151d5..a2d8a20 100644
--- a/paludis/repositories/fake/fake_repository.cc
+++ b/paludis/repositories/fake/fake_repository.cc
@@ -58,9 +58,9 @@ namespace paludis
};
}
-FakeRepository::FakeRepository(const Environment * const e, const RepositoryName & our_name) :
+FakeRepository::FakeRepository(const Environment * const env, const RepositoryName & r) :
PrivateImplementationPattern<FakeRepository>(new Implementation<FakeRepository>),
- FakeRepositoryBase(e, our_name, RepositoryCapabilities::named_create()
+ FakeRepositoryBase(env, r, RepositoryCapabilities::named_create()
(k::sets_interface(), this)
(k::syncable_interface(), static_cast<RepositorySyncableInterface *>(0))
(k::use_interface(), this)
@@ -68,14 +68,13 @@ FakeRepository::FakeRepository(const Environment * const e, const RepositoryName
(k::environment_variable_interface(), static_cast<RepositoryEnvironmentVariableInterface *>(0))
(k::provides_interface(), static_cast<RepositoryProvidesInterface *>(0))
(k::virtuals_interface(), (*DistributionData::get_instance()->distribution_from_string(
- e->default_distribution()))[k::support_old_style_virtuals()] ? this : 0)
+ env->default_distribution()))[k::support_old_style_virtuals()] ? this : 0)
(k::destination_interface(), static_cast<RepositoryDestinationInterface *>(0))
(k::e_interface(), static_cast<RepositoryEInterface *>(0))
(k::make_virtuals_interface(), static_cast<RepositoryMakeVirtualsInterface *>(0))
(k::qa_interface(), static_cast<RepositoryQAInterface *>(0))
(k::hook_interface(), static_cast<RepositoryHookInterface *>(0))
- (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0)),
- "0"),
+ (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0))),
_imp(PrivateImplementationPattern<FakeRepository>::_imp)
{
add_metadata_key(_imp->format_key);
@@ -97,8 +96,7 @@ FakeRepository::FakeRepository(const FakeRepositoryParams & params) :
(k::make_virtuals_interface(), static_cast<RepositoryMakeVirtualsInterface *>(0))
(k::qa_interface(), static_cast<RepositoryQAInterface *>(0))
(k::hook_interface(), static_cast<RepositoryHookInterface *>(0))
- (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0)),
- params.eapi),
+ (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0))),
_imp(PrivateImplementationPattern<FakeRepository>::_imp)
{
add_metadata_key(_imp->format_key);
diff --git a/paludis/repositories/fake/fake_repository.sr b/paludis/repositories/fake/fake_repository.sr
index f183e7d..2be8f95 100644
--- a/paludis/repositories/fake/fake_repository.sr
+++ b/paludis/repositories/fake/fake_repository.sr
@@ -7,7 +7,6 @@ make_class_FakeRepositoryParams()
key environment "const Environment *"
key name "RepositoryName"
- key eapi "std::string"
doxygen_comment << "END"
/**
diff --git a/paludis/repositories/fake/fake_repository_base.cc b/paludis/repositories/fake/fake_repository_base.cc
index d5b6ebc..b12bff8 100644
--- a/paludis/repositories/fake/fake_repository_base.cc
+++ b/paludis/repositories/fake/fake_repository_base.cc
@@ -50,25 +50,22 @@ namespace paludis
std::map<SetName, std::tr1::shared_ptr<SetSpecTree::ConstItem> > sets;
const Environment * const env;
- const std::string eapi;
- Implementation(const Environment * const, const std::string & ea);
+ Implementation(const Environment * const);
};
- Implementation<FakeRepositoryBase>::Implementation(const Environment * const e, const std::string & ea) :
+ Implementation<FakeRepositoryBase>::Implementation(const Environment * const e) :
category_names(new CategoryNamePartSet),
- env(e),
- eapi(ea)
+ env(e)
{
}
}
FakeRepositoryBase::FakeRepositoryBase(const Environment * const e,
- const RepositoryName & our_name, const RepositoryCapabilities & caps,
- const std::string & eapi) :
+ const RepositoryName & our_name, const RepositoryCapabilities & caps) :
Repository(our_name, caps),
RepositoryUseInterface(),
- PrivateImplementationPattern<FakeRepositoryBase>(new Implementation<FakeRepositoryBase>(e, eapi)),
+ PrivateImplementationPattern<FakeRepositoryBase>(new Implementation<FakeRepositoryBase>(e)),
_imp(PrivateImplementationPattern<FakeRepositoryBase>::_imp)
{
}
@@ -140,7 +137,7 @@ std::tr1::shared_ptr<FakePackageID>
FakeRepositoryBase::add_version(const QualifiedPackageName & q, const VersionSpec & v)
{
add_package(q);
- std::tr1::shared_ptr<FakePackageID> id(new FakePackageID(_imp->env, shared_from_this(), q, v, _imp->eapi));
+ std::tr1::shared_ptr<FakePackageID> id(new FakePackageID(_imp->env, shared_from_this(), q, v));
_imp->ids.find(q)->second->push_back(id);
return id;
}
diff --git a/paludis/repositories/fake/fake_repository_base.hh b/paludis/repositories/fake/fake_repository_base.hh
index d097d21..4a49e4a 100644
--- a/paludis/repositories/fake/fake_repository_base.hh
+++ b/paludis/repositories/fake/fake_repository_base.hh
@@ -57,7 +57,7 @@ namespace paludis
* Constructor.
*/
FakeRepositoryBase(const Environment * const env, const RepositoryName & name,
- const RepositoryCapabilities & caps, const std::string & eapi);
+ const RepositoryCapabilities & caps);
virtual void need_keys_added() const;
diff --git a/paludis/user_dep_spec-fwd.hh b/paludis/user_dep_spec-fwd.hh
index 3bfb13e..8a822ed 100644
--- a/paludis/user_dep_spec-fwd.hh
+++ b/paludis/user_dep_spec-fwd.hh
@@ -23,6 +23,8 @@
#include <paludis/util/attributes.hh>
#include <paludis/util/options-fwd.hh>
#include <paludis/dep_spec-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <tr1/memory>
#include <iosfwd>
namespace paludis
diff --git a/paludis/user_dep_spec.cc b/paludis/user_dep_spec.cc
index 1797a96..7fd03bd 100644
--- a/paludis/user_dep_spec.cc
+++ b/paludis/user_dep_spec.cc
@@ -19,6 +19,7 @@
#include <paludis/user_dep_spec.hh>
#include <paludis/environment.hh>
+#include <paludis/elike_use_requirement.hh>
#include <paludis/version_operator.hh>
#include <paludis/version_spec.hh>
#include <paludis/version_requirements.hh>
@@ -31,37 +32,6 @@ using namespace paludis;
#include <paludis/user_dep_spec-se.cc>
-namespace
-{
- struct UserUseRequirement :
- AdditionalPackageDepSpecRequirement
- {
- bool inverse;
- UseFlagName f;
-
- UserUseRequirement(const std::string & s) :
- inverse((! s.empty()) && ('-' == s.at(0))),
- f(inverse ? UseFlagName(s.substr(1)) : UseFlagName(s))
- {
- }
-
- virtual bool requirement_met(const Environment * const env, const PackageID & id) const
- {
- return env->query_use(f, id) ^ inverse;
- }
-
- virtual const std::string as_human_string() const
- {
- return "Use flag '" + stringify(f) + "' " + (inverse ? "disabled" : "enabled");
- }
-
- virtual const std::string as_raw_string() const
- {
- return "[" + std::string(inverse ? "-" : "") + stringify(f) + "]";
- }
- };
-}
-
PackageDepSpec
paludis::parse_user_package_dep_spec(const std::string & ss, const UserPackageDepSpecOptions & options)
{
@@ -155,7 +125,8 @@ paludis::parse_user_package_dep_spec(const std::string & ss, const UserPackageDe
default:
{
- std::tr1::shared_ptr<UserUseRequirement> req(new UserUseRequirement(flag));
+ std::tr1::shared_ptr<const AdditionalPackageDepSpecRequirement> req(parse_elike_use_requirement(flag,
+ std::tr1::shared_ptr<const PackageID>(), ELikeUseRequirementOptions()));
result.additional_requirement(req);
}
break;
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index 484ab94..743568c 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -54,6 +54,7 @@ add(`sequence', `hh', `fwd', `impl')
add(`set', `hh', `fwd', `impl')
add(`sha1', `hh', `cc', `test')
add(`sha256', `hh', `cc', `test')
+add(`simple_parser', `hh', `cc')
add(`sr', `hh', `cc')
add(`stringify', `hh', `test')
add(`strip', `hh', `cc', `test')
diff --git a/paludis/util/keys.hh b/paludis/util/keys.hh
index 9a0ab68..ab0b49d 100644
--- a/paludis/util/keys.hh
+++ b/paludis/util/keys.hh
@@ -163,6 +163,18 @@ namespace paludis
typedef kc::Key<134> magic;
typedef kc::Key<135> mutex;
typedef kc::Key<136> ndbam;
+ typedef kc::Key<137> on_string;
+ typedef kc::Key<138> on_arrow;
+ typedef kc::Key<139> on_any;
+ typedef kc::Key<140> on_use;
+ typedef kc::Key<141> on_label;
+ typedef kc::Key<142> on_pop;
+ typedef kc::Key<143> on_should_be_empty;
+ typedef kc::Key<144> on_all;
+ typedef kc::Key<145> on_error;
+ typedef kc::Key<146> add_handler;
+ typedef kc::Key<147> item;
+ typedef kc::Key<148> on_use_under_any;
}
}
diff --git a/paludis/util/simple_parser.cc b/paludis/util/simple_parser.cc
new file mode 100644
index 0000000..c211154
--- /dev/null
+++ b/paludis/util/simple_parser.cc
@@ -0,0 +1,268 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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/util/simple_parser.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+
+using namespace paludis;
+using namespace paludis::simple_parser;
+
+
+SimpleParserExpression::SimpleParserExpression(const SimpleParserMatchFunction & f) :
+ _match(f)
+{
+}
+
+std::string::size_type
+SimpleParserExpression::match(const std::string & s, const std::string::size_type offset) const
+{
+ return _match(s, offset);
+}
+
+namespace
+{
+ std::string::size_type
+ m_and(const SimpleParserExpression & e1, const SimpleParserExpression & e2, const std::string & text,
+ const std::string::size_type offset)
+ {
+ if (offset >= text.length())
+ return std::string::npos;
+
+ std::string::size_type len_1(e1.match(text, offset));
+ if (std::string::npos == len_1)
+ return std::string::npos;
+
+ std::string::size_type len_2(e2.match(text, offset + len_1));
+ if (std::string::npos == len_2)
+ return std::string::npos;
+
+ return len_1 + len_2;
+ }
+
+ std::string::size_type
+ m_capture(const SimpleParserExpression & e1, std::string & var, const std::string & text,
+ const std::string::size_type offset)
+ {
+ std::string::size_type len_1(e1.match(text, offset));
+ if (std::string::npos != len_1)
+ var = text.substr(offset, len_1);
+ return len_1;
+ }
+
+ std::string::size_type
+ m_star(const SimpleParserExpression & e1, const std::string & text,
+ const std::string::size_type offset)
+ {
+ std::string::size_type new_offset(offset);
+
+ while (true)
+ {
+ std::string::size_type len_1(e1.match(text, new_offset));
+ if (std::string::npos == len_1 || 0 == len_1)
+ return new_offset - offset;
+ new_offset += len_1;
+ }
+ }
+
+ std::string::size_type
+ m_plus(const SimpleParserExpression & e1, const std::string & text,
+ const std::string::size_type offset)
+ {
+ bool any(false);
+ std::string::size_type new_offset(offset);
+
+ while (true)
+ {
+ std::string::size_type len_1(e1.match(text, new_offset));
+ if (std::string::npos == len_1)
+ return any ? new_offset - offset : std::string::npos;
+ else if (0 == len_1)
+ return new_offset - offset;
+
+ new_offset += len_1;
+ any = true;
+ }
+ }
+
+ std::string::size_type
+ m_minus(const SimpleParserExpression & e1, const std::string & text,
+ const std::string::size_type offset)
+ {
+ std::string::size_type len_1(e1.match(text, offset));
+ return std::string::npos == len_1 ? 0 : len_1;
+ }
+
+ std::string::size_type
+ m_exact(const std::string & pattern, const std::string & text,
+ const std::string::size_type offset)
+ {
+ if (offset >= text.length())
+ return std::string::npos;
+
+ return (0 == text.compare(offset, pattern.length(), pattern)) ? pattern.length() : std::string::npos;
+ }
+
+ std::string::size_type
+ m_any_of(const std::string & allowed, const std::string & text,
+ const std::string::size_type offset)
+ {
+ if (offset >= text.length())
+ return std::string::npos;
+
+ if (std::string::npos != allowed.find(text.at(offset)))
+ return 1;
+ else
+ return std::string::npos;
+ }
+
+ std::string::size_type
+ m_any_except(const std::string & not_allowed, const std::string & text,
+ const std::string::size_type offset)
+ {
+ if (offset >= text.length())
+ return std::string::npos;
+
+ if (std::string::npos != not_allowed.find(text.at(offset)))
+ return std::string::npos;
+ else
+ return 1;
+ }
+}
+
+SimpleParserExpression
+paludis::simple_parser::operator& (const SimpleParserExpression & e1, const SimpleParserExpression & e2)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_and, e1, e2, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::operator>> (const SimpleParserExpression & e1, std::string & var)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_capture, e1, std::tr1::ref(var), _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::operator* (const SimpleParserExpression & e1)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_star, e1, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::operator+ (const SimpleParserExpression & e1)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_plus, e1, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::operator- (const SimpleParserExpression & e1)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_minus, e1, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::exact(const std::string & s)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_exact, s, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::any_of(const std::string & s)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_any_of, s, _1, _2));
+}
+
+SimpleParserExpression
+paludis::simple_parser::any_except(const std::string & s)
+{
+ using namespace std::tr1::placeholders;
+ return SimpleParserExpression(std::tr1::bind(m_any_except, s, _1, _2));
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<SimpleParser>
+ {
+ std::string text;
+ std::string::size_type offset;
+
+ Implementation(const std::string & t) :
+ text(t),
+ offset(0)
+ {
+ }
+ };
+}
+
+SimpleParser::SimpleParser(const std::string & s) :
+ PrivateImplementationPattern<SimpleParser>(new Implementation<SimpleParser>(s))
+{
+}
+
+SimpleParser::~SimpleParser()
+{
+}
+
+bool
+SimpleParser::consume(const SimpleParserExpression & e1)
+{
+ std::string::size_type len_1(e1.match(_imp->text, _imp->offset));
+ if (std::string::npos == len_1)
+ return false;
+ else
+ {
+ _imp->offset += len_1;
+ return true;
+ }
+}
+
+bool
+SimpleParser::lookahead(const SimpleParserExpression & e1) const
+{
+ std::string::size_type len_1(e1.match(_imp->text, _imp->offset));
+ return std::string::npos != len_1;
+}
+
+bool
+SimpleParser::eof() const
+{
+ return _imp->offset == _imp->text.length();
+}
+
+std::string::size_type
+SimpleParser::offset() const
+{
+ return _imp->offset;
+}
+
+const std::string
+SimpleParser::text() const
+{
+ return _imp->text;
+}
+
+template struct PrivateImplementationPattern<SimpleParser>;
+
diff --git a/paludis/util/simple_parser.hh b/paludis/util/simple_parser.hh
new file mode 100644
index 0000000..c0f7922
--- /dev/null
+++ b/paludis/util/simple_parser.hh
@@ -0,0 +1,91 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 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_UTIL_SIMPLE_PARSER_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_SIMPLE_PARSER_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <tr1/functional>
+#include <string>
+
+namespace paludis
+{
+ namespace simple_parser
+ {
+ typedef std::tr1::function<std::string::size_type (const std::string &, const std::string::size_type)> SimpleParserMatchFunction;
+
+ class PALUDIS_VISIBLE SimpleParserExpression
+ {
+ private:
+ const SimpleParserMatchFunction _match;
+
+ public:
+ SimpleParserExpression(const SimpleParserMatchFunction &);
+
+ std::string::size_type match(const std::string &, const std::string::size_type) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ SimpleParserExpression operator& (const SimpleParserExpression &, const SimpleParserExpression &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression operator>> (const SimpleParserExpression &, std::string &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression operator* (const SimpleParserExpression &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression operator+ (const SimpleParserExpression &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression operator- (const SimpleParserExpression &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression exact(const std::string &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression any_of(const std::string &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ SimpleParserExpression any_except(const std::string &)
+ PALUDIS_VISIBLE PALUDIS_ATTRIBUTE((warn_unused_result));
+ }
+
+ class PALUDIS_VISIBLE SimpleParser :
+ private PrivateImplementationPattern<SimpleParser>
+ {
+ public:
+ SimpleParser(const std::string &);
+ ~SimpleParser();
+
+ bool consume(const simple_parser::SimpleParserExpression &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool lookahead(const simple_parser::SimpleParserExpression &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool eof() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::string::size_type offset() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ const std::string text() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template struct PrivateImplementationPattern<SimpleParser>;
+#endif
+}
+
+#endif
diff --git a/paludis/version_spec.cc b/paludis/version_spec.cc
index 176b7ca..48e7f45 100644
--- a/paludis/version_spec.cc
+++ b/paludis/version_spec.cc
@@ -28,6 +28,7 @@
#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/kc.hh>
#include <paludis/util/keys.hh>
+#include <paludis/util/simple_parser.hh>
#include <paludis/version_spec.hh>
#include <vector>
#include <limits>
@@ -103,24 +104,18 @@ VersionSpec::VersionSpec(const std::string & text) :
_imp->text = text;
/* parse */
- std::string::size_type p(0);
+ SimpleParser parser(text);
- if (0 == text.compare(p, 3, "scm"))
- {
+ if (parser.consume(simple_parser::exact("scm")))
_imp->parts.push_back(Part(scm, ""));
- p += 3;
- }
else
{
/* numbers... */
- while (p < text.length())
+ while (true)
{
- std::string::size_type q(text.find_first_not_of("0123456789", p));
- std::string number_part(std::string::npos == q ? text.substr(p) : text.substr(p, q - p));
- p = std::string::npos == q ? text.length() : q;
-
- if (number_part.empty())
- throw BadVersionSpecError(text, "Expected number part not found at offset " + stringify(p));
+ std::string number_part;
+ if (! parser.consume(+simple_parser::any_of("0123456789") >> number_part))
+ throw BadVersionSpecError(text, "Expected number part not found at offset " + stringify(parser.offset()));
if (number_part.size() > 8)
Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
@@ -129,108 +124,83 @@ VersionSpec::VersionSpec(const std::string & text) :
_imp->parts.push_back(Part(number, number_part));
- if (p < text.length() && ('.' != text.at(p) || p + 1 == text.length()))
+ if (! parser.consume(simple_parser::exact(".")))
break;
-
- ++p;
}
/* letter */
- if (p < text.length())
- if (text.at(p) >= 'a' && text.at(p) <= 'z')
- _imp->parts.push_back(Part(letter, text.substr(p++, 1)));
+ {
+ std::string l;
+ if (parser.consume(simple_parser::any_of("abcdefghijklmnopqrstuvwxyz") >> l))
+ _imp->parts.push_back(Part(letter, l));
+ }
- bool suffix(true);
- while (suffix)
+ while (true)
{
- suffix = false;
+ std::string suffix_str, number_str;
+ PartKind k(empty);
+ if (parser.consume(simple_parser::exact("_alpha") >> suffix_str))
+ k = alpha;
+ else if (parser.consume(simple_parser::exact("_beta") >> suffix_str))
+ k = beta;
+ else if (parser.consume(simple_parser::exact("_pre") >> suffix_str))
+ k = pre;
+ else if (parser.consume(simple_parser::exact("_rc") >> suffix_str))
+ k = rc;
+ else if (parser.consume(simple_parser::exact("_p") >> suffix_str))
+ k = patch;
+ else
+ break;
- /* suffix */
- if (p < text.length())
- do
- {
- PartKind k(empty);
- if (0 == text.compare(p, 6, "_alpha"))
- {
- k = alpha;
- p += 6;
- }
- else if (0 == text.compare(p, 5, "_beta"))
- {
- k = beta;
- p += 5;
- }
- else if (0 == text.compare(p, 4, "_pre"))
- {
- k = pre;
- p += 4;
- }
- else if (0 == text.compare(p, 3, "_rc"))
- {
- k = rc;
- p += 3;
- }
- else if (0 == text.compare(p, 2, "_p"))
- {
- k = patch;
- p += 2;
- }
- else
- break;
-
- std::string::size_type q(text.find_first_not_of("0123456789", p));
- std::string number_part(std::string::npos == q ? text.substr(p) : text.substr(p, q - p));
- p = std::string::npos == q ? text.length() : q;
-
- if (number_part.size() > 8)
- Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
- "Number part '" << number_part << "' exceeds 8 digit limit permitted by the Package Manager Specification "
- "(Paludis supports arbitrary lengths, but other package managers do not)";
-
- if (number_part.size() > 0)
- {
- number_part = strip_leading(number_part, "0");
- if (number_part.empty())
- number_part = "0";
- }
- _imp->parts.push_back(Part(k, number_part));
- suffix = true;
- } while (false);
+ if (! parser.consume(*simple_parser::any_of("0123456789") >> number_str))
+ throw BadVersionSpecError(text, "Expected optional number at offset " + stringify(parser.offset()));
+
+ if (number_str.size() > 8)
+ Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
+ "Number part '" << number_str << "' exceeds 8 digit limit permitted by the Package Manager Specification "
+ "(Paludis supports arbitrary lengths, but other package managers do not)";
+
+ if (number_str.size() > 0)
+ {
+ number_str = strip_leading(number_str, "0");
+ if (number_str.empty())
+ number_str = "0";
+ }
+
+ _imp->parts.push_back(Part(k, number_str));
}
/* try */
- if (p < text.length() && 0 == text.compare(p, 4, "-try"))
+ if (parser.consume(simple_parser::exact("-try")))
{
- p += 4;
-
- std::string::size_type q(text.find_first_not_of("0123456789", p));
- std::string number_part(std::string::npos == q ? text.substr(p) : text.substr(p, q - p));
- p = std::string::npos == q ? text.length() : q;
+ std::string number_str;
+ if (! parser.consume(*simple_parser::any_of("0123456789") >> number_str))
+ throw BadVersionSpecError(text, "Expected optional number at offset " + stringify(parser.offset()));
- if (number_part.size() > 8)
+ if (number_str.size() > 8)
Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
- "Number part '" << number_part << "' exceeds 8 digit limit permitted by the Package Manager Specification "
+ "Number part '" << number_str << "' exceeds 8 digit limit permitted by the Package Manager Specification "
"(Paludis supports arbitrary lengths, but other package managers do not)";
- if (number_part.size() > 0)
+ if (number_str.size() > 0)
{
- number_part = strip_leading(number_part, "0");
- if (number_part.empty())
- number_part = "0";
+ number_str = strip_leading(number_str, "0");
+ if (number_str.empty())
+ number_str = "0";
}
- _imp->parts.push_back(Part(trypart, number_part));
+ _imp->parts.push_back(Part(trypart, number_str));
}
/* scm */
- if ((p < text.length()) && (0 == text.compare(p, 4, "-scm")))
+ if (parser.consume(simple_parser::exact("-scm")))
{
- p += 4;
/* _suffix-scm? */
if (_imp->parts.back()[k::value()].empty())
_imp->parts.back()[k::value()] = "MAX";
_imp->parts.push_back(Part(scm, ""));
}
+
/* Now we can change empty values to "0" */
for (std::vector<Part>::iterator i(_imp->parts.begin()),
i_end(_imp->parts.end()) ; i != i_end ; ++i)
@@ -239,52 +209,46 @@ VersionSpec::VersionSpec(const std::string & text) :
}
/* revision */
- if (p < text.length())
- if (0 == text.compare(p, 2, "-r"))
+ if (parser.consume(simple_parser::exact("-r")))
+ {
+ do
{
- p += 2;
- do
+ std::string number_str;
+ if (! parser.consume(*simple_parser::any_of("0123456789") >> number_str))
+ throw BadVersionSpecError(text, "Expected optional number at offset " + stringify(parser.offset()));
+
+ if (number_str.size() > 8)
+ Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
+ "Number part '" << number_str << "' exceeds 8 digit limit permitted by the Package Manager Specification "
+ "(Paludis supports arbitrary lengths, but other package managers do not)";
+
+ /* Are we -r */
+ bool empty(number_str.empty());
+
+ number_str = strip_leading(number_str, "0");
+ if (number_str.empty())
+ number_str = "0";
+ _imp->parts.push_back(Part(revision, number_str));
+
+ if (empty)
{
- std::string::size_type q(text.find_first_not_of("0123456789", p));
- std::string number_part(std::string::npos == q ? text.substr(p) : text.substr(p, q - p));
- p = std::string::npos == q ? text.length() : q;
-
- if (number_part.size() > 8)
- Log::get_instance()->message("version_spec.too_long", ll_qa, lc_context) <<
- "Number part '" << number_part << "' exceeds 8 digit limit permitted by the Package Manager Specification "
- "(Paludis supports arbitrary lengths, but other package managers do not)";
-
- /* Are we -r */
- bool empty(number_part.empty());
-
- number_part = strip_leading(number_part, "0");
- if (number_part.empty())
- number_part = "0";
- _imp->parts.push_back(Part(revision, number_part));
-
- if (p >= text.length())
- break;
- if (text.at(p) != '.')
- break;
- else if (empty)
- {
- /* we don't like -r. */
- break;
- }
- else if (! (p + 1 < text.length() && text.at(p + 1) >= '0' && text.at(p + 1) <= '9'))
- {
- /* we don't like -rN.x where x is not a digit */
- break;
- }
- else
- ++p;
+ /* we don't like -r.x */
+ break;
}
- while (true);
+ else if (! parser.lookahead(simple_parser::exact(".") & simple_parser::any_of("0123456789")))
+ {
+ /* we don't like -rN.x where x is not a digit */
+ break;
+ }
+ else if (! parser.consume(simple_parser::exact(".")))
+ throw BadVersionSpecError(text, "Expected . or end after revision number at offset " + stringify(parser.offset()));
}
+ while (true);
+ }
/* trailing stuff? */
- if (p < text.length())
- throw BadVersionSpecError(text, "unexpected trailing text '" + text.substr(p) + "'");
+ if (! parser.eof())
+ throw BadVersionSpecError(text, "unexpected trailing text '" + text.substr(parser.offset()) + "'");
}
VersionSpec::VersionSpec(const VersionSpec & other) :