qapi: Make c_type() more OO-like

QAPISchemaType.c_type() is a bit awkward: it takes two optional
boolean flags is_param and is_unboxed, and they should never both
be True.

Add a new method for each of the flags, and drop the flags from
c_type().

Most callers pass no flags; they remain unchanged.

One caller passes is_param=True; call the new .c_param_type()
instead.

One caller passes is_unboxed=True, except for simple union types.
This is actually an ugly special case that will go away soon, so
until then, we now have to call either .c_type() or the new
.c_unboxed_type().  Tolerable in the interim.

It requires slightly more Python, but is arguably easier to read.

Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1458254921-17042-4-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Eric Blake 2016-03-17 16:48:28 -06:00 committed by Markus Armbruster
parent 972a110162
commit 4040d995e4
2 changed files with 35 additions and 11 deletions

View file

@ -124,11 +124,14 @@ def gen_variants(variants):
for var in variants.variants:
# Ugly special case for simple union TODO get rid of it
simple_union_type = var.simple_union_type()
typ = simple_union_type or var.type
if simple_union_type:
typ = simple_union_type.c_type()
else:
typ = var.type.c_unboxed_type()
ret += mcgen('''
%(c_type)s %(c_name)s;
''',
c_type=typ.c_type(is_unboxed=not simple_union_type),
c_type=typ,
c_name=c_name(var.name))
ret += mcgen('''

View file

@ -822,8 +822,18 @@ class QAPISchemaVisitor(object):
class QAPISchemaType(QAPISchemaEntity):
def c_type(self, is_param=False, is_unboxed=False):
return c_name(self.name) + pointer_suffix
# Return the C type for common use.
# For the types we commonly box, this is a pointer type.
def c_type(self):
pass
# Return the C type to be used in a parameter list.
def c_param_type(self):
return self.c_type()
# Return the C type to be used where we suppress boxing.
def c_unboxed_type(self):
return self.c_type()
def c_null(self):
return 'NULL'
@ -855,8 +865,11 @@ class QAPISchemaBuiltinType(QAPISchemaType):
def c_name(self):
return self.name
def c_type(self, is_param=False, is_unboxed=False):
if is_param and self.name == 'str':
def c_type(self):
return self._c_type_name
def c_param_type(self):
if self.name == 'str':
return 'const ' + self._c_type_name
return self._c_type_name
@ -889,7 +902,7 @@ class QAPISchemaEnumType(QAPISchemaType):
# See QAPISchema._make_implicit_enum_type()
return self.name.endswith('Kind')
def c_type(self, is_param=False, is_unboxed=False):
def c_type(self):
return c_name(self.name)
def member_names(self):
@ -921,6 +934,9 @@ class QAPISchemaArrayType(QAPISchemaType):
def is_implicit(self):
return True
def c_type(self):
return c_name(self.name) + pointer_suffix
def json_type(self):
return 'array'
@ -985,12 +1001,14 @@ class QAPISchemaObjectType(QAPISchemaType):
assert not self.is_implicit()
return QAPISchemaType.c_name(self)
def c_type(self, is_param=False, is_unboxed=False):
def c_type(self):
assert not self.is_implicit()
if is_unboxed:
return c_name(self.name)
return c_name(self.name) + pointer_suffix
def c_unboxed_type(self):
assert not self.is_implicit()
return c_name(self.name)
def json_type(self):
return 'object'
@ -1139,6 +1157,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
for v in self.variants.variants:
v.check_clash(self.info, seen)
def c_type(self):
return c_name(self.name) + pointer_suffix
def json_type(self):
return 'value'
@ -1630,7 +1651,7 @@ def gen_params(arg_type, extra):
sep = ', '
if memb.optional:
ret += 'bool has_%s, ' % c_name(memb.name)
ret += '%s %s' % (memb.type.c_type(is_param=True), c_name(memb.name))
ret += '%s %s' % (memb.type.c_param_type(), c_name(memb.name))
if extra:
ret += sep + extra
return ret