aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-05-13 14:23:33 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-05-13 14:23:33 +0000
commite9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1 (patch)
tree38d0d41b09db961226fc006253a096012ab23b2e
parent52bfe9da687d079d44eca092c180f0159f1a95b8 (diff)
downloadpaludis-e9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1.tar.gz
paludis-e9cb1d6a2e87901ceaee28c65b199e59f7f9d2f1.tar.xz
parse and ignore annotations
-rw-r--r--paludis/elike_dep_parser-fwd.hh7
-rw-r--r--paludis/elike_dep_parser.cc98
-rw-r--r--paludis/elike_dep_parser_TEST.cc40
-rw-r--r--paludis/repositories/e/dep_parser.cc10
-rw-r--r--paludis/repositories/fake/dep_parser.cc9
-rw-r--r--paludis/util/keys.hh1
6 files changed, 164 insertions, 1 deletions
diff --git a/paludis/elike_dep_parser-fwd.hh b/paludis/elike_dep_parser-fwd.hh
index 1ff49a6..a1f5bf8 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 4c794ba..0ad9247 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 3852927..c6a6b87 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 c69a0f3..9c800ea 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 68c673b..1bbff76 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 ab0b49d..b388438 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;
}
}