1#include "../include/str_to_num.h"
2#include "../include/str.h"
15static inline StoError validate_and_parse_signed(
const char* str,
int base, intmax_t* result) {
16 if (str == NULL || result == NULL) {
22 *result = strtoimax(str, &endptr, base);
25 if (errno == ERANGE) {
30 if (endptr == str || *endptr !=
'\0') {
38static inline StoError validate_and_parse_unsigned(
const char* str,
int base, uintmax_t* result) {
39 if (str == NULL || result == NULL) {
45 while (*p ==
' ' || *p ==
'\t' || *p ==
'\n' || *p ==
'\r' || *p ==
'\v' || *p ==
'\f') {
58 *result = strtoumax(str, &endptr, base);
61 if (errno == ERANGE) {
66 if (endptr == str || *endptr !=
'\0') {
78#define IMPLEMENT_SIGNED_CONVERSION(func_name, type_name, type_max, type_min) \
79 StoError func_name(const char* str, type_name* result) { \
80 if (result == NULL) { \
85 StoError err = validate_and_parse_signed(str, 10, &temp); \
86 if (err != STO_SUCCESS) { \
91 if (temp > (intmax_t)(type_max) || temp < (intmax_t)(type_min)) { \
92 return STO_OVERFLOW; \
95 *result = (type_name)temp; \
103#define IMPLEMENT_UNSIGNED_CONVERSION(func_name, type_name, type_max) \
104 StoError func_name(const char* str, type_name* result) { \
105 if (result == NULL) { \
106 return STO_INVALID; \
110 StoError err = validate_and_parse_unsigned(str, 10, &temp); \
111 if (err != STO_SUCCESS) { \
116 if (temp > (uintmax_t)(type_max)) { \
117 return STO_OVERFLOW; \
120 *result = (type_name)temp; \
121 return STO_SUCCESS; \
125#define IMPLEMENT_SIGNED_BASE_CONVERSION(func_name, type_name, type_max, type_min) \
126 StoError func_name(const char* str, int base, type_name* result) { \
127 if (result == NULL) { \
128 return STO_INVALID; \
132 StoError err = validate_and_parse_signed(str, base, &temp); \
133 if (err != STO_SUCCESS) { \
138 if (temp > (intmax_t)(type_max) || temp < (intmax_t)(type_min)) { \
139 return STO_OVERFLOW; \
142 *result = (type_name)temp; \
143 return STO_SUCCESS; \
147#define IMPLEMENT_UNSIGNED_BASE_CONVERSION(func_name, type_name, type_max) \
148 StoError func_name(const char* str, int base, type_name* result) { \
149 if (result == NULL) { \
150 return STO_INVALID; \
154 StoError err = validate_and_parse_unsigned(str, base, &temp); \
155 if (err != STO_SUCCESS) { \
160 if (temp > (uintmax_t)(type_max)) { \
161 return STO_OVERFLOW; \
164 *result = (type_name)temp; \
165 return STO_SUCCESS; \
171IMPLEMENT_SIGNED_CONVERSION(
str_to_i8, int8_t, INT8_MAX, INT8_MIN)
172IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u8, uint8_t, UINT8_MAX)
174IMPLEMENT_SIGNED_CONVERSION(
str_to_i16, int16_t, INT16_MAX, INT16_MIN)
175IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u16, uint16_t, UINT16_MAX)
177IMPLEMENT_SIGNED_CONVERSION(
str_to_i32, int32_t, INT32_MAX, INT32_MIN)
178IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u32, uint32_t, UINT32_MAX)
180IMPLEMENT_SIGNED_CONVERSION(
str_to_i64, int64_t, INT64_MAX, INT64_MIN)
181IMPLEMENT_UNSIGNED_CONVERSION(
str_to_u64, uint64_t, UINT64_MAX)
183IMPLEMENT_SIGNED_CONVERSION(
str_to_int,
int, INT_MAX, INT_MIN)
184IMPLEMENT_UNSIGNED_CONVERSION(
str_to_uint,
unsigned int, UINT_MAX)
186IMPLEMENT_SIGNED_CONVERSION(
str_to_long,
long, LONG_MAX, LONG_MIN)
187IMPLEMENT_UNSIGNED_CONVERSION(
str_to_ulong,
unsigned long, ULONG_MAX)
190IMPLEMENT_SIGNED_BASE_CONVERSION(
str_to_int_base,
int, INT_MAX, INT_MIN)
195StoError str_to_uintptr(const
char* str, uintptr_t* result) {
196 if (result == NULL) {
201 StoError err = validate_and_parse_unsigned(str, 10, &temp);
202 if (err != STO_SUCCESS) {
208 *result = (uintptr_t)temp;
213 if (str == NULL || result == NULL) {
218 *result = strtof(str, &endptr);
219 if (endptr == str || *endptr !=
'\0')
return STO_INVALID;
220 if (errno == ERANGE) {
221 if (isinf(*result) || fabsf(*result) > FLT_MAX)
return STO_OVERFLOW;
222 if (*result == 0.0f || fabsf(*result) < FLT_MIN)
return STO_UNDERFLOW;
229 if (str == NULL || result == NULL) {
234 *result = strtod(str, &endptr);
235 if (endptr == str || *endptr !=
'\0')
return STO_INVALID;
236 if (errno == ERANGE) {
237 if (isinf(*result) || fabs(*result) > DBL_MAX)
return STO_OVERFLOW;
238 if (*result == 0.0 || fabs(*result) < DBL_MIN)
return STO_UNDERFLOW;
249static const bool_mapping_t BOOL_MAPPINGS[] = {
250 {
"true",
true}, {
"false",
false}, {
"yes",
true}, {
"no",
false},
251 {
"on",
true}, {
"off",
false}, {
"1",
true}, {
"0",
false},
254static const size_t BOOL_MAPPINGS_COUNT =
sizeof(BOOL_MAPPINGS) /
sizeof(BOOL_MAPPINGS[0]);
257 if (str == NULL || result == NULL) {
262 for (
size_t i = 0; i < BOOL_MAPPINGS_COUNT; i++) {
263 if (strcasecmp(str, BOOL_MAPPINGS[i].str) == 0) {
264 *result = BOOL_MAPPINGS[i].value;
275 return "Conversion successful";
277 return "Invalid input string or null pointer";
279 return "Numeric overflow";
281 return "Numeric overflow";
283 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.