diff options
-rw-r--r-- | config.cc | 6 | ||||
-rw-r--r-- | quotes.cc | 3 | ||||
-rw-r--r-- | valexpr.cc | 69 | ||||
-rw-r--r-- | valexpr.h | 25 | ||||
-rw-r--r-- | walk.cc | 11 |
5 files changed, 58 insertions, 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); @@ -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(); @@ -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()); } } } @@ -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); |