qemu/qapi/string-input-visitor.c
<<
>>
Prefs
   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
  18struct StringInputVisitor
  19{
  20    Visitor visitor;
  21    const char *string;
  22};
  23
  24static 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
  44static 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
  68static 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
  80static 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
 100static 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
 113Visitor *string_input_get_visitor(StringInputVisitor *v)
 114{
 115    return &v->visitor;
 116}
 117
 118void string_input_visitor_cleanup(StringInputVisitor *v)
 119{
 120    g_free(v);
 121}
 122
 123StringInputVisitor *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