Made several changes to the parsing infrastructure to allow passing
the "config_t" object around. This is needed for parsing option settings in the initialization file.
This commit is contained in:
parent
06b7e9d904
commit
0a8b36de3f
16 changed files with 88 additions and 73 deletions
|
|
@ -495,6 +495,7 @@ bool binary_parser_t::test(std::istream& in) const
|
|||
}
|
||||
|
||||
unsigned int binary_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
|
|||
1
binary.h
1
binary.h
|
|
@ -12,6 +12,7 @@ class binary_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
|
|
@ -988,6 +988,7 @@ OPT_BEGIN(total_data, "J") {
|
|||
|
||||
OPT_BEGIN(price_db, ":") {
|
||||
config->price_db = optarg;
|
||||
std::cerr << "Setting --price_db=" << optarg << std::endl;
|
||||
} OPT_END(price_db);
|
||||
|
||||
OPT_BEGIN(price_exp, "Z:") {
|
||||
|
|
|
|||
|
|
@ -352,6 +352,7 @@ bool gnucash_parser_t::test(std::istream& in) const
|
|||
}
|
||||
|
||||
unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class gnucash_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
4
main.cc
4
main.cc
|
|
@ -68,8 +68,10 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
|||
config.process_option("file", p);
|
||||
if (const char * p = std::getenv("LEDGER_INIT"))
|
||||
config.process_option("init-file", p);
|
||||
#if 0
|
||||
if (const char * p = std::getenv("PRICE_HIST"))
|
||||
config.process_option("price-db", p);
|
||||
#endif
|
||||
if (const char * p = std::getenv("PRICE_EXP"))
|
||||
config.process_option("price-exp", p);
|
||||
#endif
|
||||
|
|
@ -128,7 +130,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
|||
|
||||
TIMER_START(parse);
|
||||
|
||||
if (parse_ledger_data(journal.get(), config) == 0)
|
||||
if (parse_ledger_data(config, journal.get()) == 0)
|
||||
throw error("Please specify ledger file using -f"
|
||||
" or LEDGER_FILE environment variable.");
|
||||
|
||||
|
|
|
|||
1
ofx.cc
1
ofx.cc
|
|
@ -196,6 +196,7 @@ bool ofx_parser_t::test(std::istream& in) const
|
|||
}
|
||||
|
||||
unsigned int ofx_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
|
|||
1
ofx.h
1
ofx.h
|
|
@ -11,6 +11,7 @@ class ofx_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
106
parser.cc
106
parser.cc
|
|
@ -57,6 +57,7 @@ bool unregister_parser(parser_t * parser)
|
|||
}
|
||||
|
||||
unsigned int parse_journal(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
@ -68,12 +69,13 @@ unsigned int parse_journal(std::istream& in,
|
|||
i != parsers->end();
|
||||
i++)
|
||||
if ((*i)->test(in))
|
||||
return (*i)->parse(in, journal, master, original_file);
|
||||
return (*i)->parse(in, config, journal, master, original_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int parse_journal_file(const std::string& path,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
@ -87,48 +89,58 @@ unsigned int parse_journal_file(const std::string& path,
|
|||
original_file = &path;
|
||||
|
||||
std::ifstream stream(path.c_str());
|
||||
return parse_journal(stream, journal, master, original_file);
|
||||
return parse_journal(stream, config, journal, master, original_file);
|
||||
}
|
||||
|
||||
unsigned int parse_ledger_data(journal_t * journal,
|
||||
const std::string& data_file,
|
||||
const std::string& init_file,
|
||||
const std::string& price_db,
|
||||
bool use_cache,
|
||||
const std::string& cache_file,
|
||||
bool * cache_dirty,
|
||||
parser_t * cache_parser,
|
||||
parser_t * xml_parser,
|
||||
parser_t * stdin_parser,
|
||||
const std::string& default_account)
|
||||
extern parser_t * binary_parser_ptr;
|
||||
extern parser_t * xml_parser_ptr;
|
||||
extern parser_t * textual_parser_ptr;
|
||||
|
||||
unsigned int parse_ledger_data(config_t& config,
|
||||
journal_t * journal,
|
||||
parser_t * cache_parser,
|
||||
parser_t * xml_parser,
|
||||
parser_t * stdin_parser)
|
||||
{
|
||||
unsigned int entry_count = 0;
|
||||
|
||||
DEBUG_PRINT("ledger.config.cache", "3. use_cache = " << use_cache);
|
||||
if (! cache_parser)
|
||||
cache_parser = binary_parser_ptr;
|
||||
if (! xml_parser)
|
||||
xml_parser = xml_parser_ptr;
|
||||
if (! stdin_parser)
|
||||
stdin_parser = textual_parser_ptr;
|
||||
|
||||
if (! init_file.empty() && access(init_file.c_str(), R_OK) != -1) {
|
||||
if (parse_journal_file(init_file, journal) ||
|
||||
DEBUG_PRINT("ledger.config.cache",
|
||||
"3. use_cache = " << config.use_cache);
|
||||
|
||||
if (! config.init_file.empty() &&
|
||||
access(config.init_file.c_str(), R_OK) != -1) {
|
||||
if (parse_journal_file(config.init_file, config, journal) ||
|
||||
journal->auto_entries.size() > 0 ||
|
||||
journal->period_entries.size() > 0)
|
||||
throw error(std::string("Entries found in initialization file '") +
|
||||
init_file + "'");
|
||||
config.init_file + "'");
|
||||
|
||||
journal->sources.pop_front(); // remove init file
|
||||
}
|
||||
|
||||
if (use_cache && ! cache_file.empty() && ! data_file.empty()) {
|
||||
DEBUG_PRINT("ledger.config.cache", "using_cache " << cache_file);
|
||||
if (cache_dirty)
|
||||
*cache_dirty = true;
|
||||
if (access(cache_file.c_str(), R_OK) != -1) {
|
||||
std::ifstream stream(cache_file.c_str());
|
||||
if (config.use_cache && ! config.cache_file.empty() &&
|
||||
! config.data_file.empty()) {
|
||||
DEBUG_PRINT("ledger.config.cache",
|
||||
"using_cache " << config.cache_file);
|
||||
if (config.cache_dirty)
|
||||
config.cache_dirty = true;
|
||||
if (access(config.cache_file.c_str(), R_OK) != -1) {
|
||||
std::ifstream stream(config.cache_file.c_str());
|
||||
if (cache_parser && cache_parser->test(stream)) {
|
||||
std::string price_db_orig = journal->price_db;
|
||||
journal->price_db = price_db;
|
||||
entry_count += cache_parser->parse(stream, journal, NULL, &data_file);
|
||||
journal->price_db = config.price_db;
|
||||
entry_count += cache_parser->parse(stream, config, journal,
|
||||
NULL, &config.data_file);
|
||||
if (entry_count > 0) {
|
||||
if (cache_dirty)
|
||||
*cache_dirty = false;
|
||||
if (config.cache_dirty)
|
||||
config.cache_dirty = false;
|
||||
} else {
|
||||
journal->price_db = price_db_orig;
|
||||
}
|
||||
|
|
@ -136,15 +148,15 @@ unsigned int parse_ledger_data(journal_t * journal,
|
|||
}
|
||||
}
|
||||
|
||||
if (entry_count == 0 && ! data_file.empty()) {
|
||||
if (entry_count == 0 && ! config.data_file.empty()) {
|
||||
account_t * acct = NULL;
|
||||
if (! default_account.empty())
|
||||
acct = journal->find_account(default_account);
|
||||
if (! config.account.empty())
|
||||
acct = journal->find_account(config.account);
|
||||
|
||||
journal->price_db = price_db;
|
||||
journal->price_db = config.price_db;
|
||||
if (! journal->price_db.empty() &&
|
||||
access(journal->price_db.c_str(), R_OK) != -1) {
|
||||
if (parse_journal_file(journal->price_db, journal)) {
|
||||
if (parse_journal_file(journal->price_db, config, journal)) {
|
||||
throw error("Entries not allowed in price history file");
|
||||
} else {
|
||||
DEBUG_PRINT("ledger.config.cache",
|
||||
|
|
@ -154,19 +166,22 @@ unsigned int parse_ledger_data(journal_t * journal,
|
|||
}
|
||||
|
||||
DEBUG_PRINT("ledger.config.cache",
|
||||
"rejected cache, parsing " << data_file);
|
||||
if (data_file == "-") {
|
||||
use_cache = false;
|
||||
"rejected cache, parsing " << config.data_file);
|
||||
if (config.data_file == "-") {
|
||||
config.use_cache = false;
|
||||
journal->sources.push_back("<stdin>");
|
||||
#if 0
|
||||
if (xml_parser && std::cin.peek() == '<')
|
||||
entry_count += xml_parser->parse(std::cin, journal, acct);
|
||||
entry_count += xml_parser->parse(std::cin, config, journal,
|
||||
acct);
|
||||
else if (stdin_parser)
|
||||
#endif
|
||||
entry_count += stdin_parser->parse(std::cin, journal, acct);
|
||||
entry_count += stdin_parser->parse(std::cin, config,
|
||||
journal, acct);
|
||||
}
|
||||
else if (access(data_file.c_str(), R_OK) != -1) {
|
||||
entry_count += parse_journal_file(data_file, journal, acct);
|
||||
else if (access(config.data_file.c_str(), R_OK) != -1) {
|
||||
entry_count += parse_journal_file(config.data_file, config,
|
||||
journal, acct);
|
||||
if (! journal->price_db.empty())
|
||||
journal->sources.push_back(journal->price_db);
|
||||
}
|
||||
|
|
@ -177,17 +192,4 @@ unsigned int parse_ledger_data(journal_t * journal,
|
|||
return entry_count;
|
||||
}
|
||||
|
||||
extern parser_t * binary_parser_ptr;
|
||||
extern parser_t * xml_parser_ptr;
|
||||
extern parser_t * textual_parser_ptr;
|
||||
|
||||
unsigned int parse_ledger_data(journal_t * journal, config_t& config)
|
||||
{
|
||||
return parse_ledger_data(journal, config.data_file, config.init_file,
|
||||
config.price_db, config.use_cache,
|
||||
config.cache_file, &config.cache_dirty,
|
||||
binary_parser_ptr, xml_parser_ptr,
|
||||
textual_parser_ptr, config.account);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
23
parser.h
23
parser.h
|
|
@ -8,6 +8,7 @@ namespace ledger {
|
|||
|
||||
class account_t;
|
||||
class journal_t;
|
||||
class config_t;
|
||||
|
||||
class parser_t
|
||||
{
|
||||
|
|
@ -17,6 +18,7 @@ class parser_t
|
|||
virtual bool test(std::istream& in) const = 0;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL) = 0;
|
||||
|
|
@ -26,29 +28,22 @@ bool register_parser(parser_t * parser);
|
|||
bool unregister_parser(parser_t * parser);
|
||||
|
||||
unsigned int parse_journal(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
||||
unsigned int parse_journal_file(const std::string& path,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
||||
unsigned int parse_ledger_data(journal_t * journal,
|
||||
const std::string& data_file,
|
||||
const std::string& init_file = "",
|
||||
const std::string& price_db = "",
|
||||
bool use_cache = false,
|
||||
const std::string& cache_file = "",
|
||||
bool * cache_dirty = NULL,
|
||||
parser_t * cache_parser = NULL,
|
||||
parser_t * xml_parser = NULL,
|
||||
parser_t * stdin_parser = NULL,
|
||||
const std::string& default_account = "");
|
||||
|
||||
class config_t;
|
||||
unsigned int parse_ledger_data(journal_t * journal, config_t& config);
|
||||
unsigned int parse_ledger_data(config_t& config,
|
||||
journal_t * journal,
|
||||
parser_t * cache_parser = NULL,
|
||||
parser_t * xml_parser = NULL,
|
||||
parser_t * stdin_parser = NULL);
|
||||
|
||||
void initialize_parser_support();
|
||||
void shutdown_parser_support();
|
||||
|
|
|
|||
1
qif.cc
1
qif.cc
|
|
@ -39,6 +39,7 @@ bool qif_parser_t::test(std::istream& in) const
|
|||
}
|
||||
|
||||
unsigned int qif_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
|
|||
1
qif.h
1
qif.h
|
|
@ -11,6 +11,7 @@ class qif_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ static void clock_out_from_timelog(const std::time_t when,
|
|||
}
|
||||
|
||||
unsigned int textual_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
|
|
@ -607,6 +608,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
|||
date_buffer[std::strlen(date_field)] = ' ';
|
||||
std::strcpy(&date_buffer[std::strlen(date_field) + 1], time_field);
|
||||
|
||||
std::cerr << "date_buffer = " << date_buffer << std::endl;
|
||||
|
||||
struct std::tm when;
|
||||
if (strptime(date_buffer, "%Y/%m/%d %H:%M:%S", &when)) {
|
||||
date = std::mktime(&when);
|
||||
|
|
@ -653,7 +656,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
|||
if (p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
process_option(config_options, line + 2, p);
|
||||
config.process_option(line + 2, p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -721,7 +724,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
|||
|
||||
DEBUG_PRINT("ledger.textual.include",
|
||||
"Including path '" << path << "'");
|
||||
count += parse_journal_file(path, journal, account_stack.front());
|
||||
count += parse_journal_file(path, config, journal,
|
||||
account_stack.front());
|
||||
}
|
||||
else if (word == "account") {
|
||||
account_t * acct;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class textual_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
9
xml.cc
9
xml.cc
|
|
@ -175,10 +175,11 @@ bool xml_parser_t::test(std::istream& in) const
|
|||
return true;
|
||||
}
|
||||
|
||||
unsigned int xml_parser_t::parse(std::istream& in,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
unsigned int xml_parser_t::parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master,
|
||||
const std::string * original_file)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
|
|
|
|||
1
xml.h
1
xml.h
|
|
@ -12,6 +12,7 @@ class xml_parser_t : public parser_t
|
|||
virtual bool test(std::istream& in) const;
|
||||
|
||||
virtual unsigned int parse(std::istream& in,
|
||||
config_t& config,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL,
|
||||
const std::string * original_file = NULL);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue