]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
time-util: add parse_time(), which is like parse_sec() but allows specification of...
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 15:04:37 +0000 (16:04 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Nov 2015 16:31:31 +0000 (17:31 +0100)
This is useful if we want to parse RLIMIT_RTTIME values where the common
UNIX syntax is without any units but refers to a non-second unit (µs in
this case), but where we want to allow specification of units.

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

index a6a906f453d9310de6ac2519755aeb4c4862b13f..7151fc3d0c6fe8a4999696caee26c016e0fc51de 100644 (file)
@@ -562,7 +562,7 @@ static int parse_date(const char **p, CalendarSpec *c) {
         return -EINVAL;
 }
 
-static int parse_time(const char **p, CalendarSpec *c) {
+static int parse_calendar_time(const char **p, CalendarSpec *c) {
         CalendarComponent *h = NULL, *m = NULL, *s = NULL;
         const char *t;
         int r;
@@ -802,7 +802,7 @@ int calendar_spec_from_string(const char *p, CalendarSpec **spec) {
                 if (r < 0)
                         goto fail;
 
-                r = parse_time(&p, c);
+                r = parse_calendar_time(&p, c);
                 if (r < 0)
                         goto fail;
 
index e629d91cb22ed289e19438303724ad423e44e583..b36fbe4f09cb05c758803958a03bf1c51219ed0f 100644 (file)
@@ -705,7 +705,8 @@ finish:
         return 0;
 }
 
-int parse_sec(const char *t, usec_t *usec) {
+int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
+
         static const struct {
                 const char *suffix;
                 usec_t usec;
@@ -737,7 +738,6 @@ int parse_sec(const char *t, usec_t *usec) {
                 { "y", USEC_PER_YEAR },
                 { "usec", 1ULL },
                 { "us", 1ULL },
-                { "", USEC_PER_SEC }, /* default is sec */
         };
 
         const char *p, *s;
@@ -746,6 +746,7 @@ int parse_sec(const char *t, usec_t *usec) {
 
         assert(t);
         assert(usec);
+        assert(default_unit > 0);
 
         p = t;
 
@@ -764,6 +765,7 @@ int parse_sec(const char *t, usec_t *usec) {
                 long long l, z = 0;
                 char *e;
                 unsigned i, n = 0;
+                usec_t multiplier, k;
 
                 p += strspn(p, WHITESPACE);
 
@@ -806,21 +808,24 @@ int parse_sec(const char *t, usec_t *usec) {
 
                 for (i = 0; i < ELEMENTSOF(table); i++)
                         if (startswith(e, table[i].suffix)) {
-                                usec_t k = (usec_t) z * table[i].usec;
-
-                                for (; n > 0; n--)
-                                        k /= 10;
-
-                                r += (usec_t) l * table[i].usec + k;
+                                multiplier = table[i].usec;
                                 p = e + strlen(table[i].suffix);
-
-                                something = true;
                                 break;
                         }
 
-                if (i >= ELEMENTSOF(table))
-                        return -EINVAL;
+                if (i >= ELEMENTSOF(table)) {
+                        multiplier = default_unit;
+                        p = e;
+                }
+
+                something = true;
+
+                k = (usec_t) z * multiplier;
 
+                for (; n > 0; n--)
+                        k /= 10;
+
+                r += (usec_t) l * multiplier + k;
         }
 
         *usec = r;
@@ -828,6 +833,10 @@ int parse_sec(const char *t, usec_t *usec) {
         return 0;
 }
 
+int parse_sec(const char *t, usec_t *usec) {
+        return parse_time(t, usec, USEC_PER_SEC);
+}
+
 int parse_nsec(const char *t, nsec_t *nsec) {
         static const struct {
                 const char *suffix;
index 925bf18eb25856a14adf41b8053ecede3ab0a809..0417c29cddbe4b5506745a190e42f9fc1f0b5bcb 100644 (file)
@@ -104,6 +104,7 @@ int dual_timestamp_deserialize(const char *value, dual_timestamp *t);
 int parse_timestamp(const char *t, usec_t *usec);
 
 int parse_sec(const char *t, usec_t *usec);
+int parse_time(const char *t, usec_t *usec, usec_t default_unit);
 int parse_nsec(const char *t, nsec_t *nsec);
 
 bool ntp_synced(void);
index 3840fff061793cee1e1086ff68b689699dff5f43..820e4aaee25bb3b1c3d16575a35fd813dbbf9bae 100644 (file)
@@ -57,6 +57,28 @@ static void test_parse_sec(void) {
         assert_se(parse_sec(".3 infinity", &u) < 0);
 }
 
+static void test_parse_time(void) {
+        usec_t u;
+
+        assert_se(parse_time("5", &u, 1) >= 0);
+        assert_se(u == 5);
+
+        assert_se(parse_time("5", &u, USEC_PER_MSEC) >= 0);
+        assert_se(u == 5 * USEC_PER_MSEC);
+
+        assert_se(parse_time("5", &u, USEC_PER_SEC) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+
+        assert_se(parse_time("5s", &u, 1) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+
+        assert_se(parse_time("5s", &u, USEC_PER_SEC) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+
+        assert_se(parse_time("5s", &u, USEC_PER_MSEC) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+}
+
 static void test_parse_nsec(void) {
         nsec_t u;
 
@@ -161,6 +183,7 @@ static void test_get_timezones(void) {
 
 int main(int argc, char *argv[]) {
         test_parse_sec();
+        test_parse_time();
         test_parse_nsec();
         test_format_timespan(1);
         test_format_timespan(USEC_PER_MSEC);