diff options
| -rw-r--r-- | Makefile | 18 | ||||
| -rw-r--r-- | config.mk | 1 | ||||
| -rw-r--r-- | pk.h.in | 10 | ||||
| -rw-r--r-- | pkstn.h | 246 | ||||
| -rw-r--r-- | test/pkstn.c | 104 | ||||
| -rw-r--r-- | test/pkstn.cpp | 104 |
6 files changed, 483 insertions, 0 deletions
@@ -12,6 +12,7 @@ SRC = \ pkstr.h \ pkev.h \ pkarr.h \ + pkstn.h \ test/pkmacros.c \ test/pkmacros.cpp \ test/pkmem-types.c \ @@ -24,6 +25,8 @@ SRC = \ test/pkev.cpp \ test/pkarr.c\ test/pkarr.cpp \ + test/pkstn.c\ + test/pkstn.cpp \ OBJ = $(SRC:%.c=.o) PPOBJ = $(SRC:%.cpp=.so) @@ -37,12 +40,14 @@ all: options .WAIT clean .WAIT \ pkstr \ pkev \ pkarr \ + pkstn \ test-pkmem-types test-pkmem-types-cpp \ test-pkmem test-pkmem-cpp \ test-pkmacros test-pkmacros-cpp \ test-pkstr test-pkstr-cpp \ test-pkev test-pkev-cpp \ test-pkarr test-pkarr-cpp \ + test-pkstn test-pkstn-cpp \ options: @echo at-suite build options: @@ -78,12 +83,15 @@ pkev: pkev.gch pkev.gchpp pkarr: pkmem pkarr.gch pkarr.gchpp +pkstn: pkstn.gch pkstn.gchpp + build: pkmacros build: pkmem-types build: pkmem build: pkstr build: pkev build: pkarr +build: pkstn echo "#ifndef PK_SINGLE_HEADER_FILE_H\n#define PK_SINGLE_HEADER_FILE_H" > pk.h cat pk.h.in \ pkmacros.h \ @@ -92,6 +100,7 @@ build: pkarr pkstr.h \ pkev.h \ pkarr.h \ + pkstn.h \ >> pk.h echo "#endif /* PK_SINGLE_HEADER_FILE_H */" >> pk.h sed -i -r \ @@ -138,6 +147,12 @@ test-pkarr: test/pkarr.o test-pkarr-cpp: test/pkarr.so $(CXX) -g -O0 -std=c++23 $(CPPFLAGS) -o test/$@ $^ $(LDFLAGS) +test-pkstn: test/pkstn.o + $(CC) -g -O0 -std=c2x $(CFLAGS) -o test/$@ $^ $(LDFLAGS) + +test-pkstn-cpp: test/pkstn.so + $(CXX) -g -O0 -std=c++23 $(CPPFLAGS) -o test/$@ $^ $(LDFLAGS) + test: pkmacros pkmem-types pkmem pkstr pkev pkarr test: test-pkmacros test-pkmacros-cpp test: test-pkmem-types test-pkmem-types-cpp @@ -145,6 +160,7 @@ test: test-pkmem test-pkmem-cpp test: test-pkstr test-pkstr-cpp test: test-pkev test-pkev-cpp test: test-pkarr test-pkarr-cpp +test: test-pkstn test-pkstn-cpp test: @echo "" ./test/test-pkmacros ; echo Result: $$? "\n" @@ -159,6 +175,8 @@ test: ./test/test-pkev-cpp ; echo Result: $$? "\n" ./test/test-pkarr ; echo Result: $$? "\n" ./test/test-pkarr-cpp ; echo Result: $$? "\n" + ./test/test-pkstn ; echo Result: $$? "\n" + ./test/test-pkstn-cpp ; echo Result: $$? "\n" clean: rm -f *.plist *.gch *.gchpp *.o *.so test/*.o test/*.so test/test-* @@ -21,6 +21,7 @@ SHARED_FLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \ -DPK_IMPL_STR \ -DPK_IMPL_EV \ -DPK_IMPL_ARR \ + -DPK_IMPL_STN \ CPPFLAGS += -Wall $(INCS) $(SHARED_FLAGS) CFLAGS += -Wall $(INCS) $(SHARED_FLAGS) @@ -28,6 +28,7 @@ * # define PK_IMPL_STR * # define PK_IMPL_EV * # define PK_IMPL_ARR +* # define PK_IMPL_STN * #include "pk.h" * ``` * @@ -163,6 +164,12 @@ * d[0] = ...; * ``` * +******************************************************************************** +* pkstn.h: def PK_IMPL_STN before including pk.h to enable ad-hoc. +* +* Provides a thorough interface for interacting with the `stoi` family of +* procedures. +* *******************************************************************************/ #define PK_VERSION "@@PK_VERSION@@" @@ -183,4 +190,7 @@ # ifndef PK_IMPL_ARR # define PK_IMPL_ARR # endif +# ifndef PK_IMPL_STN +# define PK_IMPL_STN +# endif #endif @@ -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 */ diff --git a/test/pkstn.c b/test/pkstn.c new file mode 100644 index 0000000..97ec8a9 --- /dev/null +++ b/test/pkstn.c @@ -0,0 +1,104 @@ + +#include "../pkstn.h" + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + enum PK_STN_ERR res = {0}; + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // stn_float + { + float f = {0}; + res = pk_stn_float(&f, "-1"); + fprintf(stdout, "pkstn: stn_float res: %f\n", f); + if (res != PK_STN_ERR_SUCCESS) exit(1); + if (-1 != f) exit(1); + } + + // stn_double + { + double f = {0}; + res = pk_stn_double(&f, "-1"); + fprintf(stdout, "pkstn: stn_double res: %f\n", f); + if (res != PK_STN_ERR_SUCCESS) exit(1); + if (-1 != f) exit(1); + } + + return 0; +} diff --git a/test/pkstn.cpp b/test/pkstn.cpp new file mode 100644 index 0000000..261fb56 --- /dev/null +++ b/test/pkstn.cpp @@ -0,0 +1,104 @@ + +#include "../pkstn.h" + +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + enum PK_STN_ERR res = {}; + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (-1 != i) exit(1); + } + + // 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_ERR_SUCCESS) exit(1); + if (1 != i) exit(1); + } + + // stn_float + { + float f = {0}; + res = pk_stn_float(&f, "-1"); + fprintf(stdout, "pkstn: stn_float res: %f\n", f); + if (res != PK_STN_ERR_SUCCESS) exit(1); + if (-1 != f) exit(1); + } + + // stn_double + { + double f = {0}; + res = pk_stn_double(&f, "-1"); + fprintf(stdout, "pkstn: stn_double res: %f\n", f); + if (res != PK_STN_ERR_SUCCESS) exit(1); + if (-1 != f) exit(1); + } + + return 0; +} |
