Commit Diff


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.