diff options
author | 2008-05-13 14:23:33 +0000 | |
---|---|---|
committer | 2008-05-13 14:23:33 +0000 | |
commit | e9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1 (patch) | |
tree | 38d0d41b09db961226fc006253a096012ab23b2e | |
parent | 52bfe9da687d079d44eca092c180f0159f1a95b8 (diff) | |
download | paludis-e9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1.tar.gz paludis-e9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1.tar.xz |
parse and ignore annotations
-rw-r--r-- | paludis/elike_dep_parser-fwd.hh | 7 | ||||
-rw-r--r-- | paludis/elike_dep_parser.cc | 98 | ||||
-rw-r--r-- | paludis/elike_dep_parser_TEST.cc | 40 | ||||
-rw-r--r-- | paludis/repositories/e/dep_parser.cc | 10 | ||||
-rw-r--r-- | paludis/repositories/fake/dep_parser.cc | 9 | ||||
-rw-r--r-- | paludis/util/keys.hh | 1 |
6 files changed, 164 insertions, 1 deletions
diff --git a/paludis/elike_dep_parser-fwd.hh b/paludis/elike_dep_parser-fwd.hh index 1ff49a627..a1f5bf896 100644 --- a/paludis/elike_dep_parser-fwd.hh +++ b/paludis/elike_dep_parser-fwd.hh @@ -23,8 +23,10 @@ #include <paludis/util/kc-fwd.hh> #include <paludis/util/keys.hh> #include <paludis/util/attributes.hh> +#include <paludis/util/map-fwd.hh> #include <paludis/name-fwd.hh> #include <tr1/functional> +#include <tr1/memory> namespace paludis { @@ -39,6 +41,8 @@ namespace paludis 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 std::tr1::function<void (const std::tr1::shared_ptr<const Map<std::string, std::string> > &)> + ELikeDepParserAnnotationsFunction; typedef kc::KeyedClass< kc::Field<k::on_string, ELikeDepParserStringFunction>, @@ -50,7 +54,8 @@ namespace paludis 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> + kc::Field<k::on_use_under_any, ELikeDepParserUseUnderAnyFunction>, + kc::Field<k::on_annotations, ELikeDepParserAnnotationsFunction> > ELikeDepParserCallbacks; void parse_elike_dependencies(const std::string &, const ELikeDepParserCallbacks & callbacks) PALUDIS_VISIBLE; diff --git a/paludis/elike_dep_parser.cc b/paludis/elike_dep_parser.cc index 4c794ba51..0ad9247f6 100644 --- a/paludis/elike_dep_parser.cc +++ b/paludis/elike_dep_parser.cc @@ -22,6 +22,8 @@ #include <paludis/util/kc.hh> #include <paludis/util/exception.hh> #include <paludis/util/stringify.hh> +#include <paludis/util/map.hh> +#include <paludis/util/wrapped_forward_iterator.hh> #include <paludis/name.hh> using namespace paludis; @@ -37,6 +39,96 @@ namespace "', but the error function returned"); } + void parse_annotations(SimpleParser & parser, const ELikeDepParserCallbacks & callbacks) + { + Context context("When parsing annotation block at offset '" + stringify(parser.offset()) + "':"); + + if (! parser.consume(*simple_parser::any_of(" \t\r\n") & simple_parser::exact("[["))) + return; + + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space after '[['"); + + std::tr1::shared_ptr<Map<std::string, std::string> > annotations(new Map<std::string, std::string>); + while (true) + { + std::string word; + + if (parser.eof()) + error(parser, callbacks, "Reached end of text but wanted ']]'"); + else if (parser.consume(+simple_parser::any_of(" \t\r\n"))) + { + } + else if (parser.consume(simple_parser::exact("]]"))) + break; + else if (parser.consume(+simple_parser::any_except(" \t\r\n") >> word)) + { + if ("=" == word) + error(parser, callbacks, "Equals not allowed here"); + else if ("[" == word || "]" == word) + error(parser, callbacks, "Brackets not allowed here"); + + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space after annotation key"); + + if (! parser.consume(simple_parser::exact("="))) + error(parser, callbacks, "Expected equals after space after annotation key"); + + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space after equals"); + + std::string value; + + if (parser.consume(simple_parser::exact("["))) + { + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space after annotation quote"); + + while (true) + { + std::string v; + if (parser.eof()) + error(parser, callbacks, "Reached end of text but wanted ']'"); + else if (parser.consume(+simple_parser::any_of(" \t\r\n"))) + { + } + else if (parser.consume(simple_parser::exact("]"))) + break; + else if (parser.consume(+simple_parser::any_except(" \t\r\n") >> v)) + { + if (! value.empty()) + value.append(" "); + value.append(v); + } + else + error(parser, callbacks, "Expected word or ']'"); + } + + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space after ']'"); + } + else if (parser.consume(+simple_parser::any_except(" \t\r\n") >> value)) + { + } + else + error(parser, callbacks, "Expected word or quoted string after equals"); + + if (annotations->end() != annotations->find(word)) + error(parser, callbacks, "Duplicate annotation key '" + word + "'"); + else + annotations->insert(word, value); + } + else + error(parser, callbacks, "Couldn't find annotation key"); + } + + if (! parser.eof()) + if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) + error(parser, callbacks, "Expected space or eof after ']]'"); + + callbacks[k::on_annotations()](annotations); + } + void parse(SimpleParser & parser, const ELikeDepParserCallbacks & callbacks, const bool end_with_close_paren, const bool child_of_any) @@ -73,6 +165,7 @@ namespace if (! parser.consume(+simple_parser::any_of(" \t\r\n"))) error(parser, callbacks, "Expected space or end of text after ')'"); callbacks[k::on_pop()](); + parse_annotations(parser, callbacks); return; } else @@ -118,6 +211,7 @@ namespace else if (':' == word.at(word.length() - 1)) { callbacks[k::on_label()](word); + parse_annotations(parser, callbacks); } else if (parser.consume(+simple_parser::any_of(" \t\r\n") & simple_parser::exact("->"))) { @@ -132,9 +226,13 @@ namespace error(parser, callbacks, "Expected word after '->' then space"); callbacks[k::on_arrow()](word, second); + parse_annotations(parser, callbacks); } else + { callbacks[k::on_string()](word); + parse_annotations(parser, callbacks); + } } else error(parser, callbacks, "Unexpected trailing text"); diff --git a/paludis/elike_dep_parser_TEST.cc b/paludis/elike_dep_parser_TEST.cc index 38529275a..c6a6b87d8 100644 --- a/paludis/elike_dep_parser_TEST.cc +++ b/paludis/elike_dep_parser_TEST.cc @@ -19,6 +19,8 @@ #include <paludis/elike_dep_parser.hh> #include <paludis/util/kc.hh> +#include <paludis/util/map.hh> +#include <paludis/util/wrapped_forward_iterator.hh> #include <test/test_framework.hh> #include <test/test_runner.hh> @@ -40,6 +42,15 @@ namespace void do_nothing() { } + + void handle_annotations(std::string & s, const std::tr1::shared_ptr<const Map<std::string, std::string> > & m) + { + s.append("["); + for (Map<std::string, std::string>::ConstIterator i(m->begin()), i_end(m->end()) ; + i != i_end ; ++i) + s.append(i->first + ":" + i->second + ";"); + s.append("]"); + } } namespace test_cases @@ -64,6 +75,7 @@ namespace test_cases (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) + (k::on_annotations(), std::tr1::bind(&handle_annotations, std::tr1::ref(out), _1)) ); parse_elike_dependencies(in, callbacks); TEST_CHECK_EQUAL(out, "any<s<a>s<b>all<s<c>s<d>s<e>>>EMPTY"); @@ -90,10 +102,38 @@ namespace test_cases (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) + (k::on_annotations(), std::tr1::bind(&handle_annotations, std::tr1::ref(out), _1)) ); parse_elike_dependencies(in, callbacks); TEST_CHECK_EQUAL(out, "all<all<>>EMPTY"); } } elike_dep_parser_test_empty_blocks; + + struct ELikeDepParserAnnotationsTest : TestCase + { + ELikeDepParserAnnotationsTest() : TestCase("annotations") { } + + void run() + { + using namespace std::tr1::placeholders; + + std::string in("a [[ first = foo second = [ bar baz ] ]]"), 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) + (k::on_annotations(), std::tr1::bind(&handle_annotations, std::tr1::ref(out), _1)) + ); + parse_elike_dependencies(in, callbacks); + TEST_CHECK_EQUAL(out, "s<a>[first:foo;second:bar baz;]EMPTY"); + } + } elike_dep_parser_annotations_test; } diff --git a/paludis/repositories/e/dep_parser.cc b/paludis/repositories/e/dep_parser.cc index c69a0f3b6..9c800ea2f 100644 --- a/paludis/repositories/e/dep_parser.cc +++ b/paludis/repositories/e/dep_parser.cc @@ -210,6 +210,10 @@ namespace void do_nothing() { } + + void discard_annotations(const std::tr1::shared_ptr<const Map<std::string, std::string> > &) + { + } } std::tr1::shared_ptr<DependencySpecTree::ConstItem> @@ -238,6 +242,7 @@ paludis::erepository::parse_depend(const std::string & 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)) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -271,6 +276,7 @@ paludis::erepository::parse_provide(const std::string & 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)) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -304,6 +310,7 @@ paludis::erepository::parse_fetchable_uri(const std::string & 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)) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -337,6 +344,7 @@ paludis::erepository::parse_simple_uri(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -370,6 +378,7 @@ paludis::erepository::parse_license(const std::string & 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)) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -403,6 +412,7 @@ paludis::erepository::parse_restrict(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); diff --git a/paludis/repositories/fake/dep_parser.cc b/paludis/repositories/fake/dep_parser.cc index 68c673bd4..1bbff762c 100644 --- a/paludis/repositories/fake/dep_parser.cc +++ b/paludis/repositories/fake/dep_parser.cc @@ -178,6 +178,10 @@ namespace void do_nothing() { } + + void discard_annotations(const std::tr1::shared_ptr<const Map<std::string, std::string> > &) + { + } } std::tr1::shared_ptr<DependencySpecTree::ConstItem> @@ -206,6 +210,7 @@ paludis::fakerepository::parse_depend(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -239,6 +244,7 @@ paludis::fakerepository::parse_provide(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -272,6 +278,7 @@ paludis::fakerepository::parse_fetchable_uri(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -305,6 +312,7 @@ paludis::fakerepository::parse_simple_uri(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); @@ -338,6 +346,7 @@ paludis::fakerepository::parse_license(const std::string & 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) + (k::on_annotations(), &discard_annotations) ); parse_elike_dependencies(s, callbacks); diff --git a/paludis/util/keys.hh b/paludis/util/keys.hh index ab0b49dd8..b3884385d 100644 --- a/paludis/util/keys.hh +++ b/paludis/util/keys.hh @@ -175,6 +175,7 @@ namespace paludis typedef kc::Key<146> add_handler; typedef kc::Key<147> item; typedef kc::Key<148> on_use_under_any; + typedef kc::Key<149> on_annotations; } } |