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 | } |