diff options
-rw-r--r-- | datetime.cc | 62 | ||||
-rw-r--r-- | datetime.h | 13 | ||||
-rw-r--r-- | debug.h | 8 | ||||
-rw-r--r-- | format.cc | 2 | ||||
-rw-r--r-- | main.cc | 58 | ||||
-rw-r--r-- | textual.cc | 4 | ||||
-rw-r--r-- | walk.cc | 6 | ||||
-rw-r--r-- | walk.h | 2 |
8 files changed, 101 insertions, 54 deletions
diff --git a/datetime.cc b/datetime.cc index baa0bd2c..0714c4ad 100644 --- a/datetime.cc +++ b/datetime.cc @@ -5,8 +5,8 @@ namespace ledger { -std::time_t now = std::time(NULL); -struct std::tm * now_tm = std::localtime(&now); +std::time_t now = std::time(NULL); +int now_year = std::localtime(&now)->tm_year; static std::time_t base = -1; static int base_year = -1; @@ -35,9 +35,11 @@ std::time_t interval_t::increment(const std::time_t moment) std::time_t then = moment; if (years || months) { - struct std::tm * desc = std::gmtime(&then); + struct std::tm * desc = std::localtime(&then); + if (years) desc->tm_year += years; + if (months) { desc->tm_mon += months; @@ -45,7 +47,12 @@ std::time_t interval_t::increment(const std::time_t moment) desc->tm_year++; desc->tm_mon -= 12; } + else if (desc->tm_mon < 0) { + desc->tm_year--; + desc->tm_mon += 12; + } } + then = std::mktime(desc); } @@ -69,7 +76,7 @@ static void parse_inclusion_specifier(const std::string& word, bool saw_mon = true; if (when.tm_year == -1) { - when.tm_year = now_tm->tm_year; + when.tm_year = now_year; saw_year = false; } if (when.tm_mon == -1) { @@ -135,6 +142,47 @@ interval_t * interval_t::parse(std::istream& in, months = 3; else if (word == "yearly") years = 1; + else if (word == "this" || word == "last" || word == "next") { + std::string type = word; + bool mon_spec = false; + char buf[32]; + + if (! in.eof()) + in >> word; + else + word = "month"; + + if (word == "month") { + std::strftime(buf, 31, "%B", std::localtime(&now)); + word = buf; + mon_spec = true; + } + else if (word == "year") { + std::strftime(buf, 31, "%Y", std::localtime(&now)); + word = buf; + } + + parse_inclusion_specifier(word, begin, end); + + if (type == "last") { + if (mon_spec) { + *begin = interval_t(0, -1, 0).increment(*begin); + *end = interval_t(0, -1, 0).increment(*end); + } else { + *begin = interval_t(0, 0, -1).increment(*begin); + *end = interval_t(0, 0, -1).increment(*end); + } + } + else if (type == "next") { + if (mon_spec) { + *begin = interval_t(0, 1, 0).increment(*begin); + *end = interval_t(0, 1, 0).increment(*end); + } else { + *begin = interval_t(0, 0, 1).increment(*begin); + *end = interval_t(0, 0, 1).increment(*end); + } + } + } else if (word == "in") { in >> word; parse_inclusion_specifier(word, begin, end); @@ -180,7 +228,7 @@ bool parse_date(const char * date_str, std::time_t * result, const int year) when.tm_sec = 0; if (when.tm_year == -1) - when.tm_year = ((year == -1) ? now_tm->tm_year : (year - 1900)); + when.tm_year = ((year == -1) ? now_year : (year - 1900)); if (when.tm_mon == -1) when.tm_mon = 0; @@ -225,8 +273,8 @@ bool quick_parse_date(char * date_str, std::time_t * result) struct std::tm when; std::memset(&when, 0, sizeof(when)); - base_year = year == -1 ? now_tm->tm_year + 1900 : year; - when.tm_year = year == -1 ? now_tm->tm_year : year - 1900; + base_year = year == -1 ? now_year + 1900 : year; + when.tm_year = year == -1 ? now_year : year - 1900; when.tm_mday = 1; base = std::mktime(&when); @@ -9,12 +9,11 @@ namespace ledger { struct interval_t { - unsigned long years; - unsigned long months; - unsigned long seconds; + int years; + int months; + int seconds; - interval_t(unsigned long _seconds, unsigned long _months = 0, - unsigned long _years = 0) + interval_t(int _seconds, int _months = 0, int _years = 0) : years(_years), months(_months), seconds(_seconds) {} std::time_t increment(const std::time_t); @@ -23,8 +22,8 @@ struct interval_t std::time_t * end); }; -extern std::time_t now; -extern struct std::tm * now_tm; +extern std::time_t now; +extern int now_year; bool parse_date_mask(const char * date_str, struct std::tm * result); @@ -92,10 +92,10 @@ inline bool _debug_active(const char * const cls) { } #define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x) -#define DEBUG_PRINT_TIME(cls, x) { \ - char buf[256]; \ - std::strftime(buf, 255, "%Y/%m/%d", std::gmtime(&x)); \ - DEBUG_PRINT(cls, #x << " is " << buf); \ +#define DEBUG_PRINT_TIME(cls, x) { \ + char buf[256]; \ + std::strftime(buf, 255, "%Y/%m/%d", std::localtime(&x)); \ + DEBUG_PRINT(cls, #x << " is " << buf); \ } #define DEBUG_PRINT_TIME_(x) DEBUG_PRINT_TIME(_debug_cls, x) @@ -223,7 +223,7 @@ void format_t::format_elements(std::ostream& out, if (details.entry && details.entry->date != -1) { char buf[256]; std::strftime(buf, 255, elem->chars.c_str(), - std::gmtime(&details.entry->date)); + std::localtime(&details.entry->date)); out << (elem->max_width == 0 ? buf : truncated(buf, elem->max_width)); } else { out << " "; @@ -365,35 +365,6 @@ int main(int argc, char * argv[], char * envp[]) show_all_related = true; } - // Compile the format strings - - const char * f; - if (! config->format_string.empty()) - f = config->format_string.c_str(); - else if (command == "b") - f = bal_fmt.c_str(); - else if (command == "r") - f = reg_fmt.c_str(); - else if (command == "E") - f = equity_fmt.c_str(); - else - f = print_fmt.c_str(); - - std::string first_line_format; - std::string next_lines_format; - - if (const char * p = std::strstr(f, "%/")) { - first_line_format = std::string(f, 0, p - f); - next_lines_format = std::string(p + 2); - } else { - first_line_format = next_lines_format = f; - } - - format_t format(first_line_format); - format_t nformat(next_lines_format); - - TIMER_STOP(handle_options); - // Setup a few local and global variables, depending on the config // settings. @@ -453,6 +424,35 @@ int main(int argc, char * argv[], char * envp[]) "disp-pred: " << config->display_predicate); #endif + // Compile the format strings + + const char * f; + if (! config->format_string.empty()) + f = config->format_string.c_str(); + else if (command == "b") + f = bal_fmt.c_str(); + else if (command == "r") + f = reg_fmt.c_str(); + else if (command == "E") + f = equity_fmt.c_str(); + else + f = print_fmt.c_str(); + + std::string first_line_format; + std::string next_lines_format; + + if (const char * p = std::strstr(f, "%/")) { + first_line_format = std::string(f, 0, p - f); + next_lines_format = std::string(p + 2); + } else { + first_line_format = next_lines_format = f; + } + + format_t format(first_line_format); + format_t nformat(next_lines_format); + + TIMER_STOP(handle_options); + // Walk the entries based on the report type and the options TIMER_START(report_gen); @@ -476,8 +476,8 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal, case 'Y': // set the current year in >> c; - in >> now_tm->tm_year; - now_tm->tm_year -= 1900; + in >> now_year; + now_year -= 1900; break; #ifdef TIMELOG_SUPPORT @@ -132,9 +132,9 @@ void subtotal_transactions::flush(const char * spec_fmt) if (start != finish) finish -= 86400; - std::strftime(buf, 255, fmt.c_str(), std::gmtime(&finish)); + std::strftime(buf, 255, fmt.c_str(), std::localtime(&finish)); } else { - std::strftime(buf, 255, spec_fmt, std::gmtime(&finish)); + std::strftime(buf, 255, spec_fmt, std::localtime(&finish)); } entry_t * entry = new entry_t; @@ -199,7 +199,7 @@ void interval_transactions::operator()(transaction_t * xact) } if (! interval.seconds) { - struct std::tm * desc = std::gmtime(&xact->entry->date); + struct std::tm * desc = std::localtime(&xact->entry->date); if (interval.years) desc->tm_mon = 0; desc->tm_mday = 1; @@ -327,7 +327,7 @@ class dow_transactions : public subtotal_transactions virtual void flush(); virtual void operator()(transaction_t * xact) { - struct std::tm * desc = std::gmtime(&xact->entry->date); + struct std::tm * desc = std::localtime(&xact->entry->date); days_of_the_week[desc->tm_wday].push_back(xact); } }; |