Loading include/qapi/util.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 qapi/qapi-util.c +47 −0 Original line number Diff line number Diff line Loading @@ -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; } tests/test-qapi-util.c +34 −0 Original line number Diff line number Diff line Loading @@ -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
include/qapi/util.h +2 −0 Original line number Diff line number Diff line Loading @@ -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
qapi/qapi-util.c +47 −0 Original line number Diff line number Diff line Loading @@ -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; }
tests/test-qapi-util.c +34 −0 Original line number Diff line number Diff line Loading @@ -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; }