summaryrefslogtreecommitdiff
path: root/pkstn.h
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-12-10 15:45:38 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-12-10 16:22:30 -0500
commit97a9b70bc2f779b9267d02c255628fd7895a53b3 (patch)
tree2185cb60964d38345b1de220027476ff6af70d20 /pkstn.h
parenta3cc7699c56ae324733bd7c4c4808090b28a2377 (diff)
pkstn: first-pass
Diffstat (limited to 'pkstn.h')
-rw-r--r--pkstn.h246
1 files changed, 246 insertions, 0 deletions
diff --git a/pkstn.h b/pkstn.h
new file mode 100644
index 0000000..fd9233d
--- /dev/null
+++ b/pkstn.h
@@ -0,0 +1,246 @@
+#ifndef PK_PK_STN_H
+#define PK_PK_STN_H
+
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+enum PK_STN_ERR {
+ PK_STN_ERR_SUCCESS,
+ PK_STN_ERR_OVERFLOW,
+ PK_STN_ERR_UNDERFLOW,
+ PK_STN_ERR_INCONVERTIBLE
+};
+
+enum PK_STN_ERR pk_stn_int64_t(int64_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_uint64_t(uint64_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_int32_t(int32_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_uint32_t(uint32_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_int16_t(int16_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_uint16_t(uint16_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_int8_t(int8_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_uint8_t(uint8_t *i, char const *s, int base);
+enum PK_STN_ERR pk_stn_float(float *f, char const *s);
+enum PK_STN_ERR pk_stn_double(double *d, char const *s);
+enum PK_STN_ERR pk_stn_float_e(float *f, char const *s, char **pEnd);
+enum PK_STN_ERR pk_stn_double_e(double *d, char const *s, char **pEnd);
+
+#endif /* PK_PK_STN_H */
+
+#ifdef PK_IMPL_STN
+
+enum PK_STN_ERR
+pk_stn_int64_t(int64_t *i, char const *s, int base)
+{
+ char *end;
+ long long l;
+ errno = 0;
+ l = strtoll(s, &end, base);
+ if (errno == ERANGE && l == LLONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LLONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_uint64_t(uint64_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long long l;
+ errno = 0;
+ l = strtoull(s, &end, base);
+ if (errno == ERANGE && l == LLONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LLONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_int32_t(int32_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_uint32_t(uint32_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_int16_t(int16_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_uint16_t(uint16_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_int8_t(int8_t *i, char const *s, int base)
+{
+ char *end;
+ long l;
+ errno = 0;
+ l = strtol(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_uint8_t(uint8_t *i, char const *s, int base)
+{
+ char *end;
+ unsigned long l;
+ errno = 0;
+ l = strtoul(s, &end, base);
+ if (errno == ERANGE && l == LONG_MAX) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == LONG_MIN) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || *end != '\0') {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *i = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_float(float *f, char const *s)
+{
+ char *end;
+ return pk_stn_float_e(f, s, &end);
+}
+
+enum PK_STN_ERR
+pk_stn_double(double *d, char const *s)
+{
+ char *end;
+ return pk_stn_double_e(d, s, &end);
+}
+
+enum PK_STN_ERR
+pk_stn_float_e(float *f, char const *s, char **pEnd)
+{
+ float l;
+ errno = 0;
+ l = strtof(s, pEnd);
+ if (errno == ERANGE && l == HUGE_VALF) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == -HUGE_VALF) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || &s == (const char **)pEnd) {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *f = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+enum PK_STN_ERR
+pk_stn_double_e(double *d, char const *s, char **pEnd)
+{
+ double l;
+ errno = 0;
+ l = strtod(s, pEnd);
+ if (errno == ERANGE && l == HUGE_VAL) {
+ return PK_STN_ERR_OVERFLOW;
+ }
+ if (errno == ERANGE && l == -HUGE_VAL) {
+ return PK_STN_ERR_UNDERFLOW;
+ }
+ if (*s == '\0' || &s == (const char **)pEnd) {
+ return PK_STN_ERR_INCONVERTIBLE;
+ }
+ *d = l;
+ return PK_STN_ERR_SUCCESS;
+}
+
+#endif /* PK_IMPL_STN */