4cad4c
From 9692477a59c47b5fb6bd6d4702302859296db070 Mon Sep 17 00:00:00 2001
4cad4c
From: Filipe Brandenburger <filbranden@google.com>
4cad4c
Date: Wed, 23 Jan 2019 19:48:54 -0800
4cad4c
Subject: [PATCH] time-util: Introduce parse_sec_def_infinity
4cad4c
4cad4c
This works like parse_sec() but defaults to USEC_INFINITY when passed an
4cad4c
empty string or only whitespace.
4cad4c
4cad4c
Also introduce config_parse_sec_def_infinity, which can be used to parse
4cad4c
config options using this function.
4cad4c
4cad4c
This is useful for time options that use "infinity" for default and that
4cad4c
can be reset by unsetting them.
4cad4c
4cad4c
Introduce a test case to ensure it works as expected.
4cad4c
4cad4c
(cherry picked from commit 7b61ce3c44ef5908e817009ce4f9d2a7a37722be)
4cad4c
4cad4c
Related: #1770379
4cad4c
---
4cad4c
 src/basic/time-util.c     |  9 +++++++++
4cad4c
 src/basic/time-util.h     |  1 +
4cad4c
 src/shared/conf-parser.c  |  1 +
4cad4c
 src/shared/conf-parser.h  |  1 +
4cad4c
 src/test/test-time-util.c | 21 +++++++++++++++++++++
4cad4c
 5 files changed, 33 insertions(+)
4cad4c
4cad4c
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
4cad4c
index fe201c398d..c36e462193 100644
4cad4c
--- a/src/basic/time-util.c
4cad4c
+++ b/src/basic/time-util.c
4cad4c
@@ -1072,6 +1072,15 @@ int parse_sec_fix_0(const char *t, usec_t *usec) {
4cad4c
         return parse_sec(t, usec);
4cad4c
 }
4cad4c
 
4cad4c
+int parse_sec_def_infinity(const char *t, usec_t *ret) {
4cad4c
+        t += strspn(t, WHITESPACE);
4cad4c
+        if (isempty(t)) {
4cad4c
+                *ret = USEC_INFINITY;
4cad4c
+                return 0;
4cad4c
+        }
4cad4c
+        return parse_sec(t, ret);
4cad4c
+}
4cad4c
+
4cad4c
 int parse_nsec(const char *t, nsec_t *nsec) {
4cad4c
         static const struct {
4cad4c
                 const char *suffix;
4cad4c
diff --git a/src/basic/time-util.h b/src/basic/time-util.h
4cad4c
index 344f2dc52e..f5c9ea6327 100644
4cad4c
--- a/src/basic/time-util.h
4cad4c
+++ b/src/basic/time-util.h
4cad4c
@@ -116,6 +116,7 @@ int parse_timestamp(const char *t, usec_t *usec);
4cad4c
 
4cad4c
 int parse_sec(const char *t, usec_t *usec);
4cad4c
 int parse_sec_fix_0(const char *t, usec_t *usec);
4cad4c
+int parse_sec_def_infinity(const char *t, usec_t *usec);
4cad4c
 int parse_time(const char *t, usec_t *usec, usec_t default_unit);
4cad4c
 int parse_nsec(const char *t, nsec_t *nsec);
4cad4c
 
4cad4c
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
4cad4c
index 2d62fdf05d..246b7431e4 100644
4cad4c
--- a/src/shared/conf-parser.c
4cad4c
+++ b/src/shared/conf-parser.c
4cad4c
@@ -509,6 +509,7 @@ DEFINE_PARSER(unsigned, unsigned, safe_atou);
4cad4c
 DEFINE_PARSER(double, double, safe_atod);
4cad4c
 DEFINE_PARSER(nsec, nsec_t, parse_nsec);
4cad4c
 DEFINE_PARSER(sec, usec_t, parse_sec);
4cad4c
+DEFINE_PARSER(sec_def_infinity, usec_t, parse_sec_def_infinity);
4cad4c
 DEFINE_PARSER(mode, mode_t, parse_mode);
4cad4c
 
4cad4c
 int config_parse_iec_size(const char* unit,
4cad4c
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
4cad4c
index 16f042d894..a0a5c89c27 100644
4cad4c
--- a/src/shared/conf-parser.h
4cad4c
+++ b/src/shared/conf-parser.h
4cad4c
@@ -127,6 +127,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_string);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_path);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_strv);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_sec);
4cad4c
+CONFIG_PARSER_PROTOTYPE(config_parse_sec_def_infinity);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_nsec);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_mode);
4cad4c
 CONFIG_PARSER_PROTOTYPE(config_parse_warn_compat);
4cad4c
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
4cad4c
index 87de8d172c..354a01dd1a 100644
4cad4c
--- a/src/test/test-time-util.c
4cad4c
+++ b/src/test/test-time-util.c
4cad4c
@@ -61,6 +61,26 @@ static void test_parse_sec_fix_0(void) {
4cad4c
         assert_se(u == USEC_INFINITY);
4cad4c
 }
4cad4c
 
4cad4c
+static void test_parse_sec_def_infinity(void) {
4cad4c
+        usec_t u;
4cad4c
+
4cad4c
+        log_info("/* %s */", __func__);
4cad4c
+
4cad4c
+        assert_se(parse_sec_def_infinity("5s", &u) >= 0);
4cad4c
+        assert_se(u == 5 * USEC_PER_SEC);
4cad4c
+        assert_se(parse_sec_def_infinity("", &u) >= 0);
4cad4c
+        assert_se(u == USEC_INFINITY);
4cad4c
+        assert_se(parse_sec_def_infinity("     ", &u) >= 0);
4cad4c
+        assert_se(u == USEC_INFINITY);
4cad4c
+        assert_se(parse_sec_def_infinity("0s", &u) >= 0);
4cad4c
+        assert_se(u == 0);
4cad4c
+        assert_se(parse_sec_def_infinity("0", &u) >= 0);
4cad4c
+        assert_se(u == 0);
4cad4c
+        assert_se(parse_sec_def_infinity(" 0", &u) >= 0);
4cad4c
+        assert_se(u == 0);
4cad4c
+        assert_se(parse_sec_def_infinity("-5s", &u) < 0);
4cad4c
+}
4cad4c
+
4cad4c
 static void test_parse_time(void) {
4cad4c
         usec_t u;
4cad4c
 
4cad4c
@@ -420,6 +440,7 @@ int main(int argc, char *argv[]) {
4cad4c
 
4cad4c
         test_parse_sec();
4cad4c
         test_parse_sec_fix_0();
4cad4c
+        test_parse_sec_def_infinity();
4cad4c
         test_parse_time();
4cad4c
         test_parse_nsec();
4cad4c
         test_format_timespan(1);