From 51375686f7c42f14b979b8e70bc5a8c7c32da890 Mon Sep 17 00:00:00 2001 From: Kevin Harwell Date: Mon, 15 May 2017 13:25:43 -0500 Subject: core/conversions: Added string to unsigned integer and long conversions Added functions that convert a string to an unsigned integer or unsigned long. A couple of unit test were also created to test the routines. The reasons for adding these conversion utilities (and hopefully eventually more) are as follows: * Conversion routines are functionally contained with consistent and better error checking * The function names offer a better description of what is happening * It encourages code reuse for easier bug fixing at a single source * It's simpler to use * It's unit testable For instance, currently in a lot of places when converting to an integer or similar the "sscanf" function is used. When using "sscanf" it may not be immediately clear what's happening as it lacks semantic naming. Limited error checking is usually done as well. For example, most of the time a check is done to make sure the value converted, but does not check for overflows or negative valued conversions when converting unsigned numbers. Why use/wrap "strtoul" and not "sscanf" then? Primarily, it lacks some of the built in error handling that "strtoul" has. For instance "strtoul" contains overflow checks. Less so, but can still factor as reasons, "sscanf" is slightly more complex in its use. And maybe a bit controversial, but it may be ("big if") potentially slower than "strtoul" in some cases. Change-Id: If7eaca4a48f8c7b89cc8b5a1f4bed2852fca82bb --- main/conversions.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 main/conversions.c (limited to 'main/conversions.c') diff --git a/main/conversions.c b/main/conversions.c new file mode 100644 index 000000000..e73e1a213 --- /dev/null +++ b/main/conversions.c @@ -0,0 +1,77 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2017, Digium, Inc. + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * + * \brief Conversion utility functions + */ + +/*** MODULEINFO + core + ***/ + +#include +#include +#include +#include + +#include "asterisk/conversions.h" + +static int str_is_negative(const char *str) +{ + /* Ignore any preceding white space */ + while (isspace(*str) && *++str); + return *str == '-'; +} + +int ast_str_to_uint(const char *str, unsigned int *res) +{ + unsigned long val; + + if (ast_str_to_ulong(str, &val) || val > UINT_MAX) { + return -1; + } + + *res = val; + return 0; +} + +int ast_str_to_ulong(const char *str, unsigned long *res) +{ + char *end; + unsigned long val; + + if (!str || str_is_negative(str)) { + return -1; + } + + errno = 0; + val = strtoul(str, &end, 0); + + /* + * If str equals end then no digits were found. If end is not pointing to + * a null character then the string contained some numbers that could be + * converted, but some characters that could not, which we'll consider + * invalid. + */ + if ((str == end || *end != '\0' || (errno == ERANGE && val == ULONG_MAX))) { + return -1; + } + + *res = val; + return 0; + +} -- cgit v1.2.3