Message ID | 20201009161558.107041-4-jsnow@redhat.com |
---|---|
State | New |
Headers | show |
Series | qapi: static typing conversion, pt1 | expand |
John Snow <jsnow@redhat.com> writes: > This is a minor re-work of the entrypoint script. It isolates a <pedantic>entrypoint is not a word</> ;-P > generate() method from the actual command-line mechanism. > > Signed-off-by: John Snow <jsnow@redhat.com> > Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> > Reviewed-by: Cleber Rosa <crosa@redhat.com> > Tested-by: Cleber Rosa <crosa@redhat.com> > --- > scripts/qapi-gen.py | 89 ++++++++++++++++++++++++++++++++++----------- > 1 file changed, 67 insertions(+), 22 deletions(-) > > diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py > index 541e8c1f55d..054554ed846 100644 > --- a/scripts/qapi-gen.py > +++ b/scripts/qapi-gen.py > @@ -1,30 +1,77 @@ > #!/usr/bin/env python3 > -# QAPI generator > -# > + > # This work is licensed under the terms of the GNU GPL, version 2 or later. > # See the COPYING file in the top-level directory. > > +""" > +QAPI Generator > + > +This is the main entry point for generating C code from the QAPI schema. > +""" > > import argparse > import re > import sys > +from typing import Optional > > from qapi.commands import gen_commands > +from qapi.error import QAPIError > from qapi.events import gen_events > from qapi.introspect import gen_introspect > -from qapi.schema import QAPIError, QAPISchema > +from qapi.schema import QAPISchema > from qapi.types import gen_types > from qapi.visit import gen_visit > > > -def main(argv): > +def invalid_char(prefix: str) -> Optional[str]: Naming is hard... invalid_char() makes sense because it returns the invalid character. The name's a tad generic, though. Would first_invalid_prefix_char() be easier to understand? > + match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix) > + if match.end() != len(prefix): > + return prefix[match.end()] > + return None [...]
On 10/9/20 1:26 PM, Markus Armbruster wrote: > John Snow <jsnow@redhat.com> writes: > >> This is a minor re-work of the entrypoint script. It isolates a > > <pedantic>entrypoint is not a word</> ;-P > I'm not entirely sure why a German is complaining about the birth of a new and beautiful compound noun. (I started to make sure I wrote it out as two words, but missed a spot. Too late now, unless you fixed it already.) >> generate() method from the actual command-line mechanism. >> >> Signed-off-by: John Snow <jsnow@redhat.com> >> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> >> Reviewed-by: Cleber Rosa <crosa@redhat.com> >> Tested-by: Cleber Rosa <crosa@redhat.com> >> --- >> scripts/qapi-gen.py | 89 ++++++++++++++++++++++++++++++++++----------- >> 1 file changed, 67 insertions(+), 22 deletions(-) >> >> diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py >> index 541e8c1f55d..054554ed846 100644 >> --- a/scripts/qapi-gen.py >> +++ b/scripts/qapi-gen.py >> @@ -1,30 +1,77 @@ >> #!/usr/bin/env python3 >> -# QAPI generator >> -# >> + >> # This work is licensed under the terms of the GNU GPL, version 2 or later. >> # See the COPYING file in the top-level directory. >> >> +""" >> +QAPI Generator >> + >> +This is the main entry point for generating C code from the QAPI schema. >> +""" >> >> import argparse >> import re >> import sys >> +from typing import Optional >> >> from qapi.commands import gen_commands >> +from qapi.error import QAPIError >> from qapi.events import gen_events >> from qapi.introspect import gen_introspect >> -from qapi.schema import QAPIError, QAPISchema >> +from qapi.schema import QAPISchema >> from qapi.types import gen_types >> from qapi.visit import gen_visit >> >> >> -def main(argv): >> +def invalid_char(prefix: str) -> Optional[str]: > > Naming is hard... invalid_char() makes sense because it returns the > invalid character. The name's a tad generic, though. Would > first_invalid_prefix_char() be easier to understand? > Sounds like an improvement to me. I guess that should be in a follow-up now. >> + match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix) >> + if match.end() != len(prefix): >> + return prefix[match.end()] >> + return None > [...] >
John Snow <jsnow@redhat.com> writes: > On 10/9/20 1:26 PM, Markus Armbruster wrote: >> John Snow <jsnow@redhat.com> writes: >> >>> This is a minor re-work of the entrypoint script. It isolates a >> <pedantic>entrypoint is not a word</> ;-P >> > > I'm not entirely sure why a German is complaining about the birth of a > new and beautiful compound noun. Ha! > (I started to make sure I wrote it out as two words, but missed a > spot. Too late now, unless you fixed it already.) I didn't. >>> generate() method from the actual command-line mechanism. >>> >>> Signed-off-by: John Snow <jsnow@redhat.com> >>> Reviewed-by: Eduardo Habkost <ehabkost@redhat.com> >>> Reviewed-by: Cleber Rosa <crosa@redhat.com> >>> Tested-by: Cleber Rosa <crosa@redhat.com> >>> --- >>> scripts/qapi-gen.py | 89 ++++++++++++++++++++++++++++++++++----------- >>> 1 file changed, 67 insertions(+), 22 deletions(-) >>> >>> diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py >>> index 541e8c1f55d..054554ed846 100644 >>> --- a/scripts/qapi-gen.py >>> +++ b/scripts/qapi-gen.py >>> @@ -1,30 +1,77 @@ >>> #!/usr/bin/env python3 >>> -# QAPI generator >>> -# >>> + >>> # This work is licensed under the terms of the GNU GPL, version 2 or later. >>> # See the COPYING file in the top-level directory. >>> +""" >>> +QAPI Generator >>> + >>> +This is the main entry point for generating C code from the QAPI schema. >>> +""" >>> import argparse >>> import re >>> import sys >>> +from typing import Optional >>> from qapi.commands import gen_commands >>> +from qapi.error import QAPIError >>> from qapi.events import gen_events >>> from qapi.introspect import gen_introspect >>> -from qapi.schema import QAPIError, QAPISchema >>> +from qapi.schema import QAPISchema >>> from qapi.types import gen_types >>> from qapi.visit import gen_visit >>> >>> -def main(argv): >>> +def invalid_char(prefix: str) -> Optional[str]: >> >> Naming is hard... invalid_char() makes sense because it returns the >> invalid character. The name's a tad generic, though. Would >> first_invalid_prefix_char() be easier to understand? > > Sounds like an improvement to me. I guess that should be in a follow-up now. I took the liberty to rename it to invalid_prefix_char() in my tree. Has since been merged into master as commit 52a474180ae. >>> + match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix) >>> + if match.end() != len(prefix): >>> + return prefix[match.end()] >>> + return None >> [...] >>
diff --git a/scripts/qapi-gen.py b/scripts/qapi-gen.py index 541e8c1f55d..054554ed846 100644 --- a/scripts/qapi-gen.py +++ b/scripts/qapi-gen.py @@ -1,30 +1,77 @@ #!/usr/bin/env python3 -# QAPI generator -# + # This work is licensed under the terms of the GNU GPL, version 2 or later. # See the COPYING file in the top-level directory. +""" +QAPI Generator + +This is the main entry point for generating C code from the QAPI schema. +""" import argparse import re import sys +from typing import Optional from qapi.commands import gen_commands +from qapi.error import QAPIError from qapi.events import gen_events from qapi.introspect import gen_introspect -from qapi.schema import QAPIError, QAPISchema +from qapi.schema import QAPISchema from qapi.types import gen_types from qapi.visit import gen_visit -def main(argv): +def invalid_char(prefix: str) -> Optional[str]: + match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix) + if match.end() != len(prefix): + return prefix[match.end()] + return None + + +def generate(schema_file: str, + output_dir: str, + prefix: str, + unmask: bool = False, + builtins: bool = False) -> None: + """ + Generate C code for the given schema into the target directory. + + :param schema_file: The primary QAPI schema file. + :param output_dir: The output directory to store generated code. + :param prefix: Optional C-code prefix for symbol names. + :param unmask: Expose non-ABI names through introspection? + :param builtins: Generate code for built-in types? + + :raise QAPIError: On failures. + """ + assert invalid_char(prefix) is None + + schema = QAPISchema(schema_file) + gen_types(schema, output_dir, prefix, builtins) + gen_visit(schema, output_dir, prefix, builtins) + gen_commands(schema, output_dir, prefix) + gen_events(schema, output_dir, prefix) + gen_introspect(schema, output_dir, prefix, unmask) + + +def main() -> int: + """ + gapi-gen executable entry point. + Expects arguments via sys.argv, see --help for details. + + :return: int, 0 on success, 1 on failure. + """ parser = argparse.ArgumentParser( description='Generate code from a QAPI schema') parser.add_argument('-b', '--builtins', action='store_true', help="generate code for built-in types") - parser.add_argument('-o', '--output-dir', action='store', default='', + parser.add_argument('-o', '--output-dir', action='store', + default='', help="write output to directory OUTPUT_DIR") - parser.add_argument('-p', '--prefix', action='store', default='', + parser.add_argument('-p', '--prefix', action='store', + default='', help="prefix for symbols") parser.add_argument('-u', '--unmask-non-abi-names', action='store_true', dest='unmask', @@ -32,25 +79,23 @@ def main(argv): parser.add_argument('schema', action='store') args = parser.parse_args() - match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', args.prefix) - if match.end() != len(args.prefix): - print("%s: 'funny character '%s' in argument of --prefix" - % (sys.argv[0], args.prefix[match.end()]), - file=sys.stderr) - sys.exit(1) + funny_char = invalid_char(args.prefix) + if funny_char: + msg = f"funny character '{funny_char}' in argument of --prefix" + print(f"{sys.argv[0]}: {msg}", file=sys.stderr) + return 1 try: - schema = QAPISchema(args.schema) + generate(args.schema, + output_dir=args.output_dir, + prefix=args.prefix, + unmask=args.unmask, + builtins=args.builtins) except QAPIError as err: - print(err, file=sys.stderr) - exit(1) - - gen_types(schema, args.output_dir, args.prefix, args.builtins) - gen_visit(schema, args.output_dir, args.prefix, args.builtins) - gen_commands(schema, args.output_dir, args.prefix) - gen_events(schema, args.output_dir, args.prefix) - gen_introspect(schema, args.output_dir, args.prefix, args.unmask) + print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr) + return 1 + return 0 if __name__ == '__main__': - main(sys.argv) + sys.exit(main())