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 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) bool parse_date_mask(const char * date_str, struct std::tm * result)
{ {
for (const char ** f = formats; *f; f++) { for (const char ** f = formats; *f; f++) {

View file

@ -5,6 +5,19 @@
namespace ledger { 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_mask(const char * date_str, struct std::tm * result);
extern bool parse_date(const char * date_str, std::time_t * 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': case 'd':
current->type = element_t::DATE_STRING; current->type = element_t::DATE_STRING;
// jww (2004-08-10): allow this to be changed
current->chars = "%Y/%m/%d"; current->chars = "%Y/%m/%d";
break; break;

81
main.cc
View file

@ -174,8 +174,8 @@ int main(int argc, char * argv[])
bool show_inverted = false; bool show_inverted = false;
bool show_empty = false; bool show_empty = false;
bool show_commodities_revalued = false; bool show_revalued = false;
bool show_commodities_revalued_only = false; bool show_revalued_only = false;
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (char * p = std::getenv("DEBUG_FILE")) { if (char * p = std::getenv("DEBUG_FILE")) {
@ -362,15 +362,15 @@ int main(int argc, char * argv[])
break; break;
case 'V': case 'V':
show_commodities_revalued = true; show_revalued = true;
value_expr = "v"; value_expr = "v";
total_expr = "V"; total_expr = "V";
break; break;
case 'G': case 'G':
show_commodities_revalued = show_revalued =
show_commodities_revalued_only = true; show_revalued_only = true;
value_expr = "c"; value_expr = "c";
total_expr = "G"; total_expr = "G";
@ -615,37 +615,62 @@ int main(int argc, char * argv[])
handle_transaction(*i, formatter, xact_display_flags); handle_transaction(*i, formatter, xact_display_flags);
} }
else { else {
std::auto_ptr<item_handler<transaction_t> > std::auto_ptr<item_handler<transaction_t> > formatter;
formatter(new format_transactions(std::cout, format, nformat));
// 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(), formatter.reset(new filter_transactions(formatter.release(),
display_predicate)); 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) if (! show_subtotals)
formatter.reset(new collapse_transactions(formatter.release())); 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) if (show_expanded)
formatter.reset(new subtotal_transactions(formatter.release())); formatter.reset(new subtotal_transactions(formatter.release()));
#if 0 else if (0)
formatter.reset(new interval_transactions(formatter.release(), formatter.reset(new interval_transactions(formatter.release(), 0,
0, 0, 9676800)); interval_t(9676800, 0, 0)));
#endif
if (show_commodities_revalued)
formatter.reset(new changed_value_transactions(formatter.release()));
if (! sort_order.get()) { // Once the filters are chained, walk `journal's entries and start
walk_entries(journal->entries.begin(), journal->entries.end(), // feeding each transaction that matches `predicate' to the chain.
*formatter.get(), predicate, xact_display_flags); walk_entries(journal->entries.begin(), journal->entries.end(),
} else { *formatter.get(), predicate, xact_display_flags);
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());
}
} }
// Save the cache, if need be // Save the cache, if need be

View file

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

83
walk.h
View file

@ -4,6 +4,7 @@
#include "ledger.h" #include "ledger.h"
#include "balance.h" #include "balance.h"
#include "valexpr.h" #include "valexpr.h"
#include "datetime.h"
#include <iostream> #include <iostream>
#include <deque> #include <deque>
@ -50,26 +51,43 @@ struct ignore_transaction : public item_handler<transaction_t>
virtual void operator()(transaction_t * xact) {} 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: public:
collect_transactions(transactions_deque& _transactions) sort_transactions(item_handler<transaction_t> * _handler,
: transactions(_transactions) {} 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) { virtual void operator()(transaction_t * xact) {
transactions.push_back(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> class filter_transactions : public item_handler<transaction_t>
{ {
item_predicate<transaction_t> pred; 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> class subtotal_transactions : public item_handler<transaction_t>
{ {
protected:
std::time_t start; std::time_t start;
std::time_t finish; std::time_t finish;
balances_map balances; balances_map balances;
@ -238,39 +257,39 @@ class subtotal_transactions : public item_handler<transaction_t>
virtual void operator()(transaction_t * xact); virtual void operator()(transaction_t * xact);
}; };
class interval_transactions : public item_handler<transaction_t> class interval_transactions : public subtotal_transactions
{ {
std::time_t start; std::time_t begin;
unsigned long months; interval_t interval;
unsigned long seconds;
transaction_t * last_xact; transaction_t * last_xact;
item_handler<transaction_t> * handler;
public: public:
interval_transactions(item_handler<transaction_t> * _handler, interval_transactions(item_handler<transaction_t> * _handler,
std::time_t _start, unsigned long _months, std::time_t _begin, const interval_t& _interval)
unsigned long _seconds) : subtotal_transactions(_handler),
: start(_start), months(_months), seconds(_seconds), begin(_begin), interval(_interval), last_xact(NULL) {}
last_xact(NULL), handler(_handler) {}
virtual ~interval_transactions() { virtual ~interval_transactions() {
flush(); start = begin;
finish = interval.increment(begin);
} }
virtual void flush() {
handler->flush();
}
virtual void operator()(transaction_t * xact) { virtual void operator()(transaction_t * xact) {
if (std::difftime(xact->entry->date, start + seconds) > 0) { if (std::difftime(xact->entry->date, interval.increment(begin)) > 0) {
if (last_xact) if (last_xact) {
handler->flush(); start = begin;
start += seconds; finish = interval.increment(begin);
while (std::difftime(xact->entry->date, start + seconds) > 0) flush();
start += seconds; }
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; last_xact = xact;
} }