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