diff options
Diffstat (limited to 'net/openbgpd/files/patch-bgpctl_fmt_scaled.c')
-rw-r--r-- | net/openbgpd/files/patch-bgpctl_fmt_scaled.c | 126 |
1 files changed, 119 insertions, 7 deletions
diff --git a/net/openbgpd/files/patch-bgpctl_fmt_scaled.c b/net/openbgpd/files/patch-bgpctl_fmt_scaled.c index fb39929e296b..66e5b90ef4c9 100644 --- a/net/openbgpd/files/patch-bgpctl_fmt_scaled.c +++ b/net/openbgpd/files/patch-bgpctl_fmt_scaled.c @@ -1,7 +1,7 @@ --- /dev/null 1 Jan 1970 00:00:00 -0000 -+++ bgpctl/fmt_scaled.c 8 Feb 2007 10:32:19 -0000 -@@ -0,0 +1,152 @@ -+/* $OpenBSD: fmt_scaled.c,v 1.8 2005/10/19 18:48:11 deraadt Exp $ */ ++++ bgpctl/fmt_scaled.c 2008-03-18 13:27:29.000000000 +0100 +@@ -0,0 +1,268 @@ ++/* $OpenBSD: fmt_scaled.c,v 1.9 2007/03/20 03:42:52 tedu Exp $ */ + +/* + * Copyright (c) 2001, 2002, 2003 Ian F. Darwin. All rights reserved. @@ -68,6 +68,122 @@ + +#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(*p) && isspace(*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(*p) && (isdigit(*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 */ ++ fpart *= 10; ++ fpart += i; ++ } else { /* normal digit */ ++ if (++ndigits >= MAX_DIGITS) { ++ errno = ERANGE; ++ return -1; ++ } ++ whole *= 10; ++ 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(scale_chars[i])) { ++ ++ /* If it ends with alphanumerics after the scale char, bad. */ ++ if (isalnum(*(p+1))) { ++ errno = EINVAL; ++ return -1; ++ } ++ scale_fact = scale_factors[i]; ++ ++ /* 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; ++ } ++ } ++ errno = ERANGE; ++ 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. @@ -153,7 +269,3 @@ + return 0; +} +#endif -Index: util.h -=================================================================== -RCS file: util.h -diff -N util.h |