Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/env python | |
| 2 # Copyright 2017 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """ | |
| 7 A tool to generate a predetermined resource ids file that can be used as an | |
| 8 input to grit via the -p option. See tools/gritsettings/README.md for details. | |
|
Nico
2017/02/17 21:49:28
Maybe mention that the idea is to run this manuall
Alexei Svitkine (slow)
2017/02/17 21:56:55
Done.
| |
| 9 """ | |
| 10 | |
| 11 import fnmatch | |
| 12 import os | |
| 13 import re | |
| 14 import sys | |
| 15 | |
| 16 # Regular expressions for parsing the #define macro format. Separate regular | |
| 17 # expressions are used for parsing lines with pragma (for builds with | |
| 18 # enable_resource_whitelist_generation flag) in windows and non-windows, and for | |
| 19 # lines without pragma, For example, | |
| 20 # Without generate whitelist flag: | |
| 21 # #define IDS_FOO_MESSAGE 1234 | |
| 22 # With generate whitelist flag in non-windows: | |
| 23 # #define IDS_FOO_MESSAGE _Pragma("whitelisted_resource_1234") 1234 | |
| 24 # With generate whitelist flag in windows: | |
| 25 # #define IDS_FOO_MESSAGE __pragma(message("whitelisted_resource_1234")) 1234 | |
| 26 RESOURCE_EXTRACT_REGEX = re.compile('^#define (\S*) (\d*)$', re.MULTILINE) | |
| 27 RESOURCE_EXTRACT_REGEX_PRAGMA = re.compile( | |
| 28 '^#define (\S*) _Pragma\("whitelisted_resource_\d*"\) (\d*)$', | |
| 29 re.MULTILINE) | |
| 30 RESOURCE_EXTRACT_REGEX_PRAGMA_WINDOWS = re.compile( | |
| 31 '^#define (\S*) __pragma\(message\("whitelisted_resource_\d*"\)\) (\d*)$', | |
| 32 re.MULTILINE) | |
| 33 | |
| 34 ORDERED_RESOURCE_IDS_REGEX = re.compile('^Resource=(\d*)$', re.MULTILINE) | |
| 35 | |
| 36 | |
| 37 def _GetResourceNameIdPairsIter(string_to_scan): | |
| 38 """Gets an iterator of the resource name and id pairs of the given string. | |
| 39 | |
| 40 Scans the input string for lines of the form "#define NAME ID" and returns | |
| 41 an iterator over all matching (NAME, ID) pairs. | |
| 42 | |
| 43 Args: | |
| 44 string_to_scan: The input string to scan. | |
| 45 | |
| 46 Yields: | |
| 47 A tuple of name and id. | |
| 48 """ | |
| 49 for match in RESOURCE_EXTRACT_REGEX.finditer(string_to_scan): | |
| 50 yield match.group(1, 2) | |
| 51 for match in RESOURCE_EXTRACT_REGEX_PRAGMA.finditer(string_to_scan): | |
| 52 yield match.group(1, 2) | |
| 53 for match in RESOURCE_EXTRACT_REGEX_PRAGMA_WINDOWS.finditer(string_to_scan): | |
| 54 yield match.group(1, 2) | |
| 55 | |
|
Nico
2017/02/17 21:49:28
2 empty lines between toplevel things again
Alexei Svitkine (slow)
2017/02/17 21:56:55
Done.
| |
| 56 def _ReadOrderedResourceIds(path): | |
| 57 """Reads ordered resource ids from the given file. | |
| 58 | |
| 59 The resources are expected to be of the format produced by running Chrome | |
| 60 with --print-resource-ids command line. | |
| 61 | |
| 62 Args: | |
| 63 path: File path to read resource ids from. | |
| 64 | |
| 65 Returns: | |
| 66 An array of ordered resource ids. | |
| 67 """ | |
| 68 ordered_resource_ids = [] | |
| 69 with open(path, "r") as f: | |
| 70 for match in ORDERED_RESOURCE_IDS_REGEX.finditer(f.read()): | |
| 71 ordered_resource_ids.append(int(match.group(1))) | |
| 72 return ordered_resource_ids | |
| 73 | |
| 74 def GenerateResourceMapping(original_resources, ordered_resource_ids): | |
| 75 """Generates a resource mapping from the ordered ids and the original mapping. | |
| 76 | |
| 77 The returned dict will assign new ids to ordered_resource_ids numerically | |
| 78 increasing from 101. | |
| 79 | |
| 80 Args: | |
| 81 original_resources: A dict of original resource ids to resource names. | |
| 82 ordered_resource_ids: An array of ordered resource ids. | |
| 83 | |
| 84 Returns: | |
| 85 A dict of resource ids to resource names. | |
| 86 """ | |
| 87 output_resource_map = {} | |
| 88 # 101 is used as the starting value since other parts of GRIT require it to be | |
| 89 # the minimum (e.g. rc_header.py) based on Windows resource numbering. | |
| 90 next_id = 101 | |
| 91 for original_id in ordered_resource_ids: | |
| 92 resource_name = original_resources[original_id] | |
| 93 output_resource_map[next_id] = resource_name | |
| 94 next_id += 1 | |
| 95 return output_resource_map | |
| 96 | |
| 97 def ReadResourceIdsFromFile(file, original_resources): | |
| 98 """Reads resource ids from a GRIT-produced header file. | |
| 99 | |
| 100 Args: | |
| 101 file: File to a GRIT-produced header file to read from. | |
| 102 original_resources: Dict of resource ids to resource names to add to. | |
| 103 """ | |
| 104 for resource_name, resource_id in _GetResourceNameIdPairsIter(file.read()): | |
| 105 original_resources[int(resource_id)] = resource_name | |
| 106 | |
| 107 def _ReadOriginalResourceIds(out_dir): | |
| 108 """Reads resource ids from GRIT header files in the specified directory. | |
| 109 | |
| 110 Args: | |
| 111 out_dir: A Chrome build output directory (e.g. out/gn) to scan. | |
| 112 | |
| 113 Returns: | |
| 114 A dict of resource ids to resource names. | |
| 115 """ | |
| 116 original_resources = {} | |
| 117 for root, dirnames, filenames in os.walk(out_dir + '/gen'): | |
| 118 for filename in filenames: | |
| 119 if filename.endswith(('_resources.h', '_settings.h', '_strings.h')): | |
| 120 with open(os.path.join(root, filename), "r") as f: | |
| 121 ReadResourceIdsFromFile(f, original_resources) | |
| 122 return original_resources | |
| 123 | |
| 124 def _GeneratePredeterminedIdsFile(ordered_resources_file, out_dir): | |
| 125 """Generates a predetermined ids file. | |
| 126 | |
| 127 Args: | |
| 128 ordered_resources_file: File path to read ordered resource ids from. | |
| 129 out_dir: A Chrome build output directory (e.g. out/gn) to scan. | |
| 130 | |
| 131 Returns: | |
| 132 A dict of resource ids to resource names. | |
| 133 """ | |
| 134 original_resources = _ReadOriginalResourceIds(out_dir) | |
| 135 ordered_resource_ids = _ReadOrderedResourceIds(ordered_resources_file) | |
| 136 output_resource_map = GenerateResourceMapping(original_resources, | |
| 137 ordered_resource_ids) | |
| 138 for res_id in sorted(output_resource_map.keys()): | |
| 139 print "{} {}".format(output_resource_map[res_id], res_id) | |
| 140 | |
| 141 | |
| 142 def main(argv): | |
| 143 if len(argv) != 2: | |
| 144 print("usage: gen_predetermined_ids.py <ordered_resources_file> <out_dir>") | |
| 145 sys.exit(1) | |
| 146 ordered_resources_file, out_dir = argv[0], argv[1] | |
| 147 _GeneratePredeterminedIdsFile(ordered_resources_file, out_dir) | |
| 148 | |
| 149 | |
| 150 if '__main__' == __name__: | |
| 151 main(sys.argv[1:]) | |
| 152 | |
| 153 | |
|
Nico
2017/02/17 21:49:28
nit: no trailing empty lines
Alexei Svitkine (slow)
2017/02/17 21:56:55
Done.
| |
| OLD | NEW |