Read a floating-point INPUT_STR represented as "NNNN[.NNNNN]", and return the value in a 'long double' VALUE. ENDPTR is required (unlike strtod) and is used to store a pointer to the character after the last character used in the conversion. PRECISION is optional and used to indicate fractions are present. Note locale'd grouping is not supported, nor is skipping of white-space s
| 554 | SSE_OVERFLOW - if more than 33 digits (999Q) were used. |
| 555 | SSE_INVALID_NUMBER - if no digits were found. */ |
| 556 | static enum simple_strtod_error |
| 557 | simple_strtod_float (char const *input_str, |
| 558 | char **endptr, |
| 559 | long double *value, |
| 560 | size_t *precision) |
| 561 | { |
| 562 | bool negative; |
| 563 | enum simple_strtod_error e = SSE_OK; |
| 564 | |
| 565 | if (precision) |
| 566 | *precision = 0; |
| 567 | |
| 568 | /* TODO: accept locale'd grouped values for the integral part. */ |
| 569 | e = simple_strtod_int (input_str, endptr, value, &negative); |
| 570 | if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS) |
| 571 | return e; |
| 572 | |
| 573 | /* optional decimal point + fraction. */ |
| 574 | if (STREQ_LEN (*endptr, decimal_point, decimal_point_length)) |
| 575 | { |
| 576 | char *ptr2; |
| 577 | long double val_frac = 0; |
| 578 | bool neg_frac; |
| 579 | |
| 580 | (*endptr) += decimal_point_length; |
| 581 | enum simple_strtod_error e2 = |
| 582 | simple_strtod_int (*endptr, &ptr2, &val_frac, &neg_frac); |
| 583 | if (e2 != SSE_OK && e2 != SSE_OK_PRECISION_LOSS) |
| 584 | return e2; |
| 585 | if (e2 == SSE_OK_PRECISION_LOSS) |
| 586 | e = e2; /* propagate warning. */ |
| 587 | if (neg_frac) |
| 588 | return SSE_INVALID_NUMBER; |
| 589 | |
| 590 | /* number of digits in the fractions. */ |
| 591 | size_t exponent = ptr2 - *endptr; |
| 592 | |
| 593 | val_frac = ((long double) val_frac) / powerld (10, exponent); |
| 594 | |
| 595 | /* TODO: detect loss of precision (only really 18 digits |
| 596 | of precision across all digits (before and after '.')). */ |
| 597 | if (value) |
| 598 | { |
| 599 | if (negative) |
| 600 | *value -= val_frac; |
| 601 | else |
| 602 | *value += val_frac; |
| 603 | } |
| 604 | |
| 605 | if (precision) |
| 606 | *precision = exponent; |
| 607 | |
| 608 | *endptr = ptr2; |
| 609 | } |
| 610 | return e; |
| 611 | } |
| 612 | |
| 613 | /* Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix", |
no test coverage detected