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 from datetime import date | 8 from datetime import date |
9 import re | 9 import re |
10 import optparse | 10 import optparse |
11 import os | 11 import os |
12 from string import Template | 12 from string import Template |
13 import sys | 13 import sys |
| 14 import zipfile |
14 | 15 |
15 from util import build_utils | 16 from util import build_utils |
16 | 17 |
17 # List of C++ types that are compatible with the Java code generated by this | 18 # List of C++ types that are compatible with the Java code generated by this |
18 # script. | 19 # script. |
19 # | 20 # |
20 # This script can parse .idl files however, at present it ignores special | 21 # This script can parse .idl files however, at present it ignores special |
21 # rules such as [cpp_enum_prefix_override="ax_attr"]. | 22 # rules such as [cpp_enum_prefix_override="ax_attr"]. |
22 ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char', | 23 ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char', |
23 'short', 'unsigned short', | 24 'short', 'unsigned short', |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 original_enum_name=enum_start.groups()[1], | 227 original_enum_name=enum_start.groups()[1], |
227 fixed_type=enum_start.groups()[3]) | 228 fixed_type=enum_start.groups()[3]) |
228 self._in_enum = True | 229 self._in_enum = True |
229 | 230 |
230 def GetScriptName(): | 231 def GetScriptName(): |
231 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) | 232 script_components = os.path.abspath(sys.argv[0]).split(os.path.sep) |
232 build_index = script_components.index('build') | 233 build_index = script_components.index('build') |
233 return os.sep.join(script_components[build_index:]) | 234 return os.sep.join(script_components[build_index:]) |
234 | 235 |
235 | 236 |
236 def DoGenerate(output_dir, source_paths, print_output_only=False): | 237 def DoGenerate(source_paths): |
237 output_paths = [] | |
238 for source_path in source_paths: | 238 for source_path in source_paths: |
239 enum_definitions = DoParseHeaderFile(source_path) | 239 enum_definitions = DoParseHeaderFile(source_path) |
240 if not enum_definitions: | 240 if not enum_definitions: |
241 raise Exception('No enums found in %s\n' | 241 raise Exception('No enums found in %s\n' |
242 'Did you forget prefixing enums with ' | 242 'Did you forget prefixing enums with ' |
243 '"// GENERATED_JAVA_ENUM_PACKAGE: foo"?' % | 243 '"// GENERATED_JAVA_ENUM_PACKAGE: foo"?' % |
244 source_path) | 244 source_path) |
245 for enum_definition in enum_definitions: | 245 for enum_definition in enum_definitions: |
246 package_path = enum_definition.enum_package.replace('.', os.path.sep) | 246 package_path = enum_definition.enum_package.replace('.', os.path.sep) |
247 file_name = enum_definition.class_name + '.java' | 247 file_name = enum_definition.class_name + '.java' |
248 output_path = os.path.join(output_dir, package_path, file_name) | 248 output_path = os.path.join(package_path, file_name) |
249 output_paths.append(output_path) | 249 output = GenerateOutput(source_path, enum_definition) |
250 if not print_output_only: | 250 yield output_path, output |
251 build_utils.MakeDirectory(os.path.dirname(output_path)) | |
252 DoWriteOutput(source_path, output_path, enum_definition) | |
253 return output_paths | |
254 | 251 |
255 | 252 |
256 def DoParseHeaderFile(path): | 253 def DoParseHeaderFile(path): |
257 with open(path) as f: | 254 with open(path) as f: |
258 return HeaderParser(f.readlines(), path).ParseDefinitions() | 255 return HeaderParser(f.readlines(), path).ParseDefinitions() |
259 | 256 |
260 | 257 |
261 def GenerateOutput(source_path, enum_definition): | 258 def GenerateOutput(source_path, enum_definition): |
262 template = Template(""" | 259 template = Template(""" |
263 // Copyright ${YEAR} The Chromium Authors. All rights reserved. | 260 // Copyright ${YEAR} The Chromium Authors. All rights reserved. |
(...skipping 26 matching lines...) Expand all Loading... |
290 'CLASS_NAME': enum_definition.class_name, | 287 'CLASS_NAME': enum_definition.class_name, |
291 'ENUM_ENTRIES': enum_entries_string, | 288 'ENUM_ENTRIES': enum_entries_string, |
292 'PACKAGE': enum_definition.enum_package, | 289 'PACKAGE': enum_definition.enum_package, |
293 'SCRIPT_NAME': GetScriptName(), | 290 'SCRIPT_NAME': GetScriptName(), |
294 'SOURCE_PATH': source_path, | 291 'SOURCE_PATH': source_path, |
295 'YEAR': str(date.today().year) | 292 'YEAR': str(date.today().year) |
296 } | 293 } |
297 return template.substitute(values) | 294 return template.substitute(values) |
298 | 295 |
299 | 296 |
300 def DoWriteOutput(source_path, output_path, enum_definition): | |
301 with open(output_path, 'w') as out_file: | |
302 out_file.write(GenerateOutput(source_path, enum_definition)) | |
303 | |
304 def AssertFilesList(output_paths, assert_files_list): | 297 def AssertFilesList(output_paths, assert_files_list): |
305 actual = set(output_paths) | 298 actual = set(output_paths) |
306 expected = set(assert_files_list) | 299 expected = set(assert_files_list) |
307 if not actual == expected: | 300 if not actual == expected: |
308 need_to_add = list(actual - expected) | 301 need_to_add = list(actual - expected) |
309 need_to_remove = list(expected - actual) | 302 need_to_remove = list(expected - actual) |
310 raise Exception('Output files list does not match expectations. Please ' | 303 raise Exception('Output files list does not match expectations. Please ' |
311 'add %s and remove %s.' % (need_to_add, need_to_remove)) | 304 'add %s and remove %s.' % (need_to_add, need_to_remove)) |
312 | 305 |
313 def DoMain(argv): | 306 def DoMain(argv): |
314 usage = 'usage: %prog [options] output_dir input_file(s)...' | 307 usage = 'usage: %prog [options] [output_dir] input_file(s)...' |
315 parser = optparse.OptionParser(usage=usage) | 308 parser = optparse.OptionParser(usage=usage) |
316 | 309 |
317 parser.add_option('--assert_file', action="append", default=[], | 310 parser.add_option('--assert_file', action="append", default=[], |
318 dest="assert_files_list", help='Assert that the given ' | 311 dest="assert_files_list", help='Assert that the given ' |
319 'file is an output. There can be multiple occurrences of ' | 312 'file is an output. There can be multiple occurrences of ' |
320 'this flag.') | 313 'this flag.') |
| 314 parser.add_option('--srcjar', |
| 315 help='When specified, a .srcjar at the given path is ' |
| 316 'created instead of individual .java files.') |
321 parser.add_option('--print_output_only', help='Only print output paths.', | 317 parser.add_option('--print_output_only', help='Only print output paths.', |
322 action='store_true') | 318 action='store_true') |
323 parser.add_option('--verbose', help='Print more information.', | 319 parser.add_option('--verbose', help='Print more information.', |
324 action='store_true') | 320 action='store_true') |
325 | 321 |
326 options, args = parser.parse_args(argv) | 322 options, args = parser.parse_args(argv) |
327 if len(args) < 2: | 323 if options.srcjar: |
328 parser.error('Need to specify output directory and at least one input file') | 324 if options.print_output_only: |
329 output_paths = DoGenerate(args[0], args[1:], | 325 parser.error('--print_output_only does not work with --srcjar') |
330 print_output_only=options.print_output_only) | 326 if options.assert_files_list: |
| 327 parser.error('--assert_file does not work with --srcjar') |
331 | 328 |
332 if options.assert_files_list: | 329 with zipfile.ZipFile(options.srcjar, 'w', zipfile.ZIP_STORED) as srcjar: |
333 AssertFilesList(output_paths, options.assert_files_list) | 330 for output_path, data in DoGenerate(args): |
| 331 srcjar.writestr(build_utils.CreateHermeticZipInfo(output_path), data) |
| 332 else: |
| 333 # TODO(agrieve): Delete this non-srcjar branch once GYP is gone. |
| 334 if len(args) < 2: |
| 335 parser.error( |
| 336 'Need to specify output directory and at least one input file') |
334 | 337 |
335 if options.verbose: | 338 output_dir = args[0] |
336 print 'Output paths:' | 339 output_paths = [] |
337 print '\n'.join(output_paths) | 340 for output_path, data in DoGenerate(args[1:]): |
| 341 full_path = os.path.join(output_dir, output_path) |
| 342 output_paths.append(full_path) |
| 343 if not options.print_output_only: |
| 344 build_utils.MakeDirectory(os.path.dirname(full_path)) |
| 345 with open(full_path, 'w') as out_file: |
| 346 out_file.write(data) |
338 | 347 |
339 return ' '.join(output_paths) | 348 if options.assert_files_list: |
| 349 AssertFilesList(output_paths, options.assert_files_list) |
| 350 |
| 351 if options.verbose: |
| 352 print 'Output paths:' |
| 353 print '\n'.join(output_paths) |
| 354 |
| 355 # Used by GYP. |
| 356 return ' '.join(output_paths) |
| 357 |
340 | 358 |
341 if __name__ == '__main__': | 359 if __name__ == '__main__': |
342 DoMain(sys.argv[1:]) | 360 DoMain(sys.argv[1:]) |
OLD | NEW |