| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # | 2 # |
| 3 # Copyright (C) 2013 Google Inc. All rights reserved. | 3 # Copyright (C) 2013 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 10 matching lines...) Expand all Loading... |
| 21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 | 30 |
| 31 """Compute global interface information, including public information, dependenc
ies, and inheritance. |
| 32 |
| 33 Computed data is stored in a global variable, |interfaces_info|, and written as |
| 34 output (concretely, exported as a pickle). This is then used by the IDL compiler |
| 35 itself, so it does not need to compute global information itself, and so that |
| 36 inter-IDL dependencies are clear, since they are all computed here. |
| 37 |
| 38 The |interfaces_info| pickle is a *global* dependency: any changes cause a full |
| 39 rebuild. This is to avoid having to compute which public data is visible by |
| 40 which IDL files on a file-by-file basis, which is very complex for little |
| 41 benefit. |
| 42 |interfaces_info| should thus only contain data about an interface that |
| 43 contains paths or is needed by *other* interfaces, e.g., path data (to abstract |
| 44 the compiler from OS-specific file paths) or public data (to avoid having to |
| 45 read other interfaces unnecessarily). |
| 46 It should *not* contain full information about an interface (e.g., all |
| 47 extended attributes), as this would cause unnecessary rebuilds. |
| 48 |
| 49 |interfaces_info| is a dict, keyed by |interface_name|. |
| 50 |
| 51 Current keys are: |
| 52 * dependencies: |
| 53 'implements_interfaces': targets of 'implements' statements |
| 54 'referenced_interfaces': reference interfaces that are introspected |
| 55 (currently just targets of [PutForwards]) |
| 56 |
| 57 * inheritance: |
| 58 'ancestors': all ancestor interfaces |
| 59 'inherited_extended_attributes': inherited extended attributes |
| 60 (all controlling memory management) |
| 61 |
| 62 * public: |
| 63 'is_callback_interface': bool, callback interface or not |
| 64 'implemented_as': value of [ImplementedAs=...] on interface (C++ class name) |
| 65 |
| 66 * paths: |
| 67 'full_path': path to the IDL file, so can lookup an IDL by interface name |
| 68 'include_path': path for use in C++ #include directives |
| 69 'dependencies_full_paths': paths to dependencies (for merging into main) |
| 70 'dependencies_include_paths': paths for use in C++ #include directives |
| 71 |
| 72 Note that all of these are stable information, unlikely to change without |
| 73 moving or deleting files (hence requiring a full rebuild anyway) or significant |
| 74 code changes (for inherited extended attributes). |
| 75 |
| 76 FIXME: also generates EventNames.in; factor out. http://crbug.com/341748 |
| 77 FIXME: also generates InterfaceDependencies.txt for Perl. http://crbug.com/2397
71 |
| 78 |
| 79 Design doc: http://www.chromium.org/developers/design-documents/idl-build |
| 80 """ |
| 81 |
| 31 import optparse | 82 import optparse |
| 32 import os | 83 import os |
| 33 import posixpath | 84 import posixpath |
| 85 import sys |
| 34 | 86 |
| 35 from utilities import get_file_contents, write_file, write_pickle_file, get_inte
rface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_
interface_name_from_idl, get_implemented_interfaces_from_idl, get_parent_interfa
ce, get_put_forward_interfaces_from_idl | 87 from utilities import get_file_contents, write_file, write_pickle_file, get_inte
rface_extended_attributes_from_idl, is_callback_interface_from_idl, get_partial_
interface_name_from_idl, get_implemented_interfaces_from_idl, get_parent_interfa
ce, get_put_forward_interfaces_from_idl |
| 36 | 88 |
| 37 module_path = os.path.dirname(__file__) | 89 module_path = os.path.dirname(__file__) |
| 38 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir)) | 90 source_path = os.path.normpath(os.path.join(module_path, os.pardir, os.pardir)) |
| 39 | 91 |
| 40 INHERITED_EXTENDED_ATTRIBUTES = set([ | 92 INHERITED_EXTENDED_ATTRIBUTES = set([ |
| 41 'ActiveDOMObject', | 93 'ActiveDOMObject', |
| 42 'DependentLifetime', | 94 'DependentLifetime', |
| 43 'WillBeGarbageCollected', | 95 'WillBeGarbageCollected', |
| 44 ]) | 96 ]) |
| 45 | 97 |
| 46 | 98 # Main variable (filled in and exported) |
| 47 # interfaces_info is *exported* (in a pickle), and should only contain data | |
| 48 # about an interface that contains paths or is needed by *other* interfaces, | |
| 49 # i.e., file layout data (to abstract the compiler from file paths) or | |
| 50 # public data (to avoid having to read other interfaces unnecessarily). | |
| 51 # It should *not* contain full information about an interface (e.g., all | |
| 52 # extended attributes), as this would cause unnecessary rebuilds. | |
| 53 interfaces_info = {} | 99 interfaces_info = {} |
| 54 | 100 |
| 55 # Auxiliary variables (not visible to future build steps) | 101 # Auxiliary variables (not visible to future build steps) |
| 56 partial_interface_files = {} | 102 partial_interface_files = {} |
| 57 parent_interfaces = {} | 103 parent_interfaces = {} |
| 58 extended_attributes_by_interface = {} # interface name -> extended attributes | 104 extended_attributes_by_interface = {} # interface name -> extended attributes |
| 59 | 105 |
| 60 | 106 |
| 61 class IdlInterfaceFileNotFoundError(Exception): | 107 class IdlInterfaceFileNotFoundError(Exception): |
| 62 """Raised if the IDL file implementing an interface cannot be found.""" | 108 """Raised if the IDL file implementing an interface cannot be found.""" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 ... | 147 ... |
| 102 | 148 |
| 103 The above indicates that: | 149 The above indicates that: |
| 104 Document.idl depends on P.idl, | 150 Document.idl depends on P.idl, |
| 105 Event.idl depends on no other IDL files, and | 151 Event.idl depends on no other IDL files, and |
| 106 Window.idl depends on Q.idl, R.idl, and S.idl. | 152 Window.idl depends on Q.idl, R.idl, and S.idl. |
| 107 | 153 |
| 108 An IDL that is a dependency of another IDL (e.g. P.idl) does not have its | 154 An IDL that is a dependency of another IDL (e.g. P.idl) does not have its |
| 109 own line in the dependency file. | 155 own line in the dependency file. |
| 110 """ | 156 """ |
| 111 # FIXME: remove text format once Perl gone (Python uses pickle) | 157 # FIXME: remove this file once Perl is gone http://crbug.com/239771 |
| 112 dependencies_list = sorted( | 158 dependencies_list = sorted( |
| 113 (interface_info['full_path'], sorted(interface_info['dependencies_full_p
aths'])) | 159 (interface_info['full_path'], sorted(interface_info['dependencies_full_p
aths'])) |
| 114 for interface_info in interfaces_info.values()) | 160 for interface_info in interfaces_info.values()) |
| 115 lines = ['%s %s\n' % (idl_file, ' '.join(dependency_files)) | 161 lines = ['%s %s\n' % (idl_file, ' '.join(dependency_files)) |
| 116 for idl_file, dependency_files in dependencies_list] | 162 for idl_file, dependency_files in dependencies_list] |
| 117 write_file(lines, dependencies_filename, only_if_changed) | 163 write_file(lines, dependencies_filename, only_if_changed) |
| 118 | 164 |
| 119 | 165 |
| 120 def write_event_names_file(destination_filename, only_if_changed): | 166 def write_event_names_file(destination_filename, only_if_changed): |
| 121 # Generate event names for all interfaces that inherit from Event, | 167 # Generate event names for all interfaces that inherit from Event, |
| 122 # including Event itself. | 168 # including Event itself. |
| 169 # FIXME: factor out. http://crbug.com/341748 |
| 123 event_names = set( | 170 event_names = set( |
| 124 interface_name | 171 interface_name |
| 125 for interface_name, interface_info in interfaces_info.iteritems() | 172 for interface_name, interface_info in interfaces_info.iteritems() |
| 126 if (interface_name == 'Event' or | 173 if (interface_name == 'Event' or |
| 127 ('ancestors' in interface_info and | 174 ('ancestors' in interface_info and |
| 128 interface_info['ancestors'][-1] == 'Event'))) | 175 interface_info['ancestors'][-1] == 'Event'))) |
| 129 | 176 |
| 130 def extended_attribute_string(name): | 177 def extended_attribute_string(name): |
| 131 value = extended_attributes[name] | 178 value = extended_attributes[name] |
| 132 if name == 'RuntimeEnabled': | 179 if name == 'RuntimeEnabled': |
| (...skipping 13 matching lines...) Expand all Loading... |
| 146 refined_filename = refined_filename.replace(os.sep, posixpath.sep) | 193 refined_filename = refined_filename.replace(os.sep, posixpath.sep) |
| 147 extended_attributes_list = [ | 194 extended_attributes_list = [ |
| 148 extended_attribute_string(name) | 195 extended_attribute_string(name) |
| 149 for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled' | 196 for name in 'Conditional', 'ImplementedAs', 'RuntimeEnabled' |
| 150 if name in extended_attributes] | 197 if name in extended_attributes] |
| 151 lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attribute
s_list))) | 198 lines.append('%s %s\n' % (refined_filename, ', '.join(extended_attribute
s_list))) |
| 152 write_file(lines, destination_filename, only_if_changed) | 199 write_file(lines, destination_filename, only_if_changed) |
| 153 | 200 |
| 154 | 201 |
| 155 ################################################################################ | 202 ################################################################################ |
| 156 # Dependency resolution | 203 # Computations |
| 157 ################################################################################ | 204 ################################################################################ |
| 158 | 205 |
| 159 def include_path(idl_filename, implemented_as=None): | 206 def include_path(idl_filename, implemented_as=None): |
| 160 """Returns relative path to header file in POSIX format; used in includes. | 207 """Returns relative path to header file in POSIX format; used in includes. |
| 161 | 208 |
| 162 POSIX format is used for consistency of output, so reference tests are | 209 POSIX format is used for consistency of output, so reference tests are |
| 163 platform-independent. | 210 platform-independent. |
| 164 """ | 211 """ |
| 165 relative_path_local = os.path.relpath(idl_filename, source_path) | 212 relative_path_local = os.path.relpath(idl_filename, source_path) |
| 166 relative_dir_local = os.path.dirname(relative_path_local) | 213 relative_dir_local = os.path.dirname(relative_path_local) |
| 167 relative_dir_posix = relative_dir_local.replace(os.path.sep, posixpath.sep) | 214 relative_dir_posix = relative_dir_local.replace(os.path.sep, posixpath.sep) |
| 168 | 215 |
| 169 idl_file_basename, _ = os.path.splitext(os.path.basename(idl_filename)) | 216 idl_file_basename, _ = os.path.splitext(os.path.basename(idl_filename)) |
| 170 cpp_class_name = implemented_as or idl_file_basename | 217 cpp_class_name = implemented_as or idl_file_basename |
| 171 | 218 |
| 172 return posixpath.join(relative_dir_posix, cpp_class_name + '.h') | 219 return posixpath.join(relative_dir_posix, cpp_class_name + '.h') |
| 173 | 220 |
| 174 | 221 |
| 175 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p
ath=None): | 222 def add_paths_to_partials_dict(partial_interface_name, full_path, this_include_p
ath=None): |
| 176 paths_dict = partial_interface_files.setdefault(partial_interface_name, | 223 paths_dict = partial_interface_files.setdefault(partial_interface_name, |
| 177 {'full_paths': [], | 224 {'full_paths': [], |
| 178 'include_paths': []}) | 225 'include_paths': []}) |
| 179 paths_dict['full_paths'].append(full_path) | 226 paths_dict['full_paths'].append(full_path) |
| 180 if this_include_path: | 227 if this_include_path: |
| 181 paths_dict['include_paths'].append(this_include_path) | 228 paths_dict['include_paths'].append(this_include_path) |
| 182 | 229 |
| 183 | 230 |
| 184 def generate_dependencies(idl_filename): | 231 def compute_individual_info(idl_filename): |
| 185 """Compute dependencies for IDL file, returning True if main (non-partial) i
nterface""" | |
| 186 full_path = os.path.realpath(idl_filename) | 232 full_path = os.path.realpath(idl_filename) |
| 187 idl_file_contents = get_file_contents(full_path) | 233 idl_file_contents = get_file_contents(full_path) |
| 188 | 234 |
| 189 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co
ntents) | 235 extended_attributes = get_interface_extended_attributes_from_idl(idl_file_co
ntents) |
| 190 implemented_as = extended_attributes.get('ImplementedAs') | 236 implemented_as = extended_attributes.get('ImplementedAs') |
| 191 # FIXME: remove [NoHeader] once switch to Python | 237 # FIXME: remove [NoHeader] once switch to Python |
| 192 this_include_path = (include_path(idl_filename, implemented_as) | 238 this_include_path = (include_path(idl_filename, implemented_as) |
| 193 if 'NoHeader' not in extended_attributes else None) | 239 if 'NoHeader' not in extended_attributes else None) |
| 194 | 240 |
| 195 # Handle partial interfaces | 241 # Handle partial interfaces |
| (...skipping 15 matching lines...) Expand all Loading... |
| 211 # deep dependencies. | 257 # deep dependencies. |
| 212 # These cause rebuilds of referrers, due to the dependency, so these | 258 # These cause rebuilds of referrers, due to the dependency, so these |
| 213 # should be minimized; currently only targets of [PutForwards]. | 259 # should be minimized; currently only targets of [PutForwards]. |
| 214 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co
ntents), | 260 'referenced_interfaces': get_put_forward_interfaces_from_idl(idl_file_co
ntents), |
| 215 } | 261 } |
| 216 if this_include_path: | 262 if this_include_path: |
| 217 interfaces_info[interface_name]['include_path'] = this_include_path | 263 interfaces_info[interface_name]['include_path'] = this_include_path |
| 218 if implemented_as: | 264 if implemented_as: |
| 219 interfaces_info[interface_name]['implemented_as'] = implemented_as | 265 interfaces_info[interface_name]['implemented_as'] = implemented_as |
| 220 | 266 |
| 221 # Record extended attributes | 267 # Record auxiliary information |
| 222 extended_attributes_by_interface[interface_name] = extended_attributes | 268 extended_attributes_by_interface[interface_name] = extended_attributes |
| 223 | |
| 224 # Record parents | |
| 225 parent = get_parent_interface(idl_file_contents) | 269 parent = get_parent_interface(idl_file_contents) |
| 226 if parent: | 270 if parent: |
| 227 parent_interfaces[interface_name] = parent | 271 parent_interfaces[interface_name] = parent |
| 228 | 272 |
| 229 | 273 |
| 230 def generate_ancestors_and_inherited_extended_attributes(interface_name): | 274 def compute_inheritance_info(interface_name): |
| 275 """Computes inheritance information, namely ancestors and inherited extended
attributes.""" |
| 231 interface_info = interfaces_info[interface_name] | 276 interface_info = interfaces_info[interface_name] |
| 232 interface_extended_attributes = extended_attributes_by_interface[interface_n
ame] | 277 interface_extended_attributes = extended_attributes_by_interface[interface_n
ame] |
| 233 inherited_extended_attributes = dict( | 278 inherited_extended_attributes = dict( |
| 234 (key, value) | 279 (key, value) |
| 235 for key, value in interface_extended_attributes.iteritems() | 280 for key, value in interface_extended_attributes.iteritems() |
| 236 if key in INHERITED_EXTENDED_ATTRIBUTES) | 281 if key in INHERITED_EXTENDED_ATTRIBUTES) |
| 237 | 282 |
| 238 def generate_ancestors(interface_name): | 283 def generate_ancestors(interface_name): |
| 239 while interface_name in parent_interfaces: | 284 while interface_name in parent_interfaces: |
| 240 interface_name = parent_interfaces[interface_name] | 285 interface_name = parent_interfaces[interface_name] |
| 241 yield interface_name | 286 yield interface_name |
| 242 | 287 |
| 243 ancestors = list(generate_ancestors(interface_name)) | 288 ancestors = list(generate_ancestors(interface_name)) |
| 244 if not ancestors: | 289 if not ancestors: |
| 245 if inherited_extended_attributes: | 290 if inherited_extended_attributes: |
| 246 interface_info['inherited_extended_attributes'] = inherited_extended
_attributes | 291 interface_info['inherited_extended_attributes'] = inherited_extended
_attributes |
| 247 return | 292 return |
| 248 | 293 |
| 249 interface_info['ancestors'] = ancestors | 294 interface_info['ancestors'] = ancestors |
| 250 for ancestor in ancestors: | 295 for ancestor in ancestors: |
| 251 # Extended attributes are missing if an ancestor is an interface that | 296 # Extended attributes are missing if an ancestor is an interface that |
| 252 # we're not processing, notably real IDL files if only processing test | 297 # we're not processing, namely real IDL files if only processing test |
| 253 # IDL files, or generated support files. | 298 # IDL files. |
| 254 ancestor_extended_attributes = extended_attributes_by_interface.get(ance
stor, {}) | 299 ancestor_extended_attributes = extended_attributes_by_interface.get(ance
stor, {}) |
| 255 inherited_extended_attributes.update(dict( | 300 inherited_extended_attributes.update(dict( |
| 256 (key, value) | 301 (key, value) |
| 257 for key, value in ancestor_extended_attributes.iteritems() | 302 for key, value in ancestor_extended_attributes.iteritems() |
| 258 if key in INHERITED_EXTENDED_ATTRIBUTES)) | 303 if key in INHERITED_EXTENDED_ATTRIBUTES)) |
| 259 if inherited_extended_attributes: | 304 if inherited_extended_attributes: |
| 260 interface_info['inherited_extended_attributes'] = inherited_extended_att
ributes | 305 interface_info['inherited_extended_attributes'] = inherited_extended_att
ributes |
| 261 | 306 |
| 262 | 307 |
| 263 def parse_idl_files(idl_files): | 308 def compute_interfaces_info(idl_files): |
| 264 """Compute information about IDL files. | 309 """Compute information about IDL files. |
| 265 | 310 |
| 266 Primary effect is computing info about main interfaces, stored in global | 311 Information is stored in global interfaces_info. |
| 267 interfaces_info. | |
| 268 """ | 312 """ |
| 269 # Generate dependencies. | 313 # Compute information for individual files |
| 270 for idl_filename in idl_files: | 314 for idl_filename in idl_files: |
| 271 generate_dependencies(idl_filename) | 315 compute_individual_info(idl_filename) |
| 272 | 316 |
| 317 # Once all individual files handled, can compute inheritance information |
| 273 for interface_name in interfaces_info: | 318 for interface_name in interfaces_info: |
| 274 generate_ancestors_and_inherited_extended_attributes(interface_name) | 319 compute_inheritance_info(interface_name) |
| 275 | 320 |
| 276 # An IDL file's dependencies are partial interface files that extend it, | 321 # An IDL file's dependencies are partial interface files that extend it, |
| 277 # and files for other interfaces that this interfaces implements. | 322 # and files for other interfaces that this interfaces implements. |
| 278 for interface_name, interface_info in interfaces_info.iteritems(): | 323 for interface_name, interface_info in interfaces_info.iteritems(): |
| 279 partial_interfaces_full_paths, partial_interfaces_include_paths = ( | 324 partial_interfaces_full_paths, partial_interfaces_include_paths = ( |
| 280 (partial_interface_files[interface_name]['full_paths'], | 325 (partial_interface_files[interface_name]['full_paths'], |
| 281 partial_interface_files[interface_name]['include_paths']) | 326 partial_interface_files[interface_name]['include_paths']) |
| 282 if interface_name in partial_interface_files else ([], [])) | 327 if interface_name in partial_interface_files else ([], [])) |
| 283 | 328 |
| 284 implemented_interfaces = interface_info['implements_interfaces'] | 329 implemented_interfaces = interface_info['implements_interfaces'] |
| (...skipping 24 matching lines...) Expand all Loading... |
| 309 # Static IDL files are passed in a file (generated at GYP time), due to OS | 354 # Static IDL files are passed in a file (generated at GYP time), due to OS |
| 310 # command line length limits | 355 # command line length limits |
| 311 with open(options.idl_files_list) as idl_files_list: | 356 with open(options.idl_files_list) as idl_files_list: |
| 312 idl_files = [line.rstrip('\n') for line in idl_files_list] | 357 idl_files = [line.rstrip('\n') for line in idl_files_list] |
| 313 # Generated IDL files are passed at the command line, since these are in the | 358 # Generated IDL files are passed at the command line, since these are in the |
| 314 # build directory, which is determined at build time, not GYP time, so these | 359 # build directory, which is determined at build time, not GYP time, so these |
| 315 # cannot be included in the file listing static files | 360 # cannot be included in the file listing static files |
| 316 idl_files.extend(args) | 361 idl_files.extend(args) |
| 317 | 362 |
| 318 only_if_changed = options.write_file_only_if_changed | 363 only_if_changed = options.write_file_only_if_changed |
| 319 | 364 compute_interfaces_info(idl_files) |
| 320 parse_idl_files(idl_files) | |
| 321 write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_cha
nged) | 365 write_pickle_file(options.interfaces_info_file, interfaces_info, only_if_cha
nged) |
| 322 write_dependencies_file(options.interface_dependencies_file, only_if_changed
) | 366 write_dependencies_file(options.interface_dependencies_file, only_if_changed
) |
| 323 write_event_names_file(options.event_names_file, only_if_changed) | 367 write_event_names_file(options.event_names_file, only_if_changed) |
| 324 | 368 |
| 325 | 369 |
| 326 if __name__ == '__main__': | 370 if __name__ == '__main__': |
| 327 main() | 371 sys.exit(main()) |
| OLD | NEW |