Copy the human_size() function from common/utils/ into the new
human-size.h header in common/include/. Remove human-size.c and
combine the tests into one.
---
common/include/human-size.h | 51 ++++++++++++++++++
common/include/test-human-size.c | 79 +++++++++++++++++++++++++---
common/utils/Makefile.am | 10 +---
common/utils/human-size.c | 56 --------------------
common/utils/human-size.h | 49 ------------------
common/utils/test-human-size.c | 89 --------------------------------
6 files changed, 126 insertions(+), 208 deletions(-)
diff --git a/common/include/human-size.h b/common/include/human-size.h
index 788dbd7ba5..47729c3c58 100644
--- a/common/include/human-size.h
+++ b/common/include/human-size.h
@@ -134,4 +134,55 @@ human_size_parse (const char *str,
return size * scale;
}
+/* If you allocate a buffer of at least this length in bytes and pass
+ * it as the first parameter to human_size, then it will not overrun.
+ */
+#define HUMAN_SIZE_LONGEST 64
+
+/* Convert bytes to a human-readable string.
+ *
+ * This is roughly the opposite of nbdkit_parse_size. It will convert
+ * multiples of powers of 1024 to the appropriate human size with the
+ * right extension like 'M' or 'G'. Anything that cannot be converted
+ * is returned as bytes. The *human flag is set to true if the output
+ * was abbreviated to a human-readable size, or false if it is just
+ * bytes.
+ *
+ * If buf == NULL, a buffer is allocated and returned. In this case
+ * the returned buffer must be freed.
+ *
+ * buf may also be allocated by the caller, in which case it must be
+ * at least HUMAN_SIZE_LONGEST bytes.
+ *
+ * On error the function returns an error and sets errno.
+ */
+static inline char *
+human_size (char *buf, uint64_t bytes, bool *human)
+{
+ static const char ext[][2] = { "E", "P", "T",
"G", "M", "K", "" };
+ size_t i;
+
+ if (buf == NULL) {
+ buf = malloc (HUMAN_SIZE_LONGEST);
+ if (buf == NULL)
+ return NULL;
+ }
+
+ /* Work out which extension to use, if any. */
+ i = 6;
+ if (bytes != 0) {
+ while ((bytes & 1023) == 0) {
+ bytes >>= 10;
+ i--;
+ }
+ }
+
+ /* Set the flag to true if we're going to add a human-readable extension. */
+ if (human)
+ *human = ext[i][0] != '\0';
+
+ snprintf (buf, HUMAN_SIZE_LONGEST, "%" PRIu64 "%s", bytes,
ext[i]);
+ return buf;
+}
+
#endif /* NBDKIT_HUMAN_SIZE_H */
diff --git a/common/include/test-human-size.c b/common/include/test-human-size.c
index e8cbe7f413..d56186b9da 100644
--- a/common/include/test-human-size.c
+++ b/common/include/test-human-size.c
@@ -36,15 +36,18 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
+#include <string.h>
#include "array-size.h"
#include "human-size.h"
-int
-main (void)
+static unsigned errors = 0;
+
+/* Test the human_size_parse function. */
+static void
+test1 (void)
{
size_t i;
- bool pass = true;
struct pair {
const char *str;
int64_t res;
@@ -119,15 +122,79 @@ main (void)
fprintf (stderr,
"Wrong parse for %s, got %" PRId64 ", expected %"
PRId64 "\n",
pairs[i].str, r, pairs[i].res);
- pass = false;
+ errors++;
}
if (r == -1) {
if (error == NULL || pstr == NULL) {
fprintf (stderr, "Wrong error message handling for %s\n",
pairs[i].str);
- pass = false;
+ errors++;
}
}
}
+}
+
+/* Test the human_size function. */
+static void
+test2_run (uint64_t bytes, const char *expected, bool expected_human_flag)
+{
+ char actual[HUMAN_SIZE_LONGEST];
+ bool actual_human_flag;
+
+ human_size (actual, bytes, &actual_human_flag);
+
+ if (strcmp (actual, expected) == 0 &&
+ actual_human_flag == expected_human_flag) {
+ printf ("test-human-size: %" PRIu64 " -> \"%s\" (%s)
OK\n",
+ bytes, actual, actual_human_flag ? "true" : "false");
+ fflush (stdout);
+ }
+ else {
+ fprintf (stderr,
+ "test-human-size: error: test case %" PRIu64 " "
+ "expected \"%s\" (%s) "
+ "but returned \"%s\" (%s)\n",
+ bytes,
+ expected, expected_human_flag ? "true" : "false",
+ actual, actual_human_flag ? "true" : "false");
+ errors++;
+ }
+}
+
+static void
+test2 (void)
+{
+ test2_run (0, "0", false);
+ test2_run (1, "1", false);
+ test2_run (512, "512", false);
+ test2_run (1023, "1023", false);
+ test2_run (1024, "1K", true);
+ test2_run (1025, "1025", false);
+ test2_run (2047, "2047", false);
+ test2_run (2048, "2K", true);
+ test2_run (3 * 1024, "3K", true);
+
+ test2_run (1023 * 1024, "1023K", true);
+ test2_run (1048575, "1048575", false);
+ test2_run (1048576, "1M", true);
+ test2_run (1048577, "1048577", false);
+
+ test2_run (UINT64_C (1073741824), "1G", true);
+
+ test2_run (UINT64_C (1099511627776), "1T", true);
+ test2_run (UINT64_C (1099511627777), "1099511627777", false);
+ test2_run (UINT64_C (1099511627776) + 1024, "1073741825K", true);
+
+ test2_run (UINT64_C (1125899906842624), "1P", true);
+
+ test2_run ((uint64_t)INT64_MAX+1, "8E", true);
+ test2_run (UINT64_MAX-1023, "18014398509481983K", true);
+ test2_run (UINT64_MAX, "18446744073709551615", false);
+}
- exit (pass ? EXIT_SUCCESS : EXIT_FAILURE);
+int
+main (int argc, char *argv[])
+{
+ test1 ();
+ test2 ();
+ exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am
index a1602fbb58..901d12ad2e 100644
--- a/common/utils/Makefile.am
+++ b/common/utils/Makefile.am
@@ -35,8 +35,6 @@ noinst_LTLIBRARIES = libutils.la
libutils_la_SOURCES = \
const-string-vector.h \
- human-size.c \
- human-size.h \
nbdkit-string.h \
string-vector.h \
vector.c \
@@ -56,12 +54,8 @@ libutils_la_LIBADD = \
# Unit tests.
-TESTS = test-human-size test-vector
-check_PROGRAMS = test-human-size test-vector
-
-test_human_size_SOURCES = test-human-size.c human-size.c human-size.h
-test_human_size_CPPFLAGS = -I$(srcdir)
-test_human_size_CFLAGS = $(WARNINGS_CFLAGS)
+TESTS = test-vector
+check_PROGRAMS = test-vector
test_vector_SOURCES = test-vector.c vector.c vector.h bench.h
test_vector_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)/common/include
diff --git a/common/utils/human-size.c b/common/utils/human-size.c
deleted file mode 100644
index 14d6801318..0000000000
--- a/common/utils/human-size.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* nbd client library in userspace
- * Copyright Red Hat
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <inttypes.h>
-
-#include "human-size.h"
-
-char *
-human_size (char *buf, uint64_t bytes, bool *human)
-{
- static const char ext[][2] = { "E", "P", "T",
"G", "M", "K", "" };
- size_t i;
-
- if (buf == NULL) {
- buf = malloc (HUMAN_SIZE_LONGEST);
- if (buf == NULL)
- return NULL;
- }
-
- /* Work out which extension to use, if any. */
- i = 6;
- if (bytes != 0) {
- while ((bytes & 1023) == 0) {
- bytes >>= 10;
- i--;
- }
- }
-
- /* Set the flag to true if we're going to add a human-readable extension. */
- if (human)
- *human = ext[i][0] != '\0';
-
- snprintf (buf, HUMAN_SIZE_LONGEST, "%" PRIu64 "%s", bytes,
ext[i]);
- return buf;
-}
diff --git a/common/utils/human-size.h b/common/utils/human-size.h
deleted file mode 100644
index 5ab90a0fa3..0000000000
--- a/common/utils/human-size.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* nbd client library in userspace
- * Copyright Red Hat
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef LIBNBD_HUMAN_SIZE_H
-#define LIBNBD_HUMAN_SIZE_H
-
-#include <stdbool.h>
-#include <stdint.h>
-
-/* If you allocate a buffer of at least this length in bytes and pass
- * it as the first parameter to human_size, then it will not overrun.
- */
-#define HUMAN_SIZE_LONGEST 64
-
-/* Convert bytes to a human-readable string.
- *
- * This is roughly the opposite of nbdkit_parse_size. It will convert
- * multiples of powers of 1024 to the appropriate human size with the
- * right extension like 'M' or 'G'. Anything that cannot be converted
- * is returned as bytes. The *human flag is set to true if the output
- * was abbreviated to a human-readable size, or false if it is just
- * bytes.
- *
- * If buf == NULL, a buffer is allocated and returned. In this case
- * the returned buffer must be freed.
- *
- * buf may also be allocated by the caller, in which case it must be
- * at least HUMAN_SIZE_LONGEST bytes.
- *
- * On error the function returns an error and sets errno.
- */
-extern char *human_size (char *buf, uint64_t bytes, bool *human);
-
-#endif /* LIBNBD_HUMAN_SIZE_H */
diff --git a/common/utils/test-human-size.c b/common/utils/test-human-size.c
deleted file mode 100644
index 94210e85f2..0000000000
--- a/common/utils/test-human-size.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* nbd client library in userspace
- * Copyright Red Hat
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-
-#include "human-size.h"
-
-static unsigned errors = 0;
-
-static void
-test (uint64_t bytes, const char *expected, bool expected_human_flag)
-{
- char actual[HUMAN_SIZE_LONGEST];
- bool actual_human_flag;
-
- human_size (actual, bytes, &actual_human_flag);
-
- if (strcmp (actual, expected) == 0 &&
- actual_human_flag == expected_human_flag) {
- printf ("test-human-size: %" PRIu64 " -> \"%s\" (%s)
OK\n",
- bytes, actual, actual_human_flag ? "true" : "false");
- fflush (stdout);
- }
- else {
- fprintf (stderr,
- "test-human-size: error: test case %" PRIu64 " "
- "expected \"%s\" (%s) "
- "but returned \"%s\" (%s)\n",
- bytes,
- expected, expected_human_flag ? "true" : "false",
- actual, actual_human_flag ? "true" : "false");
- errors++;
- }
-}
-
-int
-main (int argc, char *argv[])
-{
- test (0, "0", false);
- test (1, "1", false);
- test (512, "512", false);
- test (1023, "1023", false);
- test (1024, "1K", true);
- test (1025, "1025", false);
- test (2047, "2047", false);
- test (2048, "2K", true);
- test (3 * 1024, "3K", true);
-
- test (1023 * 1024, "1023K", true);
- test (1048575, "1048575", false);
- test (1048576, "1M", true);
- test (1048577, "1048577", false);
-
- test (UINT64_C (1073741824), "1G", true);
-
- test (UINT64_C (1099511627776), "1T", true);
- test (UINT64_C (1099511627777), "1099511627777", false);
- test (UINT64_C (1099511627776) + 1024, "1073741825K", true);
-
- test (UINT64_C (1125899906842624), "1P", true);
-
- test ((uint64_t)INT64_MAX+1, "8E", true);
- test (UINT64_MAX-1023, "18014398509481983K", true);
- test (UINT64_MAX, "18446744073709551615", false);
-
- exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
-}
--
2.41.0