utils: Add helper function to parse time spans from strings
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user