diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2025-03-05 21:53:11 +0800 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2025-03-05 21:53:12 +0800 |
commit | b93c9dfd700ae91c0080694f53c281ef51b0d028 (patch) | |
tree | 83e1e427fbb01e09b71a6b55fe49e656d93e74df /scripts/qapi/main.py | |
parent | 661c2e1ab29cd9c4d268ae3f44712e8d421c0e56 (diff) | |
parent | dde279925c97b614e45351400bfcf9efaf732f9d (diff) | |
download | qemu-b93c9dfd700ae91c0080694f53c281ef51b0d028.zip qemu-b93c9dfd700ae91c0080694f53c281ef51b0d028.tar.gz qemu-b93c9dfd700ae91c0080694f53c281ef51b0d028.tar.bz2 |
Merge tag 'pull-qapi-2025-02-26-v2' of https://repo.or.cz/qemu/armbru into staging
QAPI patches patches for 2025-02-26
# -----BEGIN PGP SIGNATURE-----
#
# iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmfGpZsSHGFybWJydUBy
# ZWRoYXQuY29tAAoJEDhwtADrkYZTGtQQAKmLIHy1c1T1yU6G9MFrAaFvH0n10UnB
# mQGOvcV+8f01KxUUIvVRBD9DyRl+kJGMelZoYuMpt+vNiO5XDMqZarJUYFOYukMW
# 6e/qrD3AMeyI0HGZYtELUENmuKLeAhhdE9d1PO56owR2jiFDxdzW+9TXkEXa1NHS
# c54v1y5HPgIdTXd11aXWI+06S6OVSpBteUOQTiSLowBq5BC28DoFAgViA1jZ1qM+
# 1PxL4IV4QkYXfEW2ORt/auamxFWuLNBYNWnyqhR+OYeQjWWAe2A0cmcoLIHVKFwE
# zcuVCXt9+8nZi3Fyx24yOineAhAi29qWxRnbXLrfa4y8OF3cihY0ZNYxvJF61iel
# Wis9WM78OcuQrHCF3BNPqBm9rrac5mQf5mMk4V75Yc+I4oeJeoDG8cLZF1HMpoBT
# iZAl4aW2aa7JQ778c4RxzuCWQSVzOzm5T72Ez9VDJRAWHxoiumoaIOPW9wDi7jWL
# 2P/XxyVCIMsuNLsxkFQEcHwtyK5BYqSf6gCpCbbzTW1YdfDzXQIvrRx4AEuClQvP
# yoLhpv3HjaomWEZbY26gJq1ImSF4uIaLbdOAvAub9wuZWCW0qd/j8PkU/xy0Q0Jx
# gNoNymbRdN5v3eekcZr7L96ILzwMDp2d+zS3q+YgpYUf30INfC7LyTCg6BZ7b06r
# zT05GmiP5DqS
# =LNhH
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 04 Mar 2025 15:02:51 HKT
# gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg: issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653
* tag 'pull-qapi-2025-02-26-v2' of https://repo.or.cz/qemu/armbru:
qapi: pluggable backend code generators
docs/qapidoc: remove example section support
docs/qapidoc: support header-less freeform sections
qapi: update pylintrc config
qapi/char.json: minor doc rewording for `hub` device
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'scripts/qapi/main.py')
-rw-r--r-- | scripts/qapi/main.py | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/scripts/qapi/main.py b/scripts/qapi/main.py index 324081b..5b4679a 100644 --- a/scripts/qapi/main.py +++ b/scripts/qapi/main.py @@ -8,18 +8,14 @@ This is the main entry point for generating C code from the QAPI schema. """ import argparse +from importlib import import_module import sys from typing import Optional -from .commands import gen_commands +from .backend import QAPIBackend, QAPICBackend 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]: @@ -29,32 +25,42 @@ def invalid_prefix_char(prefix: str) -> Optional[str]: 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. +def create_backend(path: str) -> QAPIBackend: + if path is None: + return QAPICBackend() - :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? + module_path, dot, class_name = path.rpartition('.') + if not dot: + print("argument of -B must be of the form MODULE.CLASS", + file=sys.stderr) + sys.exit(1) - :raise QAPIError: On failures. - """ - assert invalid_prefix_char(prefix) is None + try: + mod = import_module(module_path) + except Exception as ex: + print(f"unable to import '{module_path}': {ex}", file=sys.stderr) + sys.exit(1) + + try: + klass = getattr(mod, class_name) + except AttributeError: + print(f"module '{module_path}' has no class '{class_name}'", + file=sys.stderr) + sys.exit(1) + + try: + backend = klass() + except Exception as ex: + print(f"backend '{path}' cannot be instantiated: {ex}", + file=sys.stderr) + sys.exit(1) + + if not isinstance(backend, QAPIBackend): + print(f"backend '{path}' must be an instance of QAPIBackend", + file=sys.stderr) + sys.exit(1) - 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) + return backend def main() -> int: @@ -77,6 +83,8 @@ def main() -> int: parser.add_argument('-u', '--unmask-non-abi-names', action='store_true', dest='unmask', help="expose non-ABI names in introspection") + parser.add_argument('-B', '--backend', default=None, + help="Python module name for code generator") # Option --suppress-tracing exists so we can avoid solving build system # problems. TODO Drop it when we no longer need it. @@ -93,12 +101,14 @@ def main() -> int: 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) + schema = QAPISchema(args.schema) + backend = create_backend(args.backend) + backend.generate(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 |