*** empty log message ***

This commit is contained in:
John Wiegley 2006-03-19 23:16:31 +00:00
parent 32bdfe20d9
commit c8ebf53ed8
6 changed files with 154 additions and 104 deletions

View file

@ -496,39 +496,50 @@ int amount_t::sign() const
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
}
// comparisons between amounts
#define AMOUNT_CMP_AMOUNT(OP) \
bool amount_t::operator OP(const amount_t& amt) const \
{ \
if (! quantity) \
return amt OP 0; \
if (! amt.quantity) \
return *this OP 0; \
\
if (commodity() && amt.commodity() && \
commodity() != amt.commodity()) \
return false; \
\
if (quantity->prec == amt.quantity->prec) { \
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity)) OP 0; \
} \
else if (quantity->prec < amt.quantity->prec) { \
amount_t temp = *this; \
temp._resize(amt.quantity->prec); \
return mpz_cmp(MPZ(temp.quantity), MPZ(amt.quantity)) OP 0; \
} \
else { \
amount_t temp = amt; \
temp._resize(quantity->prec); \
return mpz_cmp(MPZ(quantity), MPZ(temp.quantity)) OP 0; \
} \
int amount_t::compare(const amount_t& amt) const
{
if (! quantity) {
if (! amt.quantity)
return 0;
return - amt.sign();
}
if (! amt.quantity)
return sign();
if (commodity() && amt.commodity() &&
commodity() != amt.commodity())
throw new amount_error
(std::string("Cannot compare amounts with different commodities: ") +
commodity().symbol() + " and " + amt.commodity().symbol());
if (quantity->prec == amt.quantity->prec) {
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity));
}
else if (quantity->prec < amt.quantity->prec) {
amount_t temp = *this;
temp._resize(amt.quantity->prec);
return mpz_cmp(MPZ(temp.quantity), MPZ(amt.quantity));
}
else {
amount_t temp = amt;
temp._resize(quantity->prec);
return mpz_cmp(MPZ(quantity), MPZ(temp.quantity));
}
}
AMOUNT_CMP_AMOUNT(<)
AMOUNT_CMP_AMOUNT(<=)
AMOUNT_CMP_AMOUNT(>)
AMOUNT_CMP_AMOUNT(>=)
AMOUNT_CMP_AMOUNT(==)
bool amount_t::operator==(const amount_t& amt) const
{
if (commodity() != amt.commodity())
return false;
return compare(amt) == 0;
}
bool amount_t::operator!=(const amount_t& amt) const
{
if (commodity() != amt.commodity())
return true;
return compare(amt) != 0;
}
amount_t::operator bool() const
{

View file

@ -202,16 +202,22 @@ class amount_t
bool realzero() const;
// comparisons between amounts
bool operator<(const amount_t& amt) const;
bool operator<=(const amount_t& amt) const;
bool operator>(const amount_t& amt) const;
bool operator>=(const amount_t& amt) const;
bool operator==(const amount_t& amt) const;
bool operator!=(const amount_t& amt) const {
if (commodity_ != amt.commodity_)
return true;
return ! (*this == amt);
int compare(const amount_t& amt) const;
bool operator<(const amount_t& amt) const {
return compare(amt) < 0;
}
bool operator<=(const amount_t& amt) const {
return compare(amt) <= 0;
}
bool operator>(const amount_t& amt) const {
return compare(amt) > 0;
}
bool operator>=(const amount_t& amt) const {
return compare(amt) >= 0;
}
bool operator==(const amount_t& amt) const;
bool operator!=(const amount_t& amt) const;
template <typename T>
void parse_num(T num) {

View file

@ -163,6 +163,8 @@ void config_t::reset()
keep_price = false;
keep_date = false;
keep_tag = false;
entry_sort = false;
sort_all = false;
use_cache = false;
cache_dirty = false;
@ -381,6 +383,9 @@ void config_t::process_options(const std::string& command,
amount_t::keep_price = keep_price;
amount_t::keep_date = keep_date;
amount_t::keep_tag = keep_tag;
if (! report_period.empty() && ! sort_all)
entry_sort = true;
}
item_handler<transaction_t> *
@ -451,7 +456,7 @@ config_t::chain_xact_handlers(const std::string& command,
parse_date(reconcile_date.c_str(), &cutoff);
ptrs.push_back(formatter =
new reconcile_transactions
(formatter, value_t(reconcile_balance), cutoff));
(formatter, value_t(reconcile_balance), cutoff));
}
// filter_transactions will only pass through transactions
@ -463,9 +468,14 @@ config_t::chain_xact_handlers(const std::string& command,
// sort_transactions will sort all the transactions it sees, based
// on the `sort_order' value expression.
if (! sort_string.empty())
ptrs.push_back(formatter =
new sort_transactions(formatter, sort_string));
if (! sort_string.empty()) {
if (entry_sort)
ptrs.push_back(formatter =
new sort_entries(formatter, sort_string));
else
ptrs.push_back(formatter =
new sort_transactions(formatter, sort_string));
}
// changed_value_transactions adds virtual transactions to the
// list to account for changes in market value of commodities,
@ -480,37 +490,37 @@ config_t::chain_xact_handlers(const std::string& command,
// commodity used.
if (show_collapsed)
ptrs.push_back(formatter = new collapse_transactions(formatter));
}
// subtotal_transactions combines all the transactions it receives
// into one subtotal entry, which has one transaction for each
// commodity in each account.
//
// period_transactions is like subtotal_transactions, but it
// subtotals according to time periods rather than totalling
// everything.
//
// dow_transactions is like period_transactions, except that it
// reports all the transactions that fall on each subsequent day
// of the week.
if (show_subtotal && ! (command == "b" || command == "E"))
ptrs.push_back(formatter =
new subtotal_transactions(formatter, remember_components));
// subtotal_transactions combines all the transactions it receives
// into one subtotal entry, which has one transaction for each
// commodity in each account.
//
// period_transactions is like subtotal_transactions, but it
// subtotals according to time periods rather than totalling
// everything.
//
// dow_transactions is like period_transactions, except that it
// reports all the transactions that fall on each subsequent day
// of the week.
if (show_subtotal)
ptrs.push_back(formatter =
new subtotal_transactions(formatter, remember_components));
if (days_of_the_week)
ptrs.push_back(formatter =
new dow_transactions(formatter, remember_components));
else if (by_payee)
ptrs.push_back(formatter =
new by_payee_transactions(formatter, remember_components));
if (days_of_the_week)
ptrs.push_back(formatter =
new dow_transactions(formatter, remember_components));
else if (by_payee)
ptrs.push_back(formatter =
new by_payee_transactions(formatter, remember_components));
if (! report_period.empty()) {
ptrs.push_back(formatter =
new interval_transactions(formatter,
report_period,
report_period_sort,
remember_components));
ptrs.push_back(formatter = new sort_transactions(formatter, "d"));
// interval_transactions groups transactions together based on a
// time period, such as weekly or monthly.
if (! report_period.empty()) {
ptrs.push_back(formatter =
new interval_transactions(formatter, report_period,
remember_components));
ptrs.push_back(formatter = new sort_transactions(formatter, "d"));
}
}
// invert_transactions inverts the value of the transactions it
@ -1037,6 +1047,22 @@ OPT_BEGIN(sort, "S:") {
config->sort_string = optarg;
} OPT_END(sort);
OPT_BEGIN(sort_entries, "") {
config->sort_string = optarg;
config->entry_sort = true;
} OPT_END(sort_entries);
OPT_BEGIN(sort_all, "") {
config->sort_string = optarg;
config->entry_sort = false;
config->sort_all = true;
} OPT_END(sort_all);
OPT_BEGIN(period_sort, ":") {
config->sort_string = optarg;
config->entry_sort = true;
} OPT_END(period_sort);
OPT_BEGIN(related, "r") {
config->show_related = true;
} OPT_END(related);
@ -1096,10 +1122,6 @@ OPT_BEGIN(period, "p:") {
}
} OPT_END(period);
OPT_BEGIN(period_sort, ":") {
config->report_period_sort = optarg;
} OPT_END(period_sort);
OPT_BEGIN(daily, "") {
if (config->report_period.empty())
config->report_period = "daily";
@ -1392,6 +1414,8 @@ option_t config_options[CONFIG_OPTIONS_SIZE] = {
{ "related", 'r', false, opt_related, false },
{ "set-price", '\0', true, opt_set_price, false },
{ "sort", 'S', true, opt_sort, false },
{ "sort-all", '\0', true, opt_sort_all, false },
{ "sort-entries", '\0', true, opt_sort_entries, false },
{ "subtotal", 's', false, opt_subtotal, false },
{ "tail", '\0', true, opt_tail, false },
{ "total", 'T', true, opt_total, false },

View file

@ -74,6 +74,8 @@ class config_t
bool keep_price;
bool keep_date;
bool keep_tag;
bool entry_sort;
bool sort_all;
config_t() {
reset();
@ -107,7 +109,7 @@ class config_t
std::list<item_handler<transaction_t> *>& ptrs);
};
#define CONFIG_OPTIONS_SIZE 91
#define CONFIG_OPTIONS_SIZE 93
extern option_t config_options[CONFIG_OPTIONS_SIZE];
void option_help(std::ostream& out);

View file

@ -439,9 +439,6 @@ void interval_transactions::report_subtotal(const std::time_t moment)
subtotal_transactions::report_subtotal();
if (sorter)
sorter->post_accumulated_xacts();
last_xact = NULL;
}

58
walk.h
View file

@ -252,7 +252,7 @@ class sort_transactions : public item_handler<transaction_t>
sort_transactions(item_handler<transaction_t> * handler,
const value_expr_t * _sort_order)
: item_handler<transaction_t>(handler),
sort_order(_sort_order) {}
sort_order(_sort_order->acquire()) {}
sort_transactions(item_handler<transaction_t> * handler,
const std::string& _sort_order)
@ -278,6 +278,35 @@ class sort_transactions : public item_handler<transaction_t>
}
};
class sort_entries : public item_handler<transaction_t>
{
sort_transactions sorter;
entry_t * last_entry;
public:
sort_entries(item_handler<transaction_t> * handler,
const value_expr_t * _sort_order)
: sorter(handler, _sort_order) {}
sort_entries(item_handler<transaction_t> * handler,
const std::string& _sort_order)
: sorter(handler, _sort_order) {}
virtual void flush() {
sorter.flush();
item_handler<transaction_t>::flush();
}
virtual void operator()(transaction_t& xact) {
if (last_entry && xact.entry != last_entry)
sorter.post_accumulated_xacts();
sorter(xact);
last_entry = xact.entry;
}
};
class filter_transactions : public item_handler<transaction_t>
{
item_predicate<transaction_t> pred;
@ -492,37 +521,18 @@ class interval_transactions : public subtotal_transactions
transaction_t * last_xact;
bool started;
sort_transactions * sorter;
public:
interval_transactions(item_handler<transaction_t> * _handler,
const interval_t& _interval,
const value_expr_t * sort_order = NULL,
const interval_t& _interval,
bool remember_components = false)
: subtotal_transactions(_handler, remember_components),
interval(_interval), last_xact(NULL), started(false),
sorter(NULL) {
if (sort_order) {
sorter = new sort_transactions(handler, sort_order);
handler = sorter;
}
}
interval(_interval), last_xact(NULL), started(false) {}
interval_transactions(item_handler<transaction_t> * _handler,
const std::string& _interval,
const std::string& sort_order = "",
bool remember_components = false)
: subtotal_transactions(_handler, remember_components),
interval(_interval), last_xact(NULL), started(false),
sorter(NULL) {
if (! sort_order.empty()) {
sorter = new sort_transactions(handler, sort_order);
handler = sorter;
}
}
virtual ~interval_transactions() {
if (sorter)
delete sorter;
}
interval(_interval), last_xact(NULL), started(false) {}
void report_subtotal(const std::time_t moment = 0);