X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=ucw%2Fxtypes-basic.c;h=26d7cb1f54b191ac64cdbcd2014573d83ed09a73;hb=b8667492cf36a609939ee35ac42900ff0b0cc80f;hp=5d149b6f54d8a29ff271515c1acbe323867d36c9;hpb=9cae0f5365827339bcd72d101ccab3b34971b8c2;p=libucw.git diff --git a/ucw/xtypes-basic.c b/ucw/xtypes-basic.c index 5d149b6f..26d7cb1f 100644 --- a/ucw/xtypes-basic.c +++ b/ucw/xtypes-basic.c @@ -13,8 +13,8 @@ #include #include #include -#include #include +#include #define XTYPE_NUM_FORMAT(_type, _fmt, _typename) static const char *xt_##_typename##_format(void *src, u32 fmt UNUSED, struct mempool *pool) \ {\ @@ -48,28 +48,47 @@ XTYPE_NUM_DEF(uintmax_t, "%ju", uintmax) static const char *xt_double_format(void *src, u32 fmt, struct mempool *pool) { - switch(fmt) { - case XTYPE_FMT_RAW: - return mp_printf(pool, "%.10lf", *(double *)src); - case XTYPE_FMT_PRETTY: - return mp_printf(pool, "%.2lf", *(double *)src); - case XTYPE_FMT_DEFAULT: - default: - return mp_printf(pool, "%.5lf", *(double *)src); - } + double val = *((double *)src); + + if (fmt & XT_DOUBLE_FMT_PREC_FLAG) + { + uint prec = fmt & ~XT_DOUBLE_FMT_PREC_FLAG; + return mp_printf(pool, "%.*lf", prec, val); + } + + switch(fmt) + { + case XTYPE_FMT_RAW: + return mp_printf(pool, "%.15lg", val); + case XTYPE_FMT_PRETTY: + return mp_printf(pool, "%.2lf", val); + case XTYPE_FMT_DEFAULT: + default: + return mp_printf(pool, "%.6lg", val); + } } static const char *xt_double_parse(const char *str, void *dest, struct mempool *pool UNUSED) { char *endptr = NULL; - size_t sz = strlen(str); errno = 0; double result = strtod(str, &endptr); - if(endptr != str + sz) return "Could not parse double"; - if(errno == ERANGE) return "Could not parse double: overflow happend during parsing"; + if (*endptr != 0 || endptr == str || + errno == ERANGE) + return "Could not parse floating point number."; *((double *) dest) = result; + return NULL; +} + +static const char * xt_double_fmt_parse(const char *str, u32 *dest, struct mempool *pool) +{ + uint precision = 0; + const char *tmp_err = str_to_uint(&precision, str, NULL, 0); + if (tmp_err) + return mp_printf(pool, "Could not parse floating point number precision: %s", tmp_err); + *dest = XT_DOUBLE_FMT_PREC(precision); return NULL; } @@ -78,72 +97,54 @@ const struct xtype xt_double = { .name = "double", .parse = xt_double_parse, .format = xt_double_format, + .parse_fmt = xt_double_fmt_parse }; /* bool */ -static const char *xt_bool_format(void *src, u32 fmt UNUSED, struct mempool *pool) +static const char *xt_bool_format(void *src, u32 fmt UNUSED, struct mempool *pool UNUSED) { - switch(fmt) { - case XTYPE_FMT_DEFAULT: + bool val = *((bool *)src); + switch (fmt) + { case XTYPE_FMT_PRETTY: - return mp_printf(pool, "%s", *((bool *)src) ? "true" : "false"); + return val ? "true" : "false"; + case XTYPE_FMT_DEFAULT: case XTYPE_FMT_RAW: - return mp_printf(pool, "%s", *((bool *)src) ? "1" : "0"); default: - die("Unsupported output type."); - } + return val ? "1" : "0"; + } } static const char *xt_bool_parse(const char *str, void *dest, struct mempool *pool UNUSED) { - if(str[1] == 0) { - if(str[0] == '1') { + if (!strcmp(str, "0") || !strcmp(str, "false") || !strcmp(str, "no")) + { *((bool *)dest) = false; return NULL; } - if(str[0] == '1') { + else if (!strcmp(str, "1") || !strcmp(str, "true") || !strcmp(str, "yes")) + { *((bool *)dest) = true; return NULL; } - } - - if(strcasecmp(str, "false") == 0) { - *((bool *)dest) = false; - return NULL; - } - - if(strcasecmp(str, "true") == 0) { - *((bool *)dest) = true; - return NULL; - } - return "Could not parse bool"; + return "Could not parse a boolean value."; } -const struct xtype xt_bool = { - .size = sizeof(bool), - .name = "bool", - .parse = xt_bool_parse, - .format = xt_bool_format, -}; +XTYPE_NUM_STRUCT(bool, bool) /* str */ static const char *xt_str_format(void *src, u32 fmt UNUSED, struct mempool *pool) { - return mp_strdup(pool, (const char *) src); + return mp_strdup(pool, *((const char **) src)); } -static const char *xt_str_parse(const char *str, void *dest, struct mempool *pool UNUSED) +static const char *xt_str_parse(const char *str, void *dest, struct mempool *pool) { - *((const char **) dest) = str; + *((const char **) dest) = mp_strdup(pool, str); return NULL; } -const struct xtype xt_str = { - .size = sizeof(char *), - .name = "str", - .parse = xt_str_parse, - .format = xt_str_format, -}; +XTYPE_NUM_STRUCT(char *, str)