Statistics
| Branch: | Revision:

root / qapi / string-input-visitor.c @ 7c9958b0

History | View | Annotate | Download (3.4 kB)

1 a020f980 Paolo Bonzini
/*
2 a020f980 Paolo Bonzini
 * String parsing visitor
3 a020f980 Paolo Bonzini
 *
4 a020f980 Paolo Bonzini
 * Copyright Red Hat, Inc. 2012
5 a020f980 Paolo Bonzini
 *
6 a020f980 Paolo Bonzini
 * Author: Paolo Bonzini <pbonzini@redhat.com>
7 a020f980 Paolo Bonzini
 *
8 a020f980 Paolo Bonzini
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
9 a020f980 Paolo Bonzini
 * See the COPYING.LIB file in the top-level directory.
10 a020f980 Paolo Bonzini
 *
11 a020f980 Paolo Bonzini
 */
12 a020f980 Paolo Bonzini
13 a020f980 Paolo Bonzini
#include "qemu-common.h"
14 a020f980 Paolo Bonzini
#include "string-input-visitor.h"
15 a020f980 Paolo Bonzini
#include "qapi/qapi-visit-impl.h"
16 a020f980 Paolo Bonzini
#include "qerror.h"
17 a020f980 Paolo Bonzini
18 a020f980 Paolo Bonzini
struct StringInputVisitor
19 a020f980 Paolo Bonzini
{
20 a020f980 Paolo Bonzini
    Visitor visitor;
21 a020f980 Paolo Bonzini
    const char *string;
22 a020f980 Paolo Bonzini
};
23 a020f980 Paolo Bonzini
24 a020f980 Paolo Bonzini
static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
25 a020f980 Paolo Bonzini
                           Error **errp)
26 a020f980 Paolo Bonzini
{
27 a020f980 Paolo Bonzini
    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
28 a020f980 Paolo Bonzini
    char *endp = (char *) siv->string;
29 a020f980 Paolo Bonzini
    long long val;
30 a020f980 Paolo Bonzini
31 a020f980 Paolo Bonzini
    errno = 0;
32 a020f980 Paolo Bonzini
    if (siv->string) {
33 a020f980 Paolo Bonzini
        val = strtoll(siv->string, &endp, 0);
34 a020f980 Paolo Bonzini
    }
35 a020f980 Paolo Bonzini
    if (!siv->string || errno || endp == siv->string || *endp) {
36 a020f980 Paolo Bonzini
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
37 a020f980 Paolo Bonzini
                  "integer");
38 a020f980 Paolo Bonzini
        return;
39 a020f980 Paolo Bonzini
    }
40 a020f980 Paolo Bonzini
41 a020f980 Paolo Bonzini
    *obj = val;
42 a020f980 Paolo Bonzini
}
43 a020f980 Paolo Bonzini
44 a020f980 Paolo Bonzini
static void parse_type_bool(Visitor *v, bool *obj, const char *name,
45 a020f980 Paolo Bonzini
                            Error **errp)
46 a020f980 Paolo Bonzini
{
47 a020f980 Paolo Bonzini
    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
48 a020f980 Paolo Bonzini
49 a020f980 Paolo Bonzini
    if (siv->string) {
50 a020f980 Paolo Bonzini
        if (!strcasecmp(siv->string, "on") ||
51 a020f980 Paolo Bonzini
            !strcasecmp(siv->string, "yes") ||
52 a020f980 Paolo Bonzini
            !strcasecmp(siv->string, "true")) {
53 a020f980 Paolo Bonzini
            *obj = true;
54 a020f980 Paolo Bonzini
            return;
55 a020f980 Paolo Bonzini
        }
56 a020f980 Paolo Bonzini
        if (!strcasecmp(siv->string, "off") ||
57 a020f980 Paolo Bonzini
            !strcasecmp(siv->string, "no") ||
58 a020f980 Paolo Bonzini
            !strcasecmp(siv->string, "false")) {
59 a020f980 Paolo Bonzini
            *obj = false;
60 a020f980 Paolo Bonzini
            return;
61 a020f980 Paolo Bonzini
        }
62 a020f980 Paolo Bonzini
    }
63 a020f980 Paolo Bonzini
64 a020f980 Paolo Bonzini
    error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
65 a020f980 Paolo Bonzini
              "boolean");
66 a020f980 Paolo Bonzini
}
67 a020f980 Paolo Bonzini
68 a020f980 Paolo Bonzini
static void parse_type_str(Visitor *v, char **obj, const char *name,
69 a020f980 Paolo Bonzini
                           Error **errp)
