Changes in uspace/lib/c/generic/str.c [d47279b:9539be6] in mainline
- File:
-
- 1 edited
-
uspace/lib/c/generic/str.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
rd47279b r9539be6 1005 1005 *end = '\0'; 1006 1006 return start; 1007 }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 1007 } 1214 1008
Note:
See TracChangeset
for help on using the changeset viewer.
