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 | |
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')
-rw-r--r-- | qapi/string-input-visitor.c | 138 | ||||
-rw-r--r-- | qapi/string-input-visitor.h | 25 | ||||
-rw-r--r-- | qapi/string-output-visitor.c | 89 | ||||
-rw-r--r-- | qapi/string-output-visitor.h | 26 |
4 files changed, 278 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; +} diff --git a/qapi/string-input-visitor.h b/qapi/string-input-visitor.h new file mode 100644 index 0000000000..d269d42cef --- /dev/null +++ b/qapi/string-input-visitor.h @@ -0,0 +1,25 @@ +/* + * 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. + * + */ + +#ifndef STRING_INPUT_VISITOR_H +#define STRING_INPUT_VISITOR_H + +#include "qapi-visit-core.h" + +typedef struct StringInputVisitor StringInputVisitor; + +StringInputVisitor *string_input_visitor_new(const char *str); +void string_input_visitor_cleanup(StringInputVisitor *v); + +Visitor *string_input_get_visitor(StringInputVisitor *v); + +#endif diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c new file mode 100644 index 0000000000..92b0305212 --- /dev/null +++ b/qapi/string-output-visitor.c @@ -0,0 +1,89 @@ +/* + * String printing 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-output-visitor.h" +#include "qapi/qapi-visit-impl.h" +#include "qerror.h" + +struct StringOutputVisitor +{ + Visitor visitor; + char *string; +}; + +static void string_output_set(StringOutputVisitor *sov, char *string) +{ + g_free(sov->string); + sov->string = string; +} + +static void print_type_int(Visitor *v, int64_t *obj, const char *name, + Error **errp) +{ + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v); + string_output_set(sov, g_strdup_printf("%lld", (long long) *obj)); +} + +static void print_type_bool(Visitor *v, bool *obj, const char *name, + Error **errp) +{ + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v); + string_output_set(sov, g_strdup(*obj ? "true" : "false")); +} + +static void print_type_str(Visitor *v, char **obj, const char *name, + Error **errp) +{ + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v); + string_output_set(sov, g_strdup(*obj ? *obj : "")); +} + +static void print_type_number(Visitor *v, double *obj, const char *name, + Error **errp) +{ + StringOutputVisitor *sov = DO_UPCAST(StringOutputVisitor, visitor, v); + string_output_set(sov, g_strdup_printf("%g", *obj)); +} + +char *string_output_get_string(StringOutputVisitor *sov) +{ + char *string = sov->string; + sov->string = NULL; + return string; +} + +Visitor *string_output_get_visitor(StringOutputVisitor *sov) +{ + return &sov->visitor; +} + +void string_output_visitor_cleanup(StringOutputVisitor *sov) +{ + g_free(sov->string); + g_free(sov); +} + +StringOutputVisitor *string_output_visitor_new(void) +{ + StringOutputVisitor *v; + + v = g_malloc0(sizeof(*v)); + + v->visitor.type_enum = output_type_enum; + v->visitor.type_int = print_type_int; + v->visitor.type_bool = print_type_bool; + v->visitor.type_str = print_type_str; + v->visitor.type_number = print_type_number; + + return v; +} diff --git a/qapi/string-output-visitor.h b/qapi/string-output-visitor.h new file mode 100644 index 0000000000..8868454110 --- /dev/null +++ b/qapi/string-output-visitor.h @@ -0,0 +1,26 @@ +/* + * String printing 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. + * + */ + +#ifndef STRING_OUTPUT_VISITOR_H +#define STRING_OUTPUT_VISITOR_H + +#include "qapi-visit-core.h" + +typedef struct StringOutputVisitor StringOutputVisitor; + +StringOutputVisitor *string_output_visitor_new(void); +void string_output_visitor_cleanup(StringOutputVisitor *v); + +char *string_output_get_string(StringOutputVisitor *v); +Visitor *string_output_get_visitor(StringOutputVisitor *v); + +#endif |