Eric Blake <ebl...@redhat.com> writes: > On 09/23/2014 08:23 AM, Markus Armbruster wrote: >> Eric Blake <ebl...@redhat.com> writes: >> >>> The previous commit demonstrated that the generator had several >>> flaws with less-than-perfect enums: >>> - an enum that listed the same string twice (or two variant >>> strings that map to the same C enum) ended up generating an >>> invalid C enum >>> - because the generator adds a _MAX terminator to each enum, >>> the use of an enum member 'max' can also cause this clash >>> - if an enum omits 'data', the generator left a python stack >>> trace rather than a graceful message >>> - an enum used a non-array 'data' was silently accepted by >>> the parser >>> - an enum that used non-string members in the 'data' member >>> was silently accepted by the parser >>> >>> Add check_enum to cover these situations, and update testcases >>> to match. While valid .json files won't trigger any of these >>> cases, we might as well be nicer to developers that make a typo >>> while trying to add new QAPI code. >>> >>> Signed-off-by: Eric Blake <ebl...@redhat.com> >>> --- > >>> --- a/tests/qapi-schema/enum-clash-member.err >>> +++ b/tests/qapi-schema/enum-clash-member.err >>> @@ -0,0 +1 @@ >>> +tests/qapi-schema/enum-clash-member.json:2: enum 'MyEnum' member 'ONE' >>> clashes with 'one' >>> diff --git a/tests/qapi-schema/enum-clash-member.exit >>> b/tests/qapi-schema/enum-clash-member.exit >>> index 573541a..d00491f 100644 >>> --- a/tests/qapi-schema/enum-clash-member.exit >>> +++ b/tests/qapi-schema/enum-clash-member.exit >>> @@ -1 +1 @@ >>> -0 >>> +1 >>> diff --git a/tests/qapi-schema/enum-clash-member.json >>> b/tests/qapi-schema/enum-clash-member.json >>> index cb4b428..c668ff5 100644 >>> --- a/tests/qapi-schema/enum-clash-member.json >>> +++ b/tests/qapi-schema/enum-clash-member.json >>> @@ -1,2 +1,2 @@ >>> -# FIXME: we should reject enums where members will clash in C switch >>> +# we reject enums where members will clash in C switch >>> { 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] } >> >> Actually in PATCH 05 already: "clash in C switch". I guess you mean we >> generate an enum with clashing enumeration constants. In the test case, >> we'd generate MY_ENUM_ONE (I think) both for 'one' and 'ONE'. Correct? > > Correct; the generated C code would include an invalid switch statement > with two repetitions of the same spelling of a case label.
Actually, it generates a broken enum definition. For instance, { 'enum': 'MyEnum', 'data': [ 'one', 'ONE' ] } produces typedef enum BadEnum { BAD_ENUM_ONE = 0, BAD_ENUM_ONE = 1, BAD_ENUM_MAX = 2, } BadEnum; Drop "in C switch" from the comment? > In patch 5, > the test case demonstrates that the parser was silently accepting code > that resulted in a clash in the generated C code; this patch updates > both qapi.py to make it a hard error, and the testsuite to change from > (accidental) pass to (intentional) error detection, so that we no longer > have to worry about the issue in the generated C code. > > The same principle applies throughout my series - I first introduced new > tests in isolation for existing pre-patch behavior, with FIXME comments > where the tests expose bogus behavior, then in later patches fix the > parser to reject bogus behavior and update the test to match that it now > covers the new error message. That's exactly how I like it done. >>> +++ b/tests/qapi-schema/enum-dict-member.err >>> @@ -0,0 +1 @@ >>> +tests/qapi-schema/enum-dict-member.json:2: enum 'MyEnum' member >>> OrderedDict([('value', 'str')])' is not a string >> >> Error message is in terms of implementation instead of source. Since >> this is merely a development tool, it'll do. Same elsewhere, and I'm >> not going to flag it. Precedents in master quite possible. > > Yeah, I couldn't figure a way to get back at the original text typed by > the user. I'm open to suggestions, but I'm (obviously) okay with > leaving it as is. Let's leave it as is for now. >>> +++ b/tests/qapi-schema/enum-max-member.json >>> @@ -1,3 +1,3 @@ >>> -# FIXME: we should either reject user-supplied 'max', or munge the implicit >>> -# max value we generate at the end of an array >>> +# we reject user-supplied 'max' for clashing with implicit enum end >>> +# FIXME: should we instead munge the the implicit value to avoid the clash? >> >> Or pick an identifier for the max member so that it cannot clash with >> the ones we generate for the user's members. >> >> The generator picks identifiers pretty much thoughtlessly in general. >> If something clashes, the C compiler spits it out, and you get to fiddle >> with the .json. > > Well, hopefully by hoisting the error message away from C compilation > time (late) to qapi.py runtime (early), we have made it easier for > anyone actually needing the name 'max' to identify what still needs > fixing. At any rate, I'm always a fan of erroring out as early as > possible, rather than waiting for an obscure crash later on in the C > compilation :) One saturday of happy hacking, followed by years of chipping away at the mess... >> [...] >> >> Reviewed-by: Markus Armbruster <arm...@redhat.com> > > Thanks.