qapi: New parse_qapi_name()
Signed-off-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Message-Id: <1488317230-26248-19-git-send-email-armbru@redhat.com>
This commit is contained in:
parent
6c873d1149
commit
069b64e3fe
@ -14,4 +14,6 @@
|
||||
int qapi_enum_parse(const char * const lookup[], const char *buf,
|
||||
int max, int def, Error **errp);
|
||||
|
||||
int parse_qapi_name(const char *name, bool complete);
|
||||
|
||||
#endif
|
||||
|
@ -33,3 +33,50 @@ int qapi_enum_parse(const char * const lookup[], const char *buf,
|
||||
error_setg(errp, "invalid parameter value: %s", buf);
|
||||
return def;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a valid QAPI name from @str.
|
||||
* A valid name consists of letters, digits, hyphen and underscore.
|
||||
* It may be prefixed by __RFQDN_ (downstream extension), where RFQDN
|
||||
* may contain only letters, digits, hyphen and period.
|
||||
* The special exception for enumeration names is not implemented.
|
||||
* See docs/qapi-code-gen.txt for more on QAPI naming rules.
|
||||
* Keep this consistent with scripts/qapi.py!
|
||||
* If @complete, the parse fails unless it consumes @str completely.
|
||||
* Return its length on success, -1 on failure.
|
||||
*/
|
||||
int parse_qapi_name(const char *str, bool complete)
|
||||
{
|
||||
const char *p = str;
|
||||
|
||||
if (*p == '_') { /* Downstream __RFQDN_ */
|
||||
p++;
|
||||
if (*p != '_') {
|
||||
return -1;
|
||||
}
|
||||
while (*++p) {
|
||||
if (!qemu_isalnum(*p) && *p != '-' && *p != '.') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*p != '_') {
|
||||
return -1;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!qemu_isalpha(*p)) {
|
||||
return -1;
|
||||
}
|
||||
while (*++p) {
|
||||
if (!qemu_isalnum(*p) && *p != '-' && *p != '_') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (complete && *p) {
|
||||
return -1;
|
||||
}
|
||||
return p - str;
|
||||
}
|
||||
|
@ -42,10 +42,44 @@ static void test_qapi_enum_parse(void)
|
||||
g_assert_cmpint(ret, ==, QTYPE__MAX - 1);
|
||||
}
|
||||
|
||||
static void test_parse_qapi_name(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Must start with a letter */
|
||||
ret = parse_qapi_name("a", true);
|
||||
g_assert(ret == 1);
|
||||
ret = parse_qapi_name("a$", false);
|
||||
g_assert(ret == 1);
|
||||
ret = parse_qapi_name("", false);
|
||||
g_assert(ret == -1);
|
||||
ret = parse_qapi_name("1", false);
|
||||
g_assert(ret == -1);
|
||||
|
||||
/* Only letters, digits, hyphen, underscore */
|
||||
ret = parse_qapi_name("A-Za-z0-9_", true);
|
||||
g_assert(ret == 10);
|
||||
ret = parse_qapi_name("A-Za-z0-9_$", false);
|
||||
g_assert(ret == 10);
|
||||
ret = parse_qapi_name("A-Za-z0-9_$", true);
|
||||
g_assert(ret == -1);
|
||||
|
||||
/* __RFQDN_ */
|
||||
ret = parse_qapi_name("__com.redhat_supports", true);
|
||||
g_assert(ret == 21);
|
||||
ret = parse_qapi_name("_com.example_", false);
|
||||
g_assert(ret == -1);
|
||||
ret = parse_qapi_name("__com.example", false);
|
||||
g_assert(ret == -1);
|
||||
ret = parse_qapi_name("__com.example_", false);
|
||||
g_assert(ret == -1);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func("/qapi/util/qapi_enum_parse", test_qapi_enum_parse);
|
||||
g_test_add_func("/qapi/util/parse_qapi_name", test_parse_qapi_name);
|
||||
g_test_run();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user