[systemd-commits] 2 commits - .gitignore Makefile.am TODO src/shared src/test

Lennart Poettering lennart at kemper.freedesktop.org
Wed Apr 3 14:00:20 PDT 2013


 .gitignore             |    1 
 Makefile.am            |   12 +++++-
 TODO                   |    6 ---
 src/shared/time-util.c |   90 ++++++++++++++++++++++++++++++++++++++++++-------
 src/shared/time-util.h |    1 
 src/test/test-time.c   |   86 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 177 insertions(+), 19 deletions(-)

New commits:
commit 911963f1a29897eee2fffbe503ac05ec13028a30
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 3 22:59:57 2013 +0200

    update TODO

diff --git a/TODO b/TODO
index 2f23647..febf0e6 100644
--- a/TODO
+++ b/TODO
@@ -74,8 +74,6 @@ Features:
 
 * teach ConditionKernelCommandLine= globs or regexes (in order to match foobar={no,0,off})
 
-* hostnamectl: when a passed pretty hostname also qualifies as low-level name, then only set low-level name, and unset the pretty hostname
-
 * we should log capabilities too
 
 * Support SO_REUSEPORT with socket activation:
@@ -128,8 +126,6 @@ Features:
 
 * man: add a link to socket activation blog from systemd.socket(5)
 
-* systemctl status: show drop-in snippets for service files in addition to service file path themesevles.
-
 * man: add more examples to man pages
 
 * man: maybe sort directives in man pages, and take sections from --help and apply them to man too
@@ -149,8 +145,6 @@ Features:
   name for the entries to de_DE if they aren't explicitly suffixed
   individually.
 
-* figure out what we do about hostnames/fqdn in hostnamectl/hostnamed
-
 * use "log level" rather than "log priority" everywhere
 
 * ensure sd_journal_seek_monotonic actually works properly.

commit cb0dac0548e5e51ba21618bfe4711dc1a2bbcfb5
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Apr 3 22:58:41 2013 +0200

    time: add suppot for fractional time specifications
    
    We can now parse "0.5s" as the same as "500ms". In fact, we can parse
    "3.45years" correctly, too, and any other unit and fraction length.

diff --git a/.gitignore b/.gitignore
index c0a340a..8ca7ae8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -123,6 +123,7 @@
 /test-strbuf
 /test-strv
 /test-strxcpyx
+/test-time
 /test-udev
 /test-unit-file
 /test-unit-name
diff --git a/Makefile.am b/Makefile.am
index b63f9a0..59a3886 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1088,7 +1088,8 @@ noinst_tests += \
 	test-strip-tab-ansi \
 	test-cgroup-util \
 	test-prioq \
-	test-fileio
+	test-fileio \
+	test-time
 
 EXTRA_DIST += \
 	test/sched_idle_bad.service \
@@ -1197,6 +1198,15 @@ test_fileio_CFLAGS = \
 test_fileio_LDADD = \
 	libsystemd-core.la
 
