qapi: move generator entrypoint into package

As part of delinting and adding type hints to the QAPI generator, it's
helpful for the entrypoint to be part of the package, only leaving a
very tiny entrypoint shim outside of the package.

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>
Message-Id: <20201009161558.107041-5-jsnow@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[invalid_char() renamed to invalid_prefix_char()]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
John Snow 2020-10-09 12:15:26 -04:00 committed by Markus Armbruster
parent 52a474180a
commit a76ab215ec
2 changed files with 101 additions and 88 deletions

View File

@ -4,98 +4,16 @@
# See the COPYING file in the top-level directory.
"""
QAPI Generator
QAPI code generation execution shim.
This is the main entry point for generating C code from the QAPI schema.
This standalone script exists primarily to facilitate the running of the QAPI
code generator without needing to install the python module to the current
execution environment.
"""
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 QAPISchema
from qapi.types import gen_types
from qapi.visit import gen_visit
def invalid_prefix_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_prefix_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='',
help="write output to directory OUTPUT_DIR")
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',
help="expose non-ABI names in introspection")
parser.add_argument('schema', action='store')
args = parser.parse_args()
funny_char = invalid_prefix_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:
generate(args.schema,
output_dir=args.output_dir,
prefix=args.prefix,
unmask=args.unmask,
builtins=args.builtins)
except QAPIError as err:
print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
return 1
return 0
from qapi import main
if __name__ == '__main__':
sys.exit(main())
sys.exit(main.main())

95
scripts/qapi/main.py Normal file
View File

@ -0,0 +1,95 @@
# 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 QAPISchema
from qapi.types import gen_types
from qapi.visit import gen_visit
def invalid_prefix_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_prefix_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='',
help="write output to directory OUTPUT_DIR")
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',
help="expose non-ABI names in introspection")
parser.add_argument('schema', action='store')
args = parser.parse_args()
funny_char = invalid_prefix_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:
generate(args.schema,
output_dir=args.output_dir,
prefix=args.prefix,
unmask=args.unmask,
builtins=args.builtins)
except QAPIError as err:
print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
return 1
return 0