diff --git a/include/shell/shell.h b/include/shell/shell.h index 0a36806600e..2de2a6bdc84 100644 --- a/include/shell/shell.h +++ b/include/shell/shell.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/include/shell/shell_string_conv.h b/include/shell/shell_string_conv.h new file mode 100644 index 00000000000..4ecb992125e --- /dev/null +++ b/include/shell/shell_string_conv.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SHELL_STRING_CONV_H__ +#define SHELL_STRING_CONV_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief String to long conversion with error check. + * + * @warning On success the passed err reference will not be altered + * to avoid err check bloating. Passed err reference should be initialized + * to zero. + * + * @param str Input string. + * @param base Conversion base. + * @param err Error code pointer: + * -EINVAL on invalid string input. + * -ERANGE if numeric string input is to large to convert. + * Unchanged on success. + * + * @return Converted long value. + */ +long shell_strtol(const char *str, int base, int *err); + +/** @brief String to unsigned long conversion with error check. + * + * @warning On success the passed err reference will not be altered + * to avoid err check bloating. Passed err reference should be initialized + * to zero. + * + * @param str Input string. + * @param base Conversion base. + * @param err Error code pointer: + * Set to -EINVAL on invalid string input. + * Set to -ERANGE if numeric string input is to large to convert. + * Unchanged on success. + * + * @return Converted unsigned long value. + */ +unsigned long shell_strtoul(const char *str, int base, int *err); + +/** @brief String to boolean conversion with error check. + * + * @warning On success the passed err reference will not be altered + * to avoid err check bloating. Passed err reference should be initialized + * to zero. + * + * @param str Input string. + * @param base Conversion base. + * @param err Error code pointer: + * Set to -EINVAL on invalid string input. + * Set to -ERANGE if numeric string input is to large to convert. + * Unchanged on success. + * + * @return Converted boolean value. + */ +bool shell_strtobool(const char *str, int base, int *err); + +#ifdef __cplusplus +} +#endif + +#endif /* SHELL_STRING_CONV_H__ */ diff --git a/subsys/shell/shell_utils.c b/subsys/shell/shell_utils.c index 57683704566..1edd69c26ca 100644 --- a/subsys/shell/shell_utils.c +++ b/subsys/shell/shell_utils.c @@ -5,6 +5,7 @@ */ #include #include +#include #include "shell_utils.h" #include "shell_wildcard.h" @@ -471,3 +472,57 @@ const struct device *shell_device_lookup(size_t idx, return NULL; } + +long shell_strtol(const char *str, int base, int *err) +{ + long val; + char *endptr = NULL; + + errno = 0; + val = strtol(str, &endptr, base); + if (errno == ERANGE) { + *err = -ERANGE; + return 0; + } else if (errno || endptr == str || *endptr) { + *err = -EINVAL; + return 0; + } + + return val; +} + +unsigned long shell_strtoul(const char *str, int base, int *err) +{ + unsigned long val; + char *endptr = NULL; + + if (*str == '-') { + *err = -EINVAL; + return 0; + } + + errno = 0; + val = strtoul(str, &endptr, base); + if (errno == ERANGE) { + *err = -ERANGE; + return 0; + } else if (errno || endptr == str || *endptr) { + *err = -EINVAL; + return 0; + } + + return val; +} + +bool shell_strtobool(const char *str, int base, int *err) +{ + if (!strcmp(str, "on") || !strcmp(str, "enable") || !strcmp(str, "true")) { + return true; + } + + if (!strcmp(str, "off") || !strcmp(str, "disable") || !strcmp(str, "false")) { + return false; + } + + return shell_strtoul(str, base, err); +}