1 /* 2 * String parsing visitor 3 * 4 * Copyright Red Hat, Inc. 2012 5 * 6 * Author: Paolo Bonzini <pbonzini@redhat.com> 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 "qapi/string-input-visitor.h" 15 #include "qapi/visitor-impl.h" 16 #include "qapi/qmp/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 } 139