diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-26 16:18:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-26 16:18:36 +0000 |
commit | 6c3ea4f47ea280811a7fe53a22f7832e4533c9ec (patch) | |
tree | 3d7ed5da23b5dbf6f9e450dfb61642832249c31e /lib/atoi | |
parent | Adding upstream version 1:4.13+dfsg1. (diff) | |
download | shadow-upstream/1%4.15.2.tar.xz shadow-upstream/1%4.15.2.zip |
Adding upstream version 1:4.15.2.upstream/1%4.15.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/atoi')
-rw-r--r-- | lib/atoi/a2i.c | 46 | ||||
-rw-r--r-- | lib/atoi/a2i.h | 386 | ||||
-rw-r--r-- | lib/atoi/str2i.c | 18 | ||||
-rw-r--r-- | lib/atoi/str2i.h | 108 | ||||
-rw-r--r-- | lib/atoi/strtoi.c | 15 | ||||
-rw-r--r-- | lib/atoi/strtoi.h | 96 | ||||
-rw-r--r-- | lib/atoi/strtou_noneg.c | 13 | ||||
-rw-r--r-- | lib/atoi/strtou_noneg.h | 39 |
8 files changed, 721 insertions, 0 deletions
diff --git a/lib/atoi/a2i.c b/lib/atoi/a2i.c new file mode 100644 index 0000000..a2cf872 --- /dev/null +++ b/lib/atoi/a2i.c @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#include <config.h> + +#include "atoi/a2i.h" + + +extern inline int a2sh_c(short *restrict n, const char *s, + const char **restrict endp, int base, short min, short max); +extern inline int a2si_c(int *restrict n, const char *s, + const char **restrict endp, int base, int min, int max); +extern inline int a2sl_c(long *restrict n, const char *s, + const char **restrict endp, int base, long min, long max); +extern inline int a2sll_c(long long *restrict n, const char *s, + const char **restrict endp, int base, long long min, long long max); +extern inline int a2uh_c(unsigned short *restrict n, const char *s, + const char **restrict endp, int base, unsigned short min, + unsigned short max); +extern inline int a2ui_c(unsigned int *restrict n, const char *s, + const char **restrict endp, int base, unsigned int min, unsigned int max); +extern inline int a2ul_c(unsigned long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long min, unsigned long max); +extern inline int a2ull_c(unsigned long long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long long min, + unsigned long long max); + + +extern inline int a2sh_nc(short *restrict n, char *s, + char **restrict endp, int base, short min, short max); +extern inline int a2si_nc(int *restrict n, char *s, + char **restrict endp, int base, int min, int max); +extern inline int a2sl_nc(long *restrict n, char *s, + char **restrict endp, int base, long min, long max); +extern inline int a2sll_nc(long long *restrict n, char *s, + char **restrict endp, int base, long long min, long long max); +extern inline int a2uh_nc(unsigned short *restrict n, char *s, + char **restrict endp, int base, unsigned short min, unsigned short max); +extern inline int a2ui_nc(unsigned int *restrict n, char *s, + char **restrict endp, int base, unsigned int min, unsigned int max); +extern inline int a2ul_nc(unsigned long *restrict n, char *s, + char **restrict endp, int base, unsigned long min, unsigned long max); +extern inline int a2ull_nc(unsigned long long *restrict n, char *s, + char **restrict endp, int base, unsigned long long min, + unsigned long long max); diff --git a/lib/atoi/a2i.h b/lib/atoi/a2i.h new file mode 100644 index 0000000..64f775a --- /dev/null +++ b/lib/atoi/a2i.h @@ -0,0 +1,386 @@ +// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_H_ +#define SHADOW_INCLUDE_LIB_ATOI_A2I_H_ + + +#include <config.h> + +#include <errno.h> + +#include "atoi/strtoi.h" +#include "atoi/strtou_noneg.h" +#include "attr.h" + + +/* + * See the manual of these macros in liba2i's documentation: + * <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf> + */ + + +#define a2i(TYPE, n, s, ...) \ +( \ + _Generic((void (*)(TYPE, typeof(s))) 0, \ + void (*)(short, const char *): a2sh_c, \ + void (*)(short, const void *): a2sh_c, \ + void (*)(short, char *): a2sh_nc, \ + void (*)(short, void *): a2sh_nc, \ + void (*)(int, const char *): a2si_c, \ + void (*)(int, const void *): a2si_c, \ + void (*)(int, char *): a2si_nc, \ + void (*)(int, void *): a2si_nc, \ + void (*)(long, const char *): a2sl_c, \ + void (*)(long, const void *): a2sl_c, \ + void (*)(long, char *): a2sl_nc, \ + void (*)(long, void *): a2sl_nc, \ + void (*)(long long, const char *): a2sll_c, \ + void (*)(long long, const void *): a2sll_c, \ + void (*)(long long, char *): a2sll_nc, \ + void (*)(long long, void *): a2sll_nc, \ + void (*)(unsigned short, const char *): a2uh_c, \ + void (*)(unsigned short, const void *): a2uh_c, \ + void (*)(unsigned short, char *): a2uh_nc, \ + void (*)(unsigned short, void *): a2uh_nc, \ + void (*)(unsigned int, const char *): a2ui_c, \ + void (*)(unsigned int, const void *): a2ui_c, \ + void (*)(unsigned int, char *): a2ui_nc, \ + void (*)(unsigned int, void *): a2ui_nc, \ + void (*)(unsigned long, const char *): a2ul_c, \ + void (*)(unsigned long, const void *): a2ul_c, \ + void (*)(unsigned long, char *): a2ul_nc, \ + void (*)(unsigned long, void *): a2ul_nc, \ + void (*)(unsigned long long, const char *): a2ull_c, \ + void (*)(unsigned long long, const void *): a2ull_c, \ + void (*)(unsigned long long, char *): a2ull_nc, \ + void (*)(unsigned long long, void *): a2ull_nc \ + )(n, s, __VA_ARGS__) \ +) + + +#define a2sh(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2sh_c, \ + const void *: a2sh_c, \ + char *: a2sh_nc, \ + void *: a2sh_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2si(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2si_c, \ + const void *: a2si_c, \ + char *: a2si_nc, \ + void *: a2si_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2sl(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2sl_c, \ + const void *: a2sl_c, \ + char *: a2sl_nc, \ + void *: a2sl_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2sll(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2sll_c, \ + const void *: a2sll_c, \ + char *: a2sll_nc, \ + void *: a2sll_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2uh(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2uh_c, \ + const void *: a2uh_c, \ + char *: a2uh_nc, \ + void *: a2uh_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2ui(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2ui_c, \ + const void *: a2ui_c, \ + char *: a2ui_nc, \ + void *: a2ui_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2ul(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2ul_c, \ + const void *: a2ul_c, \ + char *: a2ul_nc, \ + void *: a2ul_nc \ + )(n, s, __VA_ARGS__) \ +) + +#define a2ull(n, s, ...) \ +( \ + _Generic(s, \ + const char *: a2ull_c, \ + const void *: a2ull_c, \ + char *: a2ull_nc, \ + void *: a2ull_nc \ + )(n, s, __VA_ARGS__) \ +) + + +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sh_c(short *restrict n, const char *s, + const char **restrict endp, int base, short min, short max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2si_c(int *restrict n, const char *s, + const char **restrict endp, int base, int min, int max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sl_c(long *restrict n, const char *s, + const char **restrict endp, int base, long min, long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sll_c(long long *restrict n, const char *s, + const char **restrict endp, int base, long long min, long long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2uh_c(unsigned short *restrict n, const char *s, + const char **restrict endp, int base, unsigned short min, + unsigned short max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ui_c(unsigned int *restrict n, const char *s, + const char **restrict endp, int base, unsigned int min, unsigned int max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ul_c(unsigned long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long min, unsigned long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ull_c(unsigned long long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long long min, + unsigned long long max); + +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sh_nc(short *restrict n, char *s, + char **restrict endp, int base, short min, short max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2si_nc(int *restrict n, char *s, + char **restrict endp, int base, int min, int max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sl_nc(long *restrict n, char *s, + char **restrict endp, int base, long min, long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2sll_nc(long long *restrict n, char *s, + char **restrict endp, int base, long long min, long long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2uh_nc(unsigned short *restrict n, char *s, + char **restrict endp, int base, unsigned short min, unsigned short max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ui_nc(unsigned int *restrict n, char *s, + char **restrict endp, int base, unsigned int min, unsigned int max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ul_nc(unsigned long *restrict n, char *s, + char **restrict endp, int base, unsigned long min, unsigned long max); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3) +inline int a2ull_nc(unsigned long long *restrict n, char *s, + char **restrict endp, int base, unsigned long long min, + unsigned long long max); + + +inline int +a2sh_c(short *restrict n, const char *s, + const char **restrict endp, int base, short min, short max) +{ + return a2sh(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2si_c(int *restrict n, const char *s, + const char **restrict endp, int base, int min, int max) +{ + return a2si(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2sl_c(long *restrict n, const char *s, + const char **restrict endp, int base, long min, long max) +{ + return a2sl(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2sll_c(long long *restrict n, const char *s, + const char **restrict endp, int base, long long min, long long max) +{ + return a2sll(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2uh_c(unsigned short *restrict n, const char *s, + const char **restrict endp, int base, unsigned short min, + unsigned short max) +{ + return a2uh(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2ui_c(unsigned int *restrict n, const char *s, + const char **restrict endp, int base, unsigned int min, unsigned int max) +{ + return a2ui(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2ul_c(unsigned long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long min, unsigned long max) +{ + return a2ul(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2ull_c(unsigned long long *restrict n, const char *s, + const char **restrict endp, int base, unsigned long long min, + unsigned long long max) +{ + return a2ull(n, (char *) s, (char **) endp, base, min, max); +} + + +inline int +a2sh_nc(short *restrict n, char *s, + char **restrict endp, int base, short min, short max) +{ + int status; + + *n = strtoi_(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2si_nc(int *restrict n, char *s, + char **restrict endp, int base, int min, int max) +{ + int status; + + *n = strtoi_(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2sl_nc(long *restrict n, char *s, + char **restrict endp, int base, long min, long max) +{ + int status; + + *n = strtoi_(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2sll_nc(long long *restrict n, char *s, + char **restrict endp, int base, long long min, long long max) +{ + int status; + + *n = strtoi_(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2uh_nc(unsigned short *restrict n, char *s, + char **restrict endp, int base, unsigned short min, + unsigned short max) +{ + int status; + + *n = strtou_noneg(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2ui_nc(unsigned int *restrict n, char *s, + char **restrict endp, int base, unsigned int min, unsigned int max) +{ + int status; + + *n = strtou_noneg(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2ul_nc(unsigned long *restrict n, char *s, + char **restrict endp, int base, unsigned long min, unsigned long max) +{ + int status; + + *n = strtou_noneg(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +inline int +a2ull_nc(unsigned long long *restrict n, char *s, + char **restrict endp, int base, unsigned long long min, + unsigned long long max) +{ + int status; + + *n = strtou_noneg(s, endp, base, min, max, &status); + if (status != 0) { + errno = status; + return -1; + } + return 0; +} + + +#endif // include guard diff --git a/lib/atoi/str2i.c b/lib/atoi/str2i.c new file mode 100644 index 0000000..25ce360 --- /dev/null +++ b/lib/atoi/str2i.c @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2007-2009, Nicolas François +// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#include <config.h> + +#include "atoi/str2i.h" + + +extern inline int str2sh(short *restrict n, const char *restrict s); +extern inline int str2si(int *restrict n, const char *restrict s); +extern inline int str2sl(long *restrict n, const char *restrict s); +extern inline int str2sll(long long *restrict n, const char *restrict s); +extern inline int str2uh(unsigned short *restrict n, const char *restrict s); +extern inline int str2ui(unsigned int *restrict n, const char *restrict s); +extern inline int str2ul(unsigned long *restrict n, const char *restrict s); +extern inline int str2ull(unsigned long long *restrict n, const char *restrict s); diff --git a/lib/atoi/str2i.h b/lib/atoi/str2i.h new file mode 100644 index 0000000..b3ded03 --- /dev/null +++ b/lib/atoi/str2i.h @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: 2007-2009, Nicolas François +// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_ +#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_ + + +#include <config.h> + +#include <limits.h> +#include <stddef.h> + +#include "atoi/a2i.h" +#include "attr.h" + + +#define str2i(TYPE, ...) \ +( \ + _Generic((TYPE) 0, \ + short: str2sh, \ + int: str2si, \ + long: str2sl, \ + long long: str2sll, \ + unsigned short: str2uh, \ + unsigned int: str2ui, \ + unsigned long: str2ul, \ + unsigned long long: str2ull \ + )(__VA_ARGS__) \ +) + + +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2sh(short *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2si(int *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2sl(long *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2sll(long long *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2uh(unsigned short *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2ui(unsigned int *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2ul(unsigned long *restrict n, const char *restrict s); +ATTR_STRING(2) ATTR_ACCESS(write_only, 1) +inline int str2ull(unsigned long long *restrict n, const char *restrict s); + + +inline int +str2sh(short *restrict n, const char *restrict s) +{ + return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX); +} + + +inline int +str2si(int *restrict n, const char *restrict s) +{ + return a2si(n, s, NULL, 0, INT_MIN, INT_MAX); +} + + +inline int +str2sl(long *restrict n, const char *restrict s) +{ + return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX); +} + + +inline int +str2sll(long long *restrict n, const char *restrict s) +{ + return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX); +} + + +inline int +str2uh(unsigned short *restrict n, const char *restrict s) +{ + return a2uh(n, s, NULL, 0, 0, USHRT_MAX); +} + + +inline int +str2ui(unsigned int *restrict n, const char *restrict s) +{ + return a2ui(n, s, NULL, 0, 0, UINT_MAX); +} + + +inline int +str2ul(unsigned long *restrict n, const char *restrict s) +{ + return a2ul(n, s, NULL, 0, 0, ULONG_MAX); +} + + +inline int +str2ull(unsigned long long *restrict n, const char *restrict s) +{ + return a2ull(n, s, NULL, 0, 0, ULLONG_MAX); +} + + +#endif // include guard diff --git a/lib/atoi/strtoi.c b/lib/atoi/strtoi.c new file mode 100644 index 0000000..197707b --- /dev/null +++ b/lib/atoi/strtoi.c @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#include <config.h> + +#include "atoi/strtoi.h" + +#include <stdint.h> + + +extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base, + intmax_t min, intmax_t max, int *restrict status); +extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base, + uintmax_t min, uintmax_t max, int *restrict status); diff --git a/lib/atoi/strtoi.h b/lib/atoi/strtoi.h new file mode 100644 index 0000000..1f061fc --- /dev/null +++ b/lib/atoi/strtoi.h @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_ +#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_ + + +#include <config.h> + +#include <errno.h> +#include <inttypes.h> +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <sys/param.h> + +#include "attr.h" + + +#define strtoNmax(TYPE, ...) \ +( \ + _Generic((TYPE) 0, \ + intmax_t: strtoimax, \ + uintmax_t: strtoumax \ + )(__VA_ARGS__) \ +) + + +#define strtoN(s, endp, base, min, max, status, TYPE) \ +({ \ + const char *s_ = s; \ + char **endp_ = endp; \ + int base_ = base; \ + TYPE min_ = min; \ + TYPE max_ = max; \ + int *status_ = status; \ + \ + int e_, st_; \ + char *end_; \ + TYPE n_; \ + \ + if (endp_ == NULL) \ + endp_ = &end_; \ + if (status_ == NULL) \ + status_ = &st_; \ + \ + if (base_ != 0 && (base_ < 0 || base_ > 36)) { \ + *status_ = EINVAL; \ + n_ = 0; \ + \ + } else { \ + e_ = errno; \ + errno = 0; \ + n_ = strtoNmax(TYPE, s_, endp_, base_); \ + \ + if (*endp_ == s_) \ + *status_ = ECANCELED; \ + else if (errno == ERANGE || n_ < min_ || n_ > max_) \ + *status_ = ERANGE; \ + else if (**endp_ != '\0') \ + *status_ = ENOTSUP; \ + else \ + *status_ = 0; \ + \ + errno = e_; \ + } \ + MAX(min_, MIN(max_, n_)); \ +}) + + +ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6) +inline intmax_t strtoi_(const char *s, char **restrict endp, int base, + intmax_t min, intmax_t max, int *restrict status); +ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6) +inline uintmax_t strtou_(const char *s, char **restrict endp, int base, + uintmax_t min, uintmax_t max, int *restrict status); + + +inline intmax_t +strtoi_(const char *s, char **restrict endp, int base, + intmax_t min, intmax_t max, int *restrict status) +{ + return strtoN(s, endp, base, min, max, status, intmax_t); +} + + +inline uintmax_t +strtou_(const char *s, char **restrict endp, int base, + uintmax_t min, uintmax_t max, int *restrict status) +{ + return strtoN(s, endp, base, min, max, status, uintmax_t); +} + + +#endif // include guard diff --git a/lib/atoi/strtou_noneg.c b/lib/atoi/strtou_noneg.c new file mode 100644 index 0000000..71cacbd --- /dev/null +++ b/lib/atoi/strtou_noneg.c @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#include <config.h> + +#include "atoi/strtou_noneg.h" + +#include <stdint.h> + + +extern inline uintmax_t strtou_noneg(const char *s, char **restrict endp, + int base, uintmax_t min, uintmax_t max, int *restrict status); diff --git a/lib/atoi/strtou_noneg.h b/lib/atoi/strtou_noneg.h new file mode 100644 index 0000000..6d77adf --- /dev/null +++ b/lib/atoi/strtou_noneg.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org> +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_ +#define SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_ + + +#include <config.h> + +#include <errno.h> +#include <stddef.h> +#include <stdint.h> + +#include "atoi/strtoi.h" +#include "attr.h" + + +ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6) +inline uintmax_t strtou_noneg(const char *s, char **restrict endp, + int base, uintmax_t min, uintmax_t max, int *restrict status); + + +inline uintmax_t +strtou_noneg(const char *s, char **restrict endp, int base, + uintmax_t min, uintmax_t max, int *restrict status) +{ + int st; + + if (status == NULL) + status = &st; + if (strtoi_(s, endp, base, 0, 1, status) == 0 && *status == ERANGE) + return min; + + return strtou_(s, endp, base, min, max, status); +} + + +#endif // include guard |