Fixed a few bugs related to apply directives
This commit is contained in:
parent
cf67fcbd06
commit
be289fba1f
3 changed files with 93 additions and 33 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
3
test/baseline/dir-apply.dat
Normal file
3
test/baseline/dir-apply.dat
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
2012-03-12 KFC
|
||||
Expenses:Food $40
|
||||
Assets:Cash
|
||||
34
test/baseline/dir-apply.test
Normal file
34
test/baseline/dir-apply.test
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
apply account Master Account
|
||||
|
||||
2012-03-12 KFC
|
||||
Expenses:Food $20
|
||||
Assets:Cash
|
||||
|
||||
end apply account
|
||||
|
||||
apply account Master Account
|
||||
|
||||
2012-03-12 KFC
|
||||
Expenses:Food $20
|
||||
Assets:Cash
|
||||
|
||||
end apply
|
||||
|
||||
apply account Master Account
|
||||
|
||||
2012-03-12 KFC
|
||||
Expenses:Food $20
|
||||
Assets:Cash
|
||||
|
||||
end
|
||||
|
||||
apply account Master Account
|
||||
include dir-apply.dat
|
||||
end
|
||||
|
||||
test reg food
|
||||
12-Mar-12 KFC Master A:Expenses:Food $20 $20
|
||||
12-Mar-12 KFC Master A:Expenses:Food $20 $40
|
||||
12-Mar-12 KFC Master A:Expenses:Food $20 $60
|
||||
12-Mar-12 KFC Master A:Expenses:Food $40 $100
|
||||
end test
|
||||
Loading…
Add table
Reference in a new issue