summaryrefslogtreecommitdiffstats
path: root/lib/libutil
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2010-08-15 18:32:06 +0000
committerdes <des@FreeBSD.org>2010-08-15 18:32:06 +0000
commit3338010b29aee1ea1d5b28973d9b981dc7e4a15a (patch)
treebce45c4d58bc27285feb085529fb4f9df1227d1e /lib/libutil
parentf407cc3b8bf18a19de0375c20d6ab712bab4f21d (diff)
downloadFreeBSD-src-3338010b29aee1ea1d5b28973d9b981dc7e4a15a.zip
FreeBSD-src-3338010b29aee1ea1d5b28973d9b981dc7e4a15a.tar.gz
Further simplify the code, and update the manpage.
Submitted by: Christoph Mallon <christoph.mallon@gmx.de>
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/expand_number.36
-rw-r--r--lib/libutil/expand_number.c47
2 files changed, 27 insertions, 26 deletions
diff --git a/lib/libutil/expand_number.3 b/lib/libutil/expand_number.3
index 23e488d..f78223b 100644
--- a/lib/libutil/expand_number.3
+++ b/lib/libutil/expand_number.3
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 16, 2007
+.Dd August 15, 2010
.Dt EXPAND_NUMBER 3
.Os
.Sh NAME
@@ -37,14 +37,14 @@
.In libutil.h
.Ft int
.Fo expand_number
-.Fa "const char *buf" "int64_t *num"
+.Fa "const char *buf" "uint64_t *num"
.Fc
.Sh DESCRIPTION
The
.Fn expand_number
function unformats the
.Fa buf
-string and stores a signed 64-bit quantity at address pointed out by the
+string and stores a unsigned 64-bit quantity at address pointed out by the
.Fa num
argument.
.Pp
diff --git a/lib/libutil/expand_number.c b/lib/libutil/expand_number.c
index 30a292e..5d55884 100644
--- a/lib/libutil/expand_number.c
+++ b/lib/libutil/expand_number.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <stdint.h>
/*
- * Convert an expression of the following forms to a int64_t.
+ * Convert an expression of the following forms to a uint64_t.
* 1) A positive decimal number.
* 2) A positive decimal number followed by a 'b' or 'B' (mult by 1).
* 3) A positive decimal number followed by a 'k' or 'K' (mult by 1 << 10).
@@ -50,6 +50,7 @@ int
expand_number(const char *buf, uint64_t *num)
{
uint64_t number;
+ unsigned shift;
char *endptr;
number = strtoumax(buf, &endptr, 0);
@@ -60,41 +61,41 @@ expand_number(const char *buf, uint64_t *num)
return (-1);
}
- if (*endptr == '\0') {
- /* No unit. */
- *num = number;
- return (0);
- }
-
-#define SHIFT(n, b) \
- do { if (((n << b) >> b) != n) goto overflow; n <<= b; } while (0)
-
switch (tolower((unsigned char)*endptr)) {
case 'e':
- SHIFT(number, 10);
+ shift = 60;
+ break;
case 'p':
- SHIFT(number, 10);
+ shift = 50;
+ break;
case 't':
- SHIFT(number, 10);
+ shift = 40;
+ break;
case 'g':
- SHIFT(number, 10);
+ shift = 30;
+ break;
case 'm':
- SHIFT(number, 10);
+ shift = 20;
+ break;
case 'k':
- SHIFT(number, 10);
- case 'b':
+ shift = 10;
break;
+ case 'b':
+ case '\0': /* No unit. */
+ *num = number;
+ return (0);
default:
/* Unrecognized unit. */
errno = EINVAL;
return (-1);
}
- *num = number;
- return (0);
+ if ((number << shift) >> shift != number) {
+ /* Overflow */
+ errno = ERANGE;
+ return (-1);
+ }
-overflow:
- /* Overflow */
- errno = ERANGE;
- return (-1);
+ *num = number << shift;
+ return (0);
}
OpenPOWER on IntegriCloud