summaryrefslogtreecommitdiff
path: root/parse.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2003-10-11 22:59:43 +0000
committerJohn Wiegley <johnw@newartisans.com>2003-10-11 22:59:43 +0000
commit854b719f1ec704a7a84bee629bc759b25d19ca6f (patch)
tree14602d9d63c0ab5bb944f1e82ed84e4ac884f8b6 /parse.cc
parent7ebe72c054575af9771644c8164ef7be7e52e388 (diff)
downloadfork-ledger-854b719f1ec704a7a84bee629bc759b25d19ca6f.tar.gz
fork-ledger-854b719f1ec704a7a84bee629bc759b25d19ca6f.tar.bz2
fork-ledger-854b719f1ec704a7a84bee629bc759b25d19ca6f.zip
c
Diffstat (limited to 'parse.cc')
-rw-r--r--parse.cc176
1 files changed, 1 insertions, 175 deletions
diff --git a/parse.cc b/parse.cc
index 5cdfb9e3..5b1ed5ab 100644
--- a/parse.cc
+++ b/parse.cc
@@ -232,185 +232,11 @@ entry * parse_entry(std::istream& in, book * ledger)
// If there were no transactions, throw away the entry
- if (curr->xacts.empty()) {
+ if (curr->xacts.empty() || ! curr->finalize(do_compute)) {
delete curr;
return NULL;
}
- // Scan through and compute the total balance for the entry. This
- // is used for auto-calculating the value of entries with no cost,
- // and the per-unit price of unpriced commodities.
-
- totals balance;
-
- for (std::list<transaction *>::iterator x = curr->xacts.begin();
- x != curr->xacts.end();
- x++)
- if ((*x)->cost && ! (*x)->is_virtual) {
- amount * value = (*x)->cost->value();
- balance.credit(value);
- delete value;
- }
-
- // If one transaction is of a different commodity than the others,
- // and it has no per-unit price, determine its price by dividing
- // the unit count into the value of the balance.
- //
- // NOTE: We don't do this for prefix-style or joined-symbol
- // commodities. Also, do it for the last eligible commodity first,
- // if it meets the criteria.
-
- if (! balance.amounts.empty() && balance.amounts.size() == 2) {
- for (std::list<transaction *>::iterator x = curr->xacts.begin();
- x != curr->xacts.end();
- x++) {
- if ((*x)->is_virtual)
- continue;
-
- if (! (*x)->cost->has_price() &&
- ! (*x)->cost->commdty()->prefix &&
- (*x)->cost->commdty()->separate) {
- for (totals::iterator i = balance.amounts.begin();
- i != balance.amounts.end();
- i++) {
- if ((*i).second->commdty() != (*x)->cost->commdty()) {
- (*x)->cost->set_value((*i).second);
- break;
- }
- }
- break;
- }
- }
- }
-
- // Walk through each of the transactions, fixing up any that we
- // can, and performing any on-the-fly calculations.
-
- bool empty_allowed = true;
-
- for (std::list<transaction *>::iterator x = curr->xacts.begin();
- x != curr->xacts.end();
- x++) {
- if ((*x)->is_virtual || (*x)->cost)
- continue;
-
- if (! empty_allowed || balance.amounts.empty() ||
- balance.amounts.size() != 1) {
- std::cerr << "Error, line " << linenum
- << ": Transaction entry is lacking an amount."
- << std::endl;
- return NULL;
- }
- empty_allowed = false;
-
- // If one transaction gives no value at all -- and all the
- // rest are of the same commodity -- then its value is the
- // inverse of the computed value of the others.
-
- totals::iterator i = balance.amounts.begin();
- (*x)->cost = (*i).second->value();
- (*x)->cost->negate();
-
- if (do_compute)
- (*x)->acct->balance.credit((*x)->cost);
- }
-
- // If virtual accounts are being supported, walk through the
- // transactions and create new virtual transactions for all that
- // apply.
-
- for (book::virtual_map_iterator m = ledger->virtual_mapping.begin();
- m != ledger->virtual_mapping.end();
- m++) {
- std::list<transaction *> xacts;
-
- for (std::list<transaction *>::iterator x = curr->xacts.begin();
- x != curr->xacts.end();
- x++) {
- if ((*x)->is_virtual ||
- ! ledger::matches(*((*m).first), (*x)->acct->as_str()))
- continue;
-
- for (std::list<transaction *>::iterator i = (*m).second->begin();
- i != (*m).second->end();
- i++) {
- transaction * t;
-
- if ((*i)->cost->commdty()) {
- t = new transaction((*i)->acct, (*i)->cost);
- } else {
- amount * temp = (*x)->cost->value();
- t = new transaction((*i)->acct, temp->value((*i)->cost));
- delete temp;
- }
-
- t->is_virtual = (*i)->is_virtual;
- t->must_balance = (*i)->must_balance;
-
- // If there is already a virtual transaction for the
- // account under consideration, and it's `must_balance'
- // flag matches, then simply add this amount to that
- // transaction.
-
- bool added = false;
-
- for (std::list<transaction *>::iterator y = xacts.begin();
- y != xacts.end();
- y++) {
- if ((*y)->is_virtual && (*y)->acct == t->acct &&
- (*y)->must_balance == t->must_balance) {
- (*y)->cost->credit(t->cost);
- delete t;
- added = true;
- break;
- }
- }
-
- if (! added)
- for (std::list<transaction *>::iterator y = curr->xacts.begin();
- y != curr->xacts.end();
- y++) {
- if ((*y)->is_virtual && (*y)->acct == t->acct &&
- (*y)->must_balance == t->must_balance) {
- (*y)->cost->credit(t->cost);
- delete t;
- added = true;
- break;
- }
- }
-
- if (! added)
- xacts.push_back(t);
- }
- }
-
- // Add to the current entry any virtual transactions which were
- // created. We have to do this afterward, otherwise the
- // iteration above is screwed up if we try adding new
- // transactions during the traversal.
-
- for (std::list<transaction *>::iterator x = xacts.begin();
- x != xacts.end();
- x++) {
- curr->xacts.push_back(*x);
-
- if (do_compute)
- (*x)->acct->balance.credit((*x)->cost);
- }
- }
-
- // Compute the balances again, just to make sure it all comes out
- // right (i.e., zero for every commodity).
-
- if (! curr->validate()) {
- std::cerr << "Error, line " << (linenum - 1)
- << ": Failed to balance the following transaction:"
- << std::endl;
- curr->print(std::cerr);
- curr->validate(true);
- delete curr;
- return NULL;
- }
return curr;
}