From d1da7b800c29fed717640682b8db342c91f8cf54 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Mon, 28 May 2018 08:15:42 -0700 Subject: [PATCH] [ptime] fix %p and %l --- src/ptimec.hh | 48 +++++++++++++++++++++++++++++-------------- test/lnav_doctests.cc | 44 +++++++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 33 deletions(-) diff --git a/src/ptimec.hh b/src/ptimec.hh index 2f4da8ec..b30c4c30 100644 --- a/src/ptimec.hh +++ b/src/ptimec.hh @@ -603,23 +603,41 @@ inline void ftime_k(char *dst, off_t &off_inout, ssize_t len, const struct exttm inline bool ptime_l(struct exttm *dst, const char *str, off_t &off_inout, ssize_t len) { off_t orig_off = off_inout; + bool consumed_space = false; dst->et_tm.tm_hour = 0; - PTIME_CONSUME(1, { - if (str[off_inout] < '1' || str[off_inout] > '9') { - return false; - } - dst->et_tm.tm_hour = str[off_inout] - '0'; - }); - if (off_inout + 1 < len) { - if (str[off_inout] >= '0' && str[off_inout] <= '9') { - dst->et_tm.tm_hour *= 10; - dst->et_tm.tm_hour += str[off_inout] - '0'; - off_inout += 1; - } + + if ((off_inout + 1) > len) { + return false; } - if (dst->et_tm.tm_hour >= 1 && dst->et_tm.tm_hour <= 12) { + if (str[off_inout] == ' ') { + consumed_space = true; + off_inout += 1; + } + + if ((off_inout + 1) > len) { + off_inout = orig_off; + return false; + } + + if (str[off_inout] < '1' || str[off_inout] > '9') { + off_inout = orig_off; + return false; + } + + dst->et_tm.tm_hour = str[off_inout] - '0'; + off_inout += 1; + + if (consumed_space || str[off_inout] < '0' || str[off_inout] > '9') { + return true; + } + + dst->et_tm.tm_hour *= 10; + dst->et_tm.tm_hour += str[off_inout] - '0'; + off_inout += 1; + + if (dst->et_tm.tm_hour >= 0 && dst->et_tm.tm_hour <= 23) { return true; } @@ -657,11 +675,11 @@ inline bool ptime_p(struct exttm *dst, const char *str, off_t &off_inout, ssize_ } else if ((lead & 0xdf) == 'A') { if (dst->et_tm.tm_hour == 12) { - dst->et_tm.tm_hour -= 12; + dst->et_tm.tm_hour = 0; } } else if ((lead & 0xdf) == 'P') { - if (dst->et_tm.tm_hour > 12) { + if (dst->et_tm.tm_hour < 12) { dst->et_tm.tm_hour += 12; } } diff --git a/test/lnav_doctests.cc b/test/lnav_doctests.cc index abb042b1..a3c08022 100644 --- a/test/lnav_doctests.cc +++ b/test/lnav_doctests.cc @@ -82,30 +82,38 @@ TEST_CASE("rgb_color from string") { } TEST_CASE("ptime_roundtrip") { - const char *fmt = "%Y-%d-%m\t%H:%M:%S"; + const char *fmts[] = { + "%Y-%m-%d %l:%M:%S %p", + "%Y-%m-%d %I:%M:%S %p", + }; time_t now = time(nullptr); - for (time_t sec = now; sec < (now + (24 * 60 * 60)); sec++) { - char ftime_result[128]; - char strftime_result[128]; - struct exttm etm; + for (auto fmt : fmts) { + for (time_t sec = now; sec < (now + (24 * 60 * 60)); sec++) { + char ftime_result[128]; + char strftime_result[128]; + struct exttm etm; - memset(&etm, 0, sizeof(etm)); - gmtime_r(&sec, &etm.et_tm); - etm.et_flags = ETF_YEAR_SET | ETF_MONTH_SET | ETF_DAY_SET; - size_t ftime_size = ftime_fmt(ftime_result, sizeof(ftime_result), fmt, etm); - size_t strftime_size = strftime(strftime_result, sizeof(strftime_result), fmt, &etm.et_tm); + memset(&etm, 0, sizeof(etm)); + gmtime_r(&sec, &etm.et_tm); + etm.et_flags = ETF_YEAR_SET | ETF_MONTH_SET | ETF_DAY_SET; + size_t ftime_size = ftime_fmt(ftime_result, sizeof(ftime_result), + fmt, etm); + size_t strftime_size = strftime(strftime_result, + sizeof(strftime_result), fmt, + &etm.et_tm); - CHECK(string(ftime_result, ftime_size) == - string(strftime_result, strftime_size)); + CHECK(string(ftime_result, ftime_size) == + string(strftime_result, strftime_size)); - struct exttm etm2; - off_t off = 0; + struct exttm etm2; + off_t off = 0; - memset(&etm2, 0, sizeof(etm2)); - bool rc = ptime_fmt(fmt, &etm2, ftime_result, off, ftime_size); - CHECK(rc); - CHECK(sec == tm2sec(&etm2.et_tm)); + memset(&etm2, 0, sizeof(etm2)); + bool rc = ptime_fmt(fmt, &etm2, ftime_result, off, ftime_size); + CHECK(rc); + CHECK(sec == tm2sec(&etm2.et_tm)); + } } }