Added a facility for handling scoped executions.
This commit is contained in:
parent
65e4fc7ebf
commit
8aada79971
4 changed files with 94 additions and 44 deletions
73
src/scoped_execute.h
Normal file
73
src/scoped_execute.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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)) {
|
||||
scoped_variable<optional<path> >
|
||||
save_price_db(journal->price_db, price_db);
|
||||
|
||||
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;
|
||||
|
||||
journal->price_db = price_db_orig;
|
||||
}
|
||||
catch (...) {
|
||||
journal->price_db = price_db_orig;
|
||||
throw;
|
||||
}
|
||||
entry_count += read_journal(stream, journal, NULL, data_file);
|
||||
if (entry_count > 0)
|
||||
cache_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -441,16 +441,13 @@ inline void throw_unexpected_error(char c, char wanted) {
|
|||
/**********************************************************************
|
||||
*
|
||||
* Date/time support classes
|
||||
* General support for objects with "flags"
|
||||
* Support for scoped execution and variable restoration
|
||||
*/
|
||||
|
||||
#include "times.h"
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* General support for objects with "flags"
|
||||
*/
|
||||
|
||||
#include "flags.h"
|
||||
#include "scoped_execute.h"
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue