aboutsummaryrefslogtreecommitdiff
path: root/scripts/qapi
AgeCommit message (Collapse)Author
2021-05-20qapi/parser: Rework _check_pragma_list_of_str as a TypeGuardJohn Snow
TypeGuards wont exist in Python proper until 3.10. Ah well. We can hack up our own by declaring this function to return the type we claim it checks for and using this to safely downcast object -> List[str]. In so doing, I bring this function under _pragma so it can use the 'info' object in its closure. Having done this, _pragma also now no longer needs to take a 'self' parameter, so drop it. To help with line-length, and with the context evident from its new scope, rename the function to the shorter check_list_str(). Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-12-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: Fix token membership tests when token can be NoneJohn Snow
When the token can be None (EOF), we can't use 'x in "abc"' style membership tests to group types of tokens together, because 'None in "abc"' is a TypeError. Easy enough to fix. (Use a tuple: It's neither a static typing error nor a runtime error to check for None in Tuple[str, ...]) Add tests to prevent a regression. (Note: they cannot be added prior to this fix, as the unhandled stack trace will not match test output in the CI system.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-11-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi: add must_match helperJohn Snow
Mypy cannot generally understand that these regex functions cannot possibly fail. Add a "must_match" helper that makes this clear for mypy. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-10-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: Use @staticmethod where appropriateJohn Snow
No self, no thank you! (Quiets pylint warnings.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: assert object keys are stringsJohn Snow
The single quote token implies the value is a string. Assert this to be the case, to allow us to write an accurate return type for get_members. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-8-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: enforce all top-level expressions must be dict in _parse()John Snow
Instead of using get_expr nested=False, allow get_expr to always return any expression. In exchange, add a new error message to the top-level parser that explains the semantic error: Top-level expressions must always be JSON objects. This helps mypy understand the rest of this function which assumes that get_expr did indeed return a dict. The exception type changes from QAPIParseError to QAPISemError as a result, and the error message in two tests now changes. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: Assert lexer value is a stringJohn Snow
The type checker can't narrow the type of the token value to string, because it's only loosely correlated with the return token. We know that a token of '#' should always have a "str" value. Add an assertion. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: factor parsing routine into methodJohn Snow
For the sake of keeping __init__ smaller (and treating it more like a gallery of what state variables we can expect to see), put the actual parsing action into a parse method. It remains invoked from the init method to reduce churn. To accomplish this, @previously_included becomes the private data member ._included, and the filename is stashed as ._fname. Add any missing declarations to the init method, and group them by function so they can be understood quickly at a glance. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/source: Remove line number from QAPISourceInfo initializerJohn Snow
With the QAPISourceInfo(None, None, None) construct gone, there's no longer any reason to have to specify that a file starts on the first line. Remove it from the initializer and default it to 1. Remove the last vestiges where we check for 'line' being unset, that can't happen, now. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-4-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-05-20qapi/parser: Don't try to handle file errorsJohn Snow
Fixes: f5d4361cda Fixes: 52a474180a Fixes: 46f49468c6 Remove the try/except block that handles file-opening errors in QAPISchemaParser.__init__() and add one each to QAPISchemaParser._include() and QAPISchema.__init__() respectively. This simultaneously fixes the typing of info.fname (f5d4361cda), A static typing violation in test-qapi (46f49468c6), and a regression of an error message (52a474180a). The short-ish version of what motivates this patch is: - It's hard to write a good error message in the init method, because we need to determine the context of our caller to do so. It's easier to just let the caller write the message. - We don't want to allow QAPISourceInfo(None, None, None) to exist. The typing introduced by commit f5d4361cda types the 'fname' field as (non-optional) str, which was premature until the removal of this construct. - Errors made using such an object are currently incorrect (since 52a474180a) - It's not technically a semantic error if we cannot open the schema. - There are various typing constraints that make mixing these two cases undesirable for a single special case. - test-qapi's code handling an fname of 'None' is now dead, drop it. Additionally, Not all QAPIError objects have an 'info' field (since 46f49468), so deleting this stanza corrects a typing oversight in test-qapi introduced by that commit. Other considerations: - open() is moved to a 'with' block to ensure file pointers are cleaned up deterministically. - Python 3.3 deprecated IOError and made it a synonym for OSError. Avoid the misleading perception these exception handlers are narrower than they really are. The long version: The error message here is incorrect (since commit 52a474180a): > python3 qapi-gen.py 'fake.json' qapi-gen.py: qapi-gen.py: can't read schema file 'fake.json': No such file or directory In pursuing it, we find that QAPISourceInfo has a special accommodation for when there's no filename. Meanwhile, the intent when QAPISourceInfo was typed (f5d4361cda) was non-optional 'str'. This usage was overlooked. To remove this, I'd want to avoid having a "fake" QAPISourceInfo object. I also don't want to explicitly begin accommodating QAPISourceInfo itself being None, because we actually want to eventually prove that this can never happen -- We don't want to confuse "The file isn't open yet" with "This error stems from a definition that wasn't defined in any file". (An earlier series tried to create a dummy info object, but it was tough to prove in review that it worked correctly without creating new regressions. This patch avoids that distraction. We would like to first prove that we never raise QAPISemError for any built-in object before we add "special" info objects. We aren't ready to do that yet.) So, which way out of the labyrinth? Here's one way: Don't try to handle errors at a level with "mixed" semantic contexts; i.e. don't mix inclusion errors (should report a source line where the include was triggered) and command line errors (where we specified a file we couldn't read). Remove the error handling from the initializer of the parser. Pythonic! Now it's the caller's job to figure out what to do about it. Handle the error in QAPISchemaParser._include() instead, where we can write a targeted error message where we are guaranteed to have an 'info' context to report with. The root level error can similarly move to QAPISchema.__init__(), where we know we'll never have an info context to report with, so we use a more abstract error type. Now the error looks sensible again: > python3 qapi-gen.py 'fake.json' qapi-gen.py: can't read schema file 'fake.json': No such file or directory With these error cases separated, QAPISourceInfo can be solidified as never having placeholder arguments that violate our desired types. Clean up test-qapi along similar lines. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210519183951.3946870-2-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error.py: enable mypy checksJohn Snow
Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error: Add type hintsJohn Snow
No functional change. Note: QAPISourceError's info parameter is Optional[] because schema.py treats the info property of its various classes as Optional to accommodate built-in types, which have no source. See prior commit 'qapi/error: assert QAPISourceInfo is not None'. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-8-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error.py: enable pylint checksJohn Snow
Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error.py: move QAPIParseError to parser.pyJohn Snow
Keeping it in error.py will create some cyclic import problems when we add types to the QAPISchemaParser. Callers don't need to know the details of QAPIParseError unless they are parsing or dealing directly with the parser, so this won't create any harsh new requirements for callers in the general case. Update error.py with a little docstring that gives a nod to where the error may now be found. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error: assert QAPISourceInfo is not NoneJohn Snow
Built-in stuff is not parsed from a source file, and therefore have no QAPISourceInfo. If such None info was used for reporting an error, built-in stuff would be broken. Programming error. Instead of reporting a confusing error with bogus source location then, we better crash. We currently crash only if self.col was set. Assert that self.info is not None in order to crash reliably. We can not yet change the type of the initializer to prove this cannot happen at static analysis time before the remainder of the code is fully typed. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error: Make QAPISourceError 'col' parameter optionalJohn Snow
It's already treated as optional, with one direct caller and some subclass callers passing 'None'. Make it officially optional, which requires moving the position of the argument to come after all required parameters. QAPISemError becomes functionally identical to QAPISourceError. Keep the name to preserve its semantic meaning and avoid code churn, but remove the now-useless __init__ wrapper. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-4-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error: Use Python3-style super()John Snow
Missed in commit 2cae67bcb5 "qapi: Use super() now we have Python 3". Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210421192233.3542904-3-jsnow@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/error: Repurpose QAPIError as an abstract base exception classJohn Snow
Rename QAPIError to QAPISourceError, and then create a new QAPIError class that serves as the basis for all of our other custom exceptions, without specifying any class properties. This leaves QAPIError as a package-wide error class that's suitable for any current or future errors. (Right now, we don't have any errors that DON'T also want to specify a Source location, but this MAY change. In these cases, a common abstract ancestor would be desired.) Add docstrings to explain the intended function of each error class. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421192233.3542904-2-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr: Update authorship and copyright informationJohn Snow
Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-18-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Use tuples instead of lists for static dataJohn Snow
It is -- maybe -- possibly -- three nanoseconds faster. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-17-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Add docstringsJohn Snow
Now with more :words:! Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-16-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr: Only explicitly prohibit 'Kind' nor 'List' for type namesJohn Snow
Per list review: qapi-code-gen.txt reserves suffixes Kind and List only for type names, but the code rejects them for events and commands, too. It turns out we reject them earlier anyway: In check_name_upper() for event names, and in check_name_lower() for command names. Still, adjust the code for clarity over what precisely we are guarding against. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-15-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: enable pylint checksJohn Snow
Signed-off-by: John Snow <jsnow@redhat.com> Tested-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Tested-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-14-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Remove single-letter variableJohn Snow
Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-13-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Consolidate check_if_str calls in check_ifJohn Snow
This is a small rewrite to address some minor style nits. Don't compare against the empty list to check for the empty condition, and move the normalization forward to unify the check on the now-normalized structure. With the check unified, the local nested function isn't needed anymore and can be brought down into the normal flow of the function. With the nesting level changed, shuffle the error strings around a bit to get them to fit in 79 columns. Note: although ifcond is typed as Sequence[str] elsewhere, we *know* that the parser will produce real, bona-fide lists. It's okay to check isinstance(ifcond, list) here. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-12-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: add type hint annotationsJohn Snow
Annotations do not change runtime behavior. This commit *only* adds annotations. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-11-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Modify check_keys to accept any CollectionJohn Snow
This is a minor adjustment that lets parameters @required and @optional take tuple arguments, in particular (). Later patches will make use of that. (Iterable would also have worked, but Iterable also includes things like generator expressions which are consumed upon iteration, which would require a rewrite to make sure that each input was only traversed once. Collection implies the "can re-iterate" property.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-10-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Add casts in a few select casesJohn Snow
Casts are instructions to the type checker only, they aren't "safe" and should probably be avoided in general. In this case, when we perform type checking on a nested structure, the type of each field does not "stick". (See PEP 647 for an example of "type narrowing" that does "stick". It is available in Python 3.10, so we can't use it yet.) We don't need to assert that something is a str if we've already checked or asserted that it is -- use a cast instead for these cases. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-9-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Check type of union and alternate 'data' memberJohn Snow
Prior to this commit, specifying a non-object value here causes the QAPI parser to crash in expr.py with a stack trace with (likely) an AttributeError when we attempt to call that value's items() method. This member needs to be an object (Dict), and not anything else. Add a check for this with a nicer error message, and formalize that check with new test cases that exercise that error. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-8-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: move string check upwards in check_typeJohn Snow
For readability purposes only, shimmy the early return upwards to the top of the function, so cases proceed in order from least to most complex. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-7-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Add assertion for union type 'check_dict'John Snow
mypy isn't fond of allowing you to check for bool membership in a collection of str elements. Guard this lookup for precisely when we were given a name. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-6-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: constrain incoming expression typesJohn Snow
mypy does not know the types of values stored in Dicts that masquerade as objects. Help the type checker out by constraining the type. Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-5-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Check for dict instead of OrderedDictJohn Snow
OrderedDict is a subtype of dict, so we can check for a more general form. These functions do not themselves depend on it being any particular type. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-4-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr.py: Remove 'info' argument from nested check_if_strJohn Snow
The function can just use the argument from the scope above. Otherwise, we get shadowed argument errors because the parameter name clashes with the name of a variable already in-scope. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> Reviewed-by: Cleber Rosa <crosa@redhat.com> Message-Id: <20210421182032.3521476-3-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-04-30qapi/expr: Comment cleanupJohn Snow
The linter yaps after 0825f62c842. Fix this trivial issue to restore the linter baseline. (Yes, ideally -- and soon -- the linter will be part of CI so we don't clutter up the log with fixups. For now, though, the baseline is useful for testing intermediate commits as types are added to the QAPI library.) Signed-off-by: John Snow <jsnow@redhat.com> Message-Id: <20210421182032.3521476-2-jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Markus Armbruster <armbru@redhat.com>
2021-03-23qapi: Enforce union and alternate branch naming rulesMarkus Armbruster
Union branch names should use '-', not '_'. Enforce this. The only offenders are in tests/. Fix them. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-29-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message typo fixed]
2021-03-23qapi: Enforce enum member naming rulesMarkus Armbruster
Enum members should use '-', not '_'. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma member-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-28-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Enforce struct member naming rulesMarkus Armbruster
Struct members, including command arguments, event data, and union inline base members, should use '-', not '_'. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma member-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-27-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Enforce command naming rulesMarkus Armbruster
Command names should be lower-case. Enforce this. Fix the fixable offenders (all in tests/), and add the remainder to pragma command-name-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-25-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Enforce feature naming rulesMarkus Armbruster
Feature names should use '-', not '_'. Enforce this. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-24-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Prepare for rejecting underscore in command and member namesMarkus Armbruster
Command names and member names within a type should be all lower case with words separated by a hyphen. We also accept underscore. Rework check_name_lower() to optionally reject underscores, but don't use that option, yet. Update expected test output for the changed error message. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-23-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Rename pragma *-whitelist to *-exceptionsMarkus Armbruster
Rename pragma returns-whitelist to command-returns-exceptions, and name-case-whitelist to member-name-case-exceptions. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-20-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Factor out QAPISchemaParser._check_pragma_list_of_str()Markus Armbruster
Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-17-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Enforce type naming rulesMarkus Armbruster
Type names should be CamelCase. Enforce this. The only offenders are in tests/. Fix them. Add test type-case to cover the new error. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-15-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Regexp simplified, new test made more robust]
2021-03-23qapi: Enforce event naming rulesMarkus Armbruster
Event names should be ALL_CAPS with words separated by underscore. Enforce this. The only offenders are in tests/. Fix them. Existing test event-case covers the new error. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-14-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Consistently permit any case in downstream prefixesMarkus Armbruster
We require lowercase __RFQDN_ downstream prefixes only where we require the prefixed name to be lowercase. Don't; permit any case in __RFQDN_ prefixes anywhere. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-13-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Move uppercase rejection to check_name_lower()Markus Armbruster
check_name_lower() is the only user of check_name_str() using permit_upper=False. Move the associated code from check_name_str() to check_name_lower(), and drop the parameter. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-12-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Rework name checking in preparation of stricter checkingMarkus Armbruster
Naming rules differ for the various kinds of names. To prepare enforcing them, define functions to check them: check_name_upper(), check_name_lower(), and check_name_camel(). For now, these merely wrap around check_name_str(), but that will change shortly. Replace the other uses of check_name_str() by appropriate uses of the wrappers. No change in behavior just yet. check_name_str() now returns the name without downstream and x- prefix, for use by the wrappers in later patches. Requires tweaking regexp @valid_name. It accepts the same strings as before. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-11-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message improved]
2021-03-23qapi: Lift enum-specific code out of check_name_str()Markus Armbruster
check_name_str() masks leading digits when passed enum_member=True. Only check_enum() does. Lift the masking into check_enum(). Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-10-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
2021-03-23qapi: Permit flat union members for any tag valueMarkus Armbruster
Flat union branch names match the tag enum's member names. Omitted branches default to "no members for this tag value". Branch names starting with a digit get rejected like "'data' member '0' has an invalid name". However, omitting the branch works. This is because flat union tag values get checked twice: as enum member name, and as union branch name. The former accepts leading digits, the latter doesn't. Branches whose names start with a digit therefore cannot have members. Feels wrong. Get rid of the restriction by skipping the latter check. This can expose c_name() to input it can't handle: a name starting with a digit. Improve it to return a valid C identifier for any input. Signed-off-by: Markus Armbruster <armbru@redhat.com> Message-Id: <20210323094025.3569441-9-armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> [Commit message rewritten]