All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: kwolf@redhat.com, lcapitulino@redhat.com, qemu-devel@nongnu.org,
	mdroth@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH V6 03/10] qapi script: check correctness of discriminator values in union
Date: Fri, 14 Feb 2014 10:43:27 +0800	[thread overview]
Message-ID: <52FD82CF.8020500@linux.vnet.ibm.com> (raw)
In-Reply-To: <8738jnvydi.fsf@blackfin.pond.sub.org>

于 2014/2/13 23:14, Markus Armbruster 写道:
> Wenchao Xia <xiawenc@linux.vnet.ibm.com> writes:
> 
>> It will check whether the values specified are written correctly,
>> and whether all enum values are covered, when discriminator is a
>> pre-defined enum type
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> ---
>>   scripts/qapi-visit.py |   17 +++++++++++++++++
>>   scripts/qapi.py       |   31 +++++++++++++++++++++++++++++++
>>   2 files changed, 48 insertions(+), 0 deletions(-)
>>
>> diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
>> index 65f1a54..c0efb5f 100644
>> --- a/scripts/qapi-visit.py
>> +++ b/scripts/qapi-visit.py
>> @@ -255,6 +255,23 @@ def generate_visit_union(expr):
>>           assert not base
>>           return generate_visit_anon_union(name, members)
>>   
>> +    # If discriminator is specified and it is a pre-defined enum in schema,
>> +    # check its correctness
>> +    enum_define = discriminator_find_enum_define(expr)
>> +    if enum_define:
>> +        for key in members:
>> +            if not key in enum_define["enum_values"]:
>> +                sys.stderr.write("Discriminator value '%s' is not found in "
>> +                                 "enum '%s'\n" %
>> +                                 (key, enum_define["enum_name"]))
>> +                sys.exit(1)
> 
> Can this happen?  If yes, why isn't it diagnosed in qapi.py, like all
> the other semantic errors?
> 
  I think the parse procedure contains two part:
1 read qapi-schema.json and parse it into exprs.
2 translate exprs into final output.
  Looking at qapi.py, qapi-visit.py, qapi-types.py, it seems qapi.py is
in charge of step 1 handling literal error, and other two script are in
charge of step 2. The above error can be only detected in step 2 after
all enum defines are remembered in step 1, so I didn't add those things
into qapi.py.

  I guess you want to place the check inside parse_schema() to let
test case detect it easier, one way to go is, let qapi.py do checks
for step 2:

def parse_schema(fp):
    try:
        schema = QAPISchema(fp)
    except QAPISchemaError, e:
        print >>sys.stderr, e
        exit(1)

    exprs = []

    for expr in schema.exprs:
        if expr.has_key('enum'):
            add_enum(expr['enum'])
        elif expr.has_key('union'):
            add_union(expr)
            add_enum('%sKind' % expr['union'])
        elif expr.has_key('type'):
            add_struct(expr)
        exprs.append(expr)

+    for expr in schema.exprs:
+        if expr.has_key('union'):
+            #check code

    return exprs

  This way qapi.py can detect such errors. Disadvantage is that,
qapi.py is invloved for step 2 things, so some code in qapi.py
and qapi-visit.py may be dupicated, here the "if .... union...
discriminator" code may appear in both qapi.py and qapi-visit.py.

>> +        for key in enum_define["enum_values"]:
>> +            if not key in members:
>> +                sys.stderr.write("Enum value '%s' is not covered by a branch "
>> +                                 "of union '%s'\n" %
>> +                                 (key, name))
>> +                sys.exit(1)
>> +
> 
> Likewise.
> 
>>       ret = generate_visit_enum('%sKind' % name, members.keys())
>>   
>>       if base:
>> diff --git a/scripts/qapi.py b/scripts/qapi.py
>> index cf34768..0a3ab80 100644
>> --- a/scripts/qapi.py
>> +++ b/scripts/qapi.py
>> @@ -385,3 +385,34 @@ def guardend(name):
>>   
>>   ''',
>>                    name=guardname(name))
>> +

  The funtions below are likely helper funtions, I planed to put them
into qapi_helper.py, but they are not much so kepted for easy.

>> +# This function can be used to check whether "base" is valid
>> +def find_base_fields(base):
>> +    base_struct_define = find_struct(base)
>> +    if not base_struct_define:
>> +        return None
>> +    return base_struct_define.get('data')
>> +
>> +# Return the discriminator enum define, if discriminator is specified in
>> +# @expr and it is a pre-defined enum type
>> +def discriminator_find_enum_define(expr):
>> +    discriminator = expr.get('discriminator')
>> +    base = expr.get('base')
>> +
>> +    # Only support discriminator when base present
>> +    if not (discriminator and base):
>> +        return None
>> +
>> +    base_fields = find_base_fields(base)
>> +
>> +    if not base_fields:
>> +        raise StandardError("Base '%s' is not a valid type\n"
>> +                            % base)
> 
> Why not QAPISchemaError, like for other semantic errors?
> 

  I think QAPISchemaError is a literal error of step 1, here
it can't be used unless we record the text/line number belong to
each expr.

>> +
>> +    discriminator_type = base_fields.get(discriminator)
>> +
>> +    if not discriminator_type:
>> +        raise StandardError("Discriminator '%s' not found in schema\n"
>> +                            % discriminator)
> 
> Likewise.
> 
>> +
>> +    return find_enum(discriminator_type)
> 
> All errors should have a test in tests/qapi-schema/.  I can try to add
> tests for you when I rebase your 09/10.
> 

  reply	other threads:[~2014-02-14  2:43 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-10 21:48 [Qemu-devel] [PATCH V6 00/10] qapi script: support enum as discriminator and better enum name Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 01/10] qapi script: remember enum values Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 02/10] qapi script: add check for duplicated key Wenchao Xia
2014-02-13 15:14   ` Markus Armbruster
2014-02-14  1:50     ` Wenchao Xia
2014-02-17  8:28       ` Markus Armbruster
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 03/10] qapi script: check correctness of discriminator values in union Wenchao Xia
2014-02-13 15:14   ` Markus Armbruster
2014-02-14  2:43     ` Wenchao Xia [this message]
2014-02-14  9:23       ` Markus Armbruster
2014-02-17  1:50         ` Wenchao Xia
2014-02-17  8:11           ` Markus Armbruster
2014-02-17 13:59           ` Luiz Capitulino
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 04/10] qapi script: code move for generate_enum_name() Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 05/10] qapi script: use same function to generate enum string Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 06/10] qapi script: support pre-defined enum type as discriminator in union Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 07/10] qapi: convert BlockdevOptions to use enum discriminator Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 08/10] qapi script: do not allow string discriminator Wenchao Xia
2014-02-13 15:18   ` Markus Armbruster
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 09/10] tests: add cases for inherited struct and union with discriminator Wenchao Xia
2014-02-13 14:53   ` Markus Armbruster
2014-02-13 15:11     ` Luiz Capitulino
2014-02-14  2:47       ` Wenchao Xia
2014-02-10 21:48 ` [Qemu-devel] [PATCH V6 10/10] qapi script: do not add "_" for every capitalized char in enum Wenchao Xia
2014-02-11 13:17 ` [Qemu-devel] [PATCH V6 00/10] qapi script: support enum as discriminator and better enum name Eric Blake
2014-02-11 19:13 ` Luiz Capitulino
2014-02-13 15:22   ` Luiz Capitulino
2014-02-13 15:23 ` Markus Armbruster
2014-02-14  2:53   ` Wenchao Xia

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=52FD82CF.8020500@linux.vnet.ibm.com \
    --to=xiawenc@linux.vnet.ibm.com \
    --cc=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.