527 memcpy(result.ptr, string.ptr, string.length); |
528 memcpy(result.ptr, string.ptr, string.length); |
528 result.ptr[string.length] = '\0'; |
529 result.ptr[string.length] = '\0'; |
529 return result; |
530 return result; |
530 } |
531 } |
531 |
532 |
532 static bool str_isspace(char c) { |
|
533 // TODO: remove once UCX has public API for this |
|
534 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; |
|
535 } |
|
536 |
|
537 cxstring cx_strtrim(cxstring string) { |
533 cxstring cx_strtrim(cxstring string) { |
538 cxstring result = string; |
534 cxstring result = string; |
539 // TODO: optimize by comparing multiple bytes at once |
535 while (result.length > 0 && isspace((unsigned char)(result.ptr[0]))) { |
540 while (result.length > 0 && str_isspace(*result.ptr)) { |
|
541 result.ptr++; |
536 result.ptr++; |
542 result.length--; |
537 result.length--; |
543 } |
538 } |
544 while (result.length > 0 && str_isspace(result.ptr[result.length - 1])) { |
539 while (result.length > 0 && isspace((unsigned char)result.ptr[result.length - 1])) { |
545 result.length--; |
540 result.length--; |
546 } |
541 } |
547 return result; |
542 return result; |
548 } |
543 } |
549 |
544 |
964 } |
959 } |
965 *output = (float) d; |
960 *output = (float) d; |
966 return 0; |
961 return 0; |
967 } |
962 } |
968 |
963 |
969 static bool str_isdigit(char c) { |
|
970 // TODO: remove once UCX has public API for this |
|
971 return c >= '0' && c <= '9'; |
|
972 } |
|
973 |
|
974 int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep) { |
964 int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep) { |
975 // TODO: overflow check |
965 // TODO: overflow check |
976 // TODO: increase precision |
966 // TODO: increase precision |
977 |
967 |
978 // emptiness check |
968 // emptiness check |
1001 } |
991 } |
1002 |
992 |
1003 // parse all digits until we find the decsep |
993 // parse all digits until we find the decsep |
1004 size_t pos = 0; |
994 size_t pos = 0; |
1005 do { |
995 do { |
1006 if (str_isdigit(str.ptr[pos])) { |
996 if (isdigit((unsigned char)str.ptr[pos])) { |
1007 result = result * 10 + (str.ptr[pos] - '0'); |
997 result = result * 10 + (str.ptr[pos] - '0'); |
1008 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
998 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1009 break; |
999 break; |
1010 } |
1000 } |
1011 } while (++pos < str.length); |
1001 } while (++pos < str.length); |
1071 } |
1061 } |
1072 |
1062 |
1073 // parse the exponent |
1063 // parse the exponent |
1074 unsigned int exp = 0; |
1064 unsigned int exp = 0; |
1075 do { |
1065 do { |
1076 if (str_isdigit(str.ptr[pos])) { |
1066 if (isdigit((unsigned char)str.ptr[pos])) { |
1077 exp = 10 * exp + (str.ptr[pos] - '0'); |
1067 exp = 10 * exp + (str.ptr[pos] - '0'); |
1078 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1068 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { |
1079 errno = EINVAL; |
1069 errno = EINVAL; |
1080 return -1; |
1070 return -1; |
1081 } |
1071 } |