(parse): Improvements to QIF parsing.

This commit is contained in:
John Wiegley 2005-08-22 18:47:54 +00:00
parent 266c43727a
commit fe825a9b78

61
qif.cc
View file

@ -44,10 +44,14 @@ unsigned int qif_parser_t::parse(std::istream& in,
{ {
std::auto_ptr<entry_t> entry; std::auto_ptr<entry_t> entry;
std::auto_ptr<amount_t> amount; std::auto_ptr<amount_t> amount;
transaction_t * xact;
unsigned int count = 0; transaction_t * xact;
account_t * misc = NULL; unsigned int count = 0;
commodity_t * def_commodity = NULL; 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); entry.reset(new entry_t);
xact = new transaction_t(master); xact = new transaction_t(master);
@ -86,14 +90,14 @@ unsigned int qif_parser_t::parse(std::istream& in,
case '!': case '!':
in >> line; in >> line;
// jww (2004-08-19): these types are not supported yet if (std::strcmp(line, "Type:Invst") == 0 ||
assert(std::strcmp(line, "Type:Invst") != 0 && std::strcmp(line, "Account") == 0 ||
std::strcmp(line, "Account") != 0 && std::strcmp(line, "Type:Cat") == 0 ||
std::strcmp(line, "Type:Cat") != 0 && std::strcmp(line, "Type:Class") == 0 ||
std::strcmp(line, "Type:Class") != 0 && std::strcmp(line, "Type:Memorized") == 0)
std::strcmp(line, "Type:Memorized") != 0); throw parse_error(path, linenum,
std::string("QIF files of type ") + line +
get_line(in); " are not supported.");
break; break;
case 'D': case 'D':
@ -120,8 +124,12 @@ unsigned int qif_parser_t::parse(std::istream& in,
if (prec > def_commodity->precision) if (prec > def_commodity->precision)
def_commodity->precision = prec; def_commodity->precision = prec;
if (c == '$') if (c == '$') {
saw_splits = true;
xact->amount.negate(); xact->amount.negate();
} else {
total = xact;
}
break; break;
} }
@ -139,6 +147,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
if (std::isdigit(in.peek())) { if (std::isdigit(in.peek())) {
in >> line; in >> line;
entry->code = line; entry->code = line;
} else {
in >> line;
} }
break; break;
@ -165,8 +175,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
line[len - 1] = '\0'; line[len - 1] = '\0';
xact->account = journal->find_account(line[0] == '[' ? xact->account = journal->find_account(line[0] == '[' ?
line + 1 : line); line + 1 : line);
// Negate the amount, to show the correct direction of flow if (c == 'L')
xact->amount.negate(); saw_category = true;
break; break;
} }
@ -194,10 +204,19 @@ unsigned int qif_parser_t::parse(std::istream& in,
other = master; other = master;
} }
transaction_t * nxact = new transaction_t(other); if (total && saw_category) {
// The amount doesn't need to be set because the code below will if (! saw_splits)
// balance this transaction against the other. total->amount.negate(); // negate, to show correct flow
entry->add_transaction(nxact); 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())) { if (journal->add_entry(entry.get())) {
entry->src_idx = src_idx; 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 beg_line = 0; // reset for next entry
break; break;
} }
default:
get_line(in);
break;
} }
} }