Re: [Qemu-devel] [PATCH v4 12/51] qapi-introspect: add preprocessor conditions to generated QLit

2018-01-12 Thread Marc-André Lureau
Hi

On Thu, Jan 11, 2018 at 10:32 PM, Marc-André Lureau
 wrote:
> The generator will take (obj, condition) tuples to wrap generated QLit
> objects for 'obj' with #if/#endif conditions.
>
> This commit adds 'ifcond' condition to top-level QLit objects.
>
> See generated tests/test-qmp-introspect.c. Example diff after this patch:
>
> --- before  2018-01-08 11:55:24.757083654 +0100
> +++ tests/test-qmp-introspect.c 2018-01-08 13:08:44.477641629 +0100
> @@ -51,6 +51,8 @@
>  { "name", QLIT_QSTR("EVENT_F"), },
>  {}
>  })),
> +#if defined(TEST_IF_CMD)
> +#if defined(TEST_IF_STRUCT)
>  QLIT_QDICT(((QLitDictEntry[]) {
>  { "arg-type", QLIT_QSTR("5"), },
>  { "meta-type", QLIT_QSTR("command"), },
> @@ -58,12 +60,16 @@
>  { "ret-type", QLIT_QSTR("0"), },
>  {}
>  })),
> +#endif /* defined(TEST_IF_STRUCT) */
> +#endif /* defined(TEST_IF_CMD) */
>

My bad, this comment causes git am (and patchew) to fail to apply. FIxed.

The series is also available on https://github.com/elmarco/qemu/commits/qapi-if

> Signed-off-by: Marc-André Lureau 
> ---
>  scripts/qapi-introspect.py | 31 +--
>  1 file changed, 21 insertions(+), 10 deletions(-)
>
> diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
> index b1d08ec97b..7d3a5c37fd 100644
> --- a/scripts/qapi-introspect.py
> +++ b/scripts/qapi-introspect.py
> @@ -17,6 +17,15 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
>  def indent(level):
>  return level * 4 * ' '
>
> +if isinstance(obj, tuple):
> +ifobj, ifcond = obj
> +ret = gen_if(ifcond)
> +ret += to_qlit(ifobj, level)
> +endif = gen_endif(ifcond)
> +if endif:
> +ret += '\n' + endif
> +return ret
> +
>  ret = ''
>  if not suppress_first_indent:
>  ret += indent(level)
> @@ -25,7 +34,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
>  elif isinstance(obj, str):
>  ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
>  elif isinstance(obj, list):
> -elts = [to_qlit(elt, level + 1)
> +elts = [to_qlit(elt, level + 1).strip('\n')
>  for elt in obj]
>  elts.append(indent(level + 1) + "{}")
>  ret += 'QLIT_QLIST(((QLitObject[]) {\n'
> @@ -121,12 +130,12 @@ const QLitObject %(c_name)s = %(c_string)s;
>  return '[' + self._use_type(typ.element_type) + ']'
>  return self._name(typ.name)
>
> -def _gen_qlit(self, name, mtype, obj):
> +def _gen_qlit(self, name, mtype, obj, ifcond):
>  if mtype not in ('command', 'event', 'builtin', 'array'):
>  name = self._name(name)
>  obj['name'] = name
>  obj['meta-type'] = mtype
> -self._qlits.append(obj)
> +self._qlits.append((obj, ifcond))
>
>  def _gen_member(self, member):
>  ret = {'name': member.name, 'type': self._use_type(member.type)}
> @@ -142,26 +151,27 @@ const QLitObject %(c_name)s = %(c_string)s;
>  return {'case': variant.name, 'type': self._use_type(variant.type)}
>
>  def visit_builtin_type(self, name, info, json_type):
> -self._gen_qlit(name, 'builtin', {'json-type': json_type})
> +self._gen_qlit(name, 'builtin', {'json-type': json_type}, [])
>
>  def visit_enum_type(self, name, info, ifcond, values, prefix):
> -self._gen_qlit(name, 'enum', {'values': values})
> +self._gen_qlit(name, 'enum', {'values': values}, ifcond)
>
>  def visit_array_type(self, name, info, ifcond, element_type):
>  element = self._use_type(element_type)
> -self._gen_qlit('[' + element + ']', 'array', {'element-type': 
> element})
> +self._gen_qlit('[' + element + ']', 'array', {'element-type': 
> element},
> +   ifcond)
>
>  def visit_object_type_flat(self, name, info, ifcond, members, variants):
>  obj = {'members': [self._gen_member(m) for m in members]}
>  if variants:
>  obj.update(self._gen_variants(variants.tag_member.name,
>variants.variants))
> -self._gen_qlit(name, 'object', obj)
> +self._gen_qlit(name, 'object', obj, ifcond)
>
>  def visit_alternate_type(self, name, info, ifcond, variants):
>  self._gen_qlit(name, 'alternate',
> {'members': [{'type': self._use_type(m.type)}
> -for m in variants.variants]})
> +for m in variants.variants]}, ifcond)
>
>  def visit_command(self, name, info, ifcond, arg_type, ret_type,
>gen, success_response, boxed):
> @@ -169,11 +179,12 @@ const QLitObject %(c_name)s = %(c_string)s;
>  ret_type = ret_type or self._schema.the_empty_object_type
>  self._gen_qlit(name, 'command',
> 

[Qemu-devel] [PATCH v4 12/51] qapi-introspect: add preprocessor conditions to generated QLit

2018-01-11 Thread Marc-André Lureau
The generator will take (obj, condition) tuples to wrap generated QLit
objects for 'obj' with #if/#endif conditions.

This commit adds 'ifcond' condition to top-level QLit objects.

See generated tests/test-qmp-introspect.c. Example diff after this patch:

--- before  2018-01-08 11:55:24.757083654 +0100
+++ tests/test-qmp-introspect.c 2018-01-08 13:08:44.477641629 +0100
@@ -51,6 +51,8 @@
 { "name", QLIT_QSTR("EVENT_F"), },
 {}
 })),
