1 # Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the "Software"),
5 # to deal in the Software without restriction, including without limitation
6 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 # and/or sell copies of the Software, and to permit persons to whom the
8 # Software is furnished to do so, subject to the following conditions:
10 # The above copyright notice and this permission notice (including the next
11 # paragraph) shall be included in all copies or substantial portions of the
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23 from __future__ import print_function
27 from gen_common import *
29 def parse_event_fields(lines, idx, event_dict):
33 # record all fields in event definition.
34 # note: we don't check if there's a leading brace.
35 while not end_of_event and idx < len(lines):
36 line = lines[idx].rstrip()
39 match = re.match(r'(\s*)([\w\*]+)(\s*)([\w]+)(\[\d+\])*', line)
43 "type": match.group(2),
44 "name": match.group(4),
45 "size": int(match.group(5)[1:-1]) if match.group(5) else 1
49 end_of_event = re.match(r'(\s*)};', line)
51 event_dict['fields'] = fields
52 event_dict['num_fields'] = len(fields)
56 def parse_enums(lines, idx, event_dict):
60 # record all enum values in enumeration
61 # note: we don't check if there's a leading brace.
62 while not end_of_enum and idx < len(lines):
63 line = lines[idx].rstrip()
66 preprocessor = re.search(r'#if|#endif', line)
69 enum = re.match(r'(\s*)(\w+)(\s*)', line)
72 enum_names.append(line)
74 end_of_enum = re.match(r'(\s*)};', line)
76 event_dict['names'] = enum_names
79 def parse_protos(files, verbose=False):
82 protos['events'] = {} # event dictionary containing events with their fields
83 protos['event_names'] = [] # needed to keep events in order parsed. dict is not ordered.
85 protos['enum_names'] = []
89 for filename in files:
91 print("Parsing proto file: %s" % os.path.normpath(filename))
93 with open(filename, 'r') as f:
99 while idx < len(lines):
100 line = lines[idx].rstrip()
103 # search for event definitions.
104 match = re.match(r'(\s*)event(\s*)(\w+)', line)
108 event_name = match.group(3)
109 protos['event_names'].append(event_name)
111 protos['events'][event_name] = {}
112 protos['events'][event_name]['event_id'] = eventId
113 idx = parse_event_fields(lines, idx, protos['events'][event_name])
116 match = re.match(r'(\s*)enum(\s*)(\w+)', line)
119 enum_name = match.group(3)
120 protos['enum_names'].append(enum_name)
122 protos['enums'][enum_name] = {}
123 idx = parse_enums(lines, idx, protos['enums'][enum_name])
130 parser = ArgumentParser()
131 parser.add_argument("--proto", "-p", dest="protos", nargs='+', help="Path to all proto file(s) to process. Accepts one or more paths (i.e. events.proto and events_private.proto)", required=True)
132 parser.add_argument("--output-dir", help="Output dir (defaults to ./codegen). Will create folder if it does not exist.", required=False, default="codegen")
133 parser.add_argument("--verbose", "-v", help="Verbose", action="store_true")
134 args = parser.parse_args()
136 if not os.path.exists(args.output_dir):
137 MakeDir(args.output_dir)
139 for f in args.protos:
140 if not os.path.exists(f):
141 print('Error: Could not find proto file %s' % f, file=sys.stderr)
144 # Parse each proto file and add to protos container
145 protos = parse_protos(args.protos, args.verbose)
148 ["gen_ar_event.hpp", ""],
149 ["gen_ar_event.cpp", ""],
150 ["gen_ar_eventhandler.hpp", "gen_ar_event.hpp"],
151 ["gen_ar_eventhandlerfile.hpp", "gen_ar_eventhandler.hpp"]
157 # Delete existing files
160 output_fullpath = os.path.join(args.output_dir, filename)
161 if os.path.exists(output_fullpath):
163 print("Deleting existing file: %s" % output_fullpath)
164 os.remove(output_fullpath)
166 # Generate files from templates
167 print("Generating c++ from proto files...")
171 curdir = os.path.dirname(os.path.abspath(__file__))
172 template_file = os.path.join(curdir, 'templates', filename)
173 output_fullpath = os.path.join(args.output_dir, filename)
176 print("Generating: %s" % output_fullpath)
177 MakoTemplateWriter.to_file(template_file, output_fullpath,
181 event_header=event_header)
183 except Exception as e:
189 if __name__ == '__main__':