summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2024-12-14 13:50:09 -0500
committerJonathan Bradley <jcb@pikum.xyz>2024-12-14 13:50:09 -0500
commit33484cccdea2790721fb20f75588d1ed4fb53017 (patch)
treee89020d1c2b9818378a47059e33f82bfb1af5091
parent243866a7ae51a7187832cc5bf7e5e6d8a0fd2202 (diff)
pkstn: more tests + pk_stn<T>
-rw-r--r--pkstn.h88
-rw-r--r--test/pkstn.cpp143
2 files changed, 147 insertions, 84 deletions
diff --git a/pkstn.h b/pkstn.h
index 1d5430f..d3131f7 100644
--- a/pkstn.h
+++ b/pkstn.h
@@ -27,6 +27,46 @@ enum PK_STN_RES pk_stn_double(double *d, char const *s);
enum PK_STN_RES pk_stn_float_e(float *f, char const *s, char **pEnd);
enum PK_STN_RES pk_stn_double_e(double *d, char const *s, char **pEnd);
+#if defined(__cplusplus)
+
+template <typename T>
+enum PK_STN_RES pk_stn(T *n, char const *s, int base = 0)
+{
+ if constexpr(std::is_same<T, int64_t>::value) {
+ return pk_stn_int64_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint64_t>::value) {
+ return pk_stn_uint64_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int32_t>::value) {
+ return pk_stn_int32_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint32_t>::value) {
+ return pk_stn_uint32_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int16_t>::value) {
+ return pk_stn_int16_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint16_t>::value) {
+ return pk_stn_uint16_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, int8_t>::value) {
+ return pk_stn_int8_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, uint8_t>::value) {
+ return pk_stn_uint8_t(n, s, base);
+ }
+ if constexpr(std::is_same<T, float>::value) {
+ return pk_stn_float(n, s);
+ }
+ if constexpr(std::is_same<T, double>::value) {
+ return pk_stn_double(n, s);
+ }
+ return (PK_STN_RES)-1;
+}
+
+#endif /* defined(__cplusplus) */
+
#endif /* PK_PK_STN_H */
#ifdef PK_IMPL_STN
@@ -38,10 +78,8 @@ pk_stn_int64_t(int64_t *i, char const *s, int base)
long long l;
errno = 0;
l = strtoll(s, &end, base);
- if (errno == ERANGE && l == LLONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LLONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == LLONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -58,10 +96,8 @@ pk_stn_uint64_t(uint64_t *i, char const *s, int base)
unsigned long long l;
errno = 0;
l = strtoull(s, &end, base);
- if (errno == ERANGE && l == LLONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LLONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == ULLONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -78,10 +114,8 @@ pk_stn_int32_t(int32_t *i, char const *s, int base)
long l;
errno = 0;
l = strtol(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -98,10 +132,8 @@ pk_stn_uint32_t(uint32_t *i, char const *s, int base)
unsigned long l;
errno = 0;
l = strtoul(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -118,10 +150,8 @@ pk_stn_int16_t(int16_t *i, char const *s, int base)
long l;
errno = 0;
l = strtol(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -138,10 +168,8 @@ pk_stn_uint16_t(uint16_t *i, char const *s, int base)
unsigned long l;
errno = 0;
l = strtoul(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -158,10 +186,8 @@ pk_stn_int8_t(int8_t *i, char const *s, int base)
long l;
errno = 0;
l = strtol(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == LONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
@@ -178,10 +204,8 @@ pk_stn_uint8_t(uint8_t *i, char const *s, int base)
unsigned long l;
errno = 0;
l = strtoul(s, &end, base);
- if (errno == ERANGE && l == LONG_MAX) {
- return PK_STN_RES_OVERFLOW;
- }
- if (errno == ERANGE && l == LONG_MIN) {
+ if (errno == ERANGE) {
+ if (l == ULONG_MAX) return PK_STN_RES_OVERFLOW;
return PK_STN_RES_UNDERFLOW;
}
if (*s == '\0' || *end != '\0') {
diff --git a/test/pkstn.cpp b/test/pkstn.cpp
index 920c6ac..8a4d901 100644
--- a/test/pkstn.cpp
+++ b/test/pkstn.cpp
@@ -1,103 +1,142 @@
#include "../pkstn.h"
+#include <iostream>
#include <stdio.h>
#include <stdlib.h>
+#include <type_traits>
+
+const char *STRNUM_ONE = "1";
+const char *STRNUM_ONE_MINUS = "-1";
+const char *STRNUM_UNDERFLOW = "-99999999999999999999999999999999";
+const char *STRNUM_OVERFLOW = "99999999999999999999999999999999";
+const char *STRNUM_UNDERFLOW_FLOAT = "-1.0e9999";
+const char *STRNUM_OVERFLOW_FLOAT = "1.0e9999";
+const char *STRNUM_INCONVERTIBLE = "junk";
+
+enum STRNUM_TESTS : uint8_t {
+ TEST_ONE = 0x01,
+ TEST_ONE_MINUS = 0x02,
+ TEST_UNDERFLOW = 0x04,
+ TEST_OVERFLOW = 0x08,
+ TEST_INCONVERTIBLE = 0x10,
+ TEST_NO_NEG = TEST_ONE | TEST_OVERFLOW | TEST_INCONVERTIBLE,
+ TEST_FLOATS = TEST_ONE | TEST_ONE_MINUS | TEST_UNDERFLOW | TEST_OVERFLOW,
+ TEST_ALL = 0xFF,
+};
+
+template <typename T, enum STRNUM_TESTS t>
+void test() {
+ enum PK_STN_RES res = {};
+ T i = {0};
+ if constexpr (t & TEST_ONE) {
+ res = pk_stn(&i, STRNUM_ONE);
+ std::cout << "pkstn: TEST_ONE res: " << i << "\n";
+ if (res != PK_STN_RES_SUCCESS) exit(1);
+ if (1 != i) exit(1);
+ }
+ if constexpr (t & TEST_ONE_MINUS) {
+ res = pk_stn(&i, STRNUM_ONE_MINUS);
+ std::cout << "pkstn: STRNUM_ONE_MINUS res: " << i << "\n";
+ if (res != PK_STN_RES_SUCCESS) exit(1);
+ if (T(-1) != i) exit(1);
+ }
+ if constexpr (t & TEST_UNDERFLOW) {
+ const char * str;
+ if constexpr(std::is_same<T, float>::value == true || std::is_same<T, double>::value == true) {
+ str = STRNUM_UNDERFLOW_FLOAT;
+ } else {
+ str = STRNUM_UNDERFLOW;
+ }
+ res = pk_stn(&i, str);
+ std::cout << "pkstn: TEST_UNDERFLOW res: " << i << "\n";
+ if constexpr(std::is_unsigned_v<T> == true) {
+ if (res != PK_STN_RES_OVERFLOW) exit(1);
+ } else {
+ if (res != PK_STN_RES_UNDERFLOW) exit(1);
+ }
+ }
+ if constexpr (t & TEST_OVERFLOW) {
+ const char * str;
+ if constexpr(std::is_same<T, float>::value == true || std::is_same<T, double>::value == true) {
+ str = STRNUM_OVERFLOW_FLOAT;
+ } else {
+ str = STRNUM_OVERFLOW;
+ }
+ res = pk_stn(&i, str);
+ std::cout << "pkstn: TEST_OVERFLOW res: " << i << "\n";
+ if (res != PK_STN_RES_OVERFLOW) exit(1);
+ }
+ if constexpr (t & TEST_INCONVERTIBLE) {
+ res = pk_stn(&i, STRNUM_INCONVERTIBLE);
+ std::cout << "pkstn: TEST_INCONVERTIBLE res: " << i << "\n";
+ if (res != PK_STN_RES_INCONVERTIBLE) exit(1);
+ }
+};
int main(int argc, char *argv[])
{
(void)argc;
(void)argv;
- enum PK_STN_RES res = {};
+ fprintf(stdout, "\n");
// stn_int64_t
{
- int64_t i = {0};
- res = pk_stn_int64_t(&i, "-1", 0);
- fprintf(stdout, "pkstn: stn_int64_t res: %ld\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting int64_t\n");
+ test<int64_t, TEST_ALL>();
}
// stn_uint64_t
{
- uint64_t i = {0};
- res = pk_stn_uint64_t(&i, "1", 0);
- fprintf(stdout, "pkstn: stn_uint64_t res: %lu\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (1 != i) exit(1);
- }
+ fprintf(stdout, "\npkstn: starting uint64_t\n");
+ test<uint64_t, TEST_ALL>(); }
// stn_int32_t
{
- int32_t i = {0};
- res = pk_stn_int32_t(&i, "-1", 0);
- fprintf(stdout, "pkstn: stn_int32_t res: %d\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting int32_t\n");
+ test<int32_t, TEST_ALL>();
}
// stn_uint32_t
{
- uint32_t i = {0};
- res = pk_stn_uint32_t(&i, "1", 0);
- fprintf(stdout, "pkstn: stn_uint32_t res: %u\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting uint32_t\n");
+ test<uint32_t, TEST_ALL>();
}
// stn_int16_t
{
- int16_t i = {0};
- res = pk_stn_int16_t(&i, "-1", 0);
- fprintf(stdout, "pkstn: stn_int16_t res: %d\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting int16_t\n");
+ test<int16_t, TEST_ALL>();
}
// stn_uint16_t
{
- uint16_t i = {0};
- res = pk_stn_uint16_t(&i, "1", 0);
- fprintf(stdout, "pkstn: stn_uint16_t res: %u\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting uint16_t\n");
+ test<uint16_t, TEST_ALL>();
}
// stn_int8_t
{
- int8_t i = {0};
- res = pk_stn_int8_t(&i, "-1", 0);
- fprintf(stdout, "pkstn: stn_int8_t res: %d\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting int8_t\n");
+ test<int8_t, TEST_ALL>();
}
// stn_uint8_t
{
- uint8_t i = {0};
- res = pk_stn_uint8_t(&i, "1", 0);
- fprintf(stdout, "pkstn: stn_uint8_t res: %u\n", i);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (1 != i) exit(1);
+ fprintf(stdout, "\npkstn: starting uint8_t\n");
+ test<uint8_t, TEST_ALL>();
}
// stn_float
{
- float f = {0};
- res = pk_stn_float(&f, "-1");
- fprintf(stdout, "pkstn: stn_float res: %f\n", f);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != f) exit(1);
+ fprintf(stdout, "\npkstn: starting float\n");
+ test<float, TEST_FLOATS>();
}
// stn_double
{
- double f = {0};
- res = pk_stn_double(&f, "-1");
- fprintf(stdout, "pkstn: stn_double res: %f\n", f);
- if (res != PK_STN_RES_SUCCESS) exit(1);
- if (-1 != f) exit(1);
+ fprintf(stdout, "\npkstn: starting double\n");
+ test<double, TEST_FLOATS>();
}
return 0;