src/string.c

branch
docs/3.1
changeset 1164
148b7c7ccaf9
parent 1162
e3bb67b72d33
equal deleted inserted replaced
1148:8ff82697f2c3 1164:148b7c7ccaf9
218 218
219 cxstring cx_strchr( 219 cxstring cx_strchr(
220 cxstring string, 220 cxstring string,
221 int chr 221 int chr
222 ) { 222 ) {
223 chr = 0xFF & chr; 223 char *ret = memchr(string.ptr, 0xFF & chr, string.length);
224 // TODO: improve by comparing multiple bytes at once 224 if (ret == NULL) return (cxstring) {NULL, 0};
225 for (size_t i = 0; i < string.length; i++) { 225 return (cxstring) {ret, string.length - (ret - string.ptr)};
226 if (string.ptr[i] == chr) {
227 return cx_strsubs(string, i);
228 }
229 }
230 return (cxstring) {NULL, 0};
231 } 226 }
232 227
233 cxmutstr cx_strchr_m( 228 cxmutstr cx_strchr_m(
234 cxmutstr string, 229 cxmutstr string,
235 int chr 230 int chr
691 } while (searchstr.length > 0 && found < replmax); 686 } while (searchstr.length > 0 && found < replmax);
692 687
693 // Allocate result string 688 // Allocate result string
694 cxmutstr result; 689 cxmutstr result;
695 { 690 {
696 ssize_t adjlen = (ssize_t) replacement.length - (ssize_t) pattern.length; 691 long long adjlen = (long long) replacement.length - (long long) pattern.length;
697 size_t rcount = 0; 692 size_t rcount = 0;
698 curbuf = &ibuf; 693 curbuf = &ibuf;
699 do { 694 do {
700 rcount += curbuf->len; 695 rcount += curbuf->len;
701 curbuf = curbuf->next; 696 curbuf = curbuf->next;
845 int cx_strtoll_lc_(cxstring str, long long *output, int base, const char *groupsep) { 840 int cx_strtoll_lc_(cxstring str, long long *output, int base, const char *groupsep) {
846 // strategy: parse as unsigned, check range, negate if required 841 // strategy: parse as unsigned, check range, negate if required
847 bool neg = false; 842 bool neg = false;
848 size_t start_unsigned = 0; 843 size_t start_unsigned = 0;
849 844
850 // trim already, to search for a sign character 845 // emptiness check
851 str = cx_strtrim(str);
852 if (str.length == 0) { 846 if (str.length == 0) {
853 errno = EINVAL; 847 errno = EINVAL;
854 return -1; 848 return -1;
855 } 849 }
856 850
901 } 895 }
902 896
903 int cx_strtoi64_lc_(cxstring str, int64_t *output, int base, const char *groupsep) { 897 int cx_strtoi64_lc_(cxstring str, int64_t *output, int base, const char *groupsep) {
904 assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms 898 assert(sizeof(long long) == sizeof(int64_t)); // should be true on all platforms
905 return cx_strtoll_lc(str, (long long*) output, base, groupsep); 899 return cx_strtoll_lc(str, (long long*) output, base, groupsep);
906 }
907
908 int cx_strtoz_lc_(cxstring str, ssize_t *output, int base, const char *groupsep) {
909 #if SSIZE_MAX == INT32_MAX
910 return cx_strtoi32_lc_(str, (int32_t*) output, base, groupsep);
911 #elif SSIZE_MAX == INT64_MAX
912 return cx_strtoll_lc_(str, (long long*) output, base, groupsep);
913 #else
914 #error "unsupported ssize_t size"
915 #endif
916 } 900 }
917 901
918 #define cx_strtoX_unsigned_impl(rtype, rmax) \ 902 #define cx_strtoX_unsigned_impl(rtype, rmax) \
919 uint64_t result; \ 903 uint64_t result; \
920 if (cx_strtou64_lc(str, &result, base, groupsep)) { \ 904 if (cx_strtou64_lc(str, &result, base, groupsep)) { \
939 cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX); 923 cx_strtoX_unsigned_impl(unsigned long, ULONG_MAX);
940 } 924 }
941 925
942 int cx_strtoull_lc_(cxstring str, unsigned long long *output, int base, const char *groupsep) { 926 int cx_strtoull_lc_(cxstring str, unsigned long long *output, int base, const char *groupsep) {
943 // some sanity checks 927 // some sanity checks
944 str = cx_strtrim(str);
945 if (str.length == 0) { 928 if (str.length == 0) {
946 errno = EINVAL; 929 errno = EINVAL;
947 return -1; 930 return -1;
948 } 931 }
949 if (!(base == 2 || base == 8 || base == 10 || base == 16)) { 932 if (!(base == 2 || base == 8 || base == 10 || base == 16)) {
1034 int cx_strtou64_lc_(cxstring str, uint64_t *output, int base, const char *groupsep) { 1017 int cx_strtou64_lc_(cxstring str, uint64_t *output, int base, const char *groupsep) {
1035 assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms 1018 assert(sizeof(unsigned long long) == sizeof(uint64_t)); // should be true on all platforms
1036 return cx_strtoull_lc(str, (unsigned long long*) output, base, groupsep); 1019 return cx_strtoull_lc(str, (unsigned long long*) output, base, groupsep);
1037 } 1020 }
1038 1021
1039 int cx_strtouz_lc_(cxstring str, size_t *output, int base, const char *groupsep) { 1022 int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep) {
1040 #if SIZE_MAX == UINT32_MAX 1023 #if SIZE_MAX == UINT32_MAX
1041 return cx_strtou32_lc_(str, (uint32_t*) output, base, groupsep); 1024 return cx_strtou32_lc_(str, (uint32_t*) output, base, groupsep);
1042 #elif SIZE_MAX == UINT64_MAX 1025 #elif SIZE_MAX == UINT64_MAX
1043 return cx_strtoull_lc_(str, (unsigned long long *) output, base, groupsep); 1026 return cx_strtoull_lc_(str, (unsigned long long *) output, base, groupsep);
1044 #else 1027 #else
1068 1051
1069 int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep) { 1052 int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep) {
1070 // TODO: overflow check 1053 // TODO: overflow check
1071 // TODO: increase precision 1054 // TODO: increase precision
1072 1055
1073 // trim and check 1056 // emptiness check
1074 str = cx_strtrim(str);
1075 if (str.length == 0) { 1057 if (str.length == 0) {
1076 errno = EINVAL; 1058 errno = EINVAL;
1077 return -1; 1059 return -1;
1078 } 1060 }
1079 1061

mercurial