src/string.c

changeset 1048
12f38affefd5
parent 1041
508dc8b32a17
child 1050
3df63e95921a
--- a/src/string.c	Sun Dec 22 22:10:04 2024 +0100
+++ b/src/string.c	Sun Dec 22 22:14:57 2024 +0100
@@ -25,13 +25,15 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
-
+#define CX_STR_IMPLEMENTATION
 #include "cx/string.h"
 
 #include <string.h>
 #include <stdarg.h>
 #include <ctype.h>
+#include <assert.h>
 #include <errno.h>
+#include <limits.h>
 
 #ifndef _WIN32
 
@@ -815,3 +817,121 @@
     ctx->delim_more = delim;
     ctx->delim_more_count = count;
 }
+
+#define cx_strtoX_signed_impl(rtype, rmin, rmax) \
+    int64_t result; \
+    if (cx_strtoi64_lc(str, &result, base, groupsep)) { \
+        return -1; \
+    } \
+    if (result < rmin || result > rmax) { \
+        errno = ERANGE; \
+        return -1; \
+    } \
+    *output = (rtype) result; \
+    return 0
+
+int cx_strtos_lc(cxstring str, short *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(short, SHRT_MIN, SHRT_MAX);
+}
+
+int cx_strtoi_lc(cxstring str, int *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(int, INT_MIN, INT_MAX);
+}
+
+int cx_strtol_lc(cxstring str, long *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(long, LONG_MIN, LONG_MAX);
+}
+
+int cx_strtoll_lc(cxstring str, long long *output, int base, const char *groupsep) {
+    assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms
+    return cx_strtoi64_lc(str, (int64_t*) output, base, groupsep);
+}
+
+int cx_strtoi8_lc(cxstring str, int8_t *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(int8_t, INT8_MIN, INT8_MAX);
+}
+
+int cx_strtoi16_lc(cxstring str, int16_t *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(int16_t, INT16_MIN, INT16_MAX);
+}
+
+int cx_strtoi32_lc(cxstring str, int32_t *output, int base, const char *groupsep) {
+    cx_strtoX_signed_impl(int32_t, INT32_MIN, INT32_MAX);
+}
+
+int cx_strtoi64_lc(cxstring str, int64_t *output, int base, const char *groupsep) {
+    // TODO: implement
+    return -1;
+}
+
+int cx_strtoz_lc(cxstring str, ssize_t *output, int base, const char *groupsep) {
+#if CX_WORDSIZE == 32
+    return cx_strtoi32_lc(str, output, base, groupsep);
+#else
+    return cx_strtoi64_lc(str, output, base, groupsep);
+#endif
+}
+
+#define cx_strtoX_unsigned_impl(rtype, rmax) \
+    uint64_t result; \
+    if (cx_strtou64_lc(str, &result, base, groupsep)) { \
+        return -1; \
+    } \
+    if (result > rmax) { \
+        errno = ERANGE; \
+        return -1; \
+    } \
+    *output = (rtype) result; \
+    return 0
+
+int cx_strtous_lc(cxstring str, unsigned short *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(unsigned short, USHRT_MAX);
+}
+
+int cx_strtou_lc(cxstring str, unsigned int *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(unsigned int, UINT_MAX);
+}
+
+int cx_strtoul_lc(cxstring str, unsigned long *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX);
+}
+
+int cx_strtoull_lc(cxstring str, unsigned long long *output, int base, const char *groupsep) {
+    assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms
+    return cx_strtou64_lc(str, (uint64_t*) output, base, groupsep);
+}
+
+int cx_strtou8_lc(cxstring str, uint8_t *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(uint8_t, UINT8_MAX);
+}
+
+int cx_strtou16_lc(cxstring str, uint16_t *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(uint16_t, UINT16_MAX);
+}
+
+int cx_strtou32_lc(cxstring str, uint32_t *output, int base, const char *groupsep) {
+    cx_strtoX_unsigned_impl(uint32_t, UINT32_MAX);
+}
+
+int cx_strtou64_lc(cxstring str, uint64_t *output, int base, const char *groupsep) {
+    // TODO: implement
+    return -1;
+}
+
+int cx_strtouz_lc(cxstring str, size_t *output, int base, const char *groupsep) {
+#if CX_WORDSIZE == 32
+    return cx_strtou32_lc(str, output, base, groupsep);
+#else
+    return cx_strtou64_lc(str, output, base, groupsep);
+#endif
+}
+
+int cx_strtof_lc(cxstring str, float *output, char decsep, const char *groupsep) {
+    // TODO: impl
+    return -1;
+}
+
+int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) {
+    // TODO: impl
+    return -1;
+}
\ No newline at end of file

mercurial