From a05353e26928464b485767cc843ec5b3d9e47040 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 15 Mar 2009 01:14:13 -0400 Subject: First iteration of the new date_interval_t rewrite --- src/filters.cc | 76 +++++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index d0e345ae..06518169 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -562,7 +562,7 @@ void interval_posts::report_subtotal(const date_t& finish) if (exact_periods) subtotal_posts::report_subtotal(); else - subtotal_posts::report_subtotal(NULL, interval.begin, finish); + subtotal_posts::report_subtotal(NULL, *interval.start, finish); } last_post = NULL; @@ -572,49 +572,37 @@ void interval_posts::operator()(post_t& post) { date_t date = post.date(); - if ((is_valid(interval.begin) && date < interval.begin) || - (is_valid(interval.end) && date >= interval.end)) + if (! interval.find_period(post.date(), &last_interval)) return; - if (interval) { - if (! is_valid(interval.begin)) - interval.set_start(date); - start = interval.begin; - - date_t quant = interval.increment(interval.begin); - if (date >= quant) { - if (last_post) - report_subtotal(quant - gregorian::days(1)); - - date_t temp; - while (date >= (temp = interval.increment(quant))) { - if (quant == temp) - break; - interval.begin = quant; - quant = temp; + if (interval.duration) { + if (last_interval) { + if (interval != last_interval) { + report_subtotal(last_interval.inclusive_end()); 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_temps.push_back(xact_t()); - xact_t& null_xact = xact_temps.back(); - null_xact.add_flags(ITEM_TEMP); - null_xact._date = quant - gregorian::days(1); - - post_temps.push_back(post_t(&empty_account)); - post_t& null_post = post_temps.back(); - null_post.add_flags(ITEM_TEMP | POST_CALCULATED); - null_post.amount = 0L; - null_xact.add_post(&null_post); - - last_post = &null_post; - subtotal_posts::operator()(null_post); - - report_subtotal(quant - gregorian::days(1)); + for (++last_interval; interval != last_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_temps.push_back(xact_t()); + xact_t& null_xact = xact_temps.back(); + null_xact.add_flags(ITEM_TEMP); + null_xact._date = last_interval.inclusive_end(); + + post_temps.push_back(post_t(&empty_account)); + post_t& null_post = post_temps.back(); + null_post.add_flags(ITEM_TEMP | POST_CALCULATED); + null_post.amount = 0L; + null_xact.add_post(&null_post); + + last_post = &null_post; + subtotal_posts::operator()(null_post); + + report_subtotal(last_interval.inclusive_end()); + } } } - start = interval.begin = quant; } subtotal_posts::operator()(post); } else { @@ -745,7 +733,7 @@ void generate_posts::add_period_xacts(period_xacts_list& period_xacts) add_post(xact->period, *post); } -void generate_posts::add_post(const interval_t& period, post_t& post) +void generate_posts::add_post(const date_interval_t& period, post_t& post) { pending_posts.push_back(pending_posts_pair(period, &post)); } @@ -759,6 +747,7 @@ void budget_posts::report_budget_items(const date_t& date) do { reported = false; foreach (pending_posts_list::value_type& pair, pending_posts) { +#if 0 date_t& begin = pair.first.begin; if (! is_valid(begin)) { pair.first.set_start(date); @@ -790,6 +779,7 @@ void budget_posts::report_budget_items(const date_t& date) reported = true; } +#endif } } while (reported); } @@ -823,11 +813,12 @@ void budget_posts::operator()(post_t& post) } } -void forecast_posts::add_post(const interval_t& period, post_t& post) +void forecast_posts::add_post(const date_interval_t& period, post_t& post) { generate_posts::add_post(period, post); - interval_t& i = pending_posts.back().first; + date_interval_t& i = pending_posts.back().first; +#if 0 if (! is_valid(i.begin)) { i.set_start(CURRENT_DATE()); i.begin = i.increment(i.begin); @@ -835,6 +826,7 @@ void forecast_posts::add_post(const interval_t& period, post_t& post) while (i.begin < CURRENT_DATE()) i.begin = i.increment(i.begin); } +#endif } void forecast_posts::flush() @@ -842,6 +834,7 @@ void forecast_posts::flush() posts_list passed; date_t last; +#if 0 while (pending_posts.size() > 0) { pending_posts_list::iterator least = pending_posts.begin(); for (pending_posts_list::iterator i = ++pending_posts.begin(); @@ -900,6 +893,7 @@ void forecast_posts::flush() } } } +#endif item_handler::flush(); } -- cgit v1.2.3 From f2c60057ef20ae7138caaac4911f4b12cdc81002 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2009 00:09:33 -0400 Subject: Restored all the old code, though not tested yet --- src/filters.cc | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 06518169..20bfc5d0 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -747,15 +747,16 @@ void budget_posts::report_budget_items(const date_t& date) do { reported = false; foreach (pending_posts_list::value_type& pair, pending_posts) { -#if 0 - date_t& begin = pair.first.begin; - if (! is_valid(begin)) { - pair.first.set_start(date); - begin = pair.first.begin; + optional begin = pair.first.start; + if (! begin) { + if (! pair.first.find_period(date)) + throw_(std::runtime_error, "Something odd has happened"); + begin = pair.first.start; } + assert(begin); - if (begin < date && - (! is_valid(pair.first.end) || begin < pair.first.end)) { + if (*begin < date && + (! pair.first.end || *begin < *pair.first.end)) { post_t& post = *pair.second; DEBUG("ledger.walk.budget", "Reporting budget for " @@ -773,13 +774,13 @@ void budget_posts::report_budget_items(const date_t& date) temp.amount.in_place_negate(); xact.add_post(&temp); - begin = pair.first.increment(begin); + ++pair.first; + begin = *pair.first.start; item_handler::operator()(temp); reported = true; } -#endif } } while (reported); } @@ -818,15 +819,14 @@ void forecast_posts::add_post(const date_interval_t& period, post_t& post) generate_posts::add_post(period, post); date_interval_t& i = pending_posts.back().first; -#if 0 - if (! is_valid(i.begin)) { - i.set_start(CURRENT_DATE()); - i.begin = i.increment(i.begin); + if (! i.start) { + if (! i.find_period(CURRENT_DATE())) + throw_(std::runtime_error, "Something odd has happened"); + ++i; } else { - while (i.begin < CURRENT_DATE()) - i.begin = i.increment(i.begin); + while (*i.start < CURRENT_DATE()) + ++i; } -#endif } void forecast_posts::flush() @@ -834,18 +834,17 @@ void forecast_posts::flush() posts_list passed; date_t last; -#if 0 while (pending_posts.size() > 0) { pending_posts_list::iterator least = pending_posts.begin(); for (pending_posts_list::iterator i = ++pending_posts.begin(); i != pending_posts.end(); i++) - if ((*i).first.begin < (*least).first.begin) + if (*(*i).first.start < *(*least).first.start) least = i; - date_t& begin = (*least).first.begin; + date_t& begin = *(*least).first.start; - if (is_valid((*least).first.end) && begin >= (*least).first.end) { + if ((*least).first.end && begin >= *(*least).first.end) { pending_posts.erase(least); passed.remove((*least).second); continue; @@ -864,7 +863,9 @@ void forecast_posts::flush() temp.add_flags(ITEM_TEMP); xact.add_post(&temp); - date_t next = (*least).first.increment(begin); + date_t next = *(*least).first.next; + ++(*least).first; + if (next < begin || (is_valid(last) && (next - last).days() > 365 * 5)) break; begin = next; @@ -893,7 +894,6 @@ void forecast_posts::flush() } } } -#endif item_handler::flush(); } -- cgit v1.2.3 From f1523b5464924bf9d9987fce0cb3dbe4acda5a4b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 16 Mar 2009 03:44:27 -0400 Subject: The new code is working now. --- src/filters.cc | 85 ++++++++++++++++++++++++++++++---------------------------- src/filters.h | 9 +++---- src/precmd.cc | 2 +- src/textual.cc | 2 -- src/times.cc | 23 ++++++++-------- src/times.h | 10 ++++--- 6 files changed, 68 insertions(+), 63 deletions(-) (limited to 'src/filters.cc') diff --git a/src/filters.cc b/src/filters.cc index 20bfc5d0..14b18db1 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -483,41 +483,41 @@ void changed_value_posts::operator()(post_t& post) last_post = &post; } -void subtotal_posts::report_subtotal(const char * spec_fmt, - const date_t& start, - const date_t& finish) +void subtotal_posts::report_subtotal(const char * spec_fmt, + const optional& interval) { if (component_posts.empty()) return; - date_t range_start = start; - date_t range_finish = finish; + optional range_start = interval ? interval->start : none; + optional range_finish = interval ? interval->inclusive_end() : none; + foreach (post_t * post, component_posts) { date_t date = post->date(); - if (! is_valid(range_start) || date < range_start) + if (! range_start || date < *range_start) range_start = date; - if (! is_valid(range_finish) || date > range_finish) + if (! range_finish || date > *range_finish) range_finish = date; } component_posts.clear(); std::ostringstream out_date; if (spec_fmt) { - out_date << format_date(range_finish, string(spec_fmt)); + out_date << format_date(*range_finish, string(spec_fmt)); } else if (date_format) { string fmt = "- "; fmt += *date_format; - out_date << format_date(range_finish, string(fmt)); + out_date << format_date(*range_finish, string(fmt)); } else { - out_date << format_date(range_finish, std::string("- ") + output_date_format); + out_date << format_date(*range_finish, std::string("- ") + output_date_format); } xact_temps.push_back(xact_t()); xact_t& xact = xact_temps.back(); xact.payee = out_date.str(); - xact._date = range_start; + xact._date = *range_start; foreach (values_map::value_type& pair, values) handle_value(pair.second.value, pair.second.account, &xact, post_temps, @@ -556,13 +556,13 @@ void subtotal_posts::operator()(post_t& post) post.reported_account()->xdata().add_flags(ACCOUNT_EXT_HAS_UNB_VIRTUALS); } -void interval_posts::report_subtotal(const date_t& finish) +void interval_posts::report_subtotal(const date_interval_t& interval) { if (last_post && interval) { if (exact_periods) subtotal_posts::report_subtotal(); else - subtotal_posts::report_subtotal(NULL, *interval.start, finish); + subtotal_posts::report_subtotal(NULL, interval); } last_post = NULL; @@ -572,37 +572,40 @@ void interval_posts::operator()(post_t& post) { date_t date = post.date(); - if (! interval.find_period(post.date(), &last_interval)) + if (! interval.find_period(post.date())) return; if (interval.duration) { - if (last_interval) { - if (interval != last_interval) { - report_subtotal(last_interval.inclusive_end()); - - if (generate_empty_posts) { - for (++last_interval; interval != last_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_temps.push_back(xact_t()); - xact_t& null_xact = xact_temps.back(); - null_xact.add_flags(ITEM_TEMP); - null_xact._date = last_interval.inclusive_end(); - - post_temps.push_back(post_t(&empty_account)); - post_t& null_post = post_temps.back(); - null_post.add_flags(ITEM_TEMP | POST_CALCULATED); - null_post.amount = 0L; - null_xact.add_post(&null_post); - - last_post = &null_post; - subtotal_posts::operator()(null_post); - - report_subtotal(last_interval.inclusive_end()); - } + if (last_interval && interval != last_interval) { + report_subtotal(last_interval); + + if (generate_empty_posts) { + for (++last_interval; interval != last_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_temps.push_back(xact_t()); + xact_t& null_xact = xact_temps.back(); + null_xact.add_flags(ITEM_TEMP); + null_xact._date = last_interval.inclusive_end(); + + post_temps.push_back(post_t(&empty_account)); + post_t& null_post = post_temps.back(); + null_post.add_flags(ITEM_TEMP | POST_CALCULATED); + null_post.amount = 0L; + null_xact.add_post(&null_post); + + last_post = &null_post; + subtotal_posts::operator()(null_post); + + report_subtotal(last_interval); } + assert(interval == last_interval); + } else { + last_interval = interval; } + } else { + last_interval = interval; } subtotal_posts::operator()(post); } else { @@ -750,7 +753,7 @@ void budget_posts::report_budget_items(const date_t& date) optional begin = pair.first.start; if (! begin) { if (! pair.first.find_period(date)) - throw_(std::runtime_error, "Something odd has happened"); + throw_(std::runtime_error, _()"Something odd has happened"); begin = pair.first.start; } assert(begin); @@ -821,7 +824,7 @@ void forecast_posts::add_post(const date_interval_t& period, post_t& post) date_interval_t& i = pending_posts.back().first; if (! i.start) { if (! i.find_period(CURRENT_DATE())) - throw_(std::runtime_error, "Something odd has happened"); + throw_(std::runtime_error, _("Something odd has happened")); ++i; } else { while (*i.start < CURRENT_DATE()) diff --git a/src/filters.h b/src/filters.h index 994d7b36..14b97c23 100644 --- a/src/filters.h +++ b/src/filters.h @@ -539,9 +539,8 @@ public: clear_xacts_posts(xact_temps); } - void report_subtotal(const char * spec_fmt = NULL, - const date_t& start = date_t(), - const date_t& finish = date_t()); + void report_subtotal(const char * spec_fmt = NULL, + const optional& interval = none); virtual void flush() { if (values.size() > 0) @@ -585,12 +584,12 @@ public: TRACE_DTOR(interval_posts); } - void report_subtotal(const date_t& finish); + void report_subtotal(const date_interval_t& interval); virtual void flush() { if (last_post && interval.duration) { if (interval.is_valid()) - report_subtotal(interval.inclusive_end()); + report_subtotal(interval); subtotal_posts::flush(); } } diff --git a/src/precmd.cc b/src/precmd.cc index c3e74c0e..1160cc64 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -204,7 +204,7 @@ value_t period_command(call_scope_t& args) out << i << "): " << format_date(*interval.start); if (interval.end_of_duration) - out << " -- " << format_date(interval.inclusive_end()); + out << " -- " << format_date(*interval.inclusive_end()); out << std::endl; if (! interval.skip_duration) diff --git a/src/textual.cc b/src/textual.cc index 8f7388a2..0c92f7bb 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -592,8 +592,6 @@ void instance_t::period_xact_directive(char * line) try { std::auto_ptr pe(new period_xact_t(skip_ws(line + 1))); - if (! pe->period) - throw_(parse_error, _("Parsing time period '%1'") << line); reveal_context = false; diff --git a/src/times.cc b/src/times.cc index 2074f651..4bf5241b 100644 --- a/src/times.cc +++ b/src/times.cc @@ -195,7 +195,7 @@ std::ostream& operator<<(std::ostream& out, void date_interval_t::resolve_end() { - if (! end_of_duration) { + if (start && ! end_of_duration) { end_of_duration = add_duration(*start, *duration); DEBUG("times.interval", "stabilize: end_of_duration = " << *end_of_duration); @@ -222,6 +222,11 @@ void date_interval_t::resolve_end() void date_interval_t::stabilize(const optional& date) { +#if defined(DEBUG_ON) + if (date) + DEBUG("times.interval", "stabilize: with date = " << *date); +#endif + if (date && ! aligned) { DEBUG("times.interval", "stabilize: date passed, but not aligned"); if (duration) { @@ -311,8 +316,7 @@ void date_interval_t::stabilize(const optional& date) } } -bool date_interval_t::find_period(const date_t& date, - date_interval_t * last_interval) +bool date_interval_t::find_period(const date_t& date) { stabilize(date); @@ -322,13 +326,16 @@ bool date_interval_t::find_period(const date_t& date, return false; } - if (date < *start) { + if (! start) { + throw_(std::runtime_error, _("Date interval is improperly initialized")); + } + else if (date < *start) { DEBUG("times.interval", "false: date [" << date << "] < start [" << *start << "]"); return false; } - if (date < *end_of_duration) { + if (end_of_duration && date < *end_of_duration) { DEBUG("times.interval", "true: date [" << date << "] < end_of_duration [" << *end_of_duration << "]"); @@ -349,12 +356,6 @@ bool date_interval_t::find_period(const date_t& date, while (date >= scan && (! end || scan < *end)) { if (date < end_of_scan) { - if (last_interval) { - last_interval->start = start; - last_interval->next = next; - last_interval->end_of_duration = end_of_duration; - } - start = scan; end_of_duration = end_of_scan; next = none; diff --git a/src/times.h b/src/times.h index eb58a97f..9750bbfb 100644 --- a/src/times.h +++ b/src/times.h @@ -155,6 +155,7 @@ public: } date_interval_t(const date_interval_t& other) : start(other.start), + aligned(other.aligned), skip_duration(other.skip_duration), factor(other.factor), next(other.next), @@ -193,10 +194,13 @@ public: /** 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, date_interval_t * last_interval = NULL); + bool find_period(const date_t& date); - date_t inclusive_end() const { - return *end_of_duration - gregorian::days(1); + optional inclusive_end() const { + if (end_of_duration) + return *end_of_duration - gregorian::days(1); + else + return none; } date_interval_t& operator++(); -- cgit v1.2.3