Changeset 1c9bf292 in mainline for uspace/lib/c/generic/strtol.c
- Timestamp:
- 2019-05-27T20:27:49Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 42e91ae
- Parents:
- dd0502ae
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/strtol.c
rdd0502ae r1c9bf292 44 44 #include <stdbool.h> 45 45 #include <stdlib.h> 46 47 // TODO: unit tests 46 #include <str.h> 47 48 // FIXME: The original HelenOS functions return EOVERFLOW instead 49 // of ERANGE. It's a pointless distinction from standard functions, 50 // so we should change that. Beware the callers though. 51 52 // TODO: more unit tests 48 53 49 54 static inline int _digit_value(int c) … … 69 74 } 70 75 71 static inline int _prefixbase(const char *restrict *nptrptr, bool nonst andard_prefixes)76 static inline int _prefixbase(const char *restrict *nptrptr, bool nonstd) 72 77 { 73 78 const char *nptr = *nptrptr; … … 83 88 } 84 89 85 if (nonst andard_prefixes) {90 if (nonstd) { 86 91 switch (nptr[1]) { 87 92 case 'b': … … 116 121 static inline uintmax_t _strtoumax( 117 122 const char *restrict nptr, char **restrict endptr, int base, 118 bool *restrict sgn, errno_t *err, bool nonst andard_prefixes)123 bool *restrict sgn, errno_t *err, bool nonstd) 119 124 { 120 125 assert(nptr != NULL); … … 144 149 145 150 if (base == 0) 146 base = _prefixbase(&nptr, nonst andard_prefixes);147 148 if (base == 16 && !nonst andard_prefixes) {151 base = _prefixbase(&nptr, nonstd); 152 153 if (base == 16 && !nonstd) { 149 154 /* 150 155 * Standard strto* functions allow hexadecimal prefix to be … … 184 189 __builtin_add_overflow(result * base, digit, &result)) { 185 190 186 *err = ERANGE;191 *err = nonstd ? EOVERFLOW : ERANGE; 187 192 result = UINTMAX_MAX; 188 193 break; … … 212 217 213 218 static inline intmax_t _strtosigned(const char *nptr, char **endptr, int base, 214 intmax_t min, intmax_t max, errno_t *err, bool nonst andard_prefixes)219 intmax_t min, intmax_t max, errno_t *err, bool nonstd) 215 220 { 216 221 bool sgn = false; 217 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, 218 nonstandard_prefixes); 222 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, nonstd); 219 223 220 224 if (number > (uintmax_t) max) { … … 223 227 } 224 228 225 *err = ERANGE;229 *err = nonstd ? EOVERFLOW : ERANGE; 226 230 return (sgn ? min : max); 227 231 } … … 231 235 232 236 static inline uintmax_t _strtounsigned(const char *nptr, char **endptr, int base, 233 uintmax_t max, errno_t *err, bool nonst andard_prefixes)237 uintmax_t max, errno_t *err, bool nonstd) 234 238 { 235 239 bool sgn = false; 236 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, 237 nonstandard_prefixes); 240 uintmax_t number = _strtoumax(nptr, endptr, base, &sgn, err, nonstd); 241 242 if (nonstd && sgn) { 243 /* Do not allow negative values */ 244 *err = EINVAL; 245 return 0; 246 } 238 247 239 248 if (number > max) { 240 *err = ERANGE;249 *err = nonstd ? EOVERFLOW : ERANGE; 241 250 return max; 242 251 } … … 316 325 } 317 326 327 /** Convert string to uint8_t. 328 * 329 * @param nptr Pointer to string. 330 * @param endptr If not NULL, pointer to the first invalid character 331 * is stored here. 332 * @param base Zero or number between 2 and 36 inclusive. 333 * @param strict Do not allow any trailing characters. 334 * @param result Result of the conversion. 335 * 336 * @return EOK if conversion was successful. 337 * 338 */ 339 errno_t str_uint8_t(const char *nptr, const char **endptr, unsigned int base, 340 bool strict, uint8_t *result) 341 { 342 assert(result != NULL); 343 344 errno_t rc = EOK; 345 char *lendptr = (char *) nptr; 346 347 uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT8_MAX, &rc, true); 348 349 if (endptr) 350 *endptr = lendptr; 351 352 if (rc != EOK) 353 return rc; 354 355 if (strict && *lendptr != '\0') 356 return EINVAL; 357 358 *result = r; 359 return EOK; 360 } 361 362 /** Convert string to uint16_t. 363 * 364 * @param nptr Pointer to string. 365 * @param endptr If not NULL, pointer to the first invalid character 366 * is stored here. 367 * @param base Zero or number between 2 and 36 inclusive. 368 * @param strict Do not allow any trailing characters. 369 * @param result Result of the conversion. 370 * 371 * @return EOK if conversion was successful. 372 * 373 */ 374 errno_t str_uint16_t(const char *nptr, const char **endptr, unsigned int base, 375 bool strict, uint16_t *result) 376 { 377 assert(result != NULL); 378 379 errno_t rc = EOK; 380 char *lendptr = (char *) nptr; 381 382 uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT16_MAX, &rc, true); 383 384 if (endptr) 385 *endptr = lendptr; 386 387 if (rc != EOK) 388 return rc; 389 390 if (strict && *lendptr != '\0') 391 return EINVAL; 392 393 *result = r; 394 return EOK; 395 } 396 397 /** Convert string to uint32_t. 398 * 399 * @param nptr Pointer to string. 400 * @param endptr If not NULL, pointer to the first invalid character 401 * is stored here. 402 * @param base Zero or number between 2 and 36 inclusive. 403 * @param strict Do not allow any trailing characters. 404 * @param result Result of the conversion. 405 * 406 * @return EOK if conversion was successful. 407 * 408 */ 409 errno_t str_uint32_t(const char *nptr, const char **endptr, unsigned int base, 410 bool strict, uint32_t *result) 411 { 412 assert(result != NULL); 413 414 errno_t rc = EOK; 415 char *lendptr = (char *) nptr; 416 417 uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT32_MAX, &rc, true); 418 419 if (endptr) 420 *endptr = lendptr; 421 422 if (rc != EOK) 423 return rc; 424 425 if (strict && *lendptr != '\0') 426 return EINVAL; 427 428 *result = r; 429 return EOK; 430 } 431 432 /** Convert string to uint64_t. 433 * 434 * @param nptr Pointer to string. 435 * @param endptr If not NULL, pointer to the first invalid character 436 * is stored here. 437 * @param base Zero or number between 2 and 36 inclusive. 438 * @param strict Do not allow any trailing characters. 439 * @param result Result of the conversion. 440 * 441 * @return EOK if conversion was successful. 442 * 443 */ 444 errno_t str_uint64_t(const char *nptr, const char **endptr, unsigned int base, 445 bool strict, uint64_t *result) 446 { 447 assert(result != NULL); 448 449 errno_t rc = EOK; 450 char *lendptr = (char *) nptr; 451 452 uintmax_t r = _strtounsigned(nptr, &lendptr, base, UINT64_MAX, &rc, true); 453 454 if (endptr) 455 *endptr = lendptr; 456 457 if (rc != EOK) 458 return rc; 459 460 if (strict && *lendptr != '\0') 461 return EINVAL; 462 463 *result = r; 464 return EOK; 465 } 466 467 /** Convert string to int64_t. 468 * 469 * @param nptr Pointer to string. 470 * @param endptr If not NULL, pointer to the first invalid character 471 * is stored here. 472 * @param base Zero or number between 2 and 36 inclusive. 473 * @param strict Do not allow any trailing characters. 474 * @param result Result of the conversion. 475 * 476 * @return EOK if conversion was successful. 477 * 478 */ 479 errno_t str_int64_t(const char *nptr, const char **endptr, unsigned int base, 480 bool strict, int64_t *result) 481 { 482 assert(result != NULL); 483 484 errno_t rc = EOK; 485 char *lendptr = (char *) nptr; 486 487 intmax_t r = _strtosigned(nptr, &lendptr, base, INT64_MIN, INT64_MAX, &rc, true); 488 489 if (endptr) 490 *endptr = lendptr; 491 492 if (rc != EOK) 493 return rc; 494 495 if (strict && *lendptr != '\0') 496 return EINVAL; 497 498 *result = r; 499 return EOK; 500 } 501 502 /** Convert string to size_t. 503 * 504 * @param nptr Pointer to string. 505 * @param endptr If not NULL, pointer to the first invalid character 506 * is stored here. 507 * @param base Zero or number between 2 and 36 inclusive. 508 * @param strict Do not allow any trailing characters. 509 * @param result Result of the conversion. 510 * 511 * @return EOK if conversion was successful. 512 * 513 */ 514 errno_t str_size_t(const char *nptr, const char **endptr, unsigned int base, 515 bool strict, size_t *result) 516 { 517 assert(result != NULL); 518 519 errno_t rc = EOK; 520 char *lendptr = (char *) nptr; 521 522 uintmax_t r = _strtounsigned(nptr, &lendptr, base, SIZE_MAX, &rc, true); 523 524 if (endptr) 525 *endptr = lendptr; 526 527 if (rc != EOK) 528 return rc; 529 530 if (strict && *lendptr != '\0') 531 return EINVAL; 532 533 *result = r; 534 return EOK; 535 } 536 318 537 /** @} 319 538 */
Note:
See TracChangeset
for help on using the changeset viewer.