From: Zbigniew Jędrzejewski-Szmek Date: Thu, 1 Jul 2021 10:10:52 +0000 (+0000) Subject: basic/time-util: add FORMAT_TIMESTAMP X-Git-Tag: v250-rc1~952^2~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae7c644c22f1bf8b4990ced7f3533d1b33547442;p=thirdparty%2Fsystemd.git basic/time-util: add FORMAT_TIMESTAMP This uses the same idea of an anonyous buffer as ETHER_ADDR_TO_STR(). --- diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 2bd947d6a8d..41b4248d89f 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -111,20 +111,25 @@ usec_t triple_timestamp_by_clock(triple_timestamp *ts, clockid_t clock); usec_t timespec_load(const struct timespec *ts) _pure_; nsec_t timespec_load_nsec(const struct timespec *ts) _pure_; -struct timespec *timespec_store(struct timespec *ts, usec_t u); -struct timespec *timespec_store_nsec(struct timespec *ts, nsec_t n); +struct timespec* timespec_store(struct timespec *ts, usec_t u); +struct timespec* timespec_store_nsec(struct timespec *ts, nsec_t n); usec_t timeval_load(const struct timeval *tv) _pure_; -struct timeval *timeval_store(struct timeval *tv, usec_t u); +struct timeval* timeval_store(struct timeval *tv, usec_t u); -char *format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style); -char *format_timestamp_relative(char *buf, size_t l, usec_t t); -char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); +char* format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style); +char* format_timestamp_relative(char *buf, size_t l, usec_t t); +char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy); -static inline char *format_timestamp(char *buf, size_t l, usec_t t) { +static inline char* format_timestamp(char *buf, size_t l, usec_t t) { return format_timestamp_style(buf, l, t, TIMESTAMP_PRETTY); } +/* Note: the lifetime of the compound literal is the immediately surrounding block, + * see C11 §6.5.2.5, and + * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */ +#define FORMAT_TIMESTAMP(t) format_timestamp((char[FORMAT_TIMESTAMP_MAX]){}, FORMAT_TIMESTAMP_MAX, t) + int parse_timestamp(const char *t, usec_t *usec); int parse_sec(const char *t, usec_t *usec); diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c index 6f4675aaf47..bc23affc816 100644 --- a/src/test/test-time-util.c +++ b/src/test/test-time-util.c @@ -335,8 +335,7 @@ static void test_format_timestamp(void) { char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESPAN_MAX)]; usec_t x, y; - random_bytes(&x, sizeof(x)); - x = x % (2147483600 * USEC_PER_SEC) + 1; + x = random_u64_range(2147483600 * USEC_PER_SEC) + 1; assert_se(format_timestamp(buf, sizeof(buf), x)); log_debug("%s", buf); @@ -370,6 +369,26 @@ static void test_format_timestamp(void) { } } +static void test_FORMAT_TIMESTAMP(void) { + log_info("/* %s */", __func__); + + for (unsigned i = 0; i < 100; i++) { + _cleanup_free_ char *buf; + usec_t x, y; + + x = random_u64_range(2147483600 * USEC_PER_SEC) + 1; + + /* strbuf() is to test the macro in an argument to a function call. */ + assert_se(buf = strdup(FORMAT_TIMESTAMP(x))); + log_debug("%s", buf); + assert_se(parse_timestamp(buf, &y) >= 0); + assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC); + + char *t = FORMAT_TIMESTAMP(x); + assert_se(streq(t, buf)); + } +} + static void test_format_timestamp_relative(void) { log_info("/* %s */", __func__); @@ -624,6 +643,7 @@ int main(int argc, char *argv[]) { test_usec_sub_signed(); test_usec_sub_unsigned(); test_format_timestamp(); + test_FORMAT_TIMESTAMP(); test_format_timestamp_relative(); test_format_timestamp_utc(); test_deserialize_dual_timestamp();