more cleanup
This commit is contained in:
parent
3edf298633
commit
cd8f61fb2d
6 changed files with 125 additions and 61 deletions
|
|
@ -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++) {
|
||||
|
|
|
|||
13
datetime.h
13
datetime.h
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
81
main.cc
|
|
@ -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
|
||||
|
|
|
|||
2
walk.cc
2
walk.cc
|
|
@ -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
83
walk.h
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue