diff --git a/config.c b/config.c index 734bd36..100f033 100644 --- a/config.c +++ b/config.c @@ -30,12 +30,6 @@ enum config_section { UNKNOWN_SECTION, }; -enum parser_result { - PARSED_OK, - NOT_PARSED, - BAD_VALUE, -}; - static enum parser_result parse_section_line(char *s, enum config_section *section) { if (!strcasecmp(s, "[global]")) { @@ -512,6 +506,14 @@ int config_read(char *name, struct config *cfg) fprintf(stderr, "%s is a bad value for option %s at line %d\n", value, option, line_num); goto parse_error; + case MALFORMED: + fprintf(stderr, "%s is a malformed value for option %s at line %d\n", + value, option, line_num); + goto parse_error; + case OUT_OF_RANGE: + fprintf(stderr, "%s is an out of range value for option %s at line %d\n", + value, option, line_num); + goto parse_error; } break; diff --git a/config.h b/config.h index 901b50a..d4a58b3 100644 --- a/config.h +++ b/config.h @@ -46,6 +46,14 @@ struct interface { #define CFG_IGNORE_USE_SYSLOG (1 << 5) #define CFG_IGNORE_VERBOSE (1 << 6) +enum parser_result { + PARSED_OK, + NOT_PARSED, + BAD_VALUE, + MALFORMED, + OUT_OF_RANGE, +}; + struct config { /* configuration override */ int cfg_ignore; diff --git a/util.c b/util.c index 55ec49f..45cf5ba 100644 --- a/util.c +++ b/util.c @@ -16,7 +16,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include +#include #include #include "sk.h" @@ -190,3 +192,45 @@ int leap_second_status(uint64_t ts, int leap_set, int *leap, int *utc_offset) return leap_status; } + +enum parser_result get_ranged_int(const char *str_val, int *result, int min, int max) +{ + long parsed_val; + char *endptr = NULL; + errno = 0; + parsed_val = strtol(str_val, &endptr, 0); + if (*endptr != '\0' || endptr == str_val) + return MALFORMED; + if (errno == ERANGE || parsed_val < min || parsed_val > max) + return OUT_OF_RANGE; + *result = parsed_val; + return PARSED_OK; +} + +enum parser_result get_ranged_uint(const char *str_val, unsigned int *result, unsigned int min, unsigned int max) +{ + unsigned long parsed_val; + char *endptr = NULL; + errno = 0; + parsed_val = strtoul(str_val, &endptr, 0); + if (*endptr != '\0' || endptr == str_val) + return MALFORMED; + if (errno == ERANGE || parsed_val < min || parsed_val > max) + return OUT_OF_RANGE; + *result = parsed_val; + return PARSED_OK; +} + +enum parser_result get_ranged_double(const char *str_val, double *result, double min, double max) +{ + double parsed_val; + char *endptr = NULL; + errno = 0; + parsed_val = strtod(str_val, &endptr); + if (*endptr != '\0' || endptr == str_val) + return MALFORMED; + if (errno == ERANGE || parsed_val < min || parsed_val > max) + return OUT_OF_RANGE; + *result = parsed_val; + return PARSED_OK; +} diff --git a/util.h b/util.h index d2734d1..ea14d3b 100644 --- a/util.h +++ b/util.h @@ -20,6 +20,7 @@ #ifndef HAVE_UTIL_H #define HAVE_UTIL_H +#include "config.h" #include "ddt.h" /** @@ -114,4 +115,49 @@ int is_utc_ambiguous(uint64_t ts); * inserted, -1 if leap second will be deleted. */ int leap_second_status(uint64_t ts, int leap_set, int *leap, int *utc_offset); + +/** + * Get an integer value from string with error checking and range + * specification. + * + * @param str_val String which contains an integer value. + * @param result Parsed value is stored in here. + * @param min Lower limit. Return OUT_OF_RANGE if parsed value + * is less than min. + * @param max Upper Limit. Return OUT_OF_RANGE if parsed value + * is bigger than max. + * @return PARSED_OK on success, MALFORMED if str_val is malformed, + * OUT_OF_RANGE if str_val is out of range. + */ +enum parser_result get_ranged_int(const char *str_val, int *result, int min, int max); + +/** + * Get an unsigned integer value from string with error checking and range + * specification. + * + * @param str_val String which contains an unsigned integer value. + * @param result Parsed value is stored in here. + * @param min Lower limit. Return OUT_OF_RANGE if parsed value + * is less than min. + * @param max Upper Limit. Return OUT_OF_RANGE if parsed value + * is bigger than max. + * @return PARSED_OK on success, MALFORMED if str_val is malformed, + * OUT_OF_RANGE if str_val is out of range. + */ +enum parser_result get_ranged_uint(const char *str_val, unsigned int *result, unsigned int min, unsigned int max); + +/** + * Get a double value from string with error checking and range + * specification. + * + * @param str_val String which contains a double value. + * @param result Parsed value is stored in here. + * @param min Lower limit. Return OUT_OF_RANGE if parsed value + * is less than min. + * @param max Upper Limit. Return OUT_OF_RANGE if parsed value + * is bigger than max. + * @return PARSED_OK on success, MALFORMED if str_val is malformed, + * OUT_OF_RANGE if str_val is out of range. + */ +enum parser_result get_ranged_double(const char *str_val, double *result, double min, double max); #endif