| #!/usr/bin/env python |
| # Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| # for details. All rights reserved. Use of this source code is governed by a |
| # BSD-style license that can be found in the LICENSE file. |
| # |
| # This python script creates string literals in a C++ source file from a C++ |
| # source template and one or more resource files. |
| |
| import os |
| import sys |
| from os.path import join, splitext |
| import time |
| from optparse import OptionParser |
| import re |
| from datetime import date |
| import zlib |
| |
| def makeResources(root_dir, client_dir, input_files, table_name, compress, no_compress_extensions): |
| result = '' |
| resources = [] |
| |
| # Write each file's contents as a byte string constant. |
| for resource_file in input_files: |
| if root_dir and resource_file.startswith(root_dir): |
| resource_file_name = resource_file[ len(root_dir) : ] |
| elif client_dir and resource_file.startswith(client_dir): |
| resource_file_name = resource_file[ len(client_dir) : ] |
| else: |
| resource_file_name = resource_file |
| _, ext = os.path.splitext(resource_file) |
| if ext in no_compress_extensions: |
| # Force no compression for files of this extension. |
| compress = None |
| resource_url = '/%s' % resource_file_name |
| result += '// %s\n' % resource_file |
| result += 'const char ' |
| resource_name = re.sub(r'(/|\.|-|\\)', '_', resource_file_name) + '_' |
| result += resource_name |
| result += '[] = {\n ' |
| fileHandle = open(resource_file, 'rb') |
| lineCounter = 0 |
| file_contents = fileHandle.read() |
| if compress: |
| file_contents = zlib.compress(file_contents) |
| for byte in file_contents: |
| result += r" '\x%02x'," % ord(byte) |
| lineCounter += 1 |
| if lineCounter == 10: |
| result += '\n ' |
| lineCounter = 0 |
| if lineCounter != 0: |
| result += '\n ' |
| result += ' 0\n};\n\n' |
| resource_url_scrubbed = re.sub(r'\\', '/', resource_url) |
| resources.append( |
| (resource_url_scrubbed, resource_name, len(file_contents))); |
| |
| # Write the resource table. |
| result += 'ResourcesEntry __%s_resources_[] = ' % table_name |
| result += '{\n' |
| for res in resources: |
| result += ' { "%s", %s, %d },\n' % res |
| result += ' { 0, 0, 0 },\n' |
| result += '};\n\n' |
| return result |
| |
| |
| def makeFile(output_file, root_dir, client_dir, input_files, outer_namespace, |
| inner_namespace, table_name, compress, no_compress_extensions): |
| cc_text = ''' |
| // Copyright (c) %d, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| ''' % date.today().year |
| cc_text += 'namespace %s {\n' % outer_namespace |
| if inner_namespace != None: |
| cc_text += 'namespace %s {\n' % inner_namespace |
| cc_text += ''' |
| struct ResourcesEntry { |
| const char* path_; |
| const char* resource_; |
| int length_; |
| }; |
| |
| ''' |
| cc_text += makeResources(root_dir, client_dir, input_files, table_name, |
| compress, no_compress_extensions) |
| cc_text += '\n' |
| if inner_namespace != None: |
| cc_text += '} // namespace %s\n' % inner_namespace |
| cc_text += '} // namespace %s\n' % outer_namespace |
| open(output_file, 'w').write(cc_text) |
| return True |
| |
| |
| def main(args): |
| try: |
| # Parse input. |
| parser = OptionParser() |
| parser.add_option("--output", |
| action="store", type="string", |
| help="output file name") |
| parser.add_option("--root_prefix", |
| action="store", type="string", |
| help="root directory for resources") |
| parser.add_option("--outer_namespace", |
| action="store", type="string", |
| help="outer C++ namespace", |
| default="dart") |
| parser.add_option("--inner_namespace", |
| action="store", type="string", |
| help="inner C++ namespace") |
| parser.add_option("--table_name", |
| action="store", type="string", |
| help="name of table") |
| parser.add_option("--client_root", |
| action="store", type="string", |
| help="root directory client resources") |
| parser.add_option("--compress", |
| action="store_true", |
| help="zlib compress resources") |
| parser.add_option("--no_compress_extensions", |
| action="append", |
| default=['.dart'], |
| help="file extensions that should not be compressed.") |
| |
| (options, args) = parser.parse_args() |
| if not options.output: |
| sys.stderr.write('--output not specified\n') |
| return -1 |
| if not options.table_name: |
| sys.stderr.write('--table_name not specified\n') |
| return -1 |
| if len(args) == 0: |
| sys.stderr.write('No input files specified\n') |
| return -1 |
| |
| files = [ ] |
| |
| if options.client_root != None: |
| for dirname, dirnames, filenames in os.walk(options.client_root): |
| # strip out all dot files. |
| filenames = [f for f in filenames if not f[0] == '.'] |
| dirnames[:] = [d for d in dirnames if not d[0] == '.'] |
| for f in filenames: |
| src_path = os.path.join(dirname, f) |
| if (os.path.isdir(src_path)): |
| continue |
| # Skip devtools version |
| if (src_path.find("index_devtools") != -1): |
| continue |
| files.append(src_path) |
| |
| for arg in args: |
| files.append(arg) |
| |
| if not makeFile(options.output, options.root_prefix, options.client_root, |
| files, options.outer_namespace, options.inner_namespace, |
| options.table_name, options.compress, |
| options.no_compress_extensions): |
| return -1 |
| |
| return 0 |
| except Exception, inst: |
| sys.stderr.write('create_resources.py exception\n') |
| sys.stderr.write(str(inst)) |
| sys.stderr.write('\n') |
| return -1 |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv)) |