qapi: introduce QAPISchemaIfCond.cgen()
Instead of building prepocessor conditions from a list of string, use the result generated from QAPISchemaIfCond.cgen() and hide the implementation details. Note: this patch introduces a minor regression, generating a redundant pair of parenthesis. This is mostly fixed in a later patch in this series ("qapi: replace if condition list with dict [..]") Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20210804083105.97531-5-marcandre.lureau@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> [Commit message tweaked] Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
parent
33aa3267ba
commit
6cc2e4817f
@ -12,7 +12,12 @@
|
||||
# See the COPYING file in the top-level directory.
|
||||
|
||||
import re
|
||||
from typing import Match, Optional, Sequence
|
||||
from typing import (
|
||||
List,
|
||||
Match,
|
||||
Optional,
|
||||
Union,
|
||||
)
|
||||
|
||||
|
||||
#: Magic string that gets removed along with all space to its right.
|
||||
@ -194,22 +199,26 @@ def guardend(name: str) -> str:
|
||||
name=c_fname(name).upper())
|
||||
|
||||
|
||||
def gen_if(ifcond: Sequence[str]) -> str:
|
||||
ret = ''
|
||||
for ifc in ifcond:
|
||||
ret += mcgen('''
|
||||
def cgen_ifcond(ifcond: Union[str, List[str]]) -> str:
|
||||
if not ifcond:
|
||||
return ''
|
||||
return '(' + ') && ('.join(ifcond) + ')'
|
||||
|
||||
|
||||
def gen_if(cond: str) -> str:
|
||||
if not cond:
|
||||
return ''
|
||||
return mcgen('''
|
||||
#if %(cond)s
|
||||
''', cond=ifc)
|
||||
return ret
|
||||
''', cond=cond)
|
||||
|
||||
|
||||
def gen_endif(ifcond: Sequence[str]) -> str:
|
||||
ret = ''
|
||||
for ifc in reversed(ifcond):
|
||||
ret += mcgen('''
|
||||
def gen_endif(cond: str) -> str:
|
||||
if not cond:
|
||||
return ''
|
||||
return mcgen('''
|
||||
#endif /* %(cond)s */
|
||||
''', cond=ifc)
|
||||
return ret
|
||||
''', cond=cond)
|
||||
|
||||
|
||||
def must_match(pattern: str, string: str) -> Match[str]:
|
||||
|
@ -95,9 +95,9 @@ def _wrap_ifcond(ifcond: QAPISchemaIfCond, before: str, after: str) -> str:
|
||||
if added[0] == '\n':
|
||||
out += '\n'
|
||||
added = added[1:]
|
||||
out += gen_if(ifcond.ifcond)
|
||||
out += gen_if(ifcond.cgen())
|
||||
out += added
|
||||
out += gen_endif(ifcond.ifcond)
|
||||
out += gen_endif(ifcond.cgen())
|
||||
return out
|
||||
|
||||
|
||||
|
@ -124,10 +124,10 @@ def _tree_to_qlit(obj: JSONValue,
|
||||
if obj.comment:
|
||||
ret += indent(level) + f"/* {obj.comment} */\n"
|
||||
if obj.ifcond.is_present():
|
||||
ret += gen_if(obj.ifcond.ifcond)
|
||||
ret += gen_if(obj.ifcond.cgen())
|
||||
ret += _tree_to_qlit(obj.value, level)
|
||||
if obj.ifcond.is_present():
|
||||
ret += '\n' + gen_endif(obj.ifcond.ifcond)
|
||||
ret += '\n' + gen_endif(obj.ifcond.cgen())
|
||||
return ret
|
||||
|
||||
ret = ''
|
||||
|
@ -19,7 +19,7 @@ import os
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from .common import POINTER_SUFFIX, c_name
|
||||
from .common import POINTER_SUFFIX, c_name, cgen_ifcond
|
||||
from .error import QAPIError, QAPISemError, QAPISourceError
|
||||
from .expr import check_exprs
|
||||
from .parser import QAPISchemaParser
|
||||
@ -29,6 +29,9 @@ class QAPISchemaIfCond:
|
||||
def __init__(self, ifcond=None):
|
||||
self.ifcond = ifcond or []
|
||||
|
||||
def cgen(self):
|
||||
return cgen_ifcond(self.ifcond)
|
||||
|
||||
def is_present(self):
|
||||
return bool(self.ifcond)
|
||||
|
||||
|
@ -51,13 +51,13 @@ const QEnumLookup %(c_name)s_lookup = {
|
||||
''',
|
||||
c_name=c_name(name))
|
||||
for memb in members:
|
||||
ret += gen_if(memb.ifcond.ifcond)
|
||||
ret += gen_if(memb.ifcond.cgen())
|
||||
index = c_enum_const(name, memb.name, prefix)
|
||||
ret += mcgen('''
|
||||
[%(index)s] = "%(name)s",
|
||||
''',
|
||||
index=index, name=memb.name)
|
||||
ret += gen_endif(memb.ifcond.ifcond)
|
||||
ret += gen_endif(memb.ifcond.cgen())
|
||||
|
||||
ret += mcgen('''
|
||||
},
|
||||
@ -81,12 +81,12 @@ typedef enum %(c_name)s {
|
||||
c_name=c_name(name))
|
||||
|
||||
for memb in enum_members:
|
||||
ret += gen_if(memb.ifcond.ifcond)
|
||||
ret += gen_if(memb.ifcond.cgen())
|
||||
ret += mcgen('''
|
||||
%(c_enum)s,
|
||||
''',
|
||||
c_enum=c_enum_const(name, memb.name, prefix))
|
||||
ret += gen_endif(memb.ifcond.ifcond)
|
||||
ret += gen_endif(memb.ifcond.cgen())
|
||||
|
||||
ret += mcgen('''
|
||||
} %(c_name)s;
|
||||
@ -126,7 +126,7 @@ struct %(c_name)s {
|
||||
def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
|
||||
ret = ''
|
||||
for memb in members:
|
||||
ret += gen_if(memb.ifcond.ifcond)
|
||||
ret += gen_if(memb.ifcond.cgen())
|
||||
if memb.optional:
|
||||
ret += mcgen('''
|
||||
bool has_%(c_name)s;
|
||||
@ -136,7 +136,7 @@ def gen_struct_members(members: List[QAPISchemaObjectTypeMember]) -> str:
|
||||
%(c_type)s %(c_name)s;
|
||||
''',
|
||||
c_type=memb.type.c_type(), c_name=c_name(memb.name))
|
||||
ret += gen_endif(memb.ifcond.ifcond)
|
||||
ret += gen_endif(memb.ifcond.cgen())
|
||||
return ret
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ def gen_object(name: str, ifcond: QAPISchemaIfCond,
|
||||
ret += mcgen('''
|
||||
|
||||
''')
|
||||
ret += gen_if(ifcond.ifcond)
|
||||
ret += gen_if(ifcond.cgen())
|
||||
ret += mcgen('''
|
||||
struct %(c_name)s {
|
||||
''',
|
||||
@ -193,7 +193,7 @@ struct %(c_name)s {
|
||||
ret += mcgen('''
|
||||
};
|
||||
''')
|
||||
ret += gen_endif(ifcond.ifcond)
|
||||
ret += gen_endif(ifcond.cgen())
|
||||
|
||||
return ret
|
||||
|
||||
@ -220,13 +220,13 @@ def gen_variants(variants: QAPISchemaVariants) -> str:
|
||||
for var in variants.variants:
|
||||
if var.type.name == 'q_empty':
|
||||
continue
|
||||
ret += gen_if(var.ifcond.ifcond)
|
||||
ret += gen_if(var.ifcond.cgen())
|
||||
ret += mcgen('''
|
||||
%(c_type)s %(c_name)s;
|
||||
''',
|
||||
c_type=var.type.c_unboxed_type(),
|
||||
c_name=c_name(var.name))
|
||||
ret += gen_endif(var.ifcond.ifcond)
|
||||
ret += gen_endif(var.ifcond.cgen())
|
||||
|
||||
ret += mcgen('''
|
||||
} u;
|
||||
|
@ -79,7 +79,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||
|
||||
for memb in members:
|
||||
deprecated = 'deprecated' in [f.name for f in memb.features]
|
||||
ret += gen_if(memb.ifcond.ifcond)
|
||||
ret += gen_if(memb.ifcond.cgen())
|
||||
if memb.optional:
|
||||
ret += mcgen('''
|
||||
if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) {
|
||||
@ -112,7 +112,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||
ret += mcgen('''
|
||||
}
|
||||
''')
|
||||
ret += gen_endif(memb.ifcond.ifcond)
|
||||
ret += gen_endif(memb.ifcond.cgen())
|
||||
|
||||
if variants:
|
||||
tag_member = variants.tag_member
|
||||
@ -126,7 +126,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||
for var in variants.variants:
|
||||
case_str = c_enum_const(tag_member.type.name, var.name,
|
||||
tag_member.type.prefix)
|
||||
ret += gen_if(var.ifcond.ifcond)
|
||||
ret += gen_if(var.ifcond.cgen())
|
||||
if var.type.name == 'q_empty':
|
||||
# valid variant and nothing to do
|
||||
ret += mcgen('''
|
||||
@ -142,7 +142,7 @@ bool visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **errp)
|
||||
case=case_str,
|
||||
c_type=var.type.c_name(), c_name=c_name(var.name))
|
||||
|
||||
ret += gen_endif(var.ifcond.ifcond)
|
||||
ret += gen_endif(var.ifcond.cgen())
|
||||
ret += mcgen('''
|
||||
default:
|
||||
abort();
|
||||
@ -228,7 +228,7 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
|
||||
c_name=c_name(name))
|
||||
|
||||
for var in variants.variants:
|
||||
ret += gen_if(var.ifcond.ifcond)
|
||||
ret += gen_if(var.ifcond.cgen())
|
||||
ret += mcgen('''
|
||||
case %(case)s:
|
||||
''',
|
||||
@ -254,7 +254,7 @@ bool visit_type_%(c_name)s(Visitor *v, const char *name,
|
||||
ret += mcgen('''
|
||||
break;
|
||||
''')
|
||||
ret += gen_endif(var.ifcond.ifcond)
|
||||
ret += gen_endif(var.ifcond.cgen())
|
||||
|
||||
ret += mcgen('''
|
||||
case QTYPE_NONE:
|
||||
|
Loading…
Reference in New Issue
Block a user