diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/conf-parser.c | 27 | ||||
-rw-r--r-- | src/shared/conf-parser.h | 1 | ||||
-rw-r--r-- | src/shared/util.c | 17 | ||||
-rw-r--r-- | src/shared/util.h | 2 |
4 files changed, 47 insertions, 0 deletions
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index c5dd26db52..b09e90ae8b 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -467,6 +467,33 @@ int config_parse_unsigned( return 0; } +int config_parse_double( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + double *d = data; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + r = safe_atod(rvalue, d); + if (r < 0) { + log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue); + return r; + } + + return 0; +} + int config_parse_bytes_size( const char *filename, unsigned line, diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 56ffc2f8a8..9096c605e2 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -92,6 +92,7 @@ int config_parse_int(const char *filename, unsigned line, const char *section, c int config_parse_unsigned(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_long(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_uint64(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_double(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_bytes_size(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_bytes_off(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_bool(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/shared/util.c b/src/shared/util.c index 152724949d..f5adedc531 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -353,6 +353,23 @@ int safe_atolli(const char *s, long long int *ret_lli) { return 0; } +int safe_atod(const char *s, double *ret_d) { + char *x = NULL; + double d; + + assert(s); + assert(ret_d); + + errno = 0; + d = strtod(s, &x); + + if (!x || x == s || *x || errno) + return errno ? -errno : -EINVAL; + + *ret_d = (double) d; + return 0; +} + /* Split a string into words. */ char *split(const char *c, size_t *l, const char *separator, char **state) { char *current; diff --git a/src/shared/util.h b/src/shared/util.h index 88ef2f9040..19cc36af84 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -122,6 +122,8 @@ int safe_atoi(const char *s, int *ret_i); int safe_atollu(const char *s, unsigned long long *ret_u); int safe_atolli(const char *s, long long int *ret_i); +int safe_atod(const char *s, double *ret_d); + #if __WORDSIZE == 32 static inline int safe_atolu(const char *s, unsigned long *ret_u) { assert_cc(sizeof(unsigned long) == sizeof(unsigned)); |