$(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 \
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
$(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)
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
+#include <errno.h>
/** xt_size **/
[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;
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;
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
};
--- /dev/null
+/*
+ * 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;
+}