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