xref: /qemu/qapi/qapi-util.c (revision 3b916140043e2757dd8d51ec641a6885e960e6ca)
1  /*
2   * QAPI util functions
3   *
4   * Authors:
5   *  Hu Tao       <hutao@cn.fujitsu.com>
6   *  Peter Lieven <pl@kamp.de>
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/osdep.h"
14  #include "qapi/compat-policy.h"
15  #include "qapi/error.h"
16  #include "qemu/ctype.h"
17  #include "qapi/qmp/qerror.h"
18  
19  CompatPolicy compat_policy;
20  
21  static bool compat_policy_input_ok1(const char *adjective,
22                                      CompatPolicyInput policy,
23                                      ErrorClass error_class,
24                                      const char *kind, const char *name,
25                                      Error **errp)
26  {
27      switch (policy) {
28      case COMPAT_POLICY_INPUT_ACCEPT:
29          return true;
30      case COMPAT_POLICY_INPUT_REJECT:
31          error_set(errp, error_class, "%s %s %s disabled by policy",
32                    adjective, kind, name);
33          return false;
34      case COMPAT_POLICY_INPUT_CRASH:
35      default:
36          abort();
37      }
38  }
39  
40  bool compat_policy_input_ok(unsigned special_features,
41                              const CompatPolicy *policy,
42                              ErrorClass error_class,
43                              const char *kind, const char *name,
44                              Error **errp)
45  {
46      if ((special_features & 1u << QAPI_DEPRECATED)
47          && !compat_policy_input_ok1("Deprecated",
48                                      policy->deprecated_input,
49                                      error_class, kind, name, errp)) {
50          return false;
51      }
52      if ((special_features & (1u << QAPI_UNSTABLE))
53          && !compat_policy_input_ok1("Unstable",
54                                      policy->unstable_input,
55                                      error_class, kind, name, errp)) {
56          return false;
57      }
58      return true;
59  }
60  
61  const char *qapi_enum_lookup(const QEnumLookup *lookup, int val)
62  {
63      assert(val >= 0 && val < lookup->size);
64  
65      return lookup->array[val];
66  }
67  
68  int qapi_enum_parse(const QEnumLookup *lookup, const char *buf,
69                      int def, Error **errp)
70  {
71      int i;
72  
73      if (!buf) {
74          return def;
75      }
76  
77      for (i = 0; i < lookup->size; i++) {
78          if (!strcmp(buf, lookup->array[i])) {
79              return i;
80          }
81      }
82  
83      error_setg(errp, "invalid parameter value: %s", buf);
84      return def;
85  }
86  
87  bool qapi_bool_parse(const char *name, const char *value, bool *obj, Error **errp)
88  {
89      if (g_str_equal(value, "on") ||
90          g_str_equal(value, "yes") ||
91          g_str_equal(value, "true") ||
92          g_str_equal(value, "y")) {
93          *obj = true;
94          return true;
95      }
96      if (g_str_equal(value, "off") ||
97          g_str_equal(value, "no") ||
98          g_str_equal(value, "false") ||
99          g_str_equal(value, "n")) {
100          *obj = false;
101          return true;
102      }
103  
104      error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
105                 "'on' or 'off'");
106      return false;
107  }
108  
109  /*
110   * Parse a valid QAPI name from @str.
111   * A valid name consists of letters, digits, hyphen and underscore.
112   * It may be prefixed by __RFQDN_ (downstream extension), where RFQDN
113   * may contain only letters, digits, hyphen and period.
114   * The special exception for enumeration names is not implemented.
115   * See docs/devel/qapi-code-gen.rst for more on QAPI naming rules.
116   * Keep this consistent with scripts/qapi-gen.py!
117   * If @complete, the parse fails unless it consumes @str completely.
118   * Return its length on success, -1 on failure.
119   */
120  int parse_qapi_name(const char *str, bool complete)
121  {
122      const char *p = str;
123  
124      if (*p == '_') {            /* Downstream __RFQDN_ */
125          p++;
126          if (*p != '_') {
127              return -1;
128          }
129          while (*++p) {
130              if (!qemu_isalnum(*p) && *p != '-' && *p != '.') {
131                  break;
132              }
133          }
134  
135          if (*p != '_') {
136              return -1;
137          }
138          p++;
139      }
140  
141      if (!qemu_isalpha(*p)) {
142          return -1;
143      }
144      while (*++p) {
145          if (!qemu_isalnum(*p) && *p != '-' && *p != '_') {
146              break;
147          }
148      }
149  
150      if (complete && *p) {
151          return -1;
152      }
153      return p - str;
154  }
155