diff options
author | John Wiegley <johnw@newartisans.com> | 2009-11-18 05:45:48 -0500 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-11-18 05:45:48 -0500 |
commit | e4b3f0bb3a74b799f0f67d8b2f1efeedad5e2021 (patch) | |
tree | 605879730937c258e41090302bff105c6d0a96a1 /src | |
parent | 7fe369eb492f737f570d0ccf4aaf5db68f900279 (diff) | |
download | fork-ledger-e4b3f0bb3a74b799f0f67d8b2f1efeedad5e2021.tar.gz fork-ledger-e4b3f0bb3a74b799f0f67d8b2f1efeedad5e2021.tar.bz2 fork-ledger-e4b3f0bb3a74b799f0f67d8b2f1efeedad5e2021.zip |
The new period parser is passing all tests
Diffstat (limited to 'src')
-rw-r--r-- | src/archive.cc | 2 | ||||
-rw-r--r-- | src/filters.cc | 14 | ||||
-rw-r--r-- | src/precmd.cc | 2 | ||||
-rw-r--r-- | src/report.cc | 13 | ||||
-rw-r--r-- | src/report.h | 31 | ||||
-rw-r--r-- | src/times.cc | 275 | ||||
-rw-r--r-- | src/times.h | 18 | ||||
-rw-r--r-- | src/token.cc | 5 |
8 files changed, 214 insertions, 146 deletions
diff --git a/src/archive.cc b/src/archive.cc index d36712ca..7306f8d3 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -43,7 +43,7 @@ #include "xact.h" #define LEDGER_MAGIC 0x4c454447 -#define ARCHIVE_VERSION 0x03000005 +#define ARCHIVE_VERSION 0x03000006 //BOOST_IS_ABSTRACT(ledger::scope_t) BOOST_CLASS_EXPORT(ledger::scope_t) diff --git a/src/filters.cc b/src/filters.cc index 5a92421b..47e7f66d 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -515,12 +515,14 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, 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 (! range_start || date < *range_start) - range_start = date; - if (! range_finish || date > *range_finish) - range_finish = date; + if (! range_start || ! range_finish) { + foreach (post_t * post, component_posts) { + date_t date = post->date(); + if (! range_start || date < *range_start) + range_start = date; + if (! range_finish || date > *range_finish) + range_finish = date; + } } component_posts.clear(); diff --git a/src/precmd.cc b/src/precmd.cc index 0e024a39..516b90dd 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -169,7 +169,7 @@ value_t period_command(call_scope_t& args) out << std::endl; date_interval_t interval(arg); - interval.dump(out); + interval.dump(out, report.session.current_year); return NULL_VALUE; } diff --git a/src/report.cc b/src/report.cc index efe162e2..78ed05c0 100644 --- a/src/report.cc +++ b/src/report.cc @@ -120,14 +120,15 @@ void report_t::normalize_options(const string& verb) date_interval_t interval(HANDLER(period_).str()); - if (! HANDLED(begin_) && interval.start) { - string predicate = - "date>=[" + to_iso_extended_string(*interval.start) + "]"; + optional<date_t> begin = interval.begin(session.current_year); + optional<date_t> end = interval.end(session.current_year); + + if (! HANDLED(begin_) && begin) { + string predicate = "date>=[" + to_iso_extended_string(*begin) + "]"; HANDLER(limit_).on(string("?normalize"), predicate); } - if (! HANDLED(end_) && interval.finish) { - string predicate = - "date<[" + to_iso_extended_string(*interval.finish) + "]"; + if (! HANDLED(end_) && end) { + string predicate = "date<[" + to_iso_extended_string(*end) + "]"; HANDLER(limit_).on(string("?normalize"), predicate); } diff --git a/src/report.h b/src/report.h index 93f6e9e0..0b1baff1 100644 --- a/src/report.h +++ b/src/report.h @@ -50,6 +50,7 @@ #include "option.h" #include "commodity.h" #include "annotate.h" +#include "session.h" #include "format.h" namespace ledger { @@ -352,7 +353,7 @@ public: set_expr(args[0].to_string(), args[1].to_string()); }); - OPTION(report_t, amount_data); + OPTION(report_t, amount_data); // -j OPTION(report_t, anon); OPTION_(report_t, average, DO() { // -A @@ -377,14 +378,14 @@ public: }); OPTION_(report_t, begin_, DO_(args) { // -b - date_interval_t interval(args[1].to_string()); - if (! interval.start) + date_interval_t interval(args[1].to_string()); + optional<date_t> begin = interval.begin(parent->session.current_year); + if (! begin) throw_(std::invalid_argument, _("Could not determine beginning of period '%1'") << args[1].to_string()); - string predicate = - "date>=[" + to_iso_extended_string(*interval.start) + "]"; + string predicate = "date>=[" + to_iso_extended_string(*begin) + "]"; parent->HANDLER(limit_).on(string("--begin"), predicate); }); @@ -524,17 +525,19 @@ public: OPTION(report_t, empty); // -E OPTION_(report_t, end_, DO_(args) { // -e - date_interval_t interval(args[1].to_string()); - if (! interval.start) + date_interval_t interval(args[1].to_string()); + // Use begin() here so that if the user says --end=2008, we end on + // 2008/01/01 instead of 2009/01/01 (which is what end() would return). + optional<date_t> end = interval.begin(parent->session.current_year); + if (! end) throw_(std::invalid_argument, _("Could not determine end of period '%1'") << args[1].to_string()); - string predicate = - "date<[" + to_iso_extended_string(*interval.start) + "]"; + string predicate = "date<[" + to_iso_extended_string(*end) + "]"; parent->HANDLER(limit_).on(string("--end"), predicate); - parent->terminus = datetime_t(*interval.start); + parent->terminus = datetime_t(*end); }); OPTION(report_t, equity); @@ -622,11 +625,13 @@ public: OPTION_(report_t, now_, DO_(args) { date_interval_t interval(args[1].to_string()); - if (! interval.start) + optional<date_t> begin = interval.begin(parent->session.current_year); + if (! begin) throw_(std::invalid_argument, _("Could not determine beginning of period '%1'") << args[1].to_string()); - ledger::epoch = datetime_t(*interval.start); + ledger::epoch = parent->terminus = datetime_t(*begin); + parent->session.current_year = ledger::epoch->date().year(); }); OPTION__ @@ -844,7 +849,7 @@ public: set_expr(args[0].to_string(), args[1].to_string()); }); - OPTION(report_t, total_data); + OPTION(report_t, total_data); // -J OPTION_(report_t, truncate_, DO_(args) { string style(args[1].to_string()); diff --git a/src/times.cc b/src/times.cc index 97fc3ab8..646f2a84 100644 --- a/src/times.cc +++ b/src/times.cc @@ -434,6 +434,7 @@ class date_parser_t } kind; typedef variant<unsigned short, + string, date_specifier_t::year_type, date_time::months_of_year, date_time::weekdays, @@ -442,7 +443,8 @@ class date_parser_t optional<content_t> value; explicit token_t(kind_t _kind = UNKNOWN, - const optional<content_t>& _value = none) + const optional<content_t>& _value = + content_t(empty_string)) : kind(_kind), value(_value) { TRACE_CTOR(date_parser_t::lexer_t::token_t, ""); } @@ -467,47 +469,110 @@ class date_parser_t } string to_string() const { + std::ostringstream out; + + switch (kind) { + case UNKNOWN: + out << boost::get<string>(*value); + break; + case TOK_DATE: + return boost::get<date_specifier_t>(*value).to_string(); + case TOK_INT: + out << boost::get<unsigned short>(*value); + break; + case TOK_SLASH: return "/"; + case TOK_DASH: return "-"; + case TOK_DOT: return "."; + case TOK_A_YEAR: + out << boost::get<date_specifier_t::year_type>(*value); + break; + case TOK_A_MONTH: + out << date_specifier_t::month_type + (boost::get<date_time::months_of_year>(*value)); + break; + case TOK_A_WDAY: + out << date_specifier_t::day_of_week_type + (boost::get<date_time::weekdays>(*value)); + break; + case TOK_SINCE: return "since"; + case TOK_UNTIL: return "until"; + case TOK_IN: return "in"; + case TOK_THIS: return "this"; + case TOK_NEXT: return "next"; + case TOK_LAST: return "last"; + case TOK_EVERY: return "every"; + case TOK_TODAY: return "today"; + case TOK_TOMORROW: return "tomorrow"; + case TOK_YESTERDAY: return "yesterday"; + case TOK_YEAR: return "year"; + case TOK_QUARTER: return "quarter"; + case TOK_MONTH: return "month"; + case TOK_WEEK: return "week"; + case TOK_DAY: return "day"; + case TOK_YEARLY: return "yearly"; + case TOK_QUARTERLY: return "quarterly"; + case TOK_BIMONTHLY: return "bimonthly"; + case TOK_MONTHLY: return "monthly"; + case TOK_BIWEEKLY: return "biweekly"; + case TOK_WEEKLY: return "weekly"; + case TOK_DAILY: return "daily"; + case TOK_YEARS: return "years"; + case TOK_QUARTERS: return "quarters"; + case TOK_MONTHS: return "months"; + case TOK_WEEKS: return "weeks"; + case TOK_DAYS: return "days"; + case END_REACHED: return "<EOF>"; + default: + assert(false); + return empty_string; + } + + return out.str(); + } + + void dump(std::ostream& out) const { switch (kind) { - case UNKNOWN: return "UNKNOWN"; - case TOK_DATE: return "TOK_DATE"; - case TOK_INT: return "TOK_INT"; - case TOK_SLASH: return "TOK_SLASH"; - case TOK_DASH: return "TOK_DASH"; - case TOK_DOT: return "TOK_DOT"; - case TOK_A_YEAR: return "TOK_A_YEAR"; - case TOK_A_MONTH: return "TOK_A_MONTH"; - case TOK_A_WDAY: return "TOK_A_WDAY"; - case TOK_SINCE: return "TOK_SINCE"; - case TOK_UNTIL: return "TOK_UNTIL"; - case TOK_IN: return "TOK_IN"; - case TOK_THIS: return "TOK_THIS"; - case TOK_NEXT: return "TOK_NEXT"; - case TOK_LAST: return "TOK_LAST"; - case TOK_EVERY: return "TOK_EVERY"; - case TOK_TODAY: return "TOK_EVERY"; - case TOK_TOMORROW: return "TOK_TOMORROW"; - case TOK_YESTERDAY: return "TOK_YESTERDAY"; - case TOK_YEAR: return "TOK_YEAR"; - case TOK_QUARTER: return "TOK_QUARTER"; - case TOK_MONTH: return "TOK_MONTH"; - case TOK_WEEK: return "TOK_WEEK"; - case TOK_DAY: return "TOK_DAY"; - case TOK_YEARLY: return "TOK_YEARLY"; - case TOK_QUARTERLY: return "TOK_QUARTERLY"; - case TOK_BIMONTHLY: return "TOK_BIMONTHLY"; - case TOK_MONTHLY: return "TOK_MONTHLY"; - case TOK_BIWEEKLY: return "TOK_BIWEEKLY"; - case TOK_WEEKLY: return "TOK_WEEKLY"; - case TOK_DAILY: return "TOK_DAILY"; - case TOK_YEARS: return "TOK_YEARS"; - case TOK_QUARTERS: return "TOK_QUARTERS"; - case TOK_MONTHS: return "TOK_MONTHS"; - case TOK_WEEKS: return "TOK_WEEKS"; - case TOK_DAYS: return "TOK_DAYS"; - case END_REACHED: return "END_REACHED"; + case UNKNOWN: out << "UNKNOWN"; break; + case TOK_DATE: out << "TOK_DATE"; break; + case TOK_INT: out << "TOK_INT"; break; + case TOK_SLASH: out << "TOK_SLASH"; break; + case TOK_DASH: out << "TOK_DASH"; break; + case TOK_DOT: out << "TOK_DOT"; break; + case TOK_A_YEAR: out << "TOK_A_YEAR"; break; + case TOK_A_MONTH: out << "TOK_A_MONTH"; break; + case TOK_A_WDAY: out << "TOK_A_WDAY"; break; + case TOK_SINCE: out << "TOK_SINCE"; break; + case TOK_UNTIL: out << "TOK_UNTIL"; break; + case TOK_IN: out << "TOK_IN"; break; + case TOK_THIS: out << "TOK_THIS"; break; + case TOK_NEXT: out << "TOK_NEXT"; break; + case TOK_LAST: out << "TOK_LAST"; break; + case TOK_EVERY: out << "TOK_EVERY"; break; + case TOK_TODAY: out << "TOK_TODAY"; break; + case TOK_TOMORROW: out << "TOK_TOMORROW"; break; + case TOK_YESTERDAY: out << "TOK_YESTERDAY"; break; + case TOK_YEAR: out << "TOK_YEAR"; break; + case TOK_QUARTER: out << "TOK_QUARTER"; break; + case TOK_MONTH: out << "TOK_MONTH"; break; + case TOK_WEEK: out << "TOK_WEEK"; break; + case TOK_DAY: out << "TOK_DAY"; break; + case TOK_YEARLY: out << "TOK_YEARLY"; break; + case TOK_QUARTERLY: out << "TOK_QUARTERLY"; break; + case TOK_BIMONTHLY: out << "TOK_BIMONTHLY"; break; + case TOK_MONTHLY: out << "TOK_MONTHLY"; break; + case TOK_BIWEEKLY: out << "TOK_BIWEEKLY"; break; + case TOK_WEEKLY: out << "TOK_WEEKLY"; break; + case TOK_DAILY: out << "TOK_DAILY"; break; + case TOK_YEARS: out << "TOK_YEARS"; break; + case TOK_QUARTERS: out << "TOK_QUARTERS"; break; + case TOK_MONTHS: out << "TOK_MONTHS"; break; + case TOK_WEEKS: out << "TOK_WEEKS"; break; + case TOK_DAYS: out << "TOK_DAYS"; break; + case END_REACHED: out << "END_REACHED"; break; + default: + assert(false); + break; } - assert(false); - return empty_string; } void unexpected(); @@ -753,7 +818,9 @@ date_interval_t date_parser_t::parse() inclusion_specifier = date_specifier_t(static_cast<date_specifier_t::year_type>(temp.year()), temp.month()); +#if 0 period.duration = date_duration_t(date_duration_t::QUARTERS, 1); +#endif break; } @@ -771,7 +838,9 @@ date_interval_t date_parser_t::parse() date_duration_t::find_nearest(today, date_duration_t::WEEKS); temp += gregorian::days(7 * adjust); inclusion_specifier = date_specifier_t(today); +#if 0 period.duration = date_duration_t(date_duration_t::WEEKS, 1); +#endif break; } @@ -806,19 +875,19 @@ date_interval_t date_parser_t::parse() tok = lexer.next_token(); switch (tok.kind) { case lexer_t::token_t::TOK_YEARS: - period.skip_duration = date_duration_t(date_duration_t::YEARS, quantity); + period.duration = date_duration_t(date_duration_t::YEARS, quantity); break; case lexer_t::token_t::TOK_QUARTERS: - period.skip_duration = date_duration_t(date_duration_t::QUARTERS, quantity); + period.duration = date_duration_t(date_duration_t::QUARTERS, quantity); break; case lexer_t::token_t::TOK_MONTHS: - period.skip_duration = date_duration_t(date_duration_t::MONTHS, quantity); + period.duration = date_duration_t(date_duration_t::MONTHS, quantity); break; case lexer_t::token_t::TOK_WEEKS: - period.skip_duration = date_duration_t(date_duration_t::WEEKS, quantity); + period.duration = date_duration_t(date_duration_t::WEEKS, quantity); break; case lexer_t::token_t::TOK_DAYS: - period.skip_duration = date_duration_t(date_duration_t::DAYS, quantity); + period.duration = date_duration_t(date_duration_t::DAYS, quantity); break; default: tok.unexpected(); @@ -827,19 +896,19 @@ date_interval_t date_parser_t::parse() } else { switch (tok.kind) { case lexer_t::token_t::TOK_YEAR: - period.skip_duration = date_duration_t(date_duration_t::YEARS, 1); + period.duration = date_duration_t(date_duration_t::YEARS, 1); break; case lexer_t::token_t::TOK_QUARTER: - period.skip_duration = date_duration_t(date_duration_t::QUARTERS, 1); + period.duration = date_duration_t(date_duration_t::QUARTERS, 1); break; case lexer_t::token_t::TOK_MONTH: - period.skip_duration = date_duration_t(date_duration_t::MONTHS, 1); + period.duration = date_duration_t(date_duration_t::MONTHS, 1); break; case lexer_t::token_t::TOK_WEEK: - period.skip_duration = date_duration_t(date_duration_t::WEEKS, 1); + period.duration = date_duration_t(date_duration_t::WEEKS, 1); break; case lexer_t::token_t::TOK_DAY: - period.skip_duration = date_duration_t(date_duration_t::DAYS, 1); + period.duration = date_duration_t(date_duration_t::DAYS, 1); break; default: tok.unexpected(); @@ -849,25 +918,25 @@ date_interval_t date_parser_t::parse() break; case lexer_t::token_t::TOK_YEARLY: - period.skip_duration = date_duration_t(date_duration_t::YEARS, 1); + period.duration = date_duration_t(date_duration_t::YEARS, 1); break; case lexer_t::token_t::TOK_QUARTERLY: - period.skip_duration = date_duration_t(date_duration_t::QUARTERS, 1); + period.duration = date_duration_t(date_duration_t::QUARTERS, 1); break; case lexer_t::token_t::TOK_BIMONTHLY: - period.skip_duration = date_duration_t(date_duration_t::MONTHS, 2); + period.duration = date_duration_t(date_duration_t::MONTHS, 2); break; case lexer_t::token_t::TOK_MONTHLY: - period.skip_duration = date_duration_t(date_duration_t::MONTHS, 1); + period.duration = date_duration_t(date_duration_t::MONTHS, 1); break; case lexer_t::token_t::TOK_BIWEEKLY: - period.skip_duration = date_duration_t(date_duration_t::WEEKS, 2); + period.duration = date_duration_t(date_duration_t::WEEKS, 2); break; case lexer_t::token_t::TOK_WEEKLY: - period.skip_duration = date_duration_t(date_duration_t::WEEKS, 1); + period.duration = date_duration_t(date_duration_t::WEEKS, 1); break; case lexer_t::token_t::TOK_DAILY: - period.skip_duration = date_duration_t(date_duration_t::DAYS, 1); + period.duration = date_duration_t(date_duration_t::DAYS, 1); break; default: @@ -876,8 +945,10 @@ date_interval_t date_parser_t::parse() } } +#if 0 if (! period.duration && inclusion_specifier) period.duration = inclusion_specifier->implied_duration(); +#endif if (since_specifier || until_specifier) { date_range_t range(since_specifier, until_specifier); @@ -915,16 +986,9 @@ void date_interval_t::resolve_end() "stabilize: end_of_duration reset to end: " << *end_of_duration); } - if (! skip_duration) { - skip_duration = duration; - DEBUG("times.interval", - "stabilize: skip_duration set to: " << *skip_duration); - } - if (start && ! next) { - next = skip_duration->add(*start); - DEBUG("times.interval", - "stabilize: next set to: " << *next); + next = end_of_duration; + DEBUG("times.interval", "stabilize: next set to: " << *next); } } @@ -988,10 +1052,10 @@ void date_interval_t::stabilize(const optional<date_t>& date) #if defined(DEBUG_ON) if (initial_start) DEBUG("times.interval", - "stabilize: initial_start = " << *initial_start); + "stabilize: initial_start = " << *initial_start); if (initial_finish) DEBUG("times.interval", - "stabilize: initial_finish = " << *initial_finish); + "stabilize: initial_finish = " << *initial_finish); #endif date_t when = start ? *start : *date; @@ -1024,9 +1088,10 @@ void date_interval_t::stabilize(const optional<date_t>& date) } } - DEBUG("times.interval", "stabilize: final start date = " << *start); + DEBUG("times.interval", "stabilize: proposed start date = " << *start); if (initial_start && (! start || *start < *initial_start)) { + // Using the discovered start, find the end of the period resolve_end(); start = initial_start; @@ -1036,14 +1101,20 @@ void date_interval_t::stabilize(const optional<date_t>& date) finish = initial_finish; DEBUG("times.interval", "stabilize: finish reset to initial finish"); } + + if (start) + DEBUG("times.interval", "stabilize: final start = " << *start); + if (finish) + DEBUG("times.interval", "stabilize: final finish = " << *finish); } else if (range) { - start = range->begin(); - finish = range->end(); - - if (start && finish) - duration = date_duration_t(date_duration_t::DAYS, - static_cast<int>((*finish - *start).days())); + if (date) { + start = range->begin(date->year()); + finish = range->end(date->year()); + } else { + start = range->begin(); + finish = range->end(); + } } aligned = true; } @@ -1116,7 +1187,7 @@ bool date_interval_t::find_period(const date_t& date) return true; } - scan = skip_duration->add(scan); + scan = duration->add(scan); end_of_scan = duration->add(scan); } @@ -1130,7 +1201,7 @@ date_interval_t& date_interval_t::operator++() stabilize(); - if (! skip_duration || ! duration) + if (! duration) throw_(date_error, _("Cannot increment a date interval without a duration")); @@ -1140,10 +1211,8 @@ date_interval_t& date_interval_t::operator++() start = none; } else { start = *next; - end_of_duration = duration->add(*start); } - next = none; resolve_end(); @@ -1151,7 +1220,7 @@ date_interval_t& date_interval_t::operator++() return *this; } -void date_interval_t::dump(std::ostream& out) +void date_interval_t::dump(std::ostream& out, optional_year current_year) { out << _("--- Before stabilization ---") << std::endl; @@ -1162,14 +1231,10 @@ void date_interval_t::dump(std::ostream& out) if (finish) out << _(" finish: ") << format_date(*finish) << std::endl; - if (skip_duration) - out << _(" skip: ") << skip_duration->to_string() << std::endl; - if (factor) - out << _(" factor: ") << factor << std::endl; if (duration) out << _("duration: ") << duration->to_string() << std::endl; - stabilize(begin()); + stabilize(begin(current_year)); out << std::endl << _("--- After stabilization ---") << std::endl; @@ -1181,27 +1246,30 @@ void date_interval_t::dump(std::ostream& out) if (finish) out << _(" finish: ") << format_date(*finish) << std::endl; - if (skip_duration) - out << _(" skip: ") << skip_duration->to_string() << std::endl; - if (factor) - out << _(" factor: ") << factor << std::endl; if (duration) out << _("duration: ") << duration->to_string() << std::endl; out << std::endl << _("--- Sample dates in range (max. 20) ---") << std::endl; - for (int i = 0; i < 20 && *this; i++, ++*this) { + date_t last_date; + + for (int i = 0; i < 20 && *this; ++i, ++*this) { out << std::right; out.width(2); + if (! last_date.is_not_a_date() && last_date == *start) + break; + out << (i + 1) << ": " << format_date(*start); - if (skip_duration) - out << " -- " << format_date(*inclusive_skip_end()); + if (duration) + out << " -- " << format_date(*inclusive_end()); out << std::endl; - if (! skip_duration) + if (! duration) break; + + last_date = *start; } } @@ -1268,6 +1336,8 @@ date_parser_t::lexer_t::token_t date_parser_t::lexer_t::next_token() token_t::content_t(lexical_cast<unsigned short>(term))); } else if (std::isalpha(term[0])) { + to_lower(term); + if (optional<date_time::months_of_year> month = string_to_month_of_year(term)) { return token_t(token_t::TOK_A_MONTH, token_t::content_t(*month)); @@ -1339,20 +1409,20 @@ date_parser_t::lexer_t::token_t date_parser_t::lexer_t::next_token() token_t::expected('\0', *begin); } - return token_t(token_t::UNKNOWN); + return token_t(token_t::UNKNOWN, token_t::content_t(term)); } void date_parser_t::lexer_t::token_t::unexpected() { - kind_t prev_kind = kind; - - kind = UNKNOWN; - - switch (prev_kind) { + switch (kind) { case END_REACHED: + kind = UNKNOWN; throw_(date_error, _("Unexpected end of expression")); - default: - throw_(date_error, _("Unexpected token '%1'") << to_string()); + default: { + string desc = to_string(); + kind = UNKNOWN; + throw_(date_error, _("Unexpected date period token '%1'") << desc); + } } } @@ -1503,7 +1573,8 @@ void show_period_tokens(std::ostream& out, const string& arg) date_parser_t::lexer_t::token_t token; do { token = lexer.next_token(); - out << token.to_string() << std::endl; + token.dump(out); + out << ": " << token.to_string() << std::endl; } while (token.kind != date_parser_t::lexer_t::token_t::END_REACHED); } diff --git a/src/times.h b/src/times.h index d378dd81..1c9d812e 100644 --- a/src/times.h +++ b/src/times.h @@ -534,16 +534,14 @@ public: optional<date_t> start; // the real start, after adjustment optional<date_t> finish; // the real end, likewise bool aligned; - optional<date_duration_t> skip_duration; - std::size_t factor; optional<date_t> next; optional<date_duration_t> duration; optional<date_t> end_of_duration; - explicit date_interval_t() : aligned(false), factor(1) { + explicit date_interval_t() : aligned(false) { TRACE_CTOR(date_interval_t, ""); } - date_interval_t(const string& str) : aligned(false), factor(1) { + date_interval_t(const string& str) : aligned(false) { TRACE_CTOR(date_interval_t, "const string&"); parse(str); } @@ -552,8 +550,6 @@ public: start(other.start), finish(other.finish), aligned(other.aligned), - skip_duration(other.skip_duration), - factor(other.factor), next(other.next), duration(other.duration), end_of_duration(other.end_of_duration) { @@ -593,12 +589,6 @@ public: containing date, or false if no such period can be found. */ bool find_period(const date_t& date); - optional<date_t> inclusive_skip_end() const { - if (skip_duration) - return skip_duration->add(*start) - gregorian::days(1); - else - return none; - } optional<date_t> inclusive_end() const { if (end_of_duration) return *end_of_duration - gregorian::days(1); @@ -608,7 +598,7 @@ public: date_interval_t& operator++(); - void dump(std::ostream& out); + void dump(std::ostream& out, optional_year current_year = none); #if defined(HAVE_BOOST_SERIALIZATION) private: @@ -622,8 +612,6 @@ private: ar & start; ar & finish; ar & aligned; - ar & skip_duration; - ar & factor; ar & next; ar & duration; ar & end_of_duration; diff --git a/src/token.cc b/src/token.cc index 3df072a7..81c54a82 100644 --- a/src/token.cc +++ b/src/token.cc @@ -206,11 +206,12 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags) length++; date_interval_t timespan(buf); - if (! timespan) + optional<date_t> begin = timespan.begin(); + if (! begin) throw_(parse_error, _("Date specifier does not refer to a starting date")); kind = VALUE; - value = *timespan.start; + value = *begin; break; } |