commit ebd3fc9d15ad0d629bba5910c9719d061c785127 from: Omar Polo date: Wed Jun 23 08:43:03 2021 UTC kill unused scan_scaled commit - 0e1eff5b95f2e5962b8941fe706d320a7eca469b commit + ebd3fc9d15ad0d629bba5910c9719d061c785127 blob - e4cb402b1b1ebfea020505a9d210f9c31fef15fc blob + 1b2d5f59da6911eb007cd5a1fae0d58fc2fce889 --- compat/fmt_scaled.c +++ compat/fmt_scaled.c @@ -65,148 +65,6 @@ static const long long scale_factors[] = { #define MAX_DIGITS (SCALE_LENGTH * 3) /* XXX strlen(sprintf("%lld", -1)? */ -/* Convert the given input string "scaled" into numeric in "result". - * Return 0 on success, -1 and errno set on error. - */ -int -scan_scaled(char *scaled, long long *result) -{ - char *p = scaled; - int sign = 0; - unsigned int i, ndigits = 0, fract_digits = 0; - long long scale_fact = 1, whole = 0, fpart = 0; - - /* Skip leading whitespace */ - while (isascii((unsigned char)*p) && isspace((unsigned char)*p)) - ++p; - - /* Then at most one leading + or - */ - while (*p == '-' || *p == '+') { - if (*p == '-') { - if (sign) { - errno = EINVAL; - return -1; - } - sign = -1; - ++p; - } else if (*p == '+') { - if (sign) { - errno = EINVAL; - return -1; - } - sign = +1; - ++p; - } - } - - /* Main loop: Scan digits, find decimal point, if present. - * We don't allow exponentials, so no scientific notation - * (but note that E for Exa might look like e to some!). - * Advance 'p' to end, to get scale factor. - */ - for (; isascii((unsigned char)*p) && - (isdigit((unsigned char)*p) || *p=='.'); ++p) { - if (*p == '.') { - if (fract_digits > 0) { /* oops, more than one '.' */ - errno = EINVAL; - return -1; - } - fract_digits = 1; - continue; - } - - i = (*p) - '0'; /* whew! finally a digit we can use */ - if (fract_digits > 0) { - if (fract_digits >= MAX_DIGITS-1) - /* ignore extra fractional digits */ - continue; - fract_digits++; /* for later scaling */ - if (fpart > LLONG_MAX / 10) { - errno = ERANGE; - return -1; - } - fpart *= 10; - if (i > LLONG_MAX - fpart) { - errno = ERANGE; - return -1; - } - fpart += i; - } else { /* normal digit */ - if (++ndigits >= MAX_DIGITS) { - errno = ERANGE; - return -1; - } - if (whole > LLONG_MAX / 10) { - errno = ERANGE; - return -1; - } - whole *= 10; - if (i > LLONG_MAX - whole) { - errno = ERANGE; - return -1; - } - whole += i; - } - } - - if (sign) { - whole *= sign; - fpart *= sign; - } - - /* If no scale factor given, we're done. fraction is discarded. */ - if (!*p) { - *result = whole; - return 0; - } - - /* Validate scale factor, and scale whole and fraction by it. */ - for (i = 0; i < SCALE_LENGTH; i++) { - - /* Are we there yet? */ - if (*p == scale_chars[i] || - *p == tolower((unsigned char)scale_chars[i])) { - - /* If it ends with alphanumerics after the scale char, bad. */ - if (isalnum((unsigned char)*(p+1))) { - errno = EINVAL; - return -1; - } - scale_fact = scale_factors[i]; - - /* check for overflow and underflow after scaling */ - if (whole > LLONG_MAX / scale_fact || - whole < LLONG_MIN / scale_fact) { - errno = ERANGE; - return -1; - } - - /* scale whole part */ - whole *= scale_fact; - - /* truncate fpart so it does't overflow. - * then scale fractional part. - */ - while (fpart >= LLONG_MAX / scale_fact) { - fpart /= 10; - fract_digits--; - } - fpart *= scale_fact; - if (fract_digits > 0) { - for (i = 0; i < fract_digits -1; i++) - fpart /= 10; - } - whole += fpart; - *result = whole; - return 0; - } - } - - /* Invalid unit or character */ - errno = EINVAL; - return -1; -} - /* Format the given "number" into human-readable form in "result". * Result must point to an allocated buffer of length FMT_SCALED_STRSIZE. * Return 0 on success, -1 and errno set if error.