From fc62402c60cd3faac37f3cd60ee417d119869929 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Feb 2012 00:08:39 -0600 Subject: Fixed nasty problem related to interval reporting --- src/filters.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 331073eb..f57f37e7 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -924,7 +924,7 @@ void interval_posts::operator()(post_t& post) report_subtotal(last_interval); if (generate_empty_posts) { - for (++last_interval; interval != last_interval; ++last_interval) { + for (++last_interval; last_interval < interval; ++last_interval) { // Generate a null posting, so the intervening periods can be // seen when -E is used, or if the calculated amount ends up being // non-zero @@ -940,7 +940,7 @@ void interval_posts::operator()(post_t& post) report_subtotal(last_interval); } - assert(interval == last_interval); + assert(last_interval <= interval); } else { last_interval = interval; } -- cgit v1.2.3 From 887f429ae40934c145e03b03cc452e6af4457c0f Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Feb 2012 01:37:29 -0600 Subject: Added debug code for debugging interval reports --- src/filters.cc | 22 ++++++++++++++++++---- src/filters.h | 31 +++++++++++++++++++++++++++---- src/times.cc | 11 +++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index f57f37e7..fbef1cd8 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -916,11 +916,24 @@ void interval_posts::report_subtotal(const date_interval_t& ival) void interval_posts::operator()(post_t& post) { - if (! interval.find_period(post.date())) + DEBUG("filters.interval", "Considering post with amount " << post.amount); +#if defined(DEBUG_ON) + DEBUG("filters.interval", "interval is:"); + debug_interval(interval); +#endif + if (! interval.find_period(post.date())) { + DEBUG("filters.interval", "Post does not fall within period"); return; + } if (interval.duration) { - if (last_interval && interval != last_interval) { + DEBUG("filters.interval", "There is an interval duration"); + if (interval != last_interval) { +#if defined(DEBUG_ON) + DEBUG("filters.interval", "interval != last_interval, so reporting"); + DEBUG("filters.interval", "last_interval is:"); + debug_interval(last_interval); +#endif report_subtotal(last_interval); if (generate_empty_posts) { @@ -942,13 +955,14 @@ void interval_posts::operator()(post_t& post) } assert(last_interval <= interval); } else { + DEBUG("filters.interval", "Setting last_interval = interval"); last_interval = interval; } - } else { - last_interval = interval; } + DEBUG("filters.interval", "Calling subtotal_posts::operator()"); subtotal_posts::operator()(post); } else { + DEBUG("filters.interval", "There is no interval duration"); item_handler::operator()(post); } diff --git a/src/filters.h b/src/filters.h index d207d842..2e51c91c 100644 --- a/src/filters.h +++ b/src/filters.h @@ -728,21 +728,44 @@ public: empty_account = &temps.create_account(_("")); } - void report_subtotal(const date_interval_t& interval); + void report_subtotal(const date_interval_t& ival); + +#if defined(DEBUG_ON) + void debug_interval(const date_interval_t& ival) { + if (ival.start) + DEBUG("filters.interval", "start = " << *ival.start); + else + DEBUG("filters.interval", "no start"); + + if (ival.finish) + DEBUG("filters.interval", "finish = " << *ival.finish); + else + DEBUG("filters.interval", "no finish"); + } +#endif virtual void flush() { if (last_post && interval.duration) { - if (last_interval && interval != last_interval) + DEBUG("filters.interval", "There is a last_post and an interval.duration"); + if (interval != last_interval) { +#if defined(DEBUG_ON) + DEBUG("filters.interval", "interval != last_interval, so reporting"); + DEBUG("filters.interval", "interval is:"); + debug_interval(interval); + DEBUG("filters.interval", "last_interval is:"); + debug_interval(last_interval); +#endif report_subtotal(last_interval); + } subtotal_posts::flush(); } } virtual void operator()(post_t& post); virtual void clear() { - interval = start_interval; + interval = start_interval; last_interval = date_interval_t(); - last_post = NULL; + last_post = NULL; subtotal_posts::clear(); create_accounts(); diff --git a/src/times.cc b/src/times.cc index 0384edf6..dd10a508 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1397,8 +1397,17 @@ bool date_interval_t::find_period(const date_t& date) DEBUG("times.interval", "date = " << date); DEBUG("times.interval", "scan = " << scan); DEBUG("times.interval", "end_of_scan = " << end_of_scan); +#if defined(DEBUG_ON) + if (finish) + DEBUG("times.interval", "finish = " << *finish); + else + DEBUG("times.interval", "finish is not set"); +#endif while (date >= scan && (! finish || scan < *finish)) { + DEBUG("times.interval", "date = " << date); + DEBUG("times.interval", "end_of_scan = " << end_of_scan); + if (date < end_of_scan) { start = scan; end_of_duration = end_of_scan; @@ -1416,6 +1425,8 @@ bool date_interval_t::find_period(const date_t& date) end_of_scan = duration->add(scan); } + DEBUG("times.interval", "false: failed scan"); + return false; } -- cgit v1.2.3 From 6adfcc8469e3d526f4bcb0971b49efb490ad6401 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 28 Feb 2012 02:34:37 -0600 Subject: Rewrite the way interval reports are generated --- src/chain.cc | 4 +- src/filters.cc | 129 ++++++---- src/filters.h | 38 +-- src/times.cc | 14 +- src/times.h | 12 +- test/baseline/opt-period.test | 2 +- test/regress/F06D5554.test | 552 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 663 insertions(+), 88 deletions(-) create mode 100644 test/regress/F06D5554.test (limited to 'src/filters.cc') diff --git a/src/chain.cc b/src/chain.cc index 450e3758..61388840 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -217,13 +217,11 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler, // interval_posts groups posts together based on a time period, such as // weekly or monthly. - if (report.HANDLED(period_)) { + if (report.HANDLED(period_)) handler.reset(new interval_posts(handler, expr, report.HANDLER(period_).str(), report.HANDLED(exact), report.HANDLED(empty))); - handler.reset(new sort_posts(handler, "date")); - } if (report.HANDLED(date_)) handler.reset(new transfer_details(handler, transfer_details::SET_DATE, diff --git a/src/filters.cc b/src/filters.cc index fbef1cd8..fa1f6fa2 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -904,69 +904,104 @@ void subtotal_posts::operator()(post_t& post) void interval_posts::report_subtotal(const date_interval_t& ival) { - if (last_post && ival) { - if (exact_periods) - subtotal_posts::report_subtotal(); - else - subtotal_posts::report_subtotal(NULL, ival); - } + if (exact_periods) + subtotal_posts::report_subtotal(); + else + subtotal_posts::report_subtotal(NULL, ival); +} - last_post = NULL; +namespace { + struct sort_posts_by_date { + bool operator()(post_t * left, post_t * right) const { + return left->date() < right->date(); + } + }; } void interval_posts::operator()(post_t& post) { - DEBUG("filters.interval", "Considering post with amount " << post.amount); -#if defined(DEBUG_ON) - DEBUG("filters.interval", "interval is:"); - debug_interval(interval); -#endif - if (! interval.find_period(post.date())) { - DEBUG("filters.interval", "Post does not fall within period"); + // If there is a duration (such as weekly), we must generate the + // report in two passes. Otherwise, we only have to check whether the + // post falls within the reporting period. + + if (interval.duration) { + all_posts.push_back(&post); + } + else if (interval.find_period(post.date())) + item_handler::operator()(post); +} + +void interval_posts::flush() +{ + if (! interval.duration) { + item_handler::flush(); return; } - if (interval.duration) { - DEBUG("filters.interval", "There is an interval duration"); - if (interval != last_interval) { -#if defined(DEBUG_ON) - DEBUG("filters.interval", "interval != last_interval, so reporting"); - DEBUG("filters.interval", "last_interval is:"); - debug_interval(last_interval); -#endif - report_subtotal(last_interval); + // Sort all the postings we saw by date ascending + std::stable_sort(all_posts.begin(), all_posts.end(), + sort_posts_by_date()); - if (generate_empty_posts) { - for (++last_interval; last_interval < interval; ++last_interval) { - // Generate a null posting, so the intervening periods can be - // seen when -E is used, or if the calculated amount ends up being - // non-zero - xact_t& null_xact = temps.create_xact(); - null_xact._date = last_interval.inclusive_end(); + // Determine the beginning interval by using the earliest post + if (! interval.find_period(all_posts.front()->date())) + throw_(std::logic_error, _("Failed to find period for interval report")); - post_t& null_post = temps.create_post(null_xact, empty_account); - null_post.add_flags(POST_CALCULATED); - null_post.amount = 0L; + // Walk the interval forward reporting all posts within each one + // before moving on, until we reach the end of all_posts + bool saw_posts = false; + for (std::deque::iterator i = all_posts.begin(); + i != all_posts.end(); ) { + post_t * post(*i); - last_post = &null_post; - subtotal_posts::operator()(null_post); + DEBUG("filters.interval", + "Considering post " << post->date() << " = " << post->amount); +#if defined(DEBUG_ON) + DEBUG("filters.interval", "interval is:"); + debug_interval(interval); +#endif + assert(! interval.finish || post->date() < *interval.finish); - report_subtotal(last_interval); - } - assert(last_interval <= interval); - } else { - DEBUG("filters.interval", "Setting last_interval = interval"); - last_interval = interval; + if (interval.within_period(post->date())) { + DEBUG("filters.interval", "Calling subtotal_posts::operator()"); + subtotal_posts::operator()(*post); + ++i; + saw_posts = true; + } else { + if (saw_posts) { + DEBUG("filters.interval", + "Calling subtotal_posts::report_subtotal()"); + report_subtotal(interval); + saw_posts = false; } + else if (generate_empty_posts) { + // Generate a null posting, so the intervening periods can be + // seen when -E is used, or if the calculated amount ends up + // being non-zero + xact_t& null_xact = temps.create_xact(); + null_xact._date = interval.inclusive_end(); + + post_t& null_post = temps.create_post(null_xact, empty_account); + null_post.add_flags(POST_CALCULATED); + null_post.amount = 0L; + + subtotal_posts::operator()(null_post); + report_subtotal(interval); + } + + DEBUG("filters.interval", "Advancing interval"); + ++interval; } - DEBUG("filters.interval", "Calling subtotal_posts::operator()"); - subtotal_posts::operator()(post); - } else { - DEBUG("filters.interval", "There is no interval duration"); - item_handler::operator()(post); } - last_post = &post; + // If the last postings weren't reported, do so now. + if (saw_posts) { + DEBUG("filters.interval", + "Calling subtotal_posts::report_subtotal() at end"); + report_subtotal(interval); + } + + // Tell our parent class to flush + subtotal_posts::flush(); } void posts_as_equity::report_subtotal() diff --git a/src/filters.h b/src/filters.h index 2e51c91c..c972de82 100644 --- a/src/filters.h +++ b/src/filters.h @@ -655,11 +655,11 @@ protected: typedef std::pair values_pair; protected: - expr_t& amount_expr; - values_map values; - optional date_format; - temporaries_t temps; - std::list component_posts; + expr_t& amount_expr; + values_map values; + optional date_format; + temporaries_t temps; + std::deque component_posts; public: subtotal_posts(post_handler_ptr handler, expr_t& _amount_expr, @@ -697,12 +697,12 @@ class interval_posts : public subtotal_posts { date_interval_t start_interval; date_interval_t interval; - date_interval_t last_interval; - post_t * last_post; account_t * empty_account; bool exact_periods; bool generate_empty_posts; + std::deque all_posts; + interval_posts(); public: @@ -713,8 +713,7 @@ public: bool _exact_periods = false, bool _generate_empty_posts = false) : subtotal_posts(_handler, amount_expr), start_interval(_interval), - interval(start_interval), last_post(NULL), - exact_periods(_exact_periods), + interval(start_interval), exact_periods(_exact_periods), generate_empty_posts(_generate_empty_posts) { TRACE_CTOR(interval_posts, "post_handler_ptr, expr_t&, date_interval_t, bool, bool"); @@ -744,28 +743,11 @@ public: } #endif - virtual void flush() { - if (last_post && interval.duration) { - DEBUG("filters.interval", "There is a last_post and an interval.duration"); - if (interval != last_interval) { -#if defined(DEBUG_ON) - DEBUG("filters.interval", "interval != last_interval, so reporting"); - DEBUG("filters.interval", "interval is:"); - debug_interval(interval); - DEBUG("filters.interval", "last_interval is:"); - debug_interval(last_interval); -#endif - report_subtotal(last_interval); - } - subtotal_posts::flush(); - } - } virtual void operator()(post_t& post); + virtual void flush(); virtual void clear() { - interval = start_interval; - last_interval = date_interval_t(); - last_post = NULL; + interval = start_interval; subtotal_posts::clear(); create_accounts(); diff --git a/src/times.cc b/src/times.cc index dd10a508..9712c2ee 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1305,7 +1305,7 @@ void date_interval_t::stabilize(const optional& date) date_interval_t next_interval(*this); ++next_interval; - if (next_interval.start && *next_interval.start < *date) { + if (next_interval.start && *next_interval.start <= *date) { *this = next_interval; } else { end_of_duration = none; @@ -1355,7 +1355,8 @@ void date_interval_t::stabilize(const optional& date) } } -bool date_interval_t::find_period(const date_t& date) +bool date_interval_t::find_period(const date_t& date, + const bool allow_shift) { stabilize(date); @@ -1405,9 +1406,6 @@ bool date_interval_t::find_period(const date_t& date) #endif while (date >= scan && (! finish || scan < *finish)) { - DEBUG("times.interval", "date = " << date); - DEBUG("times.interval", "end_of_scan = " << end_of_scan); - if (date < end_of_scan) { start = scan; end_of_duration = end_of_scan; @@ -1420,9 +1418,15 @@ bool date_interval_t::find_period(const date_t& date) return true; } + else if (! allow_shift) { + break; + } scan = duration->add(scan); end_of_scan = duration->add(scan); + + DEBUG("times.interval", "scan = " << scan); + DEBUG("times.interval", "end_of_scan = " << end_of_scan); } DEBUG("times.interval", "false: failed scan"); diff --git a/src/times.h b/src/times.h index a2680ae3..bc462efa 100644 --- a/src/times.h +++ b/src/times.h @@ -578,10 +578,14 @@ public: return start; } - /** Find the current or next period containing date. Returns true if the - date_interval_t object has been altered to reflect the interval - containing date, or false if no such period can be found. */ - bool find_period(const date_t& date = CURRENT_DATE()); + /** Find the current or next period containing date. Returns false if + no such period can be found. If allow_shift is true, the default, + then the interval may be shifted in time to find the period. */ + bool find_period(const date_t& date = CURRENT_DATE(), + const bool allow_shift = true); + bool within_period(const date_t& date = CURRENT_DATE()) { + return find_period(date, false); + } optional inclusive_end() const { if (end_of_duration) diff --git a/test/baseline/opt-period.test b/test/baseline/opt-period.test index 7268bcce..f370b404 100644 --- a/test/baseline/opt-period.test +++ b/test/baseline/opt-period.test @@ -257,7 +257,7 @@ test reg -p "weekly january 2008" 08-Jan-01 - 08-Jan-05 Assets:Cash $-20.00 $-20.00 Expenses:Books $10.00 $-10.00 Liabilities:Cards $10.00 0 -08-Jan-29 - 08-Jan-31 Assets:Cash $-20.00 $-20.00 +08-Jan-27 - 08-Jan-31 Assets:Cash $-20.00 $-20.00 Expenses:Books $10.00 $-10.00 Liabilities:Cards $10.00 0 end test diff --git a/test/regress/F06D5554.test b/test/regress/F06D5554.test new file mode 100644 index 00000000..4541b791 --- /dev/null +++ b/test/regress/F06D5554.test @@ -0,0 +1,552 @@ +2011/04/01 serveraxis.com + Expenses:Computer:Internet $15.00 + Expenses:Computer:Internet $1.10 + Liabilities:MasterCard + +2011/04/05 Pennsylvania toll booth + Expenses:Auto:Fees $13.00 + Expenses:Cash + +2011/04/05 iTunes + Expenses:Music $1.29 + Expenses:Taxes:Sales $0.09 + Liabilities:MasterCard $-1.38 + +2011/04/19 iTunes + Expenses:Computer:Software $4.99 + Expenses:Taxes:Sales $0.35 + Liabilities:MasterCard $-5.34 + +2011/04/24 iTunes + Expenses:Movies $1.99 + Expenses:Movies $2.99 + Expenses:Taxes:Sales $0.35 + Liabilities:MasterCard $-5.33 + +2011/04/29 iTunes + Expenses:Computer:Movies $0.99 + Expenses:Taxes:Sales $0.07 + Liabilities:MasterCard $-1.06 + +2011/05/01 serveraxis.com + Expenses:Computer:Internet $15.00 + Expenses:Computer:Internet $1.10 + Liabilities:MasterCard + +2011/05/18 iTunes + Expenses:Computer:Software $6.99 + Expenses:Taxes:Sales $0.49 + Liabilities:MasterCard $-7.48 + +2011/05/20 DynDNS.com + Expenses:Computer:Internet $15.00 + Liabilities:MasterCard + +2011/05/20 DynDNS.com + Expenses:Computer:Internet $15.00 + Liabilities:MasterCard + +2011/05/27 iTunes + Expenses:Movies $1.99 + Expenses:Movies $1.99 + Expenses:Movies $1.99 + Expenses:Taxes:Sales $0.42 + Liabilities:MasterCard $-6.39 + +2011/05/26 Valero + Expenses:Auto:Gas $26.79 + Liabilities:MasterCard + +2011/05/26 Starbucks + Expenses:Food $2.20 + Expenses:Taxes:Sales $0.15 + Liabilities:MasterCard $-2.35 + +2011/05/26 La Mex + Expenses:Food $17.70 + Expenses:Taxes:Sales $1.11 + Expenses:Tips $3.00 + Liabilities:MasterCard $-21.81 + +2011/05/27 Leaves N Beans + Expenses:Food:Dining $20.98 + Expenses:Taxes:Sales $1.63 + Expenses:Tips $2.00 + Liabilities:MasterCard $-24.61 + +2011/05/27 Wal*Mart + Expenses:Home:Supplies $7.97 + Expenses:Food:Grocery $3.25 + Expenses:Food:Grocery $3.18 + Expenses:Food:Grocery $3.18 + Expenses:Food:Grocery $2.98 + Expenses:Food:Grocery $1.98 + Expenses:Food:Grocery $3.98 + Expenses:Food:Grocery $3.58 + Expenses:Food:Grocery $3.58 + Expenses:Food:Grocery $1.58 + Expenses:Food:Grocery $1.88 + Expenses:Food:Grocery $2.50 + Expenses:Food:Grocery $1.26 + Expenses:Food:Grocery $2.62 + Expenses:Food:Grocery $3.48 + Expenses:Home:Supplies $1.37 + Expenses:Home:Supplies $2.92 + Expenses:Beauty $3.38 + Expenses:Beauty $0.97 + Expenses:Beauty $4.64 + Expenses:Beauty $1.97 + Expenses:Beauty $1.97 + Expenses:Beauty $5.98 + Expenses:Home:Supplies $9.98 + Expenses:Bedding $4.00 + Expenses:Bedding $4.00 + Expenses:Home:Supplies $2.88 + Expenses:Home:Supplies $2.88 + Expenses:Home:Supplies $2.88 + Expenses:Home:Supplies $2.88 + Expenses:Clothing $2.96 + Expenses:Supplies $0.84 + Expenses:Food:Grocery $1.38 + Expenses:Food:Grocery $1.38 + Expenses:Food:Grocery $2.32 + Expenses:Food:Grocery $2.00 + Expenses:Food:Grocery $2.98 + Expenses:Food:Grocery $3.00 + Expenses:Food:Grocery $2.14 + Expenses:Food:Grocery $2.14 + Expenses:Food:Grocery $2.50 + Expenses:Food:Grocery $2.50 + Expenses:Food:Grocery $3.48 + Expenses:Home:Supplies $1.17 + Expenses:Supplies $3.00 + Expenses:Bedding $34.88 + Expenses:Home $6.00 + Expenses:Home $6.00 + Expenses:Home:Supplies $3.97 + Expenses:Food:Grocery $0.78 + Expenses:Food:Grocery $0.78 + Expenses:Food:Grocery $0.78 + Expenses:Food:Grocery $0.78 + Expenses:Home $4.00 + Expenses:Home $4.00 + Expenses:Home $10.87 + Expenses:Home $4.00 + Expenses:Bedding $65.96 + Expenses:Taxes:Sales $16.89 + Expenses:Taxes:Sales $0.65 + Liabilities:MasterCard $-293.83 + +2011/05/27 Asia Grill + Expenses:Food:Dining $28.63 + Expenses:Tips $4.00 + Liabilities:MasterCard $-32.63 + +2011/05/28 Shell + Expenses:Auto:Gas $43.41 + Liabilities:MasterCard + +2011/05/28 Sears + Expenses:Home $1,728.96 + Expenses:Taxes:Sales $136.87 + Liabilities:MasterCard $-1,865.83 + +2011/05/28 Sears + Expenses:Home $99.61 + Expenses:Taxes:Sales $8.22 + Liabilities:MasterCard $-107.83 + +2011/05/28 Buffalo Wild Wings + Expenses:Food:Dining $22.98 + Expenses:Tips $2.35 + Expenses:Taxes:Sales $3.50 + Liabilities:MasterCard $-28.83 + +2011/05/28 Cold Stone Creamery + Expenses:Food:Dining $5.73 + Expenses:Tips $0.50 + Liabilities:MasterCard $-6.23 + +2011/05/29 Hy Vee + Expenses:Supplies $2.00 + Expenses:Supplies $7.99 + Expenses:Supplies $7.99 + Expenses:Food:Grocery $157.64 + Expenses:Taxes:Sales $5.74 + Liabilities:MasterCard $-181.36 + +2011/05/30 Allied movers, Fidel & Manny + Expenses:Tips $97.00 + Expenses:Cash + +2011/05/30 Starbucks + Expenses:Food:Dining $6.90 + Expenses:Taxes:Sales $0.71 + Liabilities:MasterCard $-7.61 + +2011/05/31 Wal*Mart + Expenses:Home $108.13 + Expenses:Taxes:Sales $8.65 + Liabilities:MasterCard $-116.78 + +test reg -p "apr 2011" Expenses +11-Apr-01 serveraxis.com Expe:Computer:Internet $15.00 $15.00 + Expe:Computer:Internet $1.10 $16.10 +11-Apr-05 Pennsylvania toll b.. Expenses:Auto:Fees $13.00 $29.10 + Expenses:Cash $-13.00 $16.10 +11-Apr-05 iTunes Expenses:Music $1.29 $17.39 + Expenses:Taxes:Sales $0.09 $17.48 +11-Apr-19 iTunes Expe:Computer:Software $4.99 $22.47 + Expenses:Taxes:Sales $0.35 $22.82 +11-Apr-24 iTunes Expenses:Movies $1.99 $24.81 + Expenses:Movies $2.99 $27.80 + Expenses:Taxes:Sales $0.35 $28.15 +11-Apr-29 iTunes Expens:Computer:Movies $0.99 $29.14 + Expenses:Taxes:Sales $0.07 $29.21 +end test + +test reg -p "apr 2011" Expenses --monthly +11-Apr-01 - 11-Apr-30 Expenses:Auto:Fees $13.00 $13.00 + Expenses:Cash $-13.00 0 + Expe:Computer:Internet $16.10 $16.10 + Expens:Computer:Movies $0.99 $17.09 + Expe:Computer:Software $4.99 $22.08 + Expenses:Movies $4.98 $27.06 + Expenses:Music $1.29 $28.35 + Expenses:Taxes:Sales $0.86 $29.21 +end test + +test reg -p "apr 2011" Expenses --monthly --exact +11-Apr-01 - 11-Apr-29 Expenses:Auto:Fees $13.00 $13.00 + Expenses:Cash $-13.00 0 + Expe:Computer:Internet $16.10 $16.10 + Expens:Computer:Movies $0.99 $17.09 + Expe:Computer:Software $4.99 $22.08 + Expenses:Movies $4.98 $27.06 + Expenses:Music $1.29 $28.35 + Expenses:Taxes:Sales $0.86 $29.21 +end test + +test reg -p "apr 2011" Expenses --weekly +11-Apr-01 - 11-Apr-02 Expe:Computer:Internet $16.10 $16.10 +11-Apr-03 - 11-Apr-09 Expenses:Auto:Fees $13.00 $29.10 + Expenses:Cash $-13.00 $16.10 + Expenses:Music $1.29 $17.39 + Expenses:Taxes:Sales $0.09 $17.48 +11-Apr-17 - 11-Apr-23 Expe:Computer:Software $4.99 $22.47 + Expenses:Taxes:Sales $0.35 $22.82 +11-Apr-24 - 11-Apr-30 Expens:Computer:Movies $0.99 $23.81 + Expenses:Movies $4.98 $28.79 + Expenses:Taxes:Sales $0.42 $29.21 +end test + +test reg -p "apr 2011" Expenses --weekly --exact +11-Apr-01 - 11-Apr-01 Expe:Computer:Internet $16.10 $16.10 +11-Apr-05 - 11-Apr-05 Expenses:Auto:Fees $13.00 $29.10 + Expenses:Cash $-13.00 $16.10 + Expenses:Music $1.29 $17.39 + Expenses:Taxes:Sales $0.09 $17.48 +11-Apr-19 - 11-Apr-19 Expe:Computer:Software $4.99 $22.47 + Expenses:Taxes:Sales $0.35 $22.82 +11-Apr-24 - 11-Apr-29 Expens:Computer:Movies $0.99 $23.81 + Expenses:Movies $4.98 $28.79 + Expenses:Taxes:Sales $0.42 $29.21 +end test + +test reg -p "apr 2011" Expenses --weekly --empty +11-Apr-01 - 11-Apr-02 Expe:Computer:Internet $16.10 $16.10 +11-Apr-03 - 11-Apr-09 Expenses:Auto:Fees $13.00 $29.10 + Expenses:Cash $-13.00 $16.10 + Expenses:Music $1.29 $17.39 + Expenses:Taxes:Sales $0.09 $17.48 +11-Apr-10 - 11-Apr-16 0 $17.48 +11-Apr-17 - 11-Apr-23 Expe:Computer:Software $4.99 $22.47 + Expenses:Taxes:Sales $0.35 $22.82 +11-Apr-24 - 11-Apr-30 Expens:Computer:Movies $0.99 $23.81 + Expenses:Movies $4.98 $28.79 + Expenses:Taxes:Sales $0.42 $29.21 +end test + +test reg -p "apr 2011" Expenses --weekly --empty --exact +11-Apr-01 - 11-Apr-01 Expe:Computer:Internet $16.10 $16.10 +11-Apr-05 - 11-Apr-05 Expenses:Auto:Fees $13.00 $29.10 + Expenses:Cash $-13.00 $16.10 + Expenses:Music $1.29 $17.39 + Expenses:Taxes:Sales $0.09 $17.48 +11-Apr-16 - 11-Apr-16 0 $17.48 +11-Apr-19 - 11-Apr-19 Expe:Computer:Software $4.99 $22.47 + Expenses:Taxes:Sales $0.35 $22.82 +11-Apr-24 - 11-Apr-29 Expens:Computer:Movies $0.99 $23.81 + Expenses:Movies $4.98 $28.79 + Expenses:Taxes:Sales $0.42 $29.21 +end test + +test reg -p "may 2011" +11-May-01 serveraxis.com Expe:Computer:Internet $15.00 $15.00 + Expe:Computer:Internet $1.10 $16.10 + Liabilities:MasterCard $-16.10 0 +11-May-18 iTunes Expe:Computer:Software $6.99 $6.99 + Expenses:Taxes:Sales $0.49 $7.48 + Liabilities:MasterCard $-7.48 0 +11-May-20 DynDNS.com Expe:Computer:Internet $15.00 $15.00 + Liabilities:MasterCard $-15.00 0 +11-May-20 DynDNS.com Expe:Computer:Internet $15.00 $15.00 + Liabilities:MasterCard $-15.00 0 +11-May-27 iTunes Expenses:Movies $1.99 $1.99 + Expenses:Movies $1.99 $3.98 + Expenses:Movies $1.99 $5.97 + Expenses:Taxes:Sales $0.42 $6.39 + Liabilities:MasterCard $-6.39 0 +11-May-26 Valero Expenses:Auto:Gas $26.79 $26.79 + Liabilities:MasterCard $-26.79 0 +11-May-26 Starbucks Expenses:Food $2.20 $2.20 + Expenses:Taxes:Sales $0.15 $2.35 + Liabilities:MasterCard $-2.35 0 +11-May-26 La Mex Expenses:Food $17.70 $17.70 + Expenses:Taxes:Sales $1.11 $18.81 + Expenses:Tips $3.00 $21.81 + Liabilities:MasterCard $-21.81 0 +11-May-27 Leaves N Beans Expenses:Food:Dining $20.98 $20.98 + Expenses:Taxes:Sales $1.63 $22.61 + Expenses:Tips $2.00 $24.61 + Liabilities:MasterCard $-24.61 0 +11-May-27 Wal*Mart Expenses:Home:Supplies $7.97 $7.97 + Expenses:Food:Grocery $3.25 $11.22 + Expenses:Food:Grocery $3.18 $14.40 + Expenses:Food:Grocery $3.18 $17.58 + Expenses:Food:Grocery $2.98 $20.56 + Expenses:Food:Grocery $1.98 $22.54 + Expenses:Food:Grocery $3.98 $26.52 + Expenses:Food:Grocery $3.58 $30.10 + Expenses:Food:Grocery $3.58 $33.68 + Expenses:Food:Grocery $1.58 $35.26 + Expenses:Food:Grocery $1.88 $37.14 + Expenses:Food:Grocery $2.50 $39.64 + Expenses:Food:Grocery $1.26 $40.90 + Expenses:Food:Grocery $2.62 $43.52 + Expenses:Food:Grocery $3.48 $47.00 + Expenses:Home:Supplies $1.37 $48.37 + Expenses:Home:Supplies $2.92 $51.29 + Expenses:Beauty $3.38 $54.67 + Expenses:Beauty $0.97 $55.64 + Expenses:Beauty $4.64 $60.28 + Expenses:Beauty $1.97 $62.25 + Expenses:Beauty $1.97 $64.22 + Expenses:Beauty $5.98 $70.20 + Expenses:Home:Supplies $9.98 $80.18 + Expenses:Bedding $4.00 $84.18 + Expenses:Bedding $4.00 $88.18 + Expenses:Home:Supplies $2.88 $91.06 + Expenses:Home:Supplies $2.88 $93.94 + Expenses:Home:Supplies $2.88 $96.82 + Expenses:Home:Supplies $2.88 $99.70 + Expenses:Clothing $2.96 $102.66 + Expenses:Supplies $0.84 $103.50 + Expenses:Food:Grocery $1.38 $104.88 + Expenses:Food:Grocery $1.38 $106.26 + Expenses:Food:Grocery $2.32 $108.58 + Expenses:Food:Grocery $2.00 $110.58 + Expenses:Food:Grocery $2.98 $113.56 + Expenses:Food:Grocery $3.00 $116.56 + Expenses:Food:Grocery $2.14 $118.70 + Expenses:Food:Grocery $2.14 $120.84 + Expenses:Food:Grocery $2.50 $123.34 + Expenses:Food:Grocery $2.50 $125.84 + Expenses:Food:Grocery $3.48 $129.32 + Expenses:Home:Supplies $1.17 $130.49 + Expenses:Supplies $3.00 $133.49 + Expenses:Bedding $34.88 $168.37 + Expenses:Home $6.00 $174.37 + Expenses:Home $6.00 $180.37 + Expenses:Home:Supplies $3.97 $184.34 + Expenses:Food:Grocery $0.78 $185.12 + Expenses:Food:Grocery $0.78 $185.90 + Expenses:Food:Grocery $0.78 $186.68 + Expenses:Food:Grocery $0.78 $187.46 + Expenses:Home $4.00 $191.46 + Expenses:Home $4.00 $195.46 + Expenses:Home $10.87 $206.33 + Expenses:Home $4.00 $210.33 + Expenses:Bedding $65.96 $276.29 + Expenses:Taxes:Sales $16.89 $293.18 + Expenses:Taxes:Sales $0.65 $293.83 + Liabilities:MasterCard $-293.83 0 +11-May-27 Asia Grill Expenses:Food:Dining $28.63 $28.63 + Expenses:Tips $4.00 $32.63 + Liabilities:MasterCard $-32.63 0 +11-May-28 Shell Expenses:Auto:Gas $43.41 $43.41 + Liabilities:MasterCard $-43.41 0 +11-May-28 Sears Expenses:Home $1,728.96 $1,728.96 + Expenses:Taxes:Sales $136.87 $1,865.83 + Liabilities:MasterCard $-1,865.83 0 +11-May-28 Sears Expenses:Home $99.61 $99.61 + Expenses:Taxes:Sales $8.22 $107.83 + Liabilities:MasterCard $-107.83 0 +11-May-28 Buffalo Wild Wings Expenses:Food:Dining $22.98 $22.98 + Expenses:Tips $2.35 $25.33 + Expenses:Taxes:Sales $3.50 $28.83 + Liabilities:MasterCard $-28.83 0 +11-May-28 Cold Stone Creamery Expenses:Food:Dining $5.73 $5.73 + Expenses:Tips $0.50 $6.23 + Liabilities:MasterCard $-6.23 0 +11-May-29 Hy Vee Expenses:Supplies $2.00 $2.00 + Expenses:Supplies $7.99 $9.99 + Expenses:Supplies $7.99 $17.98 + Expenses:Food:Grocery $157.64 $175.62 + Expenses:Taxes:Sales $5.74 $181.36 + Liabilities:MasterCard $-181.36 0 +11-May-30 Allied movers, Fide.. Expenses:Tips $97.00 $97.00 + Expenses:Cash $-97.00 0 +11-May-30 Starbucks Expenses:Food:Dining $6.90 $6.90 + Expenses:Taxes:Sales $0.71 $7.61 + Liabilities:MasterCard $-7.61 0 +11-May-31 Wal*Mart Expenses:Home $108.13 $108.13 + Expenses:Taxes:Sales $8.65 $116.78 + Liabilities:MasterCard $-116.78 0 +end test + +test reg -p "may 2011" --monthly +11-May-01 - 11-May-31 Expenses:Auto:Gas $70.20 $70.20 + Expenses:Beauty $18.91 $89.11 + Expenses:Bedding $108.84 $197.95 + Expenses:Cash $-97.00 $100.95 + Expenses:Clothing $2.96 $103.91 + Expe:Computer:Internet $46.10 $150.01 + Expe:Computer:Software $6.99 $157.00 + Expenses:Food $19.90 $176.90 + Expenses:Food:Dining $85.22 $262.12 + Expenses:Food:Grocery $225.61 $487.73 + Expenses:Home $1,971.57 $2,459.30 + Expenses:Home:Supplies $38.90 $2,498.20 + Expenses:Movies $5.97 $2,504.17 + Expenses:Supplies $21.82 $2,525.99 + Expenses:Taxes:Sales $185.03 $2,711.02 + Expenses:Tips $108.85 $2,819.87 + Liabilities:MasterCard $-2,819.87 0 +end test + +test reg -p "may 2011" --weekly +11-May-01 - 11-May-07 Expe:Computer:Internet $16.10 $16.10 + Liabilities:MasterCard $-16.10 0 +11-May-15 - 11-May-21 Expe:Computer:Internet $30.00 $30.00 + Expe:Computer:Software $6.99 $36.99 + Expenses:Taxes:Sales $0.49 $37.48 + Liabilities:MasterCard $-37.48 0 +11-May-22 - 11-May-28 Expenses:Auto:Gas $70.20 $70.20 + Expenses:Beauty $18.91 $89.11 + Expenses:Bedding $108.84 $197.95 + Expenses:Clothing $2.96 $200.91 + Expenses:Food $19.90 $220.81 + Expenses:Food:Dining $78.32 $299.13 + Expenses:Food:Grocery $67.97 $367.10 + Expenses:Home $1,863.44 $2,230.54 + Expenses:Home:Supplies $38.90 $2,269.44 + Expenses:Movies $5.97 $2,275.41 + Expenses:Supplies $3.84 $2,279.25 + Expenses:Taxes:Sales $169.44 $2,448.69 + Expenses:Tips $11.85 $2,460.54 + Liabilities:MasterCard $-2,460.54 0 +11-May-29 - 11-May-31 Expenses:Cash $-97.00 $-97.00 + Expenses:Food:Dining $6.90 $-90.10 + Expenses:Food:Grocery $157.64 $67.54 + Expenses:Home $108.13 $175.67 + Expenses:Supplies $17.98 $193.65 + Expenses:Taxes:Sales $15.10 $208.75 + Expenses:Tips $97.00 $305.75 + Liabilities:MasterCard $-305.75 0 +end test + +test reg -p "may 2011" --weekly --exact +11-May-01 - 11-May-01 Expe:Computer:Internet $16.10 $16.10 + Liabilities:MasterCard $-16.10 0 +11-May-18 - 11-May-20 Expe:Computer:Internet $30.00 $30.00 + Expe:Computer:Software $6.99 $36.99 + Expenses:Taxes:Sales $0.49 $37.48 + Liabilities:MasterCard $-37.48 0 +11-May-26 - 11-May-28 Expenses:Auto:Gas $70.20 $70.20 + Expenses:Beauty $18.91 $89.11 + Expenses:Bedding $108.84 $197.95 + Expenses:Clothing $2.96 $200.91 + Expenses:Food $19.90 $220.81 + Expenses:Food:Dining $78.32 $299.13 + Expenses:Food:Grocery $67.97 $367.10 + Expenses:Home $1,863.44 $2,230.54 + Expenses:Home:Supplies $38.90 $2,269.44 + Expenses:Movies $5.97 $2,275.41 + Expenses:Supplies $3.84 $2,279.25 + Expenses:Taxes:Sales $169.44 $2,448.69 + Expenses:Tips $11.85 $2,460.54 + Liabilities:MasterCard $-2,460.54 0 +11-May-29 - 11-May-31 Expenses:Cash $-97.00 $-97.00 + Expenses:Food:Dining $6.90 $-90.10 + Expenses:Food:Grocery $157.64 $67.54 + Expenses:Home $108.13 $175.67 + Expenses:Supplies $17.98 $193.65 + Expenses:Taxes:Sales $15.10 $208.75 + Expenses:Tips $97.00 $305.75 + Liabilities:MasterCard $-305.75 0 +end test + +test reg -p "may 2011" --weekly --empty +11-May-01 - 11-May-07 Expe:Computer:Internet $16.10 $16.10 + Liabilities:MasterCard $-16.10 0 +11-May-08 - 11-May-14 0 0 +11-May-15 - 11-May-21 Expe:Computer:Internet $30.00 $30.00 + Expe:Computer:Software $6.99 $36.99 + Expenses:Taxes:Sales $0.49 $37.48 + Liabilities:MasterCard $-37.48 0 +11-May-22 - 11-May-28 Expenses:Auto:Gas $70.20 $70.20 + Expenses:Beauty $18.91 $89.11 + Expenses:Bedding $108.84 $197.95 + Expenses:Clothing $2.96 $200.91 + Expenses:Food $19.90 $220.81 + Expenses:Food:Dining $78.32 $299.13 + Expenses:Food:Grocery $67.97 $367.10 + Expenses:Home $1,863.44 $2,230.54 + Expenses:Home:Supplies $38.90 $2,269.44 + Expenses:Movies $5.97 $2,275.41 + Expenses:Supplies $3.84 $2,279.25 + Expenses:Taxes:Sales $169.44 $2,448.69 + Expenses:Tips $11.85 $2,460.54 + Liabilities:MasterCard $-2,460.54 0 +11-May-29 - 11-May-31 Expenses:Cash $-97.00 $-97.00 + Expenses:Food:Dining $6.90 $-90.10 + Expenses:Food:Grocery $157.64 $67.54 + Expenses:Home $108.13 $175.67 + Expenses:Supplies $17.98 $193.65 + Expenses:Taxes:Sales $15.10 $208.75 + Expenses:Tips $97.00 $305.75 + Liabilities:MasterCard $-305.75 0 +end test + +test reg -p "may 2011" --weekly --empty --exact +11-May-01 - 11-May-01 Expe:Computer:Internet $16.10 $16.10 + Liabilities:MasterCard $-16.10 0 +11-May-14 - 11-May-14 0 0 +11-May-18 - 11-May-20 Expe:Computer:Internet $30.00 $30.00 + Expe:Computer:Software $6.99 $36.99 + Expenses:Taxes:Sales $0.49 $37.48 + Liabilities:MasterCard $-37.48 0 +11-May-26 - 11-May-28 Expenses:Auto:Gas $70.20 $70.20 + Expenses:Beauty $18.91 $89.11 + Expenses:Bedding $108.84 $197.95 + Expenses:Clothing $2.96 $200.91 + Expenses:Food $19.90 $220.81 + Expenses:Food:Dining $78.32 $299.13 + Expenses:Food:Grocery $67.97 $367.10 + Expenses:Home $1,863.44 $2,230.54 + Expenses:Home:Supplies $38.90 $2,269.44 + Expenses:Movies $5.97 $2,275.41 + Expenses:Supplies $3.84 $2,279.25 + Expenses:Taxes:Sales $169.44 $2,448.69 + Expenses:Tips $11.85 $2,460.54 + Liabilities:MasterCard $-2,460.54 0 +11-May-29 - 11-May-31 Expenses:Cash $-97.00 $-97.00 + Expenses:Food:Dining $6.90 $-90.10 + Expenses:Food:Grocery $157.64 $67.54 + Expenses:Home $108.13 $175.67 + Expenses:Supplies $17.98 $193.65 + Expenses:Taxes:Sales $15.10 $208.75 + Expenses:Tips $97.00 $305.75 + Liabilities:MasterCard $-305.75 0 +end test -- cgit v1.2.3 From e2afc783db0dff1927b00dc506390353d9e3bbd2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Feb 2012 22:32:23 -0600 Subject: Increased file copyrights to 2012 --- src/account.cc | 2 +- src/account.h | 2 +- src/accum.cc | 2 +- src/accum.h | 2 +- src/amount.cc | 2 +- src/amount.h | 2 +- src/annotate.cc | 2 +- src/annotate.h | 2 +- src/archive.cc | 2 +- src/archive.h | 2 +- src/balance.cc | 2 +- src/balance.h | 2 +- src/chain.cc | 2 +- src/chain.h | 2 +- src/commodity.cc | 2 +- src/commodity.h | 2 +- src/compare.cc | 2 +- src/compare.h | 2 +- src/convert.cc | 2 +- src/convert.h | 2 +- src/csv.cc | 2 +- src/csv.h | 2 +- src/draft.cc | 2 +- src/draft.h | 2 +- src/emacs.cc | 2 +- src/emacs.h | 2 +- src/error.cc | 2 +- src/error.h | 2 +- src/expr.cc | 2 +- src/expr.h | 2 +- src/exprbase.h | 2 +- src/filters.cc | 2 +- src/filters.h | 2 +- src/flags.h | 2 +- src/format.cc | 2 +- src/format.h | 2 +- src/generate.cc | 2 +- src/generate.h | 2 +- src/global.cc | 2 +- src/global.h | 4 ++-- src/item.cc | 2 +- src/item.h | 2 +- src/iterators.cc | 2 +- src/iterators.h | 2 +- src/journal.cc | 2 +- src/journal.h | 2 +- src/lookup.cc | 2 +- src/lookup.h | 2 +- src/main.cc | 2 +- src/mask.cc | 2 +- src/mask.h | 2 +- src/op.cc | 2 +- src/op.h | 2 +- src/option.cc | 2 +- src/option.h | 2 +- src/org.cc | 2 +- src/org.h | 2 +- src/output.cc | 2 +- src/output.h | 2 +- src/parser.cc | 2 +- src/parser.h | 2 +- src/pool.cc | 2 +- src/pool.h | 2 +- src/post.cc | 2 +- src/post.h | 2 +- src/precmd.cc | 2 +- src/precmd.h | 2 +- src/predicate.cc | 2 +- src/predicate.h | 2 +- src/print.cc | 2 +- src/print.h | 2 +- src/pstream.h | 2 +- src/py_account.cc | 2 +- src/py_amount.cc | 2 +- src/py_balance.cc | 2 +- src/py_commodity.cc | 2 +- src/py_expr.cc | 2 +- src/py_format.cc | 2 +- src/py_item.cc | 2 +- src/py_journal.cc | 2 +- src/py_post.cc | 2 +- src/py_times.cc | 2 +- src/py_utils.cc | 2 +- src/py_value.cc | 2 +- src/py_xact.cc | 2 +- src/pyfstream.h | 2 +- src/pyinterp.cc | 2 +- src/pyinterp.h | 2 +- src/pyledger.cc | 2 +- src/pyutils.h | 2 +- src/query.cc | 2 +- src/query.h | 2 +- src/quotes.cc | 2 +- src/quotes.h | 2 +- src/report.cc | 2 +- src/report.h | 2 +- src/scope.cc | 2 +- src/scope.h | 2 +- src/series.h | 2 +- src/session.cc | 2 +- src/session.h | 2 +- src/stats.cc | 2 +- src/stats.h | 2 +- src/stream.cc | 2 +- src/stream.h | 2 +- src/system.hh.in | 2 +- src/temps.cc | 2 +- src/temps.h | 2 +- src/textual.cc | 2 +- src/timelog.cc | 2 +- src/timelog.h | 2 +- src/times.cc | 2 +- src/times.h | 2 +- src/token.cc | 2 +- src/token.h | 2 +- src/unistring.h | 2 +- src/utils.cc | 2 +- src/utils.h | 2 +- src/value.cc | 2 +- src/value.h | 2 +- src/xact.cc | 2 +- src/xact.h | 2 +- src/xml.cc | 2 +- src/xml.h | 2 +- 124 files changed, 125 insertions(+), 125 deletions(-) (limited to 'src/filters.cc') diff --git a/src/account.cc b/src/account.cc index 42c10839..40ddf70b 100644 --- a/src/account.cc +++ b/src/account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/account.h b/src/account.h index 7a632b35..8f0f915f 100644 --- a/src/account.h +++ b/src/account.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/accum.cc b/src/accum.cc index 0187995e..3add051b 100644 --- a/src/accum.cc +++ b/src/accum.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/accum.h b/src/accum.h index 411bcbe6..349aeba9 100644 --- a/src/accum.h +++ b/src/accum.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/amount.cc b/src/amount.cc index 85afc3d8..4d26a688 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/amount.h b/src/amount.h index f7e877a7..3a8e06b9 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/annotate.cc b/src/annotate.cc index 8ba46f4f..cd1733ca 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/annotate.h b/src/annotate.h index b590ca45..3c6db8e8 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/archive.cc b/src/archive.cc index 28760512..72ec0419 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/archive.h b/src/archive.h index 1ebf3496..4ce5e0e7 100644 --- a/src/archive.h +++ b/src/archive.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/balance.cc b/src/balance.cc index 7ce9d994..4fba7344 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/balance.h b/src/balance.h index ac22f3e7..57e6ace4 100644 --- a/src/balance.h +++ b/src/balance.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/chain.cc b/src/chain.cc index 61388840..fc1be5bd 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/chain.h b/src/chain.h index 7bd76712..080c4231 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/commodity.cc b/src/commodity.cc index 5fd54d11..643d0d1e 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/commodity.h b/src/commodity.h index d7747b2a..68f788e3 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/compare.cc b/src/compare.cc index cdc96a86..e2a298c2 100644 --- a/src/compare.cc +++ b/src/compare.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/compare.h b/src/compare.h index 0e7bf5e5..e1abbca1 100644 --- a/src/compare.h +++ b/src/compare.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/convert.cc b/src/convert.cc index 15995d05..1b1bf814 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/convert.h b/src/convert.h index 6d02f24a..de958108 100644 --- a/src/convert.h +++ b/src/convert.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/csv.cc b/src/csv.cc index 82c28ff3..823238c7 100644 --- a/src/csv.cc +++ b/src/csv.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/csv.h b/src/csv.h index 909439ff..4d6e1253 100644 --- a/src/csv.h +++ b/src/csv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/draft.cc b/src/draft.cc index 9f9ec6e8..7c95caf7 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/draft.h b/src/draft.h index 59039f77..41485731 100644 --- a/src/draft.h +++ b/src/draft.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/emacs.cc b/src/emacs.cc index 5048a348..41c67cc6 100644 --- a/src/emacs.cc +++ b/src/emacs.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/emacs.h b/src/emacs.h index 97292728..a018ce68 100644 --- a/src/emacs.h +++ b/src/emacs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/error.cc b/src/error.cc index 88adfbdb..4a16f4e3 100644 --- a/src/error.cc +++ b/src/error.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/error.h b/src/error.h index b9960b03..7630f017 100644 --- a/src/error.h +++ b/src/error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/expr.cc b/src/expr.cc index b3d4abcd..74d16ecc 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/expr.h b/src/expr.h index 79ae2864..e082efa5 100644 --- a/src/expr.h +++ b/src/expr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/exprbase.h b/src/exprbase.h index e0e2824f..0b1ef243 100644 --- a/src/exprbase.h +++ b/src/exprbase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/filters.cc b/src/filters.cc index fa1f6fa2..72ce9c32 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/filters.h b/src/filters.h index c972de82..22f2d2cb 100644 --- a/src/filters.h +++ b/src/filters.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/flags.h b/src/flags.h index 09b7eec4..e2046c08 100644 --- a/src/flags.h +++ b/src/flags.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/format.cc b/src/format.cc index 65c06488..a391fdf1 100644 --- a/src/format.cc +++ b/src/format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/format.h b/src/format.h index f30b8184..74d77768 100644 --- a/src/format.h +++ b/src/format.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/generate.cc b/src/generate.cc index 963cd845..bf9a8036 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/generate.h b/src/generate.h index abf719d4..1b22004b 100644 --- a/src/generate.h +++ b/src/generate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/global.cc b/src/global.cc index 34427f4b..ee921fc5 100644 --- a/src/global.cc +++ b/src/global.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/global.h b/src/global.h index 6504230d..28bffc3a 100644 --- a/src/global.h +++ b/src/global.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -113,7 +113,7 @@ public: out << "Ledger " << ledger::version << _(", the command-line accounting tool"); out << - _("\n\nCopyright (c) 2003-2010, John Wiegley. All rights reserved.\n\n\ + _("\n\nCopyright (c) 2003-2012, John Wiegley. All rights reserved.\n\n\ This program is made available under the terms of the BSD Public License.\n\ See LICENSE file included with the distribution for details and disclaimer."); out << std::endl; diff --git a/src/item.cc b/src/item.cc index d123ee5a..3a2b0b60 100644 --- a/src/item.cc +++ b/src/item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/item.h b/src/item.h index af3992c0..3a9c55bb 100644 --- a/src/item.h +++ b/src/item.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/iterators.cc b/src/iterators.cc index b398646e..72e0481c 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/iterators.h b/src/iterators.h index 93782400..6d490259 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/journal.cc b/src/journal.cc index ea90fa05..2ebe90fb 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/journal.h b/src/journal.h index 70820cbd..6d10ffda 100644 --- a/src/journal.h +++ b/src/journal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/lookup.cc b/src/lookup.cc index 452727d6..ce22529d 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/lookup.h b/src/lookup.h index 8e83b84e..ba64b0b5 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/main.cc b/src/main.cc index 9031341f..2202a5de 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/mask.cc b/src/mask.cc index 52907cfe..5bc10d5f 100644 --- a/src/mask.cc +++ b/src/mask.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/mask.h b/src/mask.h index e72347ad..15929b2e 100644 --- a/src/mask.h +++ b/src/mask.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/op.cc b/src/op.cc index 6dff031c..372101f0 100644 --- a/src/op.cc +++ b/src/op.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/op.h b/src/op.h index c4d353dc..192c1f5e 100644 --- a/src/op.h +++ b/src/op.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/option.cc b/src/option.cc index 2843c775..170b94af 100644 --- a/src/option.cc +++ b/src/option.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/option.h b/src/option.h index 8f89d081..dc1099db 100644 --- a/src/option.h +++ b/src/option.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/org.cc b/src/org.cc index 7c8e8c0d..3c897f54 100644 --- a/src/org.cc +++ b/src/org.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/org.h b/src/org.h index ed023be2..0b34b610 100644 --- a/src/org.h +++ b/src/org.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/output.cc b/src/output.cc index b26881a3..aaf81f60 100644 --- a/src/output.cc +++ b/src/output.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/output.h b/src/output.h index ac3925c4..281f69b6 100644 --- a/src/output.h +++ b/src/output.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/parser.cc b/src/parser.cc index 6197af6b..2c9069d7 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/parser.h b/src/parser.h index 09e12d95..75fd9a41 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pool.cc b/src/pool.cc index 65edbd6a..ba408fc5 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pool.h b/src/pool.h index 4b935f69..87b315f9 100644 --- a/src/pool.h +++ b/src/pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/post.cc b/src/post.cc index 125947e4..e0ca149f 100644 --- a/src/post.cc +++ b/src/post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/post.h b/src/post.h index 0cfd3e90..ce33fefc 100644 --- a/src/post.h +++ b/src/post.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/precmd.cc b/src/precmd.cc index 663b638d..6f8becb6 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/precmd.h b/src/precmd.h index 277933c3..1c52d8a7 100644 --- a/src/precmd.h +++ b/src/precmd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/predicate.cc b/src/predicate.cc index fd301a7d..58d6c752 100644 --- a/src/predicate.cc +++ b/src/predicate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/predicate.h b/src/predicate.h index 673f1d5d..7d58dc2f 100644 --- a/src/predicate.h +++ b/src/predicate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/print.cc b/src/print.cc index 63f38d80..c544c4e0 100644 --- a/src/print.cc +++ b/src/print.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/print.h b/src/print.h index 527f1912..42bfc8b6 100644 --- a/src/print.h +++ b/src/print.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pstream.h b/src/pstream.h index 8134495d..a894325d 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/py_account.cc b/src/py_account.cc index 5ef86871..64a7ae54 100644 --- a/src/py_account.cc +++ b/src/py_account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_amount.cc b/src/py_amount.cc index 9ce4a02d..f10595e8 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_balance.cc b/src/py_balance.cc index 0140a625..6c9ccb24 100644 --- a/src/py_balance.cc +++ b/src/py_balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_commodity.cc b/src/py_commodity.cc index 6d8a29b3..11ebe844 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_expr.cc b/src/py_expr.cc index 027125e2..dd9df1f5 100644 --- a/src/py_expr.cc +++ b/src/py_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_format.cc b/src/py_format.cc index fc2103c7..482eaf5b 100644 --- a/src/py_format.cc +++ b/src/py_format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_item.cc b/src/py_item.cc index a12784ff..e3e49457 100644 --- a/src/py_item.cc +++ b/src/py_item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_journal.cc b/src/py_journal.cc index bd781225..4f5427f5 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_post.cc b/src/py_post.cc index cace419f..bd599604 100644 --- a/src/py_post.cc +++ b/src/py_post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_times.cc b/src/py_times.cc index c2e0b8f8..17f9ec7e 100644 --- a/src/py_times.cc +++ b/src/py_times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_utils.cc b/src/py_utils.cc index 710dca4b..45ffe545 100644 --- a/src/py_utils.cc +++ b/src/py_utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_value.cc b/src/py_value.cc index f8f36453..3b67c4c6 100644 --- a/src/py_value.cc +++ b/src/py_value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_xact.cc b/src/py_xact.cc index af1fcdd5..97d5df47 100644 --- a/src/py_xact.cc +++ b/src/py_xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyfstream.h b/src/pyfstream.h index 49b072f2..972f976f 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyinterp.cc b/src/pyinterp.cc index e48f16c6..44bea2cd 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyinterp.h b/src/pyinterp.h index ea947c5a..ae8dd9c2 100644 --- a/src/pyinterp.h +++ b/src/pyinterp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyledger.cc b/src/pyledger.cc index 4a53532a..cf5e362e 100644 --- a/src/pyledger.cc +++ b/src/pyledger.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyutils.h b/src/pyutils.h index 7e016502..44bb6d90 100644 --- a/src/pyutils.h +++ b/src/pyutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/query.cc b/src/query.cc index 812123cb..8bdabb38 100644 --- a/src/query.cc +++ b/src/query.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/query.h b/src/query.h index 8f7917b2..52168539 100644 --- a/src/query.h +++ b/src/query.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/quotes.cc b/src/quotes.cc index 0cc8d06b..b29eb8bd 100644 --- a/src/quotes.cc +++ b/src/quotes.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/quotes.h b/src/quotes.h index 376d8918..52092fbc 100644 --- a/src/quotes.h +++ b/src/quotes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/report.cc b/src/report.cc index 530e7727..2c0c3970 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/report.h b/src/report.h index 2b521aae..35d45437 100644 --- a/src/report.h +++ b/src/report.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/scope.cc b/src/scope.cc index 2b9851b0..b2a7b17b 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/scope.h b/src/scope.h index 2720e8fc..6fcd67e9 100644 --- a/src/scope.h +++ b/src/scope.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/series.h b/src/series.h index 40f34051..75b98194 100644 --- a/src/series.h +++ b/src/series.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/session.cc b/src/session.cc index 31122daa..9d994a9b 100644 --- a/src/session.cc +++ b/src/session.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/session.h b/src/session.h index 680b8a0e..93bee8ba 100644 --- a/src/session.h +++ b/src/session.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stats.cc b/src/stats.cc index 524f5a87..0966fee2 100644 --- a/src/stats.cc +++ b/src/stats.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stats.h b/src/stats.h index b7bf94c5..7b00fec8 100644 --- a/src/stats.h +++ b/src/stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stream.cc b/src/stream.cc index 5d4cf5e0..ce40bfcc 100644 --- a/src/stream.cc +++ b/src/stream.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stream.h b/src/stream.h index 42c85534..c317ebdf 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/system.hh.in b/src/system.hh.in index 42a82e41..e14166b2 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/temps.cc b/src/temps.cc index 365c33c5..cb471d41 100644 --- a/src/temps.cc +++ b/src/temps.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/temps.h b/src/temps.h index 1e7eb69f..ad4e5672 100644 --- a/src/temps.h +++ b/src/temps.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/textual.cc b/src/textual.cc index 4977852c..15642cae 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/timelog.cc b/src/timelog.cc index 5ab6a25c..8d3d69c1 100644 --- a/src/timelog.cc +++ b/src/timelog.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/timelog.h b/src/timelog.h index 020ae4f2..12083302 100644 --- a/src/timelog.h +++ b/src/timelog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/times.cc b/src/times.cc index 8ea90892..21ec1859 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/times.h b/src/times.h index bc462efa..6eadcad3 100644 --- a/src/times.h +++ b/src/times.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/token.cc b/src/token.cc index 77092d49..9449d9b7 100644 --- a/src/token.cc +++ b/src/token.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/token.h b/src/token.h index cbdf1258..01ff7ee9 100644 --- a/src/token.h +++ b/src/token.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/unistring.h b/src/unistring.h index 4be36b0d..a33c6e3f 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/utils.cc b/src/utils.cc index 5260fd42..09526267 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/utils.h b/src/utils.h index c7aaac52..e37f37aa 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/value.cc b/src/value.cc index 61066f03..5fa748f6 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/value.h b/src/value.h index f8495002..1e4d0ce9 100644 --- a/src/value.h +++ b/src/value.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xact.cc b/src/xact.cc index 8e1951a5..0fedb42a 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xact.h b/src/xact.h index ff4b7bc2..cb7bdeb3 100644 --- a/src/xact.h +++ b/src/xact.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xml.cc b/src/xml.cc index 90efd4b3..560db805 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xml.h b/src/xml.h index 5d14dab3..871fd120 100644 --- a/src/xml.h +++ b/src/xml.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are -- cgit v1.2.3 From 48ab6ad1dbab100bb8abd87029a0ca5bc501a3db Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 4 Mar 2012 03:35:06 -0600 Subject: Switched to using Boost.Graph for commodity pricing --- src/commodity.cc | 442 +++++------------------------------------------------- src/commodity.h | 114 +------------- src/filters.cc | 3 + src/history.cc | 196 ++++++++++++++++++++++++ src/history.h | 184 +++++++++++++++++++++++ src/iterators.cc | 3 + src/pool.cc | 88 ++--------- src/pool.h | 23 ++- src/report.cc | 10 +- src/system.hh.in | 15 ++ tools/Makefile.am | 2 + 11 files changed, 476 insertions(+), 604 deletions(-) create mode 100644 src/history.cc create mode 100644 src/history.h (limited to 'src/filters.cc') diff --git a/src/commodity.cc b/src/commodity.cc index 643d0d1e..c0ccae11 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -40,410 +40,68 @@ namespace ledger { bool commodity_t::decimal_comma_by_default = false; -void commodity_t::history_t::add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive) +void commodity_t::add_price(const datetime_t& date, const amount_t& price, + const bool reflexive) { - DEBUG("commodity.prices.add", "add_price to " << source - << (reflexive ? " (secondary)" : " (primary)") - << " : " << date << ", " << price); + if (! reflexive) + add_flags(COMMODITY_PRIMARY); + pool().commodity_price_history.add_price(*this, date, price); - history_map::iterator i = prices.find(date); - if (i != prices.end()) { - (*i).second = price; - } else { - std::pair result - = prices.insert(history_map::value_type(date, price)); - assert(result.second); - } - - if (reflexive) { - amount_t inverse = price.inverted(); - inverse.set_commodity(const_cast(source)); - price.commodity().add_price(date, inverse, false); - } else { - DEBUG("commodity.prices.add", - "marking commodity " << source.symbol() << " as primary"); - source.add_flags(COMMODITY_PRIMARY); - } -} - -bool commodity_t::history_t::remove_price(const datetime_t& date) -{ - DEBUG("commodity.prices.add", "remove_price: " << date); - - history_map::size_type n = prices.erase(date); - if (n > 0) - return true; - return false; -} - -void commodity_t::varied_history_t:: - add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive) -{ - optional hist = history(price.commodity()); - if (! hist) { - std::pair result - = histories.insert(history_by_commodity_map::value_type - (&price.commodity(), history_t())); - assert(result.second); - - hist = (*result.first).second; - } - assert(hist); - - hist->add_price(source, date, price, reflexive); + DEBUG("commodity.prices.find", "Price added, clearing price_map"); + base->price_map.clear(); // a price was added, invalid the map } -bool commodity_t::varied_history_t::remove_price(const datetime_t& date, - commodity_t& comm) +void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) { - DEBUG("commodity.prices.add", "varied_remove_price: " << date << ", " << comm); + pool().commodity_price_history.remove_price(*this, commodity, date); - if (optional hist = history(comm)) - return hist->remove_price(date); - return false; + DEBUG("commodity.prices.find", "Price removed, clearing price_map"); + base->price_map.clear(); // a price was added, invalid the map } optional -commodity_t::history_t::find_price(const optional& moment, - const optional& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const +commodity_t::find_price(const optional& target = none, + const optional& moment = none, + const optional& oldest = none) const { - price_point_t point; - bool found = false; - -#if defined(DEBUG_ON) -#define DEBUG_INDENT(cat, indent) \ - do { \ - if (SHOW_DEBUG(cat)) \ - for (int _i = 0; _i < indent; _i++) \ - ledger::_log_buffer << " "; \ - } while (false) -#else -#define DEBUG_INDENT(cat, indent) -#endif - -#if defined(DEBUG_ON) + pair = base_t::time_and_commodity_t + (base_t::optional_time_pair_t(moment, oldest), + commodity ? &(*commodity) : NULL); DEBUG_INDENT("commodity.prices.find", indent); - if (moment) - DEBUG("commodity.prices.find", "find price nearest before or on: " << *moment); - else - DEBUG("commodity.prices.find", "find any price"); + DEBUG("commodity.prices.find", "looking for memoized args: " + << (moment ? format_datetime(*moment) : "NONE") << ", " + << (oldest ? format_datetime(*oldest) : "NONE") << ", " + << (commodity ? commodity->symbol() : "NONE")); - if (oldest) { + base_t::memoized_price_map::iterator i = base->price_map.find(*pair); + if (i != base->price_map.end()) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "but no older than: " << *oldest); - } -#endif - - if (prices.size() == 0) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "there are no prices in this history"); - return none; + DEBUG("commodity.prices.find", "found! returning: " + << ((*i).second ? (*i).second->price : amount_t(0L))); + return (*i).second; } - if (! moment) { - history_map::const_reverse_iterator r = prices.rbegin(); - point.when = (*r).first; - point.price = (*r).second; - found = true; - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using most recent price"); - } else { - history_map::const_iterator i = prices.upper_bound(*moment); - if (i == prices.end()) { - history_map::const_reverse_iterator r = prices.rbegin(); - point.when = (*r).first; - point.price = (*r).second; - found = true; + optional point = + pool().commodity_price_history.find_price + (*this, commodity, moment ? *moment : epoch, oldest); + if (pair) { + if (base->price_map.size() > base_t::max_price_map_size) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using last price"); - } else { - point.when = (*i).first; - if (*moment < point.when) { - if (i != prices.begin()) { - --i; - point.when = (*i).first; - point.price = (*i).second; - found = true; - } - } else { - point.price = (*i).second; - found = true; - } - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "using found price"); - } - } - - if (! found) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "could not find a price"); - return none; - } - else if (moment && point.when > *moment) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "price is too young "); - return none; - } - else if (oldest && point.when < *oldest) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "price is too old "); - return none; - } - else { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "returning price: " << point.when << ", " << point.price); - return point; - } -} - -optional -commodity_t::varied_history_t::find_price(const commodity_t& source, - const optional& commodity, - const optional& moment, - const optional& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - optional point; - optional limit = oldest; - -#if defined(VERIFY_ON) - if (commodity) { - VERIFY(source != *commodity); - VERIFY(! commodity->has_annotation()); - VERIFY(source.referent() != commodity->referent()); - } -#endif - -#if defined(DEBUG_ON) - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "varied_find_price for: " << source); - - DEBUG_INDENT("commodity.prices.find", indent); - if (commodity) - DEBUG("commodity.prices.find", "looking for: commodity '" << *commodity << "'"); - else - DEBUG("commodity.prices.find", "looking for: any commodity"); - - if (moment) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "time index: " << *moment); - } - - if (oldest) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "only consider prices younger than: " << *oldest); - } -#endif - - // Either we couldn't find a history for the target commodity, or we - // couldn't find a price. In either case, search all histories known - // to this commodity for a price which we can calculate in terms of - // the goal commodity. - price_point_t best; - bool found = false; - - foreach (const history_by_commodity_map::value_type& hist, histories) { - commodity_t& comm(*hist.first); - if (comm == source) - continue; - - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "searching for price via commodity '" << comm << "'"); - - point = hist.second.find_price(moment, limit -#if defined(DEBUG_ON) - , indent + 2 -#endif - ); - assert(! point || point->price.commodity() == comm); - - if (point) { - optional xlat; - - if (commodity && comm != *commodity) { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "looking for translation price"); - - xlat = comm.find_price(commodity, moment, limit, true -#if defined(DEBUG_ON) - , indent + 2 -#endif - ); - if (xlat) { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "found translated price " - << xlat->price << " from " << xlat->when); - - point->price = xlat->price * point->price; - if (xlat->when < point->when) { - point->when = xlat->when; - - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "adjusting date of result back to " << point->when); - } - } else { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "saw no translated price there"); - continue; - } - } - - assert(! commodity || point->price.commodity() == *commodity); - - DEBUG_INDENT("commodity.prices.find", indent + 1); DEBUG("commodity.prices.find", - "saw a price there: " << point->price << " from " << point->when); - - if (! limit || point->when > *limit) { - limit = point->when; - best = *point; - found = true; + "price map has grown too large, clearing it by half"); - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", - "search limit adjusted to " << *limit); - } - } else { - DEBUG_INDENT("commodity.prices.find", indent + 1); - DEBUG("commodity.prices.find", "saw no price there"); + for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) + base->price_map.erase(base->price_map.begin()); } - } - if (found) { DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.download", - "found price " << best.price << " from " << best.when); - return best; - } - return none; -} - -optional -commodity_t::varied_history_t::history(const optional& commodity) -{ - commodity_t * comm = NULL; - if (! commodity) { - if (histories.size() > 1) - return none; - comm = (*histories.begin()).first; - } else { - comm = &(*commodity); - } - - history_by_commodity_map::iterator i = histories.find(comm); - if (i != histories.end()) - return (*i).second; - - return none; -} - -optional -commodity_t::find_price(const optional& commodity, - const optional& moment, - const optional& oldest, - const bool nested -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - if (! has_flags(COMMODITY_WALKED) && base->varied_history) { - optional pair; -#if defined(VERIFY_ON) - optional checkpoint; - bool found = false; -#endif - - if (! nested) { - pair = base_t::time_and_commodity_t - (base_t::optional_time_pair_t(moment, oldest), - commodity ? &(*commodity) : NULL); - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "looking for memoized args: " - << (moment ? format_datetime(*moment) : "NONE") << ", " - << (oldest ? format_datetime(*oldest) : "NONE") << ", " - << (commodity ? commodity->symbol() : "NONE")); - - base_t::memoized_price_map::iterator i = base->price_map.find(*pair); - if (i != base->price_map.end()) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "found! returning: " - << ((*i).second ? (*i).second->price : amount_t(0L))); -#if defined(VERIFY_ON) - IF_VERIFY() { - found = true; - checkpoint = (*i).second; - } else -#endif // defined(VERIFY_ON) - return (*i).second; - } - } - - optional point; - - const_cast(*this).add_flags(COMMODITY_WALKED); - try { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", "manually finding price..."); - - point = base->varied_history->find_price(*this, commodity, - moment, oldest -#if defined(DEBUG_ON) - , indent -#endif - ); - } - catch (...) { - const_cast(*this).drop_flags(COMMODITY_WALKED); - throw; - } - const_cast(*this).drop_flags(COMMODITY_WALKED); - -#if defined(VERIFY_ON) - if (DO_VERIFY() && found) { - VERIFY(checkpoint == point); - return checkpoint; - } -#endif // defined(VERIFY_ON) - - if (! nested && pair) { - if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "price map has grown too large, clearing it by half"); - - for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) - base->price_map.erase(base->price_map.begin()); - } - - DEBUG_INDENT("commodity.prices.find", indent); - DEBUG("commodity.prices.find", - "remembered: " << (point ? point->price : amount_t(0L))); - base->price_map.insert - (base_t::memoized_price_map::value_type(*pair, point)); - } - return point; + DEBUG("commodity.prices.find", + "remembered: " << (point ? point->price : amount_t(0L))); + base->price_map.insert + (base_t::memoized_price_map::value_type(*pair, point)); } - return none; + return point; } optional @@ -767,28 +425,6 @@ void to_xml(std::ostream& out, const commodity_t& comm, if (commodity_details) { if (comm.has_annotation()) to_xml(out, as_annotated_commodity(comm).details); - - if (comm.varied_history()) { - push_xml y(out, "varied-history"); - - foreach (const commodity_t::history_by_commodity_map::value_type& pair, - comm.varied_history()->histories) { - { - push_xml z(out, "symbol"); - out << y.guard(pair.first->symbol()); - } - { - push_xml z(out, "history"); - - foreach (const commodity_t::history_map::value_type& inner_pair, - pair.second.prices) { - push_xml w(out, "price-point"); - to_xml(out, inner_pair.first); - to_xml(out, inner_pair.second); - } - } - } - } } } diff --git a/src/commodity.h b/src/commodity.h index 68f788e3..1505fe24 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -85,78 +85,6 @@ class commodity_t : public delegates_flags, public equality_comparable1 { -public: - typedef std::map history_map; - - struct history_t - { - history_map prices; - - void add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive = true); - bool remove_price(const datetime_t& date); - - optional - find_price(const optional& moment = none, - const optional& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; - -#if defined(HAVE_BOOST_SERIALIZATION) - private: - /** Serialization. */ - - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int /* version */) { - ar & prices; - } -#endif // HAVE_BOOST_SERIALIZATION - }; - - typedef std::map history_by_commodity_map; - - struct varied_history_t - { - history_by_commodity_map histories; - - void add_price(commodity_t& source, - const datetime_t& date, - const amount_t& price, - const bool reflexive = true); - bool remove_price(const datetime_t& date, commodity_t& commodity); - - optional - find_price(const commodity_t& source, - const optional& commodity = none, - const optional& moment = none, - const optional& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; - - optional - history(const optional& commodity = none); - -#if defined(HAVE_BOOST_SERIALIZATION) - private: - /** Serialization. */ - - friend class boost::serialization::access; - - template - void serialize(Archive& ar, const unsigned int /* version */) { - ar & histories; - } -#endif // HAVE_BOOST_SERIALIZATION - }; - protected: friend class commodity_pool_t; friend class annotated_commodity_t; @@ -182,7 +110,6 @@ protected: amount_t::precision_t precision; optional name; optional note; - optional varied_history; optional smaller; optional larger; @@ -228,7 +155,6 @@ protected: ar & precision; ar & name; ar & note; - ar & varied_history; ar & smaller; ar & larger; } @@ -335,48 +261,14 @@ public: base->larger = arg; } - optional varied_history() { - if (base->varied_history) - return *base->varied_history; - return none; - } - optional varied_history() const { - if (base->varied_history) - return *base->varied_history; - return none; - } - - optional history(const optional& commodity); - - // These methods provide a transparent pass-through to the underlying - // base->varied_history object. - void add_price(const datetime_t& date, const amount_t& price, - const bool reflexive = true) { - if (! base->varied_history) - base->varied_history = varied_history_t(); - base->varied_history->add_price(*this, date, price, reflexive); - DEBUG("commodity.prices.find", "Price added, clearing price_map"); - base->price_map.clear(); // a price was added, invalid the map - } - bool remove_price(const datetime_t& date, commodity_t& commodity) { - if (base->varied_history) { - base->varied_history->remove_price(date, commodity); - DEBUG("commodity.prices.find", "Price removed, clearing price_map"); - base->price_map.clear(); // a price was added, invalid the map - } - return false; - } + const bool reflexive = true); + void remove_price(const datetime_t& date, commodity_t& commodity); optional find_price(const optional& commodity = none, const optional& moment = none, - const optional& oldest = none, - const bool nested = false -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; + const optional& oldest = none) const; optional check_for_updated_price(const optional& point, diff --git a/src/filters.cc b/src/filters.cc index 72ce9c32..0c6222d7 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -754,6 +754,8 @@ void changed_value_posts::output_intermediate_prices(post_t& post, // fall through... case value_t::BALANCE: { +#if 0 + // jww (2012-03-04): TODO commodity_t::history_map all_prices; foreach (const balance_t::amounts_map::value_type& amt_comm, @@ -797,6 +799,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, output_revaluation(post, price.first); last_total = repriced_total; } +#endif break; } default: diff --git a/src/history.cc b/src/history.cc new file mode 100644 index 00000000..44d19f5a --- /dev/null +++ b/src/history.cc @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "history.h" + +template +struct f_max : public std::binary_function { + T operator()(const T& x, const T& y) const { + return std::max(x, y); + } +}; + +namespace ledger { + +void commodity_history_t::add_commodity(const commodity_t& comm) +{ + const vertex_descriptor vert = add_vertex(&comm, price_graph); + put(indexmap, vert, reinterpret_cast(&comm)); +} + +void commodity_history_t::add_price(const commodity_t& source, + const datetime_t& when, + const amount_t& price) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&price.commodity()), price_graph); + + std::pair e1 = add_edge(sv, tv, 0, price_graph); + price_map_t& prices(get(ratiomap, e1.first)); + + std::pair result = + prices.insert(price_map_t::value_type(when, price)); + if (! result.second) { + // There is already an entry for this moment, so update it + (*result.first).second = price; + } +} + +void commodity_history_t::remove_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& date) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&target), price_graph); + + std::pair e1 = add_edge(sv, tv, 0, price_graph); + price_map_t& prices(get(ratiomap, e1.first)); + + // jww (2012-03-04): If it fails, should we give a warning? + prices.erase(date); +} + +optional +commodity_history_t::find_price(const commodity_t& source, + const datetime_t& moment, + const optional& oldest, + const optional& target) +{ + vertex_descriptor sv = + vertex(reinterpret_cast(&source), price_graph); + vertex_descriptor tv = + vertex(reinterpret_cast(&*target), price_graph); + + // Filter out edges which came into being after the reference time + + FGraph fg(price_graph, + recent_edge_weight + (get(edge_weight, price_graph), pricemap, ratiomap, + moment, oldest)); + + std::vector predecessors(num_vertices(fg)); + std::vector distances(num_vertices(fg)); + + PredecessorMap predecessorMap(&predecessors[0]); + DistanceMap distanceMap(&distances[0]); + + dijkstra_shortest_paths(fg, /* start= */ sv, + predecessor_map(predecessorMap) + .distance_map(distanceMap) + .distance_combine(f_max())); + + // Extract the shortest path and performance the calculations + datetime_t least_recent = moment; + amount_t price; + + vertex_descriptor v = tv; + for (vertex_descriptor u = predecessorMap[v]; + u != v; + v = u, u = predecessorMap[v]) + { + std::pair edgePair = edge(u, v, fg); + Graph::edge_descriptor edge = edgePair.first; + + const price_point_t& point(get(pricemap, edge)); + + if (price.is_null()) { + least_recent = point.when; + price = point.price; + } + else if (point.when < least_recent) + least_recent = point.when; + + // jww (2012-03-04): TODO + //price *= point.price; + } + + return price_point_t(least_recent, price); +} + +#if 0 + print_vertices(fg, f_commmap); + print_edges(fg, f_commmap); + print_graph(fg, f_commmap); + + graph_traits::vertex_iterator f_vi, f_vend; + for(tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi) + std::cerr << get(f_commmap, *f_vi) << " is in the filtered graph" + << std::endl; + + for (tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi) { + std::cerr << "distance(" << get(f_commmap, *f_vi) << ") = " + << distanceMap[*f_vi] << ", "; + std::cerr << "parent(" << get(f_commmap, *f_vi) << ") = " + << get(f_commmap, predecessorMap[*f_vi]) + << std::endl; + } + + // Write shortest path + FCommMap f_commmap = get(vertex_comm, fg); + + std::cerr << "Shortest path from CAD to EUR:" << std::endl; + for (PathType::reverse_iterator pathIterator = path.rbegin(); + pathIterator != path.rend(); + ++pathIterator) + { + std::cerr << get(f_commmap, source(*pathIterator, fg)) + << " -> " << get(f_commmap, target(*pathIterator, fg)) + << " = " << get(edge_weight, fg, *pathIterator) + << std::endl; + } + std::cerr << std::endl; + + std::cerr << "Distance: " << distanceMap[vd4] << std::endl; +#endif + +#if 0 + #include + + // Writing graph to file + { + std::ofstream f("test.dot"); + + dynamic_properties p; + p.property("label", get(edge_weight, g)); + p.property("weight", get(edge_weight, g)); + p.property("node_id", get(vertex_comm, g)); + write_graphviz(f,g,p); + f.close(); + } +#endif + +} // namespace ledger diff --git a/src/history.h b/src/history.h new file mode 100644 index 00000000..486602dd --- /dev/null +++ b/src/history.h @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @addtogroup math + */ + +/** + * @file history.h + * @author John Wiegley + * + * @ingroup math + * + * @brief Types for managing commodity historys + * + * Long. + */ +#ifndef _HISTORY_H +#define _HISTORY_H + +#include "amount.h" +#include "commodity.h" + +namespace boost { + enum edge_price_point_t { edge_price_point }; + enum edge_price_ratio_t { edge_price_ratio }; + BOOST_INSTALL_PROPERTY(edge, price_point); + BOOST_INSTALL_PROPERTY(edge, price_ratio); +} + +namespace ledger { + +typedef std::map price_map_t; + +template +class recent_edge_weight +{ +public: + EdgeWeightMap weight; + PricePointMap price_point; + PriceRatioMap ratios; + + datetime_t reftime; + optional oldest; + + recent_edge_weight() { } + recent_edge_weight(EdgeWeightMap _weight, + PricePointMap _price_point, + PriceRatioMap _ratios, + datetime_t _reftime, + const optional& _oldest = none) + : weight(_weight), price_point(_price_point), ratios(_ratios), + reftime(_reftime), oldest(_oldest) { } + + template + bool operator()(const Edge& e) const { + const price_map_t& prices(get(ratios, e)); + price_map_t::const_iterator low = prices.upper_bound(reftime); + if (prices.empty() || + (low != prices.end() && low == prices.begin())) { + return false; + } else { + if (low == prices.end()) + --low; + assert(((*low).first <= reftime)); + + if (oldest && (*low).first <= *oldest) + return false; + + long secs = (reftime - (*low).first).total_seconds(); + assert(secs >= 0); + + put(weight, e, secs); + put(price_point, e, price_point_t((*low).first, (*low).second)); + + return true; + } + } +}; + +class commodity_history_t : public noncopyable +{ +public: + typedef adjacency_list + >, + + // All edges are weights computed as the absolute difference between + // the reference time of a search and a known price point. A + // filtered_graph is used to select the recent price point to the + // reference time before performing the search. + property > >, + + // Graph itself has a std::string name + property + > Graph; + + Graph price_graph; + + typedef graph_traits::vertex_descriptor vertex_descriptor; + typedef graph_traits::edge_descriptor edge_descriptor; + + typedef property_map::type IndexMap; + typedef property_map::type NameMap; + + typedef iterator_property_map PredecessorMap; + typedef iterator_property_map DistanceMap; + + typedef property_map::type EdgeWeightMap; + typedef property_map::type PricePointMap; + typedef property_map::type PriceRatioMap; + + IndexMap indexmap; + PricePointMap pricemap; + PriceRatioMap ratiomap; + + typedef filtered_graph > FGraph; + typedef property_map::type FNameMap; + + commodity_history_t() + : indexmap(get(vertex_index, price_graph)), + pricemap(get(edge_price_point, price_graph)), + ratiomap(get(edge_price_ratio, price_graph)) {} + + void add_commodity(const commodity_t& comm); + + void add_price(const commodity_t& source, + const datetime_t& when, + const amount_t& price); + void remove_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& date); + + optional + find_price(const commodity_t& source, + const datetime_t& moment, + const optional& oldest = none, + const optional& commodity = none); +}; + +} // namespace ledger + +#endif // _HISTORY_H diff --git a/src/iterators.cc b/src/iterators.cc index 72e0481c..b7ed011e 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -90,6 +90,8 @@ void posts_commodities_iterator::reset(journal_t& journal) std::map xacts_by_commodity; +#if 0 + // jww (2012-03-04): TODO foreach (commodity_t * comm, commodities) { if (optional history = comm->varied_history()) { @@ -136,6 +138,7 @@ void posts_commodities_iterator::reset(journal_t& journal) } } } +#endif xacts.reset(xact_temps.begin(), xact_temps.end()); diff --git a/src/pool.cc b/src/pool.cc index ba408fc5..67cfe3d1 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -35,6 +35,7 @@ #include "commodity.h" #include "annotate.h" #include "pool.h" +#include "history.h" #include "quotes.h" namespace ledger { @@ -74,15 +75,15 @@ commodity_t * commodity_pool_t::create(const string& symbol) commodity.get())); assert(result.second); + commodity_price_history.add_commodity(*commodity.get()); + return commodity.release(); } commodity_t * commodity_pool_t::find_or_create(const string& symbol) { DEBUG("pool.commodities", "Find-or-create commodity " << symbol); - - commodity_t * commodity = find(symbol); - if (commodity) + if (commodity_t * commodity = find(symbol)) return commodity; return create(symbol); } @@ -222,6 +223,15 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, return create(comm, details, name); } +optional +commodity_pool_t::find_price(const commodity_t& source, + const optional& commodity, + const optional& moment, + const optional& oldest) const +{ + return commodity_price_history.find_price(source, commodity, moment, oldest); +} + void commodity_pool_t::exchange(commodity_t& commodity, const amount_t& per_unit_cost, const datetime_t& moment) @@ -382,76 +392,4 @@ commodity_pool_t::parse_price_expression(const std::string& str, return NULL; } -void commodity_pool_t::print_pricemap(std::ostream& out, - const keep_details_t& keep, - const optional& moment) -{ - typedef std::map comm_map_t; - - comm_map_t comm_map; - - foreach (const commodities_map::value_type& comm_pair, commodities) { - commodity_t * comm(&comm_pair.second->strip_annotations(keep)); - comm_map.insert(comm_map_t::value_type(comm, NULL)); - } - - out << "digraph commodities {\n"; - - foreach (const comm_map_t::value_type& comm_pair, comm_map) { - commodity_t * comm(comm_pair.first); - if (comm->has_flags(COMMODITY_BUILTIN)) - continue; - - out << " "; - if (commodity_t::symbol_needs_quotes(comm->symbol())) - out << comm->symbol() << ";\n"; - else - out << "\"" << comm->symbol() << "\";\n"; - - if (! comm->has_flags(COMMODITY_NOMARKET) && - (! commodity_pool_t::current_pool->default_commodity || - comm != commodity_pool_t::current_pool->default_commodity)) { - if (optional vhist = - comm->varied_history()) { - foreach (const commodity_t::history_by_commodity_map::value_type& pair, - vhist->histories) { - datetime_t most_recent; - amount_t most_recent_amt; - foreach (const commodity_t::history_map::value_type& inner_pair, - pair.second.prices) { - if ((most_recent.is_not_a_date_time() || - inner_pair.first > most_recent) && - (! moment || inner_pair.first <= moment)) { - most_recent = inner_pair.first; - most_recent_amt = inner_pair.second; - } - } - - if (! most_recent.is_not_a_date_time()) { - out << " "; - if (commodity_t::symbol_needs_quotes(comm->symbol())) - out << comm->symbol(); - else - out << "\"" << comm->symbol() << "\""; - - out << " -> "; - - if (commodity_t::symbol_needs_quotes(pair.first->symbol())) - out << pair.first->symbol(); - else - out << "\"" << pair.first->symbol() << "\""; - - out << " [label=\"" - << most_recent_amt.number() << "\\n" - << format_date(most_recent.date(), FMT_WRITTEN) - << "\" fontcolor=\"#008e28\"];\n"; - } - } - } - } - } - - out << "}\n"; -} - } // namespace ledger diff --git a/src/pool.h b/src/pool.h index 87b315f9..709f5c71 100644 --- a/src/pool.h +++ b/src/pool.h @@ -46,6 +46,8 @@ #ifndef _POOL_H #define _POOL_H +#include "history.h" + namespace ledger { struct cost_breakdown_t @@ -66,15 +68,16 @@ public: */ typedef std::map commodities_map; - commodities_map commodities; - commodity_t * null_commodity; - commodity_t * default_commodity; + commodities_map commodities; + commodity_history_t commodity_price_history; + commodity_t * null_commodity; + commodity_t * default_commodity; - bool keep_base; // --base + bool keep_base; // --base - optional price_db; // --price-db= - long quote_leeway; // --leeway= - bool get_quotes; // --download + optional price_db; // --price-db= + long quote_leeway; // --leeway= + bool get_quotes; // --download static shared_ptr current_pool; @@ -131,12 +134,6 @@ public: const bool add_prices = true, const optional& moment = none); - // Output the commodity price map for a given date as a DOT file - - void print_pricemap(std::ostream& out, - const keep_details_t& keep, - const optional& moment = none); - #if defined(HAVE_BOOST_SERIALIZATION) private: /** Serialization. */ diff --git a/src/report.cc b/src/report.cc index 647df3d2..689028d0 100644 --- a/src/report.cc +++ b/src/report.cc @@ -878,11 +878,12 @@ value_t report_t::echo_command(call_scope_t& args) value_t report_t::pricemap_command(call_scope_t& args) { std::ostream& out(output_stream); - +#if 0 + // jww (2012-03-04): TODO commodity_pool_t::current_pool->print_pricemap (out, what_to_keep(), args.has(0) ? optional(datetime_t(parse_date(args.get(0)))) : none); - +#endif return true; } @@ -913,6 +914,11 @@ option_t * report_t::lookup_option(const char * p) case 'G': OPT_CH(gain); break; +#if 0 + case 'H': + OPT_CH(historical); + break; +#endif case 'I': OPT_CH(price); break; diff --git a/src/system.hh.in b/src/system.hh.in index 3aa60f71..8f684486 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -138,37 +138,52 @@ typedef std::ostream::pos_type ostream_pos_type; #include #include #include + #include #include #include + #include #include #include #include #include + #if !(defined(__GXX_EXPERIMENTAL_CXX0X__) && __GXX_EXPERIMENTAL_CXX0X__) #include #endif #include + +#include +#include +#include +#include + #include + #include #include #define BOOST_IOSTREAMS_USE_DEPRECATED 1 #include + #include #include + #include #include #include #include + #include #include #include #include + #if defined(HAVE_BOOST_REGEX_UNICODE) #include #else #include + #endif // HAVE_BOOST_REGEX_UNICODE #include #include diff --git a/tools/Makefile.am b/tools/Makefile.am index 09021b1f..671db294 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -30,6 +30,7 @@ libledger_util_la_LDFLAGS = -release $(LIBVERSION) libledger_math_la_SOURCES = \ src/balance.cc \ src/quotes.cc \ + src/history.cc \ src/pool.cc \ src/annotate.cc \ src/commodity.cc \ @@ -104,6 +105,7 @@ pkginclude_HEADERS = \ src/amount.h \ src/commodity.h \ src/annotate.h \ + src/history.h \ src/pool.h \ src/quotes.h \ src/balance.h \ -- cgit v1.2.3 From 8d6bf11334562d7781b339cf822a93ff42fee2b5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 01:48:21 -0600 Subject: All tests are working again but one --- src/amount.cc | 9 +- src/amount.h | 7 +- src/commodity.cc | 54 +++++++--- src/commodity.h | 4 + src/filters.cc | 52 +++++----- src/history.cc | 179 ++++++++++++++++++++++++--------- src/history.h | 61 ++++++++--- src/iterators.cc | 104 +++++++++---------- test/baseline/feat-fixated-prices.test | 2 + test/regress/25A099C9.test | 12 +-- test/unit/t_commodity.cc | 2 +- 11 files changed, 318 insertions(+), 168 deletions(-) (limited to 'src/filters.cc') diff --git a/src/amount.cc b/src/amount.cc index 4d26a688..9704dd21 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -605,16 +605,13 @@ void amount_t::in_place_negate() } } -amount_t amount_t::inverted() const +void amount_t::in_place_invert() { if (! quantity) throw_(amount_error, _("Cannot invert an uninitialized amount")); - amount_t t(*this); - t._dup(); - mpq_inv(MP(t.quantity), MP(t.quantity)); - - return t; + _dup(); + mpq_inv(MP(quantity), MP(quantity)); } void amount_t::in_place_round() diff --git a/src/amount.h b/src/amount.h index 3a8e06b9..1db59b7e 100644 --- a/src/amount.h +++ b/src/amount.h @@ -327,7 +327,12 @@ public: return *this; } - amount_t inverted() const; + amount_t inverted() const { + amount_t temp(*this); + temp.in_place_invert(); + return temp; + } + void in_place_invert(); /** Yields an amount whose display precision when output is truncated to the display precision of its commodity. This is normally the diff --git a/src/commodity.cc b/src/commodity.cc index 5e55db31..7d473d74 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -43,11 +43,20 @@ bool commodity_t::decimal_comma_by_default = false; void commodity_t::add_price(const datetime_t& date, const amount_t& price, const bool reflexive) { - if (! reflexive) + if (reflexive) { + DEBUG("history.find", "Marking " + << price.commodity().symbol() << " as a primary commodity"); + price.commodity().add_flags(COMMODITY_PRIMARY); + } else { + DEBUG("history.find", "Marking " << symbol() << " as a primary commodity"); add_flags(COMMODITY_PRIMARY); + } + + DEBUG("history.find", "Adding price: " << symbol() + << " for " << price << " on " << date); + pool().commodity_price_history.add_price(*this, date, price); - DEBUG("commodity.prices.find", "Price added, clearing price_map"); base->price_map.clear(); // a price was added, invalid the map } @@ -55,27 +64,52 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) { pool().commodity_price_history.remove_price(*this, commodity, date); - DEBUG("commodity.prices.find", "Price removed, clearing price_map"); + DEBUG("history.find", "Removing price: " << symbol() << " on " << date); + base->price_map.clear(); // a price was added, invalid the map } +void commodity_t::map_prices(function fn, + const optional& moment, + const optional& _oldest) +{ + datetime_t when; + if (moment) + when = *moment; + else if (epoch) + when = *epoch; + else + when = CURRENT_TIME(); + + pool().commodity_price_history.map_prices(fn, *this, when, _oldest); +} + optional commodity_t::find_price(const optional& commodity, const optional& moment, const optional& oldest) const { + optional target; + if (commodity) + target = commodity; + else if (pool().default_commodity) + target = *pool().default_commodity; + + if (target && *this == *target) + return none; + optional pair = base_t::time_and_commodity_t(base_t::optional_time_pair_t(moment, oldest), commodity ? &(*commodity) : NULL); - DEBUG("commodity.prices.find", "looking for memoized args: " + DEBUG("history.find", "looking for memoized args: " << (moment ? format_datetime(*moment) : "NONE") << ", " << (oldest ? format_datetime(*oldest) : "NONE") << ", " << (commodity ? commodity->symbol() : "NONE")); { base_t::memoized_price_map::iterator i = base->price_map.find(*pair); if (i != base->price_map.end()) { - DEBUG("commodity.prices.find", "found! returning: " + DEBUG("history.find", "found! returning: " << ((*i).second ? (*i).second->price : amount_t(0L))); return (*i).second; } @@ -89,12 +123,6 @@ commodity_t::find_price(const optional& commodity, else when = CURRENT_TIME(); - optional target; - if (commodity) - target = commodity; - else if (pool().default_commodity) - target = *pool().default_commodity; - optional point = target ? pool().commodity_price_history.find_price(*this, *target, when, oldest) : @@ -102,13 +130,13 @@ commodity_t::find_price(const optional& commodity, if (pair) { if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG("commodity.prices.find", + DEBUG("history.find", "price map has grown too large, clearing it by half"); for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) base->price_map.erase(base->price_map.begin()); } - DEBUG("commodity.prices.find", + DEBUG("history.find", "remembered: " << (point ? point->price : amount_t(0L))); base->price_map.insert (base_t::memoized_price_map::value_type(*pair, point)); diff --git a/src/commodity.h b/src/commodity.h index a1ad0147..524daaab 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -271,6 +271,10 @@ public: const bool reflexive = true); void remove_price(const datetime_t& date, commodity_t& commodity); + void map_prices(function fn, + const optional& moment = none, + const optional& _oldest = none); + optional find_price(const optional& commodity = none, const optional& moment = none, diff --git a/src/filters.cc b/src/filters.cc index 0c6222d7..6e52c40f 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -37,6 +37,7 @@ #include "report.h" #include "compare.h" #include "pool.h" +#include "history.h" namespace ledger { @@ -688,6 +689,27 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) } } +namespace { + struct create_price_xact { + post_t& post; + const date_t& current; + price_map_t& all_prices; + + create_price_xact(post_t& _post, const date_t& _current, + price_map_t& _all_prices) + : post(_post), current(_current), all_prices(_all_prices) {} + + void operator()(datetime_t& date, const amount_t& price) { + if (date.date() > post.value_date() && date.date() < current) { + DEBUG("filters.revalued", + post.value_date() << " < " << date << " < " << current); + DEBUG("filters.revalued", "inserting " << price << " at " << date); + all_prices.insert(price_map_t::value_type(date, price)); + } + } + }; +} + void changed_value_posts::output_intermediate_prices(post_t& post, const date_t& current) { @@ -754,38 +776,17 @@ void changed_value_posts::output_intermediate_prices(post_t& post, // fall through... case value_t::BALANCE: { -#if 0 - // jww (2012-03-04): TODO - commodity_t::history_map all_prices; + price_map_t all_prices; foreach (const balance_t::amounts_map::value_type& amt_comm, - display_total.as_balance().amounts) { - if (optional hist = - amt_comm.first->varied_history()) { - foreach - (const commodity_t::history_by_commodity_map::value_type& comm_hist, - hist->histories) { - foreach (const commodity_t::history_map::value_type& price, - comm_hist.second.prices) { - if (price.first.date() > post.value_date() && - price.first.date() < current) { - DEBUG("filters.revalued", post.value_date() << " < " - << price.first.date() << " < " << current); - DEBUG("filters.revalued", "inserting " - << price.second << " at " << price.first.date()); - all_prices.insert(price); - } - } - } - } - } + display_total.as_balance().amounts) + amt_comm.first->map_prices(create_price_xact(post, current, all_prices)); // Choose the last price from each day as the price to use typedef std::map date_map; date_map pricing_dates; - BOOST_REVERSE_FOREACH - (const commodity_t::history_map::value_type& price, all_prices) { + BOOST_REVERSE_FOREACH(const price_map_t::value_type& price, all_prices) { // This insert will fail if a later price has already been inserted // for that date. DEBUG("filters.revalued", @@ -799,7 +800,6 @@ void changed_value_posts::output_intermediate_prices(post_t& post, output_revaluation(post, price.first); last_total = repriced_total; } -#endif break; } default: diff --git a/src/history.cc b/src/history.cc index a3d9139b..95ed584f 100644 --- a/src/history.cc +++ b/src/history.cc @@ -67,6 +67,9 @@ void commodity_history_t::add_price(const commodity_t& source, if (! result.second) { // There is already an entry for this moment, so update it (*result.first).second = price; + } else { + last_reftime = none; // invalidate the FGraph cache + last_oldest = none; } } @@ -82,64 +85,128 @@ void commodity_history_t::remove_price(const commodity_t& source, // jww (2012-03-04): If it fails, should we give a warning? prices.erase(date); + + last_reftime = none; // invalidate the FGraph cache + last_oldest = none; +} + +void commodity_history_t::map_prices(function fn, + const commodity_t& source, + const datetime_t& moment, + const optional& _oldest) +{ + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); + + reftime = moment; + oldest = _oldest; + + graph_traits::adjacency_iterator f_vi, f_vend; + for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) { + std::pair edgePair = edge(sv, *f_vi, fg); + Graph::edge_descriptor edge = edgePair.first; + + const price_map_t& prices(get(ratiomap, edge)); + + foreach (const price_map_t::value_type& pair, prices) { + const datetime_t& when(pair.first); + + if ((! _oldest || when >= *_oldest) && when <= moment) { + if (pair.second.commodity() == source) { + amount_t price(pair.second); + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + } + fn(when, pair.second); + } + } + } } optional commodity_history_t::find_price(const commodity_t& source, const datetime_t& moment, - const optional& oldest) + const optional& _oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - moment, oldest)); - + DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol()); +#if defined(DEBUG_ON) + if (source.has_flags(COMMODITY_PRIMARY)) + DEBUG("history.find", "sv commodity is primary"); +#endif + DEBUG("history.find", "tv commodity = none "); + datetime_t most_recent = moment; amount_t price; + reftime = moment; + oldest = _oldest; + graph_traits::adjacency_iterator f_vi, f_vend; for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) { std::pair edgePair = edge(sv, *f_vi, fg); Graph::edge_descriptor edge = edgePair.first; + DEBUG("history.find", "u commodity = " << get(namemap, sv)->symbol()); + DEBUG("history.find", "v commodity = " << get(namemap, *f_vi)->symbol()); + const price_point_t& point(get(pricemap, edge)); if (price.is_null() || point.when > most_recent) { most_recent = point.when; price = point.price; } + + DEBUG("history.find", "price was = " << price.unrounded()); + + if (price.commodity() == source) { + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + } + + DEBUG("history.find", "price is = " << price.unrounded()); } - if (price.is_null()) + last_reftime = reftime; // invalidate the FGraph cache + last_oldest = oldest; + + if (price.is_null()) { + DEBUG("history.find", "there is no final price"); return none; - else + } else { + DEBUG("history.find", "final price is = " << price.unrounded()); return price_point_t(most_recent, price); + } } optional commodity_history_t::find_price(const commodity_t& source, const commodity_t& target, const datetime_t& moment, - const optional& oldest) + const optional& _oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - moment, oldest)); - + DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol()); + DEBUG("history.find", "tv commodity = " << get(namemap, tv)->symbol()); + std::vector predecessors(num_vertices(fg)); std::vector distances(num_vertices(fg)); PredecessorMap predecessorMap(&predecessors[0]); DistanceMap distanceMap(&distances[0]); + reftime = moment; + oldest = _oldest; + dijkstra_shortest_paths(fg, /* start= */ sv, predecessor_map(predecessorMap) .distance_map(distanceMap) @@ -149,7 +216,7 @@ commodity_history_t::find_price(const commodity_t& source, datetime_t least_recent = moment; amount_t price; - FNameMap ptrs = get(vertex_name, fg); + const commodity_t * last_target = ⌖ vertex_descriptor v = tv; for (vertex_descriptor u = predecessorMap[v]; @@ -161,73 +228,85 @@ commodity_history_t::find_price(const commodity_t& source, const price_point_t& point(get(pricemap, edge)); - const commodity_t * last_source = &source; - bool first_run = false; if (price.is_null()) { least_recent = point.when; - price = point.price; first_run = true; } else if (point.when < least_recent) { least_recent = point.when; } - DEBUG("history.find", "u commodity = " << get(ptrs, u)->symbol()); - DEBUG("history.find", "v commodity = " << get(ptrs, v)->symbol()); - DEBUG("history.find", "last source = " << last_source->symbol()); + DEBUG("history.find", "u commodity = " << get(namemap, u)->symbol()); + DEBUG("history.find", "v commodity = " << get(namemap, v)->symbol()); + DEBUG("history.find", "last target = " << last_target->symbol()); // Determine which direction we are converting in amount_t pprice(point.price); - DEBUG("history.find", "pprice = " << pprice); + DEBUG("history.find", "pprice = " << pprice.unrounded()); - DEBUG("history.find", "price was = " << price); if (! first_run) { - if (pprice.commodity() == *last_source) + DEBUG("history.find", "price was = " << price.unrounded()); + if (pprice.commodity() != *last_target) price *= pprice.inverted(); else price *= pprice; } - else if (price.commodity() == *last_source) { - price = price.inverted(); + else if (pprice.commodity() != *last_target) { + price = pprice.inverted(); + } + else { + price = pprice; } - DEBUG("history.find", "price is = " << price); + DEBUG("history.find", "price is = " << price.unrounded()); - if (*last_source == *get(ptrs, v)) - last_source = get(ptrs, u); + if (*last_target == *get(namemap, v)) + last_target = get(namemap, u); else - last_source = get(ptrs, v); + last_target = get(namemap, v); + + DEBUG("history.find", "last target now = " << last_target->symbol()); } - price.set_commodity(const_cast(target)); - DEBUG("history.find", "final price is = " << price); + last_reftime = reftime; // invalidate the FGraph cache + last_oldest = oldest; - if (price.is_null()) + if (price.is_null()) { + DEBUG("history.find", "there is no final price"); return none; - else + } else { + price.set_commodity(const_cast(target)); + DEBUG("history.find", "final price is = " << price.unrounded()); + return price_point_t(least_recent, price); + } } +template +class label_writer { +public: + label_writer(Name _name) : name(_name) {} + + template + void operator()(std::ostream& out, const VertexOrEdge& v) const { + out << "[label=\"" << name[v]->symbol() << "\"]"; + } + +private: + Name name; +}; + void commodity_history_t::print_map(std::ostream& out, const optional& moment) { -#if 0 - dynamic_properties p; - p.property("label", get(edge_weight, price_graph)); - p.property("weight", get(edge_weight, price_graph)); - p.property("node_id", get(vertex_index, price_graph)); - if (moment) { - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - *moment)); - write_graphviz(out, fg, p); + reftime = *moment; + write_graphviz(out, fg, label_writer(namemap)); + last_reftime = reftime; } else { - write_graphviz(out, price_graph, p); + write_graphviz(out, price_graph, + label_writer(get(vertex_name, price_graph))); } -#endif } } // namespace ledger diff --git a/src/history.h b/src/history.h index 70831445..eaca07ac 100644 --- a/src/history.h +++ b/src/history.h @@ -70,36 +70,50 @@ public: PricePointMap price_point; PriceRatioMap ratios; - datetime_t reftime; - optional oldest; + datetime_t * reftime; + optional * last_reftime; + optional * oldest; + optional * last_oldest; recent_edge_weight() { } - recent_edge_weight(EdgeWeightMap _weight, - PricePointMap _price_point, - PriceRatioMap _ratios, - datetime_t _reftime, - const optional& _oldest = none) + recent_edge_weight(EdgeWeightMap _weight, + PricePointMap _price_point, + PriceRatioMap _ratios, + datetime_t * _reftime, + optional * _last_reftime, + optional * _oldest, + optional * _last_oldest) : weight(_weight), price_point(_price_point), ratios(_ratios), - reftime(_reftime), oldest(_oldest) { } + reftime(_reftime), last_reftime(_last_reftime), + oldest(_oldest), last_oldest(_last_oldest) { } template bool operator()(const Edge& e) const { + if (*last_reftime && *reftime == **last_reftime && + *oldest == *last_oldest) + return get(weight, e) != std::numeric_limits::max(); + const price_map_t& prices(get(ratios, e)); - if (prices.empty()) + if (prices.empty()) { + put(weight, e, std::numeric_limits::max()); return false; + } - price_map_t::const_iterator low = prices.upper_bound(reftime); + price_map_t::const_iterator low = prices.upper_bound(*reftime); if (low != prices.end() && low == prices.begin()) { + put(weight, e, std::numeric_limits::max()); return false; } else { --low; - assert(((*low).first <= reftime)); + assert(((*low).first <= *reftime)); - if (oldest && (*low).first < *oldest) + if (*oldest && (*low).first < **oldest) { + put(weight, e, std::numeric_limits::max()); return false; + } - long secs = (reftime - (*low).first).total_seconds(); + long secs = (*reftime - (*low).first).total_seconds(); assert(secs >= 0); put(weight, e, secs); @@ -160,10 +174,24 @@ public: PriceRatioMap> > FGraph; typedef property_map::type FNameMap; + FGraph fg; + FNameMap namemap; + + // jww (2012-03-05): Prevents threading + mutable datetime_t reftime; + mutable optional last_reftime; + mutable optional oldest; + mutable optional last_oldest; + commodity_history_t() : indexmap(get(vertex_index, price_graph)), pricemap(get(edge_price_point, price_graph)), - ratiomap(get(edge_price_ratio, price_graph)) {} + ratiomap(get(edge_price_ratio, price_graph)), + fg(price_graph, + recent_edge_weight + (get(edge_weight, price_graph), pricemap, ratiomap, + &reftime, &last_reftime, &oldest, &last_oldest)), + namemap(get(vertex_name, fg)) {} void add_commodity(commodity_t& comm); @@ -174,6 +202,11 @@ public: const commodity_t& target, const datetime_t& date); + void map_prices(function fn, + const commodity_t& source, + const datetime_t& moment, + const optional& _oldest = none); + optional find_price(const commodity_t& source, const datetime_t& moment, diff --git a/src/iterators.cc b/src/iterators.cc index b7ed011e..b994d59a 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -75,6 +75,55 @@ void journal_posts_iterator::increment() } } +namespace { + struct create_price_xact { + account_t * account; + temporaries_t& temps; + xacts_list& xact_temps; + + std::map xacts_by_commodity; + + create_price_xact(account_t * _account, temporaries_t& _temps, + xacts_list& _xact_temps) + : account(_account), temps(_temps), xact_temps(_xact_temps) {} + + void operator()(datetime_t& date, const amount_t& price) { + xact_t * xact; + string symbol = price.commodity().symbol(); + + std::map::iterator i = + xacts_by_commodity.find(symbol); + if (i != xacts_by_commodity.end()) { + xact = (*i).second; + } else { + xact = &temps.create_xact(); + xact_temps.push_back(xact); + xact->payee = symbol; + xact->_date = date.date(); + xacts_by_commodity.insert + (std::pair(symbol, xact)); + } + + bool post_already_exists = false; + + foreach (post_t * post, xact->posts) { + if (post->date() == date.date() && post->amount == price) { + post_already_exists = true; + break; + } + } + + if (! post_already_exists) { + post_t& temp = temps.create_post(*xact, account); + temp._date = date.date(); + temp.amount = price; + + temp.xdata().datetime = date; + } + } + }; +} + void posts_commodities_iterator::reset(journal_t& journal) { journal_posts.reset(journal); @@ -88,57 +137,10 @@ void posts_commodities_iterator::reset(journal_t& journal) commodities.insert(&comm); } - std::map xacts_by_commodity; - -#if 0 - // jww (2012-03-04): TODO - foreach (commodity_t * comm, commodities) { - if (optional history = - comm->varied_history()) { - account_t * account = journal.master->find_account(comm->symbol()); - - foreach (commodity_t::history_by_commodity_map::value_type& pair, - history->histories) { - foreach (commodity_t::history_map::value_type& hpair, - pair.second.prices) { - xact_t * xact; - string symbol = hpair.second.commodity().symbol(); - - std::map::iterator i = - xacts_by_commodity.find(symbol); - if (i != xacts_by_commodity.end()) { - xact = (*i).second; - } else { - xact = &temps.create_xact(); - xact_temps.push_back(xact); - xact->payee = symbol; - xact->_date = hpair.first.date(); - xacts_by_commodity.insert - (std::pair(symbol, xact)); - } - - bool post_already_exists = false; - - foreach (post_t * post, xact->posts) { - if (post->_date == hpair.first.date() && - post->amount == hpair.second) { - post_already_exists = true; - break; - } - } - - if (! post_already_exists) { - post_t& temp = temps.create_post(*xact, account); - temp._date = hpair.first.date(); - temp.amount = hpair.second; - - temp.xdata().datetime = hpair.first; - } - } - } - } - } -#endif + foreach (commodity_t * comm, commodities) + comm->map_prices + (create_price_xact(journal.master->find_account(comm->symbol()), + temps, xact_temps)); xacts.reset(xact_temps.begin(), xact_temps.end()); diff --git a/test/baseline/feat-fixated-prices.test b/test/baseline/feat-fixated-prices.test index f4370870..4767d866 100644 --- a/test/baseline/feat-fixated-prices.test +++ b/test/baseline/feat-fixated-prices.test @@ -1,3 +1,5 @@ +P 1989/01/15 12:00:00 GAL $3 + 1990/01/01 Payee Expenses:Gas 100 GAL {=$2} Liabilities:MasterCard $-200 diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index fc06449b..48b6814e 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -2,16 +2,16 @@ test -f $sourcepath/src/amount.h reg -> 7 __ERROR__ While parsing file "$sourcepath/src/amount.h", line 66: Error: No quantity specified for amount -While parsing file "$sourcepath/src/amount.h", line 726: +While parsing file "$sourcepath/src/amount.h", line 731: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 732: +While parsing file "$sourcepath/src/amount.h", line 737: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 738: +While parsing file "$sourcepath/src/amount.h", line 743: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 744: +While parsing file "$sourcepath/src/amount.h", line 749: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 750: +While parsing file "$sourcepath/src/amount.h", line 755: Error: Invalid date/time: line std::ostream& -While parsing file "$sourcepath/src/amount.h", line 757: +While parsing file "$sourcepath/src/amount.h", line 762: Error: Invalid date/time: line std::istream& end test diff --git a/test/unit/t_commodity.cc b/test/unit/t_commodity.cc index dc64dcfb..6a6f27aa 100644 --- a/test/unit/t_commodity.cc +++ b/test/unit/t_commodity.cc @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(testPriceHistory) amt = x1.value(CURRENT_TIME(), euro); BOOST_CHECK(amt); - BOOST_CHECK_EQUAL(string("EUR 1366.87"), amt->rounded().to_string()); + BOOST_CHECK_EQUAL(string("EUR 1787.50"), amt->rounded().to_string()); // Add a newer Euro pricing aapl.add_price(jan17_07, amount_t("EUR 23.00")); -- cgit v1.2.3 From 3ea5d88eb3ddfd8cac248fe96fdaa293e3b5bf70 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 02:26:15 -0600 Subject: The last test is closer to working now --- src/filters.cc | 22 ++++++++-------------- src/history.h | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 15 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 6e52c40f..8543cddb 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -690,22 +690,14 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) } namespace { - struct create_price_xact { - post_t& post; - const date_t& current; - price_map_t& all_prices; + struct insert_prices_in_map { + price_map_t& all_prices; - create_price_xact(post_t& _post, const date_t& _current, - price_map_t& _all_prices) - : post(_post), current(_current), all_prices(_all_prices) {} + insert_prices_in_map(price_map_t& _all_prices) + : all_prices(_all_prices) {} void operator()(datetime_t& date, const amount_t& price) { - if (date.date() > post.value_date() && date.date() < current) { - DEBUG("filters.revalued", - post.value_date() << " < " << date << " < " << current); - DEBUG("filters.revalued", "inserting " << price << " at " << date); - all_prices.insert(price_map_t::value_type(date, price)); - } + all_prices.insert(price_map_t::value_type(date, price)); } }; } @@ -780,7 +772,9 @@ void changed_value_posts::output_intermediate_prices(post_t& post, foreach (const balance_t::amounts_map::value_type& amt_comm, display_total.as_balance().amounts) - amt_comm.first->map_prices(create_price_xact(post, current, all_prices)); + amt_comm.first->map_prices(insert_prices_in_map(all_prices), + datetime_t(current), + datetime_t(post.value_date())); // Choose the last price from each day as the price to use typedef std::map date_map; diff --git a/src/history.h b/src/history.h index eaca07ac..6430202b 100644 --- a/src/history.h +++ b/src/history.h @@ -90,18 +90,30 @@ public: template bool operator()(const Edge& e) const { + DEBUG("history.find", " reftime = " << *reftime); + if (*last_reftime) + DEBUG("history.find", " last_reftime = " << **last_reftime); + if (*oldest) + DEBUG("history.find", " oldest = " << **oldest); + if (*last_oldest) + DEBUG("history.find", " last_oldest = " << **last_oldest); + if (*last_reftime && *reftime == **last_reftime && - *oldest == *last_oldest) + *oldest == *last_oldest) { + DEBUG("history.find", " using previous reftime"); return get(weight, e) != std::numeric_limits::max(); + } const price_map_t& prices(get(ratios, e)); if (prices.empty()) { + DEBUG("history.find", " prices map is empty for this edge"); put(weight, e, std::numeric_limits::max()); return false; } price_map_t::const_iterator low = prices.upper_bound(*reftime); if (low != prices.end() && low == prices.begin()) { + DEBUG("history.find", " don't use this edge"); put(weight, e, std::numeric_limits::max()); return false; } else { @@ -109,6 +121,7 @@ public: assert(((*low).first <= *reftime)); if (*oldest && (*low).first < **oldest) { + DEBUG("history.find", " edge is out of range"); put(weight, e, std::numeric_limits::max()); return false; } @@ -119,6 +132,8 @@ public: put(weight, e, secs); put(price_point, e, price_point_t((*low).first, (*low).second)); + DEBUG("history.find", " using edge at price point " + << (*low).first << " " << (*low).second); return true; } } -- cgit v1.2.3 From 71d0033b6f65260698cf0bf367002a9b6429a3fd Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 6 Mar 2012 23:04:27 -0600 Subject: Corrected several compile and link problems --- src/account.cc | 6 ++++-- src/amount.cc | 2 ++ src/draft.cc | 7 +++++++ src/filters.cc | 13 +++++++++++-- src/format.cc | 2 ++ src/op.cc | 10 ++++++++++ src/op.h | 8 ++------ src/pool.cc | 18 +++++++++++------- src/pyinterp.cc | 1 + src/query.h | 1 + src/textual.cc | 10 +++++++--- src/times.h | 2 ++ src/xact.cc | 2 ++ 13 files changed, 62 insertions(+), 20 deletions(-) (limited to 'src/filters.cc') diff --git a/src/account.cc b/src/account.cc index e1874839..29c05719 100644 --- a/src/account.cc +++ b/src/account.cc @@ -89,8 +89,10 @@ account_t * account_t::find_account(const string& acct_name, if (has_flags(ACCOUNT_GENERATED)) account->add_flags(ACCOUNT_GENERATED); - std::pair result - = accounts.insert(accounts_map::value_type(first, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + accounts.insert(accounts_map::value_type(first, account)); assert(result.second); } else { account = (*i).second; diff --git a/src/amount.cc b/src/amount.cc index f9e2309b..313f8d27 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -120,11 +120,13 @@ namespace { { char * buf = NULL; try { +#if defined(DEBUG_ON) IF_DEBUG("amount.convert") { char * tbuf = mpq_get_str(NULL, 10, quant); DEBUG("amount.convert", "Rational to convert = " << tbuf); std::free(tbuf); } +#endif // Convert the rational number to a floating-point, extending the // floating-point to a large enough size to get a precise answer. diff --git a/src/draft.cc b/src/draft.cc index 017c637d..9abc769e 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -109,7 +109,14 @@ void draft_t::parse_args(const value_t& args) } else if (check_for_date && bool(weekday = string_to_day_of_week(what[0]))) { +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif short dow = static_cast(*weekday); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif date_t date = CURRENT_DATE() - date_duration(1); while (date.day_of_week() != dow) date -= date_duration(1); diff --git a/src/filters.cc b/src/filters.cc index 8543cddb..34df2056 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -833,10 +833,17 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, foreach (post_t * post, component_posts) { date_t date = post->date(); date_t value_date = post->value_date(); +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif if (! range_start || date < *range_start) range_start = date; if (! range_finish || value_date > *range_finish) range_finish = value_date; +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#pragma GCC diagnostic pop +#endif } } component_posts.clear(); @@ -880,8 +887,10 @@ void subtotal_posts::operator()(post_t& post) if (i == values.end()) { value_t temp; post.add_to_value(temp, amount_expr); - std::pair result - = values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); +#if defined(DEBUG_ON) + std::pair result = +#endif + values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); assert(result.second); } else { post.add_to_value((*i).second.value, amount_expr); diff --git a/src/format.cc b/src/format.cc index d8c03e6a..79f94869 100644 --- a/src/format.cc +++ b/src/format.cc @@ -221,8 +221,10 @@ format_t::element_t * format_t::parse_elements(const string& fmt, static_cast(current->max_width) : -1); else if (keyword == "left") expr << (current->has_flags(ELEMENT_ALIGN_LEFT) ? "false" : "true"); +#if defined(DEBUG_ON) else assert("Unrecognized format substitution keyword" == NULL); +#endif } else { expr << *ptr++; } diff --git a/src/op.cc b/src/op.cc index 56d3710e..1889f2aa 100644 --- a/src/op.cc +++ b/src/op.cc @@ -38,6 +38,16 @@ namespace ledger { +void intrusive_ptr_add_ref(const expr_t::op_t * op) +{ + op->acquire(); +} + +void intrusive_ptr_release(const expr_t::op_t * op) +{ + op->release(); +} + namespace { value_t split_cons_expr(expr_t::ptr_op_t op) { diff --git a/src/op.h b/src/op.h index 192c1f5e..1807cdd7 100644 --- a/src/op.h +++ b/src/op.h @@ -260,12 +260,8 @@ private: checked_delete(this); } - friend inline void intrusive_ptr_add_ref(const op_t * op) { - op->acquire(); - } - friend inline void intrusive_ptr_release(const op_t * op) { - op->release(); - } + friend void intrusive_ptr_add_ref(const op_t * op); + friend void intrusive_ptr_release(const op_t * op); ptr_op_t copy(ptr_op_t _left = NULL, ptr_op_t _right = NULL) const { ptr_op_t node(new_node(kind, _left, _right)); diff --git a/src/pool.cc b/src/pool.cc index ca50db2c..a6ae0919 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -70,9 +70,11 @@ commodity_t * commodity_pool_t::create(const string& symbol) DEBUG("pool.commodities", "Creating commodity '" << commodity->symbol() << "'"); - std::pair result - = commodities.insert(commodities_map::value_type - (commodity->base_symbol(), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + commodities.insert(commodities_map::value_type + (commodity->base_symbol(), commodity)); assert(result.second); commodity_price_history.add_commodity(*commodity.get()); @@ -211,10 +213,12 @@ commodity_pool_t::create(commodity_t& comm, << "symbol " << commodity->symbol() << std::endl << details); - std::pair result - = annotated_commodities.insert(annotated_commodities_map::value_type - (annotated_commodities_map::key_type - (comm.symbol(), details), commodity)); +#if defined(DEBUG_ON) + std::pair result = +#endif + annotated_commodities.insert(annotated_commodities_map::value_type + (annotated_commodities_map::key_type + (comm.symbol(), details), commodity)); assert(result.second); return commodity.get(); diff --git a/src/pyinterp.cc b/src/pyinterp.cc index d733c40d..d1f46580 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -535,6 +535,7 @@ namespace { case value_t::ANY: // a pointer to an arbitrary object return object(val); } + return object(); } } diff --git a/src/query.h b/src/query.h index f95988a7..7286e89b 100644 --- a/src/query.h +++ b/src/query.h @@ -186,6 +186,7 @@ public: assert(false); return ""; } + return ""; } void unexpected(); diff --git a/src/textual.cc b/src/textual.cc index cf15f048..258a4d76 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -107,10 +107,12 @@ namespace { return (in.good() && ! in.eof() && (in.peek() == ' ' || in.peek() == '\t')); } +#if defined(HAVE_BOOST_PYTHON) bool peek_blank_line() { return (in.good() && ! in.eof() && (in.peek() == '\n' || in.peek() == '\r')); } +#endif void read_next_directive(); @@ -943,9 +945,11 @@ void instance_t::account_alias_directive(account_t * account, string alias) // (account), add a reference to the account in the `account_aliases' // map, which is used by the post parser to resolve alias references. trim(alias); - std::pair result - = context.journal - ->account_aliases.insert(accounts_map::value_type(alias, account)); +#if defined(DEBUG_ON) + std::pair result = +#endif + context.journal->account_aliases.insert + (accounts_map::value_type(alias, account)); assert(result.second); } diff --git a/src/times.h b/src/times.h index 6eadcad3..edc6d8b8 100644 --- a/src/times.h +++ b/src/times.h @@ -218,6 +218,7 @@ struct date_duration_t case YEARS: return date + gregorian::years(length); } + return date_t(); } date_t subtract(const date_t& date) const { @@ -233,6 +234,7 @@ struct date_duration_t case YEARS: return date - gregorian::years(length); } + return date_t(); } string to_string() const { diff --git a/src/xact.cc b/src/xact.cc index 5cec9ab0..5c43558d 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -336,7 +336,9 @@ bool xact_base_t::finalize() amount_t> sorted_amounts_map; sorted_amounts_map samp; foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) { +#if defined(DEBUG_ON) std::pair result = +#endif samp.insert(sorted_amounts_map::value_type (sorted_amounts_map::key_type (pair.first->symbol(), -- cgit v1.2.3 From 7bb83173dae617b8e754fff8e52390ff9664873b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 08:34:15 -0600 Subject: Added some missing DEBUG #if's --- src/account.cc | 2 ++ src/filters.cc | 2 ++ src/pool.cc | 4 ++++ src/textual.cc | 2 ++ src/xact.cc | 2 ++ 5 files changed, 12 insertions(+) (limited to 'src/filters.cc') diff --git a/src/account.cc b/src/account.cc index 29c05719..d772368c 100644 --- a/src/account.cc +++ b/src/account.cc @@ -93,7 +93,9 @@ account_t * account_t::find_account(const string& acct_name, std::pair result = #endif accounts.insert(accounts_map::value_type(first, account)); +#if defined(DEBUG_ON) assert(result.second); +#endif } else { account = (*i).second; } diff --git a/src/filters.cc b/src/filters.cc index 34df2056..3a975920 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -891,7 +891,9 @@ void subtotal_posts::operator()(post_t& post) std::pair result = #endif values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); +#if defined(DEBUG_ON) assert(result.second); +#endif } else { post.add_to_value((*i).second.value, amount_expr); } diff --git a/src/pool.cc b/src/pool.cc index a6ae0919..fd661fe1 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -75,7 +75,9 @@ commodity_t * commodity_pool_t::create(const string& symbol) #endif commodities.insert(commodities_map::value_type (commodity->base_symbol(), commodity)); +#if defined(DEBUG_ON) assert(result.second); +#endif commodity_price_history.add_commodity(*commodity.get()); @@ -219,7 +221,9 @@ commodity_pool_t::create(commodity_t& comm, annotated_commodities.insert(annotated_commodities_map::value_type (annotated_commodities_map::key_type (comm.symbol(), details), commodity)); +#if defined(DEBUG_ON) assert(result.second); +#endif return commodity.get(); } diff --git a/src/textual.cc b/src/textual.cc index 1d1835e3..66972fb3 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -950,7 +950,9 @@ void instance_t::account_alias_directive(account_t * account, string alias) #endif context.journal->account_aliases.insert (accounts_map::value_type(alias, account)); +#if defined(DEBUG_ON) assert(result.second); +#endif } void instance_t::alias_directive(char * line) diff --git a/src/xact.cc b/src/xact.cc index 4ec40f69..4e43e680 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -346,7 +346,9 @@ bool xact_base_t::finalize() as_annotated_commodity(*pair.first).details : annotation_t()), pair.second)); +#if defined(DEBUG_ON) assert(result.second); +#endif } bool first = true; -- cgit v1.2.3 From f35f68823a2054e99ef720ca78cbaf33f4188391 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 13 Mar 2012 00:04:44 -0500 Subject: The anonymizer wasn't properly setting the journal --- src/filters.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 3a975920..9501856e 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -263,6 +263,8 @@ void anonymize_posts::operator()(post_t& post) xact.payee = to_hex(message_digest); xact.note = none; + } else { + xact.journal = post.xact->journal; } std::list account_names; -- cgit v1.2.3 From 610a3e170994dc3cd3ae0dc989a49e4e7c7fdadf Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 15 Mar 2012 04:47:32 -0500 Subject: Don't map_prices if price commodity matches source Fixes #680 --- src/commodity.cc | 6 ++++-- src/commodity.h | 3 ++- src/filters.cc | 2 +- src/history.cc | 32 ++++++++++++++++++++++++-------- src/history.h | 3 ++- src/pool.cc | 3 +++ test/regress/786A3DD0.test | 17 +++++++++++++++++ 7 files changed, 53 insertions(+), 13 deletions(-) create mode 100644 test/regress/786A3DD0.test (limited to 'src/filters.cc') diff --git a/src/commodity.cc b/src/commodity.cc index 8f0dc100..0dad9a1a 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -72,7 +72,8 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) void commodity_t::map_prices(function fn, const datetime_t& moment, - const datetime_t& _oldest) + const datetime_t& _oldest, + bool bidirectionally) { datetime_t when; if (! moment.is_not_a_date_time()) @@ -82,7 +83,8 @@ void commodity_t::map_prices(function fn, else when = CURRENT_TIME(); - pool().commodity_price_history.map_prices(fn, *this, when, _oldest); + pool().commodity_price_history.map_prices(fn, *this, when, _oldest, + bidirectionally); } optional diff --git a/src/commodity.h b/src/commodity.h index bd1aedb9..148a3636 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -273,7 +273,8 @@ public: void map_prices(function fn, const datetime_t& moment = datetime_t(), - const datetime_t& _oldest = datetime_t()); + const datetime_t& _oldest = datetime_t(), + bool bidirectionally = false); optional find_price_from_expr(expr_t& expr, const commodity_t * commodity, diff --git a/src/filters.cc b/src/filters.cc index 9501856e..d5cb8ebb 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -776,7 +776,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, display_total.as_balance().amounts) amt_comm.first->map_prices(insert_prices_in_map(all_prices), datetime_t(current), - datetime_t(post.value_date())); + datetime_t(post.value_date()), true); // Choose the last price from each day as the price to use typedef std::map date_map; diff --git a/src/history.cc b/src/history.cc index fcb80d67..3767c1df 100644 --- a/src/history.cc +++ b/src/history.cc @@ -132,6 +132,8 @@ void commodity_history_t::add_price(const commodity_t& source, const datetime_t& when, const amount_t& price) { + assert(source != price.commodity()); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*price.commodity().graph_index(), price_graph); @@ -153,6 +155,8 @@ void commodity_history_t::remove_price(const commodity_t& source, const commodity_t& target, const datetime_t& date) { + assert(source != target); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); @@ -172,8 +176,11 @@ void commodity_history_t::map_prices(function fn, const commodity_t& source, const datetime_t& moment, - const datetime_t& oldest) + const datetime_t& oldest, + bool bidirectionally) { + DEBUG("history.map", "Mapping prices for source commodity: " << source); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); FGraph fg(price_graph, @@ -193,16 +200,23 @@ void commodity_history_t::map_prices(function= oldest) && when <= moment) { if (pair.second.commodity() == source) { - amount_t price(pair.second); - price.in_place_invert(); - if (source == *get(namemap, sv)) - price.set_commodity(const_cast(*get(namemap, *f_vi))); - else - price.set_commodity(const_cast(*get(namemap, sv))); + if (bidirectionally) { + amount_t price(pair.second); + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + DEBUG("history.map", "Inverted price is " << price); + fn(when, price); + } + } else { + fn(when, pair.second); } - fn(when, pair.second); } } } @@ -275,6 +289,8 @@ commodity_history_t::find_price(const commodity_t& source, const datetime_t& moment, const datetime_t& oldest) { + assert(source != target); + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); diff --git a/src/history.h b/src/history.h index 71cbad0c..af0d90f9 100644 --- a/src/history.h +++ b/src/history.h @@ -113,7 +113,8 @@ public: void map_prices(function fn, const commodity_t& source, const datetime_t& moment, - const datetime_t& _oldest = datetime_t()); + const datetime_t& _oldest = datetime_t(), + bool bidirectionally = false); optional find_price(const commodity_t& source, diff --git a/src/pool.cc b/src/pool.cc index 0118a97d..d5494352 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -266,6 +266,9 @@ commodity_pool_t::exchange(const amount_t& amount, amount_t per_unit_cost = (is_per_unit || amount.is_realzero()) ? cost.abs() : (cost / amount).abs(); + if (! cost.has_commodity()) + per_unit_cost.clear_commodity(); + DEBUG("commodity.prices.add", "exchange: per-unit-cost = " << per_unit_cost); // Do not record commodity exchanges where amount's commodity has a diff --git a/test/regress/786A3DD0.test b/test/regress/786A3DD0.test new file mode 100644 index 00000000..051f6382 --- /dev/null +++ b/test/regress/786A3DD0.test @@ -0,0 +1,17 @@ +D 1000.00 EUR + +2011-02-27 * Australia + A -100.00 AUD @ 0.746 EUR + B + +2012-03-12 * Withdrawal + Assets:Cash USD 200.00 + Expenses:Banking:Fees USD 2.50 + Assets:Chequing CAD -203.42 + Epenses:Banking:Fees CAD 2.00 + Assets:Chqeuing CAD -2.00 + +test pricedb +P 2011/02/27 00:00:00 AUD 0.746 EUR +P 2012/03/12 00:00:00 USD CAD 1.00454320987654321 +end test -- cgit v1.2.3 From 09cf0cbb2ae3690b357fc04d6f80476b8d60ce37 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 17 Mar 2012 23:14:17 -0500 Subject: Change some #if guards to test for gcc 4.7 --- src/draft.cc | 4 ++-- src/filters.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/filters.cc') diff --git a/src/draft.cc b/src/draft.cc index 74a6f4d2..7edf7edc 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -109,12 +109,12 @@ void draft_t::parse_args(const value_t& args) } else if (check_for_date && bool(weekday = string_to_day_of_week(what[0]))) { -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif short dow = static_cast(*weekday); -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic pop #endif date_t date = CURRENT_DATE() - date_duration(1); diff --git a/src/filters.cc b/src/filters.cc index d5cb8ebb..6fedd7ce 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -835,7 +835,7 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, foreach (post_t * post, component_posts) { date_t date = post->date(); date_t value_date = post->value_date(); -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -843,7 +843,7 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, range_start = date; if (! range_finish || value_date > *range_finish) range_finish = value_date; -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic pop #endif } -- cgit v1.2.3 From 20edb3a34069b33ec83846c3026138d8fa432c97 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 18 Mar 2012 02:33:25 -0500 Subject: Fixed bug relating to historical pricing Fixes #681 --- src/filters.cc | 11 +++++++---- src/filters.h | 1 + test/regress/14DB77E7.test | 2 +- test/regress/9E0E606D.test | 19 +++++++++++++++++++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 test/regress/9E0E606D.test (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 6fedd7ce..749efc77 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -593,6 +593,7 @@ changed_value_posts::changed_value_posts report.HANDLER(display_total_).expr), display_total_expr(report.HANDLER(display_total_).expr), changed_values_only(report.HANDLED(revalued_only)), + historical_prices_only(report.HANDLED(historical)), for_accounts_report(_for_accounts_report), show_unrealized(_show_unrealized), last_post(NULL), display_filter(_display_filter) @@ -624,9 +625,11 @@ changed_value_posts::changed_value_posts void changed_value_posts::flush() { if (last_post && last_post->date() <= report.terminus.date()) { - if (! for_accounts_report) - output_intermediate_prices(*last_post, report.terminus.date()); - output_revaluation(*last_post, report.terminus.date()); + if (! historical_prices_only) { + if (! for_accounts_report) + output_intermediate_prices(*last_post, report.terminus.date()); + output_revaluation(*last_post, report.terminus.date()); + } last_post = NULL; } item_handler::flush(); @@ -807,7 +810,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, void changed_value_posts::operator()(post_t& post) { if (last_post) { - if (! for_accounts_report) + if (! for_accounts_report && ! historical_prices_only) output_intermediate_prices(*last_post, post.value_date()); output_revaluation(*last_post, post.value_date()); } diff --git a/src/filters.h b/src/filters.h index 1ef92bbe..d73fff86 100644 --- a/src/filters.h +++ b/src/filters.h @@ -576,6 +576,7 @@ class changed_value_posts : public item_handler expr_t& total_expr; expr_t& display_total_expr; bool changed_values_only; + bool historical_prices_only; bool for_accounts_report; bool show_unrealized; post_t * last_post; diff --git a/test/regress/14DB77E7.test b/test/regress/14DB77E7.test index ee155afb..4d8734f9 100644 --- a/test/regress/14DB77E7.test +++ b/test/regress/14DB77E7.test @@ -13,6 +13,6 @@ P 2011-02-01 EUR 0.8576 GBP test reg income:adse -X GBP -H 11-Jan-31 AdSense earnings Income:AdSense -11.00 EUR -11.00 EUR -11-Feb-01 Commodities revalued -9.43 GBP -9.43 GBP +11-Feb-28 Commodities revalued -9.43 GBP -9.43 GBP 11-Feb-28 AdSense earnings Income:AdSense -8.58 GBP -18.01 GBP end test diff --git a/test/regress/9E0E606D.test b/test/regress/9E0E606D.test new file mode 100644 index 00000000..86b8e36f --- /dev/null +++ b/test/regress/9E0E606D.test @@ -0,0 +1,19 @@ +D 1000.00 GBP + +P 2011-02-01 EUR 0.8576 GBP +P 2011-03-01 EUR 0.8612 GBP +P 2011-04-01 EUR 0.8510 GBP + +2011-01-31 * AdSense earnings + Assets:Receivable:AdSense 11.00 EUR + Income:AdSense + +2011-02-28 * AdSense earnings + Assets:Receivable:AdSense 10.00 EUR + Income:AdSense + +test reg income:ad -X GBP -H +11-Jan-31 AdSense earnings Income:AdSense -11.00 EUR -11.00 EUR +11-Feb-28 Commodities revalued -9.43 GBP -9.43 GBP +11-Feb-28 AdSense earnings Income:AdSense -8.58 GBP -18.01 GBP +end test -- cgit v1.2.3 From d2422f99e6edd17b86502b34be4fb618fe4c838d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 19 Mar 2012 04:18:56 -0500 Subject: Allow the equity command to strip annotations --- src/chain.cc | 2 +- src/filters.cc | 47 ++++++++++++++++++++++++++--------------------- src/filters.h | 6 ++++-- 3 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src/filters.cc') diff --git a/src/chain.cc b/src/chain.cc index 44b3db82..52d52f14 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -207,7 +207,7 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler, // day_of_week_posts is like period_posts, except that it reports // all the posts that fall on each subsequent day of the week. if (report.HANDLED(equity)) - handler.reset(new posts_as_equity(handler, expr)); + handler.reset(new posts_as_equity(handler, report, expr)); else if (report.HANDLED(subtotal)) handler.reset(new subtotal_posts(handler, expr)); } diff --git a/src/filters.cc b/src/filters.cc index 749efc77..96e8026a 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1033,40 +1033,45 @@ void posts_as_equity::report_subtotal() value_t total = 0L; foreach (values_map::value_type& pair, values) { - if (pair.second.value.is_balance()) { - foreach (const balance_t::amounts_map::value_type& amount_pair, - pair.second.value.as_balance().amounts) - handle_value(/* value= */ amount_pair.second, + value_t value(pair.second.value.strip_annotations(report.what_to_keep())); + if (! value.is_zero()) { + if (value.is_balance()) { + foreach (const balance_t::amounts_map::value_type& amount_pair, + value.as_balance_lval().amounts) + handle_value(/* value= */ amount_pair.second, + /* account= */ pair.second.account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ finish, + /* act_date_p= */ false); + } else { + handle_value(/* value= */ value.to_amount(), /* account= */ pair.second.account, /* xact= */ &xact, /* temps= */ temps, /* handler= */ handler, /* date= */ finish, /* act_date_p= */ false); - } else { - handle_value(/* value= */ pair.second.value, - /* account= */ pair.second.account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler, - /* date= */ finish, - /* act_date_p= */ false); + } } - total += pair.second.value; + total += value; } values.clear(); - if (total.is_balance()) { - foreach (const balance_t::amounts_map::value_type& pair, - total.as_balance().amounts) { + if (! total.is_zero()) { + if (total.is_balance()) { + foreach (const balance_t::amounts_map::value_type& pair, + total.as_balance().amounts) { + post_t& balance_post = temps.create_post(xact, balance_account); + balance_post.amount = - pair.second; + (*handler)(balance_post); + } + } else { post_t& balance_post = temps.create_post(xact, balance_account); - balance_post.amount = - pair.second; + balance_post.amount = - total.to_amount(); (*handler)(balance_post); } - } else { - post_t& balance_post = temps.create_post(xact, balance_account); - balance_post.amount = - total.to_amount(); - (*handler)(balance_post); } } diff --git a/src/filters.h b/src/filters.h index d73fff86..3e766863 100644 --- a/src/filters.h +++ b/src/filters.h @@ -763,6 +763,7 @@ public: class posts_as_equity : public subtotal_posts { + report_t& report; post_t * last_post; account_t * equity_account; account_t * balance_account; @@ -770,8 +771,9 @@ class posts_as_equity : public subtotal_posts posts_as_equity(); public: - posts_as_equity(post_handler_ptr _handler, expr_t& amount_expr) - : subtotal_posts(_handler, amount_expr) { + posts_as_equity(post_handler_ptr _handler, report_t& _report, + expr_t& amount_expr) + : subtotal_posts(_handler, amount_expr), report(_report) { TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); create_accounts(); } -- cgit v1.2.3 From ceb8dd89a6740c218d17ed01dbe5a7e8a37be2f0 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 19 Mar 2012 04:21:15 -0500 Subject: Don't output zero balances with the equity command --- src/filters.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 96e8026a..73ee200d 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1037,14 +1037,16 @@ void posts_as_equity::report_subtotal() if (! value.is_zero()) { if (value.is_balance()) { foreach (const balance_t::amounts_map::value_type& amount_pair, - value.as_balance_lval().amounts) - handle_value(/* value= */ amount_pair.second, - /* account= */ pair.second.account, - /* xact= */ &xact, - /* temps= */ temps, - /* handler= */ handler, - /* date= */ finish, - /* act_date_p= */ false); + value.as_balance_lval().amounts) { + if (! amount_pair.second.is_zero()) + handle_value(/* value= */ amount_pair.second, + /* account= */ pair.second.account, + /* xact= */ &xact, + /* temps= */ temps, + /* handler= */ handler, + /* date= */ finish, + /* act_date_p= */ false); + } } else { handle_value(/* value= */ value.to_amount(), /* account= */ pair.second.account, @@ -1063,9 +1065,11 @@ void posts_as_equity::report_subtotal() if (total.is_balance()) { foreach (const balance_t::amounts_map::value_type& pair, total.as_balance().amounts) { - post_t& balance_post = temps.create_post(xact, balance_account); - balance_post.amount = - pair.second; - (*handler)(balance_post); + if (! pair.second.is_zero()) { + post_t& balance_post = temps.create_post(xact, balance_account); + balance_post.amount = - pair.second; + (*handler)(balance_post); + } } } else { post_t& balance_post = temps.create_post(xact, balance_account); -- cgit v1.2.3 From 22505d9527edce59cd3cf90c5241e4bd809eb8a2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 20 Mar 2012 02:10:40 -0500 Subject: Always call TRACE_CTOR at the end of constructors --- src/amount.cc | 10 +++++----- src/amount.h | 8 ++++---- src/annotate.h | 2 +- src/balance.cc | 6 +++--- src/balance.h | 6 +++--- src/csv.h | 2 +- src/draft.h | 2 +- src/expr.cc | 4 ++-- src/filters.cc | 12 ++++++------ src/filters.h | 15 +++++++-------- src/format.h | 2 +- src/generate.cc | 3 +-- src/global.cc | 4 ++-- src/item.h | 4 ++-- src/iterators.h | 14 +++++++------- src/journal.cc | 6 +++--- src/journal.h | 2 +- src/mask.cc | 2 +- src/option.h | 2 +- src/org.cc | 4 ++-- src/output.cc | 8 ++++---- src/pool.cc | 2 +- src/post.h | 2 +- src/pstream.h | 8 ++++---- src/pyfstream.h | 8 ++++---- src/query.h | 8 +++++--- src/scope.h | 2 +- src/session.cc | 4 ++-- src/times.h | 5 +++-- src/unistring.h | 4 ++-- src/utils.cc | 12 +++++++----- src/value.h | 34 ++++++++++++++++++---------------- 32 files changed, 106 insertions(+), 101 deletions(-) (limited to 'src/filters.cc') diff --git a/src/amount.cc b/src/amount.cc index 5fa58528..8c5ae574 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -63,16 +63,16 @@ struct amount_t::bigint_t : public supports_flags<> #define MP(bigint) ((bigint)->val) bigint_t() : prec(0), refc(1) { - TRACE_CTOR(bigint_t, ""); mpq_init(val); + TRACE_CTOR(bigint_t, ""); } bigint_t(const bigint_t& other) : supports_flags<>(static_cast (other.flags() & ~BIGINT_BULK_ALLOC)), prec(other.prec), refc(1) { - TRACE_CTOR(bigint_t, "copy"); mpq_init(val); mpq_set(val, other.val); + TRACE_CTOR(bigint_t, "copy"); } ~bigint_t() { TRACE_DTOR(bigint_t); @@ -349,24 +349,24 @@ void amount_t::_release() amount_t::amount_t(const double val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const double"); quantity = new bigint_t; mpq_set_d(MP(quantity), val); quantity->prec = extend_by_digits; // an approximation + TRACE_CTOR(amount_t, "const double"); } amount_t::amount_t(const unsigned long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const unsigned long"); quantity = new bigint_t; mpq_set_ui(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const unsigned long"); } amount_t::amount_t(const long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const long"); quantity = new bigint_t; mpq_set_si(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const long"); } diff --git a/src/amount.h b/src/amount.h index 903a01cd..10e83552 100644 --- a/src/amount.h +++ b/src/amount.h @@ -155,17 +155,17 @@ public: commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const string& val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const string&"); parse(val); + TRACE_CTOR(amount_t, "const string&"); } /** Parse a pointer to a C string as an (optionally commoditized) amount. If no commodity is present, the resulting commodity is \c commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const char * val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const char *"); assert(val); parse(val); + TRACE_CTOR(amount_t, "const char *"); } /*@}*/ @@ -195,21 +195,21 @@ public: same memory used by the original via reference counting. The \c amount_t::bigint_t class in amount.cc maintains the reference. */ amount_t(const amount_t& amt) : quantity(NULL) { - TRACE_CTOR(amount_t, "copy"); if (amt.quantity) _copy(amt); else commodity_ = NULL; + TRACE_CTOR(amount_t, "copy"); } /** Copy an amount object, applying the given commodity annotation details afterward. This is equivalent to doing a normal copy (@see amount_t(const amount_t&)) and then calling amount_t::annotate(). */ amount_t(const amount_t& amt, const annotation_t& details) : quantity(NULL) { - TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); assert(amt.quantity); _copy(amt); annotate(details); + TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); } /** Assign an amount object. This is like copying if the amount was null beforehand, otherwise the previous value's reference is must diff --git a/src/annotate.h b/src/annotate.h index 163ffac5..85a34662 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -226,9 +226,9 @@ protected: explicit annotated_commodity_t(commodity_t * _ptr, const annotation_t& _details) : commodity_t(_ptr->parent_, _ptr->base), ptr(_ptr), details(_details) { - TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); annotated = true; qualified_symbol = _ptr->qualified_symbol; + TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); } public: diff --git a/src/balance.cc b/src/balance.cc index f87e8bbd..5c57cd99 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -41,23 +41,23 @@ namespace ledger { balance_t::balance_t(const double val) { - TRACE_CTOR(balance_t, "const double"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const double"); } balance_t::balance_t(const unsigned long val) { - TRACE_CTOR(balance_t, "const unsigned long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const unsigned long"); } balance_t::balance_t(const long val) { - TRACE_CTOR(balance_t, "const long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const long"); } balance_t& balance_t::operator+=(const balance_t& bal) diff --git a/src/balance.h b/src/balance.h index 5f0d52ed..11c370bb 100644 --- a/src/balance.h +++ b/src/balance.h @@ -108,26 +108,26 @@ public: TRACE_CTOR(balance_t, ""); } balance_t(const amount_t& amt) { - TRACE_CTOR(balance_t, "const amount_t&"); if (amt.is_null()) throw_(balance_error, _("Cannot initialize a balance from an uninitialized amount")); if (! amt.is_realzero()) amounts.insert(amounts_map::value_type(&amt.commodity(), amt)); + TRACE_CTOR(balance_t, "const amount_t&"); } balance_t(const double val); balance_t(const unsigned long val); balance_t(const long val); explicit balance_t(const string& val) { - TRACE_CTOR(balance_t, "const string&"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const string&"); } explicit balance_t(const char * val) { - TRACE_CTOR(balance_t, "const char *"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const char *"); } /** diff --git a/src/csv.h b/src/csv.h index d98c0567..7d5098d2 100644 --- a/src/csv.h +++ b/src/csv.h @@ -91,8 +91,8 @@ public: cost_mask("cost"), total_mask("total"), note_mask("note") { - TRACE_CTOR(csv_reader, "parse_context_t&"); read_index(*context.stream.get()); + TRACE_CTOR(csv_reader, "parse_context_t&"); } ~csv_reader() { TRACE_DTOR(csv_reader); diff --git a/src/draft.h b/src/draft.h index e5d29134..46aa26e1 100644 --- a/src/draft.h +++ b/src/draft.h @@ -92,9 +92,9 @@ class draft_t : public expr_base_t public: draft_t(const value_t& args) : base_type() { - TRACE_CTOR(draft_t, "value_t"); if (! args.empty()) parse_args(args); + TRACE_CTOR(draft_t, "value_t"); } virtual ~draft_t() throw() { TRACE_DTOR(draft_t); diff --git a/src/expr.cc b/src/expr.cc index b22572f8..25967207 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -55,16 +55,16 @@ expr_t::expr_t(ptr_op_t _ptr, scope_t * _context) expr_t::expr_t(const string& _str, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "string, parse_flags_t"); if (! _str.empty()) parse(_str, flags); + TRACE_CTOR(expr_t, "string, parse_flags_t"); } expr_t::expr_t(std::istream& in, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); parse(in, flags); + TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); } expr_t::~expr_t() { diff --git a/src/filters.cc b/src/filters.cc index 73ee200d..5915ad3c 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -512,8 +512,8 @@ display_filter_posts::display_filter_posts(post_handler_ptr handler, display_total_expr(report.HANDLER(display_total_).expr), show_rounding(_show_rounding) { - TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); create_accounts(); + TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); } bool display_filter_posts::output_rounding(post_t& post) @@ -598,9 +598,6 @@ changed_value_posts::changed_value_posts show_unrealized(_show_unrealized), last_post(NULL), display_filter(_display_filter) { - TRACE_CTOR(changed_value_posts, - "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); - string gains_equity_account_name; if (report.HANDLED(unrealized_gains_)) gains_equity_account_name = report.HANDLER(unrealized_gains_).str(); @@ -620,6 +617,9 @@ changed_value_posts::changed_value_posts losses_equity_account->add_flags(ACCOUNT_GENERATED); create_accounts(); + + TRACE_CTOR(changed_value_posts, + "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); } void changed_value_posts::flush() @@ -1417,8 +1417,6 @@ inject_posts::inject_posts(post_handler_ptr handler, account_t * master) : item_handler(handler) { - TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); - scoped_array buf(new char[tag_list.length() + 1]); std::strcpy(buf.get(), tag_list.c_str()); @@ -1435,6 +1433,8 @@ inject_posts::inject_posts(post_handler_ptr handler, tags_list.push_back (tags_list_pair(q, tag_mapping_pair(account, tag_injected_set()))); } + + TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); } void inject_posts::operator()(post_t& post) diff --git a/src/filters.h b/src/filters.h index 3e766863..ab226429 100644 --- a/src/filters.h +++ b/src/filters.h @@ -75,8 +75,8 @@ public: expr_t& _group_by_expr) : post_chain(_post_chain), report(_report), group_by_expr(_group_by_expr) { + preflush_func = bind(&post_splitter::print_title, this, _1); TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t"); - preflush_func = bind(&post_splitter::print_title, this, _1); } virtual ~post_splitter() { TRACE_DTOR(post_splitter); @@ -154,8 +154,6 @@ class pass_down_posts : public item_handler public: pass_down_posts(post_handler_ptr handler, Iterator& iter) : item_handler(handler) { - TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); - while (post_t * post = *iter) { try { item_handler::operator()(*post); @@ -168,6 +166,8 @@ public: } item_handler::flush(); + + TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); } virtual ~pass_down_posts() { @@ -448,8 +448,8 @@ public: only_predicate(_only_predicate), count(0), last_xact(NULL), last_post(NULL), only_collapse_if_zero(_only_collapse_if_zero), report(_report) { - TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); create_accounts(); + TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); } virtual ~collapse_posts() { TRACE_DTOR(collapse_posts); @@ -499,8 +499,7 @@ public: const bool _also_matching = false) : item_handler(handler), also_matching(_also_matching) { - TRACE_CTOR(related_posts, - "post_handler_ptr, const bool"); + TRACE_CTOR(related_posts, "post_handler_ptr, const bool"); } virtual ~related_posts() throw() { TRACE_DTOR(related_posts); @@ -722,9 +721,9 @@ public: : subtotal_posts(_handler, amount_expr), start_interval(_interval), interval(start_interval), exact_periods(_exact_periods), generate_empty_posts(_generate_empty_posts) { + create_accounts(); TRACE_CTOR(interval_posts, "post_handler_ptr, expr_t&, date_interval_t, bool, bool"); - create_accounts(); } virtual ~interval_posts() throw() { TRACE_DTOR(interval_posts); @@ -774,8 +773,8 @@ public: posts_as_equity(post_handler_ptr _handler, report_t& _report, expr_t& amount_expr) : subtotal_posts(_handler, amount_expr), report(_report) { - TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); create_accounts(); + TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); } virtual ~posts_as_equity() throw() { TRACE_DTOR(posts_as_equity); diff --git a/src/format.h b/src/format.h index 60ae2abe..cc48bdda 100644 --- a/src/format.h +++ b/src/format.h @@ -125,9 +125,9 @@ public: } format_t(const string& _str, scope_t * context = NULL) : base_type(context) { - TRACE_CTOR(format_t, "const string&"); if (! _str.empty()) parse_format(_str); + TRACE_CTOR(format_t, "const string&"); } virtual ~format_t() { TRACE_DTOR(format_t); diff --git a/src/generate.cc b/src/generate.cc index edd58632..8769c99c 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -63,8 +63,6 @@ generate_posts_iterator::generate_posts_iterator neg_number_range(-10000, -1), neg_number_gen(rnd_gen, neg_number_range), pos_number_range(1, 10000), pos_number_gen(rnd_gen, pos_number_range) { - TRACE_CTOR(generate_posts_iterator, "bool"); - std::ostringstream next_date_buf; generate_date(next_date_buf); next_date = parse_date(next_date_buf.str()); @@ -73,6 +71,7 @@ generate_posts_iterator::generate_posts_iterator generate_date(next_aux_date_buf); next_aux_date = parse_date(next_aux_date_buf.str()); + TRACE_CTOR(generate_posts_iterator, "bool"); } void generate_posts_iterator::generate_string(std::ostream& out, int len, diff --git a/src/global.cc b/src/global.cc index b5ceb614..6dc8d150 100644 --- a/src/global.cc +++ b/src/global.cc @@ -47,8 +47,6 @@ static bool args_only = false; global_scope_t::global_scope_t(char ** envp) { - TRACE_CTOR(global_scope_t, ""); - epoch = CURRENT_TIME(); #if defined(HAVE_BOOST_PYTHON) @@ -89,6 +87,8 @@ global_scope_t::global_scope_t(char ** envp) } else { session().HANDLER(price_db_).off(); } + + TRACE_CTOR(global_scope_t, ""); } global_scope_t::~global_scope_t() diff --git a/src/item.h b/src/item.h index e7415918..a1160329 100644 --- a/src/item.h +++ b/src/item.h @@ -60,8 +60,8 @@ struct position_t TRACE_CTOR(position_t, ""); } position_t(const position_t& pos) { - TRACE_CTOR(position_t, "copy"); *this = pos; + TRACE_CTOR(position_t, "copy"); } ~position_t() throw() { TRACE_DTOR(position_t); @@ -125,8 +125,8 @@ public: } item_t(const item_t& item) : supports_flags(), scope_t() { - TRACE_CTOR(item_t, "copy"); copy_details(item); + TRACE_CTOR(item_t, "copy"); } virtual ~item_t() { TRACE_DTOR(item_t); diff --git a/src/iterators.h b/src/iterators.h index 922ebccd..53814666 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -100,8 +100,8 @@ public: } xact_posts_iterator(xact_t& xact) : posts_uninitialized(true) { - TRACE_CTOR(xact_posts_iterator, "xact_t&"); reset(xact); + TRACE_CTOR(xact_posts_iterator, "xact_t&"); } xact_posts_iterator(const xact_posts_iterator& i) : iterator_facade_base& _prepend_format) : report(_report), last_xact(NULL), last_post(NULL) { - TRACE_CTOR(posts_to_org_table, "report&, optional"); - first_line_format.parse_format ("|%(format_date(date))" "|%(code)" @@ -79,6 +77,8 @@ posts_to_org_table::posts_to_org_table(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(posts_to_org_table, "report&, optional"); } void posts_to_org_table::flush() diff --git a/src/output.cc b/src/output.cc index aaf81f60..742000bd 100644 --- a/src/output.cc +++ b/src/output.cc @@ -47,8 +47,6 @@ format_posts::format_posts(report_t& _report, : report(_report), prepend_width(_prepend_width), last_xact(NULL), last_post(NULL), first_report_title(true) { - TRACE_CTOR(format_posts, "report&, const string&, bool"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -70,6 +68,8 @@ format_posts::format_posts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_posts, "report&, const string&, bool"); } void format_posts::flush() @@ -131,8 +131,6 @@ format_accounts::format_accounts(report_t& _report, : report(_report), prepend_width(_prepend_width), disp_pred(), first_report_title(true) { - TRACE_CTOR(format_accounts, "report&, const string&"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -154,6 +152,8 @@ format_accounts::format_accounts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_accounts, "report&, const string&"); } std::size_t format_accounts::post_account(account_t& account, const bool flat) diff --git a/src/pool.cc b/src/pool.cc index be26de3b..61b5bef2 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -47,9 +47,9 @@ commodity_pool_t::commodity_pool_t() quote_leeway(86400), get_quotes(false), get_commodity_quote(commodity_quote_from_script) { - TRACE_CTOR(commodity_pool_t, ""); null_commodity = create(""); null_commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET); + TRACE_CTOR(commodity_pool_t, ""); } commodity_t * commodity_pool_t::create(const string& symbol) diff --git a/src/post.h b/src/post.h index d6004c9f..76a89a33 100644 --- a/src/post.h +++ b/src/post.h @@ -96,8 +96,8 @@ public: assigned_amount(post.assigned_amount), xdata_(post.xdata_) { - TRACE_CTOR(post_t, "copy"); copy_details(post); + TRACE_CTOR(post_t, "copy"); } virtual ~post_t() { TRACE_DTOR(post_t); diff --git a/src/pstream.h b/src/pstream.h index dfb27056..6e38158a 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -58,14 +58,14 @@ class ptristream : public std::istream public: ptrinbuf(char * _ptr, std::size_t _len) : ptr(_ptr), len(_len) { - TRACE_CTOR(ptrinbuf, "char *, std::size_t"); - if (*ptr && len == 0) len = std::strlen(ptr); - setg(ptr, // beginning of putback area - ptr, // read position + setg(ptr, // beginning of putback area + ptr, // read position ptr+len); // end position + + TRACE_CTOR(ptrinbuf, "char *, std::size_t"); } ~ptrinbuf() throw() { TRACE_DTOR(ptrinbuf); diff --git a/src/pyfstream.h b/src/pyfstream.h index 972f976f..18f28bc4 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -86,8 +86,8 @@ protected: public: pyofstream (PyFileObject * fo) : std::ostream(0), buf(fo) { - TRACE_CTOR(pyofstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyofstream, "PyFileObject *"); } ~pyofstream() throw() { TRACE_DTOR(pyofstream); @@ -121,11 +121,11 @@ public: * => force underflow() */ pyinbuf (PyFileObject * _fo) : fo(_fo) { - TRACE_CTOR(pyinbuf, "PyFileObject *"); - setg (buffer+pbSize, // beginning of putback area buffer+pbSize, // read position buffer+pbSize); // end position + + TRACE_CTOR(pyinbuf, "PyFileObject *"); } ~pyinbuf() throw() { TRACE_DTOR(pyinbuf); @@ -191,8 +191,8 @@ protected: public: pyifstream (PyFileObject * fo) : std::istream(0), buf(fo) { - TRACE_CTOR(pyifstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyifstream, "PyFileObject *"); } ~pyifstream() throw() { TRACE_DTOR(pyifstream); diff --git a/src/query.h b/src/query.h index c694d099..fe52eb35 100644 --- a/src/query.h +++ b/src/query.h @@ -204,10 +204,11 @@ public: consume_whitespace(false), consume_next_arg(false), multiple_args(_multiple_args) { - TRACE_CTOR(query_t::lexer_t, ""); assert(begin != end); arg_i = (*begin).as_string().begin(); arg_end = (*begin).as_string().end(); + + TRACE_CTOR(query_t::lexer_t, ""); } lexer_t(const lexer_t& lexer) : begin(lexer.begin), end(lexer.end), @@ -302,18 +303,19 @@ public: query_t(const string& arg, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "string, keep_details_t, bool"); if (! arg.empty()) { value_t temp(string_value(arg)); parse_args(temp.to_sequence(), what_to_keep, multiple_args); } + TRACE_CTOR(query_t, "string, keep_details_t, bool"); } query_t(const value_t& args, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); if (! args.empty()) parse_args(args, what_to_keep, multiple_args); + + TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); } virtual ~query_t() { TRACE_DTOR(query_t); diff --git a/src/scope.h b/src/scope.h index 9318fc5c..acaf7194 100644 --- a/src/scope.h +++ b/src/scope.h @@ -209,9 +209,9 @@ public: explicit bind_scope_t(scope_t& _parent, scope_t& _grandchild) : child_scope_t(_parent), grandchild(_grandchild) { - TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); DEBUG("scope.symbols", "Binding scope " << &_parent << " with " << &_grandchild); + TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); } virtual ~bind_scope_t() { TRACE_DTOR(bind_scope_t); diff --git a/src/session.cc b/src/session.cc index 5c9e4fd4..9a77d341 100644 --- a/src/session.cc +++ b/src/session.cc @@ -62,14 +62,14 @@ void set_session_context(session_t * session) session_t::session_t() : flush_on_next_data_file(false), journal(new journal_t) { - TRACE_CTOR(session_t, ""); - if (const char * home_var = std::getenv("HOME")) HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string()); else HANDLER(price_db_).on(none, path("./.pricedb").string()); parsing_context.push(); + + TRACE_CTOR(session_t, ""); } std::size_t session_t::read_data(const string& master_account) diff --git a/src/times.h b/src/times.h index e3134665..3bb95903 100644 --- a/src/times.h +++ b/src/times.h @@ -307,13 +307,14 @@ public: } date_specifier_t(const date_t& date, const optional& traits = none) { - TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); if (! traits || traits->has_year) year = date.year(); if (! traits || traits->has_month) month = date.month(); if (! traits || traits->has_day) day = date.day(); + + TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); } date_specifier_t(const date_specifier_t& other) : year(other.year), month(other.month), @@ -538,8 +539,8 @@ public: TRACE_CTOR(date_interval_t, ""); } date_interval_t(const string& str) : aligned(false) { - TRACE_CTOR(date_interval_t, "const string&"); parse(str); + TRACE_CTOR(date_interval_t, "const string&"); } date_interval_t(const date_interval_t& other) : range(other.range), diff --git a/src/unistring.h b/src/unistring.h index a33c6e3f..b2278796 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -64,14 +64,14 @@ public: } unistring(const std::string& input) { - TRACE_CTOR(unistring, "std::string"); - const char * p = input.c_str(); std::size_t len = input.length(); assert(len < 1024); VERIFY(utf8::is_valid(p, p + len)); utf8::unchecked::utf8to32(p, p + len, std::back_inserter(utf32chars)); + + TRACE_CTOR(unistring, "std::string"); } ~unistring() { TRACE_DTOR(unistring); diff --git a/src/utils.cc b/src/utils.cc index 5a364008..17118904 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -278,16 +278,18 @@ namespace { buf << num; + string number(buf.str()); + int integer_digits = 0; // Count the number of integer digits - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') break; else if (*p != '-') integer_digits++; } - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') { obuf << *p; assert(integer_digits <= 3); @@ -335,7 +337,7 @@ namespace { void report_count_map(std::ostream& out, object_count_map& the_map) { foreach (object_count_map::value_type& pair, the_map) { - out << " " << std::right << std::setw(12); + out << " " << std::right << std::setw(18); stream_commified_number(out, pair.second.first); out << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); @@ -433,7 +435,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live memory:" << std::endl; foreach (const memory_map::value_type& pair, *live_memory) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first @@ -455,7 +457,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live objects:" << std::endl; foreach (const objects_map::value_type& pair, *live_objects) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first diff --git a/src/value.h b/src/value.h index a95968c2..d128bb89 100644 --- a/src/value.h +++ b/src/value.h @@ -179,8 +179,8 @@ public: */ explicit storage_t(const storage_t& rhs) : type(rhs.type), refc(0) { - TRACE_CTOR(value_t::storage_t, "copy"); *this = rhs; + TRACE_CTOR(value_t::storage_t, "copy"); } storage_t& operator=(const storage_t& rhs); @@ -290,73 +290,75 @@ public: } value_t(const bool val) { - TRACE_CTOR(value_t, "const bool"); set_boolean(val); + TRACE_CTOR(value_t, "const bool"); } value_t(const datetime_t& val) { - TRACE_CTOR(value_t, "const datetime_t&"); set_datetime(val); + TRACE_CTOR(value_t, "const datetime_t&"); } value_t(const date_t& val) { - TRACE_CTOR(value_t, "const date_t&"); set_date(val); + TRACE_CTOR(value_t, "const date_t&"); } value_t(const long val) { - TRACE_CTOR(value_t, "const long"); set_long(val); + TRACE_CTOR(value_t, "const long"); } value_t(const unsigned long val) { - TRACE_CTOR(value_t, "const unsigned long"); set_amount(val); + TRACE_CTOR(value_t, "const unsigned long"); } value_t(const double val) { - TRACE_CTOR(value_t, "const double"); set_amount(val); + TRACE_CTOR(value_t, "const double"); } value_t(const amount_t& val) { - TRACE_CTOR(value_t, "const amount_t&"); set_amount(val); + TRACE_CTOR(value_t, "const amount_t&"); } value_t(const balance_t& val) { - TRACE_CTOR(value_t, "const balance_t&"); set_balance(val); + TRACE_CTOR(value_t, "const balance_t&"); } value_t(const mask_t& val) { - TRACE_CTOR(value_t, "const mask_t&"); set_mask(val); + TRACE_CTOR(value_t, "const mask_t&"); } explicit value_t(const string& val, bool literal = false) { - TRACE_CTOR(value_t, "const string&, bool"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const string&, bool"); } explicit value_t(const char * val, bool literal = false) { - TRACE_CTOR(value_t, "const char *"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const char *"); } value_t(const sequence_t& val) { - TRACE_CTOR(value_t, "const sequence_t&"); set_sequence(val); + TRACE_CTOR(value_t, "const sequence_t&"); } explicit value_t(scope_t * item) { - TRACE_CTOR(value_t, "scope_t *"); set_scope(item); + TRACE_CTOR(value_t, "scope_t *"); } #if 0 template explicit value_t(T& item) { - TRACE_CTOR(value_t, "T&"); set_any(item); + TRACE_CTOR(value_t, "T&"); } #endif @@ -375,8 +377,8 @@ public: * object. A true copy is only ever made prior to modification. */ value_t(const value_t& val) { - TRACE_CTOR(value_t, "copy"); *this = val; + TRACE_CTOR(value_t, "copy"); } value_t& operator=(const value_t& val) { if (! (this == &val || storage == val.storage)) -- cgit v1.2.3 From f76d458ab7f200bd52676fe8103fbfaae4f10488 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 20 Mar 2012 03:15:42 -0500 Subject: Strip annotations in display_filter_posts Fixes #718 --- src/filters.cc | 6 ++++-- test/regress/A560FDAD.test | 50 ++++++++++++++++++++++++++++++++++++++++++++++ test/regress/BFD3FBE1.test | 3 +-- 3 files changed, 55 insertions(+), 4 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 73ee200d..b5f68907 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -522,7 +522,8 @@ bool display_filter_posts::output_rounding(post_t& post) value_t new_display_total; if (show_rounding) { - new_display_total = display_total_expr.calc(bound_scope); + new_display_total = (display_total_expr.calc(bound_scope) + .strip_annotations(report.what_to_keep())); DEBUG("filters.changed_value.rounding", "rounding.new_display_total = " << new_display_total); @@ -539,7 +540,8 @@ bool display_filter_posts::output_rounding(post_t& post) return true; } - if (value_t repriced_amount = display_amount_expr.calc(bound_scope)) { + if (value_t repriced_amount = (display_amount_expr.calc(bound_scope) + .strip_annotations(report.what_to_keep()))) { if (! last_display_total.is_null()) { DEBUG("filters.changed_value.rounding", "rounding.repriced_amount = " << repriced_amount); diff --git a/test/regress/A560FDAD.test b/test/regress/A560FDAD.test index 053f5aaf..b30ea086 100644 --- a/test/regress/A560FDAD.test +++ b/test/regress/A560FDAD.test @@ -33,4 +33,54 @@ Assets:Current test reg -X EUR -H +12-Jan-01 Opening balance Assets:Current 17.43 EUR 17.43 EUR + Assets:Investments 4959.80 EUR 4977.23 EUR + Assets:Investments 1438.34 EUR 6415.57 EUR + Equity:Opening balance -6409.77 EUR 5.80 EUR +12-Jan-01 Opening balance Assets:Pension 785.44 GBP 5.80 EUR + 785.44 GBP + Assets:Pension 97.0017 H2 5.80 EUR + 785.44 GBP + 97.0017 H2 + Assets:Pension 4.3441 H1 5.80 EUR + 785.44 GBP + 4.3441 H1 + 97.0017 H2 + Equity:Opening balance -1326.70 GBP 5.80 EUR + -541.26 GBP + 4.3441 H1 + 97.0017 H2 +12-Jan-01 Opening balance: misc Assets:Piggy bank 3.51 GBP 5.80 EUR + -537.75 GBP + 4.3441 H1 + 97.0017 H2 + Equity:Opening balance -3.51 GBP 5.80 EUR + -541.26 GBP + 4.3441 H1 + 97.0017 H2 +12-Jan-01 Opening balance Assets:Rewards 9836 AAdvantage 9836 AAdvantage + 5.80 EUR + -541.26 GBP + 4.3441 H1 + 97.0017 H2 + Equity:Opening balance -9836 AAdvantage 5.80 EUR + -541.26 GBP + 4.3441 H1 + 97.0017 H2 +12-Jan-03 Commodities revalued 0 5.80 EUR +12-Jan-03 Receivable Assets:Current 172.71 EUR 178.51 EUR + Assets:Receivable -161.06 EUR 17.45 EUR + Assets:Receivable -11.65 EUR 5.80 EUR +12-Jan-27 Test 0.01 EUR 5.81 EUR + Income:Test -3218.04 EUR -3212.23 EUR + -0.01 EUR -3212.24 EUR + Income:Test -129.16 EUR -3341.40 EUR + Assets:Foo 402.99 EUR -2938.41 EUR + Expenses:Test 19.21 EUR -2919.20 EUR + Expenses:Test 7.38 EUR -2911.82 EUR + 0.01 EUR -2911.81 EUR + Expenses:Test 304.82 EUR -2606.99 EUR + -0.01 EUR -2607.00 EUR + Assets:Current 2612.80 EUR 5.80 EUR + 0.01 EUR 5.82 EUR end test diff --git a/test/regress/BFD3FBE1.test b/test/regress/BFD3FBE1.test index 5b2f8b42..0dbda2c7 100644 --- a/test/regress/BFD3FBE1.test +++ b/test/regress/BFD3FBE1.test @@ -11,7 +11,6 @@ test reg -X EUR -H 11-Jan-01 Opening balance Assets:Investment 1658.90 EUR 1658.90 EUR Assets:Investments 124.00 EUR 1782.90 EUR Equity:Opening balance -1782.90 EUR 0 -11-Feb-10 Reimbursement: Taxi.. -0.01 EUR -0.01 EUR - Assets:A 1.80 EUR 1.80 EUR +11-Feb-10 Reimbursement: Taxi.. Assets:A 1.80 EUR 1.80 EUR Assets:B -1.80 EUR 0 end test -- cgit v1.2.3 From e3248ee5a6b2c29e1c35eb0315fd66370a117784 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 20 Mar 2012 04:56:03 -0500 Subject: Fix problems with postings --- src/annotate.cc | 3 ++- src/commodity.cc | 2 ++ src/filters.cc | 9 ++++++--- src/temps.cc | 8 ++++++-- src/temps.h | 3 ++- test/regress/A560FDAD.test | 1 - 6 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src/filters.cc') diff --git a/src/annotate.cc b/src/annotate.cc index 25f0e582..98635ad7 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -328,7 +328,8 @@ annotated_commodity_t::strip_annotations(const keep_details_t& what_to_keep) if ((keep_price && details.price) || (keep_date && details.date) || (keep_tag && details.tag) || - details.value_expr) + (details.value_expr && + ! details.has_flags(ANNOTATION_VALUE_EXPR_CALCULATED))) { new_comm = pool().find_or_create (referent(), annotation_t(keep_price ? details.price : none, diff --git a/src/commodity.cc b/src/commodity.cc index 5335d8a8..51b8f29c 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -221,6 +221,8 @@ commodity_t& commodity_t::nail_down(const expr_t& expr) { annotation_t new_details; new_details.value_expr = expr; + new_details.add_flags(ANNOTATION_VALUE_EXPR_CALCULATED); + commodity_t * new_comm = commodity_pool_t::current_pool->find_or_create(symbol(), new_details); return *new_comm; diff --git a/src/filters.cc b/src/filters.cc index 02dc392b..58e5fcaf 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -340,9 +340,10 @@ namespace { const bool act_date_p = true, const value_t& total = value_t(), const bool direct_amount = false, - const bool mark_visited = false) + const bool mark_visited = false, + const bool bidir_link = true) { - post_t& post = temps.create_post(*xact, account); + post_t& post = temps.create_post(*xact, account, bidir_link); post.add_flags(ITEM_GENERATED); // If the account for this post is all virtual, then report the post as @@ -566,7 +567,9 @@ bool display_filter_posts::output_rounding(post_t& post) /* date= */ date_t(), /* act_date_p= */ true, /* total= */ precise_display_total, - /* direct_amount= */ true); + /* direct_amount= */ true, + /* mark_visited= */ false, + /* bidir_link= */ false); } } if (show_rounding) diff --git a/src/temps.cc b/src/temps.cc index cb471d41..881077f6 100644 --- a/src/temps.cc +++ b/src/temps.cc @@ -81,7 +81,8 @@ post_t& temporaries_t::copy_post(post_t& origin, xact_t& xact, return temp; } -post_t& temporaries_t::create_post(xact_t& xact, account_t * account) +post_t& temporaries_t::create_post(xact_t& xact, account_t * account, + bool bidir_link) { if (! post_temps) post_temps = std::list(); @@ -93,7 +94,10 @@ post_t& temporaries_t::create_post(xact_t& xact, account_t * account) temp.account = account; temp.account->add_post(&temp); - xact.add_post(&temp); + if (bidir_link) + xact.add_post(&temp); + else + temp.xact = &xact; return temp; } diff --git a/src/temps.h b/src/temps.h index f41c487c..daa1493b 100644 --- a/src/temps.h +++ b/src/temps.h @@ -66,7 +66,8 @@ public: } post_t& copy_post(post_t& origin, xact_t& xact, account_t * account = NULL); - post_t& create_post(xact_t& xact, account_t * account); + post_t& create_post(xact_t& xact, account_t * account, + bool bidir_link = true); post_t& last_post() { return post_temps->back(); } diff --git a/test/regress/A560FDAD.test b/test/regress/A560FDAD.test index b30ea086..ee19e71e 100644 --- a/test/regress/A560FDAD.test +++ b/test/regress/A560FDAD.test @@ -82,5 +82,4 @@ test reg -X EUR -H Expenses:Test 304.82 EUR -2606.99 EUR -0.01 EUR -2607.00 EUR Assets:Current 2612.80 EUR 5.80 EUR - 0.01 EUR 5.82 EUR end test -- cgit v1.2.3 From 5addacfbf21250204b8db25f0a4890c1299cb891 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 22 Mar 2012 23:42:18 -0500 Subject: Fixed an interaction with equity and virtual accounts Fixes #686 --- src/filters.cc | 20 ++++++++++++++++++-- src/filters.h | 17 ++++++++++++----- test/regress/012ADB60.test | 24 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 test/regress/012ADB60.test (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 58e5fcaf..32b3ec3a 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -900,11 +900,19 @@ void subtotal_posts::operator()(post_t& post) #if defined(DEBUG_ON) std::pair result = #endif - values.insert(values_pair(acct->fullname(), acct_value_t(acct, temp))); + values.insert(values_pair + (acct->fullname(), + acct_value_t(acct, temp, post.has_flags(POST_VIRTUAL), + post.has_flags(POST_MUST_BALANCE)))); #if defined(DEBUG_ON) assert(result.second); #endif } else { + if (post.has_flags(POST_VIRTUAL) != (*i).second.is_virtual) + throw_(std::logic_error, + _("'equity' cannot accept virtual and " + "non-virtual postings to the same account")); + post.add_to_value((*i).second.value, amount_expr); } @@ -1062,10 +1070,17 @@ void posts_as_equity::report_subtotal() /* act_date_p= */ false); } } - total += value; + + if (! pair.second.is_virtual || pair.second.must_balance) + total += value; } values.clear(); +#if 1 + // This last part isn't really needed, since an Equity:Opening + // Balances posting with a null amount will automatically balance with + // all the other postings generated. But it does make the full + // balancing amount clearer to the user. if (! total.is_zero()) { if (total.is_balance()) { foreach (const balance_t::amounts_map::value_type& pair, @@ -1082,6 +1097,7 @@ void posts_as_equity::report_subtotal() (*handler)(balance_post); } } +#endif } void by_payee_posts::flush() diff --git a/src/filters.h b/src/filters.h index ab226429..1dad8852 100644 --- a/src/filters.h +++ b/src/filters.h @@ -640,15 +640,22 @@ protected: public: account_t * account; value_t value; + bool is_virtual; + bool must_balance; - acct_value_t(account_t * a) : account(a) { - TRACE_CTOR(acct_value_t, "account_t *"); + acct_value_t(account_t * a, bool _is_virtual = false, + bool _must_balance = false) + : account(a), is_virtual(_is_virtual), must_balance(_must_balance) { + TRACE_CTOR(acct_value_t, "account_t *, bool, bool"); } - acct_value_t(account_t * a, value_t& v) : account(a), value(v) { - TRACE_CTOR(acct_value_t, "account_t *, value_t&"); + acct_value_t(account_t * a, value_t& v, bool _is_virtual = false, + bool _must_balance = false) + : account(a), value(v), is_virtual(_is_virtual), + must_balance(_must_balance) { + TRACE_CTOR(acct_value_t, "account_t *, value_t&, bool, bool"); } acct_value_t(const acct_value_t& av) - : account(av.account), value(av.value) { + : account(av.account), value(av.value), is_virtual(av.is_virtual) { TRACE_CTOR(acct_value_t, "copy"); } ~acct_value_t() throw() { diff --git a/test/regress/012ADB60.test b/test/regress/012ADB60.test new file mode 100644 index 00000000..443b9e5b --- /dev/null +++ b/test/regress/012ADB60.test @@ -0,0 +1,24 @@ +2005/01/03 * Pay Credit card + Liabilities:CredCard $1,000.00 ; Electronic/ACH Debit + Assets:Current:Checking ; Electronic/ACH Debit + (Virtualaccount) $1,000.00 + +2006/01/03 Gift shop + Expenses:Gifts $46.50 + * Liabilities:CredCard + +2006/01/03 Bike shop + Expenses:Misc $199.00 + * Liabilities:CredCard + (testvirtual) $184.72 + +2006/01/04 Store + Expenses:Misc $49.95 + * Liabilities:CredCard + +test equity -e 2006 +2005/01/03 Opening Balances + Assets:Current:Checking $-1,000.00 + Liabilities:CredCard $1,000.00 + (Virtualaccount) $1,000.00 +end test -- cgit v1.2.3 From 4b057599626538a0d1463c63f2110d2fe5baa2e6 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 23 Mar 2012 16:46:11 -0500 Subject: Fixed sorting of equity output --- src/balance.cc | 102 +++++++++++++++++++++++++++++------------- src/balance.h | 8 ++++ src/filters.cc | 56 ++++++++++++++++------- test/baseline/opt-equity.test | 4 +- 4 files changed, 121 insertions(+), 49 deletions(-) (limited to 'src/filters.cc') diff --git a/src/balance.cc b/src/balance.cc index 5c57cd99..cd25eede 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -240,17 +240,8 @@ balance_t::strip_annotations(const keep_details_t& what_to_keep) const return temp; } -void balance_t::print(std::ostream& out, - const int first_width, - const int latter_width, - const uint_least8_t flags) const +void balance_t::map_sorted_amounts(function fn) const { - bool first = true; - int lwidth = latter_width; - - if (lwidth == -1) - lwidth = first_width; - typedef std::vector amounts_array; amounts_array sorted; @@ -261,30 +252,79 @@ void balance_t::print(std::ostream& out, std::stable_sort(sorted.begin(), sorted.end(), commodity_t::compare_by_commodity()); - foreach (const amount_t * amount, sorted) { - int width; - if (! first) { - out << std::endl; - width = lwidth; - } else { - first = false; - width = first_width; + foreach (const amount_t * amount, sorted) + fn(*amount); +} + +namespace { + struct print_amount_from_balance + { + std::ostream& out; + bool& first; + int fwidth; + int lwidth; + uint_least8_t flags; + + explicit print_amount_from_balance(std::ostream& _out, + bool& _first, + int _fwidth, int _lwidth, + uint_least8_t _flags) + : out(_out), first(_first), fwidth(_fwidth), lwidth(_lwidth), + flags(_flags) { + TRACE_CTOR(print_amount_from_balance, + "ostream&, int, int, uint_least8_t"); + } + print_amount_from_balance(const print_amount_from_balance& other) + : out(other.out), first(other.first), fwidth(other.fwidth), + lwidth(other.lwidth), flags(other.flags) { + TRACE_CTOR(print_amount_from_balance, "copy"); + } + ~print_amount_from_balance() throw() { + TRACE_DTOR(print_amount_from_balance); } - std::ostringstream buf; - amount->print(buf, flags); - justify(out, buf.str(), width, flags & AMOUNT_PRINT_RIGHT_JUSTIFY, - flags & AMOUNT_PRINT_COLORIZE && amount->sign() < 0); - } + void operator()(const amount_t& amount) { + int width; + if (! first) { + out << std::endl; + width = lwidth; + } else { + first = false; + width = fwidth; + } + + std::ostringstream buf; + amount.print(buf, flags); + + justify(out, buf.str(), width, + flags & AMOUNT_PRINT_RIGHT_JUSTIFY, + flags & AMOUNT_PRINT_COLORIZE && amount.sign() < 0); + } - if (first) { - out.width(first_width); - if (flags & AMOUNT_PRINT_RIGHT_JUSTIFY) - out << std::right; - else - out << std::left; - out << 0; - } + void close() { + out.width(fwidth); + if (flags & AMOUNT_PRINT_RIGHT_JUSTIFY) + out << std::right; + else + out << std::left; + out << 0; + } + }; +} + +void balance_t::print(std::ostream& out, + const int first_width, + const int latter_width, + const uint_least8_t flags) const +{ + bool first = true; + print_amount_from_balance + amount_printer(out, first, first_width, + latter_width == 1 ? first_width : latter_width, flags); + map_sorted_amounts(amount_printer); + + if (first) + amount_printer.close(); } void to_xml(std::ostream& out, const balance_t& bal) diff --git a/src/balance.h b/src/balance.h index 11c370bb..704b4072 100644 --- a/src/balance.h +++ b/src/balance.h @@ -506,6 +506,14 @@ public: */ balance_t strip_annotations(const keep_details_t& what_to_keep) const; + /** + * Iteration primitives. `map_sorted_amounts' allows one to visit + * each amount in balance in the proper order for displaying to the + * user. Mostly used by `print' and other routinse where the sort + * order of the amounts' commodities is significant. + */ + void map_sorted_amounts(function fn) const; + /** * Printing methods. A balance may be output to a stream using the * `print' method. There is also a global operator<< defined which diff --git a/src/filters.cc b/src/filters.cc index 32b3ec3a..a665f9e6 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1030,6 +1030,40 @@ void interval_posts::flush() subtotal_posts::flush(); } +namespace { + struct create_post_from_amount + { + post_handler_ptr handler; + xact_t& xact; + account_t& balance_account; + temporaries_t& temps; + + explicit create_post_from_amount(post_handler_ptr _handler, + xact_t& _xact, + account_t& _balance_account, + temporaries_t& _temps) + : handler(_handler), xact(_xact), + balance_account(_balance_account), temps(_temps) { + TRACE_CTOR(create_post_from_amount, + "post_handler_ptr, xact_t&, account_t&, temporaries_t&"); + } + create_post_from_amount(const create_post_from_amount& other) + : handler(other.handler), xact(other.xact), + balance_account(other.balance_account), temps(other.temps) { + TRACE_CTOR(create_post_from_amount, "copy"); + } + ~create_post_from_amount() throw() { + TRACE_DTOR(create_post_from_amount); + } + + void operator()(const amount_t& amount) { + post_t& balance_post = temps.create_post(xact, &balance_account); + balance_post.amount = - amount; + (*handler)(balance_post); + } + }; +} + void posts_as_equity::report_subtotal() { date_t finish; @@ -1076,28 +1110,18 @@ void posts_as_equity::report_subtotal() } values.clear(); -#if 1 // This last part isn't really needed, since an Equity:Opening // Balances posting with a null amount will automatically balance with // all the other postings generated. But it does make the full // balancing amount clearer to the user. if (! total.is_zero()) { - if (total.is_balance()) { - foreach (const balance_t::amounts_map::value_type& pair, - total.as_balance().amounts) { - if (! pair.second.is_zero()) { - post_t& balance_post = temps.create_post(xact, balance_account); - balance_post.amount = - pair.second; - (*handler)(balance_post); - } - } - } else { - post_t& balance_post = temps.create_post(xact, balance_account); - balance_post.amount = - total.to_amount(); - (*handler)(balance_post); - } + create_post_from_amount post_creator(handler, xact, + *balance_account, temps); + if (total.is_balance()) + total.as_balance_lval().map_sorted_amounts(post_creator); + else + post_creator(total.to_amount()); } -#endif } void by_payee_posts::flush() diff --git a/test/baseline/opt-equity.test b/test/baseline/opt-equity.test index 511333cc..35ea6b1e 100644 --- a/test/baseline/opt-equity.test +++ b/test/baseline/opt-equity.test @@ -41,9 +41,9 @@ test equity --lot-prices Assets:Bank -3.80 GBP Assets:Broker 2 AAA {0.90 GBP} Assets:Broker 2 AAA {1.00 GBP} - Equity:Opening Balances 3.80 GBP Equity:Opening Balances -2 AAA {0.90 GBP} Equity:Opening Balances -2 AAA {1.00 GBP} + Equity:Opening Balances 3.80 GBP end test test equity --lots @@ -51,8 +51,8 @@ test equity --lots Assets:Bank -3.80 GBP Assets:Broker 2 AAA {0.90 GBP} [2011/03/04] Assets:Broker 2 AAA {1.00 GBP} [2011/03/05] - Equity:Opening Balances 3.80 GBP Equity:Opening Balances -2 AAA {0.90 GBP} [2011/03/04] Equity:Opening Balances -2 AAA {1.00 GBP} [2011/03/05] + Equity:Opening Balances 3.80 GBP end test -- cgit v1.2.3 From ad7ace902c6a1c756ca22d2e67edcc58fe07cd40 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 6 Apr 2012 01:01:43 -0500 Subject: Allow --invert to work with --monthly Fixes #770 --- src/filters.cc | 23 ++++++++++++++++++----- src/report.h | 2 +- test/regress/FCE11C8D.test | 7 +++++++ 3 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 test/regress/FCE11C8D.test (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index a665f9e6..9589958c 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -893,16 +893,28 @@ void subtotal_posts::operator()(post_t& post) account_t * acct = post.reported_account(); assert(acct); +#if 0 + // jww (2012-04-06): The problem with doing this early is that + // fn_display_amount will recalculate this again. For example, if you + // use --invert, it will invert both here and in the display amount, + // effectively negating it. + bind_scope_t bound_scope(*amount_expr.get_context(), post); + value_t amount(amount_expr.calc(bound_scope)); +#else + value_t amount(post.amount); +#endif + + post.xdata().compound_value = amount; + post.xdata().add_flags(POST_EXT_COMPOUND); + values_map::iterator i = values.find(acct->fullname()); if (i == values.end()) { - value_t temp; - post.add_to_value(temp, amount_expr); #if defined(DEBUG_ON) std::pair result = #endif values.insert(values_pair (acct->fullname(), - acct_value_t(acct, temp, post.has_flags(POST_VIRTUAL), + acct_value_t(acct, amount, post.has_flags(POST_VIRTUAL), post.has_flags(POST_MUST_BALANCE)))); #if defined(DEBUG_ON) assert(result.second); @@ -913,7 +925,7 @@ void subtotal_posts::operator()(post_t& post) _("'equity' cannot accept virtual and " "non-virtual postings to the same account")); - post.add_to_value((*i).second.value, amount_expr); + add_or_set_value((*i).second.value, amount); } // If the account for this post is all virtual, mark it as @@ -953,8 +965,9 @@ void interval_posts::operator()(post_t& post) if (interval.duration) { all_posts.push_back(&post); } - else if (interval.find_period(post.date())) + else if (interval.find_period(post.date())) { item_handler::operator()(post); + } } void interval_posts::flush() diff --git a/src/report.h b/src/report.h index 37123377..e7d68dda 100644 --- a/src/report.h +++ b/src/report.h @@ -725,7 +725,7 @@ public: OPTION(report_t, inject_); OPTION_(report_t, invert, DO() { - OTHER(amount_).on(whence, "-amount"); + OTHER(amount_).on(whence, "-amount_expr"); }); OPTION_ diff --git a/test/regress/FCE11C8D.test b/test/regress/FCE11C8D.test new file mode 100644 index 00000000..595edc2d --- /dev/null +++ b/test/regress/FCE11C8D.test @@ -0,0 +1,7 @@ +2012-03-17 Payee + Expenses:Food $20 + Assets:Cash + +test reg --monthly --invert exp +12-Mar-01 - 12-Mar-31 Expenses:Food $-20 $-20 +end test -- cgit v1.2.3