added back sorting support
This commit is contained in:
parent
1741c80fe4
commit
7e87a0a0b1
12 changed files with 200 additions and 169 deletions
33
binary.cc
33
binary.cc
|
|
@ -1,5 +1,4 @@
|
|||
#include "ledger.h"
|
||||
#include "textual.h"
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
|
@ -97,7 +96,7 @@ transaction_t * read_binary_transaction(std::istream& in, entry_t * entry)
|
|||
return xact;
|
||||
}
|
||||
|
||||
entry_t * read_binary_entry(std::istream& in, ledger_t * ledger)
|
||||
entry_t * read_binary_entry(std::istream& in, journal_t * journal)
|
||||
{
|
||||
entry_t * entry = new entry_t;
|
||||
|
||||
|
|
@ -258,7 +257,7 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL)
|
|||
|
||||
// If all of the subaccounts will be added to a different master
|
||||
// account, throw away what we've learned about the recorded
|
||||
// ledger's own master account.
|
||||
// journal's own master account.
|
||||
|
||||
if (master) {
|
||||
delete acct;
|
||||
|
|
@ -282,9 +281,9 @@ account_t * read_binary_account(std::istream& in, account_t * master = NULL)
|
|||
return acct;
|
||||
}
|
||||
|
||||
unsigned int read_binary_ledger(std::istream& in,
|
||||
unsigned int read_binary_journal(std::istream& in,
|
||||
const std::string& leader,
|
||||
ledger_t * ledger,
|
||||
journal_t * journal,
|
||||
account_t * master)
|
||||
{
|
||||
ident = 0;
|
||||
|
|
@ -325,7 +324,7 @@ unsigned int read_binary_ledger(std::istream& in,
|
|||
in.read(buf, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
ledger->sources.push_back(buf);
|
||||
journal->sources.push_back(buf);
|
||||
|
||||
std::time_t old_mtime;
|
||||
struct stat info;
|
||||
|
|
@ -335,7 +334,7 @@ unsigned int read_binary_ledger(std::istream& in,
|
|||
return 0;
|
||||
}
|
||||
|
||||
ledger->master = read_binary_account(in, master);
|
||||
journal->master = read_binary_account(in, master);
|
||||
|
||||
unsigned long count;
|
||||
in.read((char *)&count, sizeof(count));
|
||||
|
|
@ -351,8 +350,8 @@ unsigned int read_binary_ledger(std::istream& in,
|
|||
in.read((char *)&count, sizeof(count));
|
||||
|
||||
for (int i = count; --i >= 0; ) {
|
||||
entry_t * entry = read_binary_entry(in, ledger);
|
||||
ledger->entries.push_back(entry);
|
||||
entry_t * entry = read_binary_entry(in, journal);
|
||||
journal->entries.push_back(entry);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
@ -557,7 +556,7 @@ void write_binary_account(std::ostream& out, account_t * account)
|
|||
#endif
|
||||
}
|
||||
|
||||
void write_binary_ledger(std::ostream& out, ledger_t * ledger,
|
||||
void write_binary_journal(std::ostream& out, journal_t * journal,
|
||||
const std::string& leader)
|
||||
{
|
||||
out.write((char *)&binary_magic_number, sizeof(binary_magic_number));
|
||||
|
|
@ -576,11 +575,11 @@ void write_binary_ledger(std::ostream& out, ledger_t * ledger,
|
|||
out.write((char *)&len, sizeof(len));
|
||||
out.write(leader.c_str(), len);
|
||||
|
||||
len = ledger->sources.size();
|
||||
len = journal->sources.size();
|
||||
out.write((char *)&len, sizeof(len));
|
||||
|
||||
for (std::list<std::string>::const_iterator i = ledger->sources.begin();
|
||||
i != ledger->sources.end();
|
||||
for (std::list<std::string>::const_iterator i = journal->sources.begin();
|
||||
i != journal->sources.end();
|
||||
i++) {
|
||||
len = (*i).length();
|
||||
out.write((char *)&len, sizeof(len));
|
||||
|
|
@ -591,7 +590,7 @@ void write_binary_ledger(std::ostream& out, ledger_t * ledger,
|
|||
out.write((char *)&info.st_mtime, sizeof(info.st_mtime));
|
||||
}
|
||||
|
||||
write_binary_account(out, ledger->master);
|
||||
write_binary_account(out, journal->master);
|
||||
|
||||
unsigned long count = commodity_t::commodities.size();
|
||||
out.write((char *)&count, sizeof(count));
|
||||
|
|
@ -601,11 +600,11 @@ void write_binary_ledger(std::ostream& out, ledger_t * ledger,
|
|||
i++)
|
||||
write_binary_commodity(out, (*i).second);
|
||||
|
||||
count = ledger->entries.size();
|
||||
count = journal->entries.size();
|
||||
out.write((char *)&count, sizeof(count));
|
||||
|
||||
for (entries_list::const_iterator i = ledger->entries.begin();
|
||||
i != ledger->entries.end();
|
||||
for (entries_list::const_iterator i = journal->entries.begin();
|
||||
i != journal->entries.end();
|
||||
i++)
|
||||
write_binary_entry(out, *i);
|
||||
|
||||
|
|
|
|||
21
binary.h
21
binary.h
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef _BINARY_H
|
||||
#define _BINARY_H
|
||||
|
||||
#include "ledger.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
extern unsigned long binary_magic_number;
|
||||
|
||||
extern unsigned int read_binary_ledger(std::istream& in,
|
||||
const std::string& leader,
|
||||
ledger_t * journal,
|
||||
account_t * master = NULL);
|
||||
|
||||
extern void write_binary_ledger(std::ostream& out,
|
||||
ledger_t * ledger,
|
||||
const std::string& leader);
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _BINARY_H
|
||||
|
|
@ -147,7 +147,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
|||
void format_t::format_elements(std::ostream& out,
|
||||
const details_t& details) const
|
||||
{
|
||||
for (const element_t * elem = elements.get(); elem; elem = elem->next) {
|
||||
for (const element_t * elem = elements; elem; elem = elem->next) {
|
||||
if (elem->align_left)
|
||||
out << std::left;
|
||||
else
|
||||
|
|
@ -158,7 +158,7 @@ void format_t::format_elements(std::ostream& out,
|
|||
|
||||
switch (elem->type) {
|
||||
case element_t::STRING:
|
||||
out << elem->chars;;
|
||||
out << elem->chars;
|
||||
break;
|
||||
|
||||
case element_t::VALUE_EXPR: {
|
||||
|
|
|
|||
11
format.h
11
format.h
|
|
@ -49,13 +49,16 @@ struct element_t
|
|||
|
||||
struct format_t
|
||||
{
|
||||
std::auto_ptr<element_t> elements;
|
||||
element_t * elements;
|
||||
|
||||
static std::auto_ptr<node_t> value_expr;
|
||||
static std::auto_ptr<node_t> total_expr;
|
||||
static std::auto_ptr<node_t> value_expr;
|
||||
static std::auto_ptr<node_t> total_expr;
|
||||
|
||||
format_t(const std::string& _format) {
|
||||
elements.reset(parse_elements(_format));
|
||||
elements = parse_elements(_format);
|
||||
}
|
||||
~format_t() {
|
||||
if (elements) delete elements;
|
||||
}
|
||||
|
||||
static element_t * parse_elements(const std::string& fmt);
|
||||
|
|
|
|||
10
gnucash.cc
10
gnucash.cc
|
|
@ -15,7 +15,7 @@ typedef std::pair<const std::string, account_t *> accounts_pair;
|
|||
typedef std::map<account_t *, commodity_t *> account_comm_map;
|
||||
typedef std::pair<account_t *, commodity_t *> account_comm_pair;
|
||||
|
||||
static ledger_t * curr_ledger;
|
||||
static journal_t * curr_journal;
|
||||
static account_t * curr_account;
|
||||
static commodity_t * curr_account_comm;
|
||||
static std::string curr_account_id;
|
||||
|
|
@ -107,7 +107,7 @@ static void endElement(void *userData, const char *name)
|
|||
if (std::strcmp(name, "gnc:account") == 0) {
|
||||
assert(curr_account);
|
||||
if (! curr_account->parent)
|
||||
curr_ledger->add_account(curr_account);
|
||||
curr_journal->add_account(curr_account);
|
||||
accounts_by_id.insert(accounts_pair(curr_account_id, curr_account));
|
||||
curr_account = NULL;
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ static void endElement(void *userData, const char *name)
|
|||
}
|
||||
else if (std::strcmp(name, "gnc:transaction") == 0) {
|
||||
assert(curr_entry);
|
||||
if (! curr_ledger->add_entry(curr_entry))
|
||||
if (! curr_journal->add_entry(curr_entry))
|
||||
assert(0);
|
||||
curr_entry = NULL;
|
||||
}
|
||||
|
|
@ -256,13 +256,13 @@ static void dataHandler(void *userData, const char *s, int len)
|
|||
}
|
||||
}
|
||||
|
||||
int parse_gnucash(std::istream& in, ledger_t * ledger, account_t * master)
|
||||
int parse_gnucash(std::istream& in, journal_t * journal, account_t * master)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
count = 0;
|
||||
action = NO_ACTION;
|
||||
curr_ledger = ledger;
|
||||
curr_journal = journal;
|
||||
curr_account = NULL;
|
||||
curr_entry = NULL;
|
||||
curr_comm = NULL;
|
||||
|
|
|
|||
39
ledger.cc
39
ledger.cc
|
|
@ -1,8 +1,6 @@
|
|||
#include "ledger.h"
|
||||
#include "valexpr.h"
|
||||
#include "datetime.h"
|
||||
#include "textual.h"
|
||||
#include "binary.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
|
@ -10,30 +8,7 @@ namespace ledger {
|
|||
|
||||
const std::string version = "2.0b";
|
||||
|
||||
#if 0
|
||||
|
||||
struct cmp_items {
|
||||
const node_t * sort_order;
|
||||
|
||||
cmp_items(const node_t * _sort_order) : sort_order(_sort_order) {
|
||||
assert(sort_order);
|
||||
}
|
||||
|
||||
bool operator()(const item_t * left, const item_t * right) const {
|
||||
assert(left);
|
||||
assert(right);
|
||||
return sort_order->compute(left) < sort_order->compute(right);
|
||||
}
|
||||
};
|
||||
|
||||
void item_t::sort(const node_t * sort_order)
|
||||
{
|
||||
std::stable_sort(subitems.begin(), subitems.end(), cmp_items(sort_order));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ledger_t::~ledger_t()
|
||||
journal_t::~journal_t()
|
||||
{
|
||||
delete master;
|
||||
|
||||
|
|
@ -46,7 +21,7 @@ ledger_t::~ledger_t()
|
|||
delete *i;
|
||||
}
|
||||
|
||||
bool ledger_t::add_entry(entry_t * entry)
|
||||
bool journal_t::add_entry(entry_t * entry)
|
||||
{
|
||||
entries.push_back(entry);
|
||||
|
||||
|
|
@ -64,7 +39,7 @@ bool ledger_t::add_entry(entry_t * entry)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ledger_t::remove_entry(entry_t * entry)
|
||||
bool journal_t::remove_entry(entry_t * entry)
|
||||
{
|
||||
entries.remove(entry);
|
||||
|
||||
|
|
@ -77,7 +52,7 @@ bool ledger_t::remove_entry(entry_t * entry)
|
|||
return true;
|
||||
}
|
||||
|
||||
entry_t * ledger_t::derive_entry(int argc, char **argv) const
|
||||
entry_t * journal_t::derive_entry(int argc, char **argv) const
|
||||
{
|
||||
entry_t * added = new entry_t;
|
||||
entry_t * matching = NULL;
|
||||
|
|
@ -204,7 +179,7 @@ entry_t * ledger_t::derive_entry(int argc, char **argv) const
|
|||
return added;
|
||||
}
|
||||
|
||||
int parse_ledger_file(char * p, ledger_t * journal)
|
||||
int parse_journal_file(char * p, journal_t * journal)
|
||||
{
|
||||
char * sep = std::strrchr(p, '=');
|
||||
if (sep) *sep++ = '\0';
|
||||
|
|
@ -225,9 +200,9 @@ int parse_ledger_file(char * p, ledger_t * journal)
|
|||
stream.seekg(start);
|
||||
|
||||
if (magic == binary_magic_number)
|
||||
return read_binary_ledger(stream, "", journal, master);
|
||||
return read_binary_journal(stream, "", journal, master);
|
||||
else
|
||||
return parse_textual_ledger(stream, journal, master);
|
||||
return parse_textual_journal(stream, journal, master);
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
30
ledger.h
30
ledger.h
|
|
@ -133,14 +133,14 @@ class account_t
|
|||
return fullname();
|
||||
}
|
||||
|
||||
// These functions should only be called from ledger_t::add_entry
|
||||
// and ledger_t::remove_entry; or from the various parsers.
|
||||
// These functions should only be called from journal_t::add_entry
|
||||
// and journal_t::remove_entry; or from the various parsers.
|
||||
void add_transaction(transaction_t * xact) {
|
||||
transactions.push_back(xact);
|
||||
}
|
||||
bool remove_transaction(transaction_t * xact);
|
||||
|
||||
friend class ledger_t;
|
||||
friend class journal_t;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, const account_t& acct) {
|
||||
|
|
@ -151,7 +151,7 @@ inline std::ostream& operator<<(std::ostream& out, const account_t& acct) {
|
|||
|
||||
typedef std::list<entry_t *> entries_list;
|
||||
|
||||
class ledger_t
|
||||
class journal_t
|
||||
{
|
||||
public:
|
||||
account_t * master;
|
||||
|
|
@ -159,13 +159,13 @@ class ledger_t
|
|||
mutable accounts_map accounts_cache;
|
||||
std::list<std::string> sources;
|
||||
|
||||
ledger_t() {
|
||||
journal_t() {
|
||||
master = new account_t(NULL, "");
|
||||
master->ident = 0;
|
||||
account_t::next_ident = 1;
|
||||
}
|
||||
|
||||
~ledger_t();
|
||||
~journal_t();
|
||||
|
||||
void add_account(account_t * acct) {
|
||||
master->add_account(acct);
|
||||
|
|
@ -186,7 +186,7 @@ class ledger_t
|
|||
account_t * find_account(const std::string& name) const {
|
||||
// With auto_create false, the other `find_account' will not
|
||||
// change the object.
|
||||
return const_cast<ledger_t *>(this)->find_account(name, false);
|
||||
return const_cast<journal_t *>(this)->find_account(name, false);
|
||||
}
|
||||
|
||||
bool add_entry(entry_t * entry);
|
||||
|
|
@ -195,7 +195,21 @@ class ledger_t
|
|||
entry_t * derive_entry(int argc, char **argv) const;
|
||||
};
|
||||
|
||||
int parse_ledger_file(char * p, ledger_t * journal);
|
||||
int parse_journal_file(char * p, journal_t * journal);
|
||||
|
||||
unsigned int parse_textual_journal(std::istream& in, journal_t * ledger,
|
||||
account_t * master = NULL);
|
||||
|
||||
extern unsigned long binary_magic_number;
|
||||
|
||||
unsigned int read_binary_journal(std::istream& in,
|
||||
const std::string& leader,
|
||||
journal_t * journal,
|
||||
account_t * master = NULL);
|
||||
|
||||
void write_binary_journal(std::ostream& out,
|
||||
journal_t * journal,
|
||||
const std::string& leader);
|
||||
|
||||
extern const std::string version;
|
||||
|
||||
|
|
|
|||
125
main.cc
125
main.cc
|
|
@ -1,7 +1,5 @@
|
|||
#include "ledger.h"
|
||||
#include "error.h"
|
||||
#include "textual.h"
|
||||
#include "binary.h"
|
||||
#include "valexpr.h"
|
||||
#include "format.h"
|
||||
#include "walk.h"
|
||||
|
|
@ -350,11 +348,13 @@ static void show_help(std::ostream& out)
|
|||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
std::auto_ptr<ledger::ledger_t> journal(new ledger::ledger_t);
|
||||
std::list<std::string> files;
|
||||
std::auto_ptr<ledger::node_t> predicate;
|
||||
std::auto_ptr<ledger::node_t> display_predicate;
|
||||
std::auto_ptr<ledger::node_t> sort_order;
|
||||
using namespace ledger;
|
||||
|
||||
std::auto_ptr<journal_t> journal(new journal_t);
|
||||
std::list<std::string> files;
|
||||
std::auto_ptr<node_t> predicate;
|
||||
std::auto_ptr<node_t> display_predicate;
|
||||
std::auto_ptr<node_t> sort_order;
|
||||
|
||||
std::string predicate_string;
|
||||
std::string display_predicate_string;
|
||||
|
|
@ -376,10 +376,10 @@ int main(int argc, char * argv[])
|
|||
// Initialize some variables based on environment variable settings
|
||||
|
||||
if (char * p = std::getenv("PRICE_HIST"))
|
||||
ledger::price_db = p;
|
||||
price_db = p;
|
||||
|
||||
if (char * p = std::getenv("PRICE_EXP"))
|
||||
ledger::pricing_leeway = std::atol(p) * 60;
|
||||
pricing_leeway = std::atol(p) * 60;
|
||||
|
||||
// A ledger data file must be specified
|
||||
|
||||
|
|
@ -392,18 +392,18 @@ int main(int argc, char * argv[])
|
|||
break;
|
||||
}
|
||||
|
||||
ledger::cache_dirty = true;
|
||||
cache_dirty = true;
|
||||
|
||||
if (use_cache)
|
||||
if (const char * p = std::getenv("LEDGER_CACHE"))
|
||||
if (access(p, R_OK) != -1) {
|
||||
std::ifstream instr(p);
|
||||
if (! ledger::read_binary_ledger(instr, std::getenv("LEDGER"),
|
||||
journal.get())) {
|
||||
if (! read_binary_journal(instr, std::getenv("LEDGER"),
|
||||
journal.get())) {
|
||||
// Throw away what's been read, and create a new journal
|
||||
journal.reset(new ledger::ledger_t);
|
||||
journal.reset(new journal_t);
|
||||
} else {
|
||||
ledger::cache_dirty = false;
|
||||
cache_dirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -428,7 +428,7 @@ int main(int argc, char * argv[])
|
|||
|
||||
case 'v':
|
||||
std::cout
|
||||
<< "Ledger " << ledger::version
|
||||
<< "Ledger " << version
|
||||
<< ", the command-line accounting tool" << std::endl
|
||||
<< " Copyright (c) 2003-2004, New Artisans LLC. All rights reserved."
|
||||
<< std::endl << std::endl
|
||||
|
|
@ -445,7 +445,7 @@ int main(int argc, char * argv[])
|
|||
break;
|
||||
|
||||
case 'p':
|
||||
ledger::set_price_conversion(optarg);
|
||||
set_price_conversion(optarg);
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
|
|
@ -536,15 +536,15 @@ int main(int argc, char * argv[])
|
|||
|
||||
// Commodity reporting
|
||||
case 'P':
|
||||
ledger::price_db = optarg;
|
||||
price_db = optarg;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
ledger::pricing_leeway = std::atol(optarg) * 60;
|
||||
pricing_leeway = std::atol(optarg) * 60;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
ledger::commodity_t::updater = ledger::download_price_quote;
|
||||
commodity_t::updater = download_price_quote;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
|
|
@ -566,15 +566,15 @@ int main(int argc, char * argv[])
|
|||
break;
|
||||
|
||||
case 'V':
|
||||
ledger::show_commodities_revalued = true;
|
||||
show_commodities_revalued = true;
|
||||
|
||||
value_expr = "v";
|
||||
total_expr = "V";
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
ledger::show_commodities_revalued =
|
||||
ledger::show_commodities_revalued_only = true;
|
||||
show_commodities_revalued =
|
||||
show_commodities_revalued_only = true;
|
||||
|
||||
value_expr = "c";
|
||||
total_expr = "G";
|
||||
|
|
@ -622,36 +622,36 @@ int main(int argc, char * argv[])
|
|||
|
||||
// Read the ledger file, unless we already read it from the cache
|
||||
|
||||
if (! use_cache || ledger::cache_dirty) {
|
||||
if (! use_cache || cache_dirty) {
|
||||
int entry_count = 0;
|
||||
|
||||
try {
|
||||
if (files.empty()) {
|
||||
if (char * p = std::getenv("LEDGER"))
|
||||
for (p = std::strtok(p, ":"); p; p = std::strtok(NULL, ":"))
|
||||
entry_count += parse_ledger_file(p, journal.get());
|
||||
entry_count += parse_journal_file(p, journal.get());
|
||||
} else {
|
||||
for (std::list<std::string>::iterator i = files.begin();
|
||||
i != files.end(); i++) {
|
||||
char buf[4096];
|
||||
char * p = buf;
|
||||
std::strcpy(p, (*i).c_str());
|
||||
entry_count += parse_ledger_file(p, journal.get());
|
||||
entry_count += parse_journal_file(p, journal.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Read prices from their own ledger file, after all others have
|
||||
// been read.
|
||||
|
||||
if (! ledger::price_db.empty()) {
|
||||
const char * path = ledger::price_db.c_str();
|
||||
if (! price_db.empty()) {
|
||||
const char * path = price_db.c_str();
|
||||
std::ifstream db(path);
|
||||
journal->sources.push_back(path);
|
||||
entry_count += ledger::parse_textual_ledger(db, journal.get(),
|
||||
entry_count += parse_textual_journal(db, journal.get(),
|
||||
journal->master);
|
||||
}
|
||||
}
|
||||
catch (ledger::error& err) {
|
||||
catch (error& err) {
|
||||
std::cerr << "Fatal: " << err.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -685,7 +685,7 @@ int main(int argc, char * argv[])
|
|||
|
||||
// Process the remaining command-line arguments
|
||||
|
||||
std::auto_ptr<ledger::entry_t> new_entry;
|
||||
std::auto_ptr<entry_t> new_entry;
|
||||
if (command == "entry") {
|
||||
new_entry.reset(journal->derive_entry(argc - index, &argv[index]));
|
||||
} else {
|
||||
|
|
@ -770,7 +770,7 @@ int main(int argc, char * argv[])
|
|||
if (debug)
|
||||
std::cerr << "predicate = " << predicate_string << std::endl;
|
||||
#endif
|
||||
predicate.reset(ledger::parse_expr(predicate_string));
|
||||
predicate.reset(parse_expr(predicate_string));
|
||||
}
|
||||
|
||||
if (display_predicate_string.empty() && command == "b" && ! show_empty)
|
||||
|
|
@ -782,18 +782,18 @@ int main(int argc, char * argv[])
|
|||
std::cerr << "display predicate = " << display_predicate_string
|
||||
<< std::endl;
|
||||
#endif
|
||||
display_predicate.reset(ledger::parse_expr(display_predicate_string));
|
||||
display_predicate.reset(parse_expr(display_predicate_string));
|
||||
}
|
||||
|
||||
// Compile the sorting string
|
||||
|
||||
if (! sort_string.empty())
|
||||
sort_order.reset(ledger::parse_expr(sort_string));
|
||||
sort_order.reset(parse_expr(sort_string));
|
||||
|
||||
// Setup the meaning of %t and %T encountered in format strings
|
||||
|
||||
ledger::format_t::value_expr.reset(ledger::parse_expr(value_expr));
|
||||
ledger::format_t::total_expr.reset(ledger::parse_expr(total_expr));
|
||||
format_t::value_expr.reset(parse_expr(value_expr));
|
||||
format_t::total_expr.reset(parse_expr(total_expr));
|
||||
|
||||
// Now handle the command that was identified above.
|
||||
|
||||
|
|
@ -812,26 +812,24 @@ int main(int argc, char * argv[])
|
|||
if (! format_string.empty())
|
||||
f = format_string.c_str();
|
||||
else if (command == "b")
|
||||
f = ledger::bal_fmt.c_str();
|
||||
f = bal_fmt.c_str();
|
||||
else if (command == "r")
|
||||
f = ledger::reg_fmt.c_str();
|
||||
f = reg_fmt.c_str();
|
||||
else
|
||||
f = ledger::print_fmt.c_str();
|
||||
f = print_fmt.c_str();
|
||||
|
||||
if (command == "b") {
|
||||
std::auto_ptr<ledger::format_t> format(new ledger::format_t(f));
|
||||
|
||||
ledger::walk_accounts(journal->master,
|
||||
ledger::format_account(std::cout, *format.get()),
|
||||
predicate.get(), show_related, show_inverted,
|
||||
show_subtotals, display_predicate.get());
|
||||
format_t format(f);
|
||||
walk_accounts(journal->master, format_account(std::cout, format),
|
||||
predicate.get(), show_related, show_inverted,
|
||||
show_subtotals, display_predicate.get());
|
||||
|
||||
if (! display_predicate.get() ||
|
||||
ledger::item_predicate(display_predicate.get())(journal->master)) {
|
||||
item_predicate(display_predicate.get())(journal->master)) {
|
||||
std::string end_format = "--------------------\n";
|
||||
end_format += f;
|
||||
format.get()->elements.reset(ledger::format_t::parse_elements(end_format));
|
||||
ledger::format_account(std::cout, *format.get())(journal->master, true);
|
||||
format.elements = format_t::parse_elements(end_format);
|
||||
format_account(std::cout, format)(journal->master, true);
|
||||
}
|
||||
} else {
|
||||
std::string first_line_format;
|
||||
|
|
@ -844,27 +842,34 @@ int main(int argc, char * argv[])
|
|||
first_line_format = next_lines_format = f;
|
||||
}
|
||||
|
||||
std::auto_ptr<ledger::format_t>
|
||||
format(new ledger::format_t(first_line_format));
|
||||
std::auto_ptr<ledger::format_t>
|
||||
nformat(new ledger::format_t(next_lines_format));
|
||||
format_t format(first_line_format);
|
||||
format_t nformat(next_lines_format);
|
||||
format_transaction formatter(std::cout, format, nformat);
|
||||
|
||||
ledger::walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||
ledger::format_transaction(std::cout,
|
||||
first_line_format,
|
||||
next_lines_format),
|
||||
predicate.get(), show_related, show_inverted,
|
||||
display_predicate.get());
|
||||
if (! sort_order.get()) {
|
||||
walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||
formatter, predicate.get(), show_related, show_inverted,
|
||||
display_predicate.get());
|
||||
} else {
|
||||
transactions_deque transactions_pool;
|
||||
walk_entries(journal->entries.begin(), journal->entries.end(),
|
||||
collect_transactions(transactions_pool), predicate.get(),
|
||||
show_related, show_inverted, display_predicate.get());
|
||||
std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
|
||||
compare_transactions(sort_order.get()));
|
||||
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
|
||||
formatter, NULL, show_related, show_inverted,
|
||||
display_predicate.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Save the cache, if need be
|
||||
|
||||
if (use_cache && ledger::cache_dirty)
|
||||
if (use_cache && cache_dirty)
|
||||
if (const char * p = std::getenv("LEDGER_CACHE")) {
|
||||
std::ofstream outstr(p);
|
||||
assert(std::getenv("LEDGER"));
|
||||
ledger::write_binary_ledger(outstr, journal.get(),
|
||||
std::getenv("LEDGER"));
|
||||
write_binary_journal(outstr, journal.get(), std::getenv("LEDGER"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include "textual.h"
|
||||
#include "datetime.h"
|
||||
#include "autoxact.h"
|
||||
#include "valexpr.h"
|
||||
|
|
@ -287,8 +286,8 @@ entry_t * parse_entry(std::istream& in, account_t * master)
|
|||
return curr;
|
||||
}
|
||||
|
||||
unsigned int parse_textual_ledger(std::istream& in, ledger_t * journal,
|
||||
account_t * master)
|
||||
unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
|
||||
account_t * master)
|
||||
{
|
||||
static char line[MAX_LINE + 1];
|
||||
char c;
|
||||
|
|
@ -518,8 +517,8 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t * journal,
|
|||
unsigned int curr_linenum = linenum;
|
||||
std::string curr_path = path;
|
||||
|
||||
count += parse_textual_ledger(stream, journal,
|
||||
account_stack.front());
|
||||
count += parse_textual_journal(stream, journal,
|
||||
account_stack.front());
|
||||
|
||||
linenum = curr_linenum;
|
||||
path = curr_path;
|
||||
|
|
|
|||
13
textual.h
13
textual.h
|
|
@ -1,13 +0,0 @@
|
|||
#ifndef _TEXTUAL_H
|
||||
#define _TEXTUAL_H
|
||||
|
||||
#include "ledger.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
extern unsigned int parse_textual_ledger(std::istream& in, ledger_t * ledger,
|
||||
account_t * master = NULL);
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
#endif // _TEXTUAL_H
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
#include "valexpr.h"
|
||||
#include "error.h"
|
||||
#include "datetime.h"
|
||||
#include "textual.h"
|
||||
|
||||
#include <pcre.h>
|
||||
|
||||
|
|
|
|||
73
walk.h
73
walk.h
|
|
@ -7,6 +7,7 @@
|
|||
#include "valexpr.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -84,7 +85,45 @@ class format_transaction
|
|||
void operator()(transaction_t * xact,
|
||||
balance_pair_t * balance,
|
||||
unsigned int * index,
|
||||
const bool inverted) const;
|
||||
const bool inverted) const;
|
||||
};
|
||||
|
||||
struct compare_transactions {
|
||||
const node_t * sort_order;
|
||||
|
||||
compare_transactions(const node_t * _sort_order)
|
||||
: sort_order(_sort_order) {
|
||||
assert(sort_order);
|
||||
}
|
||||
|
||||
bool operator()(const transaction_t * left,
|
||||
const transaction_t * right) const {
|
||||
assert(left);
|
||||
assert(right);
|
||||
balance_t left_result;
|
||||
sort_order->compute(left_result, details_t(left));
|
||||
balance_t right_result;
|
||||
sort_order->compute(right_result, details_t(right));
|
||||
return left_result < right_result;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::deque<transaction_t *> transactions_deque;
|
||||
|
||||
class collect_transactions
|
||||
{
|
||||
transactions_deque& transactions;
|
||||
|
||||
public:
|
||||
collect_transactions(transactions_deque& _transactions)
|
||||
: transactions(_transactions) {}
|
||||
|
||||
void operator()(transaction_t * xact,
|
||||
balance_pair_t * balance,
|
||||
unsigned int * index,
|
||||
const bool inverted) {
|
||||
transactions.push_back(xact);
|
||||
}
|
||||
};
|
||||
|
||||
class ignore_transaction
|
||||
|
|
@ -153,6 +192,38 @@ void walk_entries(entries_list::iterator begin,
|
|||
related, inverted, &balance, &index);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_transactions(transactions_list::iterator begin,
|
||||
transactions_list::iterator end,
|
||||
Function functor,
|
||||
const node_t * predicate,
|
||||
const bool related,
|
||||
const bool inverted,
|
||||
const node_t * display_predicate = NULL)
|
||||
{
|
||||
balance_pair_t balance;
|
||||
unsigned int index;
|
||||
|
||||
for (transactions_list::iterator i = begin; i != end; i++)
|
||||
functor(*i, &balance, &index, inverted);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
void walk_transactions(transactions_deque::iterator begin,
|
||||
transactions_deque::iterator end,
|
||||
Function functor,
|
||||
const node_t * predicate,
|
||||
const bool related,
|
||||
const bool inverted,
|
||||
const node_t * display_predicate = NULL)
|
||||
{
|
||||
balance_pair_t balance;
|
||||
unsigned int index;
|
||||
|
||||
for (transactions_deque::iterator i = begin; i != end; i++)
|
||||
functor(*i, &balance, &index, inverted);
|
||||
}
|
||||
|
||||
class format_account
|
||||
{
|
||||
std::ostream& output_stream;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue