813 ctx->delim_more = delim; |
813 ctx->delim_more = delim; |
814 ctx->delim_more_count = count; |
814 ctx->delim_more_count = count; |
815 } |
815 } |
816 |
816 |
817 #define cx_strtoX_signed_impl(rtype, rmin, rmax) \ |
817 #define cx_strtoX_signed_impl(rtype, rmin, rmax) \ |
818 int64_t result; \ |
818 long long result; \ |
819 if (cx_strtoi64_lc(str, &result, base, groupsep)) { \ |
819 if (cx_strtoll_lc(str, &result, base, groupsep)) { \ |
820 return -1; \ |
820 return -1; \ |
821 } \ |
821 } \ |
822 if (result < rmin || result > rmax) { \ |
822 if (result < rmin || result > rmax) { \ |
823 errno = ERANGE; \ |
823 errno = ERANGE; \ |
824 return -1; \ |
824 return -1; \ |
837 int cx_strtol_lc(cxstring str, long *output, int base, const char *groupsep) { |
837 int cx_strtol_lc(cxstring str, long *output, int base, const char *groupsep) { |
838 cx_strtoX_signed_impl(long, LONG_MIN, LONG_MAX); |
838 cx_strtoX_signed_impl(long, LONG_MIN, LONG_MAX); |
839 } |
839 } |
840 |
840 |
841 int cx_strtoll_lc(cxstring str, long long *output, int base, const char *groupsep) { |
841 int cx_strtoll_lc(cxstring str, long long *output, int base, const char *groupsep) { |
842 assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms |
842 // TODO: replace temporary implementation |
843 return cx_strtoi64_lc(str, (int64_t*) output, base, groupsep); |
843 (void) groupsep; // unused in temp impl |
|
844 char *s = malloc(str.length + 1); |
|
845 memcpy(s, str.ptr, str.length); |
|
846 s[str.length] = '\0'; |
|
847 char *e; |
|
848 errno = 0; |
|
849 *output = strtoll(s, &e, base); |
|
850 int r = errno || !(e && *e == '\0'); |
|
851 free(s); |
|
852 return r; |
844 } |
853 } |
845 |
854 |
846 int cx_strtoi8_lc(cxstring str, int8_t *output, int base, const char *groupsep) { |
855 int cx_strtoi8_lc(cxstring str, int8_t *output, int base, const char *groupsep) { |
847 cx_strtoX_signed_impl(int8_t, INT8_MIN, INT8_MAX); |
856 cx_strtoX_signed_impl(int8_t, INT8_MIN, INT8_MAX); |
848 } |
857 } |
854 int cx_strtoi32_lc(cxstring str, int32_t *output, int base, const char *groupsep) { |
863 int cx_strtoi32_lc(cxstring str, int32_t *output, int base, const char *groupsep) { |
855 cx_strtoX_signed_impl(int32_t, INT32_MIN, INT32_MAX); |
864 cx_strtoX_signed_impl(int32_t, INT32_MIN, INT32_MAX); |
856 } |
865 } |
857 |
866 |
858 int cx_strtoi64_lc(cxstring str, int64_t *output, int base, const char *groupsep) { |
867 int cx_strtoi64_lc(cxstring str, int64_t *output, int base, const char *groupsep) { |
859 // TODO: implement |
868 assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms |
860 return -1; |
869 return cx_strtoll_lc(str, (long long*) output, base, groupsep); |
861 } |
870 } |
862 |
871 |
863 int cx_strtoz_lc(cxstring str, ssize_t *output, int base, const char *groupsep) { |
872 int cx_strtoz_lc(cxstring str, ssize_t *output, int base, const char *groupsep) { |
864 #if CX_WORDSIZE == 32 |
873 #if SSIZE_MAX == INT32_MAX |
865 return cx_strtoi32_lc(str, output, base, groupsep); |
874 return cx_strtoi32_lc(str, (int32_t*) output, base, groupsep); |
|
875 #elif SSIZE_MAX == INT64_MAX |
|
876 return cx_strtoll_lc(str, (long long*) output, base, groupsep); |
866 #else |
877 #else |
867 return cx_strtoi64_lc(str, output, base, groupsep); |
878 #error "unsupported ssize_t size" |
868 #endif |
879 #endif |
869 } |
880 } |
870 |
881 |
871 #define cx_strtoX_unsigned_impl(rtype, rmax) \ |
882 #define cx_strtoX_unsigned_impl(rtype, rmax) \ |
872 uint64_t result; \ |
883 uint64_t result; \ |
891 int cx_strtoul_lc(cxstring str, unsigned long *output, int base, const char *groupsep) { |
902 int cx_strtoul_lc(cxstring str, unsigned long *output, int base, const char *groupsep) { |
892 cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX); |
903 cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX); |
893 } |
904 } |
894 |
905 |
895 int cx_strtoull_lc(cxstring str, unsigned long long *output, int base, const char *groupsep) { |
906 int cx_strtoull_lc(cxstring str, unsigned long long *output, int base, const char *groupsep) { |
896 assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms |
907 // TODO: replace temporary implementation |
897 return cx_strtou64_lc(str, (uint64_t*) output, base, groupsep); |
908 (void) groupsep; // unused in temp impl |
|
909 char *s = malloc(str.length + 1); |
|
910 memcpy(s, str.ptr, str.length); |
|
911 s[str.length] = '\0'; |
|
912 char *e; |
|
913 *output = strtoull(s, &e, base); |
|
914 int r = !(e && *e == '\0'); |
|
915 free(s); |
|
916 return r; |
898 } |
917 } |
899 |
918 |
900 int cx_strtou8_lc(cxstring str, uint8_t *output, int base, const char *groupsep) { |
919 int cx_strtou8_lc(cxstring str, uint8_t *output, int base, const char *groupsep) { |
901 cx_strtoX_unsigned_impl(uint8_t, UINT8_MAX); |
920 cx_strtoX_unsigned_impl(uint8_t, UINT8_MAX); |
902 } |
921 } |
908 int cx_strtou32_lc(cxstring str, uint32_t *output, int base, const char *groupsep) { |
927 int cx_strtou32_lc(cxstring str, uint32_t *output, int base, const char *groupsep) { |
909 cx_strtoX_unsigned_impl(uint32_t, UINT32_MAX); |
928 cx_strtoX_unsigned_impl(uint32_t, UINT32_MAX); |
910 } |
929 } |
911 |
930 |
912 int cx_strtou64_lc(cxstring str, uint64_t *output, int base, const char *groupsep) { |
931 int cx_strtou64_lc(cxstring str, uint64_t *output, int base, const char *groupsep) { |
913 // TODO: implement |
932 assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms |
914 return -1; |
933 return cx_strtoull_lc(str, (unsigned long long*) output, base, groupsep); |
915 } |
934 } |
916 |
935 |
917 int cx_strtouz_lc(cxstring str, size_t *output, int base, const char *groupsep) { |
936 int cx_strtouz_lc(cxstring str, size_t *output, int base, const char *groupsep) { |
918 #if CX_WORDSIZE == 32 |
937 #if SIZE_MAX == UINT32_MAX |
919 return cx_strtou32_lc(str, output, base, groupsep); |
938 return cx_strtou32_lc(str, (uint32_t*) output, base, groupsep); |
|
939 #elif SIZE_MAX == UINT64_MAX |
|
940 return cx_strtoull_lc(str, (unsigned long long *) output, base, groupsep); |
920 #else |
941 #else |
921 return cx_strtou64_lc(str, output, base, groupsep); |
942 #error "unsupported size_t size" |
922 #endif |
943 #endif |
923 } |
944 } |
924 |
945 |
925 int cx_strtof_lc(cxstring str, float *output, char decsep, const char *groupsep) { |
946 int cx_strtof_lc(cxstring str, float *output, char decsep, const char *groupsep) { |
926 // TODO: impl |
947 // TODO: replace temporary implementation |
927 return -1; |
948 (void) groupsep; // unused in temp impl |
|
949 (void) decsep; // unused in temp impl |
|
950 char *s = malloc(str.length + 1); |
|
951 memcpy(s, str.ptr, str.length); |
|
952 s[str.length] = '\0'; |
|
953 char *e; |
|
954 *output = strtof(s, &e); |
|
955 int r = !(e && *e == '\0'); |
|
956 free(s); |
|
957 return r; |
928 } |
958 } |
929 |
959 |
930 int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) { |
960 int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) { |
931 // TODO: impl |
961 // TODO: replace temporary implementation |
932 return -1; |
962 (void) groupsep; // unused in temp impl |
933 } |
963 (void) decsep; // unused in temp impl |
|
964 char *s = malloc(str.length + 1); |
|
965 memcpy(s, str.ptr, str.length); |
|
966 s[str.length] = '\0'; |
|
967 char *e; |
|
968 *output = strtod(s, &e); |
|
969 int r = !(e && *e == '\0'); |
|
970 free(s); |
|
971 return r; |
|
972 } |