Exit if parsing errors are encountered
This commit is contained in:
parent
c598550d50
commit
a2f805ef73
6 changed files with 60 additions and 48 deletions
19
binary.cc
19
binary.cc
|
|
@ -282,8 +282,10 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL)
|
||||||
return acct;
|
return acct;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int read_binary_ledger(std::istream& in, const std::string& leader,
|
unsigned int read_binary_ledger(std::istream& in,
|
||||||
ledger_t *& ledger, account_t * master)
|
const std::string& leader,
|
||||||
|
ledger_t * ledger,
|
||||||
|
account_t * master)
|
||||||
{
|
{
|
||||||
ident = 0;
|
ident = 0;
|
||||||
c_ident = 0;
|
c_ident = 0;
|
||||||
|
|
@ -291,7 +293,7 @@ unsigned int read_binary_ledger(std::istream& in, const std::string& leader,
|
||||||
unsigned long magic;
|
unsigned long magic;
|
||||||
in.read((char *)&magic, sizeof(magic));
|
in.read((char *)&magic, sizeof(magic));
|
||||||
if (magic != magic_number)
|
if (magic != magic_number)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
|
|
@ -304,19 +306,16 @@ unsigned int read_binary_ledger(std::istream& in, const std::string& leader,
|
||||||
unsigned long this_ver;
|
unsigned long this_ver;
|
||||||
in.read((char *)&this_ver, sizeof(this_ver));
|
in.read((char *)&this_ver, sizeof(this_ver));
|
||||||
if (this_ver != format_version)
|
if (this_ver != format_version)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
in.read((char *)&len, sizeof(len));
|
in.read((char *)&len, sizeof(len));
|
||||||
if (! len)
|
if (! len)
|
||||||
return NULL;
|
return 0;
|
||||||
in.read(buf, len);
|
in.read(buf, len);
|
||||||
|
|
||||||
if (leader != buf)
|
if (leader != buf)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
if (! ledger)
|
|
||||||
ledger = new ledger_t;
|
|
||||||
|
|
||||||
in.read((char *)&len, sizeof(len));
|
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));
|
in.read((char *)&old_mtime, sizeof(old_mtime));
|
||||||
stat(buf, &info);
|
stat(buf, &info);
|
||||||
if (info.st_mtime > old_mtime)
|
if (info.st_mtime > old_mtime)
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ledger->master = read_binary_account(in, master);
|
ledger->master = read_binary_account(in, master);
|
||||||
|
|
|
||||||
8
binary.h
8
binary.h
|
|
@ -7,10 +7,10 @@ namespace ledger {
|
||||||
|
|
||||||
extern unsigned long magic_number;
|
extern unsigned long magic_number;
|
||||||
|
|
||||||
extern unsigned int read_binary_ledger(std::istream& in,
|
extern unsigned int read_binary_ledger(std::istream& in,
|
||||||
const std::string& leader,
|
const std::string& leader,
|
||||||
ledger_t *& book,
|
ledger_t * book,
|
||||||
account_t * master = NULL);
|
account_t * master = NULL);
|
||||||
|
|
||||||
extern void write_binary_ledger(std::ostream& out,
|
extern void write_binary_ledger(std::ostream& out,
|
||||||
ledger_t * ledger,
|
ledger_t * ledger,
|
||||||
|
|
|
||||||
2
error.h
2
error.h
|
|
@ -30,7 +30,7 @@ class parse_error : public error
|
||||||
|
|
||||||
virtual const char* what() const throw() {
|
virtual const char* what() const throw() {
|
||||||
static std::ostringstream msg;
|
static std::ostringstream msg;
|
||||||
msg << "Error: " << file << ", line " << line << ": " << error::what();
|
msg << file << ", line " << line << ": " << error::what();
|
||||||
return msg.str().c_str();
|
return msg.str().c_str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
60
main.cc
60
main.cc
|
|
@ -1,5 +1,6 @@
|
||||||
#include "ledger.h"
|
#include "ledger.h"
|
||||||
#include "balance.h"
|
#include "balance.h"
|
||||||
|
#include "error.h"
|
||||||
#include "textual.h"
|
#include "textual.h"
|
||||||
#include "binary.h"
|
#include "binary.h"
|
||||||
#include "constraint.h"
|
#include "constraint.h"
|
||||||
|
|
@ -505,7 +506,7 @@ static void show_help(std::ostream& out)
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
{
|
{
|
||||||
std::list<std::string> files;
|
std::list<std::string> files;
|
||||||
ledger::ledger_t * book = NULL;
|
ledger::ledger_t * book = new ledger::ledger_t;
|
||||||
ledger::constraints_t constraints;
|
ledger::constraints_t constraints;
|
||||||
ledger::format_t format;
|
ledger::format_t format;
|
||||||
|
|
||||||
|
|
@ -532,23 +533,24 @@ int main(int argc, char * argv[])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ledger::cache_dirty = true;
|
||||||
|
|
||||||
if (use_cache)
|
if (use_cache)
|
||||||
if (const char * p = std::getenv("LEDGER_CACHE"))
|
if (const char * p = std::getenv("LEDGER_CACHE"))
|
||||||
if (access(p, R_OK) != -1) {
|
if (access(p, R_OK) != -1) {
|
||||||
std::ifstream instr(p);
|
std::ifstream instr(p);
|
||||||
if (! ledger::read_binary_ledger(instr, std::getenv("LEDGER"),
|
if (! ledger::read_binary_ledger(instr, std::getenv("LEDGER"),
|
||||||
book)) {
|
book)) {
|
||||||
|
// We need to throw away what we've read, and create a new
|
||||||
|
// ledger
|
||||||
delete book;
|
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;
|
ledger::current_ledger = book;
|
||||||
|
|
||||||
// Parse the command-line options
|
// Parse the command-line options
|
||||||
|
|
@ -749,28 +751,34 @@ int main(int argc, char * argv[])
|
||||||
if (! use_cache || ledger::cache_dirty) {
|
if (! use_cache || ledger::cache_dirty) {
|
||||||
int entry_count = 0;
|
int entry_count = 0;
|
||||||
|
|
||||||
if (files.empty()) {
|
try {
|
||||||
if (char * p = std::getenv("LEDGER"))
|
if (files.empty()) {
|
||||||
for (p = std::strtok(p, ":"); p; p = std::strtok(NULL, ":"))
|
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<std::string>::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);
|
entry_count += parse_ledger_file(p, book);
|
||||||
} else {
|
}
|
||||||
for (std::list<std::string>::iterator i = files.begin();
|
}
|
||||||
i != files.end(); i++) {
|
|
||||||
char buf[4096];
|
// Read prices from their own ledger file, after all others have
|
||||||
char * p = buf;
|
// been read.
|
||||||
std::strcpy(p, (*i).c_str());
|
|
||||||
entry_count += parse_ledger_file(p, book);
|
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) {
|
||||||
// Read prices from their own ledger file, after all others have
|
std::cerr << "Fatal: " << err.what() << std::endl;
|
||||||
// been read.
|
return 1;
|
||||||
|
|
||||||
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 (entry_count == 0) {
|
if (entry_count == 0) {
|
||||||
|
|
|
||||||
17
textual.cc
17
textual.cc
|
|
@ -504,20 +504,18 @@ entry_t * parse_entry(std::istream& in, ledger_t * ledger,
|
||||||
// Textual ledger parser
|
// 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)
|
account_t * master)
|
||||||
{
|
{
|
||||||
static char line[MAX_LINE + 1];
|
static char line[MAX_LINE + 1];
|
||||||
char c;
|
char c;
|
||||||
int count = 0;
|
unsigned int count = 0;
|
||||||
|
unsigned int errors = 0;
|
||||||
commodity_t * time_commodity = NULL;
|
commodity_t * time_commodity = NULL;
|
||||||
|
|
||||||
std::list<account_t *> account_stack;
|
std::list<account_t *> account_stack;
|
||||||
automated_transactions_t auto_xacts;
|
automated_transactions_t auto_xacts;
|
||||||
|
|
||||||
if (! ledger)
|
|
||||||
ledger = new ledger_t;
|
|
||||||
|
|
||||||
if (! master)
|
if (! master)
|
||||||
master = ledger->master;
|
master = ledger->master;
|
||||||
|
|
||||||
|
|
@ -761,7 +759,8 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t *& ledger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const parse_error& err) {
|
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);
|
COMMODITY_STYLE_NOMARKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errors > 0) {
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "Errors parsing file '" << path << "'";
|
||||||
|
throw error(msg.str());
|
||||||
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace ledger {
|
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);
|
account_t * master = NULL);
|
||||||
|
|
||||||
extern bool parse_date_mask(const char * date_str, struct std::tm * result);
|
extern bool parse_date_mask(const char * date_str, struct std::tm * result);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue