blob: 767deb2adc84e75e057d14cdc5bfa54452a38439 [file]
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: LGPL-3.0-only WITH LGPL-3.0-linking-exception
#ifndef LIB_SRC_A2I_STRTOI_STRTOU_STRTOU_H_
#define LIB_SRC_A2I_STRTOI_STRTOU_STRTOU_H_
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/param.h>
#include "lib/src/a2i/attr.h"
#include "lib/src/a2i/qual.h"
#if defined(__clang__)
# pragma clang assume_nonnull begin
#endif
A2I_ATTR_ACCESS(read_only, 1)
A2I_ATTR_ACCESS(write_only, 2)
A2I_ATTR_ACCESS(write_only, 6)
A2I_ATTR_NONNULL(1)
A2I_ATTR_STRING(1)
A2I_ATTR_LEAF
A2I_ATTR_NOTHROW
A2I_ATTR_VISIBILITY("internal")
inline uintmax_t a2i_strtou(char *restrict s,
char **a2i_nullable restrict endp, int base,
uintmax_t min, uintmax_t max, int *a2i_nullable restrict status);
inline uintmax_t
a2i_strtou(char *restrict s,
char **a2i_nullable restrict endp, int base,
uintmax_t min, uintmax_t max, int *a2i_nullable restrict status)
{
int errno_saved, st;
char *e;
uintmax_t n;
errno_saved = errno;
errno = 0;
if (endp == NULL)
endp = &e;
if (base < 0 || base == 1 || base > 36) {
n = 0;
st = EINVAL;
goto out;
}
n = strtoumax(s, endp, base);
if (errno != 0 && errno != EINVAL)
st = errno;
else if (*endp == s)
st = ECANCELED;
else if (n < min || n > max)
st = ERANGE;
else if (**endp != '\0')
st = ENOTSUP;
else
st = 0;
out:
if (status != NULL)
*status = st;
errno = errno_saved;
return MAX(min, MIN(max, n));
}
#if defined(__clang__)
# pragma clang assume_nonnull end
#endif
#endif // include guard