diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-02-09 09:36:37 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2012-02-21 10:21:05 +0100 |
commit | a020f9809cff1cfdb99c64348400cf86a0bbe40a (patch) | |
tree | 845a3708352c0415d7f857b77a068eb96cfc4e44 /qapi/string-input-visitor.c | |
parent | 9f9ab465a504e3b356d9f99fd740bff2870abf24 (diff) |
qapi: add string-based visitors
String based visitors provide a consistent interface for parsing
strings to C values, as well as consuming C values as strings.
They will be used to parse command-line options.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'qapi/string-input-visitor.c')
-rw-r--r-- | qapi/string-input-visitor.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c new file mode 100644 index 0000000000..497eb9a60a --- /dev/null +++ b/qapi/string-input-visitor.c @@ -0,0 +1,138 @@ +/* + * String parsing visitor + * + * Copyright Red Hat, Inc. 2012 + * + * Author: Paolo Bonzini <pbonzini@redhat.com> + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "string-input-visitor.h" +#include "qapi/qapi-visit-impl.h" +#include "qerror.h" + +struct StringInputVisitor +{ + Visitor visitor; + const char *string; +}; + +static void parse_type_int(Visitor *v, int64_t *obj, const char *name, + Error **errp) +{ + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); + char *endp = (char *) siv->string; + long long val; + + errno = 0; + if (siv->string) { + val = strtoll(siv->string, &endp, 0); + } + if (!siv->string || errno || endp == siv->string || *endp) { + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "integer"); + return; + } + + *obj = val; +} + +static void parse_type_bool(Visitor *v, bool *obj, const char *name, + Error **errp) +{ + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); + + if (siv->string) { + if (!strcasecmp(siv->string, "on") || + !strcasecmp(siv->string, "yes") || + !strcasecmp(siv->string, "true")) { + *obj = true; + return; + } + if (!strcasecmp(siv->string, "off") || + !strcasecmp(siv->string, "no") || + !strcasecmp(siv->string, "false")) { + *obj = false; + return; + } + } + + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "boolean"); +} + +static void parse_type_str(Visitor *v, char **obj, const char *name, + Error **errp) +{ + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); + if (siv->string) { + *obj = g_strdup(siv->string); + } else { + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "string"); + } +} + +static void parse_type_number(Visitor *v, double *obj, const char *name, + Error **errp) +{ + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); + char *endp = (char *) siv->string; + double val; + + errno = 0; + if (siv->string) { + val = strtod(siv->string, &endp); + } + if (!siv->string || errno || endp == siv->string || *endp) { + error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "number"); + return; + } + + *obj = val; +} + +static void parse_start_optional(Visitor *v, bool *present, + const char *name, Error **errp) +{ + StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v); + + if (!siv->string) { + *present = false; + return; + } + + *present = true; +} + +Visitor *string_input_get_visitor(StringInputVisitor *v) +{ + return &v->visitor; +} + +void string_input_visitor_cleanup(StringInputVisitor *v) +{ + g_free(v); +} + +StringInputVisitor *string_input_visitor_new(const char *str) +{ + StringInputVisitor *v; + + v = g_malloc0(sizeof(*v)); + + v->visitor.type_enum = input_type_enum; + v->visitor.type_int = parse_type_int; + v->visitor.type_bool = parse_type_bool; + v->visitor.type_str = parse_type_str; + v->visitor.type_number = parse_type_number; + v->visitor.start_optional = parse_start_optional; + + v->string = str; + return v; +} |