| 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 11 matching lines...) Expand all Loading... |
| 22 'short', 'unsigned short', | 22 'short', 'unsigned short', |
| 23 'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t'] | 23 'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t'] |
| 24 | 24 |
| 25 class EnumDefinition(object): | 25 class EnumDefinition(object): |
| 26 def __init__(self, original_enum_name=None, class_name_override=None, | 26 def __init__(self, original_enum_name=None, class_name_override=None, |
| 27 enum_package=None, entries=None, fixed_type=None): | 27 enum_package=None, entries=None, fixed_type=None): |
| 28 self.original_enum_name = original_enum_name | 28 self.original_enum_name = original_enum_name |
| 29 self.class_name_override = class_name_override | 29 self.class_name_override = class_name_override |
| 30 self.enum_package = enum_package | 30 self.enum_package = enum_package |
| 31 self.entries = collections.OrderedDict(entries or []) | 31 self.entries = collections.OrderedDict(entries or []) |
| 32 self.comments = collections.OrderedDict(entries or []) |
| 32 self.prefix_to_strip = None | 33 self.prefix_to_strip = None |
| 33 self.fixed_type = fixed_type | 34 self.fixed_type = fixed_type |
| 34 | 35 |
| 35 def AppendEntry(self, key, value): | 36 def AppendEntry(self, key, value, comment): |
| 36 if key in self.entries: | 37 if key in self.entries: |
| 37 raise Exception('Multiple definitions of key %s found.' % key) | 38 raise Exception('Multiple definitions of key %s found.' % key) |
| 38 self.entries[key] = value | 39 self.entries[key] = value |
| 40 self.comments[key] = comment |
| 39 | 41 |
| 40 @property | 42 @property |
| 41 def class_name(self): | 43 def class_name(self): |
| 42 return self.class_name_override or self.original_enum_name | 44 return self.class_name_override or self.original_enum_name |
| 43 | 45 |
| 44 def Finalize(self): | 46 def Finalize(self): |
| 45 self._Validate() | 47 self._Validate() |
| 46 self._AssignEntryIndices() | 48 self._AssignEntryIndices() |
| 47 self._StripPrefix() | 49 self._StripPrefix() |
| 48 | 50 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 def UpdateDefinition(self, definition): | 116 def UpdateDefinition(self, definition): |
| 115 definition.class_name_override = self._directives.get( | 117 definition.class_name_override = self._directives.get( |
| 116 DirectiveSet.class_name_override_key, '') | 118 DirectiveSet.class_name_override_key, '') |
| 117 definition.enum_package = self._directives.get( | 119 definition.enum_package = self._directives.get( |
| 118 DirectiveSet.enum_package_key) | 120 DirectiveSet.enum_package_key) |
| 119 definition.prefix_to_strip = self._directives.get( | 121 definition.prefix_to_strip = self._directives.get( |
| 120 DirectiveSet.prefix_to_strip_key) | 122 DirectiveSet.prefix_to_strip_key) |
| 121 | 123 |
| 122 | 124 |
| 123 class HeaderParser(object): | 125 class HeaderParser(object): |
| 124 single_line_comment_re = re.compile(r'\s*//') | 126 single_line_comment_re = re.compile(r'\s*//(.*)') |
| 125 multi_line_comment_start_re = re.compile(r'\s*/\*') | 127 multi_line_comment_start_re = re.compile(r'\s*/\*') |
| 126 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') | 128 enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?') |
| 127 enum_end_re = re.compile(r'^\s*}\s*;\.*$') | 129 enum_end_re = re.compile(r'^\s*}\s*;\.*$') |
| 128 generator_directive_re = re.compile( | 130 generator_directive_re = re.compile( |
| 129 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') | 131 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$') |
| 130 multi_line_generator_directive_start_re = re.compile( | 132 multi_line_generator_directive_start_re = re.compile( |
| 131 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$') | 133 r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$') |
| 132 multi_line_directive_continuation_re = re.compile( | 134 multi_line_directive_continuation_re = re.compile( |
| 133 r'^\s*//\s+([\.\w]+)$') | 135 r'^\s*//\s+([\.\w]+)$') |
| 134 multi_line_directive_end_re = re.compile( | 136 multi_line_directive_end_re = re.compile( |
| 135 r'^\s*//\s+([\.\w]*)\)$') | 137 r'^\s*//\s+([\.\w]*)\)$') |
| 136 | 138 |
| 137 optional_class_or_struct_re = r'(class|struct)?' | 139 optional_class_or_struct_re = r'(class|struct)?' |
| 138 enum_name_re = r'(\w+)' | 140 enum_name_re = r'(\w+)' |
| 139 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?' | 141 optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?' |
| 140 enum_start_re = re.compile(r'^\s*(?:\[cpp.*\])?\s*enum\s+' + | 142 enum_start_re = re.compile(r'^\s*(?:\[cpp.*\])?\s*enum\s+' + |
| 141 optional_class_or_struct_re + '\s*' + enum_name_re + '\s*' + | 143 optional_class_or_struct_re + '\s*' + enum_name_re + '\s*' + |
| 142 optional_fixed_type_re + '\s*{\s*$') | 144 optional_fixed_type_re + '\s*{\s*$') |
| 143 | 145 |
| 144 def __init__(self, lines, path=None): | 146 def __init__(self, lines, path=None): |
| 145 self._lines = lines | 147 self._lines = lines |
| 146 self._path = path | 148 self._path = path |
| 147 self._enum_definitions = [] | 149 self._enum_definitions = [] |
| 148 self._in_enum = False | 150 self._in_enum = False |
| 151 self._current_comment = [] |
| 149 self._current_definition = None | 152 self._current_definition = None |
| 150 self._generator_directives = DirectiveSet() | 153 self._generator_directives = DirectiveSet() |
| 151 self._multi_line_generator_directive = None | 154 self._multi_line_generator_directive = None |
| 152 | 155 |
| 153 def _ApplyGeneratorDirectives(self): | 156 def _ApplyGeneratorDirectives(self): |
| 154 self._generator_directives.UpdateDefinition(self._current_definition) | 157 self._generator_directives.UpdateDefinition(self._current_definition) |
| 155 self._generator_directives = DirectiveSet() | 158 self._generator_directives = DirectiveSet() |
| 156 | 159 |
| 157 def ParseDefinitions(self): | 160 def ParseDefinitions(self): |
| 158 for line in self._lines: | 161 for line in self._lines: |
| 159 self._ParseLine(line) | 162 self._ParseLine(line) |
| 160 return self._enum_definitions | 163 return self._enum_definitions |
| 161 | 164 |
| 162 def _ParseLine(self, line): | 165 def _ParseLine(self, line): |
| 163 if self._multi_line_generator_directive: | 166 if self._multi_line_generator_directive: |
| 164 self._ParseMultiLineDirectiveLine(line) | 167 self._ParseMultiLineDirectiveLine(line) |
| 165 elif not self._in_enum: | 168 elif not self._in_enum: |
| 166 self._ParseRegularLine(line) | 169 self._ParseRegularLine(line) |
| 167 else: | 170 else: |
| 168 self._ParseEnumLine(line) | 171 self._ParseEnumLine(line) |
| 169 | 172 |
| 170 def _ParseEnumLine(self, line): | 173 def _ParseEnumLine(self, line): |
| 171 if HeaderParser.single_line_comment_re.match(line): | 174 comment = HeaderParser.single_line_comment_re.match(line) |
| 175 if comment: |
| 176 self._current_comment.append(comment.groups()[0]) |
| 172 return | 177 return |
| 173 if HeaderParser.multi_line_comment_start_re.match(line): | 178 if HeaderParser.multi_line_comment_start_re.match(line): |
| 179 self._current_comment = [] |
| 174 raise Exception('Multi-line comments in enums are not supported in ' + | 180 raise Exception('Multi-line comments in enums are not supported in ' + |
| 175 self._path) | 181 self._path) |
| 176 enum_end = HeaderParser.enum_end_re.match(line) | 182 enum_end = HeaderParser.enum_end_re.match(line) |
| 177 enum_entry = HeaderParser.enum_line_re.match(line) | 183 enum_entry = HeaderParser.enum_line_re.match(line) |
| 178 if enum_end: | 184 if enum_end: |
| 179 self._ApplyGeneratorDirectives() | 185 self._ApplyGeneratorDirectives() |
| 180 self._current_definition.Finalize() | 186 self._current_definition.Finalize() |
| 181 self._enum_definitions.append(self._current_definition) | 187 self._enum_definitions.append(self._current_definition) |
| 182 self._in_enum = False | 188 self._in_enum = False |
| 183 elif enum_entry: | 189 elif enum_entry: |
| 184 enum_key = enum_entry.groups()[0] | 190 enum_key = enum_entry.groups()[0] |
| 185 enum_value = enum_entry.groups()[2] | 191 enum_value = enum_entry.groups()[2] |
| 186 self._current_definition.AppendEntry(enum_key, enum_value) | 192 self._current_definition.AppendEntry(enum_key, enum_value, |
| 193 self._current_comment) |
| 194 self._current_comment = [] |
| 187 | 195 |
| 188 def _ParseMultiLineDirectiveLine(self, line): | 196 def _ParseMultiLineDirectiveLine(self, line): |
| 189 multi_line_directive_continuation = ( | 197 multi_line_directive_continuation = ( |
| 190 HeaderParser.multi_line_directive_continuation_re.match(line)) | 198 HeaderParser.multi_line_directive_continuation_re.match(line)) |
| 191 multi_line_directive_end = ( | 199 multi_line_directive_end = ( |
| 192 HeaderParser.multi_line_directive_end_re.match(line)) | 200 HeaderParser.multi_line_directive_end_re.match(line)) |
| 193 | 201 |
| 194 if multi_line_directive_continuation: | 202 if multi_line_directive_continuation: |
| 195 value_cont = multi_line_directive_continuation.groups()[0] | 203 value_cont = multi_line_directive_continuation.groups()[0] |
| 196 self._multi_line_generator_directive[1].append(value_cont) | 204 self._multi_line_generator_directive[1].append(value_cont) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 return output_paths | 260 return output_paths |
| 253 | 261 |
| 254 | 262 |
| 255 def DoParseHeaderFile(path): | 263 def DoParseHeaderFile(path): |
| 256 with open(path) as f: | 264 with open(path) as f: |
| 257 return HeaderParser(f.readlines(), path).ParseDefinitions() | 265 return HeaderParser(f.readlines(), path).ParseDefinitions() |
| 258 | 266 |
| 259 | 267 |
| 260 def GenerateOutput(source_path, enum_definition): | 268 def GenerateOutput(source_path, enum_definition): |
| 261 template = Template(""" | 269 template = Template(""" |
| 262 // Copyright 2014 The Chromium Authors. All rights reserved. | 270 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 263 // Use of this source code is governed by a BSD-style license that can be | 271 // Use of this source code is governed by a BSD-style license that can be |
| 264 // found in the LICENSE file. | 272 // found in the LICENSE file. |
| 265 | 273 |
| 266 // This file is autogenerated by | 274 // This file is autogenerated by |
| 267 // ${SCRIPT_NAME} | 275 // ${SCRIPT_NAME} |
| 268 // From | 276 // From |
| 269 // ${SOURCE_PATH} | 277 // ${SOURCE_PATH} |
| 270 | 278 |
| 271 package ${PACKAGE}; | 279 package ${PACKAGE}; |
| 272 | 280 |
| 273 public class ${CLASS_NAME} { | 281 public class ${CLASS_NAME} { |
| 274 ${ENUM_ENTRIES} | 282 ${ENUM_ENTRIES} |
| 275 } | 283 } |
| 276 """) | 284 """) |
| 277 | 285 |
| 278 enum_template = Template(' public static final int ${NAME} = ${VALUE};') | 286 enum_template = Template('${COMMENT} ' |
| 287 'public static final int ${NAME} = ${VALUE};') |
| 279 enum_entries_string = [] | 288 enum_entries_string = [] |
| 280 for enum_name, enum_value in enum_definition.entries.iteritems(): | 289 for enum_name, enum_value in enum_definition.entries.iteritems(): |
| 290 enum_comment_string = [] |
| 291 line_separator = '\n' |
| 292 if enum_name in enum_definition.comments and \ |
| 293 enum_definition.comments[enum_name]: |
| 294 line_separator += '\n' |
| 295 enum_comment_string.append(' /**\n') |
| 296 for comment_line in enum_definition.comments[enum_name]: |
| 297 enum_comment_string.append(' *' + comment_line + '\n') |
| 298 enum_comment_string.append(' */\n') |
| 281 values = { | 299 values = { |
| 300 'COMMENT': ''.join(enum_comment_string), |
| 282 'NAME': enum_name, | 301 'NAME': enum_name, |
| 283 'VALUE': enum_value, | 302 'VALUE': enum_value, |
| 284 } | 303 } |
| 285 enum_entries_string.append(enum_template.substitute(values)) | 304 enum_entries_string.append(enum_template.substitute(values)) |
| 286 enum_entries_string = '\n'.join(enum_entries_string) | 305 enum_entries_string = line_separator.join(enum_entries_string) |
| 287 | 306 |
| 288 values = { | 307 values = { |
| 289 'CLASS_NAME': enum_definition.class_name, | 308 'CLASS_NAME': enum_definition.class_name, |
| 290 'ENUM_ENTRIES': enum_entries_string, | 309 'ENUM_ENTRIES': enum_entries_string, |
| 291 'PACKAGE': enum_definition.enum_package, | 310 'PACKAGE': enum_definition.enum_package, |
| 292 'SCRIPT_NAME': GetScriptName(), | 311 'SCRIPT_NAME': GetScriptName(), |
| 293 'SOURCE_PATH': source_path, | 312 'SOURCE_PATH': source_path, |
| 294 } | 313 } |
| 295 return template.substitute(values) | 314 return template.substitute(values) |
| 296 | 315 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 AssertFilesList(output_paths, options.assert_files_list) | 350 AssertFilesList(output_paths, options.assert_files_list) |
| 332 | 351 |
| 333 if options.verbose: | 352 if options.verbose: |
| 334 print 'Output paths:' | 353 print 'Output paths:' |
| 335 print '\n'.join(output_paths) | 354 print '\n'.join(output_paths) |
| 336 | 355 |
| 337 return ' '.join(output_paths) | 356 return ' '.join(output_paths) |
| 338 | 357 |
| 339 if __name__ == '__main__': | 358 if __name__ == '__main__': |
| 340 DoMain(sys.argv[1:]) | 359 DoMain(sys.argv[1:]) |
| OLD | NEW |