Commit acb577d6c150370ea17fe5a07bd1361bfa4d18e2

Guillem Jover 2008-06-13T05:25:57

Sync humanize_number from NetBSD Add the missing man page.

diff --git a/man/humanize_number.3 b/man/humanize_number.3
new file mode 100644
index 0000000..90465af
--- /dev/null
+++ b/man/humanize_number.3
@@ -0,0 +1,166 @@
+.\"	$NetBSD: humanize_number.3,v 1.8 2008/04/30 13:10:50 martin Exp $
+.\"
+.\" Copyright (c) 1999, 2002, 2008 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Luke Mewburn and by Tomas Svensson.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd February 9, 2008
+.Dt HUMANIZE_NUMBER 3
+.Os
+.Sh NAME
+.Nm dehumanize_number ,
+.Nm humanize_number
+.Nd format a number into a human readable form and viceversa
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft int
+.Fn dehumanize_number "const char *str" "int64_t *result"
+.Ft int
+.Fn humanize_number "char *buf" "size_t len" "int64_t number" "const char *suffix" "int scale" "int flags"
+.Sh DESCRIPTION
+The
+.Fn humanize_number
+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.
+.Fa buffer
+must be at least
+.Fa len
+bytes long.
+.Pp
+If the formatted number (including
+.Fa suffix )
+would be too long to fit into
+.Fa buffer ,
+then divide
+.Fa number
+by 1024 until it will.
+In this case, prefix
+.Fa suffix
+with the appropriate SI designator.
+.Pp
+The prefixes are:
+.Bl -column "Prefix" "Description" "Multiplier" -offset indent
+.It Sy "Prefix" Ta Sy "Description" Ta Sy "Multiplier"
+.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
+.Fa len
+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 can not be combined with any of the
+.Fa scale
+flags below.
+.Pp
+The following flags may be passed in
+.Pa scale :
+.Bl -tag -width Dv -offset indent
+.It Dv HN_AUTOSCALE
+Format the buffer using the lowest multiplier possible.
+.It Dv HN_GETSCALE
+Return the prefix index number (the number of times
+.Fa number
+must be divided to fit) instead of formatting it to the buffer.
+.El
+.Pp
+The following flags may be passed in
+.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
+Do not put a space between
+.Fa number
+and the prefix.
+.It Dv HN_B
+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
+.Pp
+The
+.Fn dehumanize_number
+function parses the string representing an integral value given in
+.Fa str
+and stores the numerical value in the integer pointed to by
+.Fa result .
+The provided string may hold one of the suffixes, which will be interpreted
+and used to scale up its accompanying numerical value.
+.Sh RETURN VALUES
+.Fn humanize_number
+returns the number of characters stored in
+.Fa buffer
+(excluding the terminating NUL) upon success, or \-1 upon failure.
+If
+.Dv HN_GETSCALE
+is specified, the prefix index number will be returned instead.
+.Pp
+.Fn dehumanize_number
+returns 0 if the string was parsed correctly.
+A \-1 is returned to indicate failure and an error code is stored in
+.Va errno .
+.Sh ERRORS
+.Fn dehumanize_number
+will fail and no number will be stored in
+.Fa result
+if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The string in
+.Fa str
+was empty or carried an unknown suffix.
+.It Bq Er ERANGE
+The string in
+.Fa str
+represented a number that does not fit in
+.Fa result .
+.El
+.Sh SEE ALSO
+.Xr humanize_number 9
+.Sh HISTORY
+.Fn humanize_number
+first appeared in
+.Nx 2.0 .
+.Pp
+.Fn dehumanize_number
+first appeared in
+.Nx 5.0 .
diff --git a/src/humanize_number.c b/src/humanize_number.c
index fe2f45e..f8cf633 100644
--- a/src/humanize_number.c
+++ b/src/humanize_number.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: humanize_number.c,v 1.11 2006/06/08 21:08:56 simonb Exp $	*/
+/*	$NetBSD: humanize_number.c,v 1.14 2008/04/28 20:22:59 martin Exp $	*/
 
 /*
  * Copyright (c) 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
@@ -109,7 +109,12 @@ humanize_number(char *buf, size_t len, int64_t bytes,
 		for (max = 100, i = len - baselen; i-- > 0;)
 			max *= 10;
 
-		for (i = 0; bytes >= max && i < maxscale; i++)
+		/*
+		 * Divide the number until it fits the given column.
+		 * If there will be an overflow by the rounding below,
+		 * divide once more.
+		 */
+		for (i = 0; bytes >= max - 50 && i < maxscale; i++)
 			bytes /= divisor;
 
 		if (scale & HN_GETSCALE)