summaryrefslogtreecommitdiff
path: root/src/textual.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-12 22:38:36 -0500
committerJohn Wiegley <johnw@newartisans.com>2012-03-12 22:38:36 -0500
commitbe289fba1f3bdb4dc07d5595ad8b46a9309f42f3 (patch)
tree73526bd98087b3ef69aaa300b2bd8112d5aab924 /src/textual.cc
parentcf67fcbd0628e03ac2f788da6f2c082121faf21f (diff)
downloadfork-ledger-be289fba1f3bdb4dc07d5595ad8b46a9309f42f3.tar.gz
fork-ledger-be289fba1f3bdb4dc07d5595ad8b46a9309f42f3.tar.bz2
fork-ledger-be289fba1f3bdb4dc07d5595ad8b46a9309f42f3.zip
Fixed a few bugs related to apply directives
Diffstat (limited to 'src/textual.cc')
-rw-r--r--src/textual.cc89
1 files changed, 56 insertions, 33 deletions
diff --git a/src/textual.cc b/src/textual.cc
index ab87a945..7d96310a 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -92,11 +92,30 @@ namespace {
return _("textual parser");
}
+ template <typename T>
+ void get_applications(std::vector<T>& result) {
+ foreach (application_t& state, apply_stack) {
+ if (state.value.type() == typeid(T))
+ result.push_back(boost::get<T>(state.value));
+ }
+ if (parent)
+ parent->get_applications<T>(result);
+ }
+
+ template <typename T>
+ optional<T> get_application() {
+ foreach (application_t& state, apply_stack) {
+ if (state.value.type() == typeid(T))
+ return boost::get<T>(state.value);
+ }
+ return parent ? parent->get_application<T>() : none;
+ }
+
account_t * top_account() {
- foreach (application_t& state, apply_stack)
- if (state.value.type() == typeid(account_t *))
- return boost::get<account_t *>(state.value);
- return NULL;
+ if (optional<account_t *> acct = get_application<account_t *>())
+ return *acct;
+ else
+ return NULL;
}
void parse();
@@ -744,12 +763,15 @@ void instance_t::include_directive(char * line)
#endif // BOOST_VERSION >= 103700
if (glob.match(base)) {
journal_t * journal = context.journal;
- account_t * master = context.master;
+ account_t * master = top_account();
scope_t * scope = context.scope;
std::size_t& errors = context.errors;
std::size_t& count = context.count;
std::size_t& sequence = context.sequence;
+ DEBUG("textual.include", "Including: " << *iter);
+ DEBUG("textual.include", "Master account: " << master->fullname());
+
context_stack.push(*iter);
context_stack.get_current().journal = journal;
@@ -848,15 +870,21 @@ void instance_t::apply_year_directive(char * line)
void instance_t::end_apply_directive(char * kind)
{
- char * b = next_element(kind);
- string name(b ? b : " ");
+ char * b = kind ? next_element(kind) : NULL;
+ string name(b ? b : "");
- if (apply_stack.size() <= 1)
- throw_(std::runtime_error,
- _("'end apply %1' found, but no enclosing 'apply %2' directive")
- << name << name);
+ if (apply_stack.size() <= 1) {
+ if (name.empty()) {
+ throw_(std::runtime_error,
+ _("'end' or 'end apply' found, but no enclosing 'apply' directive"));
+ } else {
+ throw_(std::runtime_error,
+ _("'end apply %1' found, but no enclosing 'apply' directive")
+ << name);
+ }
+ }
- if (name != " " && name != apply_stack.front().label)
+ if (! name.empty() && name != apply_stack.front().label)
throw_(std::runtime_error,
_("'end apply %1' directive does not match 'apply %2' directive")
<< name << apply_stack.front().label);
@@ -1425,15 +1453,14 @@ post_t * instance_t::parse_post(char * line,
context.journal->register_commodity(post->amount.commodity(), post.get());
if (! post->amount.has_annotation()) {
- foreach (application_t& state, apply_stack) {
- if (state.value.type() == typeid(fixed_rate_t)) {
- fixed_rate_t& rate(boost::get<fixed_rate_t>(state.value));
- if (*rate.first == post->amount.commodity()) {
- annotation_t details(rate.second);
- details.add_flags(ANNOTATION_PRICE_FIXATED);
- post->amount.annotate(details);
- break;
- }
+ std::vector<fixed_rate_t> rates;
+ get_applications<fixed_rate_t>(rates);
+ foreach (fixed_rate_t& rate, rates) {
+ if (*rate.first == post->amount.commodity()) {
+ annotation_t details(rate.second);
+ details.add_flags(ANNOTATION_PRICE_FIXATED);
+ post->amount.annotate(details);
+ break;
}
}
}
@@ -1631,12 +1658,10 @@ post_t * instance_t::parse_post(char * line,
post->pos->end_pos = context.curr_pos;
post->pos->end_line = context.linenum;
- if (! apply_stack.empty()) {
- foreach (const application_t& state, apply_stack)
- if (state.value.type() == typeid(string))
- post->parse_tags(boost::get<string>(state.value).c_str(),
- *context.scope, true);
- }
+ std::vector<string> tags;
+ get_applications<string>(tags);
+ foreach (string& tag, tags)
+ post->parse_tags(tag.c_str(), *context.scope, true);
TRACE_STOP(post_details, 1);
@@ -1849,12 +1874,10 @@ xact_t * instance_t::parse_xact(char * line,
xact->pos->end_pos = context.curr_pos;
xact->pos->end_line = context.linenum;
- if (! apply_stack.empty()) {
- foreach (const application_t& state, apply_stack)
- if (state.value.type() == typeid(string))
- xact->parse_tags(boost::get<string>(state.value).c_str(),
- *context.scope, false);
- }
+ std::vector<string> tags;
+ get_applications<string>(tags);
+ foreach (string& tag, tags)
+ xact->parse_tags(tag.c_str(), *context.scope, false);
TRACE_STOP(xact_details, 1);