qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: QEMU <qemu-devel@nongnu.org>, Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members
Date: Thu, 11 Jan 2018 22:24:22 +0100	[thread overview]
Message-ID: <CAJ+F1CLdM92EkdPDw=UL65G476dMMUNMVaLd3hi-66Mk9N99Jg@mail.gmail.com> (raw)
In-Reply-To: <87r2s5ipgd.fsf@dusky.pond.sub.org>

Hi

On Fri, Dec 8, 2017 at 9:38 AM, Markus Armbruster <armbru@redhat.com> wrote:
> A bit more detail in the commit message would make this patch easier to
> review.
>
> Marc-André Lureau <marcandre.lureau@redhat.com> writes:
>
>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>> ---
>>  scripts/qapi.py                         | 39 ++++++++++++++++++++++++++++-----
>>  tests/Makefile.include                  |  1 -
>>  tests/qapi-schema/enum-dict-member.err  |  1 -
>>  tests/qapi-schema/enum-dict-member.exit |  1 -
>>  tests/qapi-schema/enum-dict-member.json |  2 --
>>  tests/qapi-schema/enum-dict-member.out  |  0
>>  tests/qapi-schema/qapi-schema-test.json |  5 +++--
>>  tests/qapi-schema/qapi-schema-test.out  |  3 ++-
>>  tests/qapi-schema/test-qapi.py          |  2 ++
>>  9 files changed, 41 insertions(+), 13 deletions(-)
>>  delete mode 100644 tests/qapi-schema/enum-dict-member.err
>>  delete mode 100644 tests/qapi-schema/enum-dict-member.exit
>>  delete mode 100644 tests/qapi-schema/enum-dict-member.json
>>  delete mode 100644 tests/qapi-schema/enum-dict-member.out
>>
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index 386a577a59..1535de9ce7 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -659,6 +659,14 @@ def check_if(expr, info):
>>              info, "'if' condition must be a string or a list of strings")
>>
>>
>> +def check_unknown_keys(info, dict, allowed_keys):
>> +    diff = set(dict) - allowed_keys
>> +    if not diff:
>> +        return
>> +    raise QAPISemError(info, "Dictionnary has unknown keys: %s (allowed: %s)" %
>
> s/Dictionnary/Dictionary/

ok

>
>> +        (', '.join(diff), ', '.join(allowed_keys)))
>
> I'm afraid this duplicates a part of check_keys().  Could it be factored
> out?

done

