*** empty log message ***
This commit is contained in:
parent
32bdfe20d9
commit
c8ebf53ed8
6 changed files with 154 additions and 104 deletions
73
amount.cc
73
amount.cc
|
|
@ -496,39 +496,50 @@ int amount_t::sign() const
|
||||||
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
|
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// comparisons between amounts
|
int amount_t::compare(const amount_t& amt) const
|
||||||
#define AMOUNT_CMP_AMOUNT(OP) \
|
{
|
||||||
bool amount_t::operator OP(const amount_t& amt) const \
|
if (! quantity) {
|
||||||
{ \
|
if (! amt.quantity)
|
||||||
if (! quantity) \
|
return 0;
|
||||||
return amt OP 0; \
|
return - amt.sign();
|
||||||
if (! amt.quantity) \
|
}
|
||||||
return *this OP 0; \
|
if (! amt.quantity)
|
||||||
\
|
return sign();
|
||||||
if (commodity() && amt.commodity() && \
|
|
||||||
commodity() != amt.commodity()) \
|
if (commodity() && amt.commodity() &&
|
||||||
return false; \
|
commodity() != amt.commodity())
|
||||||
\
|
throw new amount_error
|
||||||
if (quantity->prec == amt.quantity->prec) { \
|
(std::string("Cannot compare amounts with different commodities: ") +
|
||||||
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity)) OP 0; \
|
commodity().symbol() + " and " + amt.commodity().symbol());
|
||||||
} \
|
|
||||||
else if (quantity->prec < amt.quantity->prec) { \
|
if (quantity->prec == amt.quantity->prec) {
|
||||||
amount_t temp = *this; \
|
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity));
|
||||||
temp._resize(amt.quantity->prec); \
|
}
|
||||||
return mpz_cmp(MPZ(temp.quantity), MPZ(amt.quantity)) OP 0; \
|
else if (quantity->prec < amt.quantity->prec) {
|
||||||
} \
|
amount_t temp = *this;
|
||||||
else { \
|
temp._resize(amt.quantity->prec);
|
||||||
amount_t temp = amt; \
|
return mpz_cmp(MPZ(temp.quantity), MPZ(amt.quantity));
|
||||||
temp._resize(quantity->prec); \
|
}
|
||||||
return mpz_cmp(MPZ(quantity), MPZ(temp.quantity)) OP 0; \
|
else {
|
||||||
} \
|
amount_t temp = amt;
|
||||||
|
temp._resize(quantity->prec);
|
||||||
|
return mpz_cmp(MPZ(quantity), MPZ(temp.quantity));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AMOUNT_CMP_AMOUNT(<)
|
bool amount_t::operator==(const amount_t& amt) const
|
||||||
AMOUNT_CMP_AMOUNT(<=)
|
{
|
||||||
AMOUNT_CMP_AMOUNT(>)
|
if (commodity() != amt.commodity())
|
||||||
AMOUNT_CMP_AMOUNT(>=)
|
return false;
|
||||||
AMOUNT_CMP_AMOUNT(==)
|
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
|
amount_t::operator bool() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
24
amount.h
24
amount.h
|
|
@ -202,16 +202,22 @@ class amount_t
|
||||||
bool realzero() const;
|
bool realzero() const;
|
||||||
|
|
||||||
// comparisons between amounts
|
// comparisons between amounts
|
||||||
bool operator<(const amount_t& amt) const;
|
int compare(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;
|
return compare(amt) < 0;
|
||||||
bool operator==(const amount_t& amt) const;
|
|
||||||
bool operator!=(const amount_t& amt) const {
|
|
||||||
if (commodity_ != amt.commodity_)
|
|
||||||
return true;
|
|
||||||
return ! (*this == amt);
|
|
||||||
}
|
}
|
||||||
|
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>
|
template <typename T>
|
||||||
void parse_num(T num) {
|
void parse_num(T num) {
|
||||||
|
|
|
||||||
44
config.cc
44
config.cc
|
|
@ -163,6 +163,8 @@ void config_t::reset()
|
||||||
keep_price = false;
|
keep_price = false;
|
||||||
keep_date = false;
|
keep_date = false;
|
||||||
keep_tag = false;
|
keep_tag = false;
|
||||||
|
entry_sort = false;
|
||||||
|
sort_all = false;
|
||||||
|
|
||||||
use_cache = false;
|
use_cache = false;
|
||||||
cache_dirty = 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_price = keep_price;
|
||||||
amount_t::keep_date = keep_date;
|
amount_t::keep_date = keep_date;
|
||||||
amount_t::keep_tag = keep_tag;
|
amount_t::keep_tag = keep_tag;
|
||||||
|
|
||||||
|
if (! report_period.empty() && ! sort_all)
|
||||||
|
entry_sort = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
item_handler<transaction_t> *
|
item_handler<transaction_t> *
|
||||||
|
|
@ -463,9 +468,14 @@ config_t::chain_xact_handlers(const std::string& command,
|
||||||
|
|
||||||
// sort_transactions will sort all the transactions it sees, based
|
// sort_transactions will sort all the transactions it sees, based
|
||||||
// on the `sort_order' value expression.
|
// on the `sort_order' value expression.
|
||||||
if (! sort_string.empty())
|
if (! sort_string.empty()) {
|
||||||
|
if (entry_sort)
|
||||||
|
ptrs.push_back(formatter =
|
||||||
|
new sort_entries(formatter, sort_string));
|
||||||
|
else
|
||||||
ptrs.push_back(formatter =
|
ptrs.push_back(formatter =
|
||||||
new sort_transactions(formatter, sort_string));
|
new sort_transactions(formatter, sort_string));
|
||||||
|
}
|
||||||
|
|
||||||
// changed_value_transactions adds virtual transactions to the
|
// changed_value_transactions adds virtual transactions to the
|
||||||
// list to account for changes in market value of commodities,
|
// list to account for changes in market value of commodities,
|
||||||
|
|
@ -480,7 +490,6 @@ config_t::chain_xact_handlers(const std::string& command,
|
||||||
// commodity used.
|
// commodity used.
|
||||||
if (show_collapsed)
|
if (show_collapsed)
|
||||||
ptrs.push_back(formatter = new collapse_transactions(formatter));
|
ptrs.push_back(formatter = new collapse_transactions(formatter));
|
||||||
}
|
|
||||||
|
|
||||||
// subtotal_transactions combines all the transactions it receives
|
// subtotal_transactions combines all the transactions it receives
|
||||||
// into one subtotal entry, which has one transaction for each
|
// into one subtotal entry, which has one transaction for each
|
||||||
|
|
@ -493,7 +502,7 @@ config_t::chain_xact_handlers(const std::string& command,
|
||||||
// dow_transactions is like period_transactions, except that it
|
// dow_transactions is like period_transactions, except that it
|
||||||
// reports all the transactions that fall on each subsequent day
|
// reports all the transactions that fall on each subsequent day
|
||||||
// of the week.
|
// of the week.
|
||||||
if (show_subtotal && ! (command == "b" || command == "E"))
|
if (show_subtotal)
|
||||||
ptrs.push_back(formatter =
|
ptrs.push_back(formatter =
|
||||||
new subtotal_transactions(formatter, remember_components));
|
new subtotal_transactions(formatter, remember_components));
|
||||||
|
|
||||||
|
|
@ -504,14 +513,15 @@ config_t::chain_xact_handlers(const std::string& command,
|
||||||
ptrs.push_back(formatter =
|
ptrs.push_back(formatter =
|
||||||
new by_payee_transactions(formatter, remember_components));
|
new by_payee_transactions(formatter, remember_components));
|
||||||
|
|
||||||
|
// interval_transactions groups transactions together based on a
|
||||||
|
// time period, such as weekly or monthly.
|
||||||
if (! report_period.empty()) {
|
if (! report_period.empty()) {
|
||||||
ptrs.push_back(formatter =
|
ptrs.push_back(formatter =
|
||||||
new interval_transactions(formatter,
|
new interval_transactions(formatter, report_period,
|
||||||
report_period,
|
|
||||||
report_period_sort,
|
|
||||||
remember_components));
|
remember_components));
|
||||||
ptrs.push_back(formatter = new sort_transactions(formatter, "d"));
|
ptrs.push_back(formatter = new sort_transactions(formatter, "d"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// invert_transactions inverts the value of the transactions it
|
// invert_transactions inverts the value of the transactions it
|
||||||
// receives.
|
// receives.
|
||||||
|
|
@ -1037,6 +1047,22 @@ OPT_BEGIN(sort, "S:") {
|
||||||
config->sort_string = optarg;
|
config->sort_string = optarg;
|
||||||
} OPT_END(sort);
|
} 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") {
|
OPT_BEGIN(related, "r") {
|
||||||
config->show_related = true;
|
config->show_related = true;
|
||||||
} OPT_END(related);
|
} OPT_END(related);
|
||||||
|
|
@ -1096,10 +1122,6 @@ OPT_BEGIN(period, "p:") {
|
||||||
}
|
}
|
||||||
} OPT_END(period);
|
} OPT_END(period);
|
||||||
|
|
||||||
OPT_BEGIN(period_sort, ":") {
|
|
||||||
config->report_period_sort = optarg;
|
|
||||||
} OPT_END(period_sort);
|
|
||||||
|
|
||||||
OPT_BEGIN(daily, "") {
|
OPT_BEGIN(daily, "") {
|
||||||
if (config->report_period.empty())
|
if (config->report_period.empty())
|
||||||
config->report_period = "daily";
|
config->report_period = "daily";
|
||||||
|
|
@ -1392,6 +1414,8 @@ option_t config_options[CONFIG_OPTIONS_SIZE] = {
|
||||||
{ "related", 'r', false, opt_related, false },
|
{ "related", 'r', false, opt_related, false },
|
||||||
{ "set-price", '\0', true, opt_set_price, false },
|
{ "set-price", '\0', true, opt_set_price, false },
|
||||||
{ "sort", 'S', true, opt_sort, 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 },
|
{ "subtotal", 's', false, opt_subtotal, false },
|
||||||
{ "tail", '\0', true, opt_tail, false },
|
{ "tail", '\0', true, opt_tail, false },
|
||||||
{ "total", 'T', true, opt_total, false },
|
{ "total", 'T', true, opt_total, false },
|
||||||
|
|
|
||||||
4
config.h
4
config.h
|
|
@ -74,6 +74,8 @@ class config_t
|
||||||
bool keep_price;
|
bool keep_price;
|
||||||
bool keep_date;
|
bool keep_date;
|
||||||
bool keep_tag;
|
bool keep_tag;
|
||||||
|
bool entry_sort;
|
||||||
|
bool sort_all;
|
||||||
|
|
||||||
config_t() {
|
config_t() {
|
||||||
reset();
|
reset();
|
||||||
|
|
@ -107,7 +109,7 @@ class config_t
|
||||||
std::list<item_handler<transaction_t> *>& ptrs);
|
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];
|
extern option_t config_options[CONFIG_OPTIONS_SIZE];
|
||||||
|
|
||||||
void option_help(std::ostream& out);
|
void option_help(std::ostream& out);
|
||||||
|
|
|
||||||
3
walk.cc
3
walk.cc
|
|
@ -439,9 +439,6 @@ void interval_transactions::report_subtotal(const std::time_t moment)
|
||||||
|
|
||||||
subtotal_transactions::report_subtotal();
|
subtotal_transactions::report_subtotal();
|
||||||
|
|
||||||
if (sorter)
|
|
||||||
sorter->post_accumulated_xacts();
|
|
||||||
|
|
||||||
last_xact = NULL;
|
last_xact = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
56
walk.h
56
walk.h
|
|
@ -252,7 +252,7 @@ class sort_transactions : public item_handler<transaction_t>
|
||||||
sort_transactions(item_handler<transaction_t> * handler,
|
sort_transactions(item_handler<transaction_t> * handler,
|
||||||
const value_expr_t * _sort_order)
|
const value_expr_t * _sort_order)
|
||||||
: item_handler<transaction_t>(handler),
|
: item_handler<transaction_t>(handler),
|
||||||
sort_order(_sort_order) {}
|
sort_order(_sort_order->acquire()) {}
|
||||||
|
|
||||||
sort_transactions(item_handler<transaction_t> * handler,
|
sort_transactions(item_handler<transaction_t> * handler,
|
||||||
const std::string& _sort_order)
|
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>
|
class filter_transactions : public item_handler<transaction_t>
|
||||||
{
|
{
|
||||||
item_predicate<transaction_t> pred;
|
item_predicate<transaction_t> pred;
|
||||||
|
|
@ -492,37 +521,18 @@ class interval_transactions : public subtotal_transactions
|
||||||
transaction_t * last_xact;
|
transaction_t * last_xact;
|
||||||
bool started;
|
bool started;
|
||||||
|
|
||||||
sort_transactions * sorter;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
interval_transactions(item_handler<transaction_t> * _handler,
|
interval_transactions(item_handler<transaction_t> * _handler,
|
||||||
const interval_t& _interval,
|
const interval_t& _interval,
|
||||||
const value_expr_t * sort_order = NULL,
|
|
||||||
bool remember_components = false)
|
bool remember_components = false)
|
||||||
: subtotal_transactions(_handler, remember_components),
|
: subtotal_transactions(_handler, remember_components),
|
||||||
interval(_interval), last_xact(NULL), started(false),
|
interval(_interval), last_xact(NULL), started(false) {}
|
||||||
sorter(NULL) {
|
|
||||||
if (sort_order) {
|
|
||||||
sorter = new sort_transactions(handler, sort_order);
|
|
||||||
handler = sorter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
interval_transactions(item_handler<transaction_t> * _handler,
|
interval_transactions(item_handler<transaction_t> * _handler,
|
||||||
const std::string& _interval,
|
const std::string& _interval,
|
||||||
const std::string& sort_order = "",
|
|
||||||
bool remember_components = false)
|
bool remember_components = false)
|
||||||
: subtotal_transactions(_handler, remember_components),
|
: subtotal_transactions(_handler, remember_components),
|
||||||
interval(_interval), last_xact(NULL), started(false),
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void report_subtotal(const std::time_t moment = 0);
|
void report_subtotal(const std::time_t moment = 0);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue