]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
basic/time-util: add FORMAT_TIMESTAMP
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 1 Jul 2021 10:10:52 +0000 (10:10 +0000)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 9 Jul 2021 09:03:35 +0000 (11:03 +0200)
This uses the same idea of an anonyous buffer as ETHER_ADDR_TO_STR().

src/basic/time-util.h
src/test/test-time-util.c

index 2bd947d6a8da117e13b9d6d2840626c16f168c74..41b4248d89fc8a3ae09cba5f5d2b2f213218487f 100644 (file)
@@ -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 timespectimespec_store(struct timespec *ts, usec_t u);
+struct timespectimespec_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 timevaltimeval_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);
+charformat_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style);
+charformat_timestamp_relative(char *buf, size_t l, usec_t t);
+charformat_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 charformat_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);
index 6f4675aaf47b7e8520a18efa0fba0c29a3fc1517..bc23affc816d42fdcae1248ab3cad9e1908fb929 100644 (file)
@@ -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();