| 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 } |