Read an *integer* INPUT_STR, but return the integer value in a 'long double' VALUE hence, no UINTMAX_MAX limitation. NEGATIVE is updated, and is stored separately from the VALUE so that signbit() isn't required to determine the sign of -0.. ENDPTR is required (unlike strtod) and is used to store a pointer to the character after the last character used in the conversion. Note
| 484 | SSE_OVERFLOW - if more than 33 digits (999Q) were used. |
| 485 | SSE_INVALID_NUMBER - if no digits were found. */ |
| 486 | static enum simple_strtod_error |
| 487 | simple_strtod_int (char const *input_str, |
| 488 | char **endptr, long double *value, bool *negative) |
| 489 | { |
| 490 | enum simple_strtod_error e = SSE_OK; |
| 491 | |
| 492 | long double val = 0; |
| 493 | int digits = 0; |
| 494 | bool found_digit = false; |
| 495 | |
| 496 | if (*input_str == '-') |
| 497 | { |
| 498 | input_str++; |
| 499 | *negative = true; |
| 500 | } |
| 501 | else |
| 502 | *negative = false; |
| 503 | |
| 504 | *endptr = (char *) input_str; |
| 505 | while (c_isdigit (**endptr)) |
| 506 | { |
| 507 | int digit = (**endptr) - '0'; |
| 508 | |
| 509 | found_digit = true; |
| 510 | |
| 511 | if (val || digit) |
| 512 | digits++; |
| 513 | |
| 514 | if (digits > MAX_UNSCALED_DIGITS) |
| 515 | e = SSE_OK_PRECISION_LOSS; |
| 516 | |
| 517 | if (digits > MAX_ACCEPTABLE_DIGITS) |
| 518 | return SSE_OVERFLOW; |
| 519 | |
| 520 | val *= 10; |
| 521 | val += digit; |
| 522 | |
| 523 | ++(*endptr); |
| 524 | |
| 525 | if (thousands_sep_length > 0 |
| 526 | && STREQ_LEN (*endptr, thousands_sep, thousands_sep_length) |
| 527 | && c_isdigit ((*endptr)[thousands_sep_length])) |
| 528 | (*endptr) += thousands_sep_length; |
| 529 | } |
| 530 | if (! found_digit |
| 531 | && ! STREQ_LEN (*endptr, decimal_point, decimal_point_length)) |
| 532 | return SSE_INVALID_NUMBER; |
| 533 | if (*negative) |
| 534 | val = -val; |
| 535 | |
| 536 | if (value) |
| 537 | *value = val; |
| 538 | |
| 539 | return e; |
| 540 | } |
| 541 | |
| 542 | /* Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]", |
| 543 | and return the value in a 'long double' VALUE. |
no outgoing calls
no test coverage detected