OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2014 The Chromium Authors. All rights reserved. | 3 # Copyright 2014 The Chromium Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 import collections | 7 import collections |
8 import re | 8 import re |
9 import optparse | 9 import optparse |
10 import os | 10 import os |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 DirectiveSet.prefix_to_strip_key) | 117 DirectiveSet.prefix_to_strip_key) |
118 | 118 |
119 | 119 |
120 class HeaderParser(object): | 120 class HeaderParser(object): |
121 single_line_comment_re = re.compile(r'\s*//') | 121 single_line_comment_re = re.compile(r'\s*//') |
122 multi_line_comment_start_re = re.compile(r'\s*/\*') | 122 multi_line_comment_start_re = re.compile(r'\s*/\*') |
123 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') | 123 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') |
124 enum_end_re = re.compile(r'^\s*}\s*;\.*$') | 124 enum_end_re = re.compile(r'^\s*}\s*;\.*$') |
125 generator_directive_re = re.compile( | 125 generator_directive_re = re.compile( |
126 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') | 126 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') |
| 127 multi_line_generator_directive_start_re = re.compile( |
| 128 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]*)\\$') |
| 129 multi_line_directive_continuation_re = re.compile( |
| 130 r'^\s*//\s+([\.\w]+)\\$') |
| 131 multi_line_directive_end_re = re.compile( |
| 132 r'^\s*//\s+([\.\w]*)$') |
127 | 133 |
128 optional_class_or_struct_re = r'(class|struct)?' | 134 optional_class_or_struct_re = r'(class|struct)?' |
129 enum_name_re = r'(\w+)' | 135 enum_name_re = r'(\w+)' |
130 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?' | 136 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?' |
131 enum_start_re = re.compile(r'^\s*enum\s+' + optional_class_or_struct_re + | 137 enum_start_re = re.compile(r'^\s*enum\s+' + optional_class_or_struct_re + |
132 '\s*' + enum_name_re + '\s*' + optional_fixed_type_re + '\s*{\s*$') | 138 '\s*' + enum_name_re + '\s*' + optional_fixed_type_re + '\s*{\s*$') |
133 | 139 |
134 def __init__(self, lines): | 140 def __init__(self, lines, path=None): |
135 self._lines = lines | 141 self._lines = lines |
| 142 self._path = path |
136 self._enum_definitions = [] | 143 self._enum_definitions = [] |
137 self._in_enum = False | 144 self._in_enum = False |
138 self._current_definition = None | 145 self._current_definition = None |
139 self._generator_directives = DirectiveSet() | 146 self._generator_directives = DirectiveSet() |
| 147 self._multi_line_generator_directive = None |
| 148 |
| 149 def _ApplyGeneratorDirectives(self): |
| 150 self._generator_directives.UpdateDefinition(self._current_definition) |
| 151 self._generator_directives = DirectiveSet() |
140 | 152 |
141 def ParseDefinitions(self): | 153 def ParseDefinitions(self): |
142 for line in self._lines: | 154 for line in self._lines: |
143 self._ParseLine(line) | 155 self._ParseLine(line) |
144 return self._enum_definitions | 156 return self._enum_definitions |
145 | 157 |
146 def _ParseLine(self, line): | 158 def _ParseLine(self, line): |
147 if not self._in_enum: | 159 if self._multi_line_generator_directive: |
| 160 self._ParseMultiLineDirectiveLine(line) |
| 161 elif not self._in_enum: |
148 self._ParseRegularLine(line) | 162 self._ParseRegularLine(line) |
149 else: | 163 else: |
150 self._ParseEnumLine(line) | 164 self._ParseEnumLine(line) |
151 | 165 |
152 def _ParseEnumLine(self, line): | 166 def _ParseEnumLine(self, line): |
153 if HeaderParser.single_line_comment_re.match(line): | 167 if HeaderParser.single_line_comment_re.match(line): |
154 return | 168 return |
155 if HeaderParser.multi_line_comment_start_re.match(line): | 169 if HeaderParser.multi_line_comment_start_re.match(line): |
156 raise Exception('Multi-line comments in enums are not supported.') | 170 raise Exception('Multi-line comments in enums are not supported in ' + |
| 171 self._path) |
157 enum_end = HeaderParser.enum_end_re.match(line) | 172 enum_end = HeaderParser.enum_end_re.match(line) |
158 enum_entry = HeaderParser.enum_line_re.match(line) | 173 enum_entry = HeaderParser.enum_line_re.match(line) |
159 if enum_end: | 174 if enum_end: |
160 self._ApplyGeneratorDirectives() | 175 self._ApplyGeneratorDirectives() |
161 self._current_definition.Finalize() | 176 self._current_definition.Finalize() |
162 self._enum_definitions.append(self._current_definition) | 177 self._enum_definitions.append(self._current_definition) |
163 self._in_enum = False | 178 self._in_enum = False |
164 elif enum_entry: | 179 elif enum_entry: |
165 enum_key = enum_entry.groups()[0] | 180 enum_key = enum_entry.groups()[0] |
166 enum_value = enum_entry.groups()[2] | 181 enum_value = enum_entry.groups()[2] |
167 self._current_definition.AppendEntry(enum_key, enum_value) | 182 self._current_definition.AppendEntry(enum_key, enum_value) |
168 | 183 |
169 def _ApplyGeneratorDirectives(self): | 184 def _ParseMultiLineDirectiveLine(self, line): |
170 self._generator_directives.UpdateDefinition(self._current_definition) | 185 multi_line_directive_continuation = ( |
171 self._generator_directives = DirectiveSet() | 186 HeaderParser.multi_line_directive_continuation_re.match(line)) |
| 187 multi_line_directive_end = ( |
| 188 HeaderParser.multi_line_directive_end_re.match(line)) |
| 189 |
| 190 if multi_line_directive_continuation: |
| 191 value_cont = multi_line_directive_continuation.groups()[0] |
| 192 self._multi_line_generator_directive[1].append(value_cont) |
| 193 elif multi_line_directive_end: |
| 194 directive_name = self._multi_line_generator_directive[0] |
| 195 directive_value = "".join(self._multi_line_generator_directive[1]) |
| 196 directive_value += multi_line_directive_end.groups()[0] |
| 197 self._multi_line_generator_directive = None |
| 198 self._generator_directives.Update(directive_name, directive_value) |
| 199 else: |
| 200 raise Exception('Malformed multi-line directive declaration in ' + |
| 201 self._path) |
172 | 202 |
173 def _ParseRegularLine(self, line): | 203 def _ParseRegularLine(self, line): |
174 enum_start = HeaderParser.enum_start_re.match(line) | 204 enum_start = HeaderParser.enum_start_re.match(line) |
175 generator_directive = HeaderParser.generator_directive_re.match(line) | 205 generator_directive = HeaderParser.generator_directive_re.match(line) |
176 if enum_start: | 206 multi_line_generator_directive_start = ( |
| 207 HeaderParser.multi_line_generator_directive_start_re.match(line)) |
| 208 |
| 209 if generator_directive: |
| 210 directive_name = generator_directive.groups()[0] |
| 211 directive_value = generator_directive.groups()[1] |
| 212 self._generator_directives.Update(directive_name, directive_value) |
| 213 elif multi_line_generator_directive_start: |
| 214 directive_name = multi_line_generator_directive_start.groups()[0] |
| 215 directive_value = multi_line_generator_directive_start.groups()[1] |
| 216 self._multi_line_generator_directive = (directive_name, [directive_value]) |
| 217 elif enum_start: |
177 if self._generator_directives.empty: | 218 if self._generator_directives.empty: |
178 return | 219 return |
179 self._current_definition = EnumDefinition( | 220 self._current_definition = EnumDefinition( |
180 original_enum_name=enum_start.groups()[1], | 221 original_enum_name=enum_start.groups()[1], |
181 fixed_type=enum_start.groups()[3]) | 222 fixed_type=enum_start.groups()[3]) |
182 self._in_enum = True | 223 self._in_enum = True |
183 elif generator_directive: | |
184 directive_name = generator_directive.groups()[0] | |
185 directive_value = generator_directive.groups()[1] | |
186 self._generator_directives.Update(directive_name, directive_value) | |
187 | |
188 | 224 |
189 def GetScriptName(): | 225 def GetScriptName(): |
190 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) | 226 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) |
191 build_index = script_components.index('build') | 227 build_index = script_components.index('build') |
192 return os.sep.join(script_components[build_index:]) | 228 return os.sep.join(script_components[build_index:]) |
193 | 229 |
194 | 230 |
195 def DoGenerate(options, source_paths): | 231 def DoGenerate(options, source_paths): |
196 output_paths = [] | 232 output_paths = [] |
197 for source_path in source_paths: | 233 for source_path in source_paths: |
198 enum_definitions = DoParseHeaderFile(source_path) | 234 enum_definitions = DoParseHeaderFile(source_path) |
199 for enum_definition in enum_definitions: | 235 for enum_definition in enum_definitions: |
200 package_path = enum_definition.enum_package.replace('.', os.path.sep) | 236 package_path = enum_definition.enum_package.replace('.', os.path.sep) |
201 file_name = enum_definition.class_name + '.java' | 237 file_name = enum_definition.class_name + '.java' |
202 output_path = os.path.join(options.output_dir, package_path, file_name) | 238 output_path = os.path.join(options.output_dir, package_path, file_name) |
203 output_paths.append(output_path) | 239 output_paths.append(output_path) |
204 if not options.print_output_only: | 240 if not options.print_output_only: |
205 build_utils.MakeDirectory(os.path.dirname(output_path)) | 241 build_utils.MakeDirectory(os.path.dirname(output_path)) |
206 DoWriteOutput(source_path, output_path, enum_definition) | 242 DoWriteOutput(source_path, output_path, enum_definition) |
207 return output_paths | 243 return output_paths |
208 | 244 |
209 | 245 |
210 def DoParseHeaderFile(path): | 246 def DoParseHeaderFile(path): |
211 with open(path) as f: | 247 with open(path) as f: |
212 return HeaderParser(f.readlines()).ParseDefinitions() | 248 return HeaderParser(f.readlines(), path).ParseDefinitions() |
213 | 249 |
214 | 250 |
215 def GenerateOutput(source_path, enum_definition): | 251 def GenerateOutput(source_path, enum_definition): |
216 template = Template(""" | 252 template = Template(""" |
217 // Copyright 2014 The Chromium Authors. All rights reserved. | 253 // Copyright 2014 The Chromium Authors. All rights reserved. |
218 // Use of this source code is governed by a BSD-style license that can be | 254 // Use of this source code is governed by a BSD-style license that can be |
219 // found in the LICENSE file. | 255 // found in the LICENSE file. |
220 | 256 |
221 // This file is autogenerated by | 257 // This file is autogenerated by |
222 // ${SCRIPT_NAME} | 258 // ${SCRIPT_NAME} |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 314 |
279 output_paths = DoGenerate(options, args) | 315 output_paths = DoGenerate(options, args) |
280 | 316 |
281 if options.assert_files_list: | 317 if options.assert_files_list: |
282 AssertFilesList(output_paths, options.assert_files_list) | 318 AssertFilesList(output_paths, options.assert_files_list) |
283 | 319 |
284 return " ".join(output_paths) | 320 return " ".join(output_paths) |
285 | 321 |
286 if __name__ == '__main__': | 322 if __name__ == '__main__': |
287 DoMain(sys.argv[1:]) | 323 DoMain(sys.argv[1:]) |
OLD | NEW |