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 (! commodity_t::updater && download_quotes)
|
||||
commodity_t::updater = new quotes_by_script(price_db,
|
||||
pricing_leeway,
|
||||
commodity_t::updater = new quotes_by_script(price_db, pricing_leeway,
|
||||
cache_dirty);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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))
|
||||
throw error("Entries not allowed in price history file");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "debug.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -56,7 +57,7 @@ void quotes_by_script::operator()(commodity_t& commodity,
|
|||
price.parse(buf);
|
||||
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];
|
||||
strftime(buf, 127, "%Y/%m/%d %H:%M:%S", localtime(&now));
|
||||
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);
|
||||
|
||||
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 == '}')
|
||||
in.get(c);
|
||||
else
|
||||
throw value_expr_error("Missing '}'");
|
||||
unexpected(c, '}');
|
||||
|
||||
node.reset(new value_expr_t(value_expr_t::CONSTANT_A));
|
||||
node->constant_a.parse(buf);
|
||||
|
|
@ -479,10 +494,9 @@ value_expr_t * parse_value_term(std::istream& in)
|
|||
in.get(c);
|
||||
node->right = parse_value_expr(in, true);
|
||||
}
|
||||
if (peek_next_nonws(in) == ')')
|
||||
in.get(c);
|
||||
else
|
||||
throw value_expr_error("Missing ')'");
|
||||
in.get(c);
|
||||
if (c != ')')
|
||||
unexpected(c, ')');
|
||||
} else {
|
||||
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 != '/');
|
||||
if (c != '/')
|
||||
throw value_expr_error("Missing closing '/'");
|
||||
unexpected(c, '/');
|
||||
|
||||
in.get(c);
|
||||
node.reset(new value_expr_t(short_account_mask ?
|
||||
|
|
@ -522,7 +536,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
|||
case '\'': {
|
||||
READ_INTO(in, buf, 255, c, c != '\'');
|
||||
if (c != '\'')
|
||||
throw value_expr_error("Missing closing '\''");
|
||||
unexpected(c, '\'');
|
||||
|
||||
in.get(c);
|
||||
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 '(':
|
||||
node.reset(parse_value_expr(in, true));
|
||||
if (peek_next_nonws(in) == ')')
|
||||
in.get(c);
|
||||
else
|
||||
throw value_expr_error("Missing ')'");
|
||||
in.get(c);
|
||||
if (c != ')')
|
||||
unexpected(c, ')');
|
||||
break;
|
||||
|
||||
case '[': {
|
||||
READ_INTO(in, buf, 255, c, c != ']');
|
||||
if (c != ']')
|
||||
throw value_expr_error("Missing ']'");
|
||||
unexpected(c, ']');
|
||||
in.get(c);
|
||||
|
||||
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:
|
||||
if (! in.eof())
|
||||
throw value_expr_error(std::string("Unexpected character '") +
|
||||
c + "'");
|
||||
unexpected(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -721,8 +733,7 @@ value_expr_t * parse_value_expr(std::istream& in, const bool partial)
|
|||
choices->left = parse_logic_expr(in);
|
||||
c = peek_next_nonws(in);
|
||||
if (c != ':')
|
||||
throw value_expr_error(std::string("Unexpected character '") +
|
||||
c + "'");
|
||||
unexpected(c, ':');
|
||||
in.get(c);
|
||||
choices->right = parse_logic_expr(in);
|
||||
break;
|
||||
|
|
@ -730,26 +741,26 @@ value_expr_t * parse_value_expr(std::istream& in, const bool partial)
|
|||
|
||||
default:
|
||||
if (! in.eof())
|
||||
throw value_expr_error(std::string("Unexpected character '") +
|
||||
c + "'");
|
||||
unexpected(c);
|
||||
break;
|
||||
}
|
||||
c = peek_next_nonws(in);
|
||||
}
|
||||
}
|
||||
|
||||
if (! partial) {
|
||||
char c;
|
||||
char c;
|
||||
if (! node.get()) {
|
||||
in.get(c);
|
||||
if (! node.get()) {
|
||||
if (in.eof())
|
||||
throw value_expr_error(std::string("Failed to parse value expression"));
|
||||
else
|
||||
throw value_expr_error(std::string("Unexpected character '") + c + "'");
|
||||
} else if (! in.eof()) {
|
||||
throw value_expr_error(std::string("Unexpected character '") +
|
||||
c + "'");
|
||||
}
|
||||
if (in.eof())
|
||||
throw value_expr_error(std::string("Failed to parse value expression"));
|
||||
else
|
||||
unexpected(c);
|
||||
} else if (! partial) {
|
||||
in.get(c);
|
||||
if (! in.eof())
|
||||
unexpected(c);
|
||||
else
|
||||
in.unget();
|
||||
}
|
||||
|
||||
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,
|
||||
const bool partial = false) {
|
||||
return parse_value_expr(str.c_str(), partial);
|
||||
return parse_value_expr(str.c_str());
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
@ -146,30 +146,15 @@ class item_predicate
|
|||
const value_expr_t * predicate;
|
||||
|
||||
public:
|
||||
item_predicate(const std::string& _predicate) {
|
||||
item_predicate(const std::string& _predicate) : predicate(NULL) {
|
||||
DEBUG_PRINT("ledger.memory.ctors", "ctor item_predicate<T>");
|
||||
predicate = NULL;
|
||||
if (! _predicate.empty()) {
|
||||
try {
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG_CLASS("valexpr.predicate.parse");
|
||||
|
||||
DEBUG_PRINT_("parsing: '" << _predicate << "'");
|
||||
#endif
|
||||
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) {
|
||||
std::cerr << "Error in predicate '" << _predicate << "': "
|
||||
<< err.what() << std::endl;
|
||||
std::exit(1);
|
||||
catch (value_expr_error& err) {
|
||||
throw value_expr_error(std::string("In predicate '") +
|
||||
_predicate + "': " + err.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
11
walk.cc
11
walk.cc
|
|
@ -360,9 +360,14 @@ void walk_accounts(account_t& account,
|
|||
const std::string& sort_string)
|
||||
{
|
||||
if (! sort_string.empty()) {
|
||||
std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
|
||||
if (! sort_order.get())
|
||||
throw error(std::string("Sort string failed to parse: " + sort_string));
|
||||
std::auto_ptr<value_expr_t> sort_order;
|
||||
try {
|
||||
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());
|
||||
} else {
|
||||
walk_accounts(account, handler);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue