|  | # 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 sys | 
|  | from typing import Optional | 
|  |  | 
|  | from .commands import gen_commands | 
|  | from .common import must_match | 
|  | from .error import QAPIError | 
|  | from .events import gen_events | 
|  | from .features import gen_features | 
|  | from .introspect import gen_introspect | 
|  | from .schema import QAPISchema | 
|  | from .types import gen_types | 
|  | from .visit import gen_visit | 
|  |  | 
|  |  | 
|  | def invalid_prefix_char(prefix: str) -> Optional[str]: | 
|  | match = must_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, | 
|  | gen_tracing: 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_features(schema, output_dir, prefix) | 
|  | gen_visit(schema, output_dir, prefix, builtins) | 
|  | gen_commands(schema, output_dir, prefix, gen_tracing) | 
|  | 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") | 
|  |  | 
|  | # Option --suppress-tracing exists so we can avoid solving build system | 
|  | # problems.  TODO Drop it when we no longer need it. | 
|  | parser.add_argument('--suppress-tracing', action='store_true', | 
|  | help="suppress adding trace events to qmp marshals") | 
|  |  | 
|  | 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, | 
|  | gen_tracing=not args.suppress_tracing) | 
|  | except QAPIError as err: | 
|  | print(err, file=sys.stderr) | 
|  | return 1 | 
|  | return 0 |