src/string.c

changeset 1415
40074e643663
parent 1413
c5a225d7228c
equal deleted inserted replaced
1414:597cf869e8bc 1415:40074e643663
35 #include <stdarg.h> 35 #include <stdarg.h>
36 #include <assert.h> 36 #include <assert.h>
37 #include <errno.h> 37 #include <errno.h>
38 #include <limits.h> 38 #include <limits.h>
39 #include <float.h> 39 #include <float.h>
40 #include <ctype.h>
40 41
41 #ifdef _WIN32 42 #ifdef _WIN32
42 #define cx_strcasecmp_impl _strnicmp 43 #define cx_strcasecmp_impl _strnicmp
43 #else 44 #else
44 #include <strings.h> 45 #include <strings.h>
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);
1030 } 1020 }
1031 } 1021 }
1032 // parse everything until exponent or end 1022 // parse everything until exponent or end
1033 double factor = 1.; 1023 double factor = 1.;
1034 do { 1024 do {
1035 if (str_isdigit(str.ptr[pos])) { 1025 if (isdigit((unsigned char)str.ptr[pos])) {
1036 factor *= 0.1; 1026 factor *= 0.1;
1037 result = result + factor * (str.ptr[pos] - '0'); 1027 result = result + factor * (str.ptr[pos] - '0');
1038 } else if (strchr(groupsep, str.ptr[pos]) == NULL) { 1028 } else if (strchr(groupsep, str.ptr[pos]) == NULL) {
1039 break; 1029 break;
1040 } 1030 }
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 }

mercurial