+test_time_SOURCES = \
+	src/test/test-time.c
+
+test_time_CFLAGS = \
+	$(AM_CFLAGS)
+
+test_time_LDADD = \
+	libsystemd-core.la
+
 test_log_SOURCES = \
 	src/test/test-log.c
 
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
index e27aaf6..476b847 100644
--- a/src/shared/time-util.c
+++ b/src/shared/time-util.c
@@ -534,15 +534,25 @@ int parse_sec(const char *t, usec_t *usec) {
 
         const char *p;
         usec_t r = 0;
+        bool something = false;
 
         assert(t);
         assert(usec);
 
         p = t;
-        do {
-                long long l;
+        for (;;) {
+                long long l, z = 0;
                 char *e;
-                unsigned i;
+                unsigned i, n = 0;
+
+                p += strspn(p, WHITESPACE);
+
+                if (*p == 0) {
+                        if (!something)
+                                return -EINVAL;
+
+                        break;
+                }
 
                 errno = 0;
                 l = strtoll(p, &e, 10);
@@ -553,22 +563,45 @@ int parse_sec(const char *t, usec_t *usec) {
                 if (l < 0)
                         return -ERANGE;
 
-                if (e == p)
+                if (*e == '.') {
+                        char *b = e + 1;
+
+                        errno = 0;
+                        z = strtoll(b, &e, 10);
+                        if (errno > 0)
+                                return -errno;
+
+                        if (z < 0)
+                                return -ERANGE;
+
+                        if (e == b)
+                                return -EINVAL;
+
+                        n = e - b;
+
+                } else if (e == p)
                         return -EINVAL;
 
                 e += strspn(e, WHITESPACE);
 
                 for (i = 0; i < ELEMENTSOF(table); i++)
                         if (startswith(e, table[i].suffix)) {
-                                r += (usec_t) l * table[i].usec;
+                                usec_t k = (usec_t) z * table[i].usec;
+
+                                for (; n > 0; n--)
+                                        k /= 10;
+
+                                r += (usec_t) l * table[i].usec + k;
                                 p = e + strlen(table[i].suffix);
+
+                                something = true;
                                 break;
                         }
 
                 if (i >= ELEMENTSOF(table))
                         return -EINVAL;
 
-        } while (*p != 0);
+        }
 
         *usec = r;
 
@@ -614,15 +647,25 @@ int parse_nsec(const char *t, nsec_t *nsec) {
 
         const char *p;
         nsec_t r = 0;
+        bool something = false;
 
         assert(t);
         assert(nsec);
 
         p = t;
-        do {
-                long long l;
+        for (;;) {
+                long long l, z = 0;
                 char *e;
-                unsigned i;
+                unsigned i, n = 0;
+
+                p += strspn(p, WHITESPACE);
+
+                if (*p == 0) {
+                        if (!something)
+                                return -EINVAL;
+
+                        break;
+                }
 
                 errno = 0;
                 l = strtoll(p, &e, 10);
@@ -633,22 +676,45 @@ int parse_nsec(const char *t, nsec_t *nsec) {
                 if (l < 0)
                         return -ERANGE;
 
-                if (e == p)
+                if (*e == '.') {
+                        char *b = e + 1;
+
+                        errno = 0;
+                        z = strtoll(b, &e, 10);
+                        if (errno > 0)
+                                return -errno;
+
+                        if (z < 0)
+                                return -ERANGE;
+
+                        if (e == b)
+                                return -EINVAL;
+
+                        n = e - b;
+
+                } else if (e == p)
                         return -EINVAL;
 
                 e += strspn(e, WHITESPACE);
 
                 for (i = 0; i < ELEMENTSOF(table); i++)
                         if (startswith(e, table[i].suffix)) {
-                                r += (nsec_t) l * table[i].nsec;
+                                nsec_t k = (nsec_t) z * table[i].nsec;
+
+                                for (; n > 0; n--)
+                                        k /= 10;
+
+                                r += (nsec_t) l * table[i].nsec + k;
                                 p = e + strlen(table[i].suffix);
+
+                                something = true;
                                 break;
                         }
 
                 if (i >= ELEMENTSOF(table))
                         return -EINVAL;
 
-        } while (*p != 0);
+        }
 
         *nsec = r;
 
diff --git a/src/shared/time-util.h b/src/shared/time-util.h
index 2e3b0f5..a02cdfc 100644
--- a/src/shared/time-util.h
+++ b/src/shared/time-util.h
@@ -22,6 +22,7 @@
 ***/
 
 #include <stdio.h>
+#include <inttypes.h>
 
 typedef uint64_t usec_t;
 typedef uint64_t nsec_t;
diff --git a/src/test/test-time.c b/src/test/test-time.c
new file mode 100644
index 0000000..e9d188f
--- /dev/null
+++ b/src/test/test-time.c
@@ -0,0 +1,86 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2013 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "time-util.h"
+
+static void test_parse_sec(void) {
+        usec_t u;
+
+        assert_se(parse_sec("5s", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+        assert_se(parse_sec("5s500ms", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC + 500 * USEC_PER_MSEC);
+        assert_se(parse_sec(" 5s 500ms  ", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC + 500 * USEC_PER_MSEC);
+        assert_se(parse_sec(" 5.5s  ", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC + 500 * USEC_PER_MSEC);
+        assert_se(parse_sec(" 5.5s 0.5ms ", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC + 500 * USEC_PER_MSEC + 500);
+        assert_se(parse_sec(" .22s ", &u) >= 0);
+        assert_se(u == 220 * USEC_PER_MSEC);
+        assert_se(parse_sec(" .50y ", &u) >= 0);
+        assert_se(u == USEC_PER_YEAR / 2);
+        assert_se(parse_sec("2.5", &u) >= 0);
+        assert_se(u == 2500 * USEC_PER_MSEC);
+        assert_se(parse_sec(".7", &u) >= 0);
+        assert_se(u == 700 * USEC_PER_MSEC);
+
+        assert_se(parse_sec(" xyz ", &u) < 0);
+        assert_se(parse_sec("", &u) < 0);
+        assert_se(parse_sec(" . ", &u) < 0);
+        assert_se(parse_sec(" 5. ", &u) < 0);
+        assert_se(parse_sec(".s ", &u) < 0);
+}
+
+static void test_parse_nsec(void) {
+        nsec_t u;
+
+        assert_se(parse_nsec("5s", &u) >= 0);
+        assert_se(u == 5 * NSEC_PER_SEC);
+        assert_se(parse_nsec("5s500ms", &u) >= 0);
+        assert_se(u == 5 * NSEC_PER_SEC + 500 * NSEC_PER_MSEC);
+        assert_se(parse_nsec(" 5s 500ms  ", &u) >= 0);
+        assert_se(u == 5 * NSEC_PER_SEC + 500 * NSEC_PER_MSEC);
+        assert_se(parse_nsec(" 5.5s  ", &u) >= 0);
+        assert_se(u == 5 * NSEC_PER_SEC + 500 * NSEC_PER_MSEC);
+        assert_se(parse_nsec(" 5.5s 0.5ms ", &u) >= 0);
+        assert_se(u == 5 * NSEC_PER_SEC + 500 * NSEC_PER_MSEC + 500 * NSEC_PER_USEC);
+        assert_se(parse_nsec(" .22s ", &u) >= 0);
+        assert_se(u == 220 * NSEC_PER_MSEC);
+        assert_se(parse_nsec(" .50y ", &u) >= 0);
+        assert_se(u == NSEC_PER_YEAR / 2);
+        assert_se(parse_nsec("2.5", &u) >= 0);
+        assert_se(u == 2);
+        assert_se(parse_nsec(".7", &u) >= 0);
+        assert_se(u == 0);
+
+        assert_se(parse_nsec(" xyz ", &u) < 0);
+        assert_se(parse_nsec("", &u) < 0);
+        assert_se(parse_nsec(" . ", &u) < 0);
+        assert_se(parse_nsec(" 5. ", &u) < 0);
+        assert_se(parse_nsec(".s ", &u) < 0);
+}
+
+int main(int argc, char *argv[]) {
+        test_parse_sec();
+        test_parse_nsec();
+        return 0;
+}



More information about the systemd-commits mailing list