aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2010-08-15 18:32:06 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2010-08-15 18:32:06 +0000
commita2e0c5ae31d37c8c9fe0ee458fbb93eca35411f8 (patch)
treebce45c4d58bc27285feb085529fb4f9df1227d1e
parentfb26ece72cb35fe66683f57ea3e776a203c407fc (diff)
downloadsrc-a2e0c5ae31d37c8c9fe0ee458fbb93eca35411f8.tar.gz
src-a2e0c5ae31d37c8c9fe0ee458fbb93eca35411f8.zip
Further simplify the code, and update the manpage.
Submitted by: Christoph Mallon <christoph.mallon@gmx.de>
Notes
Notes: svn path=/head/; revision=211343
-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 23e488d3acda..f78223b0a9d0 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 30a292ef64c2..5d55884d9ac5 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);
}