more error checking and robustness mods
This commit is contained in:
parent
c57a2e74b8
commit
be18ab2f1a
5 changed files with 58 additions and 56 deletions
|
|
@ -187,8 +187,7 @@ void config_t::process_options(const std::string& command,
|
||||||
// If downloading is to be supported, configure the updater
|
// If downloading is to be supported, configure the updater
|
||||||
|
|
||||||
if (! commodity_t::updater && download_quotes)
|
if (! commodity_t::updater && download_quotes)
|
||||||
commodity_t::updater = new quotes_by_script(price_db,
|
commodity_t::updater = new quotes_by_script(price_db, pricing_leeway,
|
||||||
pricing_leeway,
|
|
||||||
cache_dirty);
|
cache_dirty);
|
||||||
|
|
||||||
if (! date_format.empty())
|
if (! date_format.empty())
|
||||||
|
|
@ -235,7 +234,8 @@ void parse_ledger_data(journal_t * journal,
|
||||||
entry_count += parse_journal_file(config.data_file, journal, account);
|
entry_count += parse_journal_file(config.data_file, journal, account);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! config.price_db.empty())
|
if (! config.price_db.empty() &&
|
||||||
|
access(config.price_db.c_str(), R_OK) != -1)
|
||||||
if (parse_journal_file(config.price_db, journal))
|
if (parse_journal_file(config.price_db, journal))
|
||||||
throw error("Entries not allowed in price history file");
|
throw error("Entries not allowed in price history file");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
|
@ -56,7 +57,7 @@ void quotes_by_script::operator()(commodity_t& commodity,
|
||||||
price.parse(buf);
|
price.parse(buf);
|
||||||
commodity.add_price(now, price);
|
commodity.add_price(now, price);
|
||||||
|
|
||||||
if (price && ! price_db.empty()) {
|
if (price && ! price_db.empty() && access(price_db.c_str(), W_OK) != -1) {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
strftime(buf, 127, "%Y/%m/%d %H:%M:%S", localtime(&now));
|
strftime(buf, 127, "%Y/%m/%d %H:%M:%S", localtime(&now));
|
||||||
ofstream database(price_db.c_str(), ios_base::out | ios_base::app);
|
ofstream database(price_db.c_str(), ios_base::out | ios_base::app);
|
||||||
|
|
|
||||||
69
valexpr.cc
69
valexpr.cc
|
|
@ -379,6 +379,21 @@ void value_expr_t::compute(value_t& result, const details_t& details) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void unexpected(char c, char wanted = '\0') {
|
||||||
|
if (c == -1) {
|
||||||
|
if (wanted)
|
||||||
|
throw value_expr_error(std::string("Missing '") + wanted + "'");
|
||||||
|
else
|
||||||
|
throw value_expr_error("Unexpected end");
|
||||||
|
} else {
|
||||||
|
if (wanted)
|
||||||
|
throw value_expr_error(std::string("Invalid char '") + c +
|
||||||
|
"' (wanted '" + wanted + "')");
|
||||||
|
else
|
||||||
|
throw value_expr_error(std::string("Invalid char '") + c + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
value_expr_t * parse_value_term(std::istream& in);
|
value_expr_t * parse_value_term(std::istream& in);
|
||||||
|
|
||||||
inline value_expr_t * parse_value_term(const char * p) {
|
inline value_expr_t * parse_value_term(const char * p) {
|
||||||
|
|
@ -406,7 +421,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
if (c == '}')
|
if (c == '}')
|
||||||
in.get(c);
|
in.get(c);
|
||||||
else
|
else
|
||||||
throw value_expr_error("Missing '}'");
|
unexpected(c, '}');
|
||||||
|
|
||||||
node.reset(new value_expr_t(value_expr_t::CONSTANT_A));
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_A));
|
||||||
node->constant_a.parse(buf);
|
node->constant_a.parse(buf);
|
||||||
|
|
@ -479,10 +494,9 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node->right = parse_value_expr(in, true);
|
node->right = parse_value_expr(in, true);
|
||||||
}
|
}
|
||||||
if (peek_next_nonws(in) == ')')
|
in.get(c);
|
||||||
in.get(c);
|
if (c != ')')
|
||||||
else
|
unexpected(c, ')');
|
||||||
throw value_expr_error("Missing ')'");
|
|
||||||
} else {
|
} else {
|
||||||
node->left = parse_value_term(in);
|
node->left = parse_value_term(in);
|
||||||
}
|
}
|
||||||
|
|
@ -508,7 +522,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
|
|
||||||
READ_INTO(in, buf, 255, c, c != '/');
|
READ_INTO(in, buf, 255, c, c != '/');
|
||||||
if (c != '/')
|
if (c != '/')
|
||||||
throw value_expr_error("Missing closing '/'");
|
unexpected(c, '/');
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node.reset(new value_expr_t(short_account_mask ?
|
node.reset(new value_expr_t(short_account_mask ?
|
||||||
|
|
@ -522,7 +536,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
case '\'': {
|
case '\'': {
|
||||||
READ_INTO(in, buf, 255, c, c != '\'');
|
READ_INTO(in, buf, 255, c, c != '\'');
|
||||||
if (c != '\'')
|
if (c != '\'')
|
||||||
throw value_expr_error("Missing closing '\''");
|
unexpected(c, '\'');
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node.reset(new value_expr_t(value_expr_t::F_INTERP_FUNC));
|
node.reset(new value_expr_t(value_expr_t::F_INTERP_FUNC));
|
||||||
|
|
@ -533,16 +547,15 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
node.reset(parse_value_expr(in, true));
|
node.reset(parse_value_expr(in, true));
|
||||||
if (peek_next_nonws(in) == ')')
|
in.get(c);
|
||||||
in.get(c);
|
if (c != ')')
|
||||||
else
|
unexpected(c, ')');
|
||||||
throw value_expr_error("Missing ')'");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '[': {
|
case '[': {
|
||||||
READ_INTO(in, buf, 255, c, c != ']');
|
READ_INTO(in, buf, 255, c, c != ']');
|
||||||
if (c != ']')
|
if (c != ']')
|
||||||
throw value_expr_error("Missing ']'");
|
unexpected(c, ']');
|
||||||
in.get(c);
|
in.get(c);
|
||||||
|
|
||||||
node.reset(new value_expr_t(value_expr_t::CONSTANT_T));
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_T));
|
||||||
|
|
@ -677,8 +690,7 @@ value_expr_t * parse_logic_expr(std::istream& in)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (! in.eof())
|
if (! in.eof())
|
||||||
throw value_expr_error(std::string("Unexpected character '") +
|
unexpected(c);
|
||||||
c + "'");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -721,8 +733,7 @@ value_expr_t * parse_value_expr(std::istream& in, const bool partial)
|
||||||
choices->left = parse_logic_expr(in);
|
choices->left = parse_logic_expr(in);
|
||||||
c = peek_next_nonws(in);
|
c = peek_next_nonws(in);
|
||||||
if (c != ':')
|
if (c != ':')
|
||||||
throw value_expr_error(std::string("Unexpected character '") +
|
unexpected(c, ':');
|
||||||
c + "'");
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
choices->right = parse_logic_expr(in);
|
choices->right = parse_logic_expr(in);
|
||||||
break;
|
break;
|
||||||
|
|
@ -730,26 +741,26 @@ value_expr_t * parse_value_expr(std::istream& in, const bool partial)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (! in.eof())
|
if (! in.eof())
|
||||||
throw value_expr_error(std::string("Unexpected character '") +
|
unexpected(c);
|
||||||
c + "'");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = peek_next_nonws(in);
|
c = peek_next_nonws(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! partial) {
|
char c;
|
||||||
char c;
|
if (! node.get()) {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
if (! node.get()) {
|
if (in.eof())
|
||||||
if (in.eof())
|
throw value_expr_error(std::string("Failed to parse value expression"));
|
||||||
throw value_expr_error(std::string("Failed to parse value expression"));
|
else
|
||||||
else
|
unexpected(c);
|
||||||
throw value_expr_error(std::string("Unexpected character '") + c + "'");
|
} else if (! partial) {
|
||||||
} else if (! in.eof()) {
|
in.get(c);
|
||||||
throw value_expr_error(std::string("Unexpected character '") +
|
if (! in.eof())
|
||||||
c + "'");
|
unexpected(c);
|
||||||
}
|
else
|
||||||
|
in.unget();
|
||||||
}
|
}
|
||||||
|
|
||||||
return node.release();
|
return node.release();
|
||||||
|
|
|
||||||
25
valexpr.h
25
valexpr.h
|
|
@ -131,7 +131,7 @@ inline value_expr_t * parse_value_expr(const char * p,
|
||||||
|
|
||||||
inline value_expr_t * parse_value_expr(const std::string& str,
|
inline value_expr_t * parse_value_expr(const std::string& str,
|
||||||
const bool partial = false) {
|
const bool partial = false) {
|
||||||
return parse_value_expr(str.c_str(), partial);
|
return parse_value_expr(str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
@ -146,30 +146,15 @@ class item_predicate
|
||||||
const value_expr_t * predicate;
|
const value_expr_t * predicate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
item_predicate(const std::string& _predicate) {
|
item_predicate(const std::string& _predicate) : predicate(NULL) {
|
||||||
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
|
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
|
||||||
predicate = NULL;
|
|
||||||
if (! _predicate.empty()) {
|
if (! _predicate.empty()) {
|
||||||
try {
|
try {
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
DEBUG_CLASS("valexpr.predicate.parse");
|
|
||||||
|
|
||||||
DEBUG_PRINT_("parsing: '" << _predicate << "'");
|
|
||||||
#endif
|
|
||||||
predicate = parse_value_expr(_predicate);
|
predicate = parse_value_expr(_predicate);
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
|
||||||
if (DEBUG_() && _debug_stream) {
|
|
||||||
*_debug_stream << "dump: ";
|
|
||||||
dump_value_expr(*_debug_stream, predicate);
|
|
||||||
*_debug_stream << std::endl;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
catch (const value_expr_error& err) {
|
catch (value_expr_error& err) {
|
||||||
std::cerr << "Error in predicate '" << _predicate << "': "
|
throw value_expr_error(std::string("In predicate '") +
|
||||||
<< err.what() << std::endl;
|
_predicate + "': " + err.what());
|
||||||
std::exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
11
walk.cc
11
walk.cc
|
|
@ -360,9 +360,14 @@ void walk_accounts(account_t& account,
|
||||||
const std::string& sort_string)
|
const std::string& sort_string)
|
||||||
{
|
{
|
||||||
if (! sort_string.empty()) {
|
if (! sort_string.empty()) {
|
||||||
std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
|
std::auto_ptr<value_expr_t> sort_order;
|
||||||
if (! sort_order.get())
|
try {
|
||||||
throw error(std::string("Sort string failed to parse: " + sort_string));
|
sort_order.reset(parse_value_expr(sort_string));
|
||||||
|
}
|
||||||
|
catch (value_expr_error& err) {
|
||||||
|
throw error(std::string("In sort string '" + sort_string + "': " +
|
||||||
|
err.what()));
|
||||||
|
}
|
||||||
walk_accounts(account, handler, sort_order.get());
|
walk_accounts(account, handler, sort_order.get());
|
||||||
} else {
|
} else {
|
||||||
walk_accounts(account, handler);
|
walk_accounts(account, handler);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue