Several improvement to transaction parsing.

This commit is contained in:
John Wiegley 2009-02-04 00:52:52 -04:00
parent 24ef163ba5
commit 28da097fc2

View file

@ -681,14 +681,16 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
string err_desc; string err_desc;
try { try {
// Parse the state flag
char p = peek_next_nonws(in);
if (in.eof())
return NULL;
// The account will be determined later... // The account will be determined later...
std::auto_ptr<xact_t> xact(new xact_t); std::auto_ptr<xact_t> xact(new xact_t);
if (entry) if (entry)
xact->entry = entry; xact->entry = entry;
// Parse the state flag
char p = peek_next_nonws(in);
switch (p) { switch (p) {
case '*': case '*':
xact->set_state(item_t::CLEARED); xact->set_state(item_t::CLEARED);
@ -801,21 +803,24 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
if (in.good() && ! in.eof()) { if (in.good() && ! in.eof()) {
p = peek_next_nonws(in); p = peek_next_nonws(in);
if (p == '@') { if (! in.eof() && p == '@') {
if (! saw_amount) if (! saw_amount)
throw parse_error("Transaction cannot have a cost without an amount"); throw parse_error("Transaction cannot have a cost without an amount");
DEBUG("textual.parse", "line " << linenum << ": " << DEBUG("textual.parse", "line " << linenum << ": " <<
"Found a price indicator"); "Found a price indicator");
bool per_unit = true; bool per_unit = true;
in.get(p); in.get(p);
if (in.peek() == '@') { if (in.peek() == '@') {
in.get(p); in.get(p);
per_unit = false; per_unit = false;
DEBUG("textual.parse", "line " << linenum << ": " << DEBUG("textual.parse", "line " << linenum << ": " <<
"And it's for a total price"); "And it's for a total price");
} }
p = peek_next_nonws(in);
if (in.good() && ! in.eof()) { if (in.good() && ! in.eof()) {
xact->cost = amount_t(); xact->cost = amount_t();
@ -862,6 +867,8 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
"Per-unit cost is " << per_unit_cost); "Per-unit cost is " << per_unit_cost);
DEBUG("textual.parse", "line " << linenum << ": " << DEBUG("textual.parse", "line " << linenum << ": " <<
"Annotated amount is " << xact->amount); "Annotated amount is " << xact->amount);
} else {
throw_(parse_error, "Expected a cost amount");
} }
} }
} }
@ -872,10 +879,13 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
if (in.good() && ! in.eof()) { if (in.good() && ! in.eof()) {
p = peek_next_nonws(in); p = peek_next_nonws(in);
if (p == '=') { if (! in.eof() && p == '=') {
in.get(p); in.get(p);
DEBUG("textual.parse", "line " << linenum << ": " << DEBUG("textual.parse", "line " << linenum << ": " <<
"Found a balance assignment indicator"); "Found a balance assignment indicator");
p = peek_next_nonws(in);
if (in.good() && ! in.eof()) { if (in.good() && ! in.eof()) {
xact->assigned_amount = amount_t(); xact->assigned_amount = amount_t();
@ -957,6 +967,8 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
"Overwrite null transaction"); "Overwrite null transaction");
} }
} }
} else {
throw_(parse_error, "Expected an assigned balance amount");
} }
} }
} }
@ -964,32 +976,39 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
// Parse the optional note // Parse the optional note
parse_note: parse_note:
if (in.good() && ! in.eof()) { if (in.good() && ! in.eof()) {
p = peek_next_nonws(in); p = peek_next_nonws(in);
if (p == ';') { if (! in.eof()) {
in.get(p); if (p == ';') {
p = peek_next_nonws(in); in.get(p);
xact->note = &line[long(in.tellg())]; if (! in.eof()) {
DEBUG("textual.parse", "line " << linenum << ": " << xact->note = &line[long(in.tellg())];
"Parsed a note '" << *xact->note << "'");
if (char * b = std::strchr(xact->note->c_str(), '['))
if (char * e = std::strchr(xact->note->c_str(), ']')) {
char buf[256];
std::strncpy(buf, b + 1, e - b - 1);
buf[e - b - 1] = '\0';
DEBUG("textual.parse", "line " << linenum << ": " << DEBUG("textual.parse", "line " << linenum << ": " <<
"Parsed a transaction date " << buf); "Parsed a note '" << *xact->note << "'");
if (char * p = std::strchr(buf, '=')) { if (char * b = std::strchr(xact->note->c_str(), '['))
*p++ = '\0'; if (char * e = std::strchr(xact->note->c_str(), ']')) {
xact->_date_eff = parse_date(p); char buf[256];
} std::strncpy(buf, b + 1, e - b - 1);
if (buf[0]) buf[e - b - 1] = '\0';
xact->_date = parse_date(buf);
DEBUG("textual.parse", "line " << linenum << ": " <<
"Parsed a transaction date " << buf);
if (char * p = std::strchr(buf, '=')) {
*p++ = '\0';
xact->_date_eff = parse_date(p);
}
if (buf[0])
xact->_date = parse_date(buf);
}
} }
} else {
beg = in.tellg();
throw_(parse_error, "Unexpected char '" << p
<< "' (Note: inline math requires parentheses)");
}
} }
} }