>
>> +
>> +
>>  def check_type(info, source, value, allow_array=False,
>>                 allow_dict=False, allow_optional=False,
>>                 allow_metas=[]):
>> @@ -739,6 +747,10 @@ def check_event(expr, info):
>>                 allow_metas=meta)
>>
>>
>> +def enum_get_values(expr):
>> +    return [e if isinstance(e, str) else e['name'] for e in expr['data']]
>> +
>> +
>>  def check_union(expr, info):
>>      name = expr['union']
>>      base = expr.get('base')
>> @@ -798,7 +810,7 @@ def check_union(expr, info):
>>          # If the discriminator names an enum type, then all members
>>          # of 'data' must also be members of the enum type.
>>          if enum_define:
>> -            if key not in enum_define['data']:
>> +            if key not in enum_get_values(enum_define):
>>                  raise QAPISemError(info,
>>                                     "Discriminator value '%s' is not found in "
>>                                     "enum '%s'"
>> @@ -806,7 +818,7 @@ def check_union(expr, info):
>>
>>      # If discriminator is user-defined, ensure all values are covered
>>      if enum_define:
>> -        for value in enum_define['data']:
>> +        for value in enum_get_values(enum_define):
>>              if value not in members.keys():
>>                  raise QAPISemError(info, "Union '%s' data missing '%s' branch"
>>                                     % (name, value))
>> @@ -837,7 +849,7 @@ def check_alternate(expr, info):
>>          if qtype == 'QTYPE_QSTRING':
>>              enum_expr = enum_types.get(value)
>>              if enum_expr:
>> -                for v in enum_expr['data']:
>> +                for v in enum_get_values(enum_expr):
>>                      if v in ['on', 'off']:
>>                          conflicting.add('QTYPE_QBOOL')
>>                      if re.match(r'[-+0-9.]', v): # lazy, could be tightened
>> @@ -865,6 +877,14 @@ def check_enum(expr, info):
>>          raise QAPISemError(info,
>>                             "Enum '%s' requires a string for 'prefix'" % name)
>>      for member in members:
>> +        if isinstance(member, dict):
>> +            if 'name' not in member:
>> +                raise QAPISemError(info, "Dictionary member of enum '%s' must "
>> +                                   "have a 'name' key" % name)
>> +            if 'if' in member:
>> +                check_if(member, info)
>> +            check_unknown_keys(info, member, {'name', 'if'})
>> +            member = member['name']
>>          check_name(info, "Member of enum '%s'" % name, member,
>>                     enum_member=True)
>>
>> @@ -1280,9 +1300,11 @@ class QAPISchemaObjectType(QAPISchemaType):
>>  class QAPISchemaMember(object):
>>      role = 'member'
>>
>> -    def __init__(self, name):
>> +    def __init__(self, name, ifcond=None):
>>          assert isinstance(name, str)
>> +        assert ifcond is None or isinstance(ifcond, str)
>>          self.name = name
>> +        self.ifcond = ifcond
>>          self.owner = None
>>
>>      def set_owner(self, name):
>
> QAPISchemaObjectTypeMember inherits .ifcond.  Peeking ahead: looks like
> it'll get used when we add conditions to object type members, PATCH
> 23ff.  Okay.  Mentioning it in the commit message wouldn't hurt, though.

It will *also* get used. Ok, updated commit message.

>
>> @@ -1559,7 +1581,14 @@ class QAPISchema(object):
>>                                              qtype_values, 'QTYPE'))
>>
>>      def _make_enum_members(self, values):
>> -        return [QAPISchemaMember(v) for v in values]
>> +        enum = []
>> +        for v in values:
>> +            ifcond = None
>> +            if isinstance(v, dict):
>> +                ifcond = v.get('if')
>> +                v = v['name']
>> +            enum.append(QAPISchemaMember(v, ifcond))
>
>
> I like brevity a lot, but if it's bought by assigning to a loop control
> variable, I pass.  Cleaner:
>
>            for v in values:
>                if isinstance(v, dict):
>                    name = v['name']
>                    ifcond = v.get('if')
>                else:
>                    name = v
>                    ifcond = None
>            enum.append(QAPISchemaMember(name, ifcond))
>

sure

>> +        return enum
>>
>>      def _make_implicit_enum_type(self, name, info, ifcond, values):
>>          # See also QAPISchemaObjectTypeMember._pretty_owner()
>> diff --git a/tests/Makefile.include b/tests/Makefile.include
>> index 8dac7c9083..a9f0ddbe01 100644
>> --- a/tests/Makefile.include
>> +++ b/tests/Makefile.include
>> @@ -443,7 +443,6 @@ qapi-schema += empty.json
>>  qapi-schema += enum-bad-name.json
>>  qapi-schema += enum-bad-prefix.json
>>  qapi-schema += enum-clash-member.json
>> -qapi-schema += enum-dict-member.json
>>  qapi-schema += enum-int-member.json
>>  qapi-schema += enum-member-case.json
>>  qapi-schema += enum-missing-data.json
>> diff --git a/tests/qapi-schema/enum-dict-member.err b/tests/qapi-schema/enum-dict-member.err
>> deleted file mode 100644
>> index 8ca146ea59..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.err
>> +++ /dev/null
>> @@ -1 +0,0 @@
>> -tests/qapi-schema/enum-dict-member.json:2: Member of enum 'MyEnum' requires a string name
>> diff --git a/tests/qapi-schema/enum-dict-member.exit b/tests/qapi-schema/enum-dict-member.exit
>> deleted file mode 100644
>> index d00491fd7e..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.exit
>> +++ /dev/null
>> @@ -1 +0,0 @@
>> -1
>> diff --git a/tests/qapi-schema/enum-dict-member.json b/tests/qapi-schema/enum-dict-member.json
>> deleted file mode 100644
>> index 79672e0f09..0000000000
>> --- a/tests/qapi-schema/enum-dict-member.json
>> +++ /dev/null
>> @@ -1,2 +0,0 @@
>> -# we reject any enum member that is not a string
>> -{ 'enum': 'MyEnum', 'data': [ { 'value': 'str' } ] }
>> diff --git a/tests/qapi-schema/enum-dict-member.out b/tests/qapi-schema/enum-dict-member.out
>> deleted file mode 100644
>> index e69de29bb2..0000000000
>
> Hmm.  The dict instance of "enum value must be of an appropriate JSON
> type" error class goes away in this patch, but the class remains.  Do we
> still cover it?
>
> There's enum-int-member.json, but it's not a good test: it dies in the
> lexer.  I think we should replace the two tests by a single one.
> Perhaps something like 'data': [ [] ] would do.

