summaryrefslogtreecommitdiff
path: root/textual.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-07-27 18:37:55 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-07-27 18:37:55 -0400
commitc93175183e790cf7f1100dfd554197161a69e6fe (patch)
treeab83255a7c883047a6e3a36bbb2097cc13c8f216 /textual.cc
parente5a8bbf997f14ea2edf52d6dfe733969cc67589b (diff)
downloadfork-ledger-c93175183e790cf7f1100dfd554197161a69e6fe.tar.gz
fork-ledger-c93175183e790cf7f1100dfd554197161a69e6fe.tar.bz2
fork-ledger-c93175183e790cf7f1100dfd554197161a69e6fe.zip
Added the concept of "balance setting transactions".
Diffstat (limited to 'textual.cc')
-rw-r--r--textual.cc81
1 files changed, 79 insertions, 2 deletions
diff --git a/textual.cc b/textual.cc
index 4e011189..9ac018fa 100644
--- a/textual.cc
+++ b/textual.cc
@@ -201,13 +201,15 @@ transaction_t * parse_transaction(char * line, account_t * account,
goto finished;
if (p == ';')
goto parse_note;
+ if (p == '=' && entry)
+ goto parse_assign;
try {
unsigned long beg = (long)in.tellg();
xact->amount_expr =
parse_amount_expr(in, xact->amount, xact.get(),
- PARSE_VALEXPR_NO_REDUCE);
+ PARSE_VALEXPR_NO_REDUCE | PARSE_VALEXPR_NO_ASSIGN);
unsigned long end = (long)in.tellg();
xact->amount_expr.expr = std::string(line, beg, end - beg);
@@ -241,7 +243,8 @@ transaction_t * parse_transaction(char * line, account_t * account,
unsigned long beg = (long)in.tellg();
if (parse_amount_expr(in, *xact->cost, xact.get(),
- PARSE_VALEXPR_NO_MIGRATE))
+ PARSE_VALEXPR_NO_MIGRATE |
+ PARSE_VALEXPR_NO_ASSIGN))
throw new parse_error
("A transaction's cost must evaluate to a constant value");
@@ -288,6 +291,80 @@ transaction_t * parse_transaction(char * line, account_t * account,
DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
"Reduced amount is " << xact->amount);
+parse_assign:
+ if (entry != NULL) {
+ // Add this amount to the related account now
+
+ account_xdata_t& xdata(account_xdata(*xact->account));
+
+ if (xact->amount) {
+ xdata.value += xact->amount;
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "XACT assign: account total = " << xdata.value);
+ }
+
+ // Parse the optional assigned (= AMOUNT)
+
+ if (in.good() && ! in.eof()) {
+ p = peek_next_nonws(in);
+ if (p == '=') {
+ in.get(p);
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "Found a balance assignment indicator");
+ if (in.good() && ! in.eof()) {
+ amount_t amt;
+
+ try {
+ unsigned long beg = (long)in.tellg();
+
+ if (parse_amount_expr(in, amt, xact.get(),
+ PARSE_VALEXPR_NO_MIGRATE))
+ throw new parse_error
+ ("An assigned balance must evaluate to a constant value");
+
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "XACT assign: parsed amt = " << amt);
+
+ unsigned long end = (long)in.tellg();
+
+ amount_t diff;
+ if (xdata.value.type == value_t::AMOUNT)
+ diff = amt - *((amount_t *) xdata.value.data);
+ else if (xdata.value.type == value_t::BALANCE)
+ diff = amt - ((balance_t *) xdata.value.data)->amount(amt.commodity());
+ else if (xdata.value.type == value_t::BALANCE_PAIR)
+ diff = amt - ((balance_pair_t *) xdata.value.data)->quantity.amount(amt.commodity());
+ else
+ diff = amt;
+
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "XACT assign: diff = " << diff);
+
+ if (! diff.realzero()) {
+ if (xact->amount) {
+ transaction_t * temp
+ = new transaction_t(xact->account, diff, TRANSACTION_CALCULATED);
+ entry->add_transaction(temp);
+
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "Created balancing transaction");
+ } else {
+ xact->amount = diff;
+ DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ "Overwrite null transaction");
+ }
+ xdata.value = amt;
+ }
+ }
+ catch (error * err) {
+ err_desc = "While parsing assigned balance:";
+ throw err;
+ }
+ }
+ }
+ }
+ }
+
// Parse the optional note
parse_note: