OSDN Git Service

swr/rast: Add string handling to AR event framework
[android-x86/external-mesa.git] / src / gallium / drivers / swr / rasterizer / codegen / gen_archrast.py
1 # Copyright (C) 2014-2016 Intel Corporation.   All Rights Reserved.
2 #
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:
9 #
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
12 # Software.
13 #
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
20 # IN THE SOFTWARE.
21
22 # Python source
23 from __future__ import print_function
24 import os
25 import sys
26 import re
27 from gen_common import *
28
29 def parse_event_fields(lines, idx, event_dict):
30     fields = []
31     end_of_event = False
32
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()
37         idx += 1
38
39         match = re.match(r'(\s*)([\w\*]+)(\s*)([\w]+)(\[\d+\])*', line)
40
41         if match:
42             field = {
43                 "type": match.group(2),
44                 "name": match.group(4),
45                 "size": int(match.group(5)[1:-1]) if match.group(5) else 1
46             }
47             fields.append(field)
48
49         end_of_event = re.match(r'(\s*)};', line)
50
51     event_dict['fields'] = fields
52     event_dict['num_fields'] = len(fields)
53
54     return idx
55
56 def parse_enums(lines, idx, event_dict):
57     enum_names = []
58     end_of_enum = False
59
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()
64         idx += 1
65
66         preprocessor = re.search(r'#if|#endif', line)
67
68         if not preprocessor:
69             enum = re.match(r'(\s*)(\w+)(\s*)', line)
70
71             if enum:
72                 enum_names.append(line)
73
74             end_of_enum = re.match(r'(\s*)};', line)
75
76     event_dict['names'] = enum_names
77     return idx
78
79 def parse_protos(files, verbose=False):
80
81     protos = {}
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.
84     protos['enums'] = {}
85     protos['enum_names'] = []
86
87     eventId = 0
88
89     for filename in files:
90         if verbose:
91             print("Parsing proto file: %s" % os.path.normpath(filename))
92
93         with open(filename, 'r') as f:
94             lines=f.readlines()
95
96             idx = 0
97
98             raw_text = []
99             while idx < len(lines):
100                 line = lines[idx].rstrip()
101                 idx += 1
102
103                 # search for event definitions.
104                 match = re.match(r'(\s*)event(\s*)(\w+)', line)
105
106                 if match:
107                     eventId += 1
108                     event_name = match.group(3)
109                     protos['event_names'].append(event_name)
110
111                     protos['events'][event_name] = {}
112                     protos['events'][event_name]['event_id'] = eventId
113                     idx = parse_event_fields(lines, idx, protos['events'][event_name])
114
115                 # search for enums.
116                 match = re.match(r'(\s*)enum(\s*)(\w+)', line)
117
118                 if match:
119                     enum_name = match.group(3)
120                     protos['enum_names'].append(enum_name)
121
122                     protos['enums'][enum_name] = {}
123                     idx = parse_enums(lines, idx, protos['enums'][enum_name])
124     return protos
125
126
127 def main():
128
129     # Parse args...
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()
135
136     if not os.path.exists(args.output_dir):
137         MakeDir(args.output_dir)
138
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)
142             return 1
143
144     # Parse each proto file and add to protos container
145     protos = parse_protos(args.protos, args.verbose)
146
147     files = [
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"]
152     ]
153
154     rval = 0
155
156     try:
157         # Delete existing files
158         for f in files:
159             filename = f[0]
160             output_fullpath = os.path.join(args.output_dir, filename)
161             if os.path.exists(output_fullpath):
162                 if args.verbose:
163                     print("Deleting existing file: %s" % output_fullpath)
164                 os.remove(output_fullpath)
165
166         # Generate files from templates
167         print("Generating c++ from proto files...")
168         for f in files:
169             filename = f[0]
170             event_header = f[1]
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)
174
175             if args.verbose:
176                 print("Generating: %s" % output_fullpath)
177             MakoTemplateWriter.to_file(template_file, output_fullpath,
178                     cmdline=sys.argv,
179                     filename=filename,
180                     protos=protos,
181                     event_header=event_header)
182
183     except Exception as e:
184         print(e)
185         rval = 1
186
187     return rval
188
189 if __name__ == '__main__':
190     sys.exit(main())