summaryrefslogtreecommitdiff
path: root/src/textual.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/textual.cc')
-rw-r--r--src/textual.cc250
1 files changed, 120 insertions, 130 deletions
diff --git a/src/textual.cc b/src/textual.cc
index 94b2f4f0..b701233f 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -116,7 +116,11 @@ namespace {
#endif
if (expr) {
- amount = expr.calc(*xact).as_amount();
+ value_t result(expr.calc(*xact));
+ // jww (2009-02-01): What about storing time-dependent expressions?
+ if (! result.is_amount())
+ throw_(parse_error, "Transactions may only specify simple amounts");
+ amount = result.as_amount();
DEBUG("textual.parse", "The transaction amount is " << amount);
return expr;
}
@@ -182,7 +186,8 @@ void textual_parser_t::instance_t::parse()
try {
read_next_directive();
- beg_pos = end_pos;
+ beg_pos = end_pos;
+ beg_line = linenum;
}
catch (const std::exception& err) {
if (parent) {
@@ -194,16 +199,14 @@ void textual_parser_t::instance_t::parse()
instances.push_front(instance);
foreach (instance_t * instance, instances)
- add_error_context("In file included from '"
+ add_error_context("In file included from "
<< file_context(instance->pathname,
- instance->linenum - 1) << "':");
+ instance->linenum - 1));
}
add_error_context("While parsing file "
- << file_context(pathname, linenum - 1) << "\n");
+ << file_context(pathname, linenum - 1));
- std::cout.flush();
- std::cerr << ledger::error_context()
- << "Error: " << err.what() << std::endl;
+ report_error(err);
errors++;
}
}
@@ -446,7 +449,7 @@ void textual_parser_t::instance_t::option_directive(char * line)
if (p)
*p++ = '\0';
}
- process_option(line + 2, session, p);
+ process_option(line + 2, session, p, line);
}
void textual_parser_t::instance_t::automated_entry_directive(char * line)
@@ -501,13 +504,15 @@ void textual_parser_t::instance_t::entry_directive(char * line)
// possibility that add_entry ma throw an exception, which
// would cause us to leak without this guard.
std::auto_ptr<entry_t> entry_ptr(entry);
+
+ entry->src_idx = src_idx;
+ entry->beg_pos = beg_pos;
+ entry->beg_line = beg_line;
+ entry->end_pos = pos;
+ entry->end_line = linenum;
+
if (journal.add_entry(entry)) {
entry_ptr.release(); // it's owned by the journal now
- entry->src_idx = src_idx;
- entry->beg_pos = beg_pos;
- entry->beg_line = beg_line;
- entry->end_pos = pos;
- entry->end_line = linenum;
count++;
}
// It's perfectly valid for the journal to reject the entry,
@@ -653,6 +658,9 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
{
std::istringstream in(line);
+ istream_pos_type beg = in.tellg();
+ istream_pos_type end = beg;
+
string err_desc;
try {
@@ -683,22 +691,22 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
// Parse the account name
- istream_pos_type account_beg = in.tellg();
- istream_pos_type account_end = account_beg;
+ beg = in.tellg();
+ end = beg;
while (! in.eof()) {
in.get(p);
if (in.eof() || (std::isspace(p) &&
(p == '\t' || in.peek() == EOF ||
std::isspace(in.peek()))))
break;
- account_end += 1;
+ end += 1;
}
- if (account_beg == account_end)
+ if (beg == end)
throw parse_error("No account was specified");
- char * b = &line[long(account_beg)];
- char * e = &line[long(account_end)];
+ char * b = &line[long(beg)];
+ char * e = &line[long(end)];
if ((*b == '[' && *(e - 1) == ']') ||
(*b == '(' && *(e - 1) == ')')) {
@@ -738,34 +746,28 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
if (p == '=' && entry)
goto parse_assign;
- try {
- istream_pos_type beg = in.tellg();
+ beg = in.tellg();
- xact->amount_expr =
- parse_amount_expr(in, xact->amount, xact.get(),
- static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
- static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
- saw_amount = true;
+ xact->amount_expr =
+ parse_amount_expr(in, xact->amount, xact.get(),
+ static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
+ static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
+ saw_amount = true;
- if (! xact->amount.is_null()) {
- xact->amount.reduce();
- DEBUG("textual.parse", "line " << linenum << ": " <<
- "Reduced amount is " << xact->amount);
- }
+ if (! xact->amount.is_null()) {
+ xact->amount.reduce();
+ DEBUG("textual.parse", "line " << linenum << ": " <<
+ "Reduced amount is " << xact->amount);
+ }
- // We don't need to store the actual expression that resulted in the
- // amount if it's constant
- if (xact->amount_expr) {
- if (xact->amount_expr->is_constant())
- xact->amount_expr = expr_t();
+ // We don't need to store the actual expression that resulted in the
+ // amount if it's constant
+ if (xact->amount_expr) {
+ if (xact->amount_expr->is_constant())
+ xact->amount_expr = expr_t();
- istream_pos_type end = in.tellg();
- xact->amount_expr->set_text(string(line, long(beg), long(end - beg)));
- }
- }
- catch (const std::exception& err) {
- add_error_context("While parsing transaction amount:\n");
- throw;
+ end = in.tellg();
+ xact->amount_expr->set_text(string(line, long(beg), long(end - beg)));
}
}
@@ -792,27 +794,21 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
if (in.good() && ! in.eof()) {
xact->cost = amount_t();
- try {
- istream_pos_type beg = in.tellg();
-
- xact->cost_expr =
- parse_amount_expr(in, *xact->cost, xact.get(),
- static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
- static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
-
- if (xact->cost_expr) {
- istream_pos_type end = in.tellg();
- if (per_unit)
- xact->cost_expr->set_text(string("@") +
- string(line, long(beg), long(end - beg)));
- else
- xact->cost_expr->set_text(string("@@") +
- string(line, long(beg), long(end - beg)));
- }
- }
- catch (const std::exception& err) {
- add_error_context("While parsing transaction cost:\n");
- throw;
+ beg = in.tellg();
+
+ xact->cost_expr =
+ parse_amount_expr(in, *xact->cost, xact.get(),
+ static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE) |
+ static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
+
+ if (xact->cost_expr) {
+ end = in.tellg();
+ if (per_unit)
+ xact->cost_expr->set_text(string("@") +
+ string(line, long(beg), long(end - beg)));
+ else
+ xact->cost_expr->set_text(string("@@") +
+ string(line, long(beg), long(end - beg)));
}
if (xact->cost->sign() < 0)
@@ -850,82 +846,76 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
if (in.good() && ! in.eof()) {
xact->assigned_amount = amount_t();
- try {
- istream_pos_type beg = in.tellg();
+ beg = in.tellg();
- xact->assigned_amount_expr =
- parse_amount_expr(in, *xact->assigned_amount, xact.get(),
- static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE));
+ xact->assigned_amount_expr =
+ parse_amount_expr(in, *xact->assigned_amount, xact.get(),
+ static_cast<uint_least8_t>(expr_t::PARSE_NO_MIGRATE));
- if (xact->assigned_amount->is_null())
- throw parse_error
- ("An assigned balance must evaluate to a constant value");
+ if (xact->assigned_amount->is_null())
+ throw parse_error
+ ("An assigned balance must evaluate to a constant value");
- DEBUG("textual.parse", "line " << linenum << ": " <<
- "XACT assign: parsed amt = " << *xact->assigned_amount);
+ DEBUG("textual.parse", "line " << linenum << ": " <<
+ "XACT assign: parsed amt = " << *xact->assigned_amount);
- if (xact->assigned_amount_expr) {
- istream_pos_type end = in.tellg();
- xact->assigned_amount_expr->set_text
- (string("=") + string(line, long(beg), long(end - beg)));
- }
+ if (xact->assigned_amount_expr) {
+ end = in.tellg();
+ xact->assigned_amount_expr->set_text
+ (string("=") + string(line, long(beg), long(end - beg)));
+ }
- account_t::xdata_t& xdata(xact->account->xdata());
- amount_t& amt(*xact->assigned_amount);
+ account_t::xdata_t& xdata(xact->account->xdata());
+ amount_t& amt(*xact->assigned_amount);
- DEBUG("xact.assign",
- "account balance = " << xdata.value.strip_annotations());
- DEBUG("xact.assign",
- "xact amount = " << amt.strip_annotations());
+ DEBUG("xact.assign",
+ "account balance = " << xdata.value.strip_annotations());
+ DEBUG("xact.assign",
+ "xact amount = " << amt.strip_annotations());
- amount_t diff;
- if (xdata.value.is_amount()) {
- diff = amt - xdata.value.as_amount();
- }
- else if (xdata.value.is_balance()) {
- if (optional<amount_t> comm_bal =
- xdata.value.as_balance().commodity_amount(amt.commodity()))
- diff = amt - *comm_bal;
- else
- diff = amt;
- }
- else if (xdata.value.is_balance_pair()) {
- if (optional<amount_t> comm_bal =
- xdata.value.as_balance_pair().commodity_amount(amt.commodity()))
- diff = amt - *comm_bal;
- else
- diff = amt;
- }
- else {
+ amount_t diff;
+ if (xdata.value.is_amount()) {
+ diff = amt - xdata.value.as_amount();
+ }
+ else if (xdata.value.is_balance()) {
+ if (optional<amount_t> comm_bal =
+ xdata.value.as_balance().commodity_amount(amt.commodity()))
+ diff = amt - *comm_bal;
+ else
diff = amt;
- }
+ }
+ else if (xdata.value.is_balance_pair()) {
+ if (optional<amount_t> comm_bal =
+ xdata.value.as_balance_pair().commodity_amount(amt.commodity()))
+ diff = amt - *comm_bal;
+ else
+ diff = amt;
+ }
+ else {
+ diff = amt;
+ }
+
+ DEBUG("xact.assign", "diff = " << diff.strip_annotations());
+ DEBUG("textual.parse", "line " << linenum << ": " <<
+ "XACT assign: diff = " << diff.strip_annotations());
+
+ if (! diff.is_zero()) {
+ if (! xact->amount.is_null()) {
+ diff -= xact->amount;
+ if (! diff.is_zero()) {
+ xact_t * temp = new xact_t(xact->account, diff,
+ ITEM_GENERATED | XACT_CALCULATED);
+ entry->add_xact(temp);
- DEBUG("xact.assign", "diff = " << diff.strip_annotations());
- DEBUG("textual.parse", "line " << linenum << ": " <<
- "XACT assign: diff = " << diff.strip_annotations());
-
- if (! diff.is_zero()) {
- if (! xact->amount.is_null()) {
- diff -= xact->amount;
- if (! diff.is_zero()) {
- xact_t * temp = new xact_t(xact->account, diff,
- ITEM_GENERATED | XACT_CALCULATED);
- entry->add_xact(temp);
-
- DEBUG("textual.parse", "line " << linenum << ": " <<
- "Created balancing transaction");
- }
- } else {
- xact->amount = diff;
DEBUG("textual.parse", "line " << linenum << ": " <<
- "Overwrite null transaction");
+ "Created balancing transaction");
}
+ } else {
+ xact->amount = diff;
+ DEBUG("textual.parse", "line " << linenum << ": " <<
+ "Overwrite null transaction");
}
}
- catch (const std::exception& err) {
- add_error_context("While parsing assigned balance:\n");
- throw;
- }
}
}
}
@@ -967,8 +957,8 @@ xact_t * textual_parser_t::instance_t::parse_xact(char * line,
}
catch (const std::exception& err) {
- add_error_context("While parsing transaction:\n");
- add_error_context(line_context(line, in.tellg()));
+ add_error_context("While parsing transaction:");
+ add_error_context(line_context(line, beg, in.tellg()));
throw;
}
}