utils: Add helper function to parse time spans from strings

This commit is contained in:
Tobias Brunner
2017-11-02 10:04:03 +01:00
parent c782d367c6
commit b93ebb4ea9
4 changed files with 132 additions and 42 deletions
+4 -34
View File
@@ -605,41 +605,11 @@ METHOD(settings_t, get_double, double,
*/
inline uint32_t settings_value_as_time(char *value, uint32_t def)
{
char *endptr;
uint32_t timeval;
if (value)
time_t val;
if (timespan_from_string(value, NULL, &val))
{
errno = 0;
timeval = strtoul(value, &endptr, 10);
if (endptr == value)
{
return def;
}
if (errno == 0)
{
while (isspace(*endptr))
{
endptr++;
}
switch (*endptr)
{
case 'd': /* time in days */
timeval *= 24 * 3600;
break;
case 'h': /* time in hours */
timeval *= 3600;
break;
case 'm': /* time in minutes */
timeval *= 60;
break;
case 's': /* time in seconds */
case '\0':
break;
default:
return def;
}
return timeval;
}
return val;
}
return def;
}
@@ -114,6 +114,54 @@ START_TEST(test_timeval_add_ms)
}
END_TEST
/*******************************************************************************
* timespan_from_string
*/
static struct {
char *s;
char *u;
bool v;
time_t t;
} ts_data[] = {
{NULL, NULL, FALSE, 0},
{"", NULL, FALSE, 0},
{"a", NULL, FALSE, 0},
{"0", NULL, TRUE, 0},
{"5", NULL, TRUE, 5},
{"5s", NULL, TRUE, 5},
{"5m", NULL, TRUE, 300},
{"5ms", NULL, TRUE, 300},
{"5h", NULL, TRUE, 18000},
{"5d", NULL, TRUE, 432000},
{"5x", NULL, FALSE, 0},
{"5", "", TRUE, 5},
{"5", "m", TRUE, 300},
{"5", "ms", TRUE, 300},
{"5", "x", FALSE, 0},
{"5x", "m", FALSE, 0},
{"18446744073709551616", NULL, FALSE, 0},
};
START_TEST(test_timespan_from_string)
{
time_t val = 42;
ck_assert(timespan_from_string(ts_data[_i].s, ts_data[_i].u,
NULL) == ts_data[_i].v);
ck_assert(timespan_from_string(ts_data[_i].s, ts_data[_i].u,
&val) == ts_data[_i].v);
if (ts_data[_i].v)
{
ck_assert_int_eq(val, ts_data[_i].t);
}
else
{
ck_assert_int_eq(val, 42);
}
}
END_TEST
/*******************************************************************************
* htoun/untoh
*/
@@ -921,6 +969,10 @@ Suite *utils_suite_create()
tcase_add_test(tc, test_timeval_add_ms);
suite_add_tcase(s, tc);
tc = tcase_create("timespan_from_string");
tcase_add_loop_test(tc, test_timespan_from_string, 0, countof(ts_data));
suite_add_tcase(s, tc);
tc = tcase_create("htoun,untoh");
tcase_add_test(tc, test_htoun);
tcase_add_test(tc, test_untoh);
+62 -6
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2008-2014 Tobias Brunner
* Copyright (C) 2008-2017 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,7 +23,9 @@
#include <utils/utils.h>
#include <inttypes.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
/**
* Return monotonic time
@@ -77,8 +79,62 @@ time_t time_monotonic(timeval_t *tv)
#endif /* !WIN32 */
}
/**
* Described in header.
/*
* Described in header
*/
bool timespan_from_string(char *str, char *defunit, time_t *val)
{
char *endptr, unit;
time_t timeval;
if (str)
{
errno = 0;
timeval = strtoull(str, &endptr, 10);
if (endptr == str)
{
return FALSE;
}
if (errno == 0)
{
while (isspace(*endptr))
{
endptr++;
}
unit = *endptr;
if (!unit && defunit)
{
unit = *defunit;
}
switch (unit)
{
case 'd': /* time in days */
timeval *= 24 * 3600;
break;
case 'h': /* time in hours */
timeval *= 3600;
break;
case 'm': /* time in minutes */
timeval *= 60;
break;
case 's': /* time in seconds */
case '\0':
break;
default:
return FALSE;
}
if (val)
{
*val = timeval;
}
return TRUE;
}
}
return FALSE;
}
/*
* Described in header
*/
int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
const void *const *args)
@@ -112,8 +168,8 @@ int time_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
t.tm_sec, utc ? " UTC " : " ", t.tm_year + 1900);
}
/**
* Described in header.
/*
* Described in header
*/
int time_delta_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
const void *const *args)
+14 -2
View File
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2008-2014 Tobias Brunner
* Copyright (C) 2008-2017 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -70,6 +70,18 @@ static inline void timeval_add_ms(timeval_t *tv, u_int ms)
}
}
/**
* Parse the given string as time span and return the number of seconds,
* optionally with a default unit ('s' for seconds, 'm' for minutes, 'h' for
* hours, 'd' for days - default is 's').
*
* @param str value to parse
* @param defunit optional default unit
* @param[out] val parsed value
* @return TRUE if a value was parsed
*/
bool timespan_from_string(char *str, char *defunit, time_t *val);
/**
* printf hook for time_t.
*