Changeset d39c46e0 in mainline for uspace/lib/c/generic/str.c
- Timestamp:
- 2018-01-16T19:12:36Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 33b8d024
- Parents:
- aec41c8
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-01-16 19:04:19)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-01-16 19:12:36)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/str.c
raec41c8 rd39c46e0 1273 1273 } 1274 1274 1275 /** Convert string to a number.1276 * Core of strtol and strtoul functions.1277 *1278 * @param nptr Pointer to string.1279 * @param endptr If not NULL, function stores here pointer to the first1280 * invalid character.1281 * @param base Zero or number between 2 and 36 inclusive.1282 * @param sgn It's set to 1 if minus found.1283 * @return Result of conversion.1284 */1285 static unsigned long1286 _strtoul(const char *nptr, char **endptr, int base, char *sgn)1287 {1288 unsigned char c;1289 unsigned long result = 0;1290 unsigned long a, b;1291 const char *str = nptr;1292 const char *tmpptr;1293 1294 while (isspace(*str))1295 str++;1296 1297 if (*str == '-') {1298 *sgn = 1;1299 ++str;1300 } else if (*str == '+')1301 ++str;1302 1303 if (base) {1304 if ((base == 1) || (base > 36)) {1305 /* FIXME: set errno to EINVAL */1306 return 0;1307 }1308 if ((base == 16) && (*str == '0') && ((str[1] == 'x') ||1309 (str[1] == 'X'))) {1310 str += 2;1311 }1312 } else {1313 base = 10;1314 1315 if (*str == '0') {1316 base = 8;1317 if ((str[1] == 'X') || (str[1] == 'x')) {1318 base = 16;1319 str += 2;1320 }1321 }1322 }1323 1324 tmpptr = str;1325 1326 while (*str) {1327 c = *str;1328 c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 :1329 (c <= '9' ? c - '0' : 0xff)));1330 if (c >= base) {1331 break;1332 }1333 1334 a = (result & 0xff) * base + c;1335 b = (result >> 8) * base + (a >> 8);1336 1337 if (b > (ULONG_MAX >> 8)) {1338 /* overflow */1339 /* FIXME: errno = ERANGE*/1340 return ULONG_MAX;1341 }1342 1343 result = (b << 8) + (a & 0xff);1344 ++str;1345 }1346 1347 if (str == tmpptr) {1348 /*1349 * No number was found => first invalid character is the first1350 * character of the string.1351 */1352 /* FIXME: set errno to EINVAL */1353 str = nptr;1354 result = 0;1355 }1356 1357 if (endptr)1358 *endptr = (char *) str;1359 1360 if (nptr == str) {1361 /*FIXME: errno = EINVAL*/1362 return 0;1363 }1364 1365 return result;1366 }1367 1368 /** Convert initial part of string to long int according to given base.1369 * The number may begin with an arbitrary number of whitespaces followed by1370 * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be1371 * inserted and the number will be taken as hexadecimal one. If the base is 01372 * and the number begin with a zero, number will be taken as octal one (as with1373 * base 8). Otherwise the base 0 is taken as decimal.1374 *1375 * @param nptr Pointer to string.1376 * @param endptr If not NULL, function stores here pointer to the first1377 * invalid character.1378 * @param base Zero or number between 2 and 36 inclusive.1379 * @return Result of conversion.1380 */1381 long int strtol(const char *nptr, char **endptr, int base)1382 {1383 char sgn = 0;1384 unsigned long number = 0;1385 1386 number = _strtoul(nptr, endptr, base, &sgn);1387 1388 if (number > LONG_MAX) {1389 if ((sgn) && (number == (unsigned long) (LONG_MAX) + 1)) {1390 /* FIXME: set 0 to errno */1391 return number;1392 }1393 /* FIXME: set ERANGE to errno */1394 return (sgn ? LONG_MIN : LONG_MAX);1395 }1396 1397 return (sgn ? -number : number);1398 }1399 1275 1400 1276 /** Duplicate string. … … 1457 1333 str_ncpy(dest, size + 1, src, size); 1458 1334 return dest; 1459 }1460 1461 /** Convert initial part of string to unsigned long according to given base.1462 * The number may begin with an arbitrary number of whitespaces followed by1463 * optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be1464 * inserted and the number will be taken as hexadecimal one. If the base is 01465 * and the number begin with a zero, number will be taken as octal one (as with1466 * base 8). Otherwise the base 0 is taken as decimal.1467 *1468 * @param nptr Pointer to string.1469 * @param endptr If not NULL, function stores here pointer to the first1470 * invalid character1471 * @param base Zero or number between 2 and 36 inclusive.1472 * @return Result of conversion.1473 */1474 unsigned long strtoul(const char *nptr, char **endptr, int base)1475 {1476 char sgn = 0;1477 unsigned long number = 0;1478 1479 number = _strtoul(nptr, endptr, base, &sgn);1480 1481 return (sgn ? -number : number);1482 1335 } 1483 1336
Note:
See TracChangeset
for help on using the changeset viewer.