Read a 'human' INPUT_STR represented as "NNNN[.NNNNN] + suffix", and return the value in a 'long double' VALUE, with the precision of the input returned in PRECISION. ENDPTR is required (unlike strtod) and is used to store a pointer to the character after the last character used in the conversion. ALLOWED_SCALING determines the scaling supported. TODO: support locale'd grou
| 630 | SSE_INVALID_SUFFIX |
| 631 | SSE_MISSING_I_SUFFIX */ |
| 632 | static enum simple_strtod_error |
| 633 | simple_strtod_human (char const *input_str, |
| 634 | char **endptr, long double *value, size_t *precision, |
| 635 | enum scale_type allowed_scaling) |
| 636 | { |
| 637 | int power = 0; |
| 638 | /* 'scale_auto' is checked below. */ |
| 639 | int scale_base = default_scale_base (allowed_scaling); |
| 640 | |
| 641 | devmsg ("simple_strtod_human:\n input string: %s\n" |
| 642 | " locale decimal-point: %s\n" |
| 643 | " MAX_UNSCALED_DIGITS: %d\n", |
| 644 | quote_n (0, input_str), |
| 645 | quote_n (1, decimal_point), |
| 646 | MAX_UNSCALED_DIGITS); |
| 647 | |
| 648 | enum simple_strtod_error e = |
| 649 | simple_strtod_float (input_str, endptr, value, precision); |
| 650 | if (e != SSE_OK && e != SSE_OK_PRECISION_LOSS) |
| 651 | return e; |
| 652 | |
| 653 | devmsg (" parsed numeric value: %Lf\n" |
| 654 | " input precision = %d\n", *value, (int)*precision); |
| 655 | |
| 656 | while (**endptr) |
| 657 | { |
| 658 | /* process suffix. */ |
| 659 | |
| 660 | /* Skip a single blank, NBSP or specified unit separator. |
| 661 | Note an explicit empty --unit-sep should disable blank matching. */ |
| 662 | bool matched_unit_sep = false; |
| 663 | if (unit_separator) |
| 664 | { |
| 665 | size_t sep_len = strlen (unit_separator); |
| 666 | if (STREQ_LEN (*endptr, unit_separator, sep_len)) |
| 667 | { |
| 668 | matched_unit_sep = true; |
| 669 | (*endptr) += sep_len; |
| 670 | } |
| 671 | } |
| 672 | if (!matched_unit_sep) |
| 673 | { |
| 674 | mcel_t g = mcel_scanz (*endptr); |
| 675 | if (c32issep (g.ch) || c32isnbspace (g.ch)) |
| 676 | (*endptr) += g.len; |
| 677 | } |
| 678 | |
| 679 | if (**endptr == '\0') |
| 680 | break; /* Treat as no suffix. */ |
| 681 | |
| 682 | if (!valid_suffix (**endptr)) |
| 683 | { |
| 684 | /* Trailing blanks are allowed. */ |
| 685 | *endptr = skip_str_matching (*endptr, newline_or_blank, true); |
| 686 | if (**endptr == '\0') |
| 687 | break; |
| 688 | |
| 689 | return SSE_INVALID_SUFFIX; |
no test coverage detected