1#!/usr/bin/python3 2# 3# Copyright 2013-2021 The Khronos Group Inc. 4# 5# SPDX-License-Identifier: Apache-2.0 6 7import argparse 8import pdb 9import re 10import sys 11import time 12import xml.etree.ElementTree as etree 13 14from cgenerator import CGeneratorOptions, COutputGenerator 15from docgenerator import DocGeneratorOptions, DocOutputGenerator 16from extensionmetadocgenerator import (ExtensionMetaDocGeneratorOptions, 17 ExtensionMetaDocOutputGenerator) 18from interfacedocgenerator import InterfaceDocGenerator 19from generator import write 20from spirvcapgenerator import SpirvCapabilityOutputGenerator 21from hostsyncgenerator import HostSynchronizationOutputGenerator 22from pygenerator import PyOutputGenerator 23from rubygenerator import RubyOutputGenerator 24from reflib import logDiag, logWarn, setLogFile 25from reg import Registry 26from validitygenerator import ValidityOutputGenerator 27from vkconventions import VulkanConventions 28 29 30# Simple timer functions 31startTime = None 32 33 34def startTimer(timeit): 35 global startTime 36 if timeit: 37 startTime = time.process_time() 38 39 40def endTimer(timeit, msg): 41 global startTime 42 if timeit: 43 endTime = time.process_time() 44 logDiag(msg, endTime - startTime) 45 startTime = None 46 47 48def makeREstring(strings, default=None, strings_are_regex=False): 49 """Turn a list of strings into a regexp string matching exactly those strings.""" 50 if strings or default is None: 51 if not strings_are_regex: 52 strings = (re.escape(s) for s in strings) 53 return '^(' + '|'.join(strings) + ')$' 54 return default 55 56 57def makeGenOpts(args): 58 """Returns a directory of [ generator function, generator options ] indexed 59 by specified short names. The generator options incorporate the following 60 parameters: 61 62 args is an parsed argument object; see below for the fields that are used.""" 63 global genOpts 64 genOpts = {} 65 66 # Default class of extensions to include, or None 67 defaultExtensions = args.defaultExtensions 68 69 # Additional extensions to include (list of extensions) 70 extensions = args.extension 71 72 # Extensions to remove (list of extensions) 73 removeExtensions = args.removeExtensions 74 75 # Extensions to emit (list of extensions) 76 emitExtensions = args.emitExtensions 77 78 # SPIR-V capabilities / features to emit (list of extensions & capabilities) 79 emitSpirv = args.emitSpirv 80 81 # Features to include (list of features) 82 features = args.feature 83 84 # Whether to disable inclusion protect in headers 85 protect = args.protect 86 87 # Output target directory 88 directory = args.directory 89 90 # Path to generated files, particularly api.py 91 genpath = args.genpath 92 93 # Generate MISRA C-friendly headers 94 misracstyle = args.misracstyle; 95 96 # Generate MISRA C++-friendly headers 97 misracppstyle = args.misracppstyle; 98 99 # Descriptive names for various regexp patterns used to select 100 # versions and extensions 101 allSpirv = allFeatures = allExtensions = r'.*' 102 103 # Turn lists of names/patterns into matching regular expressions 104 addExtensionsPat = makeREstring(extensions, None) 105 removeExtensionsPat = makeREstring(removeExtensions, None) 106 emitExtensionsPat = makeREstring(emitExtensions, allExtensions) 107 emitSpirvPat = makeREstring(emitSpirv, allSpirv) 108 featuresPat = makeREstring(features, allFeatures) 109 110 # Copyright text prefixing all headers (list of strings). 111 # The SPDX formatting below works around constraints of the 'reuse' tool 112 prefixStrings = [ 113 '/*', 114 '** Copyright 2015-2021 The Khronos Group Inc.', 115 '**', 116 '** SPDX' + '-License-Identifier: Apache-2.0', 117 '*/', 118 '' 119 ] 120 121 # Text specific to Vulkan headers 122 vkPrefixStrings = [ 123 '/*', 124 '** This header is generated from the Khronos Vulkan XML API Registry.', 125 '**', 126 '*/', 127 '' 128 ] 129 130 # Defaults for generating re-inclusion protection wrappers (or not) 131 protectFile = protect 132 133 # An API style conventions object 134 conventions = VulkanConventions() 135 136 # API include files for spec and ref pages 137 # Overwrites include subdirectories in spec source tree 138 # The generated include files do not include the calling convention 139 # macros (apientry etc.), unlike the header files. 140 # Because the 1.0 core branch includes ref pages for extensions, 141 # all the extension interfaces need to be generated, even though 142 # none are used by the core spec itself. 143 genOpts['apiinc'] = [ 144 DocOutputGenerator, 145 DocGeneratorOptions( 146 conventions = conventions, 147 filename = 'timeMarker', 148 directory = directory, 149 genpath = genpath, 150 apiname = 'vulkan', 151 profile = None, 152 versions = featuresPat, 153 emitversions = featuresPat, 154 defaultExtensions = None, 155 addExtensions = addExtensionsPat, 156 removeExtensions = removeExtensionsPat, 157 emitExtensions = emitExtensionsPat, 158 prefixText = prefixStrings + vkPrefixStrings, 159 apicall = '', 160 apientry = '', 161 apientryp = '*', 162 alignFuncParam = 48, 163 expandEnumerants = False) 164 ] 165 166 # Python representation of API information, used by scripts that 167 # don't need to load the full XML. 168 genOpts['api.py'] = [ 169 PyOutputGenerator, 170 DocGeneratorOptions( 171 conventions = conventions, 172 filename = 'api.py', 173 directory = directory, 174 genpath = None, 175 apiname = 'vulkan', 176 profile = None, 177 versions = featuresPat, 178 emitversions = featuresPat, 179 defaultExtensions = None, 180 addExtensions = addExtensionsPat, 181 removeExtensions = removeExtensionsPat, 182 emitExtensions = emitExtensionsPat, 183 reparentEnums = False) 184 ] 185 186 # Ruby representation of API information, used by scripts that 187 # don't need to load the full XML. 188 genOpts['api.rb'] = [ 189 RubyOutputGenerator, 190 DocGeneratorOptions( 191 conventions = conventions, 192 filename = 'api.rb', 193 directory = directory, 194 genpath = None, 195 apiname = 'vulkan', 196 profile = None, 197 versions = featuresPat, 198 emitversions = featuresPat, 199 defaultExtensions = None, 200 addExtensions = addExtensionsPat, 201 removeExtensions = removeExtensionsPat, 202 emitExtensions = emitExtensionsPat, 203 reparentEnums = False) 204 ] 205 206 207 # API validity files for spec 208 # 209 # requireCommandAliases is set to True because we need validity files 210 # for the command something is promoted to even when the promoted-to 211 # feature is not included. This avoids wordy includes of validity files. 212 genOpts['validinc'] = [ 213 ValidityOutputGenerator, 214 DocGeneratorOptions( 215 conventions = conventions, 216 filename = 'timeMarker', 217 directory = directory, 218 genpath = None, 219 apiname = 'vulkan', 220 profile = None, 221 versions = featuresPat, 222 emitversions = featuresPat, 223 defaultExtensions = None, 224 addExtensions = addExtensionsPat, 225 removeExtensions = removeExtensionsPat, 226 emitExtensions = emitExtensionsPat, 227 requireCommandAliases = True, 228 ) 229 ] 230 231 # API host sync table files for spec 232 genOpts['hostsyncinc'] = [ 233 HostSynchronizationOutputGenerator, 234 DocGeneratorOptions( 235 conventions = conventions, 236 filename = 'timeMarker', 237 directory = directory, 238 genpath = None, 239 apiname = 'vulkan', 240 profile = None, 241 versions = featuresPat, 242 emitversions = featuresPat, 243 defaultExtensions = None, 244 addExtensions = addExtensionsPat, 245 removeExtensions = removeExtensionsPat, 246 emitExtensions = emitExtensionsPat, 247 reparentEnums = False) 248 ] 249 250 # Extension metainformation for spec extension appendices 251 # Includes all extensions by default, but only so that the generated 252 # 'promoted_extensions_*' files refer to all extensions that were 253 # promoted to a core version. 254 genOpts['extinc'] = [ 255 ExtensionMetaDocOutputGenerator, 256 ExtensionMetaDocGeneratorOptions( 257 conventions = conventions, 258 filename = 'timeMarker', 259 directory = directory, 260 genpath = None, 261 apiname = 'vulkan', 262 profile = None, 263 versions = featuresPat, 264 emitversions = None, 265 defaultExtensions = defaultExtensions, 266 addExtensions = addExtensionsPat, 267 removeExtensions = None, 268 emitExtensions = emitExtensionsPat) 269 ] 270 271 # Version and extension interface docs for version/extension appendices 272 # Includes all extensions by default. 273 genOpts['interfaceinc'] = [ 274 InterfaceDocGenerator, 275 DocGeneratorOptions( 276 conventions = conventions, 277 filename = 'timeMarker', 278 directory = directory, 279 genpath = None, 280 apiname = 'vulkan', 281 profile = None, 282 versions = featuresPat, 283 emitversions = featuresPat, 284 defaultExtensions = None, 285 addExtensions = addExtensionsPat, 286 removeExtensions = removeExtensionsPat, 287 emitExtensions = emitExtensionsPat, 288 reparentEnums = False) 289 ] 290 291 genOpts['spirvcapinc'] = [ 292 SpirvCapabilityOutputGenerator, 293 DocGeneratorOptions( 294 conventions = conventions, 295 filename = 'timeMarker', 296 directory = directory, 297 genpath = None, 298 apiname = 'vulkan', 299 profile = None, 300 versions = featuresPat, 301 emitversions = featuresPat, 302 defaultExtensions = None, 303 addExtensions = addExtensionsPat, 304 removeExtensions = removeExtensionsPat, 305 emitExtensions = emitExtensionsPat, 306 emitSpirv = emitSpirvPat, 307 reparentEnums = False) 308 ] 309 310 # Platform extensions, in their own header files 311 # Each element of the platforms[] array defines information for 312 # generating a single platform: 313 # [0] is the generated header file name 314 # [1] is the set of platform extensions to generate 315 # [2] is additional extensions whose interfaces should be considered, 316 # but suppressed in the output, to avoid duplicate definitions of 317 # dependent types like VkDisplayKHR and VkSurfaceKHR which come from 318 # non-platform extensions. 319 320 # Track all platform extensions, for exclusion from vulkan_core.h 321 allPlatformExtensions = [] 322 323 # Extensions suppressed for all WSI platforms (WSI extensions required 324 # by all platforms) 325 commonSuppressExtensions = [ 'VK_KHR_display', 'VK_KHR_swapchain' ] 326 327 # Extensions required and suppressed for beta "platform". This can 328 # probably eventually be derived from the requires= attributes of 329 # the extension blocks. 330 betaRequireExtensions = [ 331 'VK_KHR_portability_subset', 332 'VK_KHR_video_queue', 333 'VK_KHR_video_decode_queue', 334 'VK_KHR_video_encode_queue', 335 'VK_EXT_video_decode_h264', 336 'VK_EXT_video_decode_h265', 337 'VK_EXT_video_encode_h264', 338 'VK_EXT_video_encode_h265', 339 ] 340 341 betaSuppressExtensions = [] 342 343 platforms = [ 344 [ 'vulkan_android.h', [ 'VK_KHR_android_surface', 345 'VK_ANDROID_external_memory_android_hardware_buffer' 346 ], commonSuppressExtensions + 347 [ 'VK_KHR_format_feature_flags2', 348 ] ], 349 [ 'vulkan_fuchsia.h', [ 'VK_FUCHSIA_imagepipe_surface', 350 'VK_FUCHSIA_external_memory', 351 'VK_FUCHSIA_external_semaphore', 352 'VK_FUCHSIA_buffer_collection' ], commonSuppressExtensions ], 353 [ 'vulkan_ggp.h', [ 'VK_GGP_stream_descriptor_surface', 354 'VK_GGP_frame_token' ], commonSuppressExtensions ], 355 [ 'vulkan_ios.h', [ 'VK_MVK_ios_surface' ], commonSuppressExtensions ], 356 [ 'vulkan_macos.h', [ 'VK_MVK_macos_surface' ], commonSuppressExtensions ], 357 [ 'vulkan_vi.h', [ 'VK_NN_vi_surface' ], commonSuppressExtensions ], 358 [ 'vulkan_wayland.h', [ 'VK_KHR_wayland_surface' ], commonSuppressExtensions ], 359 [ 'vulkan_win32.h', [ 'VK_.*_win32(|_.*)', 'VK_EXT_full_screen_exclusive' ], 360 commonSuppressExtensions + 361 [ 'VK_KHR_external_semaphore', 362 'VK_KHR_external_memory_capabilities', 363 'VK_KHR_external_fence', 364 'VK_KHR_external_fence_capabilities', 365 'VK_KHR_get_surface_capabilities2', 366 'VK_NV_external_memory_capabilities', 367 ] ], 368 [ 'vulkan_xcb.h', [ 'VK_KHR_xcb_surface' ], commonSuppressExtensions ], 369 [ 'vulkan_xlib.h', [ 'VK_KHR_xlib_surface' ], commonSuppressExtensions ], 370 [ 'vulkan_directfb.h', [ 'VK_EXT_directfb_surface' ], commonSuppressExtensions ], 371 [ 'vulkan_xlib_xrandr.h', [ 'VK_EXT_acquire_xlib_display' ], commonSuppressExtensions ], 372 [ 'vulkan_metal.h', [ 'VK_EXT_metal_surface' ], commonSuppressExtensions ], 373 [ 'vulkan_screen.h', [ 'VK_QNX_screen_surface' ], commonSuppressExtensions ], 374 [ 'vulkan_beta.h', betaRequireExtensions, betaSuppressExtensions ], 375 ] 376 377 for platform in platforms: 378 headername = platform[0] 379 380 allPlatformExtensions += platform[1] 381 382 addPlatformExtensionsRE = makeREstring( 383 platform[1] + platform[2], strings_are_regex=True) 384 emitPlatformExtensionsRE = makeREstring( 385 platform[1], strings_are_regex=True) 386 387 opts = CGeneratorOptions( 388 conventions = conventions, 389 filename = headername, 390 directory = directory, 391 genpath = None, 392 apiname = 'vulkan', 393 profile = None, 394 versions = featuresPat, 395 emitversions = None, 396 defaultExtensions = None, 397 addExtensions = addPlatformExtensionsRE, 398 removeExtensions = None, 399 emitExtensions = emitPlatformExtensionsRE, 400 prefixText = prefixStrings + vkPrefixStrings, 401 genFuncPointers = True, 402 protectFile = protectFile, 403 protectFeature = False, 404 protectProto = '#ifndef', 405 protectProtoStr = 'VK_NO_PROTOTYPES', 406 apicall = 'VKAPI_ATTR ', 407 apientry = 'VKAPI_CALL ', 408 apientryp = 'VKAPI_PTR *', 409 alignFuncParam = 48, 410 misracstyle = misracstyle, 411 misracppstyle = misracppstyle) 412 413 genOpts[headername] = [ COutputGenerator, opts ] 414 415 # Header for core API + extensions. 416 # To generate just the core API, 417 # change to 'defaultExtensions = None' below. 418 # 419 # By default this adds all enabled, non-platform extensions. 420 # It removes all platform extensions (from the platform headers options 421 # constructed above) as well as any explicitly specified removals. 422 423 removeExtensionsPat = makeREstring( 424 allPlatformExtensions + removeExtensions, None, strings_are_regex=True) 425 426 genOpts['vulkan_core.h'] = [ 427 COutputGenerator, 428 CGeneratorOptions( 429 conventions = conventions, 430 filename = 'vulkan_core.h', 431 directory = directory, 432 genpath = None, 433 apiname = 'vulkan', 434 profile = None, 435 versions = featuresPat, 436 emitversions = featuresPat, 437 defaultExtensions = defaultExtensions, 438 addExtensions = addExtensionsPat, 439 removeExtensions = removeExtensionsPat, 440 emitExtensions = emitExtensionsPat, 441 prefixText = prefixStrings + vkPrefixStrings, 442 genFuncPointers = True, 443 protectFile = protectFile, 444 protectFeature = False, 445 protectProto = '#ifndef', 446 protectProtoStr = 'VK_NO_PROTOTYPES', 447 apicall = 'VKAPI_ATTR ', 448 apientry = 'VKAPI_CALL ', 449 apientryp = 'VKAPI_PTR *', 450 alignFuncParam = 48, 451 misracstyle = misracstyle, 452 misracppstyle = misracppstyle) 453 ] 454 455 # Unused - vulkan10.h target. 456 # It is possible to generate a header with just the Vulkan 1.0 + 457 # extension interfaces defined, but since the promoted KHR extensions 458 # are now defined in terms of the 1.1 interfaces, such a header is very 459 # similar to vulkan_core.h. 460 genOpts['vulkan10.h'] = [ 461 COutputGenerator, 462 CGeneratorOptions( 463 conventions = conventions, 464 filename = 'vulkan10.h', 465 directory = directory, 466 genpath = None, 467 apiname = 'vulkan', 468 profile = None, 469 versions = 'VK_VERSION_1_0', 470 emitversions = 'VK_VERSION_1_0', 471 defaultExtensions = None, 472 addExtensions = None, 473 removeExtensions = None, 474 emitExtensions = None, 475 prefixText = prefixStrings + vkPrefixStrings, 476 genFuncPointers = True, 477 protectFile = protectFile, 478 protectFeature = False, 479 protectProto = '#ifndef', 480 protectProtoStr = 'VK_NO_PROTOTYPES', 481 apicall = 'VKAPI_ATTR ', 482 apientry = 'VKAPI_CALL ', 483 apientryp = 'VKAPI_PTR *', 484 alignFuncParam = 48, 485 misracstyle = misracstyle, 486 misracppstyle = misracppstyle) 487 ] 488 489 # Unused - vulkan11.h target. 490 # It is possible to generate a header with just the Vulkan 1.0 + 491 # extension interfaces defined, but since the promoted KHR extensions 492 # are now defined in terms of the 1.1 interfaces, such a header is very 493 # similar to vulkan_core.h. 494 genOpts['vulkan11.h'] = [ 495 COutputGenerator, 496 CGeneratorOptions( 497 conventions = conventions, 498 filename = 'vulkan11.h', 499 directory = directory, 500 genpath = None, 501 apiname = 'vulkan', 502 profile = None, 503 versions = '^VK_VERSION_1_[01]$', 504 emitversions = '^VK_VERSION_1_[01]$', 505 defaultExtensions = None, 506 addExtensions = None, 507 removeExtensions = None, 508 emitExtensions = None, 509 prefixText = prefixStrings + vkPrefixStrings, 510 genFuncPointers = True, 511 protectFile = protectFile, 512 protectFeature = False, 513 protectProto = '#ifndef', 514 protectProtoStr = 'VK_NO_PROTOTYPES', 515 apicall = 'VKAPI_ATTR ', 516 apientry = 'VKAPI_CALL ', 517 apientryp = 'VKAPI_PTR *', 518 alignFuncParam = 48, 519 misracstyle = misracstyle, 520 misracppstyle = misracppstyle) 521 ] 522 523 genOpts['alias.h'] = [ 524 COutputGenerator, 525 CGeneratorOptions( 526 conventions = conventions, 527 filename = 'alias.h', 528 directory = directory, 529 genpath = None, 530 apiname = 'vulkan', 531 profile = None, 532 versions = featuresPat, 533 emitversions = featuresPat, 534 defaultExtensions = defaultExtensions, 535 addExtensions = None, 536 removeExtensions = removeExtensionsPat, 537 emitExtensions = emitExtensionsPat, 538 prefixText = None, 539 genFuncPointers = False, 540 protectFile = False, 541 protectFeature = False, 542 protectProto = '', 543 protectProtoStr = '', 544 apicall = '', 545 apientry = '', 546 apientryp = '', 547 alignFuncParam = 36) 548 ] 549 550 551def genTarget(args): 552 """Create an API generator and corresponding generator options based on 553 the requested target and command line options. 554 555 This is encapsulated in a function so it can be profiled and/or timed. 556 The args parameter is an parsed argument object containing the following 557 fields that are used: 558 559 - target - target to generate 560 - directory - directory to generate it in 561 - protect - True if re-inclusion wrappers should be created 562 - extensions - list of additional extensions to include in generated interfaces""" 563 564 # Create generator options with parameters specified on command line 565 makeGenOpts(args) 566 567 # pdb.set_trace() 568 569 # Select a generator matching the requested target 570 if args.target in genOpts: 571 createGenerator = genOpts[args.target][0] 572 options = genOpts[args.target][1] 573 574 logDiag('* Building', options.filename) 575 logDiag('* options.versions =', options.versions) 576 logDiag('* options.emitversions =', options.emitversions) 577 logDiag('* options.defaultExtensions =', options.defaultExtensions) 578 logDiag('* options.addExtensions =', options.addExtensions) 579 logDiag('* options.removeExtensions =', options.removeExtensions) 580 logDiag('* options.emitExtensions =', options.emitExtensions) 581 582 gen = createGenerator(errFile=errWarn, 583 warnFile=errWarn, 584 diagFile=diag) 585 return (gen, options) 586 else: 587 logErr('No generator options for unknown target:', args.target) 588 return None 589 590 591# -feature name 592# -extension name 593# For both, "name" may be a single name, or a space-separated list 594# of names, or a regular expression. 595if __name__ == '__main__': 596 parser = argparse.ArgumentParser() 597 598 parser.add_argument('-defaultExtensions', action='store', 599 default='vulkan', 600 help='Specify a single class of extensions to add to targets') 601 parser.add_argument('-extension', action='append', 602 default=[], 603 help='Specify an extension or extensions to add to targets') 604 parser.add_argument('-removeExtensions', action='append', 605 default=[], 606 help='Specify an extension or extensions to remove from targets') 607 parser.add_argument('-emitExtensions', action='append', 608 default=[], 609 help='Specify an extension or extensions to emit in targets') 610 parser.add_argument('-emitSpirv', action='append', 611 default=[], 612 help='Specify a SPIR-V extension or capability to emit in targets') 613 parser.add_argument('-feature', action='append', 614 default=[], 615 help='Specify a core API feature name or names to add to targets') 616 parser.add_argument('-debug', action='store_true', 617 help='Enable debugging') 618 parser.add_argument('-dump', action='store_true', 619 help='Enable dump to stderr') 620 parser.add_argument('-diagfile', action='store', 621 default=None, 622 help='Write diagnostics to specified file') 623 parser.add_argument('-errfile', action='store', 624 default=None, 625 help='Write errors and warnings to specified file instead of stderr') 626 parser.add_argument('-noprotect', dest='protect', action='store_false', 627 help='Disable inclusion protection in output headers') 628 parser.add_argument('-profile', action='store_true', 629 help='Enable profiling') 630 parser.add_argument('-registry', action='store', 631 default='vk.xml', 632 help='Use specified registry file instead of vk.xml') 633 parser.add_argument('-time', action='store_true', 634 help='Enable timing') 635 parser.add_argument('-validate', action='store_true', 636 help='Validate the registry properties and exit') 637 parser.add_argument('-genpath', action='store', default='gen', 638 help='Path to generated files') 639 parser.add_argument('-o', action='store', dest='directory', 640 default='.', 641 help='Create target and related files in specified directory') 642 parser.add_argument('target', metavar='target', nargs='?', 643 help='Specify target') 644 parser.add_argument('-quiet', action='store_true', default=True, 645 help='Suppress script output during normal execution.') 646 parser.add_argument('-verbose', action='store_false', dest='quiet', default=True, 647 help='Enable script output during normal execution.') 648 parser.add_argument('-misracstyle', dest='misracstyle', action='store_true', 649 help='generate MISRA C-friendly headers') 650 parser.add_argument('-misracppstyle', dest='misracppstyle', action='store_true', 651 help='generate MISRA C++-friendly headers') 652 653 args = parser.parse_args() 654 655 # This splits arguments which are space-separated lists 656 args.feature = [name for arg in args.feature for name in arg.split()] 657 args.extension = [name for arg in args.extension for name in arg.split()] 658 659 # create error/warning & diagnostic files 660 if args.errfile: 661 errWarn = open(args.errfile, 'w', encoding='utf-8') 662 else: 663 errWarn = sys.stderr 664 665 if args.diagfile: 666 diag = open(args.diagfile, 'w', encoding='utf-8') 667 else: 668 diag = None 669 670 if args.time: 671 # Log diagnostics and warnings 672 setLogFile(setDiag = True, setWarn = True, filename = '-') 673 674 (gen, options) = (None, None) 675 if not args.validate: 676 # Create the API generator & generator options 677 (gen, options) = genTarget(args) 678 679 # Create the registry object with the specified generator and generator 680 # options. The options are set before XML loading as they may affect it. 681 reg = Registry(gen, options) 682 683 # Parse the specified registry XML into an ElementTree object 684 startTimer(args.time) 685 tree = etree.parse(args.registry) 686 endTimer(args.time, '* Time to make ElementTree =') 687 688 # Load the XML tree into the registry object 689 startTimer(args.time) 690 reg.loadElementTree(tree) 691 endTimer(args.time, '* Time to parse ElementTree =') 692 693 if args.validate: 694 success = reg.validateRegistry() 695 sys.exit(0 if success else 1) 696 697 if args.dump: 698 logDiag('* Dumping registry to regdump.txt') 699 reg.dumpReg(filehandle=open('regdump.txt', 'w', encoding='utf-8')) 700 701 # Finally, use the output generator to create the requested target 702 if args.debug: 703 pdb.run('reg.apiGen()') 704 else: 705 startTimer(args.time) 706 reg.apiGen() 707 endTimer(args.time, '* Time to generate ' + options.filename + ' =') 708 709 if not args.quiet: 710 logDiag('* Generated', options.filename) 711