70 a020f980 Paolo Bonzini
{
71 a020f980 Paolo Bonzini
    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
72 a020f980 Paolo Bonzini
    if (siv->string) {
73 a020f980 Paolo Bonzini
        *obj = g_strdup(siv->string);
74 a020f980 Paolo Bonzini
    } else {
75 a020f980 Paolo Bonzini
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
76 a020f980 Paolo Bonzini
                  "string");
77 a020f980 Paolo Bonzini
    }
78 a020f980 Paolo Bonzini
}
79 a020f980 Paolo Bonzini
80 a020f980 Paolo Bonzini
static void parse_type_number(Visitor *v, double *obj, const char *name,
81 a020f980 Paolo Bonzini
                              Error **errp)
82 a020f980 Paolo Bonzini
{
83 a020f980 Paolo Bonzini
    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
84 a020f980 Paolo Bonzini
    char *endp = (char *) siv->string;
85 a020f980 Paolo Bonzini
    double val;
86 a020f980 Paolo Bonzini
87 a020f980 Paolo Bonzini
    errno = 0;
88 a020f980 Paolo Bonzini
    if (siv->string) {
89 a020f980 Paolo Bonzini
        val = strtod(siv->string, &endp);
90 a020f980 Paolo Bonzini
    }
91 a020f980 Paolo Bonzini
    if (!siv->string || errno || endp == siv->string || *endp) {
92 a020f980 Paolo Bonzini
        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
93 a020f980 Paolo Bonzini
                  "number");
94 a020f980 Paolo Bonzini
        return;
95 a020f980 Paolo Bonzini
    }
96 a020f980 Paolo Bonzini
97 a020f980 Paolo Bonzini
    *obj = val;
98 a020f980 Paolo Bonzini
}
99 a020f980 Paolo Bonzini
100 a020f980 Paolo Bonzini
static void parse_start_optional(Visitor *v, bool *present,
101 a020f980 Paolo Bonzini
                                 const char *name, Error **errp)
102 a020f980 Paolo Bonzini
{
103 a020f980 Paolo Bonzini
    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
104 a020f980 Paolo Bonzini
105 a020f980 Paolo Bonzini
    if (!siv->string) {
106 a020f980 Paolo Bonzini
        *present = false;
107 a020f980 Paolo Bonzini
        return;
108 a020f980 Paolo Bonzini
    }
109 a020f980 Paolo Bonzini
110 a020f980 Paolo Bonzini
    *present = true;
111 a020f980 Paolo Bonzini
}
112 a020f980 Paolo Bonzini
113 a020f980 Paolo Bonzini
Visitor *string_input_get_visitor(StringInputVisitor *v)
114 a020f980 Paolo Bonzini
{
115 a020f980 Paolo Bonzini
    return &v->visitor;
116 a020f980 Paolo Bonzini
}
117 a020f980 Paolo Bonzini
118 a020f980 Paolo Bonzini
void string_input_visitor_cleanup(StringInputVisitor *v)
119 a020f980 Paolo Bonzini
{
120 a020f980 Paolo Bonzini
    g_free(v);
121 a020f980 Paolo Bonzini
}
122 a020f980 Paolo Bonzini
123 a020f980 Paolo Bonzini
StringInputVisitor *string_input_visitor_new(const char *str)
124 a020f980 Paolo Bonzini
{
125 a020f980 Paolo Bonzini
    StringInputVisitor *v;
126 a020f980 Paolo Bonzini
127 a020f980 Paolo Bonzini
    v = g_malloc0(sizeof(*v));
128 a020f980 Paolo Bonzini
129 a020f980 Paolo Bonzini
    v->visitor.type_enum = input_type_enum;
130 a020f980 Paolo Bonzini
    v->visitor.type_int = parse_type_int;
131 a020f980 Paolo Bonzini
    v->visitor.type_bool = parse_type_bool;
132 a020f980 Paolo Bonzini
    v->visitor.type_str = parse_type_str;
133 a020f980 Paolo Bonzini
    v->visitor.type_number = parse_type_number;
134 a020f980 Paolo Bonzini
    v->visitor.start_optional = parse_start_optional;
135 a020f980 Paolo Bonzini
136 a020f980 Paolo Bonzini
    v->string = str;
137 a020f980 Paolo Bonzini
    return v;
138 a020f980 Paolo Bonzini
}