]> mj.ucw.cz Git - libucw.git/commitdiff
xtypes&tableprinter: added parsing of size and tests
authorRobert Kessl <kesslr@centrum.cz>
Tue, 22 Jul 2014 12:54:17 +0000 (14:54 +0200)
committerRobert Kessl <kesslr@centrum.cz>
Tue, 22 Jul 2014 12:54:17 +0000 (14:54 +0200)
ucw/Makefile
ucw/table-types.c
ucw/xtypes-test.c [new file with mode: 0644]

index 9a716946a51f667ba71887fd4e9beae24a5879a2..5b62dba0638b8e18adbbbd75d31b747306873ebb 100644 (file)
@@ -136,6 +136,7 @@ $(o)/ucw/opt-test: $(o)/ucw/opt-test.o $(LIBUCW)
 $(o)/ucw/table-test: $(o)/ucw/table-test.o $(LIBUCW)
 $(o)/ucw/table-test-2: $(o)/ucw/table-test-2.o $(LIBUCW)
 $(o)/ucw/table-test-align: $(o)/ucw/table-test-align.o $(LIBUCW)
+$(o)/ucw/xtypes-test: $(o)/ucw/xtypes-test.o $(LIBUCW)
 
 TESTS+=$(addprefix $(o)/ucw/,regex.test unicode.test hash-test.test mempool.test stkstring.test \
     slists.test bbuf.test kmp-test.test getopt.test ff-unicode.test eltpool.test \
@@ -144,7 +145,7 @@ TESTS+=$(addprefix $(o)/ucw/,regex.test unicode.test hash-test.test mempool.test
     fb-mem.test fb-buffer.test fb-mmap.test fb-multi.test fb-null.test \
     redblack-test.test url.test strtonum-test.test \
     gary.test time.test crc.test signames.test md5.test bitops.test opt.test \
-    table.test table-test.test table-test-2.test table-test-align.test)
+    table.test table-test.test table-test-2.test table-test-align.test xtypes-test.test)
 
 $(o)/ucw/varint.test: $(o)/ucw/varint-t
 $(o)/ucw/regex.test: $(o)/ucw/regex-t
@@ -180,6 +181,7 @@ $(o)/ucw/table.test: $(o)/ucw/table-t
 $(o)/ucw/table-test.test: $(o)/ucw/table-test
 $(o)/ucw/table-test-2.test: $(o)/ucw/table-test-2
 $(o)/ucw/table-test-align.test: $(o)/ucw/table-test-align
+$(o)/ucw/xtypes-test.test: $(o)/ucw/xtypes-test
 
 ifdef CONFIG_UCW_THREADS
 TESTS+=$(addprefix $(o)/ucw/,asio.test)
index b5027817c8cee071759dcffab6ed4b016774b479..bcb2abb811ec01b04bfdefb812e090aad5b8901e 100644 (file)
@@ -12,6 +12,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
+#include <errno.h>
 
 /** xt_size **/
 
@@ -23,6 +24,14 @@ static const char *unit_suffix[] = {
   [SIZE_UNIT_TERABYTE] = "TB"
 };
 
