The new code is working now.

This commit is contained in:
John Wiegley 2009-03-16 03:44:27 -04:00
parent f2c60057ef
commit f1523b5464
6 changed files with 64 additions and 59 deletions

View file

@ -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<date_interval_t>& interval)
{
if (component_posts.empty())
return;
date_t range_start = start;
date_t range_finish = finish;
optional<date_t> range_start = interval ? interval->start : none;
optional<date_t> 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 (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();
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);
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);
last_post = &null_post;
subtotal_posts::operator()(null_post);
report_subtotal(last_interval.inclusive_end());
}
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<date_t> 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())

View file

@ -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<date_interval_t>& 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();
}
}

View file

@ -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)

View file

@ -592,8 +592,6 @@ void instance_t::period_xact_directive(char * line)
try {
std::auto_ptr<period_xact_t> pe(new period_xact_t(skip_ws(line + 1)));
if (! pe->period)
throw_(parse_error, _("Parsing time period '%1'") << line);
reveal_context = false;

View file

@ -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_t>& 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_t>& 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;

View file

@ -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<date_t> inclusive_end() const {
if (end_of_duration)
return *end_of_duration - gregorian::days(1);
else
return none;
}
date_interval_t& operator++();