A great deal of reorganization to restore the old parsing code (since the
newer XML stuff was pulled).
This commit is contained in:
parent
e41dbc204a
commit
4bc29e1351
24 changed files with 165 additions and 570 deletions
|
|
@ -39,7 +39,6 @@ endif
|
||||||
libledger_la_CPPFLAGS = $(libamounts_la_CPPFLAGS)
|
libledger_la_CPPFLAGS = $(libamounts_la_CPPFLAGS)
|
||||||
libledger_la_SOURCES = \
|
libledger_la_SOURCES = \
|
||||||
binary.cc \
|
binary.cc \
|
||||||
config.cc \
|
|
||||||
csv.cc \
|
csv.cc \
|
||||||
derive.cc \
|
derive.cc \
|
||||||
emacs.cc \
|
emacs.cc \
|
||||||
|
|
@ -47,13 +46,11 @@ libledger_la_SOURCES = \
|
||||||
journal.cc \
|
journal.cc \
|
||||||
mask.cc \
|
mask.cc \
|
||||||
option.cc \
|
option.cc \
|
||||||
parser.cc \
|
|
||||||
parsexp.cc \
|
parsexp.cc \
|
||||||
qif.cc \
|
qif.cc \
|
||||||
reconcile.cc \
|
reconcile.cc \
|
||||||
report.cc \
|
report.cc \
|
||||||
session.cc \
|
session.cc \
|
||||||
startup.cc \
|
|
||||||
textual.cc \
|
textual.cc \
|
||||||
valexpr.cc \
|
valexpr.cc \
|
||||||
walk.cc \
|
walk.cc \
|
||||||
|
|
@ -83,7 +80,6 @@ pkginclude_HEADERS = \
|
||||||
utils.h \
|
utils.h \
|
||||||
\
|
\
|
||||||
binary.h \
|
binary.h \
|
||||||
config.h \
|
|
||||||
csv.h \
|
csv.h \
|
||||||
derive.h \
|
derive.h \
|
||||||
emacs.h \
|
emacs.h \
|
||||||
|
|
@ -223,7 +219,6 @@ clean-backupfiles:
|
||||||
.\#*
|
.\#*
|
||||||
|
|
||||||
clean-documentation:
|
clean-documentation:
|
||||||
(cd doc; \
|
|
||||||
rm -fr *.aux \
|
rm -fr *.aux \
|
||||||
*.cp \
|
*.cp \
|
||||||
*.fn \
|
*.fn \
|
||||||
|
|
@ -234,7 +229,7 @@ clean-documentation:
|
||||||
*.pg \
|
*.pg \
|
||||||
*.toc \
|
*.toc \
|
||||||
*.tp \
|
*.tp \
|
||||||
*.vr)
|
*.vr
|
||||||
|
|
||||||
clean-buildproducts:
|
clean-buildproducts:
|
||||||
rm -fr *.Plo \
|
rm -fr *.Plo \
|
||||||
|
|
@ -284,7 +279,7 @@ clean-autoconf:
|
||||||
texinfo.tex \
|
texinfo.tex \
|
||||||
ylwrap
|
ylwrap
|
||||||
|
|
||||||
all-clean: maintainer-clean \
|
scour: maintainer-clean \
|
||||||
clean-buildproducts \
|
clean-buildproducts \
|
||||||
clean-backupfiles \
|
clean-backupfiles \
|
||||||
clean-debugdata \
|
clean-debugdata \
|
||||||
|
|
|
||||||
84
binary.cc
84
binary.cc
|
|
@ -72,13 +72,13 @@ bool binary_parser_t::test(std::istream& in) const
|
||||||
namespace binary {
|
namespace binary {
|
||||||
unsigned int read_journal(std::istream& in,
|
unsigned int read_journal(std::istream& in,
|
||||||
const path& file,
|
const path& file,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master);
|
account_t * master);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int binary_parser_t::parse(std::istream& in,
|
unsigned int binary_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
|
|
@ -558,13 +558,13 @@ inline commodity_t * read_commodity_annotated(const char *& data)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
account_t * read_account(const char *& data, journal_t * journal,
|
account_t * read_account(const char *& data, journal_t& journal,
|
||||||
account_t * master = NULL)
|
account_t * master = NULL)
|
||||||
{
|
{
|
||||||
account_t * acct = new account_t(NULL);
|
account_t * acct = new account_t(NULL);
|
||||||
*accounts_next++ = acct;
|
*accounts_next++ = acct;
|
||||||
|
|
||||||
acct->journal = journal;
|
acct->journal = &journal;
|
||||||
|
|
||||||
account_t::ident_t id;
|
account_t::ident_t id;
|
||||||
read_long(data, id); // parent id
|
read_long(data, id); // parent id
|
||||||
|
|
@ -601,7 +601,7 @@ account_t * read_account(const char *& data, journal_t * journal,
|
||||||
|
|
||||||
unsigned int read_journal(std::istream& in,
|
unsigned int read_journal(std::istream& in,
|
||||||
const path& file,
|
const path& file,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master)
|
account_t * master)
|
||||||
{
|
{
|
||||||
account_index =
|
account_index =
|
||||||
|
|
@ -625,7 +625,7 @@ unsigned int read_journal(std::istream& in,
|
||||||
if (std::difftime(info.st_mtime, old_mtime) > 0)
|
if (std::difftime(info.st_mtime, old_mtime) > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
journal->sources.push_back(pathname);
|
journal.sources.push_back(pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the cache uses the same price database,
|
// Make sure that the cache uses the same price database,
|
||||||
|
|
@ -634,8 +634,8 @@ unsigned int read_journal(std::istream& in,
|
||||||
if (read_bool(in)) {
|
if (read_bool(in)) {
|
||||||
string pathname;
|
string pathname;
|
||||||
read_string(in, pathname);
|
read_string(in, pathname);
|
||||||
if (! journal->price_db ||
|
if (! journal.price_db ||
|
||||||
journal->price_db->string() != std::string(pathname))
|
journal.price_db->string() != std::string(pathname))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -655,12 +655,12 @@ unsigned int read_journal(std::istream& in,
|
||||||
account_t::ident_t a_count = read_long<account_t::ident_t>(data);
|
account_t::ident_t a_count = read_long<account_t::ident_t>(data);
|
||||||
accounts = accounts_next = new account_t *[a_count];
|
accounts = accounts_next = new account_t *[a_count];
|
||||||
|
|
||||||
assert(journal->master);
|
assert(journal.master);
|
||||||
delete journal->master;
|
delete journal.master;
|
||||||
journal->master = read_account(data, journal, master);
|
journal.master = read_account(data, journal, master);
|
||||||
|
|
||||||
if (read_bool(data))
|
if (read_bool(data))
|
||||||
journal->basket = accounts[read_long<account_t::ident_t>(data) - 1];
|
journal.basket = accounts[read_long<account_t::ident_t>(data) - 1];
|
||||||
|
|
||||||
// Allocate the memory needed for the entries and transactions in
|
// Allocate the memory needed for the entries and transactions in
|
||||||
// one large block, which is then chopped up and custom constructed
|
// one large block, which is then chopped up and custom constructed
|
||||||
|
|
@ -678,8 +678,8 @@ unsigned int read_journal(std::istream& in,
|
||||||
|
|
||||||
char * item_pool = new char[pool_size];
|
char * item_pool = new char[pool_size];
|
||||||
|
|
||||||
journal->item_pool = item_pool;
|
journal.item_pool = item_pool;
|
||||||
journal->item_pool_end = item_pool + pool_size;
|
journal.item_pool_end = item_pool + pool_size;
|
||||||
|
|
||||||
entry_t * entry_pool = (entry_t *) item_pool;
|
entry_t * entry_pool = (entry_t *) item_pool;
|
||||||
transaction_t * xact_pool = (transaction_t *) (item_pool +
|
transaction_t * xact_pool = (transaction_t *) (item_pool +
|
||||||
|
|
@ -777,27 +777,27 @@ unsigned int read_journal(std::istream& in,
|
||||||
new(entry_pool) entry_t;
|
new(entry_pool) entry_t;
|
||||||
bool finalize = false;
|
bool finalize = false;
|
||||||
read_entry(data, entry_pool, xact_pool, finalize);
|
read_entry(data, entry_pool, xact_pool, finalize);
|
||||||
entry_pool->journal = journal;
|
entry_pool->journal = &journal;
|
||||||
if (finalize && ! entry_pool->finalize())
|
if (finalize && ! entry_pool->finalize())
|
||||||
continue;
|
continue;
|
||||||
journal->entries.push_back(entry_pool++);
|
journal.entries.push_back(entry_pool++);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned long i = 0; i < auto_count; i++) {
|
for (unsigned long i = 0; i < auto_count; i++) {
|
||||||
auto_entry_t * auto_entry = new auto_entry_t;
|
auto_entry_t * auto_entry = new auto_entry_t;
|
||||||
read_auto_entry(data, auto_entry, xact_pool);
|
read_auto_entry(data, auto_entry, xact_pool);
|
||||||
auto_entry->journal = journal;
|
auto_entry->journal = &journal;
|
||||||
journal->auto_entries.push_back(auto_entry);
|
journal.auto_entries.push_back(auto_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned long i = 0; i < period_count; i++) {
|
for (unsigned long i = 0; i < period_count; i++) {
|
||||||
period_entry_t * period_entry = new period_entry_t;
|
period_entry_t * period_entry = new period_entry_t;
|
||||||
bool finalize = false;
|
bool finalize = false;
|
||||||
read_period_entry(data, period_entry, xact_pool, finalize);
|
read_period_entry(data, period_entry, xact_pool, finalize);
|
||||||
period_entry->journal = journal;
|
period_entry->journal = &journal;
|
||||||
if (finalize && ! period_entry->finalize())
|
if (finalize && ! period_entry->finalize())
|
||||||
continue;
|
continue;
|
||||||
journal->period_entries.push_back(period_entry);
|
journal.period_entries.push_back(period_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up and return the number of entries read
|
// Clean up and return the number of entries read
|
||||||
|
|
@ -806,7 +806,7 @@ unsigned int read_journal(std::istream& in,
|
||||||
delete[] commodities;
|
delete[] commodities;
|
||||||
delete[] data_pool;
|
delete[] data_pool;
|
||||||
|
|
||||||
VERIFY(journal->valid());
|
VERIFY(journal.valid());
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
@ -1104,7 +1104,7 @@ void write_account(std::ostream& out, account_t * account)
|
||||||
write_account(out, (*i).second);
|
write_account(out, (*i).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_journal(std::ostream& out, journal_t * journal)
|
void write_journal(std::ostream& out, journal_t& journal)
|
||||||
{
|
{
|
||||||
account_index =
|
account_index =
|
||||||
base_commodity_index =
|
base_commodity_index =
|
||||||
|
|
@ -1116,12 +1116,12 @@ void write_journal(std::ostream& out, journal_t * journal)
|
||||||
// Write out the files that participated in this journal, so that
|
// Write out the files that participated in this journal, so that
|
||||||
// they can be checked for changes on reading.
|
// they can be checked for changes on reading.
|
||||||
|
|
||||||
if (journal->sources.empty()) {
|
if (journal.sources.empty()) {
|
||||||
write_number<unsigned short>(out, 0);
|
write_number<unsigned short>(out, 0);
|
||||||
} else {
|
} else {
|
||||||
write_number<unsigned short>(out, journal->sources.size());
|
write_number<unsigned short>(out, journal.sources.size());
|
||||||
for (paths_list::const_iterator i = journal->sources.begin();
|
for (paths_list::const_iterator i = journal.sources.begin();
|
||||||
i != journal->sources.end();
|
i != journal.sources.end();
|
||||||
i++) {
|
i++) {
|
||||||
write_string(out, (*i).string());
|
write_string(out, (*i).string());
|
||||||
struct stat info;
|
struct stat info;
|
||||||
|
|
@ -1131,9 +1131,9 @@ void write_journal(std::ostream& out, journal_t * journal)
|
||||||
|
|
||||||
// Write out the price database that relates to this data file, so
|
// Write out the price database that relates to this data file, so
|
||||||
// that if it ever changes the cache can be invalidated.
|
// that if it ever changes the cache can be invalidated.
|
||||||
if (journal->price_db) {
|
if (journal.price_db) {
|
||||||
write_bool(out, true);
|
write_bool(out, true);
|
||||||
write_string(out, journal->price_db->string());
|
write_string(out, journal.price_db->string());
|
||||||
} else {
|
} else {
|
||||||
write_bool(out, false);
|
write_bool(out, false);
|
||||||
}
|
}
|
||||||
|
|
@ -1144,21 +1144,21 @@ void write_journal(std::ostream& out, journal_t * journal)
|
||||||
|
|
||||||
// Write out the accounts
|
// Write out the accounts
|
||||||
|
|
||||||
write_long<account_t::ident_t>(out, count_accounts(journal->master));
|
write_long<account_t::ident_t>(out, count_accounts(journal.master));
|
||||||
write_account(out, journal->master);
|
write_account(out, journal.master);
|
||||||
|
|
||||||
if (journal->basket) {
|
if (journal.basket) {
|
||||||
write_bool(out, true);
|
write_bool(out, true);
|
||||||
write_long(out, journal->basket->ident);
|
write_long(out, journal.basket->ident);
|
||||||
} else {
|
} else {
|
||||||
write_bool(out, false);
|
write_bool(out, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out the number of entries, transactions, and amounts
|
// Write out the number of entries, transactions, and amounts
|
||||||
|
|
||||||
write_long<unsigned long>(out, journal->entries.size());
|
write_long<unsigned long>(out, journal.entries.size());
|
||||||
write_long<unsigned long>(out, journal->auto_entries.size());
|
write_long<unsigned long>(out, journal.auto_entries.size());
|
||||||
write_long<unsigned long>(out, journal->period_entries.size());
|
write_long<unsigned long>(out, journal.period_entries.size());
|
||||||
|
|
||||||
ostream_pos_type xacts_val = out.tellp();
|
ostream_pos_type xacts_val = out.tellp();
|
||||||
write_number<unsigned long>(out, 0);
|
write_number<unsigned long>(out, 0);
|
||||||
|
|
@ -1222,22 +1222,22 @@ void write_journal(std::ostream& out, journal_t * journal)
|
||||||
|
|
||||||
unsigned long xact_count = 0;
|
unsigned long xact_count = 0;
|
||||||
|
|
||||||
for (entries_list::const_iterator i = journal->entries.begin();
|
for (entries_list::const_iterator i = journal.entries.begin();
|
||||||
i != journal->entries.end();
|
i != journal.entries.end();
|
||||||
i++) {
|
i++) {
|
||||||
write_entry(out, *i);
|
write_entry(out, *i);
|
||||||
xact_count += (*i)->transactions.size();
|
xact_count += (*i)->transactions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto_entries_list::const_iterator i = journal->auto_entries.begin();
|
for (auto_entries_list::const_iterator i = journal.auto_entries.begin();
|
||||||
i != journal->auto_entries.end();
|
i != journal.auto_entries.end();
|
||||||
i++) {
|
i++) {
|
||||||
write_auto_entry(out, *i);
|
write_auto_entry(out, *i);
|
||||||
xact_count += (*i)->transactions.size();
|
xact_count += (*i)->transactions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (period_entries_list::const_iterator i = journal->period_entries.begin();
|
for (period_entries_list::const_iterator i = journal.period_entries.begin();
|
||||||
i != journal->period_entries.end();
|
i != journal.period_entries.end();
|
||||||
i++) {
|
i++) {
|
||||||
write_period_entry(out, *i);
|
write_period_entry(out, *i);
|
||||||
xact_count += (*i)->transactions.size();
|
xact_count += (*i)->transactions.size();
|
||||||
|
|
|
||||||
6
binary.h
6
binary.h
|
|
@ -272,7 +272,7 @@ inline void write_object(std::ostream& out, const T& journal) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_journal(std::ostream& out, journal_t * journal);
|
void write_journal(std::ostream& out, journal_t& journal);
|
||||||
|
|
||||||
} // namespace binary
|
} // namespace binary
|
||||||
|
|
||||||
|
|
@ -282,8 +282,8 @@ class binary_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
91
config.cc
91
config.cc
|
|
@ -1,91 +0,0 @@
|
||||||
#include "config.h"
|
|
||||||
#include "acconf.h"
|
|
||||||
#include "option.h"
|
|
||||||
//#include "quotes.h"
|
|
||||||
#include "valexpr.h"
|
|
||||||
#include "walk.h"
|
|
||||||
|
|
||||||
namespace ledger {
|
|
||||||
|
|
||||||
string expand_path(const string& pathname)
|
|
||||||
{
|
|
||||||
if (pathname.length() == 0 || pathname[0] != '~')
|
|
||||||
return pathname;
|
|
||||||
|
|
||||||
const char * pfx = NULL;
|
|
||||||
string::size_type pos = pathname.find_first_of('/');
|
|
||||||
|
|
||||||
if (pathname.length() == 1 || pos == 1) {
|
|
||||||
pfx = std::getenv("HOME");
|
|
||||||
#ifdef HAVE_GETPWUID
|
|
||||||
if (! pfx) {
|
|
||||||
// Punt. We're trying to expand ~/, but HOME isn't set
|
|
||||||
struct passwd * pw = getpwuid(getuid());
|
|
||||||
if (pw)
|
|
||||||
pfx = pw->pw_dir;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#ifdef HAVE_GETPWNAM
|
|
||||||
else {
|
|
||||||
string user(pathname, 1, pos == string::npos ?
|
|
||||||
string::npos : pos - 1);
|
|
||||||
struct passwd * pw = getpwnam(user.c_str());
|
|
||||||
if (pw)
|
|
||||||
pfx = pw->pw_dir;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if we failed to find an expansion, return the pathname unchanged.
|
|
||||||
|
|
||||||
if (! pfx)
|
|
||||||
return pathname;
|
|
||||||
|
|
||||||
string result(pfx);
|
|
||||||
|
|
||||||
if (pos == string::npos)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
if (result.length() == 0 || result[result.length() - 1] != '/')
|
|
||||||
result += '/';
|
|
||||||
|
|
||||||
result += pathname.substr(pos + 1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// jww (2008-04-22): This needs to be changed to use boost::filesystem
|
|
||||||
string resolve_path(const string& pathname)
|
|
||||||
{
|
|
||||||
if (pathname[0] == '~')
|
|
||||||
return expand_path(pathname);
|
|
||||||
return pathname;
|
|
||||||
}
|
|
||||||
|
|
||||||
config_t::config_t()
|
|
||||||
{
|
|
||||||
balance_format = "%20T %2_%-a\n";
|
|
||||||
register_format = ("%D %-.20P %-.22A %12.67t %!12.80T\n%/"
|
|
||||||
"%32|%-.22A %12.67t %!12.80T\n");
|
|
||||||
wide_register_format = ("%D %-.35P %-.38A %22.108t %!22.132T\n%/"
|
|
||||||
"%48|%-.38A %22.108t %!22.132T\n");
|
|
||||||
plot_amount_format = "%D %(@S(@t))\n";
|
|
||||||
plot_total_format = "%D %(@S(@T))\n";
|
|
||||||
print_format = "\n%d %Y%C%P\n %-34W %12o%n\n%/ %-34W %12o%n\n";
|
|
||||||
write_hdr_format = "%d %Y%C%P\n";
|
|
||||||
write_xact_format = " %-34W %12o%n\n";
|
|
||||||
equity_format = "\n%D %Y%C%P\n%/ %-34W %12t\n";
|
|
||||||
prices_format = "%[%Y/%m/%d %H:%M:%S %Z] %-10A %12t %12T\n";
|
|
||||||
pricesdb_format = "P %[%Y/%m/%d %H:%M:%S] %A %t\n";
|
|
||||||
|
|
||||||
pricing_leeway = 24 * 3600;
|
|
||||||
|
|
||||||
download_quotes = false;
|
|
||||||
use_cache = false;
|
|
||||||
cache_dirty = false;
|
|
||||||
debug_mode = false;
|
|
||||||
verbose_mode = false;
|
|
||||||
trace_mode = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ledger
|
|
||||||
47
config.h
47
config.h
|
|
@ -1,47 +0,0 @@
|
||||||
#ifndef _CONFIG_H
|
|
||||||
#define _CONFIG_H
|
|
||||||
|
|
||||||
#include "ledger.h"
|
|
||||||
|
|
||||||
namespace ledger {
|
|
||||||
|
|
||||||
class config_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
path init_file;
|
|
||||||
path data_file;
|
|
||||||
path cache_file;
|
|
||||||
path price_db;
|
|
||||||
|
|
||||||
string balance_format;
|
|
||||||
string register_format;
|
|
||||||
string wide_register_format;
|
|
||||||
string plot_amount_format;
|
|
||||||
string plot_total_format;
|
|
||||||
string print_format;
|
|
||||||
string write_hdr_format;
|
|
||||||
string write_xact_format;
|
|
||||||
string equity_format;
|
|
||||||
string prices_format;
|
|
||||||
string pricesdb_format;
|
|
||||||
|
|
||||||
string date_input_format;
|
|
||||||
|
|
||||||
string account;
|
|
||||||
string pager;
|
|
||||||
|
|
||||||
unsigned long pricing_leeway;
|
|
||||||
|
|
||||||
bool download_quotes;
|
|
||||||
bool use_cache;
|
|
||||||
bool cache_dirty;
|
|
||||||
bool debug_mode;
|
|
||||||
bool verbose_mode;
|
|
||||||
bool trace_mode;
|
|
||||||
|
|
||||||
config_t();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ledger
|
|
||||||
|
|
||||||
#endif // _CONFIG_H
|
|
||||||
10
gnucash.cc
10
gnucash.cc
|
|
@ -344,8 +344,8 @@ bool gnucash_parser_t::test(std::istream& in) const
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int gnucash_parser_t::parse(std::istream& in,
|
unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
|
|
@ -360,8 +360,8 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
action = NO_ACTION;
|
action = NO_ACTION;
|
||||||
curr_journal = journal;
|
curr_journal = &journal;
|
||||||
master_account = master ? master : journal->master;
|
master_account = master ? master : journal.master;
|
||||||
curr_account = NULL;
|
curr_account = NULL;
|
||||||
curr_entry = NULL;
|
curr_entry = NULL;
|
||||||
curr_comm = NULL;
|
curr_comm = NULL;
|
||||||
|
|
@ -370,7 +370,7 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
instreamp = ∈
|
instreamp = ∈
|
||||||
pathname = original_file ? *original_file : "<gnucash>";
|
pathname = original_file ? *original_file : "<gnucash>";
|
||||||
src_idx = journal->sources.size() - 1;
|
src_idx = journal.sources.size() - 1;
|
||||||
|
|
||||||
// GnuCash uses the USD commodity without defining it, which really
|
// GnuCash uses the USD commodity without defining it, which really
|
||||||
// means $.
|
// means $.
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ class gnucash_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -399,9 +399,12 @@ typedef std::list<period_entry_t *> period_entries_list;
|
||||||
typedef std::list<path> paths_list;
|
typedef std::list<path> paths_list;
|
||||||
typedef std::list<string> strings_list;
|
typedef std::list<string> strings_list;
|
||||||
|
|
||||||
|
class session_t;
|
||||||
|
|
||||||
class journal_t
|
class journal_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
session_t * owner;
|
||||||
account_t * master;
|
account_t * master;
|
||||||
account_t * basket;
|
account_t * basket;
|
||||||
entries_list entries;
|
entries_list entries;
|
||||||
|
|
@ -416,7 +419,8 @@ class journal_t
|
||||||
|
|
||||||
std::list<entry_finalizer_t *> entry_finalize_hooks;
|
std::list<entry_finalizer_t *> entry_finalize_hooks;
|
||||||
|
|
||||||
journal_t() : basket(NULL), item_pool(NULL), item_pool_end(NULL) {
|
journal_t(session_t * _owner) :
|
||||||
|
owner(_owner), basket(NULL), item_pool(NULL), item_pool_end(NULL) {
|
||||||
TRACE_CTOR(journal_t, "");
|
TRACE_CTOR(journal_t, "");
|
||||||
master = new account_t(NULL, "");
|
master = new account_t(NULL, "");
|
||||||
master->journal = this;
|
master->journal = this;
|
||||||
|
|
|
||||||
2
ledger.h
2
ledger.h
|
|
@ -76,7 +76,7 @@ namespace ledger {
|
||||||
extern parser_t * textual_parser_ptr;
|
extern parser_t * textual_parser_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <config.h>
|
#include <session.h>
|
||||||
#include <report.h>
|
#include <report.h>
|
||||||
|
|
||||||
#endif // _LEDGER_H
|
#endif // _LEDGER_H
|
||||||
|
|
|
||||||
8
main.cc
8
main.cc
|
|
@ -199,19 +199,15 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
// Parse the initialization file, which can only be textual; then
|
// Parse the initialization file, which can only be textual; then
|
||||||
// parse the journal data.
|
// parse the journal data.
|
||||||
|
|
||||||
#if 0
|
|
||||||
session.read_init();
|
session.read_init();
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO_START(journal, "Read journal file");
|
INFO_START(journal, "Read journal file");
|
||||||
|
|
||||||
journal_t * journal = session.create_journal();
|
journal_t& journal(*session.create_journal());
|
||||||
|
|
||||||
#if 0
|
if (! session.read_data(journal, report.account))
|
||||||
if (! session.read_data(builder, journal, report.account))
|
|
||||||
throw_(parse_error, "Failed to locate any journal entries; "
|
throw_(parse_error, "Failed to locate any journal entries; "
|
||||||
"did you specify a valid file with -f?");
|
"did you specify a valid file with -f?");
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO_FINISH(journal);
|
INFO_FINISH(journal);
|
||||||
|
|
||||||
|
|
|
||||||
4
ofx.cc
4
ofx.cc
|
|
@ -195,8 +195,8 @@ bool ofx_parser_t::test(std::istream& in) const
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int ofx_parser_t::parse(std::istream& in,
|
unsigned int ofx_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
4
ofx.h
4
ofx.h
|
|
@ -11,8 +11,8 @@ class ofx_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
185
parser.cc
185
parser.cc
|
|
@ -1,185 +0,0 @@
|
||||||
#include "parser.h"
|
|
||||||
#include "journal.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
namespace ledger {
|
|
||||||
|
|
||||||
typedef std::list<parser_t *> parsers_list;
|
|
||||||
|
|
||||||
static parsers_list * parsers = NULL;
|
|
||||||
|
|
||||||
void initialize_parser_support()
|
|
||||||
{
|
|
||||||
parsers = new parsers_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void shutdown_parser_support()
|
|
||||||
{
|
|
||||||
if (parsers) {
|
|
||||||
delete parsers;
|
|
||||||
parsers = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool register_parser(parser_t * parser)
|
|
||||||
{
|
|
||||||
parsers_list::iterator i;
|
|
||||||
for (i = parsers->begin(); i != parsers->end(); i++)
|
|
||||||
if (*i == parser)
|
|
||||||
break;
|
|
||||||
if (i != parsers->end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
parsers->push_back(parser);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool unregister_parser(parser_t * parser)
|
|
||||||
{
|
|
||||||
parsers_list::iterator i;
|
|
||||||
for (i = parsers->begin(); i != parsers->end(); i++)
|
|
||||||
if (*i == parser)
|
|
||||||
break;
|
|
||||||
if (i == parsers->end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
parsers->erase(i);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int parse_journal(std::istream& in,
|
|
||||||
config_t& config,
|
|
||||||
journal_t * journal,
|
|
||||||
account_t * master,
|
|
||||||
const path * original_file)
|
|
||||||
{
|
|
||||||
if (! master)
|
|
||||||
master = journal->master;
|
|
||||||
|
|
||||||
for (parsers_list::iterator i = parsers->begin();
|
|
||||||
i != parsers->end();
|
|
||||||
i++)
|
|
||||||
if ((*i)->test(in))
|
|
||||||
return (*i)->parse(in, config, journal, master, original_file);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int parse_journal_file(const path& pathname,
|
|
||||||
config_t& config,
|
|
||||||
journal_t * journal,
|
|
||||||
account_t * master,
|
|
||||||
const path * original_file)
|
|
||||||
{
|
|
||||||
journal->sources.push_back(pathname);
|
|
||||||
|
|
||||||
if (! boost::filesystem::exists(pathname))
|
|
||||||
throw new error(string("Cannot read file '") +
|
|
||||||
string(pathname.string()) + "'");
|
|
||||||
|
|
||||||
if (! original_file)
|
|
||||||
original_file = &pathname;
|
|
||||||
|
|
||||||
boost::filesystem::ifstream stream(pathname);
|
|
||||||
return parse_journal(stream, config, journal, master, original_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (! cache_parser)
|
|
||||||
cache_parser = binary_parser_ptr;
|
|
||||||
if (! xml_parser)
|
|
||||||
xml_parser = xml_parser_ptr;
|
|
||||||
if (! stdin_parser)
|
|
||||||
stdin_parser = textual_parser_ptr;
|
|
||||||
|
|
||||||
DEBUG("ledger.config.cache",
|
|
||||||
"3. use_cache = " << config.use_cache);
|
|
||||||
|
|
||||||
if (! config.init_file.empty() &&
|
|
||||||
boost::filesystem::exists(config.init_file)) {
|
|
||||||
if (parse_journal_file(config.init_file.string(), config, journal) ||
|
|
||||||
journal->auto_entries.size() > 0 ||
|
|
||||||
journal->period_entries.size() > 0)
|
|
||||||
throw new error(string("Entries found in initialization file '") +
|
|
||||||
string(config.init_file.string()) + "'");
|
|
||||||
|
|
||||||
journal->sources.pop_front(); // remove init file
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.use_cache && ! config.cache_file.empty() &&
|
|
||||||
! config.data_file.empty()) {
|
|
||||||
DEBUG("ledger.config.cache",
|
|
||||||
"using_cache " << config.cache_file);
|
|
||||||
config.cache_dirty = true;
|
|
||||||
if (boost::filesystem::exists(config.cache_file)) {
|
|
||||||
boost::filesystem::ifstream stream(config.cache_file);
|
|
||||||
if (cache_parser && cache_parser->test(stream)) {
|
|
||||||
optional<path> price_db_orig = journal->price_db;
|
|
||||||
journal->price_db = config.price_db;
|
|
||||||
entry_count += cache_parser->parse(stream, config, journal,
|
|
||||||
NULL, &config.data_file);
|
|
||||||
if (entry_count > 0)
|
|
||||||
config.cache_dirty = false;
|
|
||||||
else
|
|
||||||
journal->price_db = price_db_orig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry_count == 0 && ! config.data_file.empty()) {
|
|
||||||
account_t * acct = NULL;
|
|
||||||
if (! config.account.empty())
|
|
||||||
acct = journal->find_account(config.account);
|
|
||||||
|
|
||||||
journal->price_db = config.price_db;
|
|
||||||
if (journal->price_db &&
|
|
||||||
boost::filesystem::exists(*journal->price_db)) {
|
|
||||||
if (parse_journal_file(*journal->price_db, config, journal)) {
|
|
||||||
throw new error("Entries not allowed in price history file");
|
|
||||||
} else {
|
|
||||||
DEBUG("ledger.config.cache",
|
|
||||||
"read price database " << *journal->price_db);
|
|
||||||
journal->sources.pop_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG("ledger.config.cache",
|
|
||||||
"rejected cache, parsing " << config.data_file);
|
|
||||||
if (config.data_file == "-") {
|
|
||||||
config.use_cache = false;
|
|
||||||
journal->sources.push_back("<stdin>");
|
|
||||||
#if 0
|
|
||||||
// jww (2006-03-23): Why doesn't XML work on stdin?
|
|
||||||
if (xml_parser && std::cin.peek() == '<')
|
|
||||||
entry_count += xml_parser->parse(std::cin, config, journal, acct);
|
|
||||||
else if (stdin_parser)
|
|
||||||
#endif
|
|
||||||
entry_count += stdin_parser->parse(std::cin, config, journal, acct);
|
|
||||||
}
|
|
||||||
else if (boost::filesystem::exists(config.data_file)) {
|
|
||||||
entry_count += parse_journal_file(config.data_file, config, journal,
|
|
||||||
acct);
|
|
||||||
if (journal->price_db)
|
|
||||||
journal->sources.push_back(*journal->price_db);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY(journal->valid());
|
|
||||||
|
|
||||||
return entry_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ledger
|
|
||||||
24
parser.h
24
parser.h
|
|
@ -7,7 +7,7 @@ namespace ledger {
|
||||||
|
|
||||||
class account_t;
|
class account_t;
|
||||||
class journal_t;
|
class journal_t;
|
||||||
class config_t;
|
class session_t;
|
||||||
|
|
||||||
class parser_t
|
class parser_t
|
||||||
{
|
{
|
||||||
|
|
@ -17,36 +17,30 @@ class parser_t
|
||||||
virtual bool test(std::istream& in) const = 0;
|
virtual bool test(std::istream& in) const = 0;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL) = 0;
|
const path * original_file = NULL) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool register_parser(parser_t * parser);
|
|
||||||
bool unregister_parser(parser_t * parser);
|
|
||||||
|
|
||||||
unsigned int parse_journal(std::istream& in,
|
unsigned int parse_journal(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
|
|
||||||
unsigned int parse_journal_file(const path& path,
|
unsigned int parse_journal_file(const path& path,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
|
|
||||||
unsigned int parse_ledger_data(config_t& config,
|
unsigned int parse_ledger_data(session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
parser_t * cache_parser = NULL,
|
parser_t * cache_parser = NULL,
|
||||||
parser_t * xml_parser = NULL,
|
parser_t * xml_parser = NULL,
|
||||||
parser_t * stdin_parser = NULL);
|
parser_t * stdin_parser = NULL);
|
||||||
|
|
||||||
void initialize_parser_support();
|
|
||||||
void shutdown_parser_support();
|
|
||||||
|
|
||||||
class parse_error : public error {
|
class parse_error : public error {
|
||||||
public:
|
public:
|
||||||
parse_error(const string& reason, error_context * ctxt = NULL) throw()
|
parse_error(const string& reason, error_context * ctxt = NULL) throw()
|
||||||
|
|
|
||||||
14
qif.cc
14
qif.cc
|
|
@ -34,8 +34,8 @@ bool qif_parser_t::test(std::istream& in) const
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int qif_parser_t::parse(std::istream& in,
|
unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
|
|
@ -54,8 +54,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
xact = new transaction_t(master);
|
xact = new transaction_t(master);
|
||||||
entry->add_transaction(xact);
|
entry->add_transaction(xact);
|
||||||
|
|
||||||
pathname = journal->sources.back();
|
pathname = journal.sources.back();
|
||||||
src_idx = journal->sources.size() - 1;
|
src_idx = journal.sources.size() - 1;
|
||||||
linenum = 1;
|
linenum = 1;
|
||||||
|
|
||||||
istream_pos_type beg_pos = 0;
|
istream_pos_type beg_pos = 0;
|
||||||
|
|
@ -166,7 +166,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
int len = std::strlen(line);
|
int len = std::strlen(line);
|
||||||
if (line[len - 1] == ']')
|
if (line[len - 1] == ']')
|
||||||
line[len - 1] = '\0';
|
line[len - 1] = '\0';
|
||||||
xact->account = journal->find_account(line[0] == '[' ?
|
xact->account = journal.find_account(line[0] == '[' ?
|
||||||
line + 1 : line);
|
line + 1 : line);
|
||||||
if (c == 'L')
|
if (c == 'L')
|
||||||
saw_category = true;
|
saw_category = true;
|
||||||
|
|
@ -191,7 +191,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
account_t * other;
|
account_t * other;
|
||||||
if (xact->account == master) {
|
if (xact->account == master) {
|
||||||
if (! misc)
|
if (! misc)
|
||||||
misc = journal->find_account("Miscellaneous");
|
misc = journal.find_account("Miscellaneous");
|
||||||
other = misc;
|
other = misc;
|
||||||
} else {
|
} else {
|
||||||
other = master;
|
other = master;
|
||||||
|
|
@ -211,7 +211,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
entry->add_transaction(nxact);
|
entry->add_transaction(nxact);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (journal->add_entry(entry.get())) {
|
if (journal.add_entry(entry.get())) {
|
||||||
entry->src_idx = src_idx;
|
entry->src_idx = src_idx;
|
||||||
entry->beg_pos = beg_pos;
|
entry->beg_pos = beg_pos;
|
||||||
entry->beg_line = beg_line;
|
entry->beg_line = beg_line;
|
||||||
|
|
|
||||||
4
qif.h
4
qif.h
|
|
@ -11,8 +11,8 @@ class qif_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
64
session.cc
64
session.cc
|
|
@ -118,39 +118,35 @@ session_t::session_t()
|
||||||
ansi_codes(false),
|
ansi_codes(false),
|
||||||
ansi_invert(false)
|
ansi_invert(false)
|
||||||
{
|
{
|
||||||
TRACE_CTOR(session_t, "xml::xpath_t::scope_t&");
|
TRACE_CTOR(session_t, "expr::scope_t&");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
std::size_t session_t::read_journal(journal_t& journal,
|
||||||
|
std::istream& in,
|
||||||
std::size_t session_t::read_journal(std::istream& in,
|
|
||||||
const path& pathname,
|
const path& pathname,
|
||||||
xml::builder_t& builder)
|
account_t * master)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (! master)
|
if (! master)
|
||||||
master = journal->master;
|
master = journal.master;
|
||||||
#endif
|
|
||||||
|
|
||||||
foreach (parser_t& parser, parsers)
|
foreach (parser_t& parser, parsers)
|
||||||
if (parser.test(in))
|
if (parser.test(in))
|
||||||
return parser.parse(in, pathname, builder);
|
return parser.parse(in, *this, journal, master, &pathname);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t session_t::read_journal(const path& pathname,
|
std::size_t session_t::read_journal(journal_t& journal,
|
||||||
xml::builder_t& builder)
|
const path& pathname,
|
||||||
|
account_t * master)
|
||||||
{
|
{
|
||||||
#if 0
|
journal.sources.push_back(pathname);
|
||||||
journal->sources.push_back(pathname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (! exists(pathname))
|
if (! exists(pathname))
|
||||||
throw_(std::logic_error, "Cannot read file" << pathname);
|
throw_(std::logic_error, "Cannot read file" << pathname);
|
||||||
|
|
||||||
ifstream stream(pathname);
|
ifstream stream(pathname);
|
||||||
return read_journal(stream, pathname, builder);
|
return read_journal(journal, stream, pathname, master);
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_t::read_init()
|
void session_t::read_init()
|
||||||
|
|
@ -166,8 +162,7 @@ void session_t::read_init()
|
||||||
// jww (2006-09-15): Read initialization options here!
|
// jww (2006-09-15): Read initialization options here!
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t session_t::read_data(xml::builder_t& builder,
|
std::size_t session_t::read_data(journal_t& journal,
|
||||||
journal_t * journal,
|
|
||||||
const string& master_account)
|
const string& master_account)
|
||||||
{
|
{
|
||||||
if (data_file.empty())
|
if (data_file.empty())
|
||||||
|
|
@ -184,9 +179,9 @@ std::size_t session_t::read_data(xml::builder_t& builder,
|
||||||
cache_dirty = true;
|
cache_dirty = true;
|
||||||
if (exists(*cache_file)) {
|
if (exists(*cache_file)) {
|
||||||
push_variable<optional<path> >
|
push_variable<optional<path> >
|
||||||
save_price_db(journal->price_db, price_db);
|
save_price_db(journal.price_db, price_db);
|
||||||
|
|
||||||
entry_count += read_journal(*cache_file, builder);
|
entry_count += read_journal(journal, *cache_file);
|
||||||
if (entry_count > 0)
|
if (entry_count > 0)
|
||||||
cache_dirty = false;
|
cache_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
@ -195,44 +190,41 @@ std::size_t session_t::read_data(xml::builder_t& builder,
|
||||||
if (entry_count == 0) {
|
if (entry_count == 0) {
|
||||||
account_t * acct = NULL;
|
account_t * acct = NULL;
|
||||||
if (! master_account.empty())
|
if (! master_account.empty())
|
||||||
acct = journal->find_account(master_account);
|
acct = journal.find_account(master_account);
|
||||||
|
|
||||||
journal->price_db = price_db;
|
journal.price_db = price_db;
|
||||||
if (journal->price_db && exists(*journal->price_db)) {
|
if (journal.price_db && exists(*journal.price_db)) {
|
||||||
if (read_journal(*journal->price_db, builder)) {
|
if (read_journal(journal, *journal.price_db)) {
|
||||||
throw_(parse_error, "Entries not allowed in price history file");
|
throw_(parse_error, "Entries not allowed in price history file");
|
||||||
} else {
|
} else {
|
||||||
DEBUG("ledger.cache",
|
DEBUG("ledger.cache",
|
||||||
"read price database " << journal->price_db->string());
|
"read price database " << journal.price_db->string());
|
||||||
journal->sources.pop_back();
|
journal.sources.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("ledger.cache", "rejected cache, parsing " << data_file.string());
|
DEBUG("ledger.cache", "rejected cache, parsing " << data_file.string());
|
||||||
if (data_file == "-") {
|
if (data_file == "-") {
|
||||||
use_cache = false;
|
use_cache = false;
|
||||||
journal->sources.push_back("<stdin>");
|
journal.sources.push_back("/dev/stdin");
|
||||||
entry_count += read_journal(std::cin, "<stdin>", builder);
|
entry_count += read_journal(journal, std::cin, "/dev/stdin", acct);
|
||||||
}
|
}
|
||||||
else if (exists(data_file)) {
|
else if (exists(data_file)) {
|
||||||
entry_count += read_journal(data_file, builder);
|
entry_count += read_journal(journal, data_file, acct);
|
||||||
if (journal->price_db)
|
if (journal.price_db)
|
||||||
journal->sources.push_back(*journal->price_db);
|
journal.sources.push_back(*journal.price_db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VERIFY(journal->valid());
|
VERIFY(journal.valid());
|
||||||
|
|
||||||
TRACE_STOP(parser, 1);
|
TRACE_STOP(parser, 1);
|
||||||
|
|
||||||
return entry_count;
|
return entry_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
optional<value_t>
|
value_t session_t::resolve(const string& name, expr::scope_t& locals)
|
||||||
session_t::resolve(const string& name, xml::xpath_t::scope_t& locals)
|
|
||||||
{
|
{
|
||||||
const char * p = name.c_str();
|
const char * p = name.c_str();
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
|
|
@ -259,7 +251,7 @@ session_t::resolve(const string& name, xml::xpath_t::scope_t& locals)
|
||||||
return value_t(register_format, true);
|
return value_t(register_format, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return xml::xpath_t::scope_t::resolve(name, locals);
|
return expr::scope_t::resolve(name, locals);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
17
session.h
17
session.h
|
|
@ -85,7 +85,7 @@ class session_t : public expr::symbol_scope_t
|
||||||
}
|
}
|
||||||
|
|
||||||
journal_t * create_journal() {
|
journal_t * create_journal() {
|
||||||
journal_t * journal = new journal_t;
|
journal_t * journal = new journal_t(this);
|
||||||
journals.push_back(journal);
|
journals.push_back(journal);
|
||||||
return journal;
|
return journal;
|
||||||
}
|
}
|
||||||
|
|
@ -101,19 +101,18 @@ class session_t : public expr::symbol_scope_t
|
||||||
checked_delete(journal);
|
checked_delete(journal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
std::size_t read_journal(journal_t& journal,
|
||||||
std::size_t read_journal(std::istream& in,
|
std::istream& in,
|
||||||
const path& pathname,
|
const path& pathname,
|
||||||
xml::builder_t& builder);
|
account_t * master = NULL);
|
||||||
std::size_t read_journal(const path& pathname,
|
std::size_t read_journal(journal_t& journal,
|
||||||
xml::builder_t& builder);
|
const path& pathname,
|
||||||
|
account_t * master = NULL);
|
||||||
|
|
||||||
void read_init();
|
void read_init();
|
||||||
|
|
||||||
std::size_t read_data(xml::builder_t& builder,
|
std::size_t read_data(journal_t& journal,
|
||||||
journal_t * journal,
|
|
||||||
const string& master_account = "");
|
const string& master_account = "");
|
||||||
#endif
|
|
||||||
|
|
||||||
void register_parser(parser_t * parser) {
|
void register_parser(parser_t * parser) {
|
||||||
parsers.push_back(parser);
|
parsers.push_back(parser);
|
||||||
|
|
|
||||||
63
startup.cc
63
startup.cc
|
|
@ -1,63 +0,0 @@
|
||||||
#include "ledger.h"
|
|
||||||
#include "xml.h"
|
|
||||||
#include "gnucash.h"
|
|
||||||
#include "qif.h"
|
|
||||||
#include "ofx.h"
|
|
||||||
|
|
||||||
using namespace ledger;
|
|
||||||
|
|
||||||
namespace ledger {
|
|
||||||
parser_t * binary_parser_ptr = NULL;
|
|
||||||
parser_t * xml_parser_ptr = NULL;
|
|
||||||
parser_t * gnucash_parser_ptr = NULL;
|
|
||||||
parser_t * ofx_parser_ptr = NULL;
|
|
||||||
parser_t * qif_parser_ptr = NULL;
|
|
||||||
parser_t * textual_parser_ptr = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
binary_parser_t binary_parser;
|
|
||||||
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
|
|
||||||
xml_parser_t xml_parser;
|
|
||||||
gnucash_parser_t gnucash_parser;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBOFX
|
|
||||||
ofx_parser_t ofx_parser;
|
|
||||||
#endif
|
|
||||||
qif_parser_t qif_parser;
|
|
||||||
textual_parser_t textual_parser;
|
|
||||||
|
|
||||||
static class startup {
|
|
||||||
public:
|
|
||||||
startup();
|
|
||||||
~startup();
|
|
||||||
} _startup;
|
|
||||||
|
|
||||||
startup::startup()
|
|
||||||
{
|
|
||||||
std::ios::sync_with_stdio(false);
|
|
||||||
|
|
||||||
initialize_parser_support();
|
|
||||||
|
|
||||||
register_parser(&binary_parser); binary_parser_ptr = &binary_parser;
|
|
||||||
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
|
|
||||||
register_parser(&xml_parser); xml_parser_ptr = &xml_parser;
|
|
||||||
register_parser(&gnucash_parser); gnucash_parser_ptr = &gnucash_parser;
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBOFX
|
|
||||||
register_parser(&ofx_parser); ofx_parser_ptr = &ofx_parser;
|
|
||||||
#endif
|
|
||||||
register_parser(&qif_parser); qif_parser_ptr = &qif_parser;
|
|
||||||
register_parser(&textual_parser); textual_parser_ptr = &textual_parser;
|
|
||||||
}
|
|
||||||
|
|
||||||
startup::~startup()
|
|
||||||
{
|
|
||||||
// jww (2008-04-22): What about this?
|
|
||||||
#if 0
|
|
||||||
if (! ledger::do_cleanup)
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
shutdown_parser_support();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
37
textual.cc
37
textual.cc
|
|
@ -5,8 +5,7 @@
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
#include "textual.h"
|
#include "textual.h"
|
||||||
#include "valexpr.h"
|
#include "valexpr.h"
|
||||||
#include "option.h"
|
#include "parsexp.h"
|
||||||
#include "config.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "acconf.h"
|
#include "acconf.h"
|
||||||
|
|
||||||
|
|
@ -494,7 +493,7 @@ static void clock_out_from_timelog(std::list<time_entry_t>& time_entries,
|
||||||
const datetime_t& when,
|
const datetime_t& when,
|
||||||
account_t * account,
|
account_t * account,
|
||||||
const char * desc,
|
const char * desc,
|
||||||
journal_t * journal)
|
journal_t& journal)
|
||||||
{
|
{
|
||||||
time_entry_t event;
|
time_entry_t event;
|
||||||
|
|
||||||
|
|
@ -551,15 +550,15 @@ static void clock_out_from_timelog(std::list<time_entry_t>& time_entries,
|
||||||
xact->state = transaction_t::CLEARED;
|
xact->state = transaction_t::CLEARED;
|
||||||
curr->add_transaction(xact);
|
curr->add_transaction(xact);
|
||||||
|
|
||||||
if (! journal->add_entry(curr.get()))
|
if (! journal.add_entry(curr.get()))
|
||||||
throw new parse_error("Failed to record 'out' timelog entry");
|
throw new parse_error("Failed to record 'out' timelog entry");
|
||||||
else
|
else
|
||||||
curr.release();
|
curr.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int textual_parser_t::parse(std::istream& in,
|
unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
|
|
@ -571,16 +570,16 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
unsigned int errors = 0;
|
unsigned int errors = 0;
|
||||||
|
|
||||||
std::list<account_t *> account_stack;
|
std::list<account_t *> account_stack;
|
||||||
auto_entry_finalizer_t auto_entry_finalizer(journal);
|
auto_entry_finalizer_t auto_entry_finalizer(&journal);
|
||||||
std::list<time_entry_t> time_entries;
|
std::list<time_entry_t> time_entries;
|
||||||
|
|
||||||
if (! master)
|
if (! master)
|
||||||
master = journal->master;
|
master = journal.master;
|
||||||
|
|
||||||
account_stack.push_front(master);
|
account_stack.push_front(master);
|
||||||
|
|
||||||
pathname = journal->sources.back();
|
pathname = journal.sources.back();
|
||||||
src_idx = journal->sources.size() - 1;
|
src_idx = journal.sources.size() - 1;
|
||||||
linenum = 1;
|
linenum = 1;
|
||||||
|
|
||||||
INFO("Parsing file '" << pathname.string() << "'");
|
INFO("Parsing file '" << pathname.string() << "'");
|
||||||
|
|
@ -662,7 +661,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'A': // a default account for unbalanced xacts
|
case 'A': // a default account for unbalanced xacts
|
||||||
journal->basket =
|
journal.basket =
|
||||||
account_stack.front()->find_account(skip_ws(line + 1));
|
account_stack.front()->find_account(skip_ws(line + 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -742,14 +741,14 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
case '=': { // automated entry
|
case '=': { // automated entry
|
||||||
if (! added_auto_entry_hook) {
|
if (! added_auto_entry_hook) {
|
||||||
journal->add_entry_finalizer(&auto_entry_finalizer);
|
journal.add_entry_finalizer(&auto_entry_finalizer);
|
||||||
added_auto_entry_hook = true;
|
added_auto_entry_hook = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_entry_t * ae = new auto_entry_t(skip_ws(line + 1));
|
auto_entry_t * ae = new auto_entry_t(skip_ws(line + 1));
|
||||||
if (parse_transactions(in, account_stack.front(), *ae,
|
if (parse_transactions(in, account_stack.front(), *ae,
|
||||||
"automated", end_pos)) {
|
"automated", end_pos)) {
|
||||||
journal->auto_entries.push_back(ae);
|
journal.auto_entries.push_back(ae);
|
||||||
ae->src_idx = src_idx;
|
ae->src_idx = src_idx;
|
||||||
ae->beg_pos = beg_pos;
|
ae->beg_pos = beg_pos;
|
||||||
ae->beg_line = beg_line;
|
ae->beg_line = beg_line;
|
||||||
|
|
@ -767,8 +766,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
if (parse_transactions(in, account_stack.front(), *pe,
|
if (parse_transactions(in, account_stack.front(), *pe,
|
||||||
"period", end_pos)) {
|
"period", end_pos)) {
|
||||||
if (pe->finalize()) {
|
if (pe->finalize()) {
|
||||||
extend_entry_base(journal, *pe, true);
|
extend_entry_base(&journal, *pe, true);
|
||||||
journal->period_entries.push_back(pe);
|
journal.period_entries.push_back(pe);
|
||||||
pe->src_idx = src_idx;
|
pe->src_idx = src_idx;
|
||||||
pe->beg_pos = beg_pos;
|
pe->beg_pos = beg_pos;
|
||||||
pe->beg_line = beg_line;
|
pe->beg_line = beg_line;
|
||||||
|
|
@ -808,11 +807,13 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
DEBUG("ledger.textual.include", "line " << linenum << ": " <<
|
DEBUG("ledger.textual.include", "line " << linenum << ": " <<
|
||||||
"Including path '" << pathname << "'");
|
"Including path '" << pathname << "'");
|
||||||
|
|
||||||
|
#if 0
|
||||||
include_stack.push_back(std::pair<path, int>
|
include_stack.push_back(std::pair<path, int>
|
||||||
(journal->sources.back(), linenum - 1));
|
(journal.sources.back(), linenum - 1));
|
||||||
count += parse_journal_file(pathname, config, journal,
|
count += parse_journal_file(pathname, config, journal,
|
||||||
account_stack.front());
|
account_stack.front());
|
||||||
include_stack.pop_back();
|
include_stack.pop_back();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (word == "account") {
|
else if (word == "account") {
|
||||||
account_t * acct;
|
account_t * acct;
|
||||||
|
|
@ -856,7 +857,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
TRACE_START(entries, 1, "Time spent handling entries:");
|
TRACE_START(entries, 1, "Time spent handling entries:");
|
||||||
if (entry_t * entry =
|
if (entry_t * entry =
|
||||||
parse_entry(in, line, account_stack.front(), *this, pos)) {
|
parse_entry(in, line, account_stack.front(), *this, pos)) {
|
||||||
if (journal->add_entry(entry)) {
|
if (journal.add_entry(entry)) {
|
||||||
entry->src_idx = src_idx;
|
entry->src_idx = src_idx;
|
||||||
entry->beg_pos = beg_pos;
|
entry->beg_pos = beg_pos;
|
||||||
entry->beg_line = beg_line;
|
entry->beg_line = beg_line;
|
||||||
|
|
@ -913,7 +914,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (added_auto_entry_hook)
|
if (added_auto_entry_hook)
|
||||||
journal->remove_entry_finalizer(&auto_entry_finalizer);
|
journal.remove_entry_finalizer(&auto_entry_finalizer);
|
||||||
|
|
||||||
if (errors > 0)
|
if (errors > 0)
|
||||||
throw (int)errors;
|
throw (int)errors;
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ class textual_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
6
walk.h
6
walk.h
|
|
@ -725,12 +725,12 @@ void walk_accounts(account_t& account,
|
||||||
void walk_commodities(commodity_pool_t::commodities_by_ident& commodities,
|
void walk_commodities(commodity_pool_t::commodities_by_ident& commodities,
|
||||||
item_handler<transaction_t>& handler);
|
item_handler<transaction_t>& handler);
|
||||||
|
|
||||||
inline void clear_journal_xdata(journal_t * journal) {
|
inline void clear_journal_xdata(journal_t& journal) {
|
||||||
clear_transaction_xdata xact_cleaner;
|
clear_transaction_xdata xact_cleaner;
|
||||||
walk_entries(journal->entries, xact_cleaner);
|
walk_entries(journal.entries, xact_cleaner);
|
||||||
|
|
||||||
clear_account_xdata acct_cleaner;
|
clear_account_xdata acct_cleaner;
|
||||||
walk_accounts(*journal->master, acct_cleaner);
|
walk_accounts(*journal.master, acct_cleaner);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
6
xml.cc
6
xml.cc
|
|
@ -180,15 +180,15 @@ bool xml_parser_t::test(std::istream& in) const
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int xml_parser_t::parse(std::istream& in,
|
unsigned int xml_parser_t::parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master,
|
account_t * master,
|
||||||
const path * original_file)
|
const path * original_file)
|
||||||
{
|
{
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
curr_journal = journal;
|
curr_journal = &journal;
|
||||||
curr_entry = NULL;
|
curr_entry = NULL;
|
||||||
curr_comm = NULL;
|
curr_comm = NULL;
|
||||||
ignore = false;
|
ignore = false;
|
||||||
|
|
|
||||||
4
xml.h
4
xml.h
|
|
@ -14,8 +14,8 @@ class xml_parser_t : public parser_t
|
||||||
virtual bool test(std::istream& in) const;
|
virtual bool test(std::istream& in) const;
|
||||||
|
|
||||||
virtual unsigned int parse(std::istream& in,
|
virtual unsigned int parse(std::istream& in,
|
||||||
config_t& config,
|
session_t& session,
|
||||||
journal_t * journal,
|
journal_t& journal,
|
||||||
account_t * master = NULL,
|
account_t * master = NULL,
|
||||||
const path * original_file = NULL);
|
const path * original_file = NULL);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue