summaryrefslogtreecommitdiff
path: root/textual.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-07-27 02:23:02 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-07-27 02:23:02 -0400
commitd7dd02276c7c9ef4c8affefc6d6ed1e3431535b9 (patch)
treef1f461724c0079b5c0a0aa3b9290880a8b4c7f5e /textual.cc
parentdd5680c2674fe9ce458941ec9b3978cd7dda9bff (diff)
downloadfork-ledger-d7dd02276c7c9ef4c8affefc6d6ed1e3431535b9.tar.gz
fork-ledger-d7dd02276c7c9ef4c8affefc6d6ed1e3431535b9.tar.bz2
fork-ledger-d7dd02276c7c9ef4c8affefc6d6ed1e3431535b9.zip
further reorganization
Diffstat (limited to 'textual.cc')
-rw-r--r--textual.cc385
1 files changed, 190 insertions, 195 deletions
diff --git a/textual.cc b/textual.cc
index d4938524..fa49cc23 100644
--- a/textual.cc
+++ b/textual.cc
@@ -1,6 +1,6 @@
-#include "ledger.h"
-#include "constraint.h"
#include "textual.h"
+#include "constraint.h"
+#include "error.h"
#include <vector>
#include <fstream>
@@ -14,7 +14,7 @@
namespace ledger {
#if 0
-static const std::string entry1_fmt = "%?10d %p";
+static const std::string entry1_fmt = "%10d %p";
static const std::string entryn_fmt = " %-30a %15t";
#endif
@@ -360,13 +360,11 @@ void parse_automated_transactions(std::istream& in, ledger_t * ledger,
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
if (transaction_t * xact = parse_transaction(in, ledger, account, NULL)) {
- if (! xact->amount) {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": All automated transactions must have a value."
- << std::endl;
- } else {
+ if (! xact->amount)
+ throw parse_error(path, linenum,
+ "All automated transactions must have a value");
+ else
xacts.push_back(xact);
- }
}
}
@@ -461,11 +459,8 @@ entry_t * parse_entry(std::istream& in, ledger_t * ledger,
char * next = next_element(line);
- if (! quick_parse_date(line, &curr->date)) {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": Failed to parse date: " << line << std::endl;
- return NULL;
- }
+ if (! quick_parse_date(line, &curr->date))
+ throw parse_error(path, linenum, "Failed to parse date");
// Parse the optional cleared flag: *
@@ -532,241 +527,241 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger,
linenum = 1;
while (! in.eof()) {
- switch (in.peek()) {
- case -1: // end of file
- goto done;
-
- case ' ':
- case '\t':
- if (peek_next_nonws(in) != '\n') {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": Ignoring entry beginning with whitespace."
- << std::endl;
- in.getline(line, MAX_LINE);
+ try {
+ switch (in.peek()) {
+ case -1: // end of file
+ goto done;
+
+ case ' ':
+ case '\t':
+ if (peek_next_nonws(in) != '\n') {
+ in.getline(line, MAX_LINE);
+ linenum++;
+ throw parse_error(path, linenum,
+ "Ignoring entry beginning with whitespace");
+ }
+ // fall through...
+
+ case '\n':
linenum++;
+ case '\r': // skip blank lines
+ in.get(c);
break;
- }
- // fall through...
-
- case '\n':
- linenum++;
- case '\r': // skip blank lines
- in.get(c);
- break;
#ifdef TIMELOG_SUPPORT
- case 'i':
- case 'I': {
- std::string date, time;
-
- in >> c;
- in >> date;
- in >> time;
- date += " ";
- date += time;
-
- in.getline(line, MAX_LINE);
- linenum++;
-
- char * p = skip_ws(line);
- char * n = next_element(p, true);
- last_desc = n ? n : "";
-
- static struct std::tm when;
- if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
- time_in = std::mktime(&when);
- last_account = account_stack.front()->find_account(p);
- } else {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": Cannot parse timelog entry date." << std::endl;
- last_account = NULL;
- }
- break;
- }
-
- case 'o':
- case 'O':
- if (last_account) {
+ case 'i':
+ case 'I': {
std::string date, time;
in >> c;
in >> date;
in >> time;
+ date += " ";
+ date += time;
in.getline(line, MAX_LINE);
linenum++;
- date += " ";
- date += time;
+ char * p = skip_ws(line);
+ char * n = next_element(p, true);
+ last_desc = n ? n : "";
static struct std::tm when;
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
- entry_t * curr = new entry_t;
- curr->date = std::mktime(&when);
- curr->state = entry_t::CLEARED;
- curr->code = "";
- curr->payee = last_desc;
-
- double diff = std::difftime(curr->date, time_in) / 60.0 / 60.0;
- char buf[32];
- std::sprintf(buf, "%fh", diff);
- amount_t amt;
- amt.parse(buf, ledger);
- time_commodity = amt.commodity;
-
- transaction_t * xact = new transaction_t(curr, last_account, amt, amt,
- TRANSACTION_VIRTUAL);
- curr->add_transaction(xact);
-
- if (! finalize_entry(curr) || ! ledger->add_entry(curr))
- assert(0);
-
- count++;
+ time_in = std::mktime(&when);
+ last_account = account_stack.front()->find_account(p);
} else {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": Cannot parse timelog entry date." << std::endl;
+ last_account = NULL;
+ throw parse_error(path, linenum, "Cannot parse timelog entry date");
}
-
- last_account = NULL;
- } else {
- in.getline(line, MAX_LINE);
- linenum++;
+ break;
}
- break;
+
+ case 'o':
+ case 'O':
+ if (last_account) {
+ std::string date, time;
+
+ in >> c;
+ in >> date;
+ in >> time;
+
+ in.getline(line, MAX_LINE);
+ linenum++;
+
+ date += " ";
+ date += time;
+
+ static struct std::tm when;
+ if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
+ entry_t * curr = new entry_t;
+ curr->date = std::mktime(&when);
+ curr->state = entry_t::CLEARED;
+ curr->code = "";
+ curr->payee = last_desc;
+
+ double diff = std::difftime(curr->date, time_in) / 60.0 / 60.0;
+ char buf[32];
+ std::sprintf(buf, "%fh", diff);
+ amount_t amt;
+ amt.parse(buf, ledger);
+ time_commodity = amt.commodity;
+
+ transaction_t * xact = new transaction_t(curr, last_account, amt, amt,
+ TRANSACTION_VIRTUAL);
+ curr->add_transaction(xact);
+
+ if (! finalize_entry(curr) || ! ledger->add_entry(curr))
+ assert(0);
+
+ count++;
+ } else {
+ throw parse_error(path, linenum, "Cannot parse timelog entry date");
+ }
+
+ last_account = NULL;
+ } else {
+ in.getline(line, MAX_LINE);
+ linenum++;
+ }
+ break;
#endif // TIMELOG_SUPPORT
- case 'P': { // a pricing entry
- in >> c;
+ case 'P': { // a pricing entry
+ in >> c;
- std::time_t date;
- std::string symbol;
+ std::time_t date;
+ std::string symbol;
- in >> line; // the date
- if (! quick_parse_date(line, &date)) {
- std::cerr << "Error in " << path << ", line " << (linenum - 1)
- << ": Failed to parse date: " << line << std::endl;
- break;
- }
+ in >> line; // the date
+ if (! quick_parse_date(line, &date))
+ throw parse_error(path, linenum, "Failed to parse date");
- int hour, min, sec;
+ int hour, min, sec;
- in >> hour; // the time
- in >> c;
- in >> min;
- in >> c;
- in >> sec;
+ in >> hour; // the time
+ in >> c;
+ in >> min;
+ in >> c;
+ in >> sec;
- date = std::time_t(((unsigned long) date) +
- hour * 3600 + min * 60 + sec);
+ date = std::time_t(((unsigned long) date) +
+ hour * 3600 + min * 60 + sec);
- amount_t price;
+ amount_t price;
- parse_commodity(in, symbol);
- in >> line; // the price
- price.parse(line, ledger);
+ parse_commodity(in, symbol);
+ in >> line; // the price
+ price.parse(line, ledger);
- commodity_t * commodity = ledger->find_commodity(symbol, true);
- commodity->add_price(date, price);
- break;
- }
+ commodity_t * commodity = ledger->find_commodity(symbol, true);
+ commodity->add_price(date, price);
+ break;
+ }
- case 'N': { // don't download prices
- std::string symbol;
+ case 'N': { // don't download prices
+ std::string symbol;
- in >> c;
- parse_commodity(in, symbol);
+ in >> c;
+ parse_commodity(in, symbol);
- commodity_t * commodity = ledger->find_commodity(line, true);
- commodity->flags |= (COMMODITY_STYLE_CONSULTED |
- COMMODITY_STYLE_NOMARKET);
- break;
- }
+ commodity_t * commodity = ledger->find_commodity(line, true);
+ commodity->flags |= (COMMODITY_STYLE_CONSULTED |
+ COMMODITY_STYLE_NOMARKET);
+ break;
+ }
- case 'C': { // a flat conversion
- in >> c;
+ case 'C': { // a flat conversion
+ in >> c;
- std::string symbol;
- amount_t price;
+ std::string symbol;
+ amount_t price;
- parse_commodity(in, symbol);
- in >> line; // the price
- price.parse(line, ledger);
+ parse_commodity(in, symbol);
+ in >> line; // the price
+ price.parse(line, ledger);
- commodity_t * commodity = ledger->find_commodity(symbol, true);
- commodity->set_conversion(price);
- break;
- }
+ commodity_t * commodity = ledger->find_commodity(symbol, true);
+ commodity->set_conversion(price);
+ break;
+ }
- case 'Y': // set the current year
- in >> c;
- in >> now_tm->tm_year;
- now_tm->tm_year -= 1900;
- break;
+ case 'Y': // set the current year
+ in >> c;
+ in >> now_tm->tm_year;
+ now_tm->tm_year -= 1900;
+ break;
#ifdef TIMELOG_SUPPORT
- case 'h':
- case 'b':
+ case 'h':
+ case 'b':
#endif
- case ';': // a comment line
- in.getline(line, MAX_LINE);
- linenum++;
- break;
+ case ';': // a comment line
+ in.getline(line, MAX_LINE);
+ linenum++;
+ break;
- case '=': // automated transactions
- parse_automated_transactions(in, ledger, account_stack.front(),
- auto_xacts);
- break;
+ case '=': // automated transactions
+ parse_automated_transactions(in, ledger, account_stack.front(),
+ auto_xacts);
+ break;
- case '@': { // account specific
- in >> c;
- if (in.peek() == '@') {
- in.get(c);
- account_stack.pop_front();
+ case '@': { // account specific
+ in >> c;
+ if (in.peek() == '@') {
+ in.get(c);
+ account_stack.pop_front();
+ break;
+ }
+
+ in.getline(line, MAX_LINE);
+ linenum++;
+
+ account_t * acct = account_stack.front()->find_account(skip_ws(line));
+ account_stack.push_front(acct);
break;
}
- in.getline(line, MAX_LINE);
- linenum++;
+ case '!': // directive
+ in >> line;
+ if (std::string(line) == "!include") {
+ in.getline(line, MAX_LINE);
+ linenum++;
- account_t * acct = account_stack.front()->find_account(skip_ws(line));
- account_stack.push_front(acct);
- break;
- }
+ char * p = skip_ws(line);
+ std::ifstream stream(p);
- case '!': // directive
- in >> line;
- if (std::string(line) == "!include") {
- in.getline(line, MAX_LINE);
- linenum++;
+ ledger->sources.push_back(p);
- char * path = skip_ws(line);
- std::ifstream stream(path);
+ unsigned int curr_linenum = linenum;
+ std::string curr_path = path;
- ledger->sources.push_back(path);
+ count += parse_textual_ledger(stream, ledger, account_stack.front());
- unsigned int curr_linenum = linenum;
- count += parse_textual_ledger(stream, ledger, account_stack.front());
- linenum = curr_linenum;
- }
- break;
+ linenum = curr_linenum;
+ path = curr_path;
+ }
+ break;
- default: {
- unsigned int first_line = linenum;
- if (entry_t * entry = parse_entry(in, ledger, account_stack.front())) {
- if (! auto_xacts.automated_transactions.empty())
- auto_xacts.extend_entry(entry);
+ default: {
+ unsigned int first_line = linenum;
+ if (entry_t * entry = parse_entry(in, ledger, account_stack.front())) {
+ if (! auto_xacts.automated_transactions.empty())
+ auto_xacts.extend_entry(entry);
- if (ledger->add_entry(entry))
- count++;
- else
- std::cerr << "Error in " << path << ", line " << first_line
- << ": Entry does not balance." << std::endl;
- } else {
- std::cerr << "Error in " << path << ", line " << first_line
- << ": Failed to parse entry." << std::endl;
+ if (ledger->add_entry(entry))
+ count++;
+ else
+ throw parse_error(path, first_line, "Entry does not balance");
+ } else {
+ throw parse_error(path, first_line, "Failed to parse entry");
+ }
+ break;
+ }
}
- break;
}
+ catch (const parse_error& err) {
+ std::cerr << err.what() << std::endl;
}
}