527 memcpy(result.ptr, string.ptr, string.length); |
526 memcpy(result.ptr, string.ptr, string.length); |
528 result.ptr[string.length] = '\0'; |
527 result.ptr[string.length] = '\0'; |
529 return result; |
528 return result; |
530 } |
529 } |
531 |
530 |
|
531 static bool str_isspace(char c) { |
|
532 // TODO: remove once UCX has public API for this |
|
533 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; |
|
534 } |
|
535 |
532 cxstring cx_strtrim(cxstring string) { |
536 cxstring cx_strtrim(cxstring string) { |
533 cxstring result = string; |
537 cxstring result = string; |
534 // TODO: optimize by comparing multiple bytes at once |
538 // TODO: optimize by comparing multiple bytes at once |
535 while (result.length > 0 && isspace(*result.ptr)) { |
539 while (result.length > 0 && str_isspace(*result.ptr)) { |
536 result.ptr++; |
540 result.ptr++; |
537 result.length--; |
541 result.length--; |
538 } |
542 } |
539 while (result.length > 0 && isspace(result.ptr[result.length - 1])) { |
543 while (result.length > 0 && str_isspace(result.ptr[result.length - 1])) { |
540 result.length--; |
544 result.length--; |
541 } |
545 } |
542 return result; |
546 return result; |
543 } |
547 } |
544 |
548 |
590 #endif |
594 #endif |
591 } |
595 } |
592 |
596 |
593 void cx_strlower(cxmutstr string) { |
597 void cx_strlower(cxmutstr string) { |
594 for (size_t i = 0; i < string.length; i++) { |
598 for (size_t i = 0; i < string.length; i++) { |
595 string.ptr[i] = (char) tolower(string.ptr[i]); |
599 if ((unsigned int) (string.ptr[i] - 'A') < 26u) { |
|
600 string.ptr[i] += 'a' - 'A'; |
|
601 } |
596 } |
602 } |
597 } |
603 } |
598 |
604 |
599 void cx_strupper(cxmutstr string) { |
605 void cx_strupper(cxmutstr string) { |
600 for (size_t i = 0; i < string.length; i++) { |
606 for (size_t i = 0; i < string.length; i++) { |
601 string.ptr[i] = (char) toupper(string.ptr[i]); |
607 if ((unsigned int) (string.ptr[i] - 'a') < 26u) { |
|
608 string.ptr[i] += 'A' - 'a'; |
|
609 } |
602 } |
610 } |
603 } |
611 } |
604 |
612 |
605 #ifndef CX_STRREPLACE_INDEX_BUFFER_SIZE |
613 #ifndef CX_STRREPLACE_INDEX_BUFFER_SIZE |
606 #define CX_STRREPLACE_INDEX_BUFFER_SIZE 64 |
614 #define CX_STRREPLACE_INDEX_BUFFER_SIZE 64 |
1053 } |
1061 } |
1054 *output = (float) d; |
1062 *output = (float) d; |
1055 return 0; |
1063 return 0; |
1056 } |
1064 } |
1057 |
1065 |
|
1066 static bool str_isdigit(char c) { |
|
1067 // TODO: remove once UCX has public API for this |
|
1068 return c >= '0' && c <= '9'; |
|
1069 } |
|
1070 |
1058 int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) { |
1071 int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep) { |
1059 // TODO: overflow check |
1072 // TODO: overflow check |
1060 // TODO: increase precision |
1073 // TODO: increase precision |
1061 |
1074 |
1062 // trim and check |
1075 // trim and check |
1086 } |
1099 } |
1087 |
1100 |
1088 // parse all digits until we find the decsep |
1101 // parse all digits until we find the decsep |
1089 size_t pos = 0; |
1102 size_t pos = 0; |
1090 do { |
1103 do { |
1091 if (isdigit(str.ptr[pos])) { |
1104 if (str_isdigit(str.ptr[pos])) { |
1092 result = result * 10 + (str.ptr[pos] - '0'); |
1105 result = result * 10 + (str.ptr[pos] - '0'); |
1093 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1106 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1094 break; |
1107 break; |
1095 } |
1108 } |
1096 } while (++pos < str.length); |
1109 } while (++pos < str.length); |
1156 } |
1169 } |
1157 |
1170 |
1158 // parse the exponent |
1171 // parse the exponent |
1159 unsigned int exp = 0; |
1172 unsigned int exp = 0; |
1160 do { |
1173 do { |
1161 if (isdigit(str.ptr[pos])) { |
1174 if (str_isdigit(str.ptr[pos])) { |
1162 exp = 10 * exp + (str.ptr[pos] - '0'); |
1175 exp = 10 * exp + (str.ptr[pos] - '0'); |
1163 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1176 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1164 errno = EINVAL; |
1177 errno = EINVAL; |
1165 return -1; |
1178 return -1; |
1166 } |
1179 } |