summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2005-08-22 18:47:54 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 02:41:17 -0400
commitfe825a9b78040ebebf9eea8f80410eb1bb116645 (patch)
tree2044d96318420bbf2f9a8cff29dd4259b2c4518f
parent266c43727adda82c0308fdea03ce81af32f088ed (diff)
downloadfork-ledger-fe825a9b78040ebebf9eea8f80410eb1bb116645.tar.gz
fork-ledger-fe825a9b78040ebebf9eea8f80410eb1bb116645.tar.bz2
fork-ledger-fe825a9b78040ebebf9eea8f80410eb1bb116645.zip
(parse): Improvements to QIF parsing.
-rw-r--r--qif.cc61
1 files changed, 42 insertions, 19 deletions
diff --git a/qif.cc b/qif.cc
index 8ca966d4..6dcb0ebb 100644
--- a/qif.cc
+++ b/qif.cc
@@ -44,10 +44,14 @@ unsigned int qif_parser_t::parse(std::istream& in,
{
std::auto_ptr<entry_t> entry;
std::auto_ptr<amount_t> amount;
- transaction_t * xact;
- unsigned int count = 0;
- account_t * misc = NULL;
- commodity_t * def_commodity = NULL;
+
+ transaction_t * xact;
+ unsigned int count = 0;
+ account_t * misc = NULL;
+ commodity_t * def_commodity = NULL;
+ bool saw_splits = false;
+ bool saw_category = false;
+ transaction_t * total = NULL;
entry.reset(new entry_t);
xact = new transaction_t(master);
@@ -86,14 +90,14 @@ unsigned int qif_parser_t::parse(std::istream& in,
case '!':
in >> line;
- // jww (2004-08-19): these types are not supported yet
- assert(std::strcmp(line, "Type:Invst") != 0 &&
- std::strcmp(line, "Account") != 0 &&
- std::strcmp(line, "Type:Cat") != 0 &&
- std::strcmp(line, "Type:Class") != 0 &&
- std::strcmp(line, "Type:Memorized") != 0);
-
- get_line(in);
+ if (std::strcmp(line, "Type:Invst") == 0 ||
+ std::strcmp(line, "Account") == 0 ||
+ std::strcmp(line, "Type:Cat") == 0 ||
+ std::strcmp(line, "Type:Class") == 0 ||
+ std::strcmp(line, "Type:Memorized") == 0)
+ throw parse_error(path, linenum,
+ std::string("QIF files of type ") + line +
+ " are not supported.");
break;
case 'D':
@@ -120,8 +124,12 @@ unsigned int qif_parser_t::parse(std::istream& in,
if (prec > def_commodity->precision)
def_commodity->precision = prec;
- if (c == '$')
+ if (c == '$') {
+ saw_splits = true;
xact->amount.negate();
+ } else {
+ total = xact;
+ }
break;
}
@@ -139,6 +147,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
if (std::isdigit(in.peek())) {
in >> line;
entry->code = line;
+ } else {
+ in >> line;
}
break;
@@ -165,8 +175,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
line[len - 1] = '\0';
xact->account = journal->find_account(line[0] == '[' ?
line + 1 : line);
- // Negate the amount, to show the correct direction of flow
- xact->amount.negate();
+ if (c == 'L')
+ saw_category = true;
break;
}
@@ -194,10 +204,19 @@ unsigned int qif_parser_t::parse(std::istream& in,
other = master;
}
- transaction_t * nxact = new transaction_t(other);
- // The amount doesn't need to be set because the code below will
- // balance this transaction against the other.
- entry->add_transaction(nxact);
+ if (total && saw_category) {
+ if (! saw_splits)
+ total->amount.negate(); // negate, to show correct flow
+ else
+ total->account = other;
+ }
+
+ if (! saw_splits) {
+ transaction_t * nxact = new transaction_t(other);
+ // The amount doesn't need to be set because the code below
+ // will balance this transaction against the other.
+ entry->add_transaction(nxact);
+ }
if (journal->add_entry(entry.get())) {
entry->src_idx = src_idx;
@@ -216,6 +235,10 @@ unsigned int qif_parser_t::parse(std::istream& in,
beg_line = 0; // reset for next entry
break;
}
+
+ default:
+ get_line(in);
+ break;
}
}