blob: 1e97496fc4568035467f2b508ad0bd83f1ef6862 [file] [log] [blame]
#!/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))