From a2f805ef73010de7f136eba5682a909cdae3e09b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 29 Jul 2004 01:56:53 -0400 Subject: Exit if parsing errors are encountered --- binary.cc | 19 +++++++++---------- binary.h | 8 ++++---- error.h | 2 +- main.cc | 58 +++++++++++++++++++++++++++++++++------------------------- textual.cc | 17 +++++++++++------ textual.h | 2 +- 6 files changed, 59 insertions(+), 47 deletions(-) diff --git a/binary.cc b/binary.cc index 1ed7f2c5..f760b83c 100644 --- a/binary.cc +++ b/binary.cc @@ -282,8 +282,10 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL) return acct; } -unsigned int read_binary_ledger(std::istream& in, const std::string& leader, - ledger_t *& ledger, account_t * master) +unsigned int read_binary_ledger(std::istream& in, + const std::string& leader, + ledger_t * ledger, + account_t * master) { ident = 0; c_ident = 0; @@ -291,7 +293,7 @@ unsigned int read_binary_ledger(std::istream& in, const std::string& leader, unsigned long magic; in.read((char *)&magic, sizeof(magic)); if (magic != magic_number) - return NULL; + return 0; #ifdef DEBUG { @@ -304,19 +306,16 @@ unsigned int read_binary_ledger(std::istream& in, const std::string& leader, unsigned long this_ver; in.read((char *)&this_ver, sizeof(this_ver)); if (this_ver != format_version) - return NULL; + return 0; unsigned short len; in.read((char *)&len, sizeof(len)); if (! len) - return NULL; + return 0; in.read(buf, len); if (leader != buf) - return NULL; - - if (! ledger) - ledger = new ledger_t; + return 0; in.read((char *)&len, sizeof(len)); @@ -333,7 +332,7 @@ unsigned int read_binary_ledger(std::istream& in, const std::string& leader, in.read((char *)&old_mtime, sizeof(old_mtime)); stat(buf, &info); if (info.st_mtime > old_mtime) - return NULL; + return 0; } ledger->master = read_binary_account(in, master); diff --git a/binary.h b/binary.h index 4c7f3a23..4fe0a5ea 100644 --- a/binary.h +++ b/binary.h @@ -7,10 +7,10 @@ namespace ledger { extern unsigned long magic_number; -extern unsigned int read_binary_ledger(std::istream& in, - const std::string& leader, - ledger_t *& book, - account_t * master = NULL); +extern unsigned int read_binary_ledger(std::istream& in, + const std::string& leader, + ledger_t * book, + account_t * master = NULL); extern void write_binary_ledger(std::ostream& out, ledger_t * ledger, diff --git a/error.h b/error.h index e6a4984c..f332ae4c 100644 --- a/error.h +++ b/error.h @@ -30,7 +30,7 @@ class parse_error : public error virtual const char* what() const throw() { static std::ostringstream msg; - msg << "Error: " << file << ", line " << line << ": " << error::what(); + msg << file << ", line " << line << ": " << error::what(); return msg.str().c_str(); } }; diff --git a/main.cc b/main.cc index b5c44113..349ada47 100644 --- a/main.cc +++ b/main.cc @@ -1,5 +1,6 @@ #include "ledger.h" #include "balance.h" +#include "error.h" #include "textual.h" #include "binary.h" #include "constraint.h" @@ -505,7 +506,7 @@ static void show_help(std::ostream& out) int main(int argc, char * argv[]) { std::list files; - ledger::ledger_t * book = NULL; + ledger::ledger_t * book = new ledger::ledger_t; ledger::constraints_t constraints; ledger::format_t format; @@ -532,23 +533,24 @@ int main(int argc, char * argv[]) break; } + ledger::cache_dirty = true; + if (use_cache) if (const char * p = std::getenv("LEDGER_CACHE")) if (access(p, R_OK) != -1) { std::ifstream instr(p); if (! ledger::read_binary_ledger(instr, std::getenv("LEDGER"), book)) { + // We need to throw away what we've read, and create a new + // ledger delete book; - book = NULL; + book = new ledger::ledger_t; + } else { + ledger::cache_dirty = false; } } } - if (! book) { - book = new ledger::ledger_t; - ledger::cache_dirty = true; - } - ledger::current_ledger = book; // Parse the command-line options @@ -749,28 +751,34 @@ int main(int argc, char * argv[]) if (! use_cache || ledger::cache_dirty) { int entry_count = 0; - if (files.empty()) { - if (char * p = std::getenv("LEDGER")) - for (p = std::strtok(p, ":"); p; p = std::strtok(NULL, ":")) + try { + if (files.empty()) { + if (char * p = std::getenv("LEDGER")) + for (p = std::strtok(p, ":"); p; p = std::strtok(NULL, ":")) + entry_count += parse_ledger_file(p, book); + } else { + for (std::list::iterator i = files.begin(); + i != files.end(); i++) { + char buf[4096]; + char * p = buf; + std::strcpy(p, (*i).c_str()); entry_count += parse_ledger_file(p, book); - } else { - for (std::list::iterator i = files.begin(); - i != files.end(); i++) { - char buf[4096]; - char * p = buf; - std::strcpy(p, (*i).c_str()); - entry_count += parse_ledger_file(p, book); + } } - } - // Read prices from their own ledger file, after all others have - // been read. + // Read prices from their own ledger file, after all others have + // been read. - if (! ledger::price_db.empty()) { - const char * path = ledger::price_db.c_str(); - std::ifstream db(path); - book->sources.push_back(path); - entry_count += ledger::parse_textual_ledger(db, book, book->master); + if (! ledger::price_db.empty()) { + const char * path = ledger::price_db.c_str(); + std::ifstream db(path); + book->sources.push_back(path); + entry_count += ledger::parse_textual_ledger(db, book, book->master); + } + } + catch (ledger::error& err) { + std::cerr << "Fatal: " << err.what() << std::endl; + return 1; } if (entry_count == 0) { diff --git a/textual.cc b/textual.cc index fa49cc23..95506e99 100644 --- a/textual.cc +++ b/textual.cc @@ -504,20 +504,18 @@ entry_t * parse_entry(std::istream& in, ledger_t * ledger, // Textual ledger parser // -unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger, +unsigned int parse_textual_ledger(std::istream& in, ledger_t * ledger, account_t * master) { static char line[MAX_LINE + 1]; char c; - int count = 0; + unsigned int count = 0; + unsigned int errors = 0; commodity_t * time_commodity = NULL; std::list account_stack; automated_transactions_t auto_xacts; - if (! ledger) - ledger = new ledger_t; - if (! master) master = ledger->master; @@ -761,7 +759,8 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger, } } catch (const parse_error& err) { - std::cerr << err.what() << std::endl; + std::cerr << "Error: " << err.what() << std::endl; + errors++; } } @@ -772,6 +771,12 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger, COMMODITY_STYLE_NOMARKET); } + if (errors > 0) { + std::ostringstream msg; + msg << "Errors parsing file '" << path << "'"; + throw error(msg.str()); + } + return count; } diff --git a/textual.h b/textual.h index bda62f02..4ed705bf 100644 --- a/textual.h +++ b/textual.h @@ -5,7 +5,7 @@ namespace ledger { -extern unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger, +extern unsigned int parse_textual_ledger(std::istream& in, ledger_t * ledger, account_t * master = NULL); extern bool parse_date_mask(const char * date_str, struct std::tm * result); -- cgit v1.2.3