+static u64 unit_div[] = {
+  [SIZE_UNIT_BYTE] = 1LLU,
+  [SIZE_UNIT_KILOBYTE] = 1024LLU,
+  [SIZE_UNIT_MEGABYTE] = 1024LLU * 1024LLU,
+  [SIZE_UNIT_GIGABYTE] = 1024LLU * 1024LLU * 1024LLU,
+  [SIZE_UNIT_TERABYTE] = 1024LLU * 1024LLU * 1024LLU * 1024LLU
+};
+
 static const char *xt_size_format(void *src, u32 fmt, struct mempool *pool)
 {
   u64 curr_val = *(u64*) src;
@@ -33,14 +42,6 @@ static const char *xt_size_format(void *src, u32 fmt, struct mempool *pool)
 
   uint out_type = SIZE_UNIT_BYTE;
 
-  static u64 unit_div[] = {
-    [SIZE_UNIT_BYTE] = 1LLU,
-    [SIZE_UNIT_KILOBYTE] = 1024LLU,
-    [SIZE_UNIT_MEGABYTE] = 1024LLU * 1024LLU,
-    [SIZE_UNIT_GIGABYTE] = 1024LLU * 1024LLU * 1024LLU,
-    [SIZE_UNIT_TERABYTE] = 1024LLU * 1024LLU * 1024LLU * 1024LLU
-  };
-
   if(fmt == XTYPE_FMT_DEFAULT) {
     curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
     out_type = SIZE_UNIT_BYTE;
@@ -76,12 +77,39 @@ static const char * xt_size_fmt_parse(const char *opt_str, u32 *dest, struct mem
   return "Unknown option.";
 }
 
+static const char *xt_size_parse(const char *str, void *dest, struct mempool *pool UNUSED)
+{
+  errno = 0;
+  char *units_start = NULL;
+  u64 parsed = strtol(str, &units_start, 10);
+  if(str == units_start) {
+    return mp_printf(pool, "Invalid value of size: '%s'.", str);
+  }
+  if(*units_start == 0) {
+    *(u64*) dest = (u64) parsed;
+    return NULL;
+  }
+
+  if(errno == EINVAL || errno == ERANGE) {
+    return mp_printf(pool, "Invalid value of size: '%s'.", str);
+  }
+
+  for(uint i = 0; i < ARRAY_SIZE(unit_suffix); i++) {
+    if(strcmp(unit_suffix[i], units_start) == 0) {
+      *(u64*) dest = parsed * unit_div[i];
+      return NULL;
+    }
+  }
+
+  return mp_printf(pool, "Invalid format of size: '%s'.", str);
+}
+
 TABLE_COL_BODY(size, u64)
 
 const struct xtype xt_size = {
   .size = sizeof(u64),
   .name = "size",
-  //.parse = xt_size_parse,
+  .parse = xt_size_parse,
   .format = xt_size_format,
   .parse_fmt = xt_size_fmt_parse
 };
diff --git a/ucw/xtypes-test.c b/ucw/xtypes-test.c
new file mode 100644 (file)
index 0000000..75e436b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ *     UCW Library -- Test of Tableprinter Types
+ *
+ *     (c) 2014 Robert Kessl <robert.kessl@economia.cz>
+ *
+ *     This software may be freely distributed and used according to the terms
+ *     of the GNU Lesser General Public License.
+ */
+
+#include <ucw/lib.h>
+#include <ucw/mempool.h>
+#include <ucw/xtypes.h>
+#include <ucw/table-types.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+
+static void test_size_correct(struct fastbuf *out)
+{
+  const char *size_strs[] = {
+    "4",
+    "4KB",
+    "4MB",
+    "4GB",
+    "4TB",
+    NULL
+  };
+
+  u64 size_parsed[] = {
+    4LLU,
+    4 * 1024LLU,
+    4 * 1024LLU * 1024LLU,
+    4 * 1024LLU * 1024LLU * 1024LLU,
+    4 * 1024LLU * 1024LLU * 1024LLU * 1024LLU
+  };
+
+  struct mempool *pool = mp_new(4096);
+
+  uint i = 0;
+  while(size_strs[i] != NULL) {
+    u64 result;
+    const char *parse_err = xt_size.parse(size_strs[i], &result, pool);
+    if(parse_err) {
+      abort();
+    }
+    ASSERT_MSG(size_parsed[i] == result, "xt_size.parse parsed an incorrect value.");
+    const char *result_str = xt_size.format(&result, i | SIZE_UNITS_FIXED, pool);
+    bprintf(out, "%s %s\n", size_strs[i], result_str);
+
+    i++;
+  }
+
+  mp_delete(pool);
+}
+
+static void test_size_parse_errors(struct fastbuf *out)
+{
+  const char *size_strs[] = {
+    "1X",
+    "KB",
+    "\0",
+    NULL
+  };
+
+  uint i = 0;
+  struct mempool *pool = mp_new(4096);
+
+  while(size_strs[i] != NULL) {
+    u64 result;
+    const char *parse_err = xt_size.parse(size_strs[i], &result, pool);
+    if(parse_err == NULL) {
+      bprintf(out, "xt_size.parse did not result in error while parsing: '%s'.\n", size_strs[i]);
+    } else {
+      bprintf(out, "xt_size.parse error: '%s'.\n", parse_err);
+    }
+
+    i++;
+  }
+
+  mp_delete(pool);
+}
+
+int main(void)
+{
+  struct fastbuf *out;
+  out = bfdopen_shared(1, 4096);
+
+  test_size_correct(out);
+  test_size_parse_errors(out);
+
+  bclose(out);
+
+  return 0;
+}