summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datetime.cc6
-rw-r--r--datetime.h13
-rw-r--r--format.cc1
-rw-r--r--main.cc83
-rw-r--r--walk.cc2
-rw-r--r--walk.h83
6 files changed, 126 insertions, 62 deletions
diff --git a/datetime.cc b/datetime.cc
index 19f54f92..71393ebf 100644
--- a/datetime.cc
+++ b/datetime.cc
@@ -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++) {
diff --git a/datetime.h b/datetime.h
index 6c9d001a..8e2ffbbd 100644
--- a/datetime.h
+++ b/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,
diff --git a/format.cc b/format.cc
index a5c73b2a..3f59807b 100644
--- a/format.cc
+++ b/format.cc
@@ -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;
diff --git a/main.cc b/main.cc
index b71f1d9b..84bba1e5 100644
--- a/main.cc
+++ b/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()));
-
- 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());
- }
+ else if (0)
+ formatter.reset(new interval_transactions(formatter.release(), 0,
+ interval_t(9676800, 0, 0)));
+
+ // 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
diff --git a/walk.cc b/walk.cc
index bbc56604..0b0a71e2 100644
--- a/walk.cc
+++ b/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
diff --git a/walk.h b/walk.h
index 351a866d..f5e48beb 100644
--- a/walk.h
+++ b/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;
}