Skip to content

Commit 7963c81

Browse files
Andrewpinicarlescufi
authored andcommitted
Shell: String to numeric conversion utils
Adds string to numeric conversion utility for shell. Signed-off-by: Anders Storrø <[email protected]>
1 parent e8a369e commit 7963c81

File tree

3 files changed

+127
-0
lines changed

3 files changed

+127
-0
lines changed

include/shell/shell.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <shell/shell_history.h>
1313
#include <shell/shell_fprintf.h>
1414
#include <shell/shell_log_backend.h>
15+
#include <shell/shell_string_conv.h>
1516
#include <logging/log_instance.h>
1617
#include <logging/log.h>
1718
#include <sys/util.h>

include/shell/shell_string_conv.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2022 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef SHELL_STRING_CONV_H__
8+
#define SHELL_STRING_CONV_H__
9+
10+
#include <stdint.h>
11+
12+
#ifdef __cplusplus
13+
extern "C" {
14+
#endif
15+
16+
/** @brief String to long conversion with error check.
17+
*
18+
* @warning On success the passed err reference will not be altered
19+
* to avoid err check bloating. Passed err reference should be initialized
20+
* to zero.
21+
*
22+
* @param str Input string.
23+
* @param base Conversion base.
24+
* @param err Error code pointer:
25+
* -EINVAL on invalid string input.
26+
* -ERANGE if numeric string input is to large to convert.
27+
* Unchanged on success.
28+
*
29+
* @return Converted long value.
30+
*/
31+
long shell_strtol(const char *str, int base, int *err);
32+
33+
/** @brief String to unsigned long conversion with error check.
34+
*
35+
* @warning On success the passed err reference will not be altered
36+
* to avoid err check bloating. Passed err reference should be initialized
37+
* to zero.
38+
*
39+
* @param str Input string.
40+
* @param base Conversion base.
41+
* @param err Error code pointer:
42+
* Set to -EINVAL on invalid string input.
43+
* Set to -ERANGE if numeric string input is to large to convert.
44+
* Unchanged on success.
45+
*
46+
* @return Converted unsigned long value.
47+
*/
48+
unsigned long shell_strtoul(const char *str, int base, int *err);
49+
50+
/** @brief String to boolean conversion with error check.
51+
*
52+
* @warning On success the passed err reference will not be altered
53+
* to avoid err check bloating. Passed err reference should be initialized
54+
* to zero.
55+
*
56+
* @param str Input string.
57+
* @param base Conversion base.
58+
* @param err Error code pointer:
59+
* Set to -EINVAL on invalid string input.
60+
* Set to -ERANGE if numeric string input is to large to convert.
61+
* Unchanged on success.
62+
*
63+
* @return Converted boolean value.
64+
*/
65+
bool shell_strtobool(const char *str, int base, int *err);
66+
67+
#ifdef __cplusplus
68+
}
69+
#endif
70+
71+
#endif /* SHELL_STRING_CONV_H__ */

subsys/shell/shell_utils.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
#include <ctype.h>
77
#include <device.h>
8+
#include <stdlib.h>
89
#include "shell_utils.h"
910
#include "shell_wildcard.h"
1011

@@ -471,3 +472,57 @@ const struct device *shell_device_lookup(size_t idx,
471472

472473
return NULL;
473474
}
475+
476+
long shell_strtol(const char *str, int base, int *err)
477+
{
478+
long val;
479+
char *endptr = NULL;
480+
481+
errno = 0;
482+
val = strtol(str, &endptr, base);
483+
if (errno == ERANGE) {
484+
*err = -ERANGE;
485+
return 0;
486+
} else if (errno || endptr == str || *endptr) {
487+
*err = -EINVAL;
488+
return 0;
489+
}
490+
491+
return val;
492+
}
493+
494+
unsigned long shell_strtoul(const char *str, int base, int *err)
495+
{
496+
unsigned long val;
497+
char *endptr = NULL;
498+
499+
if (*str == '-') {
500+
*err = -EINVAL;
501+
return 0;
502+
}
503+
504+
errno = 0;
505+
val = strtoul(str, &endptr, base);
506+
if (errno == ERANGE) {
507+
*err = -ERANGE;
508+
return 0;
509+
} else if (errno || endptr == str || *endptr) {
510+
*err = -EINVAL;
511+
return 0;
512+
}
513+
514+
return val;
515+
}
516+
517+
bool shell_strtobool(const char *str, int base, int *err)
518+
{
519+
if (!strcmp(str, "on") || !strcmp(str, "enable") || !strcmp(str, "true")) {
520+
return true;
521+
}
522+
523+
if (!strcmp(str, "off") || !strcmp(str, "disable") || !strcmp(str, "false")) {
524+
return false;
525+
}
526+
527+
return shell_strtoul(str, base, err);
528+
}

0 commit comments

Comments
 (0)