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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user