summaryrefslogtreecommitdiff
path: root/src/textual.cc
diff options
context:
space:
mode:
authorMartin Michlmayr <tbm@cyrius.com>2019-02-05 08:27:25 -0500
committerMartin Michlmayr <tbm@cyrius.com>2019-02-05 08:27:25 -0500
commit0bbb976ee3064ff59b319e30fd97e31020259760 (patch)
tree5d13986511c18d911b0d1b2dc498b0f81d3a3b0e /src/textual.cc
parent9de94d4adb7a566af38814f9d37e26c559b68b4f (diff)
parent7a5871d3b53e66ee261bea4b41512e99269b18b1 (diff)
downloadfork-ledger-0bbb976ee3064ff59b319e30fd97e31020259760.tar.gz
fork-ledger-0bbb976ee3064ff59b319e30fd97e31020259760.tar.bz2
fork-ledger-0bbb976ee3064ff59b319e30fd97e31020259760.zip
Merge branch 'next' into release/3.1.2
Diffstat (limited to 'src/textual.cc')
-rw-r--r--src/textual.cc88
1 files changed, 45 insertions, 43 deletions
diff --git a/src/textual.cc b/src/textual.cc
index 8fbc5c08..04e90e45 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2018, John Wiegley. All rights reserved.
+ * Copyright (c) 2003-2019, John Wiegley. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -282,6 +282,10 @@ void instance_t::parse()
std::cerr << _("Error: ") << err.what() << std::endl;
context.errors++;
+ if (! current_context.empty())
+ context.last = current_context + "\n" + err.what();
+ else
+ context.last = err.what();
}
}
@@ -553,7 +557,7 @@ void instance_t::option_directive(char * line)
void instance_t::automated_xact_directive(char * line)
{
- istream_pos_type pos = context.line_beg_pos;
+ std::istream::pos_type pos = context.line_beg_pos;
bool reveal_context = true;
@@ -649,7 +653,7 @@ void instance_t::automated_xact_directive(char * line)
void instance_t::period_xact_directive(char * line)
{
- istream_pos_type pos = context.line_beg_pos;
+ std::istream::pos_type pos = context.line_beg_pos;
bool reveal_context = true;
@@ -739,17 +743,8 @@ void instance_t::include_directive(char * line)
DEBUG("textual.include", "resolved path: " << filename.string());
mask_t glob;
-#if BOOST_VERSION >= 103700
path parent_path = filename.parent_path();
-#if BOOST_VERSION >= 104600
glob.assign_glob('^' + filename.filename().string() + '$');
-#else
- glob.assign_glob('^' + filename.filename() + '$');
-#endif
-#else // BOOST_VERSION >= 103700
- path parent_path = filename.branch_path();
- glob.assign_glob('^' + filename.leaf() + '$');
-#endif // BOOST_VERSION >= 103700
bool files_found = false;
if (exists(parent_path)) {
@@ -757,21 +752,9 @@ void instance_t::include_directive(char * line)
for (filesystem::directory_iterator iter(parent_path);
iter != end;
++iter) {
-#if BOOST_VERSION <= 103500
- if (is_regular(*iter))
-#else
if (is_regular_file(*iter))
-#endif
{
-#if BOOST_VERSION >= 103700
-#if BOOST_VERSION >= 104600
string base = (*iter).path().filename().string();
-#else
- string base = (*iter).filename();
-#endif
-#else // BOOST_VERSION >= 103700
- string base = (*iter).leaf();
-#endif // BOOST_VERSION >= 103700
if (glob.match(base)) {
journal_t * journal = context.journal;
account_t * master = top_account();
@@ -912,8 +895,8 @@ void instance_t::end_apply_directive(char * kind)
void instance_t::account_directive(char * line)
{
- istream_pos_type beg_pos = context.line_beg_pos;
- std::size_t beg_linenum = context.linenum;
+ std::istream::pos_type beg_pos = context.line_beg_pos;
+ std::size_t beg_linenum = context.linenum;
char * p = skip_ws(line);
account_t * account =
@@ -1644,29 +1627,30 @@ post_t * instance_t::parse_post(char * line,
}
DEBUG("textual.parse", "line " << context.linenum << ": "
- << "POST assign: parsed amt = " << *post->assigned_amount);
+ << "POST assign: parsed balance amount = " << *post->assigned_amount);
- amount_t& amt(*post->assigned_amount);
+ const amount_t& amt(*post->assigned_amount);
value_t account_total
(post->account->amount().strip_annotations(keep_details_t()));
DEBUG("post.assign", "line " << context.linenum << ": "
<< "account balance = " << account_total);
- DEBUG("post.assign",
- "line " << context.linenum << ": " << "post amount = " << amt);
+ DEBUG("post.assign", "line " << context.linenum << ": "
+ << "post amount = " << amt << " (is_zero = " << amt.is_zero() << ")");
- amount_t diff = amt;
+ balance_t diff = amt;
switch (account_total.type()) {
case value_t::AMOUNT:
- if (account_total.as_amount().commodity_ptr() == diff.commodity_ptr())
- diff -= account_total.as_amount();
+ diff -= account_total.as_amount();
+ DEBUG("textual.parse", "line " << context.linenum << ": "
+ << "Subtracting amount " << account_total.as_amount() << " from diff, yielding " << diff);
break;
case value_t::BALANCE:
- if (optional<amount_t> comm_bal =
- account_total.as_balance().commodity_amount(amt.commodity()))
- diff -= *comm_bal;
+ diff -= account_total.as_balance();
+ DEBUG("textual.parse", "line " << context.linenum << ": "
+ << "Subtracting balance " << account_total.as_balance() << " from diff, yielding " << diff);
break;
default:
@@ -1680,18 +1664,34 @@ post_t * instance_t::parse_post(char * line,
// Subtract amounts from previous posts to this account in the xact.
for (post_t* p : xact->posts) {
- if (p->account == post->account &&
- p->amount.commodity_ptr() == diff.commodity_ptr()) {
+ if (p->account == post->account) {
diff -= p->amount;
DEBUG("textual.parse", "line " << context.linenum << ": "
- << "Subtract " << p->amount << ", diff = " << diff);
+ << "Subtracting " << p->amount << ", diff = " << diff);
}
}
+ // If amt has a commodity, restrict balancing to that. Otherwise, it's the blanket '0' and
+ // check that all of them are zero.
+ if (amt.has_commodity()) {
+ DEBUG("textual.parse", "line " << context.linenum << ": "
+ << "Finding commodity " << amt.commodity() << " (" << amt << ") in balance " << diff);
+ optional<amount_t> wanted_commodity = diff.commodity_amount(amt.commodity());
+ if (!wanted_commodity) {
+ diff = amt - amt; // this is '0' with the correct commodity.
+ } else {
+ diff = *wanted_commodity;
+ }
+ DEBUG("textual.parse", "line " << context.linenum << ": "
+ << "Diff is now " << diff);
+ }
+
if (post->amount.is_null()) {
// balance assignment
if (! diff.is_zero()) {
- post->amount = diff;
+ // This will fail if there are more than 1 commodity in diff, which is wanted,
+ // as amount cannot store more than 1 commodity.
+ post->amount = diff.to_amount();
DEBUG("textual.parse", "line " << context.linenum << ": "
<< "Overwrite null posting");
}
@@ -1699,10 +1699,11 @@ post_t * instance_t::parse_post(char * line,
// balance assertion
diff -= post->amount;
if (! no_assertions && ! diff.is_zero()) {
- amount_t tot = amt - diff;
+ balance_t tot = -diff + amt;
+ DEBUG("textual.parse", "Balance assertion: off by " << diff << " (expected to see " << tot << ")");
throw_(parse_error,
_f("Balance assertion off by %1% (expected to see %2%)")
- % diff % tot);
+ % diff.to_string() % tot.to_string());
}
}
@@ -2012,7 +2013,8 @@ std::size_t journal_t::read_textual(parse_context_stack_t& context_stack)
TRACE_FINISH(parsing_total, 1);
if (context_stack.get_current().errors > 0)
- throw error_count(context_stack.get_current().errors);
+ throw error_count(context_stack.get_current().errors,
+ context_stack.get_current().last);
return context_stack.get_current().count;
}