From: Robert Kessl Date: Tue, 22 Jul 2014 12:54:17 +0000 (+0200) Subject: xtypes&tableprinter: added parsing of size and tests X-Git-Tag: v6.1~3^2~67 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=a7b91de90e7c0a8b6aded23913bd80f47e0bcdc9;p=libucw.git xtypes&tableprinter: added parsing of size and tests --- diff --git a/ucw/Makefile b/ucw/Makefile index 9a716946..5b62dba0 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -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) diff --git a/ucw/table-types.c b/ucw/table-types.c index b5027817..bcb2abb8 100644 --- a/ucw/table-types.c +++ b/ucw/table-types.c @@ -12,6 +12,7 @@ #include #include #include +#include /** 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 index 00000000..75e436b5 --- /dev/null +++ b/ucw/xtypes-test.c @@ -0,0 +1,96 @@ +/* + * UCW Library -- Test of Tableprinter Types + * + * (c) 2014 Robert Kessl + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include +#include +#include +#include + +#include +#include +#include + + +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; +}