mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-03-05 19:39:59 +00:00
qapi: Clean up after recent conversions to QAPISchemaVisitor
Generate just 'FOO' instead of 'struct FOO' when possible. Drop helper functions that are now unused. Make pep8 and pylint reasonably happy. Rename generate_FOO() functions to gen_FOO() for consistency. Use more consistent and sensible variable names. Consistently use c_ for mapping keys when their value is a C identifier or type. Simplify gen_enum() and gen_visit_union() Consistently use single quotes for C text string literals. Backports commit e98859a9b96d71dea8f9af43325edd43c7effe66 from qemu
This commit is contained in:
parent
64e9fceab9
commit
d6866a50f6
|
@ -154,6 +154,7 @@ void qapi_free_uint8List(uint8List *obj);
|
|||
|
||||
#endif /* QAPI_TYPES_BUILTIN */
|
||||
|
||||
|
||||
typedef enum ErrorClass {
|
||||
ERROR_CLASS_GENERIC_ERROR = 0,
|
||||
ERROR_CLASS_COMMAND_NOT_FOUND = 1,
|
||||
|
@ -170,6 +171,7 @@ typedef struct ErrorClassList ErrorClassList;
|
|||
typedef struct X86CPUFeatureWordInfo X86CPUFeatureWordInfo;
|
||||
|
||||
typedef struct X86CPUFeatureWordInfoList X86CPUFeatureWordInfoList;
|
||||
|
||||
typedef enum X86CPURegister32 {
|
||||
X86_CPU_REGISTER32_EAX = 0,
|
||||
X86_CPU_REGISTER32_EBX = 1,
|
||||
|
|
|
@ -13,24 +13,26 @@
|
|||
|
||||
from qapi import *
|
||||
|
||||
|
||||
def gen_fwd_object_or_array(name):
|
||||
return mcgen('''
|
||||
|
||||
typedef struct %(name)s %(name)s;
|
||||
typedef struct %(c_name)s %(c_name)s;
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
def gen_array(name, element_type):
|
||||
return mcgen('''
|
||||
struct %(name)s {
|
||||
struct %(c_name)s {
|
||||
union {
|
||||
%(c_type)s value;
|
||||
uint64_t padding;
|
||||
};
|
||||
struct %(name)s *next;
|
||||
struct %(c_name)s *next;
|
||||
};
|
||||
''',
|
||||
name=c_name(name), c_type=element_type.c_type())
|
||||
c_name=c_name(name), c_type=element_type.c_type())
|
||||
|
||||
|
||||
def gen_struct_field(name, typ, optional):
|
||||
ret = ''
|
||||
|
@ -46,7 +48,8 @@ def gen_struct_field(name, typ, optional):
|
|||
c_type=typ.c_type(), c_name=c_name(name))
|
||||
return ret
|
||||
|
||||
def generate_struct_fields(members):
|
||||
|
||||
def gen_struct_fields(members):
|
||||
ret = ''
|
||||
|
||||
for memb in members:
|
||||
|
@ -55,18 +58,19 @@ def generate_struct_fields(members):
|
|||
|
||||
def gen_struct(name, base, members):
|
||||
ret = mcgen('''
|
||||
struct %(name)s {
|
||||
struct %(c_name)s {
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
if base:
|
||||
ret += gen_struct_field('base', base, False)
|
||||
|
||||
ret += generate_struct_fields(members)
|
||||
ret += gen_struct_fields(members)
|
||||
|
||||
# Make sure that all structs have at least one field; this avoids
|
||||
# potential issues with attempting to malloc space for zero-length structs
|
||||
# in C, and also incompatibility with C++ (where an empty struct is size 1).
|
||||
# potential issues with attempting to malloc space for zero-length
|
||||
# structs in C, and also incompatibility with C++ (where an empty
|
||||
# struct is size 1).
|
||||
if not base and not members:
|
||||
ret += mcgen('''
|
||||
char qapi_dummy_field_for_empty_struct;
|
||||
|
@ -78,37 +82,6 @@ struct %(name)s {
|
|||
|
||||
return ret
|
||||
|
||||
def generate_enum(name, values, prefix=None):
|
||||
name = c_name(name)
|
||||
lookup_decl = mcgen('''
|
||||
extern const char *const %(name)s_lookup[];
|
||||
''',
|
||||
name=name)
|
||||
|
||||
enum_decl = mcgen('''
|
||||
typedef enum %(name)s {
|
||||
''',
|
||||
name=name)
|
||||
|
||||
# append automatically generated _MAX value
|
||||
enum_values = values + [ 'MAX' ]
|
||||
|
||||
i = 0
|
||||
for value in enum_values:
|
||||
enum_full_value = c_enum_const(name, value, prefix)
|
||||
enum_decl += mcgen('''
|
||||
%(enum_full_value)s = %(i)d,
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
i=i)
|
||||
i += 1
|
||||
|
||||
enum_decl += mcgen('''
|
||||
} %(name)s;
|
||||
''',
|
||||
name=name)
|
||||
|
||||
return enum_decl + lookup_decl
|
||||
|
||||
def gen_alternate_qtypes_decl(name):
|
||||
return mcgen('''
|
||||
|
@ -117,12 +90,13 @@ extern const int %(c_name)s_qtypes[];
|
|||
''',
|
||||
c_name=c_name(name))
|
||||
|
||||
|
||||
def gen_alternate_qtypes(name, variants):
|
||||
ret = mcgen('''
|
||||
|
||||
const int %(name)s_qtypes[QTYPE_MAX] = {
|
||||
const int %(c_name)s_qtypes[QTYPE_MAX] = {
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
for var in variants.variants:
|
||||
qtype = var.type.alternate_qtype()
|
||||
|
@ -131,6 +105,7 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
|
|||
ret += mcgen('''
|
||||
[%(qtype)s] = %(enum_const)s,
|
||||
''',
|
||||
qtype=qtype,
|
||||
enum_const=c_enum_const(variants.tag_member.type.name,
|
||||
var.name))
|
||||
|
||||
|
@ -142,26 +117,24 @@ const int %(name)s_qtypes[QTYPE_MAX] = {
|
|||
|
||||
|
||||
def gen_union(name, base, variants):
|
||||
name = c_name(name)
|
||||
|
||||
ret = mcgen('''
|
||||
struct %(name)s {
|
||||
struct %(c_name)s {
|
||||
''',
|
||||
name=name)
|
||||
c_name=c_name(name))
|
||||
if base:
|
||||
ret += mcgen('''
|
||||
/* Members inherited from %(c_name)s: */
|
||||
''',
|
||||
c_name=c_name(base.name))
|
||||
ret += generate_struct_fields(base.members)
|
||||
ret += gen_struct_fields(base.members)
|
||||
ret += mcgen('''
|
||||
/* Own members: */
|
||||
''')
|
||||
else:
|
||||
ret += mcgen('''
|
||||
%(discriminator_type_name)s kind;
|
||||
%(c_type)s kind;
|
||||
''',
|
||||
discriminator_type_name=c_name(variants.tag_member.type.name))
|
||||
c_type=c_name(variants.tag_member.type.name))
|
||||
|
||||
# FIXME: What purpose does data serve, besides preventing a union that
|
||||
# has a branch named 'data'? We use it in qapi-visit.py to decide
|
||||
|
@ -196,17 +169,19 @@ struct %(name)s {
|
|||
|
||||
return ret
|
||||
|
||||
def generate_type_cleanup_decl(name):
|
||||
|
||||
def gen_type_cleanup_decl(name):
|
||||
ret = mcgen('''
|
||||
void qapi_free_%(name)s(%(name)s *obj);
|
||||
void qapi_free_%(c_name)s(%(c_name)s *obj);
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
return ret
|
||||
|
||||
def generate_type_cleanup(name):
|
||||
|
||||
def gen_type_cleanup(name):
|
||||
ret = mcgen('''
|
||||
|
||||
void qapi_free_%(name)s(%(name)s *obj)
|
||||
void qapi_free_%(c_name)s(%(c_name)s *obj)
|
||||
{
|
||||
QapiDeallocVisitor *md;
|
||||
Visitor *v;
|
||||
|
@ -217,11 +192,11 @@ void qapi_free_%(name)s(%(name)s *obj)
|
|||
|
||||
md = qapi_dealloc_visitor_new();
|
||||
v = qapi_dealloc_get_visitor(md);
|
||||
visit_type_%(name)s(v, &obj, NULL, NULL);
|
||||
visit_type_%(c_name)s(v, &obj, NULL, NULL);
|
||||
qapi_dealloc_visitor_cleanup(md);
|
||||
}
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -254,20 +229,20 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
|
|||
self._btin = None
|
||||
|
||||
def _gen_type_cleanup(self, name):
|
||||
self.decl += generate_type_cleanup_decl(name)
|
||||
self.defn += generate_type_cleanup(name)
|
||||
self.decl += gen_type_cleanup_decl(name)
|
||||
self.defn += gen_type_cleanup(name)
|
||||
|
||||
def visit_enum_type(self, name, info, values, prefix):
|
||||
self._fwdecl += generate_enum(name, values, prefix)
|
||||
self._fwdefn += generate_enum_lookup(name, values, prefix)
|
||||
self._fwdecl += gen_enum(name, values, prefix)
|
||||
self._fwdefn += gen_enum_lookup(name, values, prefix)
|
||||
|
||||
def visit_array_type(self, name, info, element_type):
|
||||
if isinstance(element_type, QAPISchemaBuiltinType):
|
||||
self._btin += gen_fwd_object_or_array(name)
|
||||
self._btin += gen_array(name, element_type)
|
||||
self._btin += generate_type_cleanup_decl(name)
|
||||
self._btin += gen_type_cleanup_decl(name)
|
||||
if do_builtins:
|
||||
self.defn += generate_type_cleanup(name)
|
||||
self.defn += gen_type_cleanup(name)
|
||||
else:
|
||||
self._fwdecl += gen_fwd_object_or_array(name)
|
||||
self.decl += gen_array(name, element_type)
|
||||
|
|
|
@ -18,18 +18,19 @@ import re
|
|||
implicit_structs_seen = set()
|
||||
struct_fields_seen = set()
|
||||
|
||||
def generate_visit_implicit_struct(type):
|
||||
if type in implicit_structs_seen:
|
||||
def gen_visit_implicit_struct(typ):
|
||||
if typ in implicit_structs_seen:
|
||||
return ''
|
||||
implicit_structs_seen.add(type)
|
||||
implicit_structs_seen.add(typ)
|
||||
|
||||
ret = ''
|
||||
if type.name not in struct_fields_seen:
|
||||
if typ.name not in struct_fields_seen:
|
||||
# Need a forward declaration
|
||||
ret += mcgen('''
|
||||
|
||||
static void visit_type_%(c_type)s_fields(Visitor *m, %(c_type)s **obj, Error **errp);
|
||||
''',
|
||||
c_type=type.c_name())
|
||||
c_type=typ.c_name())
|
||||
|
||||
ret += mcgen('''
|
||||
|
||||
|
@ -45,35 +46,35 @@ static void visit_type_implicit_%(c_type)s(Visitor *m, %(c_type)s **obj, Error *
|
|||
error_propagate(errp, err);
|
||||
}
|
||||
''',
|
||||
c_type=type.c_name())
|
||||
c_type=typ.c_name())
|
||||
return ret
|
||||
|
||||
def generate_visit_struct_fields(name, members, base = None):
|
||||
def gen_visit_struct_fields(name, base, members):
|
||||
struct_fields_seen.add(name)
|
||||
|
||||
ret = ''
|
||||
|
||||
if base:
|
||||
ret += generate_visit_implicit_struct(base)
|
||||
ret += gen_visit_implicit_struct(base)
|
||||
|
||||
ret += mcgen('''
|
||||
|
||||
static void visit_type_%(name)s_fields(Visitor *m, %(name)s **obj, Error **errp)
|
||||
static void visit_type_%(c_name)s_fields(Visitor *m, %(c_name)s **obj, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
push_indent()
|
||||
|
||||
if base:
|
||||
ret += mcgen('''
|
||||
visit_type_implicit_%(type)s(m, &(*obj)->%(c_name)s, &err);
|
||||
visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
''',
|
||||
type=base.c_name(), c_name=c_name('base'))
|
||||
c_type=base.c_name(), c_name=c_name('base'))
|
||||
|
||||
for memb in members:
|
||||
if memb.optional:
|
||||
|
@ -85,9 +86,9 @@ if (!err && (*obj)->has_%(c_name)s) {
|
|||
push_indent()
|
||||
|
||||
ret += mcgen('''
|
||||
visit_type_%(type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err);
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err);
|
||||
''',
|
||||
type=memb.type.c_name(), c_name=c_name(memb.name),
|
||||
c_type=memb.type.c_name(), c_name=c_name(memb.name),
|
||||
name=memb.name)
|
||||
|
||||
if memb.optional:
|
||||
|
@ -102,7 +103,7 @@ if (err) {
|
|||
''')
|
||||
|
||||
pop_indent()
|
||||
if re.search('^ *goto out\\;', ret, re.MULTILINE):
|
||||
if re.search('^ *goto out;', ret, re.MULTILINE):
|
||||
ret += mcgen('''
|
||||
|
||||
out:
|
||||
|
@ -114,7 +115,7 @@ out:
|
|||
return ret
|
||||
|
||||
|
||||
def generate_visit_struct_body(name):
|
||||
def gen_visit_struct_body(name):
|
||||
ret = mcgen('''
|
||||
Error *err = NULL;
|
||||
|
||||
|
@ -129,30 +130,29 @@ def generate_visit_struct_body(name):
|
|||
error_propagate(errp, err);
|
||||
''',
|
||||
name=name, c_name=c_name(name))
|
||||
|
||||
return ret
|
||||
|
||||
def gen_visit_struct(name, base, members):
|
||||
ret = generate_visit_struct_fields(name, members, base)
|
||||
|
||||
ret = gen_visit_struct_fields(name, base, members)
|
||||
ret += mcgen('''
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
|
||||
void visit_type_%(c_name)s(Visitor *m, %(c_name)s **obj, const char *name, Error **errp)
|
||||
{
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
ret += generate_visit_struct_body(name)
|
||||
ret += gen_visit_struct_body(name)
|
||||
|
||||
ret += mcgen('''
|
||||
}
|
||||
''')
|
||||
return ret
|
||||
|
||||
|
||||
def gen_visit_list(name, element_type):
|
||||
return mcgen('''
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
|
||||
void visit_type_%(c_name)s(Visitor *m, %(c_name)s **obj, const char *name, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
GenericList *i, **prev;
|
||||
|
@ -165,7 +165,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **e
|
|||
for (prev = (GenericList **)obj;
|
||||
!err && (i = visit_next_list(m, prev)) != NULL;
|
||||
prev = &i) {
|
||||
%(name)s *native_i = (%(name)s *)i;
|
||||
%(c_name)s *native_i = (%(c_name)s *)i;
|
||||
visit_type_%(c_elt_type)s(m, &native_i->value, NULL, &err);
|
||||
}
|
||||
|
||||
|
@ -176,10 +176,10 @@ out:
|
|||
error_propagate(errp, err);
|
||||
}
|
||||
''',
|
||||
name=c_name(name),
|
||||
c_elt_type=element_type.c_name())
|
||||
c_name=c_name(name), c_elt_type=element_type.c_name())
|
||||
|
||||
def generate_visit_enum(name):
|
||||
|
||||
def gen_visit_enum(name):
|
||||
return mcgen('''
|
||||
|
||||
void visit_type_%(c_name)s(Visitor *m, %(c_name)s *obj, const char *name, Error **errp)
|
||||
|
@ -189,34 +189,34 @@ void visit_type_%(c_name)s(Visitor *m, %(c_name)s *obj, const char *name, Error
|
|||
''',
|
||||
c_name=c_name(name), name=name)
|
||||
|
||||
|
||||
def gen_visit_alternate(name, variants):
|
||||
ret = mcgen('''
|
||||
|
||||
void visit_type_%(name)s(Visitor *m, %(name)s **obj, const char *name, Error **errp)
|
||||
void visit_type_%(c_name)s(Visitor *m, %(c_name)s **obj, const char *name, Error **errp)
|
||||
{
|
||||
Error *err = NULL;
|
||||
|
||||
visit_start_implicit_struct(m, (void**) obj, sizeof(%(name)s), &err);
|
||||
visit_start_implicit_struct(m, (void**) obj, sizeof(%(c_name)s), &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
visit_get_next_type(m, (int*) &(*obj)->kind, %(name)s_qtypes, name, &err);
|
||||
visit_get_next_type(m, (int*) &(*obj)->kind, %(c_name)s_qtypes, name, &err);
|
||||
if (err) {
|
||||
goto out_end;
|
||||
}
|
||||
switch ((*obj)->kind) {
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
for var in variants.variants:
|
||||
enum_full_value = c_enum_const(variants.tag_member.type.name,
|
||||
var.name)
|
||||
ret += mcgen('''
|
||||
case %(enum_full_value)s:
|
||||
case %(case)s:
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, name, &err);
|
||||
break;
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
case=c_enum_const(variants.tag_member.type.name,
|
||||
var.name),
|
||||
c_type=var.type.c_name(),
|
||||
c_name=c_name(var.name))
|
||||
|
||||
|
@ -235,17 +235,18 @@ out:
|
|||
|
||||
return ret
|
||||
|
||||
|
||||
def gen_visit_union(name, base, variants):
|
||||
ret = ''
|
||||
|
||||
if base:
|
||||
members = [m for m in base.members if m != variants.tag_member]
|
||||
ret += generate_visit_struct_fields(name, members)
|
||||
ret += gen_visit_struct_fields(name, None, members)
|
||||
|
||||
for var in variants.variants:
|
||||
# Ugly special case for simple union TODO get rid of it
|
||||
if not var.simple_union_type():
|
||||
ret += generate_visit_implicit_struct(var.type)
|
||||
ret += gen_visit_implicit_struct(var.type)
|
||||
|
||||
ret += mcgen('''
|
||||
|
||||
|
@ -263,19 +264,19 @@ void visit_type_%(c_name)s(Visitor *m, %(c_name)s **obj, const char *name, Error
|
|||
|
||||
if base:
|
||||
ret += mcgen('''
|
||||
visit_type_%(name)s_fields(m, obj, &err);
|
||||
visit_type_%(c_name)s_fields(m, obj, &err);
|
||||
if (err) {
|
||||
goto out_obj;
|
||||
}
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
|
||||
disc_key = variants.tag_member.name
|
||||
tag_key = variants.tag_member.name
|
||||
if not variants.tag_name:
|
||||
# we pointlessly use a different key for simple unions
|
||||
disc_key = 'type'
|
||||
tag_key = 'type'
|
||||
ret += mcgen('''
|
||||
visit_type_%(disc_type)s(m, &(*obj)->%(c_name)s, "%(disc_key)s", &err);
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "%(name)s", &err);
|
||||
if (err) {
|
||||
goto out_obj;
|
||||
}
|
||||
|
@ -284,30 +285,37 @@ void visit_type_%(c_name)s(Visitor *m, %(c_name)s **obj, const char *name, Error
|
|||
}
|
||||
switch ((*obj)->%(c_name)s) {
|
||||
''',
|
||||
disc_type=variants.tag_member.type.c_name(),
|
||||
c_type=variants.tag_member.type.c_name(),
|
||||
# TODO ugly special case for simple union
|
||||
# Use same tag name in C as on the wire to get rid of
|
||||
# it, then: c_name=c_name(variants.tag_member.name)
|
||||
c_name=c_name(variants.tag_name or 'kind'),
|
||||
disc_key = disc_key)
|
||||
name=tag_key)
|
||||
|
||||
for var in variants.variants:
|
||||
# TODO ugly special case for simple union
|
||||
simple_union_type = var.simple_union_type()
|
||||
if simple_union_type:
|
||||
fmt = 'visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err);'
|
||||
else:
|
||||
fmt = 'visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);'
|
||||
|
||||
enum_full_value = c_enum_const(variants.tag_member.type.name, var.name)
|
||||
ret += mcgen('''
|
||||
case %(enum_full_value)s:
|
||||
''' + fmt + '''
|
||||
break;
|
||||
case %(case)s:
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
c_type=(simple_union_type or var.type).c_name(),
|
||||
case=c_enum_const(variants.tag_member.type.name,
|
||||
var.name))
|
||||
if simple_union_type:
|
||||
ret += mcgen('''
|
||||
visit_type_%(c_type)s(m, &(*obj)->%(c_name)s, "data", &err);
|
||||
''',
|
||||
c_type=simple_union_type.c_name(),
|
||||
c_name=c_name(var.name))
|
||||
else:
|
||||
ret += mcgen('''
|
||||
visit_type_implicit_%(c_type)s(m, &(*obj)->%(c_name)s, &err);
|
||||
''',
|
||||
c_type=var.type.c_name(),
|
||||
c_name=c_name(var.name))
|
||||
|
||||
ret += mcgen('''
|
||||
break;
|
||||
''')
|
||||
|
||||
ret += mcgen('''
|
||||
default:
|
||||
|
@ -328,6 +336,7 @@ out:
|
|||
|
||||
return ret
|
||||
|
||||
|
||||
def gen_visit_decl(name, scalar=False):
|
||||
c_type = c_name(name) + ' *'
|
||||
if not scalar:
|
||||
|
@ -361,7 +370,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaVisitor):
|
|||
|
||||
def visit_enum_type(self, name, info, values, prefix):
|
||||
self.decl += gen_visit_decl(name, scalar=True)
|
||||
self.defn += generate_visit_enum(name)
|
||||
self.defn += gen_visit_enum(name)
|
||||
|
||||
def visit_array_type(self, name, info, element_type):
|
||||
decl = gen_visit_decl(name)
|
||||
|
@ -437,7 +446,7 @@ fdef.write(mcgen('''
|
|||
#include "qemu-common.h"
|
||||
#include "%(prefix)sqapi-visit.h"
|
||||
''',
|
||||
prefix = prefix))
|
||||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
#include "qapi/visitor.h"
|
||||
|
|
|
@ -1083,9 +1083,6 @@ class QAPISchema(object):
|
|||
self._def_exprs()
|
||||
self.check()
|
||||
|
||||
def get_exprs(self):
|
||||
return [expr_elem['expr'] for expr_elem in self.exprs]
|
||||
|
||||
def _def_entity(self, ent):
|
||||
assert ent.name not in self._entity_dict
|
||||
self._entity_dict[ent.name] = ent
|
||||
|
@ -1277,23 +1274,6 @@ class QAPISchema(object):
|
|||
# Code generation helpers
|
||||
#
|
||||
|
||||
def parse_args(typeinfo):
|
||||
if isinstance(typeinfo, str):
|
||||
struct = find_struct(typeinfo)
|
||||
assert struct != None
|
||||
typeinfo = struct['data']
|
||||
|
||||
for member in typeinfo:
|
||||
argname = member
|
||||
argentry = typeinfo[member]
|
||||
optional = False
|
||||
if member.startswith('*'):
|
||||
argname = member[1:]
|
||||
optional = True
|
||||
# Todo: allow argentry to be OrderedDict, for providing the
|
||||
# value of an optional argument.
|
||||
yield (argname, argentry, optional)
|
||||
|
||||
def camel_case(name):
|
||||
new_name = ''
|
||||
first = True
|
||||
|
@ -1376,67 +1356,9 @@ def c_name(name, protect=True):
|
|||
return "q_" + name
|
||||
return name.translate(c_name_trans)
|
||||
|
||||
# Map type @name to the C typedef name for the list form.
|
||||
#
|
||||
# ['Name'] -> 'NameList', ['x-Foo'] -> 'x_FooList', ['int'] -> 'intList'
|
||||
def c_list_type(name):
|
||||
return name + 'List'
|
||||
|
||||
# Map type @value to the C typedef form.
|
||||
#
|
||||
# Used for converting 'type' from a 'member':'type' qapi definition
|
||||
# into the alphanumeric portion of the type for a generated C parameter,
|
||||
# as well as generated C function names. See c_type() for the rest of
|
||||
# the conversion such as adding '*' on pointer types.
|
||||
# 'int' -> 'int', '[x-Foo]' -> 'x_FooList', '__a.b_c' -> '__a_b_c'
|
||||
def type_name(value):
|
||||
if type(value) == list:
|
||||
return c_list_type(value[0])
|
||||
if value in builtin_types.keys():
|
||||
return value
|
||||
return c_name(value)
|
||||
|
||||
eatspace = '\033EATSPACE.'
|
||||
pointer_suffix = ' *' + eatspace
|
||||
|
||||
# Map type @name to its C type expression.
|
||||
# If @is_param, const-qualify the string type.
|
||||
#
|
||||
# This function is used for computing the full C type of 'member':'name'.
|
||||
# A special suffix is added in c_type() for pointer types, and it's
|
||||
# stripped in mcgen(). So please notice this when you check the return
|
||||
# value of c_type() outside mcgen().
|
||||
def c_type(value, is_param=False):
|
||||
if value == 'str':
|
||||
if is_param:
|
||||
return 'const char' + pointer_suffix
|
||||
return 'char' + pointer_suffix
|
||||
|
||||
elif value == 'int':
|
||||
return 'int64_t'
|
||||
elif (value == 'int8' or value == 'int16' or value == 'int32' or
|
||||
value == 'int64' or value == 'uint8' or value == 'uint16' or
|
||||
value == 'uint32' or value == 'uint64'):
|
||||
return value + '_t'
|
||||
elif value == 'size':
|
||||
return 'uint64_t'
|
||||
elif value == 'bool':
|
||||
return 'bool'
|
||||
elif value == 'number':
|
||||
return 'double'
|
||||
elif type(value) == list:
|
||||
return c_list_type(value[0]) + pointer_suffix
|
||||
elif is_enum(value):
|
||||
return c_name(value)
|
||||
elif value == None:
|
||||
return 'void'
|
||||
elif value in events:
|
||||
return camel_case(value) + 'Event' + pointer_suffix
|
||||
else:
|
||||
# complex type name
|
||||
assert isinstance(value, str) and value != ""
|
||||
return c_name(value) + pointer_suffix
|
||||
|
||||
def genindent(count):
|
||||
ret = ""
|
||||
for i in range(count):
|
||||
|
@ -1490,18 +1412,18 @@ def guardend(name):
|
|||
''',
|
||||
name=guardname(name))
|
||||
|
||||
def generate_enum_lookup(name, values, prefix=None):
|
||||
def gen_enum_lookup(name, values, prefix=None):
|
||||
ret = mcgen('''
|
||||
|
||||
const char *const %(name)s_lookup[] = {
|
||||
const char *const %(c_name)s_lookup[] = {
|
||||
''',
|
||||
name=c_name(name))
|
||||
c_name=c_name(name))
|
||||
for value in values:
|
||||
index = c_enum_const(name, value, prefix)
|
||||
ret += mcgen('''
|
||||
"%(value)s",
|
||||
''',
|
||||
index = index, value = value)
|
||||
value=value)
|
||||
|
||||
# Unicorn: We don't use C99 [ARRAY_INDICING] = Thing because
|
||||
# MSVC is still in the stone-age with this part of C compiler
|
||||
|
@ -1510,43 +1432,38 @@ const char *const %(name)s_lookup[] = {
|
|||
ret += mcgen('''
|
||||
NULL,
|
||||
};
|
||||
''',
|
||||
max_index=max_index)
|
||||
''')
|
||||
|
||||
return ret
|
||||
|
||||
def generate_enum(name, values, prefix=None):
|
||||
name = c_name(name)
|
||||
lookup_decl = mcgen('''
|
||||
|
||||
extern const char *const %(name)s_lookup[];
|
||||
''',
|
||||
name=name)
|
||||
|
||||
enum_decl = mcgen('''
|
||||
|
||||
typedef enum %(name)s {
|
||||
''',
|
||||
name=name)
|
||||
|
||||
def gen_enum(name, values, prefix=None):
|
||||
# append automatically generated _MAX value
|
||||
enum_values = values + [ 'MAX' ]
|
||||
enum_values = values + ['MAX']
|
||||
ret = mcgen('''
|
||||
|
||||
typedef enum %(c_name)s {
|
||||
''',
|
||||
c_name=c_name(name))
|
||||
|
||||
i = 0
|
||||
for value in enum_values:
|
||||
enum_full_value = c_enum_const(name, value, prefix)
|
||||
enum_decl += mcgen('''
|
||||
%(enum_full_value)s = %(i)d,
|
||||
ret += mcgen('''
|
||||
%(c_enum)s = %(i)d,
|
||||
''',
|
||||
enum_full_value = enum_full_value,
|
||||
c_enum=c_enum_const(name, value, prefix),
|
||||
i=i)
|
||||
i += 1
|
||||
|
||||
enum_decl += mcgen('''
|
||||
} %(name)s;
|
||||
ret += mcgen('''
|
||||
} %(c_name)s;
|
||||
''',
|
||||
name=name)
|
||||
c_name=c_name(name))
|
||||
|
||||
return enum_decl + lookup_decl
|
||||
ret += mcgen('''
|
||||
extern const char *const %(c_name)s_lookup[];
|
||||
''',
|
||||
c_name=c_name(name))
|
||||
return ret
|
||||
|
||||
#
|
||||
# Common command line parsing
|
||||
|
|
Loading…
Reference in a new issue