From 2ec35ea6e98dcfb03fb8c2e90b85991aaa7be2fa Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 27 Feb 2012 04:59:04 -0600 Subject: Implement the "tag" metadata directive --- src/journal.cc | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'src/journal.cc') diff --git a/src/journal.cc b/src/journal.cc index 17fcb687..8f382125 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -217,8 +217,38 @@ void journal_t::register_commodity(commodity_t& comm, } } -#if 0 -void journal_t::register_metadata(const string& key, const string& value, +namespace { + void check_metadata(journal_t& journal, + const string& key, const value_t& value, + variant context, + const string& location) + { + std::pair range = + journal.tag_check_exprs.equal_range(key); + + for (tag_check_exprs_map::iterator i = range.first; + i != range.second; + ++i) { + value_scope_t val_scope + (context.which() == 1 ? + static_cast(*boost::get(context)) : + static_cast(*boost::get(context)), value); + + if (! (*i).second.first.calc(val_scope).to_boolean()) { + if ((*i).second.second == expr_t::EXPR_ASSERTION) + throw_(parse_error, + _("Metadata assertion failed for (%1: %2): %3") + << key << value << (*i).second.first); + else + warning_(_("%1Metadata check failed for (%2: %3): %4") + << location << key << value << (*i).second.first); + } + } + } +} + +void journal_t::register_metadata(const string& key, const value_t& value, variant context, const string& location) { @@ -244,8 +274,34 @@ void journal_t::register_metadata(const string& key, const string& value, throw_(parse_error, _("Unknown metadata tag '%1'") << key); } } + + if (! value.is_null()) + check_metadata(*this, key, value, context, location); +} + +namespace { + void check_all_metadata(journal_t& journal, + variant context) + { + xact_t * xact = context.which() == 1 ? boost::get(context) : NULL; + post_t * post = context.which() == 2 ? boost::get(context) : NULL; + + if ((xact || post) && xact ? xact->metadata : post->metadata) { + foreach (const item_t::string_map::value_type& pair, + xact ? *xact->metadata : *post->metadata) { + const string& key(pair.first); + + // jww (2012-02-27): We really need to know the parsing context, + // both here and for the call to warning_ in + // xact_t::extend_xact. + if (optional value = pair.second.first) + journal.register_metadata(key, *value, context, ""); + else + journal.register_metadata(key, NULL_VALUE, context, ""); + } + } + } } -#endif bool journal_t::add_xact(xact_t * xact) { @@ -258,6 +314,10 @@ bool journal_t::add_xact(xact_t * xact) extend_xact(xact); + check_all_metadata(*this, xact); + foreach (post_t * post, xact->posts) + check_all_metadata(*this, post); + // If a transaction with this UUID has already been seen, simply do // not add this one to the journal. However, all automated checks // will have been performed by extend_xact, so asserts can still be -- cgit v1.2.3