I replaced enum-dict-member by enum-bad-member. I left the int-member
test, because it has also the purpose to check the lexer.

>
>> diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
>> index dc2c444fc1..ad2b405d83 100644
>> --- a/tests/qapi-schema/qapi-schema-test.json
>> +++ b/tests/qapi-schema/qapi-schema-test.json
>> @@ -194,7 +194,8 @@
>>  { 'struct': 'TestIfStruct', 'data': { 'foo': 'int' },
>>    'if': 'defined(TEST_IF_STRUCT)' }
>>
>> -{ 'enum': 'TestIfEnum', 'data': [ 'foo', 'bar' ],
>> +{ 'enum': 'TestIfEnum', 'data':
>> +  [ 'foo', { 'name' : 'bar', 'if': 'defined(TEST_IF_ENUM_BAR)' } ],
>>    'if': 'defined(TEST_IF_ENUM)' }
>>
>>  { 'union': 'TestIfUnion', 'data': { 'foo': 'TestStruct' },
>> @@ -203,7 +204,7 @@
>>  { 'alternate': 'TestIfAlternate', 'data': { 'foo': 'int', 'bar': 'TestStruct' },
>>    'if': 'defined(TEST_IF_ALT) && defined(TEST_IF_STRUCT)' }
>>
>> -{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct' },
>> +{ 'command': 'TestIfCmd', 'data': { 'foo': 'TestIfStruct', 'bar': 'TestIfEnum' },
>>    'if': 'defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)' }
>>
>>  { 'event': 'TestIfEvent', 'data': { 'foo': 'TestIfStruct' },
>
> Should this hunk be in PATCH 04?

It could, but it is not necessary until conditionals are added to
verify introspection generation.

>
>> diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
>> index 9a7cafc269..8a0cf1a551 100644
>> --- a/tests/qapi-schema/qapi-schema-test.out
>> +++ b/tests/qapi-schema/qapi-schema-test.out
>> @@ -74,7 +74,7 @@ command TestIfCmd q_obj_TestIfCmd-arg -> None
>>      if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
>>  enum TestIfEnum
>>      member foo:
>> -    member bar:
>> +    member bar: if=defined(TEST_IF_ENUM_BAR)
>>      if defined(TEST_IF_ENUM)
>>  event TestIfEvent q_obj_TestIfEvent-arg
>>     boxed=False
>> @@ -228,6 +228,7 @@ object q_obj_EVENT_D-arg
>>      member enum3: EnumOne optional=True
>>  object q_obj_TestIfCmd-arg
>>      member foo: TestIfStruct optional=False
>> +    member bar: TestIfEnum optional=False
>>      if defined(TEST_IF_CMD) && defined(TEST_IF_STRUCT)
>>  object q_obj_TestIfEvent-arg
>>      member foo: TestIfStruct optional=False
>> diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
>> index 67c6c1ecef..a86c3b5ee1 100644
>> --- a/tests/qapi-schema/test-qapi.py
>> +++ b/tests/qapi-schema/test-qapi.py
>> @@ -56,6 +56,8 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
>>              print '    member %s:' % m.name,
>>              if isinstance(m, QAPISchemaObjectTypeMember):
>>                  print '%s optional=%s' % (m.type.name, m.optional),
>> +            if m.ifcond:
>> +                print 'if=%s' % m.ifcond,
>>              print
>>
>>      @staticmethod
>



-- 
Marc-André Lureau

  reply	other threads:[~2018-01-11 21:24 UTC|newest]

Thread overview: 118+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-11 11:05 [Qemu-devel] [PATCH v3 00/50] Hi, Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 01/50] qlit: add qobject_from_qlit() Marc-André Lureau
2017-09-13 13:51   ` Eric Blake
2017-09-13 14:08     ` Marc-André Lureau
2017-12-06 14:37       ` Markus Armbruster
2017-12-06 14:37   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 02/50] qapi: generate a literal qobject for introspection Marc-André Lureau
2017-12-06 15:17   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 03/50] qapi2texi: minor python code simplification Marc-André Lureau
2017-12-06 15:19   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 04/50] qapi: add 'if' to top-level expressions Marc-André Lureau
2017-12-06 15:46   ` Markus Armbruster
2017-12-06 16:23   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 05/50] qapi: add tests for invalid 'if' Marc-André Lureau
2017-12-06 16:34   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 06/50] qapi: pass 'if' condition into QAPISchemaEntity objects Marc-André Lureau
2017-12-06 17:13   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 07/50] qapi: add 'ifcond' to visitor methods Marc-André Lureau
2017-12-06 17:23   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 08/50] qapi: mcgen() shouldn't indent # lines Marc-André Lureau
2017-12-06 17:41   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 09/50] qapi: add #if/#endif helpers Marc-André Lureau
2017-12-07 14:10   ` Markus Armbruster
2018-01-11 21:21     ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 10/50] qapi-introspect: modify to_qlit() to append ', ' on level > 0 Marc-André Lureau
2017-12-07 14:47   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 11/50] qapi-introspect: modify to_qlit() to generate #if code Marc-André Lureau
2017-12-07 14:50   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 12/50] qapi-introspect: add preprocessor conditions to generated QLit Marc-André Lureau
2017-12-07 15:41   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 13/50] qapi-commands: add #if conditions to commands Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 14/50] qapi-event: add #if conditions to events Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 15/50] qapi-types: refactor variants handling Marc-André Lureau
2017-12-07 15:57   ` Markus Armbruster
2018-01-11 21:22     ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 16/50] qapi-types: add #if conditions to types & visitors Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 17/50] qapi: do not define enumeration value explicitely Marc-André Lureau
2017-12-07 16:23   ` Markus Armbruster
2017-12-07 17:01     ` Marc-André Lureau
2017-12-08  7:50       ` Markus Armbruster
2018-01-11 21:24         ` Marc-André Lureau
2018-02-02 14:43           ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 18/50] qapi: change enum visitor to take QAPISchemaMember Marc-André Lureau
2017-12-07 17:34   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 19/50] qapi: add 'if' to enum members Marc-André Lureau
2017-12-08  8:38   ` Markus Armbruster
2018-01-11 21:24     ` Marc-André Lureau [this message]
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 20/50] qapi-event: add 'if' condition to generated enum Marc-André Lureau
2017-12-08 13:58   ` Markus Armbruster
2017-12-08 14:07     ` Markus Armbruster
2018-01-11 21:31       ` Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 21/50] qapi: add #if conditions on generated enum members Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 22/50] tests: add some enum members tests Marc-André Lureau
2017-12-08 17:58   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 23/50] qapi: add 'if' to struct members and implicit objects members Marc-André Lureau
2017-12-09  8:18   ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 24/50] qapi: add some struct member tests Marc-André Lureau
2017-12-09  9:07   ` Markus Armbruster
2018-01-11 21:31     ` Marc-André Lureau
2018-02-02 14:51       ` Markus Armbruster
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 25/50] qapi: add #if conditions to generated struct members Marc-André Lureau
2017-09-11 11:05 ` [Qemu-devel] [PATCH v3 26/50] qapi: add 'if' on union variants Marc-André Lureau
2017-12-11 10:36   ` Markus Armbruster
2018-01-11 21:32     ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 27/50] qapi: add #if conditions to generated variants Marc-André Lureau
2017-12-13 12:37   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 28/50] qapi: add 'if' to alternate variant Marc-André Lureau
2017-12-12 14:51   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 29/50] qapi: add tests for invalid alternate Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 30/50] qapi: add #if conditions to generated alternate variants Marc-André Lureau
2017-12-12 19:25   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 31/50] docs: document schema configuration Marc-André Lureau
2017-12-13 10:41   ` Markus Armbruster
2017-12-13 19:49     ` Eric Blake
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 32/50] qapi2texi: add 'If:' section to generated documentation Marc-André Lureau
2017-12-13 12:35   ` Markus Armbruster
2017-12-13 19:54     ` Eric Blake
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 33/50] qapi2texi: add 'If:' condition to enum values Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 34/50] qapi2texi: add 'If:' condition to struct members Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 35/50] qapi2texi: add condition to variants Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 36/50] qapi: add conditions to VNC type/commands/events on the schema Marc-André Lureau
2017-12-13 14:12   ` Markus Armbruster
2017-12-13 14:20     ` Daniel P. Berrange
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 37/50] qapi: add conditions to SPICE " Marc-André Lureau
2017-12-13 14:17   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 38/50] qapi: add conditions to REPLICATION type/commands " Marc-André Lureau
2017-12-13 14:19   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 39/50] qapi-commands: don't initialize command list in qmp_init_marshall() Marc-André Lureau
2017-12-13 16:23   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 40/50] qapi: add -i/--include filename.h Marc-André Lureau
2017-12-14 13:50   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 41/50] qapi: add a 'unit' pragma Marc-André Lureau
2017-12-14 13:54   ` Markus Armbruster
2017-12-14 14:00     ` Marc-André Lureau
2017-12-14 14:33       ` Markus Armbruster
2017-12-14 16:08   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 42/50] qapi: add a -u/--unit option to specify which unit to visit Marc-André Lureau
2017-12-14 16:16   ` Markus Armbruster
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 43/50] build-sys: move qmp-introspect per target Marc-André Lureau
2017-12-14 16:30   ` Markus Armbruster
2018-01-11 21:32     ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 44/50] build-sys: add a target schema Marc-André Lureau
2017-12-14 16:34   ` Markus Armbruster
2018-01-11 21:32     ` Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 45/50] qapi: make rtc-reset-reinjection depend on TARGET_I386 Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 46/50] qapi: make s390 commands depend on TARGET_S390X Marc-André Lureau
2017-09-13  7:45   ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 47/50] target.json: add a note about query-cpu* not being s390x-specific Marc-André Lureau
2017-09-13  7:46   ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 48/50] qapi: make query-gic-capabilities depend on TARGET_ARM Marc-André Lureau
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 49/50] qapi: make query-cpu-model-expansion depend on s390 or x86 Marc-André Lureau
2017-09-12 17:40   ` Eduardo Habkost
2017-09-13  7:47   ` Cornelia Huck
2017-09-11 11:06 ` [Qemu-devel] [PATCH v3 50/50] qapi: make query-cpu-definitions depend on specific targets Marc-André Lureau
2017-09-12 17:45   ` Eduardo Habkost
2017-09-13  7:48   ` Cornelia Huck
2017-09-11 11:54 ` [Qemu-devel] [PATCH v3 00/50] Hi, no-reply
2017-12-18 13:14 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJ+F1CLdM92EkdPDw=UL65G476dMMUNMVaLd3hi-66Mk9N99Jg@mail.gmail.com' \
    --to=marcandre.lureau@gmail.com \
    --cc=armbru@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).