blob: cf942d9ce36f9f59b3531757af82d3cd86a70377 [file] [log] [blame]
Philippe Mathieu-Daudé3d004a32020-01-30 17:32:25 +01001#!/usr/bin/env python3
John Snow52a47412020-10-09 12:15:25 -04002
Markus Armbrusterfb0bc832018-02-26 13:48:58 -06003# This work is licensed under the terms of the GNU GPL, version 2 or later.
4# See the COPYING file in the top-level directory.
5
John Snow52a47412020-10-09 12:15:25 -04006"""
7QAPI Generator
8
9This is the main entry point for generating C code from the QAPI schema.
10"""
Markus Armbrustere6c42b92019-10-18 09:43:44 +020011
Markus Armbruster3b446a12018-02-11 10:35:47 +010012import argparse
13import re
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060014import sys
John Snow52a47412020-10-09 12:15:25 -040015from typing import Optional
Markus Armbrustere6c42b92019-10-18 09:43:44 +020016
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060017from qapi.commands import gen_commands
John Snow52a47412020-10-09 12:15:25 -040018from qapi.error import QAPIError
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060019from qapi.events import gen_events
20from qapi.introspect import gen_introspect
John Snow52a47412020-10-09 12:15:25 -040021from qapi.schema import QAPISchema
Markus Armbrustere6c42b92019-10-18 09:43:44 +020022from qapi.types import gen_types
23from qapi.visit import gen_visit
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060024
25
John Snow52a47412020-10-09 12:15:25 -040026def invalid_prefix_char(prefix: str) -> Optional[str]:
27 match = re.match(r'([A-Za-z_.-][A-Za-z0-9_.-]*)?', prefix)
28 if match.end() != len(prefix):
29 return prefix[match.end()]
30 return None
31
32
33def generate(schema_file: str,
34 output_dir: str,
35 prefix: str,
36 unmask: bool = False,
37 builtins: bool = False) -> None:
38 """
39 Generate C code for the given schema into the target directory.
40
41 :param schema_file: The primary QAPI schema file.
42 :param output_dir: The output directory to store generated code.
43 :param prefix: Optional C-code prefix for symbol names.
44 :param unmask: Expose non-ABI names through introspection?
45 :param builtins: Generate code for built-in types?
46
47 :raise QAPIError: On failures.
48 """
49 assert invalid_prefix_char(prefix) is None
50
51 schema = QAPISchema(schema_file)
52 gen_types(schema, output_dir, prefix, builtins)
53 gen_visit(schema, output_dir, prefix, builtins)
54 gen_commands(schema, output_dir, prefix)
55 gen_events(schema, output_dir, prefix)
56 gen_introspect(schema, output_dir, prefix, unmask)
57
58
59def main() -> int:
60 """
61 gapi-gen executable entry point.
62 Expects arguments via sys.argv, see --help for details.
63
64 :return: int, 0 on success, 1 on failure.
65 """
Markus Armbruster3b446a12018-02-11 10:35:47 +010066 parser = argparse.ArgumentParser(
67 description='Generate code from a QAPI schema')
68 parser.add_argument('-b', '--builtins', action='store_true',
69 help="generate code for built-in types")
John Snow52a47412020-10-09 12:15:25 -040070 parser.add_argument('-o', '--output-dir', action='store',
71 default='',
Markus Armbruster3b446a12018-02-11 10:35:47 +010072 help="write output to directory OUTPUT_DIR")
John Snow52a47412020-10-09 12:15:25 -040073 parser.add_argument('-p', '--prefix', action='store',
74 default='',
Markus Armbruster3b446a12018-02-11 10:35:47 +010075 help="prefix for symbols")
76 parser.add_argument('-u', '--unmask-non-abi-names', action='store_true',
77 dest='unmask',
78 help="expose non-ABI names in introspection")
79 parser.add_argument('schema', action='store')
80 args = parser.parse_args()
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060081
John Snow52a47412020-10-09 12:15:25 -040082 funny_char = invalid_prefix_char(args.prefix)
83 if funny_char:
84 msg = f"funny character '{funny_char}' in argument of --prefix"
85 print(f"{sys.argv[0]}: {msg}", file=sys.stderr)
86 return 1
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060087
Markus Armbruster181feaf2018-02-11 10:35:51 +010088 try:
John Snow52a47412020-10-09 12:15:25 -040089 generate(args.schema,
90 output_dir=args.output_dir,
91 prefix=args.prefix,
92 unmask=args.unmask,
93 builtins=args.builtins)
Markus Armbruster181feaf2018-02-11 10:35:51 +010094 except QAPIError as err:
John Snow52a47412020-10-09 12:15:25 -040095 print(f"{sys.argv[0]}: {str(err)}", file=sys.stderr)
96 return 1
97 return 0
Markus Armbrusterfb0bc832018-02-26 13:48:58 -060098
99
100if __name__ == '__main__':
John Snow52a47412020-10-09 12:15:25 -0400101 sys.exit(main())