1#include "../include/str_to_num.h"
3#include "../include/str_utils.h"
16static inline StoError validate_and_parse_signed(
const char* str,
int base, intmax_t* result) {
17 if (str == NULL || result == NULL) {
23 *result = strtoimax(str, &endptr, base);
26 if (errno == ERANGE) {
31 if (endptr == str || *endptr !=
'\0') {
39static inline StoError validate_and_parse_unsigned(
const char* str,
int base, uintmax_t* result) {
40 if (str == NULL || result == NULL) {
46 while (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r' || *p ==
'\v' || *p ==
'\f') {
59 *result = strtoumax(str, &endptr, base);
62 if (errno == ERANGE) {
67 if (endptr == str || *endptr !=
'\0') {
79#define IMPLEMENT_SIGNED_CONVERSION(func_name, type_name, type_max, type_min) \
80 StoError func_name(const char* str, type_name* result) { \
81 if (result == NULL) { \
86 StoError err = validate_and_parse_signed(str, 10, &temp); \
87 if (err != STO_SUCCESS) { \
92 if (temp > (intmax_t)(type_max) || temp < (intmax_t)(type_min)) { \
93 return STO_OVERFLOW; \
96 *result = (type_name)temp; \
104#define IMPLEMENT_UNSIGNED_CONVERSION(func_name, type_name, type_max) \
105 StoError func_name(const char* str, type_name* result) { \
106 if (result == NULL) { \
107 return STO_INVALID; \
111 StoError err = validate_and_parse_unsigned(str, 10, &temp); \
112 if (err != STO_SUCCESS) { \
117 if (temp > (uintmax_t)(type_max)) { \
118 return STO_OVERFLOW; \
121 *result = (type_name)temp; \
122 return STO_SUCCESS; \
126#define IMPLEMENT_SIGNED_BASE_CONVERSION(func_name, type_name, type_max, type_min) \
127 StoError func_name(const char* str, int base, type_name* result) { \
128 if (result == NULL) { \
129 return STO_INVALID; \
133 StoError err = validate_and_parse_signed(str, base, &temp); \
134 if (err != STO_SUCCESS) { \
139 if (temp > (intmax_t)(type_max) || temp < (intmax_t)(type_min)) { \
140 return STO_OVERFLOW; \
143 *result = (type_name)temp; \
144 return STO_SUCCESS; \
148#define IMPLEMENT_UNSIGNED_BASE_CONVERSION(func_name, type_name, type_max) \
149 StoError func_name(const char* str, int base, type_name* result) { \
150 if (result == NULL) { \
151 return STO_INVALID; \
155 StoError err = validate_and_parse_unsigned(str, base, &temp); \
156 if (err != STO_SUCCESS) { \
161 if (temp > (uintmax_t)(type_max)) { \
162 return STO_OVERFLOW; \
165 *result = (type_name)temp; \
166 return STO_SUCCESS; \
172IMPLEMENT_SIGNED_CONVERSION(
str_to_i8, int8_t, INT8_MAX, INT8_MIN)
173IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u8, uint8_t, UINT8_MAX)
175IMPLEMENT_SIGNED_CONVERSION(
str_to_i16, int16_t, INT16_MAX, INT16_MIN)
176IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u16, uint16_t, UINT16_MAX)
178IMPLEMENT_SIGNED_CONVERSION(
str_to_i32, int32_t, INT32_MAX, INT32_MIN)
179IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u32, uint32_t, UINT32_MAX)
181IMPLEMENT_SIGNED_CONVERSION(
str_to_i64, int64_t, INT64_MAX, INT64_MIN)
182IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u64, uint64_t, UINT64_MAX)
184IMPLEMENT_SIGNED_CONVERSION(
str_to_int,
int, INT_MAX, INT_MIN)
185IMPLEMENT_UNSIGNED_CONVERSION(
str_to_uint,
unsigned int, UINT_MAX)
187IMPLEMENT_SIGNED_CONVERSION(
str_to_long,
long, LONG_MAX, LONG_MIN)
188IMPLEMENT_UNSIGNED_CONVERSION(
str_to_ulong,
unsigned long, ULONG_MAX)
191IMPLEMENT_SIGNED_BASE_CONVERSION(
str_to_int_base,
int, INT_MAX, INT_MIN)
196StoError str_to_uintptr(const
char* str, uintptr_t* result) {
197 if (result == NULL) {
202 StoError err = validate_and_parse_unsigned(str, 10, &temp);
203 if (err != STO_SUCCESS) {
209 *result = (uintptr_t)temp;
214 if (str == NULL || result == NULL) {
219 *result = strtof(str, &endptr);
220 if (endptr == str || *endptr !=
'\0')
return STO_INVALID;
221 if (errno == ERANGE) {
222 if (isinf(*result) || fabsf(*result) > FLT_MAX)
return STO_OVERFLOW;
223 if (*result == 0.0f || fabsf(*result) < FLT_MIN)
return STO_UNDERFLOW;
230 if (str == NULL || result == NULL) {
235 *result = strtod(str, &endptr);
236 if (endptr == str || *endptr !=
'\0')
return STO_INVALID;
237 if (errno == ERANGE) {
238 if (isinf(*result) || fabs(*result) > DBL_MAX)
return STO_OVERFLOW;
239 if (*result == 0.0 || fabs(*result) < DBL_MIN)
return STO_UNDERFLOW;
250static const bool_mapping_t BOOL_MAPPINGS[] = {
251 {
"true",
true}, {
"false",
false}, {
"yes",
true}, {
"no",
false},
252 {
"on",
true}, {
"off",
false}, {
"1",
true}, {
"0",
false},
255static const size_t BOOL_MAPPINGS_COUNT =
sizeof(BOOL_MAPPINGS) /
sizeof(BOOL_MAPPINGS[0]);
258 if (str == NULL || result == NULL) {
263 for (
size_t i = 0; i < BOOL_MAPPINGS_COUNT; i++) {
264 if (strcasecmp(str, BOOL_MAPPINGS[i].str) == 0) {
265 *result = BOOL_MAPPINGS[i].value;
276 return "Conversion successful";
278 return "Invalid input string or null pointer";
280 return "Numeric overflow";
282 return "Numeric overflow";
284 return "Unknown error code";
StoError str_to_bool(const char *str, bool *result)
Converts a string to a boolean. Valid inputs are "true", "false", "yes", "no", "1",...
StoError str_to_ulong_base(const char *str, int base, unsigned long *result)
Converts a string to an unsigned long with a specified base.
StoError str_to_int_base(const char *str, int base, int *result)
Converts a string to an int with a specified base.
StoError str_to_float(const char *str, float *result)
Converts a string to a float.
StoError str_to_ulong(const char *str, unsigned long *result)
Converts a string to an unsigned long.
StoError str_to_u64(const char *str, uint64_t *result)
Converts a string to a uint64_t.
StoError str_to_i64(const char *str, int64_t *result)
Converts a string to an int64_t.
StoError str_to_u8(const char *str, uint8_t *result)
Converts a string to a uint8_t.
StoError str_to_uint(const char *str, unsigned int *result)
Converts a string to an unsigned int.
StoError str_to_u32(const char *str, uint32_t *result)
Converts a string to a uint32_t.
StoError str_to_double(const char *str, double *result)
Converts a string to a double.
StoError str_to_long_base(const char *str, int base, long *result)
Converts a string to a long with a specified base.
StoError str_to_u16(const char *str, uint16_t *result)
Converts a string to a uint16_t.
const char * sto_error_string(StoError code)
StoError str_to_i32(const char *str, int32_t *result)
Converts a string to an int32_t.
StoError str_to_i16(const char *str, int16_t *result)
Converts a string to an int16_t.
StoError str_to_i8(const char *str, int8_t *result)
Converts a string to an int8_t.
StoError str_to_long(const char *str, long *result)
Converts a string to a long.
StoError str_to_int(const char *str, int *result)
Converts a string to an int.