Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright (C) 2009 Google Inc. All rights reserved. | 3 # Copyright (C) 2009 Google Inc. All rights reserved. |
| 4 # | 4 # |
| 5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
| 6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
| 7 # met: | 7 # met: |
| 8 # | 8 # |
| 9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
| 10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 # all v8 bindings cpp files generated from idls. Files can be assigned into | 36 # all v8 bindings cpp files generated from idls. Files can be assigned into |
| 37 # multiple output files, to reduce maximum compilation unit size and allow | 37 # multiple output files, to reduce maximum compilation unit size and allow |
| 38 # parallel compilation. | 38 # parallel compilation. |
| 39 # | 39 # |
| 40 # usage: action_derivedsourcesallinone.py IDL_FILES_LIST -- OUTPUT_FILE1 OUTPUT_ FILE2 ... | 40 # usage: action_derivedsourcesallinone.py IDL_FILES_LIST -- OUTPUT_FILE1 OUTPUT_ FILE2 ... |
| 41 # | 41 # |
| 42 # Note that IDL_FILES_LIST is a text file containing the IDL file paths. | 42 # Note that IDL_FILES_LIST is a text file containing the IDL file paths. |
| 43 | 43 |
| 44 import errno | 44 import errno |
| 45 import os | 45 import os |
| 46 import os.path | |
| 47 import re | 46 import re |
| 48 import subprocess | 47 import subprocess |
| 49 import sys | 48 import sys |
| 50 | 49 |
| 51 # A regexp for finding Conditional attributes in interface definitions. | 50 # A regexp for finding Conditional attributes in interface definitions. |
| 52 conditionalPattern = re.compile('interface[\s]*\[[^\]]*Conditional=([\_0-9a-zA-Z &|]*)') | 51 CONDITIONAL_PATTERN = re.compile('\[[^\]]*Conditional=([\_0-9a-zA-Z&|]*)[^\]]\]\ s*interface', re.MULTILINE) |
| 53 | 52 |
| 54 copyrightTemplate = """/* | 53 COPYRIGHT_TEMPLATE = """/* |
| 55 * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. | 54 * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT. |
| 56 * | 55 * |
| 57 * This file was generated by the action_derivedsourcesallinone.py script. | 56 * This file was generated by the action_derivedsourcesallinone.py script. |
| 58 * | 57 * |
| 59 * Copyright (C) 2009 Google Inc. All rights reserved. | 58 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 60 * | 59 * |
| 61 * Redistribution and use in source and binary forms, with or without | 60 * Redistribution and use in source and binary forms, with or without |
| 62 * modification, are permitted provided that the following conditions | 61 * modification, are permitted provided that the following conditions |
| 63 * are met: | 62 * are met: |
| 64 * 1. Redistributions of source code must retain the above copyright | 63 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 75 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 74 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 76 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 75 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 77 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 76 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 78 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 77 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 79 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 78 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 80 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 79 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 81 */ | 80 */ |
| 82 """ | 81 """ |
| 83 | 82 |
| 84 | 83 |
| 85 # Wraps conditional with ENABLE() and replace '&','|' with '&&','||' if more tha n one conditional is specified. | 84 def format_conditional(conditional): |
| 86 def formatConditional(conditional): | 85 """Wraps conditional with ENABLE() and replace '&','|' with '&&','||' if |
| 87 def wrapWithEnable(s): | 86 more than one conditional is specified.""" |
| 88 if re.match('[|&]$', s): | 87 def wrap_with_enable(s): |
| 88 if s in ['|', '&']: | |
| 89 return s * 2 | 89 return s * 2 |
| 90 return 'ENABLE(' + s + ')' | 90 return 'ENABLE(' + s + ')' |
| 91 return ' '.join(map(wrapWithEnable, conditional)) | 91 return ' '.join(map(wrap_with_enable, conditional)) |
| 92 | 92 |
| 93 | 93 |
| 94 # Find the conditional interface attribute. | 94 def extract_conditional(idl_file_path): |
| 95 def extractConditional(idlFilePath): | 95 """Find the conditional interface attribute.""" |
| 96 conditional = None | |
| 97 | 96 |
| 98 # Read file and look for "interface [ Conditional=XXX ]". | 97 # Read file and look for [Conditional=XXX] interface. |
| 99 idlFile = open(idlFilePath) | 98 with open(idl_file_path) as idl_file: |
| 100 idlContents = idlFile.read().replace('\n', '') | 99 idl_contents = idl_file.read() |
| 101 idlFile.close() | |
| 102 | 100 |
| 103 match = conditionalPattern.search(idlContents) | 101 match = CONDITIONAL_PATTERN.search(idl_contents) |
| 104 if match: | 102 if not match: |
| 105 conditional = match.group(1) | 103 return None |
| 106 conditional = re.split('([|&])', conditional) | 104 conditional = match.group(1) |
| 105 return re.split('([|&])', conditional) | |
| 107 | 106 |
| 108 return conditional | |
| 109 | 107 |
| 110 # Extracts conditional and interface name from each IDL file. | 108 def extract_meta_data(file_paths): |
| 111 def extractMetaData(filePaths): | 109 """Extracts conditional and interface name from each IDL file.""" |
| 112 metaDataList = [] | 110 meta_data_list = [] |
| 113 | 111 |
| 114 for f in filePaths: | 112 for file_path in file_paths: |
| 115 metaData = {} | 113 if not file_path.endswith('.idl'): |
| 116 if len(f) == 0: | 114 print 'WARNING: non-IDL file passed: "%s"' % file_path |
| 117 continue | 115 continue |
| 118 if not os.path.exists(f): | 116 if not os.path.exists(file_path): |
| 119 print 'WARNING: file not found: "%s"' % f | 117 print 'WARNING: file not found: "%s"' % file_path |
| 120 continue | 118 continue |
| 121 | 119 |
| 122 # Extract type name from file name | 120 # Extract interface name from file name |
| 123 (parentPath, fileName) = os.path.split(f) | 121 parent_path, file_name = os.path.split(file_path) |
| 124 (interfaceName, ext) = os.path.splitext(fileName) | 122 interface_name, _ = os.path.splitext(file_name) |
| 125 | 123 |
| 126 if not ext == '.idl': | 124 meta_data = { |
| 127 continue | 125 'conditional': extract_conditional(file_path), |
| 126 'name': interface_name, | |
| 127 } | |
| 128 meta_data_list.append(meta_data) | |
| 128 | 129 |
| 129 metaData = { | 130 return meta_data_list |
| 130 'conditional': extractConditional(f), | |
| 131 'name': interfaceName, | |
| 132 } | |
| 133 | |
| 134 metaDataList.append(metaData) | |
| 135 | |
| 136 return metaDataList | |
| 137 | 131 |
| 138 | 132 |
| 139 def generateContent(filesMetaData, partition, totalPartitions): | 133 def generate_content(files_meta_data_this_partition): |
| 140 # Sort files by conditionals. | |
| 141 filesMetaData.sort() | |
| 142 | |
| 143 output = [] | |
| 144 | |
| 145 # Add fixed content. | 134 # Add fixed content. |
| 146 output.append(copyrightTemplate) | 135 output = [COPYRIGHT_TEMPLATE, |
| 147 output.append('#define NO_IMPLICIT_ATOMICSTRING\n\n') | 136 '#define NO_IMPLICIT_ATOMICSTRING\n\n'] |
| 148 | 137 |
| 149 # List all includes segmented by if and endif. | 138 # List all includes segmented by if and endif. |
| 150 prevConditional = None | 139 prev_conditional = None |
| 151 for metaData in filesMetaData: | 140 files_meta_data_this_partition.sort(key=lambda e: e['conditional']) |
| 152 name = metaData['name'] | 141 for meta_data in files_meta_data_this_partition: |
| 153 if (hash(name) % totalPartitions) != partition: | 142 conditional = meta_data['conditional'] |
| 154 continue | 143 if prev_conditional != conditional: |
| 155 conditional = metaData['conditional'] | 144 if prev_conditional: |
| 145 output.append('#endif\n') | |
| 146 if conditional: | |
| 147 output.append('\n#if %s\n' % format_conditional(conditional)) | |
| 148 prev_conditional = conditional | |
| 156 | 149 |
| 157 if prevConditional and prevConditional != conditional: | 150 output.append('#include "bindings/V8%s.cpp"\n' % meta_data['name']) |
| 158 output.append('#endif\n') | |
| 159 if conditional and prevConditional != conditional: | |
| 160 output.append('\n#if %s\n' % formatConditional(conditional)) | |
| 161 | 151 |
| 162 output.append('#include "bindings/V8%s.cpp"\n' % name) | 152 if prev_conditional: |
| 163 | |
| 164 prevConditional = conditional | |
| 165 | |
| 166 if prevConditional: | |
| 167 output.append('#endif\n') | 153 output.append('#endif\n') |
| 168 | 154 |
| 169 return ''.join(output) | 155 return ''.join(output) |
| 170 | 156 |
| 171 | 157 |
| 172 def writeContent(content, outputFileName): | 158 def write_content(content, output_file_name): |
| 173 (parentPath, fileName) = os.path.split(outputFileName) | 159 parent_path, file_name = os.path.split(output_file_name) |
| 174 if not os.path.exists(parentPath): | 160 if not os.path.exists(parent_path): |
| 175 print parentPath | 161 print parent_path |
| 176 os.mkdir(parentPath) | 162 os.mkdir(parent_path) |
|
eseidel
2013/10/10 14:44:47
This probably won't do what the author intends. Mk
Nils Barth (inactive)
2013/10/11 01:58:37
Good point (rather, os.makedirs).
This making dire
| |
| 177 f = open(outputFileName, 'w') | 163 with open(output_file_name, 'w') as f: |
| 178 f.write(content) | 164 f.write(content) |
| 179 f.close() | |
| 180 | 165 |
| 181 | 166 |
| 182 def resolveCygpath(cygdriveNames): | 167 def resolve_cygpath(cygdrive_names): |
| 183 cmd = ['cygpath', '-f', '-', '-wa'] | 168 cmd = ['cygpath', '-f', '-', '-wa'] |
| 184 process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIP E, stderr=subprocess.STDOUT) | 169 process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIP E, stderr=subprocess.STDOUT) |
| 185 idlFileNames = [] | 170 idl_file_names = [] |
| 186 for fileName in cygdriveNames: | 171 for file_name in cygdrive_names: |
| 187 process.stdin.write("%s\n" % fileName) | 172 process.stdin.write('%s\n' % file_name) |
| 188 process.stdin.flush() | 173 process.stdin.flush() |
| 189 idlFileNames.append(process.stdout.readline().rstrip()) | 174 idl_file_names.append(process.stdout.readline().rstrip()) |
| 190 process.stdin.close() | 175 process.stdin.close() |
| 191 process.wait() | 176 process.wait() |
| 192 return idlFileNames | 177 return idl_file_names |
| 193 | 178 |
| 194 | 179 |
| 195 def main(args): | 180 def main(args): |
| 196 assert(len(args) > 3) | 181 if len(args) <= 3: |
| 197 inOutBreakIndex = args.index('--') | 182 raise 'Expected at least 4 arguments.' |
| 198 inputFileName = args[1] | 183 in_out_break_index = args.index('--') |
| 199 outputFileNames = args[inOutBreakIndex+1:] | 184 input_file_name = args[1] |
| 185 output_file_names = args[in_out_break_index + 1:] | |
| 200 | 186 |
| 201 inputFile = open(inputFileName, 'r') | 187 with open(input_file_name) as input_file: |
| 202 idlFileNames = [] | 188 idl_file_names = [] |
| 203 cygdriveNames = [] | 189 cygdrive_names = [] |
| 204 for line in inputFile: | 190 for line in input_file: |
| 205 idlFileName = line.rstrip().split(' ')[0] | 191 idl_file_name = line.rstrip().split(' ')[0] |
| 206 if idlFileName.startswith("/cygdrive"): | 192 if idl_file_name.startswith('/cygdrive'): |
| 207 cygdriveNames.append(idlFileName) | 193 cygdrive_names.append(idl_file_name) |
| 208 else: | 194 else: |
| 209 idlFileNames.append(idlFileName) | 195 idl_file_names.append(idl_file_name) |
| 210 | 196 |
| 211 if cygdriveNames: | 197 if cygdrive_names: |
| 212 idlFileNames.extend(resolveCygpath(cygdriveNames)) | 198 idl_file_names.extend(resolve_cygpath(cygdrive_names)) |
| 213 inputFile.close() | |
| 214 | 199 |
| 215 filesMetaData = extractMetaData(idlFileNames) | 200 files_meta_data = extract_meta_data(idl_file_names) |
| 216 for fileName in outputFileNames: | 201 total_partitions = len(output_file_names) |
| 217 partition = outputFileNames.index(fileName) | 202 for partition, file_name in enumerate(output_file_names): |
| 218 fileContents = generateContent(filesMetaData, partition, len(outputFileN ames)) | 203 files_meta_data_this_partition = [ |
| 219 writeContent(fileContents, fileName) | 204 meta_data |
| 205 for meta_data in files_meta_data | |
| 206 if hash(meta_data['name']) % total_partitions == partition] | |
| 207 file_contents = generate_content(files_meta_data_this_partition) | |
| 208 write_content(file_contents, file_name) | |
| 220 | 209 |
| 221 return 0 | 210 return 0 |
| 222 | 211 |
| 223 | 212 |
| 224 if __name__ == '__main__': | 213 if __name__ == '__main__': |
| 225 sys.exit(main(sys.argv)) | 214 sys.exit(main(sys.argv)) |
| OLD | NEW |