[systemd-devel] [PATCH] conf parser: introduce milisecond parsing
Susant Sahani
susant at redhat.com
Wed Jul 16 00:37:52 PDT 2014
Add millisecord parsing support to conf parser.
Immediate usage of this function is to parse bond options
such as MIIMonitor, UpDelayMSec, DownDelayMSec which is
represented in milli seconds.
---
src/shared/conf-parser.c | 1 +
src/shared/conf-parser.h | 1 +
src/shared/time-util.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++
src/shared/time-util.h | 8 ++++
4 files changed, 118 insertions(+)
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index 1f40986..07e8c76 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -451,6 +451,7 @@ DEFINE_PARSER(unsigned, unsigned, safe_atou)
DEFINE_PARSER(double, double, safe_atod)
DEFINE_PARSER(nsec, nsec_t, parse_nsec)
DEFINE_PARSER(sec, usec_t, parse_sec)
+DEFINE_PARSER(msec, msec_t, parse_msec)
int config_parse_iec_size(const char* unit,
const char *filename,
diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h
index 3e2c784..671e207 100644
--- a/src/shared/conf-parser.h
+++ b/src/shared/conf-parser.h
@@ -106,6 +106,7 @@ int config_parse_path(const char *unit, const char *filename, unsigned line, con
int config_parse_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_sec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_nsec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_msec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_log_facility(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_log_level(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
index fc79c56..58d8a67 100644
--- a/src/shared/time-util.c
+++ b/src/shared/time-util.c
@@ -816,6 +816,114 @@ int parse_nsec(const char *t, nsec_t *nsec) {
return 0;
}
+int parse_msec(const char *t, msec_t *msec) {
+ static const struct {
+ const char *suffix;
+ msec_t msec;
+ } table[] = {
+ { "seconds", MSEC_PER_SEC },
+ { "second", MSEC_PER_SEC },
+ { "sec", MSEC_PER_SEC },
+ { "s", MSEC_PER_SEC },
+ { "minutes", MSEC_PER_MINUTE },
+ { "minute", MSEC_PER_MINUTE },
+ { "min", MSEC_PER_MINUTE },
+ { "months", MSEC_PER_MONTH },
+ { "month", MSEC_PER_MONTH },
+ { "m", MSEC_PER_MINUTE },
+ { "hours", MSEC_PER_HOUR },
+ { "hour", MSEC_PER_HOUR },
+ { "hr", MSEC_PER_HOUR },
+ { "h", MSEC_PER_HOUR },
+ { "days", MSEC_PER_DAY },
+ { "day", MSEC_PER_DAY },
+ { "d", MSEC_PER_DAY },
+ { "weeks", MSEC_PER_WEEK },
+ { "week", MSEC_PER_WEEK },
+ { "w", MSEC_PER_WEEK },
+ { "years", MSEC_PER_YEAR },
+ { "year", MSEC_PER_YEAR },
+ { "y", MSEC_PER_YEAR },
+ { "", 1ULL }, /* default is msec */
+ };
+
+ const char *p;
+ msec_t r = 0;
+ bool something = false;
+
+ assert(t);
+ assert(msec);
+
+ p = t;
+ for (;;) {
+ long long l, z = 0;
+ char *e;
+ unsigned i, n = 0;
+
+ p += strspn(p, WHITESPACE);
+
+ if (*p == 0) {
+ if (!something)
+ return -EINVAL;
+
+ break;
+ }
+
+ errno = 0;
+ l = strtoll(p, &e, 10);
+
+ if (errno > 0)
+ return -errno;
+
+ if (l < 0)
+ return -ERANGE;
+
+ 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)) {
+ msec_t k = (msec_t) z * table[i].msec;
+
+ for (; n > 0; n--)
+ k /= 10;
+
+ r += (msec_t) l * table[i].msec + k;
+ p = e + strlen(table[i].suffix);
+
+ something = true;
+ break;
+ }
+
+ if (i >= ELEMENTSOF(table))
+ return -EINVAL;
+
+ }
+
+ *msec = r;
+
+ return 0;
+}
+
+
bool ntp_synced(void) {
struct timex txc = {};
diff --git a/src/shared/time-util.h b/src/shared/time-util.h
index 792cd27..3969df8 100644
--- a/src/shared/time-util.h
+++ b/src/shared/time-util.h
@@ -26,6 +26,7 @@
typedef uint64_t usec_t;
typedef uint64_t nsec_t;
+typedef uint64_t msec_t;
#define NSEC_FMT "%" PRIu64
#define USEC_FMT "%" PRIu64
@@ -46,16 +47,22 @@ typedef struct dual_timestamp {
#define USEC_PER_MINUTE ((usec_t) (60ULL*USEC_PER_SEC))
#define NSEC_PER_MINUTE ((usec_t) (60ULL*NSEC_PER_SEC))
+#define MSEC_PER_MINUTE ((usec_t) (60ULL*MSEC_PER_SEC))
#define USEC_PER_HOUR ((usec_t) (60ULL*USEC_PER_MINUTE))
#define NSEC_PER_HOUR ((usec_t) (60ULL*NSEC_PER_MINUTE))
+#define MSEC_PER_HOUR ((usec_t) (60ULL*MSEC_PER_MINUTE))
#define USEC_PER_DAY ((usec_t) (24ULL*USEC_PER_HOUR))
#define NSEC_PER_DAY ((usec_t) (24ULL*NSEC_PER_HOUR))
+#define MSEC_PER_DAY ((usec_t) (24ULL*MSEC_PER_HOUR))
#define USEC_PER_WEEK ((usec_t) (7ULL*USEC_PER_DAY))
#define NSEC_PER_WEEK ((usec_t) (7ULL*NSEC_PER_DAY))
+#define MSEC_PER_WEEK ((usec_t) (7ULL*MSEC_PER_DAY))
#define USEC_PER_MONTH ((usec_t) (2629800ULL*USEC_PER_SEC))
#define NSEC_PER_MONTH ((usec_t) (2629800ULL*NSEC_PER_SEC))
+#define MSEC_PER_MONTH ((usec_t) (2629800ULL*MSEC_PER_SEC))
#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
#define NSEC_PER_YEAR ((usec_t) (31557600ULL*NSEC_PER_SEC))
+#define MSEC_PER_YEAR ((usec_t) (31557600ULL*MSEC_PER_SEC))
#define FORMAT_TIMESTAMP_MAX ((4*4+1)+11+9+4+1) /* weekdays can be unicode */
#define FORMAT_TIMESTAMP_WIDTH 28 /* when outputting, assume this width */
@@ -93,6 +100,7 @@ int parse_timestamp(const char *t, usec_t *usec);
int parse_sec(const char *t, usec_t *usec);
int parse_nsec(const char *t, nsec_t *nsec);
+int parse_msec(const char *t, msec_t *msec);
bool ntp_synced(void);
--
1.9.3
More information about the systemd-devel
mailing list