Chromium Code Reviews| 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 | |
| 140 | 148 |
| 141 def ParseDefinitions(self): | 149 def ParseDefinitions(self): |
| 142 for line in self._lines: | 150 for line in self._lines: |
| 143 self._ParseLine(line) | 151 self._ParseLine(line) |
| 144 return self._enum_definitions | 152 return self._enum_definitions |
| 145 | 153 |
| 146 def _ParseLine(self, line): | 154 def _ParseLine(self, line): |
| 147 if not self._in_enum: | 155 if not self._in_enum: |
| 148 self._ParseRegularLine(line) | 156 self._ParseRegularLine(line) |
| 149 else: | 157 else: |
| 150 self._ParseEnumLine(line) | 158 self._ParseEnumLine(line) |
| 151 | 159 |
| 152 def _ParseEnumLine(self, line): | 160 def _ParseEnumLine(self, line): |
| 153 if HeaderParser.single_line_comment_re.match(line): | 161 if HeaderParser.single_line_comment_re.match(line): |
| 154 return | 162 return |
| 155 if HeaderParser.multi_line_comment_start_re.match(line): | 163 if HeaderParser.multi_line_comment_start_re.match(line): |
| 156 raise Exception('Multi-line comments in enums are not supported.') | 164 raise Exception('Multi-line comments in enums are not supported in ' + |
| 165 self._path) | |
| 157 enum_end = HeaderParser.enum_end_re.match(line) | 166 enum_end = HeaderParser.enum_end_re.match(line) |
| 158 enum_entry = HeaderParser.enum_line_re.match(line) | 167 enum_entry = HeaderParser.enum_line_re.match(line) |
| 159 if enum_end: | 168 if enum_end: |
| 160 self._ApplyGeneratorDirectives() | 169 self._ApplyGeneratorDirectives() |
| 161 self._current_definition.Finalize() | 170 self._current_definition.Finalize() |
| 162 self._enum_definitions.append(self._current_definition) | 171 self._enum_definitions.append(self._current_definition) |
| 163 self._in_enum = False | 172 self._in_enum = False |
| 164 elif enum_entry: | 173 elif enum_entry: |
| 165 enum_key = enum_entry.groups()[0] | 174 enum_key = enum_entry.groups()[0] |
| 166 enum_value = enum_entry.groups()[2] | 175 enum_value = enum_entry.groups()[2] |
| 167 self._current_definition.AppendEntry(enum_key, enum_value) | 176 self._current_definition.AppendEntry(enum_key, enum_value) |
| 168 | 177 |
| 169 def _ApplyGeneratorDirectives(self): | 178 def _ApplyGeneratorDirectives(self): |
| 170 self._generator_directives.UpdateDefinition(self._current_definition) | 179 self._generator_directives.UpdateDefinition(self._current_definition) |
| 171 self._generator_directives = DirectiveSet() | 180 self._generator_directives = DirectiveSet() |
| 172 | 181 |
| 173 def _ParseRegularLine(self, line): | 182 def _ParseRegularLine(self, line): |
| 174 enum_start = HeaderParser.enum_start_re.match(line) | 183 enum_start = HeaderParser.enum_start_re.match(line) |
|
jbudorick
2015/01/09 16:39:17
nit: you don't need to run these three regexes if
mkosiba (inactive)
2015/01/09 17:09:57
Done.
| |
| 175 generator_directive = HeaderParser.generator_directive_re.match(line) | 184 generator_directive = HeaderParser.generator_directive_re.match(line) |
| 176 if enum_start: | 185 multi_line_generator_directive_start = ( |
| 186 HeaderParser.multi_line_generator_directive_start_re.match(line)) | |
| 187 | |
| 188 if self._multi_line_generator_directive: | |
| 189 multi_line_directive_continuation = ( | |
| 190 HeaderParser.multi_line_directive_continuation_re.match(line)) | |
| 191 multi_line_directive_end = ( | |
| 192 HeaderParser.multi_line_directive_end_re.match(line)) | |
| 193 | |
| 194 if multi_line_directive_continuation: | |
| 195 value_cont = multi_line_directive_continuation.groups()[0] | |
| 196 self._multi_line_generator_directive[1].append(value_cont) | |
| 197 elif multi_line_directive_end: | |
| 198 directive_name = self._multi_line_generator_directive[0] | |
| 199 directive_value = "".join(self._multi_line_generator_directive[1]) | |
| 200 directive_value += multi_line_directive_end.groups()[0] | |
| 201 self._multi_line_generator_directive = None | |
| 202 self._generator_directives.Update(directive_name, directive_value) | |
| 203 else: | |
| 204 raise Exception('Malformed multi-line directive declaration in ' + | |
| 205 self._path) | |
| 206 elif generator_directive: | |
| 207 directive_name = generator_directive.groups()[0] | |
| 208 directive_value = generator_directive.groups()[1] | |
| 209 self._generator_directives.Update(directive_name, directive_value) | |
| 210 elif multi_line_generator_directive_start: | |
| 211 directive_name = multi_line_generator_directive_start.groups()[0] | |
| 212 directive_value = multi_line_generator_directive_start.groups()[1] | |
| 213 self._multi_line_generator_directive = (directive_name, [directive_value]) | |
| 214 elif enum_start: | |
| 177 if self._generator_directives.empty: | 215 if self._generator_directives.empty: |
| 178 return | 216 return |
| 179 self._current_definition = EnumDefinition( | 217 self._current_definition = EnumDefinition( |
| 180 original_enum_name=enum_start.groups()[1], | 218 original_enum_name=enum_start.groups()[1], |
| 181 fixed_type=enum_start.groups()[3]) | 219 fixed_type=enum_start.groups()[3]) |
| 182 self._in_enum = True | 220 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 | 221 |
| 189 def GetScriptName(): | 222 def GetScriptName(): |
| 190 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) | 223 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) |
| 191 build_index = script_components.index('build') | 224 build_index = script_components.index('build') |
| 192 return os.sep.join(script_components[build_index:]) | 225 return os.sep.join(script_components[build_index:]) |
| 193 | 226 |
| 194 | 227 |
| 195 def DoGenerate(options, source_paths): | 228 def DoGenerate(options, source_paths): |
| 196 output_paths = [] | 229 output_paths = [] |
| 197 for source_path in source_paths: | 230 for source_path in source_paths: |
| 198 enum_definitions = DoParseHeaderFile(source_path) | 231 enum_definitions = DoParseHeaderFile(source_path) |
| 199 for enum_definition in enum_definitions: | 232 for enum_definition in enum_definitions: |
| 200 package_path = enum_definition.enum_package.replace('.', os.path.sep) | 233 package_path = enum_definition.enum_package.replace('.', os.path.sep) |
| 201 file_name = enum_definition.class_name + '.java' | 234 file_name = enum_definition.class_name + '.java' |
| 202 output_path = os.path.join(options.output_dir, package_path, file_name) | 235 output_path = os.path.join(options.output_dir, package_path, file_name) |
| 203 output_paths.append(output_path) | 236 output_paths.append(output_path) |
| 204 if not options.print_output_only: | 237 if not options.print_output_only: |
| 205 build_utils.MakeDirectory(os.path.dirname(output_path)) | 238 build_utils.MakeDirectory(os.path.dirname(output_path)) |
| 206 DoWriteOutput(source_path, output_path, enum_definition) | 239 DoWriteOutput(source_path, output_path, enum_definition) |
| 207 return output_paths | 240 return output_paths |
| 208 | 241 |
| 209 | 242 |
| 210 def DoParseHeaderFile(path): | 243 def DoParseHeaderFile(path): |
| 211 with open(path) as f: | 244 with open(path) as f: |
| 212 return HeaderParser(f.readlines()).ParseDefinitions() | 245 return HeaderParser(f.readlines(), path).ParseDefinitions() |
| 213 | 246 |
| 214 | 247 |
| 215 def GenerateOutput(source_path, enum_definition): | 248 def GenerateOutput(source_path, enum_definition): |
| 216 template = Template(""" | 249 template = Template(""" |
| 217 // Copyright 2014 The Chromium Authors. All rights reserved. | 250 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 218 // Use of this source code is governed by a BSD-style license that can be | 251 // Use of this source code is governed by a BSD-style license that can be |
| 219 // found in the LICENSE file. | 252 // found in the LICENSE file. |
| 220 | 253 |
| 221 // This file is autogenerated by | 254 // This file is autogenerated by |
| 222 // ${SCRIPT_NAME} | 255 // ${SCRIPT_NAME} |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 278 | 311 |
| 279 output_paths = DoGenerate(options, args) | 312 output_paths = DoGenerate(options, args) |
| 280 | 313 |
| 281 if options.assert_files_list: | 314 if options.assert_files_list: |
| 282 AssertFilesList(output_paths, options.assert_files_list) | 315 AssertFilesList(output_paths, options.assert_files_list) |
| 283 | 316 |
| 284 return " ".join(output_paths) | 317 return " ".join(output_paths) |
| 285 | 318 |
| 286 if __name__ == '__main__': | 319 if __name__ == '__main__': |
| 287 DoMain(sys.argv[1:]) | 320 DoMain(sys.argv[1:]) |
| OLD | NEW |