string-input-visitor.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. #include "qemu-common.h"
  13. #include "string-input-visitor.h"
  14. #include "qapi/qapi-visit-impl.h"
  15. #include "qerror.h"
  16. struct StringInputVisitor
  17. {
  18. Visitor visitor;
  19. const char *string;
  20. };
  21. static void parse_type_int(Visitor *v, int64_t *obj, const char *name,
  22. Error **errp)
  23. {
  24. StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
  25. char *endp = (char *) siv->string;
  26. long long val;
  27. errno = 0;
  28. if (siv->string) {
  29. val = strtoll(siv->string, &endp, 0);
  30. }
  31. if (!siv->string || errno || endp == siv->string || *endp) {
  32. error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
  33. "integer");
  34. return;
  35. }
  36. *obj = val;
  37. }
  38. static void parse_type_bool(Visitor *v, bool *obj, const char *name,
  39. Error **errp)
  40. {
  41. StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
  42. if (siv->string) {
  43. if (!strcasecmp(siv->string, "on") ||
  44. !strcasecmp(siv->string, "yes") ||
  45. !strcasecmp(siv->string, "true")) {
  46. *obj = true;
  47. return;
  48. }
  49. if (!strcasecmp(siv->string, "off") ||
  50. !strcasecmp(siv->string, "no") ||
  51. !strcasecmp(siv->string, "false")) {
  52. *obj = false;
  53. return;
  54. }
  55. }
  56. error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
  57. "boolean");
  58. }
  59. static void parse_type_str(Visitor *v, char **obj, const char *name,
  60. Error **errp)
  61. {
  62. StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
  63. if (siv->string) {
  64. *obj = g_strdup(siv->string);
  65. } else {
  66. error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
  67. "string");
  68. }
  69. }
  70. static void parse_type_number(Visitor *v, double *obj, const char *name,
  71. Error **errp)
  72. {
  73. StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
  74. char *endp = (char *) siv->string;
  75. double val;
  76. errno = 0;
  77. if (siv->string) {
  78. val = strtod(siv->string, &endp);
  79. }
  80. if (!siv->string || errno || endp == siv->string || *endp) {
  81. error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
  82. "number");
  83. return;
  84. }
  85. *obj = val;
  86. }
  87. static void parse_start_optional(Visitor *v, bool *present,
  88. const char *name, Error **errp)
  89. {
  90. StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
  91. if (!siv->string) {
  92. *present = false;
  93. return;
  94. }
  95. *present = true;
  96. }
  97. Visitor *string_input_get_visitor(StringInputVisitor *v)
  98. {
  99. return &v->visitor;
  100. }
  101. void string_input_visitor_cleanup(StringInputVisitor *v)
  102. {
  103. g_free(v);
  104. }
  105. StringInputVisitor *string_input_visitor_new(const char *str)
  106. {
  107. StringInputVisitor *v;
  108. v = g_malloc0(sizeof(*v));
  109. v->visitor.type_enum = input_type_enum;
  110. v->visitor.type_int = parse_type_int;
  111. v->visitor.type_bool = parse_type_bool;
  112. v->visitor.type_str = parse_type_str;
  113. v->visitor.type_number = parse_type_number;
  114. v->visitor.start_optional = parse_start_optional;
  115. v->string = str;
  116. return v;
  117. }