+#if defined(TEST_IF_CMD)
+#if defined(TEST_IF_STRUCT)
 QLIT_QDICT(((QLitDictEntry[]) {
 { "arg-type", QLIT_QSTR("5"), },
 { "meta-type", QLIT_QSTR("command"), },
@@ -58,12 +60,16 @@
 { "ret-type", QLIT_QSTR("0"), },
 {}
 })),
+#endif /* defined(TEST_IF_STRUCT) */
+#endif /* defined(TEST_IF_CMD) */

Signed-off-by: Marc-André Lureau 
---
 scripts/qapi-introspect.py | 31 +--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index b1d08ec97b..7d3a5c37fd 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -17,6 +17,15 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 def indent(level):
 return level * 4 * ' '
 
+if isinstance(obj, tuple):
+ifobj, ifcond = obj
+ret = gen_if(ifcond)
+ret += to_qlit(ifobj, level)
+endif = gen_endif(ifcond)
+if endif:
+ret += '\n' + endif
+return ret
+
 ret = ''
 if not suppress_first_indent:
 ret += indent(level)
@@ -25,7 +34,7 @@ def to_qlit(obj, level=0, suppress_first_indent=False):
 elif isinstance(obj, str):
 ret += 'QLIT_QSTR(' + to_c_string(obj) + ')'
 elif isinstance(obj, list):
-elts = [to_qlit(elt, level + 1)
+elts = [to_qlit(elt, level + 1).strip('\n')
 for elt in obj]
 elts.append(indent(level + 1) + "{}")
 ret += 'QLIT_QLIST(((QLitObject[]) {\n'
@@ -121,12 +130,12 @@ const QLitObject %(c_name)s = %(c_string)s;
 return '[' + self._use_type(typ.element_type) + ']'
 return self._name(typ.name)
 
-def _gen_qlit(self, name, mtype, obj):
+def _gen_qlit(self, name, mtype, obj, ifcond):
 if mtype not in ('command', 'event', 'builtin', 'array'):
 name = self._name(name)
 obj['name'] = name
 obj['meta-type'] = mtype
-self._qlits.append(obj)
+self._qlits.append((obj, ifcond))
 
 def _gen_member(self, member):
 ret = {'name': member.name, 'type': self._use_type(member.type)}
@@ -142,26 +151,27 @@ const QLitObject %(c_name)s = %(c_string)s;
 return {'case': variant.name, 'type': self._use_type(variant.type)}
 
 def visit_builtin_type(self, name, info, json_type):
-self._gen_qlit(name, 'builtin', {'json-type': json_type})
+self._gen_qlit(name, 'builtin', {'json-type': json_type}, [])
 
 def visit_enum_type(self, name, info, ifcond, values, prefix):
-self._gen_qlit(name, 'enum', {'values': values})
+self._gen_qlit(name, 'enum', {'values': values}, ifcond)
 
 def visit_array_type(self, name, info, ifcond, element_type):
 element = self._use_type(element_type)
-self._gen_qlit('[' + element + ']', 'array', {'element-type': element})
+self._gen_qlit('[' + element + ']', 'array', {'element-type': element},
+   ifcond)
 
 def visit_object_type_flat(self, name, info, ifcond, members, variants):
 obj = {'members': [self._gen_member(m) for m in members]}
 if variants:
 obj.update(self._gen_variants(variants.tag_member.name,
   variants.variants))
-self._gen_qlit(name, 'object', obj)
+self._gen_qlit(name, 'object', obj, ifcond)
 
 def visit_alternate_type(self, name, info, ifcond, variants):
 self._gen_qlit(name, 'alternate',
{'members': [{'type': self._use_type(m.type)}
-for m in variants.variants]})
+for m in variants.variants]}, ifcond)
 
 def visit_command(self, name, info, ifcond, arg_type, ret_type,
   gen, success_response, boxed):
@@ -169,11 +179,12 @@ const QLitObject %(c_name)s = %(c_string)s;
 ret_type = ret_type or self._schema.the_empty_object_type
 self._gen_qlit(name, 'command',
{'arg-type': self._use_type(arg_type),
-'ret-type': self._use_type(ret_type)})
+'ret-type': self._use_type(ret_type)}, ifcond)
 
 def visit_event(self, name, info, ifcond, arg_type, boxed):
 arg_type = arg_type or self._schema.the_empty_object_type
-self._gen_qlit(name, 'event', {'arg-type': self._use_type(arg_type)})
+self._gen_qlit(name, 'event', {'arg-type':