mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
time-util: add parse_time(), which is like parse_sec() but allows specification of default time unit if none is specified
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.
This commit is contained in:
parent
75eb615480
commit
519cffec89
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user