diff options
author | John Wiegley <johnw@newartisans.com> | 2007-05-07 10:24:55 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 03:38:38 -0400 |
commit | 8aada79971b772fda92131053fa03021cfbc625a (patch) | |
tree | fbb25be31a419958167d1d166ab0f35d3b7f6a86 /src | |
parent | 65e4fc7ebff0245fe13f99663c341e000a29af48 (diff) | |
download | fork-ledger-8aada79971b772fda92131053fa03021cfbc625a.tar.gz fork-ledger-8aada79971b772fda92131053fa03021cfbc625a.tar.bz2 fork-ledger-8aada79971b772fda92131053fa03021cfbc625a.zip |
Added a facility for handling scoped executions.
Diffstat (limited to 'src')
-rw-r--r-- | src/scoped_execute.h | 73 | ||||
-rw-r--r-- | src/session.cc | 21 | ||||
-rw-r--r-- | src/textual.cc | 35 | ||||
-rw-r--r-- | src/utils.h | 9 |
4 files changed, 94 insertions, 44 deletions
diff --git a/src/scoped_execute.h b/src/scoped_execute.h new file mode 100644 index 00000000..da3f388e --- /dev/null +++ b/src/scoped_execute.h @@ -0,0 +1,73 @@ +#ifndef _SCOPE_EXECUTE_H +#define _SCOPE_EXECUTE_H + +template <typename T> +class scoped_variable : public boost::noncopyable +{ + T& var; + T prev; + bool enabled; + +public: + explicit scoped_variable(T& _var) + : var(_var), prev(var), enabled(true) {} + explicit scoped_variable(T& _var, const T& value) + : var(_var), prev(var), enabled(true) { + var = value; + } + ~scoped_variable() { + if (enabled) + var = prev; + } + + void clear() { + enabled = false; + } +}; + +template <typename T> +class scoped_execute : public boost::noncopyable +{ + typedef boost::function<void (T)> function_t; + + function_t code; + T arg; + bool enabled; + +public: + explicit scoped_execute(const function_t& _code, T _arg) + : code(_code), arg(_arg), enabled(true) {} + + ~scoped_execute() { + if (enabled) + code(arg); + } + + void clear() { + enabled = false; + } +}; + +template <> +class scoped_execute<void> : public boost::noncopyable +{ + typedef boost::function<void ()> function_t; + + function_t code; + bool enabled; + +public: + explicit scoped_execute(const function_t& _code) + : code(_code), enabled(true) {} + + ~scoped_execute() { + if (enabled) + code(); + } + + void clear() { + enabled = false; + } +}; + +#endif // _SCOPE_EXECUTE_H diff --git a/src/session.cc b/src/session.cc index d53faf09..1477139c 100644 --- a/src/session.cc +++ b/src/session.cc @@ -103,22 +103,13 @@ journal_t * session_t::read_data(const string& master_account) DEBUG("ledger.cache", "using_cache " << cache_file->string()); cache_dirty = true; if (exists(*cache_file)) { - ifstream stream(*cache_file); - - optional<path> price_db_orig = journal->price_db; - try { - journal->price_db = price_db; - - entry_count += read_journal(stream, journal, NULL, data_file); - if (entry_count > 0) - cache_dirty = false; + scoped_variable<optional<path> > + save_price_db(journal->price_db, price_db); - journal->price_db = price_db_orig; - } - catch (...) { - journal->price_db = price_db_orig; - throw; - } + ifstream stream(*cache_file); + entry_count += read_journal(stream, journal, NULL, data_file); + if (entry_count > 0) + cache_dirty = false; } } diff --git a/src/textual.cc b/src/textual.cc index 8ed83698..5c2dd81d 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -10,7 +10,8 @@ static unsigned int linenum; static unsigned int src_idx; static accounts_map account_aliases; -static std::list<std::pair<path, int> > include_stack; +typedef std::list<std::pair<path, int> > include_stack_t; +static include_stack_t include_stack; #define TIMELOG_SUPPORT 1 #ifdef TIMELOG_SUPPORT @@ -508,14 +509,6 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal, return curr.release(); } -template <typename T> -struct push_var { - T& var; - T prev; - push_var(T& _var) : var(_var), prev(var) {} - ~push_var() { var = prev; } -}; - static inline void parse_symbol(char *& p, string& symbol) { if (*p == '"') { @@ -836,11 +829,11 @@ unsigned int textual_parser_t::parse(std::istream& in, char * p = next_element(line); string word(line + 1); if (word == "include") { - push_var<path> save_path(pathname); - push_var<unsigned int> save_src_idx(src_idx); - push_var<unsigned long> save_beg_pos(beg_pos); - push_var<unsigned long> save_end_pos(end_pos); - push_var<unsigned int> save_linenum(linenum); + scoped_variable<path> save_path(pathname); + scoped_variable<unsigned int> save_src_idx(src_idx); + scoped_variable<unsigned long> save_beg_pos(beg_pos); + scoped_variable<unsigned long> save_end_pos(end_pos); + scoped_variable<unsigned int> save_linenum(linenum); if (*p != '~' && *p != '/') pathname = (pathname.branch_path() / path(p)).normalize(); @@ -850,18 +843,14 @@ unsigned int textual_parser_t::parse(std::istream& in, DEBUG("ledger.textual.include", "Line " << linenum << ": " << "Including path '" << pathname.string() << "'"); + scoped_execute<void> + pop_include_stack(boost::bind(&include_stack_t::pop_back, + boost::ref(include_stack))); include_stack.push_back (std::pair<path, int>(journal->sources.back(), linenum - 1)); - try { - count += journal->session->read_journal(pathname, journal, - account_stack.front()); - include_stack.pop_back(); - } - catch (...) { - include_stack.pop_back(); - throw; - } + count += journal->session->read_journal(pathname, journal, + account_stack.front()); } else if (word == "account") { if (account_t * acct = account_stack.front()->find_account(p)) diff --git a/src/utils.h b/src/utils.h index 22fc48dc..a3ef8d39 100644 --- a/src/utils.h +++ b/src/utils.h @@ -441,16 +441,13 @@ inline void throw_unexpected_error(char c, char wanted) { /********************************************************************** * * Date/time support classes - */ - -#include "times.h" - -/********************************************************************** - * * General support for objects with "flags" + * Support for scoped execution and variable restoration */ +#include "times.h" #include "flags.h" +#include "scoped_execute.h" /********************************************************************** * |