more cleanup

This commit is contained in:
John Wiegley 2004-08-11 03:23:19 -04:00
parent 3edf298633
commit cd8f61fb2d
6 changed files with 125 additions and 61 deletions

View file

@ -29,6 +29,12 @@ static const char * formats[] = {
NULL
};
std::time_t interval_t::increment(const std::time_t moment)
{
// jww (2004-08-11): NYI
return moment + seconds;
}
bool parse_date_mask(const char * date_str, struct std::tm * result)
{
for (const char ** f = formats; *f; f++) {

View file

@ -5,6 +5,19 @@
namespace ledger {
struct interval_t
{
unsigned long years;
unsigned long months;
unsigned long seconds;
interval_t(unsigned long _seconds, unsigned long _months,
unsigned long _years)
: years(_years), months(_months), seconds(_seconds) {}
std::time_t increment(const std::time_t);
};
extern bool parse_date_mask(const char * date_str, struct std::tm * result);
extern bool parse_date(const char * date_str, std::time_t * result,

View file

@ -116,6 +116,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
case 'd':
current->type = element_t::DATE_STRING;
// jww (2004-08-10): allow this to be changed
current->chars = "%Y/%m/%d";
break;

81
main.cc
View file

@ -174,8 +174,8 @@ int main(int argc, char * argv[])
bool show_inverted = false;
bool show_empty = false;
bool show_commodities_revalued = false;
bool show_commodities_revalued_only = false;
bool show_revalued = false;
bool show_revalued_only = false;
#ifdef DEBUG_ENABLED
if (char * p = std::getenv("DEBUG_FILE")) {
@ -362,15 +362,15 @@ int main(int argc, char * argv[])
break;
case 'V':
show_commodities_revalued = true;
show_revalued = true;
value_expr = "v";
total_expr = "V";
break;
case 'G':
show_commodities_revalued =
show_commodities_revalued_only = true;
show_revalued =
show_revalued_only = true;
value_expr = "c";
total_expr = "G";
@ -615,37 +615,62 @@ int main(int argc, char * argv[])
handle_transaction(*i, formatter, xact_display_flags);
}
else {
std::auto_ptr<item_handler<transaction_t> >
formatter(new format_transactions(std::cout, format, nformat));
std::auto_ptr<item_handler<transaction_t> > formatter;
// Stack up all the formatter needed to fulfills the user's
// requests. Some of these are order dependent, in terms of
// whether calc_transactions occurs before or after them.
// format_transactions write each transaction received to the
// output stream.
formatter.reset(new format_transactions(std::cout, format, nformat));
// sort_transactions will sort all the transactions it sees, based
// on the `sort_order' value expression.
if (sort_order.get())
formatter.reset(new sort_transactions(formatter.release(),
sort_order.get()));
// filter_transactions will only pass through transactions
// matching the `display_predicate'.
formatter.reset(new filter_transactions(formatter.release(),
display_predicate));
formatter.reset(new calc_transactions(formatter.release(),
show_inverted));
// calc_transactions computes the running total. When this
// appears will determine, for example, whether filtered
// transactions are included or excluded from the running total.
formatter.reset(new calc_transactions(formatter.release(), show_inverted));
// changed_value_transactions adds virtual transactions to the
// list to account for changes in market value of commodities,
// which otherwise would affect the running total unpredictably.
if (show_revalued)
formatter.reset(new changed_value_transactions(formatter.release() /*,
show_revalued_only*/));
// collapse_transactions causes entries with multiple transactions
// to appear as entries with a subtotaled transaction for each
// commodity used.
if (! show_subtotals)
formatter.reset(new collapse_transactions(formatter.release()));
// subtotal_transactions combines all the transactions it receives
// into one subtotal entry, which has one transaction for each
// commodity in each account.
//
// interval_transactions is like subtotal_transactions, but it
// subtotals according to time intervals rather than totalling
// everything.
if (show_expanded)
formatter.reset(new subtotal_transactions(formatter.release()));
#if 0
formatter.reset(new interval_transactions(formatter.release(),
0, 0, 9676800));
#endif
if (show_commodities_revalued)
formatter.reset(new changed_value_transactions(formatter.release()));
else if (0)
formatter.reset(new interval_transactions(formatter.release(), 0,
interval_t(9676800, 0, 0)));
if (! sort_order.get()) {
walk_entries(journal->entries.begin(), journal->entries.end(),
*formatter.get(), predicate, xact_display_flags);
} else {
transactions_deque transactions_pool;
collect_transactions handler(transactions_pool);
walk_entries(journal->entries.begin(), journal->entries.end(),
handler, predicate, xact_display_flags);
std::stable_sort(transactions_pool.begin(), transactions_pool.end(),
compare_items<transaction_t>(sort_order.get()));
walk_transactions(transactions_pool.begin(), transactions_pool.end(),
*formatter.get());
}
// Once the filters are chained, walk `journal's entries and start
// feeding each transaction that matches `predicate' to the chain.
walk_entries(journal->entries.begin(), journal->entries.end(),
*formatter.get(), predicate, xact_display_flags);
}
// Save the cache, if need be

View file

@ -92,7 +92,7 @@ void changed_value_transactions::operator()(transaction_t * xact)
void subtotal_transactions::flush()
{
entry_t * entry = new entry_t;
entry->date = start;
entry->date = start;
char buf[256];
// jww (2004-08-10): allow for a format string here

83
walk.h
View file

@ -4,6 +4,7 @@
#include "ledger.h"
#include "balance.h"
#include "valexpr.h"
#include "datetime.h"
#include <iostream>
#include <deque>
@ -50,26 +51,43 @@ struct ignore_transaction : public item_handler<transaction_t>
virtual void operator()(transaction_t * xact) {}
};
class collect_transactions : public item_handler<transaction_t>
class sort_transactions : public item_handler<transaction_t>
{
transactions_deque& transactions;
transactions_deque transactions;
const node_t * sort_order;
item_handler<transaction_t> * handler;
public:
collect_transactions(transactions_deque& _transactions)
: transactions(_transactions) {}
sort_transactions(item_handler<transaction_t> * _handler,
const node_t * _sort_order)
: sort_order(_sort_order), handler(_handler) {}
virtual ~sort_transactions() {
flush();
handler->flush();
delete handler;
}
virtual void flush() {
std::stable_sort(transactions.begin(), transactions.end(),
compare_items<transaction_t>(sort_order));
for (transactions_deque::iterator i = transactions.begin();
i != transactions.end();
i++)
(*handler)(*i);
transactions.clear();
handler->flush();
}
virtual void operator()(transaction_t * xact) {
transactions.push_back(xact);
}
};
inline void sort_transactions(transactions_deque& transactions,
const node_t * sort_order)
{
std::stable_sort(transactions.begin(), transactions.end(),
compare_items<transaction_t>(sort_order));
}
class filter_transactions : public item_handler<transaction_t>
{
item_predicate<transaction_t> pred;
@ -205,6 +223,7 @@ typedef std::pair<account_t *, balance_pair_t> balances_pair;
class subtotal_transactions : public item_handler<transaction_t>
{
protected:
std::time_t start;
std::time_t finish;
balances_map balances;
@ -238,39 +257,39 @@ class subtotal_transactions : public item_handler<transaction_t>
virtual void operator()(transaction_t * xact);
};
class interval_transactions : public item_handler<transaction_t>
class interval_transactions : public subtotal_transactions
{
std::time_t start;
unsigned long months;
unsigned long seconds;
std::time_t begin;
interval_t interval;
transaction_t * last_xact;
item_handler<transaction_t> * handler;
public:
interval_transactions(item_handler<transaction_t> * _handler,
std::time_t _start, unsigned long _months,
unsigned long _seconds)
: start(_start), months(_months), seconds(_seconds),
last_xact(NULL), handler(_handler) {}
std::time_t _begin, const interval_t& _interval)
: subtotal_transactions(_handler),
begin(_begin), interval(_interval), last_xact(NULL) {}
virtual ~interval_transactions() {
flush();
start = begin;
finish = interval.increment(begin);
}
virtual void flush() {
handler->flush();
}
virtual void operator()(transaction_t * xact) {
if (std::difftime(xact->entry->date, start + seconds) > 0) {
if (last_xact)
handler->flush();
start += seconds;
while (std::difftime(xact->entry->date, start + seconds) > 0)
start += seconds;
if (std::difftime(xact->entry->date, interval.increment(begin)) > 0) {
if (last_xact) {
start = begin;
finish = interval.increment(begin);
flush();
}
begin = interval.increment(begin);
std::time_t temp;
while (std::difftime(xact->entry->date,
temp = interval.increment(begin)) > 0)
begin = temp;
}
(*handler)(xact);
subtotal_transactions::operator()(xact);
last_xact = xact;
}