summaryrefslogtreecommitdiffstats
path: root/lib/libutil
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2004-09-25 14:11:34 +0000
committerpjd <pjd@FreeBSD.org>2004-09-25 14:11:34 +0000
commitafbc779ed060e27981f69dae175dd65e3a84af7c (patch)
tree2c89645db72188f54f80d8baa0b23d6a6367274d /lib/libutil
parent9f5e8e56329a2fee389d296bcc060797773f6cdf (diff)
downloadFreeBSD-src-afbc779ed060e27981f69dae175dd65e3a84af7c.zip
FreeBSD-src-afbc779ed060e27981f69dae175dd65e3a84af7c.tar.gz
Take the lastest fixes from NetBSD.
Obtained from: NetBSD
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/humanize_number.346
-rw-r--r--lib/libutil/humanize_number.c114
2 files changed, 70 insertions, 90 deletions
diff --git a/lib/libutil/humanize_number.3 b/lib/libutil/humanize_number.3
index 09ed619..5e1f9ae 100644
--- a/lib/libutil/humanize_number.3
+++ b/lib/libutil/humanize_number.3
@@ -35,7 +35,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd May 25, 2004
+.Dd Sep 25, 2004
.Dt HUMANIZE_NUMBER 3
.Os
.Sh NAME
@@ -53,14 +53,13 @@
.Sh DESCRIPTION
The
.Fn humanize_number
-function formats the signed 64-bit quantity given in
+function formats the signed 64 bit quantity given in
.Fa number
into
.Fa buffer .
A space and then
.Fa suffix
is appended to the end.
-The buffer pointed to by
.Fa buffer
must be at least
.Fa len
@@ -80,30 +79,29 @@ with the appropriate SI designator.
The prefixes are:
.Bl -column "Prefix" "Description" "Multiplier" -offset indent
.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
-.It Li k Ta No kilo Ta 1024
-.It Li M Ta No mega Ta 1048576
-.It Li G Ta No giga Ta 1073741824
-.It Li T Ta No tera Ta 1099511627776
-.It Li P Ta No peta Ta 1125899906842624
-.It Li E Ta No exa Ta 1152921504606846976
+.It k kilo 1024
+.It M mega 1048576
+.It G giga 1073741824
+.It T tera 1099511627776
+.It P peta 1125899906842624
+.It E exa 1152921504606846976
.El
.Pp
-The
.Fa len
-argument must be at least 4 plus the length of
+must be at least 4 plus the length of
.Fa suffix ,
in order to ensure a useful result is generated into
.Fa buffer .
To use a specific prefix, specify this as
.Fa scale
-(multiplier = 1024 ^ scale).
-This cannot be combined with any of the
+(Multiplier = 1024 ^ scale).
+This can not be combined with any of the
.Fa scale
flags below.
.Pp
The following flags may be passed in
-.Fa scale :
-.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
+.Pa scale :
+.Bl -tag -width Dv -offset indent
.It Dv HN_AUTOSCALE
Format the buffer using the lowest multiplier possible.
.It Dv HN_GETSCALE
@@ -113,8 +111,8 @@ must be divided to fit) instead of formatting it to the buffer.
.El
.Pp
The following flags may be passed in
-.Fa flags :
-.Bl -tag -width ".Dv HN_DIVISOR_1000" -offset indent
+.Pa flags :
+.Bl -tag -width Dv -offset indent
.It Dv HN_DECIMAL
If the final result is less than 10, display it using one digit.
.It Dv HN_NOSPACE
@@ -122,27 +120,21 @@ Do not put a space between
.Fa number
and the prefix.
.It Dv HN_B
-Use
-.Ql B
-(bytes) as prefix if the original result does not have a prefix.
+Use 'B' (bytes) as prefix if the original result does not have a prefix.
.It Dv HN_DIVISOR_1000
Divide
.Fa number
with 1000 instead of 1024.
.El
.Sh RETURN VALUES
-The
.Fn humanize_number
-function returns the number of characters stored in
+returns the number of characters stored in
.Fa buffer
-(excluding the terminating
-.Dv NUL )
-upon success, or \-1 upon failure.
+(excluding the terminating NUL) upon success, or \-1 upon failure.
If
.Dv HN_GETSCALE
is specified, the prefix index number will be returned instead.
.Sh HISTORY
-The
.Fn humanize_number
-function first appeared in
+first appeared in
.Nx 2.0 .
diff --git a/lib/libutil/humanize_number.c b/lib/libutil/humanize_number.c
index 51bd24b..21d5e39 100644
--- a/lib/libutil/humanize_number.c
+++ b/lib/libutil/humanize_number.c
@@ -1,4 +1,4 @@
-/* $NetBSD: humanize_number.c,v 1.5 2003/12/26 11:30:36 simonb Exp $ */
+/* $NetBSD: humanize_number.c,v 1.8 2004/07/27 01:56:24 enami Exp $ */
/*
* Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
@@ -52,10 +52,10 @@ int
humanize_number(char *buf, size_t len, int64_t bytes,
const char *suffix, int scale, int flags)
{
- const char *prefixes;
- int i, r;
- int64_t divisor, max, s1, s2, sign;
- size_t baselen, suffixlen;
+ const char *prefixes, *sep;
+ int b, i, r, maxscale, s1, s2, sign;
+ int64_t divisor, max;
+ size_t baselen;
assert(buf != NULL);
assert(suffix != NULL);
@@ -64,18 +64,27 @@ humanize_number(char *buf, size_t len, int64_t bytes,
if (flags & HN_DIVISOR_1000) {
/* SI for decimal multiplies */
divisor = 1000;
- prefixes = " kMGTPE";
+ if (flags & HN_B)
+ prefixes = "B\0k\0M\0G\0T\0P\0E";
+ else
+ prefixes = "\0\0k\0M\0G\0T\0P\0E";
} else {
/*
* binary multiplies
* XXX IEC 60027-2 recommends Ki, Mi, Gi...
*/
divisor = 1024;
- prefixes = " KMGTPE";
+ if (flags & HN_B)
+ prefixes = "B\0K\0M\0G\0T\0P\0E";
+ else
+ prefixes = "\0\0K\0M\0G\0T\0P\0E";
}
- if ((size_t) scale >= strlen(prefixes) && scale != HN_AUTOSCALE &&
- scale != HN_GETSCALE)
+#define SCALE2PREFIX(scale) (&prefixes[(scale) << 1])
+ maxscale = 7;
+
+ if (scale >= maxscale &&
+ (scale & (HN_AUTOSCALE | HN_GETSCALE)) == 0)
return (-1);
if (buf == NULL || suffix == NULL)
@@ -86,75 +95,54 @@ humanize_number(char *buf, size_t len, int64_t bytes,
if (bytes < 0) {
sign = -1;
bytes *= -100;
- baselen = 4;
+ baselen = 3; /* sign, digit, prefix */
} else {
sign = 1;
bytes *= 100;
- baselen = 3;
+ baselen = 2; /* digit, prefix */
}
+ if (flags & HN_NOSPACE)
+ sep = "";
+ else {
+ sep = " ";
+ baselen++;
+ }
+ baselen += strlen(suffix);
- suffixlen = strlen(suffix);
-
- /* check if enough room for `x y' + suffix + `\0' */
- if (len < baselen + suffixlen + 1)
+ /* Check if enough room for `x y' + suffix + `\0' */
+ if (len < baselen + 1)
return (-1);
- if (flags & HN_DIVISOR_1000)
- divisor = 1000;
- else
- divisor = 1024;
-
- max = 100;
- for (i = 0;
- (size_t) i < len - suffixlen - baselen + ((flags & HN_NOSPACE) ?
- 1 : 0); i++)
- max *= 10;
+ if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
+ /* See if there is additional columns can be used. */
+ for (max = 100, i = len - baselen; i-- > 0;)
+ max *= 10;
- if ((scale & HN_AUTOSCALE) || (scale & HN_GETSCALE)) {
- for (i = 0; bytes >= max && prefixes[i + 1]; i++)
+ for (i = 0; bytes >= max && i < maxscale; i++)
bytes /= divisor;
- } else {
- for (i = 0; i < scale && prefixes[i + 1]; i++)
- bytes /= divisor;
- }
- if (scale & HN_GETSCALE)
- return (i);
+ if (scale & HN_GETSCALE)
+ return (i);
+ } else
+ for (i = 0; i < scale && i < maxscale; i++)
+ bytes /= divisor;
- if (bytes < 1000 && flags & HN_DECIMAL) {
- if (len < (baselen + 2 + ((flags & HN_NOSPACE) || (i == 0 &&
- !(flags & HN_B)) ? 0 : 1)))
+ /* If a value <= 9.9 after rounding and ... */
+ if (bytes < 995 && i > 0 && flags & HN_DECIMAL) {
+ /* baselen + \0 + .N */
+ if (len < baselen + 1 + 2)
return (-1);
- s1 = bytes / 100;
- if ((s2 = (((bytes % 100) + 5) / 10)) == 10) {
- s1++;
- s2 = 0;
- }
- if (s1 < 10 && i == 0)
- /* Don't ever use .0 for a number less than 10. */
- r = snprintf(buf, len, "%lld%s%c%s",
- /* LONGLONG */
- (long long)(sign * s1),
- (i == 0 && !(flags & HN_B)) || flags & HN_NOSPACE ?
- "" : " ", (i == 0 && (flags & HN_B)) ? 'B' :
- prefixes[i], suffix);
- else
- r = snprintf(buf, len, "%lld%s%lld%s%c%s",
- /* LONGLONG */
- (long long)(sign * s1),
- localeconv()->decimal_point,
- /* LONGLONG */
- (long long)s2,
- (i == 0 && !(flags & HN_B)) || flags & HN_NOSPACE ?
- "" : " ", (i == 0 && (flags & HN_B)) ? 'B' :
- prefixes[i], suffix);
-
+ b = ((int)bytes + 5) / 10;
+ s1 = b / 10;
+ s2 = b % 10;
+ r = snprintf(buf, len, "%d%s%d%s%s%s",
+ sign * s1, localeconv()->decimal_point, s2,
+ sep, SCALE2PREFIX(i), suffix);
} else
- r = snprintf(buf, len, "%lld%s%c%s",
+ r = snprintf(buf, len, "%lld%s%s%s",
/* LONGLONG */
(long long)(sign * ((bytes + 50) / 100)),
- i == 0 || flags & HN_NOSPACE ? "" : " ", (i == 0 &&
- (flags & HN_B)) ? 'B' : prefixes[i], suffix);
+ sep, SCALE2PREFIX(i), suffix);
return (r);
}
OpenPOWER on IntegriCloud