#!/usr/bin/env python # Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights # reserved. Use of this source code is governed by a BSD-style license # that can be found in the LICENSE file. """ A simple utility function to merge pack resource files into a single resource file. """ from __future__ import absolute_import from __future__ import print_function from cef_parser import get_copyright from file_util import * import os import re import string import sys def _make_pack_header_segment(input, ids): result = """ // --------------------------------------------------------------------------- // From $FILE$: """ filename = os.path.split(input)[1] result = result.replace('$FILE$', filename) for name, id in ids.items(): result += "\n#define %s %s" % (name, id) return result def make_pack_header(output, all_files): # header string result = get_copyright(full=True, translator=False) + \ """// // --------------------------------------------------------------------------- // // This file is generated by the make_pack_header.py tool. // #ifndef $GUARD$ #define $GUARD$ #pragma once""" # generate the file segments for file, ids in all_files.items(): result += _make_pack_header_segment(file, ids) # footer string result += \ """ #endif // $GUARD$ """ # add the guard string filename = os.path.split(output)[1] guard = 'CEF_INCLUDE_' + filename.replace('.', '_').upper() + '_' result = result.replace('$GUARD$', guard) return result def _get_cpp_var_name(output): filename_no_ext = os.path.splitext(os.path.split(output)[1])[0] # Convert to CamelCase after removing the 'cef_' prefix. parts = filename_no_ext.split('_')[1:] return "".join([p[0].upper() + p[1:] for p in parts]) def make_pack_inc(output, all_files): var = 'IdNames' + _get_cpp_var_name(output) result = get_copyright(full=False, translator=False) + \ """// // --------------------------------------------------------------------------- // // This file was generated by the make_pack_header.py tool. // namespace { struct $var$ { int id; const char* const name; }; const $var$ k$var$[] = {""".replace('$var$', var) for file, ids in all_files.items(): result += '\n // From %s:' % file for name, id in ids.items(): result += '\n {%s, "%s"},' % (id, name) result += \ """ }; const size_t k$var$Size = std::size(k$var$); } // namespace """.replace('$var$', var) return result def _get_defines(input, all_names): contents = read_file(input) ids = {} # Format for Windows builds with resource whitelisting enabled [1]: # #define IDR_RESOURCE_NAME (::ui::WhitelistedResource<12345>(), 12345) # Format for other builds: # #define IDR_RESOURCE_NAME 12345 # [1] See https://crbug.com/684788#c18 regex = r'#define\s([A-Za-z0-9_]{1,})\s+' if contents.find('ui::WhitelistedResource') > 0: regex += r'.*<' regex += r'([0-9]{1,})' # identify the defines in the file p = re.compile(regex) list = p.findall(contents) for name, id in list: # If the same define exists in multiple files add a suffix. if name in all_names: all_names[name] += 1 name += '_%d' % all_names[name] else: all_names[name] = 1 ids[name] = id return ids def write_pack_header(out_header_file, out_inc_file, inputs): # sort the input files by name inputs = sorted(inputs, key=lambda path: os.path.split(path)[1]) all_names = {} all_files = {} # generate the file segments for file in inputs: filename = os.path.split(file)[1] assert not filename in all_files, filename all_files[filename] = _get_defines(file, all_names) out_file = os.path.abspath(out_header_file) result = make_pack_header(out_file, all_files) if not bool(result): sys.stderr.write('Failed to create %s\n' % out_file) sys.exit(1) retval1 = write_file_if_changed(out_file, result) out_file = os.path.abspath(out_inc_file) result = make_pack_inc(out_file, all_files) if not bool(result): sys.stderr.write('Failed to create %s\n' % out_file) sys.exit(1) retval2 = write_file_if_changed(out_file, result) return retval1 #or retval2 def main(argv): if len(argv) < 4: print( "Usage:\n %s [input_file2] ... " % argv[0]) sys.exit(-1) write_pack_header(argv[1], argv[2], argv[3:]) if '__main__' == __name__: main(sys.argv)