1bf215546Sopenharmony_ci 2bf215546Sopenharmony_ci# (C) Copyright IBM Corporation 2005, 2006 3bf215546Sopenharmony_ci# All Rights Reserved. 4bf215546Sopenharmony_ci# 5bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci# on the rights to use, copy, modify, merge, publish, distribute, sub 9bf215546Sopenharmony_ci# license, and/or sell copies of the Software, and to permit persons to whom 10bf215546Sopenharmony_ci# the Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci# 12bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci# Software. 15bf215546Sopenharmony_ci# 16bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci# IN THE SOFTWARE. 23bf215546Sopenharmony_ci# 24bf215546Sopenharmony_ci# Authors: 25bf215546Sopenharmony_ci# Ian Romanick <idr@us.ibm.com> 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ciimport argparse 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ciimport gl_XML, glX_XML, glX_proto_common, license 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cidef log2(value): 33bf215546Sopenharmony_ci for i in range(0, 30): 34bf215546Sopenharmony_ci p = 1 << i 35bf215546Sopenharmony_ci if p >= value: 36bf215546Sopenharmony_ci return i 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci return -1 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_cidef round_down_to_power_of_two(n): 42bf215546Sopenharmony_ci """Returns the nearest power-of-two less than or equal to n.""" 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci for i in range(30, 0, -1): 45bf215546Sopenharmony_ci p = 1 << i 46bf215546Sopenharmony_ci if p <= n: 47bf215546Sopenharmony_ci return p 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci return -1 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ciclass function_table: 53bf215546Sopenharmony_ci def __init__(self, name, do_size_check): 54bf215546Sopenharmony_ci self.name_base = name 55bf215546Sopenharmony_ci self.do_size_check = do_size_check 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci self.max_bits = 1 59bf215546Sopenharmony_ci self.next_opcode_threshold = (1 << self.max_bits) 60bf215546Sopenharmony_ci self.max_opcode = 0 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci self.functions = {} 63bf215546Sopenharmony_ci self.lookup_table = [] 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci # Minimum number of opcodes in a leaf node. 66bf215546Sopenharmony_ci self.min_op_bits = 3 67bf215546Sopenharmony_ci self.min_op_count = (1 << self.min_op_bits) 68bf215546Sopenharmony_ci return 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ci def append(self, opcode, func): 72bf215546Sopenharmony_ci self.functions[opcode] = func 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci if opcode > self.max_opcode: 75bf215546Sopenharmony_ci self.max_opcode = opcode 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci if opcode > self.next_opcode_threshold: 78bf215546Sopenharmony_ci bits = log2(opcode) 79bf215546Sopenharmony_ci if (1 << bits) <= opcode: 80bf215546Sopenharmony_ci bits += 1 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci self.max_bits = bits 83bf215546Sopenharmony_ci self.next_opcode_threshold = 1 << bits 84bf215546Sopenharmony_ci return 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci def divide_group(self, min_opcode, total): 88bf215546Sopenharmony_ci """Divide the group starting min_opcode into subgroups. 89bf215546Sopenharmony_ci Returns a tuple containing the number of bits consumed by 90bf215546Sopenharmony_ci the node, the list of the children's tuple, and the number 91bf215546Sopenharmony_ci of entries in the final array used by this node and its 92bf215546Sopenharmony_ci children, and the depth of the subtree rooted at the node.""" 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci remaining_bits = self.max_bits - total 95bf215546Sopenharmony_ci next_opcode = min_opcode + (1 << remaining_bits) 96bf215546Sopenharmony_ci empty_children = 0 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci for M in range(0, remaining_bits): 99bf215546Sopenharmony_ci op_count = 1 << (remaining_bits - M); 100bf215546Sopenharmony_ci child_count = 1 << M; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci empty_children = 0 103bf215546Sopenharmony_ci full_children = 0 104bf215546Sopenharmony_ci for i in range(min_opcode, next_opcode, op_count): 105bf215546Sopenharmony_ci used = 0 106bf215546Sopenharmony_ci empty = 0 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci for j in range(i, i + op_count): 109bf215546Sopenharmony_ci if self.functions.has_key(j): 110bf215546Sopenharmony_ci used += 1; 111bf215546Sopenharmony_ci else: 112bf215546Sopenharmony_ci empty += 1; 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci if empty == op_count: 116bf215546Sopenharmony_ci empty_children += 1 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci if used == op_count: 119bf215546Sopenharmony_ci full_children += 1 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci if (empty_children > 0) or (full_children == child_count) or (op_count <= self.min_op_count): 122bf215546Sopenharmony_ci break 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci # If all the remaining bits are used by this node, as is the 126bf215546Sopenharmony_ci # case when M is 0 or remaining_bits, the node is a leaf. 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci if (M == 0) or (M == remaining_bits): 129bf215546Sopenharmony_ci return [remaining_bits, [], 0, 0] 130bf215546Sopenharmony_ci else: 131bf215546Sopenharmony_ci children = [] 132bf215546Sopenharmony_ci count = 1 133bf215546Sopenharmony_ci depth = 1 134bf215546Sopenharmony_ci all_children_are_nonempty_leaf_nodes = 1 135bf215546Sopenharmony_ci for i in range(min_opcode, next_opcode, op_count): 136bf215546Sopenharmony_ci n = self.divide_group(i, total + M) 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci if not (n[1] == [] and not self.is_empty_leaf(i, n[0])): 139bf215546Sopenharmony_ci all_children_are_nonempty_leaf_nodes = 0 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci children.append(n) 142bf215546Sopenharmony_ci count += n[2] + 1 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci if n[3] >= depth: 145bf215546Sopenharmony_ci depth = n[3] + 1 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci # If all of the child nodes are non-empty leaf nodes, pull 148bf215546Sopenharmony_ci # them up and make this node a leaf. 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci if all_children_are_nonempty_leaf_nodes: 151bf215546Sopenharmony_ci return [remaining_bits, [], 0, 0] 152bf215546Sopenharmony_ci else: 153bf215546Sopenharmony_ci return [M, children, count, depth] 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci def is_empty_leaf(self, base_opcode, M): 157bf215546Sopenharmony_ci for op in range(base_opcode, base_opcode + (1 << M)): 158bf215546Sopenharmony_ci if self.functions.has_key(op): 159bf215546Sopenharmony_ci return 0 160bf215546Sopenharmony_ci break 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci return 1 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci def dump_tree(self, node, base_opcode, remaining_bits, base_entry, depth): 166bf215546Sopenharmony_ci M = node[0] 167bf215546Sopenharmony_ci children = node[1] 168bf215546Sopenharmony_ci child_M = remaining_bits - M 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci # This actually an error condition. 172bf215546Sopenharmony_ci if children == []: 173bf215546Sopenharmony_ci return 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci print ' /* [%u] -> opcode range [%u, %u], node depth %u */' % (base_entry, base_opcode, base_opcode + (1 << remaining_bits), depth) 176bf215546Sopenharmony_ci print ' %u,' % (M) 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci base_entry += (1 << M) + 1 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci child_index = base_entry 181bf215546Sopenharmony_ci child_base_opcode = base_opcode 182bf215546Sopenharmony_ci for child in children: 183bf215546Sopenharmony_ci if child[1] == []: 184bf215546Sopenharmony_ci if self.is_empty_leaf(child_base_opcode, child_M): 185bf215546Sopenharmony_ci print ' EMPTY_LEAF,' 186bf215546Sopenharmony_ci else: 187bf215546Sopenharmony_ci # Emit the index of the next dispatch 188bf215546Sopenharmony_ci # function. Then add all the 189bf215546Sopenharmony_ci # dispatch functions for this leaf 190bf215546Sopenharmony_ci # node to the dispatch function 191bf215546Sopenharmony_ci # lookup table. 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci print ' LEAF(%u),' % (len(self.lookup_table)) 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci for op in range(child_base_opcode, child_base_opcode + (1 << child_M)): 196bf215546Sopenharmony_ci if self.functions.has_key(op): 197bf215546Sopenharmony_ci func = self.functions[op] 198bf215546Sopenharmony_ci size = func.command_fixed_length() 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci if func.glx_rop != 0: 201bf215546Sopenharmony_ci size += 4 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci size = ((size + 3) & ~3) 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci if func.has_variable_size_request(): 206bf215546Sopenharmony_ci size_name = "__glX%sReqSize" % (func.name) 207bf215546Sopenharmony_ci else: 208bf215546Sopenharmony_ci size_name = "" 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci if func.glx_vendorpriv == op: 211bf215546Sopenharmony_ci func_name = func.glx_vendorpriv_names[0] 212bf215546Sopenharmony_ci else: 213bf215546Sopenharmony_ci func_name = func.name 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci temp = [op, "__glXDisp_%s" % (func_name), "__glXDispSwap_%s" % (func_name), size, size_name] 216bf215546Sopenharmony_ci else: 217bf215546Sopenharmony_ci temp = [op, "NULL", "NULL", 0, ""] 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci self.lookup_table.append(temp) 220bf215546Sopenharmony_ci else: 221bf215546Sopenharmony_ci print ' %u,' % (child_index) 222bf215546Sopenharmony_ci child_index += child[2] 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci child_base_opcode += 1 << child_M 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci print '' 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci child_index = base_entry 229bf215546Sopenharmony_ci for child in children: 230bf215546Sopenharmony_ci if child[1] != []: 231bf215546Sopenharmony_ci self.dump_tree(child, base_opcode, remaining_bits - M, child_index, depth + 1) 232bf215546Sopenharmony_ci child_index += child[2] 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci base_opcode += 1 << (remaining_bits - M) 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci def Print(self): 238bf215546Sopenharmony_ci # Each dispatch table consists of two data structures. 239bf215546Sopenharmony_ci # 240bf215546Sopenharmony_ci # The first structure is an N-way tree where the opcode for 241bf215546Sopenharmony_ci # the function is the key. Each node switches on a range of 242bf215546Sopenharmony_ci # bits from the opcode. M bits are extracted from the opcde 243bf215546Sopenharmony_ci # and are used as an index to select one of the N, where 244bf215546Sopenharmony_ci # N = 2^M, children. 245bf215546Sopenharmony_ci # 246bf215546Sopenharmony_ci # The tree is stored as a flat array. The first value is the 247bf215546Sopenharmony_ci # number of bits, M, used by the node. For inner nodes, the 248bf215546Sopenharmony_ci # following 2^M values are indexes into the array for the 249bf215546Sopenharmony_ci # child nodes. For leaf nodes, the followign 2^M values are 250bf215546Sopenharmony_ci # indexes into the second data structure. 251bf215546Sopenharmony_ci # 252bf215546Sopenharmony_ci # If an inner node's child index is 0, the child is an empty 253bf215546Sopenharmony_ci # leaf node. That is, none of the opcodes selectable from 254bf215546Sopenharmony_ci # that child exist. Since most of the possible opcode space 255bf215546Sopenharmony_ci # is unused, this allows compact data storage. 256bf215546Sopenharmony_ci # 257bf215546Sopenharmony_ci # The second data structure is an array of pairs of function 258bf215546Sopenharmony_ci # pointers. Each function contains a pointer to a protocol 259bf215546Sopenharmony_ci # decode function and a pointer to a byte-swapped protocol 260bf215546Sopenharmony_ci # decode function. Elements in this array are selected by the 261bf215546Sopenharmony_ci # leaf nodes of the first data structure. 262bf215546Sopenharmony_ci # 263bf215546Sopenharmony_ci # As the tree is traversed, an accumulator is kept. This 264bf215546Sopenharmony_ci # accumulator counts the bits of the opcode consumed by the 265bf215546Sopenharmony_ci # traversal. When accumulator + M = B, where B is the 266bf215546Sopenharmony_ci # maximum number of bits in an opcode, the traversal has 267bf215546Sopenharmony_ci # reached a leaf node. The traversal starts with the most 268bf215546Sopenharmony_ci # significant bits and works down to the least significant 269bf215546Sopenharmony_ci # bits. 270bf215546Sopenharmony_ci # 271bf215546Sopenharmony_ci # Creation of the tree is the most complicated part. At 272bf215546Sopenharmony_ci # each node the elements are divided into groups of 2^M 273bf215546Sopenharmony_ci # elements. The value of M selected is the smallest possible 274bf215546Sopenharmony_ci # value where all of the groups are either empty or full, or 275bf215546Sopenharmony_ci # the groups are a preset minimum size. If all the children 276bf215546Sopenharmony_ci # of a node are non-empty leaf nodes, the children are merged 277bf215546Sopenharmony_ci # to create a single leaf node that replaces the parent. 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci tree = self.divide_group(0, 0) 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci print '/*****************************************************************/' 282bf215546Sopenharmony_ci print '/* tree depth = %u */' % (tree[3]) 283bf215546Sopenharmony_ci print 'static const int_fast16_t %s_dispatch_tree[%u] = {' % (self.name_base, tree[2]) 284bf215546Sopenharmony_ci self.dump_tree(tree, 0, self.max_bits, 0, 1) 285bf215546Sopenharmony_ci print '};\n' 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci # After dumping the tree, dump the function lookup table. 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci print 'static const void *%s_function_table[%u][2] = {' % (self.name_base, len(self.lookup_table)) 290bf215546Sopenharmony_ci index = 0 291bf215546Sopenharmony_ci for func in self.lookup_table: 292bf215546Sopenharmony_ci opcode = func[0] 293bf215546Sopenharmony_ci name = func[1] 294bf215546Sopenharmony_ci name_swap = func[2] 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci print ' /* [% 3u] = %5u */ {%s, %s},' % (index, opcode, name, name_swap) 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci index += 1 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci print '};\n' 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci if self.do_size_check: 303bf215546Sopenharmony_ci var_table = [] 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci print 'static const int_fast16_t %s_size_table[%u][2] = {' % (self.name_base, len(self.lookup_table)) 306bf215546Sopenharmony_ci index = 0 307bf215546Sopenharmony_ci var_table = [] 308bf215546Sopenharmony_ci for func in self.lookup_table: 309bf215546Sopenharmony_ci opcode = func[0] 310bf215546Sopenharmony_ci fixed = func[3] 311bf215546Sopenharmony_ci var = func[4] 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci if var != "": 314bf215546Sopenharmony_ci var_offset = "%2u" % (len(var_table)) 315bf215546Sopenharmony_ci var_table.append(var) 316bf215546Sopenharmony_ci else: 317bf215546Sopenharmony_ci var_offset = "~0" 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci print ' /* [%3u] = %5u */ {%3u, %s},' % (index, opcode, fixed, var_offset) 320bf215546Sopenharmony_ci index += 1 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci print '};\n' 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci print 'static const gl_proto_size_func %s_size_func_table[%u] = {' % (self.name_base, len(var_table)) 327bf215546Sopenharmony_ci for func in var_table: 328bf215546Sopenharmony_ci print ' %s,' % (func) 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci print '};\n' 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci print 'const struct __glXDispatchInfo %s_dispatch_info = {' % (self.name_base) 334bf215546Sopenharmony_ci print ' %u,' % (self.max_bits) 335bf215546Sopenharmony_ci print ' %s_dispatch_tree,' % (self.name_base) 336bf215546Sopenharmony_ci print ' %s_function_table,' % (self.name_base) 337bf215546Sopenharmony_ci if self.do_size_check: 338bf215546Sopenharmony_ci print ' %s_size_table,' % (self.name_base) 339bf215546Sopenharmony_ci print ' %s_size_func_table' % (self.name_base) 340bf215546Sopenharmony_ci else: 341bf215546Sopenharmony_ci print ' NULL,' 342bf215546Sopenharmony_ci print ' NULL' 343bf215546Sopenharmony_ci print '};\n' 344bf215546Sopenharmony_ci return 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ciclass PrintGlxDispatchTables(glX_proto_common.glx_print_proto): 348bf215546Sopenharmony_ci def __init__(self): 349bf215546Sopenharmony_ci gl_XML.gl_print_base.__init__(self) 350bf215546Sopenharmony_ci self.name = "glX_server_table.py (from Mesa)" 351bf215546Sopenharmony_ci self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005, 2006", "IBM") 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci self.rop_functions = function_table("Render", 1) 354bf215546Sopenharmony_ci self.sop_functions = function_table("Single", 0) 355bf215546Sopenharmony_ci self.vop_functions = function_table("VendorPriv", 0) 356bf215546Sopenharmony_ci return 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci def printRealHeader(self): 360bf215546Sopenharmony_ci print '#include <inttypes.h>' 361bf215546Sopenharmony_ci print '#include "glxserver.h"' 362bf215546Sopenharmony_ci print '#include "glxext.h"' 363bf215546Sopenharmony_ci print '#include "indirect_dispatch.h"' 364bf215546Sopenharmony_ci print '#include "indirect_reqsize.h"' 365bf215546Sopenharmony_ci print '#include "indirect_table.h"' 366bf215546Sopenharmony_ci print '' 367bf215546Sopenharmony_ci return 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci def printBody(self, api): 371bf215546Sopenharmony_ci for f in api.functionIterateAll(): 372bf215546Sopenharmony_ci if not f.ignore and f.vectorequiv == None: 373bf215546Sopenharmony_ci if f.glx_rop != 0: 374bf215546Sopenharmony_ci self.rop_functions.append(f.glx_rop, f) 375bf215546Sopenharmony_ci if f.glx_sop != 0: 376bf215546Sopenharmony_ci self.sop_functions.append(f.glx_sop, f) 377bf215546Sopenharmony_ci if f.glx_vendorpriv != 0: 378bf215546Sopenharmony_ci self.vop_functions.append(f.glx_vendorpriv, f) 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci self.sop_functions.Print() 381bf215546Sopenharmony_ci self.rop_functions.Print() 382bf215546Sopenharmony_ci self.vop_functions.Print() 383bf215546Sopenharmony_ci return 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_cidef _parser(): 387bf215546Sopenharmony_ci """Parse arguments and return namespace.""" 388bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 389bf215546Sopenharmony_ci parser.add_argument('-f', 390bf215546Sopenharmony_ci dest='filename', 391bf215546Sopenharmony_ci default='gl_API.xml', 392bf215546Sopenharmony_ci help='An XML file describing an API.') 393bf215546Sopenharmony_ci return parser.parse_args() 394bf215546Sopenharmony_ci 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ciif __name__ == '__main__': 397bf215546Sopenharmony_ci args = _parser() 398bf215546Sopenharmony_ci printer = PrintGlxDispatchTables() 399bf215546Sopenharmony_ci api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory()) 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci printer.Print(api) 402