summaryrefslogtreecommitdiff
path: root/tools/InterfaceGenerator/Generator.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/InterfaceGenerator/Generator.py')
-rwxr-xr-xtools/InterfaceGenerator/Generator.py236
1 files changed, 142 insertions, 94 deletions
diff --git a/tools/InterfaceGenerator/Generator.py b/tools/InterfaceGenerator/Generator.py
index 905b0754b3..6f90f62e71 100755
--- a/tools/InterfaceGenerator/Generator.py
+++ b/tools/InterfaceGenerator/Generator.py
@@ -16,113 +16,161 @@ optional arguments:
--parser-type {sdlrpcv2}
"""
-import os.path
-import argparse
-import errno
+import os
+import re
import sys
-
-import generator.parsers.SDLRPCV1
-import generator.parsers.SDLRPCV2
-import generator.parsers.JSONRPC
-import generator.generators.SmartFactorySDLRPC
-import generator.generators.SmartFactoryJSONRPC
-import generator.generators.PolicyTypes
-import MsgVersionGenerate
-
-from generator.parsers.RPCBase import ParseError
-from generator.generators.SmartFactoryBase import GenerateError
-
-SUPPORTED_FORMATS = {
- "sdlrpcv1": (generator.parsers.SDLRPCV1.Parser,
- generator.generators.SmartFactorySDLRPC.CodeGenerator),
- "sdlrpcv2": (generator.parsers.SDLRPCV2.Parser,
- generator.generators.SmartFactorySDLRPC.CodeGenerator),
- "jsonrpc": (generator.parsers.JSONRPC.Parser,
- generator.generators.SmartFactoryJSONRPC.CodeGenerator),
- "mobile-policy-types": (generator.parsers.SDLRPCV2.Parser,
- generator.generators.PolicyTypes.CodeGenerator),
- "hmi-policy-types": (generator.parsers.JSONRPC.Parser,
- generator.generators.PolicyTypes.CodeGenerator)
-}
-
-
-def _create_parser():
- """Create parser for parsing command-line arguments.
-
- Returns an instance of argparse.ArgumentParser
-
- """
-
- parser = argparse.ArgumentParser(
- description="SmartSchema interface generator"
- )
- parser.add_argument("source-xml")
- parser.add_argument("namespace")
- parser.add_argument("output-dir")
- parser.add_argument("--parser-type",
- choices=SUPPORTED_FORMATS.keys(),
- required=True)
- return parser
-
-
-def _handle_fatal_error(error):
- """Handle fatal error during parsing or code generation.
-
- Keyword arguments:
- error -- base exception to handle.
+from argparse import ArgumentParser
+from pathlib import Path
+
+ROOT = Path(__file__).absolute().parents[1]
+sys.path.append(ROOT.joinpath('rpc_spec/InterfaceParser').as_posix())
+
+try:
+ from model.interface import Interface
+ from parsers import sdl_rpc_v2
+ from parsers.parse_error import ParseError
+ from MsgVersionGenerate import generate_msg_version
+ from generator.generators import SmartFactorySDLRPC, SmartFactoryJSONRPC, PolicyTypes
+ from generator.generators.SmartFactoryBase import GenerateError
+ from generator.parsers import SDLRPCV1, JSONRPC
+except ModuleNotFoundError as error:
+ print(str(error) + '\nPlease make sure the RPC Spec Generator Submodule is initialized.\n'
+ 'Check the sdl_core source directory in `tools/rpc_spec`.\n'
+ 'Try running in the source directory:\n'
+ '$ git submodule init\n'
+ '$ git submodule update')
+ sys.exit(1)
+
+
+class Generator:
+ """Generator application that generates c++ interfaces code from xml description
"""
- print(error.message)
- print
- sys.exit(errno.EINVAL)
-
-def main():
- """Main function of the generator that does actual work."""
-
- args = vars(_create_parser().parse_args())
-
- src_xml = args["source-xml"]
- src_xml_name = os.path.splitext(os.path.basename(src_xml))[0]
- namespace = args["namespace"]
- output_dir = args["output-dir"]
- parser_type = args["parser_type"]
-
- print("""
+ def __init__(self):
+ self._supported_formats = {
+ 'sdlrpcv1': (SDLRPCV1.Parser, SmartFactorySDLRPC.CodeGenerator),
+ 'sdlrpcv2': (sdl_rpc_v2.Parser, SmartFactorySDLRPC.CodeGenerator),
+ 'jsonrpc': (JSONRPC.Parser, SmartFactoryJSONRPC.CodeGenerator),
+ 'mobile-policy-types': (sdl_rpc_v2.Parser, PolicyTypes.CodeGenerator),
+ 'hmi-policy-types': (JSONRPC.Parser, PolicyTypes.CodeGenerator)
+ }
+
+ @property
+ def supported_formats(self):
+ """
+ :return: dictionary with supported_formats
+ """
+ return self._supported_formats
+
+ def _create_parser(self):
+ """
+ Parsing command-line arguments, or evaluating required Paths interactively.
+ :return: an instance of argparse.ArgumentParser
+ """
+ if len(sys.argv) == 2 and sys.argv[1] in ('-v', '--version'):
+ print('1.0.0')
+ sys.exit(0)
+
+ parser = ArgumentParser(description='Proxy Library RPC Generator')
+ parser.add_argument('-xml', '--source-xml', '--input-file', required=True,
+ help='should point to MOBILE_API.xml')
+ parser.add_argument('-ns', '--namespace', required=True)
+ parser.add_argument('-d', '-o', '--output-dir', required=True,
+ help='define the place where the generated output should be placed')
+ parser.add_argument('-t', '--parser-type', required=True, choices=self.supported_formats.keys())
+ parser.add_argument('-v', '--version', action='store_true', help='print the version and exit')
+ parser.add_argument('-r', '--regex-pattern', required=False,
+ help='only elements matched with defined regex pattern will be parsed and generated')
+ parser.add_argument('--verbose', action='store_true', help='display additional details like logs etc')
+ parser.add_argument('-e', '--enums', required=False, action='store_true',
+ help='only specified elements will be generated, if present')
+ parser.add_argument('-s', '--structs', required=False, action='store_true',
+ help='only specified elements will be generated, if present')
+ parser.add_argument('-m', '-f', '--functions', required=False, action='store_true',
+ help='only specified elements will be generated, if present')
+ parser.add_argument('-y', '--overwrite', action='store_true',
+ help='force overwriting of existing files in output directory, ignore confirmation message')
+ parser.add_argument('-n', '--skip', action='store_true',
+ help='skip overwriting of existing files in output directory, ignore confirmation message')
+
+ args, unknown = parser.parse_known_args()
+
+ if unknown:
+ print('found unknown arguments: ' + ' '.join(unknown))
+ parser.print_help(sys.stderr)
+ sys.exit(1)
+
+ if args.skip and args.overwrite or not args.skip and not args.overwrite:
+ print('please select one option skip or overwrite')
+ sys.exit(1)
+
+ if not args.enums and not args.structs and not args.functions:
+ args.enums = args.structs = args.functions = True
+
+ return args
+
+ @staticmethod
+ def filter_pattern(interface, pattern):
+ """
+ Filtring model according to regex pattern
+ :param interface: Interface model
+ :param pattern: regex pattern
+ :return:
+ """
+ match = {i: {} for i in vars(interface).keys()}
+ match['params'] = interface.params
+ if pattern:
+ for key, value in vars(interface).items():
+ if key == 'params':
+ continue
+ for name, item in value.items():
+ if re.match(pattern, item.name):
+ if key in match:
+ match[key].update({name: item})
+ else:
+ return interface
+
+ return Interface(**match)
+
+ def main(self):
+ """Main function of the generator that does actual work."""
+
+ args = self._create_parser()
+
+ print("""
Generating interface source code with following parameters:
Source xml : {0}
Namespace : {1}
Output directory: {2}
Parser type : {3}
-""".format(src_xml, namespace, output_dir, parser_type))
+ overwrite : {4}
+""".format(args.source_xml, args.namespace, args.output_dir, args.parser_type, args.overwrite))
- # Select required parser and code generator
- parser = SUPPORTED_FORMATS[parser_type][0]()
- code_generator = SUPPORTED_FORMATS[parser_type][1]()
+ # Select required parser and code generator
+ parser = self.supported_formats[args.parser_type][0]()
+ code_generator = self.supported_formats[args.parser_type][1]()
- # Convert incoming xml to internal model
- try:
- interface = parser.parse(args["source-xml"])
- except ParseError as error:
- _handle_fatal_error(error)
-
- # Parse sdl version from MOBILE_API.xml and create source file with this version
- if src_xml_name == "MOBILE_API":
+ # Convert incoming xml to internal model
try:
- MsgVersionGenerate.generate_msg_version(src_xml, output_dir)
- except ParseError as error:
- _handle_fatal_error(error)
+ interface = parser.parse(args.source_xml)
+ filtered = self.filter_pattern(interface, args.regex_pattern)
+ src_xml_name = os.path.splitext(os.path.basename(args.source_xml))[0]
+ # Parse sdl version from MOBILE_API.xml and create source file with this version
+ if src_xml_name == "MOBILE_API":
+ generate_msg_version(args.source_xml, args.output_dir)
+
+ # Generate SmartFactory source code from internal model
+ code_generator.generate(filtered,
+ src_xml_name,
+ args.namespace,
+ args.output_dir)
+ except (ParseError, GenerateError) as error1:
+ print(error1)
+ sys.exit(1)
- # Generate SmartFactory source code from internal model
- try:
- code_generator.generate(interface,
- src_xml_name,
- namespace,
- output_dir)
- except GenerateError as error:
- _handle_fatal_error(error)
+ print('Done.')
- print("Done.")
if __name__ == '__main__':
- main()
+ Generator().main()