Changes in uspace/lib/c/generic/str.c [933cadf:9539be6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
r933cadf r9539be6 1007 1007 } 1008 1008 1009 /** Convert string to uint64_t (internal variant).1010 *1011 * @param nptr Pointer to string.1012 * @param endptr Pointer to the first invalid character is stored here.1013 * @param base Zero or number between 2 and 36 inclusive.1014 * @param neg Indication of unary minus is stored here.1015 * @apram result Result of the conversion.1016 *1017 * @return EOK if conversion was successful.1018 *1019 */1020 static int str_uint(const char *nptr, char **endptr, unsigned int base,1021 bool *neg, uint64_t *result)1022 {1023 assert(endptr != NULL);1024 assert(neg != NULL);1025 assert(result != NULL);1026 1027 *neg = false;1028 const char *str = nptr;1029 1030 /* Ignore leading whitespace */1031 while (isspace(*str))1032 str++;1033 1034 if (*str == '-') {1035 *neg = true;1036 str++;1037 } else if (*str == '+')1038 str++;1039 1040 if (base == 0) {1041 /* Decode base if not specified */1042 base = 10;1043 1044 if (*str == '0') {1045 base = 8;1046 str++;1047 1048 switch (*str) {1049 case 'b':1050 case 'B':1051 base = 2;1052 str++;1053 break;1054 case 'o':1055 case 'O':1056 base = 8;1057 str++;1058 break;1059 case 'd':1060 case 'D':1061 case 't':1062 case 'T':1063 base = 10;1064 str++;1065 break;1066 case 'x':1067 case 'X':1068 base = 16;1069 str++;1070 break;1071 default:1072 str--;1073 }1074 }1075 } else {1076 /* Check base range */1077 if ((base < 2) || (base > 36)) {1078 *endptr = (char *) str;1079 return EINVAL;1080 }1081 }1082 1083 *result = 0;1084 const char *startstr = str;1085 1086 while (*str != 0) {1087 unsigned int digit;1088 1089 if ((*str >= 'a') && (*str <= 'z'))1090 digit = *str - 'a' + 10;1091 else if ((*str >= 'A') && (*str <= 'Z'))1092 digit = *str - 'A' + 10;1093 else if ((*str >= '0') && (*str <= '9'))1094 digit = *str - '0';1095 else1096 break;1097 1098 if (digit >= base)1099 break;1100 1101 uint64_t prev = *result;1102 *result = (*result) * base + digit;1103 1104 if (*result < prev) {1105 /* Overflow */1106 *endptr = (char *) str;1107 return EOVERFLOW;1108 }1109 1110 str++;1111 }1112 1113 if (str == startstr) {1114 /*1115 * No digits were decoded => first invalid character is1116 * the first character of the string.1117 */1118 str = nptr;1119 }1120 1121 *endptr = (char *) str;1122 1123 if (str == nptr)1124 return EINVAL;1125 1126 return EOK;1127 }1128 1129 /** Convert string to uint64_t.1130 *1131 * @param nptr Pointer to string.1132 * @param endptr If not NULL, pointer to the first invalid character1133 * is stored here.1134 * @param base Zero or number between 2 and 36 inclusive.1135 * @param strict Do not allow any trailing characters.1136 * @param result Result of the conversion.1137 *1138 * @return EOK if conversion was successful.1139 *1140 */1141 int str_uint64(const char *nptr, char **endptr, unsigned int base,1142 bool strict, uint64_t *result)1143 {1144 assert(result != NULL);1145 1146 bool neg;1147 char *lendptr;1148 int ret = str_uint(nptr, &lendptr, base, &neg, result);1149 1150 if (endptr != NULL)1151 *endptr = (char *) lendptr;1152 1153 if (ret != EOK)1154 return ret;1155 1156 /* Do not allow negative values */1157 if (neg)1158 return EINVAL;1159 1160 /* Check whether we are at the end of1161 the string in strict mode */1162 if ((strict) && (*lendptr != 0))1163 return EINVAL;1164 1165 return EOK;1166 }1167 1168 /** Convert string to size_t.1169 *1170 * @param nptr Pointer to string.1171 * @param endptr If not NULL, pointer to the first invalid character1172 * is stored here.1173 * @param base Zero or number between 2 and 36 inclusive.1174 * @param strict Do not allow any trailing characters.1175 * @param result Result of the conversion.1176 *1177 * @return EOK if conversion was successful.1178 *1179 */1180 int str_size_t(const char *nptr, char **endptr, unsigned int base,1181 bool strict, size_t *result)1182 {1183 assert(result != NULL);1184 1185 bool neg;1186 char *lendptr;1187 uint64_t res;1188 int ret = str_uint(nptr, &lendptr, base, &neg, &res);1189 1190 if (endptr != NULL)1191 *endptr = (char *) lendptr;1192 1193 if (ret != EOK)1194 return ret;1195 1196 /* Do not allow negative values */1197 if (neg)1198 return EINVAL;1199 1200 /* Check whether we are at the end of1201 the string in strict mode */1202 if ((strict) && (*lendptr != 0))1203 return EINVAL;1204 1205 /* Check for overflow */1206 size_t _res = (size_t) res;1207 if (_res != res)1208 return EOVERFLOW;1209 1210 *result = _res;1211 1212 return EOK;1213 }1214 1215 1009 void order_suffix(const uint64_t val, uint64_t *rv, char *suffix) 1216 1010 { 1217 if (val > UINT64_C(10000000000000000000)) {1218 *rv = val / UINT64_C(1000000000000000000);1011 if (val > 10000000000000000000ULL) { 1012 *rv = val / 1000000000000000000ULL; 1219 1013 *suffix = 'Z'; 1220 } else if (val > UINT64_C(1000000000000000000)) {1221 *rv = val / UINT64_C(1000000000000000);1014 } else if (val > 1000000000000000000ULL) { 1015 *rv = val / 1000000000000000ULL; 1222 1016 *suffix = 'E'; 1223 } else if (val > UINT64_C(1000000000000000)) {1224 *rv = val / UINT64_C(1000000000000);1017 } else if (val > 1000000000000000ULL) { 1018 *rv = val / 1000000000000ULL; 1225 1019 *suffix = 'T'; 1226 } else if (val > UINT64_C(1000000000000)) {1227 *rv = val / UINT64_C(1000000000);1020 } else if (val > 1000000000000ULL) { 1021 *rv = val / 1000000000ULL; 1228 1022 *suffix = 'G'; 1229 } else if (val > UINT64_C(1000000000)) {1230 *rv = val / UINT64_C(1000000);1023 } else if (val > 1000000000ULL) { 1024 *rv = val / 1000000ULL; 1231 1025 *suffix = 'M'; 1232 } else if (val > UINT64_C(1000000)) {1233 *rv = val / UINT64_C(1000);1026 } else if (val > 1000000ULL) { 1027 *rv = val / 1000ULL; 1234 1028 *suffix = 'k'; 1235 1029 } else { … … 1239 1033 } 1240 1034 1241 void bin_order_suffix(const uint64_t val, uint64_t *rv, const char **suffix,1242 bool fixed)1243 {1244 if (val > UINT64_C(1152921504606846976)) {1245 *rv = val / UINT64_C(1125899906842624);1246 *suffix = "EiB";1247 } else if (val > UINT64_C(1125899906842624)) {1248 *rv = val / UINT64_C(1099511627776);1249 *suffix = "TiB";1250 } else if (val > UINT64_C(1099511627776)) {1251 *rv = val / UINT64_C(1073741824);1252 *suffix = "GiB";1253 } else if (val > UINT64_C(1073741824)) {1254 *rv = val / UINT64_C(1048576);1255 *suffix = "MiB";1256 } else if (val > UINT64_C(1048576)) {1257 *rv = val / UINT64_C(1024);1258 *suffix = "KiB";1259 } else {1260 *rv = val;1261 if (fixed)1262 *suffix = "B ";1263 else1264 *suffix = "B";1265 }1266 }1267 1268 1035 /** @} 1269 1036 */
Note:
See TracChangeset
for help on using the changeset viewer.