1bf215546Sopenharmony_ci 2bf215546Sopenharmony_ci# (C) Copyright IBM Corporation 2004, 2005 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_cifrom collections import OrderedDict 28bf215546Sopenharmony_cifrom decimal import Decimal 29bf215546Sopenharmony_ciimport xml.etree.ElementTree as ET 30bf215546Sopenharmony_ciimport re, sys 31bf215546Sopenharmony_ciimport os.path 32bf215546Sopenharmony_ciimport typeexpr 33bf215546Sopenharmony_ciimport static_data 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cidef parse_GL_API( file_name, factory = None ): 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci if not factory: 39bf215546Sopenharmony_ci factory = gl_item_factory() 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci api = factory.create_api() 42bf215546Sopenharmony_ci api.parse_file( file_name ) 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci # After the XML has been processed, we need to go back and assign 45bf215546Sopenharmony_ci # dispatch offsets to the functions that request that their offsets 46bf215546Sopenharmony_ci # be assigned by the scripts. Typically this means all functions 47bf215546Sopenharmony_ci # that are not part of the ABI. 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci for func in api.functionIterateByCategory(): 50bf215546Sopenharmony_ci if func.assign_offset and func.offset < 0: 51bf215546Sopenharmony_ci func.offset = api.next_offset; 52bf215546Sopenharmony_ci api.next_offset += 1 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci return api 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_cidef is_attr_true( element, name, default = "false" ): 58bf215546Sopenharmony_ci """Read a name value from an element's attributes. 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci The value read from the attribute list must be either 'true' or 61bf215546Sopenharmony_ci 'false'. If the value is 'false', zero will be returned. If the 62bf215546Sopenharmony_ci value is 'true', non-zero will be returned. An exception will be 63bf215546Sopenharmony_ci raised for any other value.""" 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci value = element.get( name, default ) 66bf215546Sopenharmony_ci if value == "true": 67bf215546Sopenharmony_ci return 1 68bf215546Sopenharmony_ci elif value == "false": 69bf215546Sopenharmony_ci return 0 70bf215546Sopenharmony_ci else: 71bf215546Sopenharmony_ci raise RuntimeError('Invalid value "%s" for boolean "%s".' % (value, name)) 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ciclass gl_print_base(object): 75bf215546Sopenharmony_ci """Base class of all API pretty-printers. 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci In the model-view-controller pattern, this is the view. Any derived 78bf215546Sopenharmony_ci class will want to over-ride the printBody, printRealHader, and 79bf215546Sopenharmony_ci printRealFooter methods. Some derived classes may want to over-ride 80bf215546Sopenharmony_ci printHeader and printFooter, or even Print (though this is unlikely). 81bf215546Sopenharmony_ci """ 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci def __init__(self): 84bf215546Sopenharmony_ci # Name of the script that is generating the output file. 85bf215546Sopenharmony_ci # Every derived class should set this to the name of its 86bf215546Sopenharmony_ci # source file. 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_ci self.name = "a" 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci # License on the *generated* source file. This may differ 92bf215546Sopenharmony_ci # from the license on the script that is generating the file. 93bf215546Sopenharmony_ci # Every derived class should set this to some reasonable 94bf215546Sopenharmony_ci # value. 95bf215546Sopenharmony_ci # 96bf215546Sopenharmony_ci # See license.py for an example of a reasonable value. 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci self.license = "The license for this file is unspecified." 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci # The header_tag is the name of the C preprocessor define 102bf215546Sopenharmony_ci # used to prevent multiple inclusion. Typically only 103bf215546Sopenharmony_ci # generated C header files need this to be set. Setting it 104bf215546Sopenharmony_ci # causes code to be generated automatically in printHeader 105bf215546Sopenharmony_ci # and printFooter. 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci self.header_tag = None 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci # List of file-private defines that must be undefined at the 111bf215546Sopenharmony_ci # end of the file. This can be used in header files to define 112bf215546Sopenharmony_ci # names for use in the file, then undefine them at the end of 113bf215546Sopenharmony_ci # the header file. 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci self.undef_list = [] 116bf215546Sopenharmony_ci return 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci def Print(self, api): 120bf215546Sopenharmony_ci self.printHeader() 121bf215546Sopenharmony_ci self.printBody(api) 122bf215546Sopenharmony_ci self.printFooter() 123bf215546Sopenharmony_ci return 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci def printHeader(self): 127bf215546Sopenharmony_ci """Print the header associated with all files and call the printRealHeader method.""" 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci print('/* DO NOT EDIT - This file generated automatically by %s script */' \ 130bf215546Sopenharmony_ci % (self.name)) 131bf215546Sopenharmony_ci print('') 132bf215546Sopenharmony_ci print('/*') 133bf215546Sopenharmony_ci print((' * ' + self.license.replace('\n', '\n * ')).replace(' \n', '\n')) 134bf215546Sopenharmony_ci print(' */') 135bf215546Sopenharmony_ci print('') 136bf215546Sopenharmony_ci if self.header_tag: 137bf215546Sopenharmony_ci print('#if !defined( %s )' % (self.header_tag)) 138bf215546Sopenharmony_ci print('# define %s' % (self.header_tag)) 139bf215546Sopenharmony_ci print('') 140bf215546Sopenharmony_ci self.printRealHeader(); 141bf215546Sopenharmony_ci return 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci def printFooter(self): 145bf215546Sopenharmony_ci """Print the header associated with all files and call the printRealFooter method.""" 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci self.printRealFooter() 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci if self.undef_list: 150bf215546Sopenharmony_ci print('') 151bf215546Sopenharmony_ci for u in self.undef_list: 152bf215546Sopenharmony_ci print("# undef %s" % (u)) 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci if self.header_tag: 155bf215546Sopenharmony_ci print('') 156bf215546Sopenharmony_ci print('#endif /* !defined( %s ) */' % (self.header_tag)) 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci def printRealHeader(self): 160bf215546Sopenharmony_ci """Print the "real" header for the created file. 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci In the base class, this function is empty. All derived 163bf215546Sopenharmony_ci classes should over-ride this function.""" 164bf215546Sopenharmony_ci return 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci def printRealFooter(self): 168bf215546Sopenharmony_ci """Print the "real" footer for the created file. 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci In the base class, this function is empty. All derived 171bf215546Sopenharmony_ci classes should over-ride this function.""" 172bf215546Sopenharmony_ci return 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci def printPure(self): 176bf215546Sopenharmony_ci """Conditionally define `PURE' function attribute. 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci Conditionally defines a preprocessor macro `PURE' that wraps 179bf215546Sopenharmony_ci GCC's `pure' function attribute. The conditional code can be 180bf215546Sopenharmony_ci easilly adapted to other compilers that support a similar 181bf215546Sopenharmony_ci feature. 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci The name is also added to the file's undef_list. 184bf215546Sopenharmony_ci """ 185bf215546Sopenharmony_ci self.undef_list.append("PURE") 186bf215546Sopenharmony_ci print("""# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) 187bf215546Sopenharmony_ci# define PURE __attribute__((pure)) 188bf215546Sopenharmony_ci# else 189bf215546Sopenharmony_ci# define PURE 190bf215546Sopenharmony_ci# endif""") 191bf215546Sopenharmony_ci return 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci def printFastcall(self): 195bf215546Sopenharmony_ci """Conditionally define `FASTCALL' function attribute. 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci Conditionally defines a preprocessor macro `FASTCALL' that 198bf215546Sopenharmony_ci wraps GCC's `fastcall' function attribute. The conditional 199bf215546Sopenharmony_ci code can be easilly adapted to other compilers that support a 200bf215546Sopenharmony_ci similar feature. 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci The name is also added to the file's undef_list. 203bf215546Sopenharmony_ci """ 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci self.undef_list.append("FASTCALL") 206bf215546Sopenharmony_ci print("""# if defined(__i386__) && defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) 207bf215546Sopenharmony_ci# define FASTCALL __attribute__((fastcall)) 208bf215546Sopenharmony_ci# else 209bf215546Sopenharmony_ci# define FASTCALL 210bf215546Sopenharmony_ci# endif""") 211bf215546Sopenharmony_ci return 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci def printVisibility(self, S, s): 215bf215546Sopenharmony_ci """Conditionally define visibility function attribute. 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci Conditionally defines a preprocessor macro name S that wraps 218bf215546Sopenharmony_ci GCC's visibility function attribute. The visibility used is 219bf215546Sopenharmony_ci the parameter s. The conditional code can be easilly adapted 220bf215546Sopenharmony_ci to other compilers that support a similar feature. 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci The name is also added to the file's undef_list. 223bf215546Sopenharmony_ci """ 224bf215546Sopenharmony_ci 225bf215546Sopenharmony_ci self.undef_list.append(S) 226bf215546Sopenharmony_ci print("""# if defined(__GNUC__) && !defined(__CYGWIN__) && !defined(__MINGW32__) 227bf215546Sopenharmony_ci# define %s __attribute__((visibility("%s"))) 228bf215546Sopenharmony_ci# else 229bf215546Sopenharmony_ci# define %s 230bf215546Sopenharmony_ci# endif""" % (S, s, S)) 231bf215546Sopenharmony_ci return 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci def printNoinline(self): 235bf215546Sopenharmony_ci """Conditionally define `NOINLINE' function attribute. 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci Conditionally defines a preprocessor macro `NOINLINE' that 238bf215546Sopenharmony_ci wraps GCC's `noinline' function attribute. The conditional 239bf215546Sopenharmony_ci code can be easilly adapted to other compilers that support a 240bf215546Sopenharmony_ci similar feature. 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci The name is also added to the file's undef_list. 243bf215546Sopenharmony_ci """ 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci self.undef_list.append("NOINLINE") 246bf215546Sopenharmony_ci print("""# if defined(__GNUC__) 247bf215546Sopenharmony_ci# define NOINLINE __attribute__((noinline)) 248bf215546Sopenharmony_ci# else 249bf215546Sopenharmony_ci# define NOINLINE 250bf215546Sopenharmony_ci# endif""") 251bf215546Sopenharmony_ci return 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_cidef real_function_name(element): 255bf215546Sopenharmony_ci name = element.get( "name" ) 256bf215546Sopenharmony_ci alias = element.get( "alias" ) 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci if alias: 259bf215546Sopenharmony_ci return alias 260bf215546Sopenharmony_ci else: 261bf215546Sopenharmony_ci return name 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_cidef real_category_name(c): 265bf215546Sopenharmony_ci if re.compile("[1-9][0-9]*[.][0-9]+").match(c): 266bf215546Sopenharmony_ci return "GL_VERSION_" + c.replace(".", "_") 267bf215546Sopenharmony_ci else: 268bf215546Sopenharmony_ci return c 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_cidef classify_category(name, number): 272bf215546Sopenharmony_ci """Based on the category name and number, select a numerical class for it. 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci Categories are divided into four classes numbered 0 through 3. The 275bf215546Sopenharmony_ci classes are: 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci 0. Core GL versions, sorted by version number. 278bf215546Sopenharmony_ci 1. ARB extensions, sorted by extension number. 279bf215546Sopenharmony_ci 2. Non-ARB extensions, sorted by extension number. 280bf215546Sopenharmony_ci 3. Un-numbered extensions, sorted by extension name. 281bf215546Sopenharmony_ci """ 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci try: 284bf215546Sopenharmony_ci core_version = float(name) 285bf215546Sopenharmony_ci except Exception: 286bf215546Sopenharmony_ci core_version = 0.0 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci if core_version > 0.0: 289bf215546Sopenharmony_ci cat_type = 0 290bf215546Sopenharmony_ci key = name 291bf215546Sopenharmony_ci elif name.startswith("GL_ARB_") or name.startswith("GLX_ARB_") or name.startswith("WGL_ARB_"): 292bf215546Sopenharmony_ci cat_type = 1 293bf215546Sopenharmony_ci key = int(number) 294bf215546Sopenharmony_ci else: 295bf215546Sopenharmony_ci if number != None: 296bf215546Sopenharmony_ci cat_type = 2 297bf215546Sopenharmony_ci key = int(number) 298bf215546Sopenharmony_ci else: 299bf215546Sopenharmony_ci cat_type = 3 300bf215546Sopenharmony_ci key = name 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci return [cat_type, key] 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_cidef create_parameter_string(parameters, include_names): 307bf215546Sopenharmony_ci """Create a parameter string from a list of gl_parameters.""" 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci list = [] 310bf215546Sopenharmony_ci for p in parameters: 311bf215546Sopenharmony_ci if p.is_padding: 312bf215546Sopenharmony_ci continue 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci if include_names: 315bf215546Sopenharmony_ci list.append( p.string() ) 316bf215546Sopenharmony_ci else: 317bf215546Sopenharmony_ci list.append( p.type_string() ) 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if len(list) == 0: list = ["void"] 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci return ", ".join(list) 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ciclass gl_item(object): 325bf215546Sopenharmony_ci def __init__(self, element, context, category): 326bf215546Sopenharmony_ci self.context = context 327bf215546Sopenharmony_ci self.name = element.get( "name" ) 328bf215546Sopenharmony_ci self.category = real_category_name( category ) 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci return 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ciclass gl_type( gl_item ): 334bf215546Sopenharmony_ci def __init__(self, element, context, category): 335bf215546Sopenharmony_ci gl_item.__init__(self, element, context, category) 336bf215546Sopenharmony_ci self.size = int( element.get( "size" ), 0 ) 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci te = typeexpr.type_expression( None ) 339bf215546Sopenharmony_ci tn = typeexpr.type_node() 340bf215546Sopenharmony_ci tn.size = int( element.get( "size" ), 0 ) 341bf215546Sopenharmony_ci tn.integer = not is_attr_true( element, "float" ) 342bf215546Sopenharmony_ci tn.unsigned = is_attr_true( element, "unsigned" ) 343bf215546Sopenharmony_ci tn.pointer = is_attr_true( element, "pointer" ) 344bf215546Sopenharmony_ci tn.name = "GL" + self.name 345bf215546Sopenharmony_ci te.set_base_type_node( tn ) 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci self.type_expr = te 348bf215546Sopenharmony_ci return 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci def get_type_expression(self): 352bf215546Sopenharmony_ci return self.type_expr 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci 355bf215546Sopenharmony_ciclass gl_enum( gl_item ): 356bf215546Sopenharmony_ci def __init__(self, element, context, category): 357bf215546Sopenharmony_ci gl_item.__init__(self, element, context, category) 358bf215546Sopenharmony_ci self.value = int( element.get( "value" ), 0 ) 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci temp = element.get( "count" ) 361bf215546Sopenharmony_ci if not temp or temp == "?": 362bf215546Sopenharmony_ci self.default_count = -1 363bf215546Sopenharmony_ci else: 364bf215546Sopenharmony_ci try: 365bf215546Sopenharmony_ci c = int(temp) 366bf215546Sopenharmony_ci except Exception: 367bf215546Sopenharmony_ci raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n)) 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci self.default_count = c 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci return 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci def priority(self): 375bf215546Sopenharmony_ci """Calculate a 'priority' for this enum name. 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci When an enum is looked up by number, there may be many 378bf215546Sopenharmony_ci possible names, but only one is the 'prefered' name. The 379bf215546Sopenharmony_ci priority is used to select which name is the 'best'. 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci Highest precedence is given to core GL name. ARB extension 382bf215546Sopenharmony_ci names have the next highest, followed by EXT extension names. 383bf215546Sopenharmony_ci Vendor extension names are the lowest. 384bf215546Sopenharmony_ci """ 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if self.name.endswith( "_BIT" ): 387bf215546Sopenharmony_ci bias = 1 388bf215546Sopenharmony_ci else: 389bf215546Sopenharmony_ci bias = 0 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci if self.category.startswith( "GL_VERSION_" ): 392bf215546Sopenharmony_ci priority = 0 393bf215546Sopenharmony_ci elif self.category.startswith( "GL_ARB_" ): 394bf215546Sopenharmony_ci priority = 2 395bf215546Sopenharmony_ci elif self.category.startswith( "GL_EXT_" ): 396bf215546Sopenharmony_ci priority = 4 397bf215546Sopenharmony_ci else: 398bf215546Sopenharmony_ci priority = 6 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci return priority + bias 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ciclass gl_parameter(object): 405bf215546Sopenharmony_ci def __init__(self, element, context): 406bf215546Sopenharmony_ci self.name = element.get( "name" ) 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci ts = element.get( "type" ) 409bf215546Sopenharmony_ci self.type_expr = typeexpr.type_expression( ts, context ) 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci temp = element.get( "variable_param" ) 412bf215546Sopenharmony_ci if temp: 413bf215546Sopenharmony_ci self.count_parameter_list = temp.split( ' ' ) 414bf215546Sopenharmony_ci else: 415bf215546Sopenharmony_ci self.count_parameter_list = [] 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci # The count tag can be either a numeric string or the name of 418bf215546Sopenharmony_ci # a variable. If it is the name of a variable, the int(c) 419bf215546Sopenharmony_ci # statement will throw an exception, and the except block will 420bf215546Sopenharmony_ci # take over. 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci c = element.get( "count" ) 423bf215546Sopenharmony_ci try: 424bf215546Sopenharmony_ci count = int(c) 425bf215546Sopenharmony_ci self.count = count 426bf215546Sopenharmony_ci self.counter = None 427bf215546Sopenharmony_ci except Exception: 428bf215546Sopenharmony_ci count = 1 429bf215546Sopenharmony_ci self.count = 0 430bf215546Sopenharmony_ci self.counter = c 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci self.marshal_count = element.get("marshal_count") 433bf215546Sopenharmony_ci self.count_scale = int(element.get( "count_scale", "1" )) 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci elements = (count * self.count_scale) 436bf215546Sopenharmony_ci if elements == 1: 437bf215546Sopenharmony_ci elements = 0 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci #if ts == "GLdouble": 440bf215546Sopenharmony_ci # print '/* stack size -> %s = %u (before)*/' % (self.name, self.type_expr.get_stack_size()) 441bf215546Sopenharmony_ci # print '/* # elements = %u */' % (elements) 442bf215546Sopenharmony_ci self.type_expr.set_elements( elements ) 443bf215546Sopenharmony_ci #if ts == "GLdouble": 444bf215546Sopenharmony_ci # print '/* stack size -> %s = %u (after) */' % (self.name, self.type_expr.get_stack_size()) 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci self.is_client_only = is_attr_true( element, 'client_only' ) 447bf215546Sopenharmony_ci self.is_counter = is_attr_true( element, 'counter' ) 448bf215546Sopenharmony_ci self.is_output = is_attr_true( element, 'output' ) 449bf215546Sopenharmony_ci 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci # Pixel data has special parameters. 452bf215546Sopenharmony_ci 453bf215546Sopenharmony_ci self.width = element.get('img_width') 454bf215546Sopenharmony_ci self.height = element.get('img_height') 455bf215546Sopenharmony_ci self.depth = element.get('img_depth') 456bf215546Sopenharmony_ci self.extent = element.get('img_extent') 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci self.img_xoff = element.get('img_xoff') 459bf215546Sopenharmony_ci self.img_yoff = element.get('img_yoff') 460bf215546Sopenharmony_ci self.img_zoff = element.get('img_zoff') 461bf215546Sopenharmony_ci self.img_woff = element.get('img_woff') 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci self.img_format = element.get('img_format') 464bf215546Sopenharmony_ci self.img_type = element.get('img_type') 465bf215546Sopenharmony_ci self.img_target = element.get('img_target') 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci self.img_pad_dimensions = is_attr_true( element, 'img_pad_dimensions' ) 468bf215546Sopenharmony_ci self.img_null_flag = is_attr_true( element, 'img_null_flag' ) 469bf215546Sopenharmony_ci self.img_send_null = is_attr_true( element, 'img_send_null' ) 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci self.is_padding = is_attr_true( element, 'padding' ) 472bf215546Sopenharmony_ci return 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci def compatible(self, other): 476bf215546Sopenharmony_ci return 1 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci def is_array(self): 480bf215546Sopenharmony_ci return self.is_pointer() 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci def is_pointer(self): 484bf215546Sopenharmony_ci return self.type_expr.is_pointer() 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci def is_image(self): 488bf215546Sopenharmony_ci if self.width: 489bf215546Sopenharmony_ci return 1 490bf215546Sopenharmony_ci else: 491bf215546Sopenharmony_ci return 0 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_ci def is_variable_length(self): 495bf215546Sopenharmony_ci return len(self.count_parameter_list) or self.counter or self.marshal_count 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci def is_64_bit(self): 499bf215546Sopenharmony_ci count = self.type_expr.get_element_count() 500bf215546Sopenharmony_ci if count: 501bf215546Sopenharmony_ci if (self.size() / count) == 8: 502bf215546Sopenharmony_ci return 1 503bf215546Sopenharmony_ci else: 504bf215546Sopenharmony_ci if self.size() == 8: 505bf215546Sopenharmony_ci return 1 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci return 0 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci def string(self): 511bf215546Sopenharmony_ci return self.type_expr.original_string + " " + self.name 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci def type_string(self): 515bf215546Sopenharmony_ci return self.type_expr.original_string 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci def get_base_type_string(self): 519bf215546Sopenharmony_ci return self.type_expr.get_base_name() 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ci def get_dimensions(self): 523bf215546Sopenharmony_ci if not self.width: 524bf215546Sopenharmony_ci return [ 0, "0", "0", "0", "0" ] 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci dim = 1 527bf215546Sopenharmony_ci w = self.width 528bf215546Sopenharmony_ci h = "1" 529bf215546Sopenharmony_ci d = "1" 530bf215546Sopenharmony_ci e = "1" 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci if self.height: 533bf215546Sopenharmony_ci dim = 2 534bf215546Sopenharmony_ci h = self.height 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci if self.depth: 537bf215546Sopenharmony_ci dim = 3 538bf215546Sopenharmony_ci d = self.depth 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci if self.extent: 541bf215546Sopenharmony_ci dim = 4 542bf215546Sopenharmony_ci e = self.extent 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci return [ dim, w, h, d, e ] 545bf215546Sopenharmony_ci 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci def get_stack_size(self): 548bf215546Sopenharmony_ci return self.type_expr.get_stack_size() 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci def size(self): 552bf215546Sopenharmony_ci if self.is_image(): 553bf215546Sopenharmony_ci return 0 554bf215546Sopenharmony_ci else: 555bf215546Sopenharmony_ci return self.type_expr.get_element_size() 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci def get_element_count(self): 559bf215546Sopenharmony_ci c = self.type_expr.get_element_count() 560bf215546Sopenharmony_ci if c == 0: 561bf215546Sopenharmony_ci return 1 562bf215546Sopenharmony_ci 563bf215546Sopenharmony_ci return c 564bf215546Sopenharmony_ci 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci def size_string(self, use_parens = 1, marshal = 0): 567bf215546Sopenharmony_ci base_size_str = "" 568bf215546Sopenharmony_ci 569bf215546Sopenharmony_ci count = self.get_element_count() 570bf215546Sopenharmony_ci if count: 571bf215546Sopenharmony_ci base_size_str = "%d * " % count 572bf215546Sopenharmony_ci 573bf215546Sopenharmony_ci base_size_str += "sizeof(%s)" % ( self.get_base_type_string() ) 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci if self.counter or self.count_parameter_list or (self.marshal_count and marshal): 576bf215546Sopenharmony_ci list = [ "compsize" ] 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci if self.marshal_count and marshal: 579bf215546Sopenharmony_ci list = [ self.marshal_count ] 580bf215546Sopenharmony_ci elif self.counter and self.count_parameter_list: 581bf215546Sopenharmony_ci list.append( self.counter ) 582bf215546Sopenharmony_ci elif self.counter: 583bf215546Sopenharmony_ci list = [ self.counter ] 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci if self.size() > 1: 586bf215546Sopenharmony_ci list.append( base_size_str ) 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci if len(list) > 1 and use_parens : 589bf215546Sopenharmony_ci return "safe_mul(%s)" % ", ".join(list) 590bf215546Sopenharmony_ci else: 591bf215546Sopenharmony_ci return " * ".join(list) 592bf215546Sopenharmony_ci 593bf215546Sopenharmony_ci elif self.is_image(): 594bf215546Sopenharmony_ci return "compsize" 595bf215546Sopenharmony_ci else: 596bf215546Sopenharmony_ci return base_size_str 597bf215546Sopenharmony_ci 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci def format_string(self): 600bf215546Sopenharmony_ci if self.type_expr.original_string == "GLenum": 601bf215546Sopenharmony_ci return "0x%x" 602bf215546Sopenharmony_ci else: 603bf215546Sopenharmony_ci return self.type_expr.format_string() 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ciclass gl_function( gl_item ): 607bf215546Sopenharmony_ci def __init__(self, element, context): 608bf215546Sopenharmony_ci self.context = context 609bf215546Sopenharmony_ci self.name = None 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci self.entry_points = [] 612bf215546Sopenharmony_ci self.return_type = "void" 613bf215546Sopenharmony_ci self.parameters = [] 614bf215546Sopenharmony_ci self.offset = -1 615bf215546Sopenharmony_ci self.initialized = 0 616bf215546Sopenharmony_ci self.images = [] 617bf215546Sopenharmony_ci self.exec_flavor = 'mesa' 618bf215546Sopenharmony_ci self.desktop = True 619bf215546Sopenharmony_ci self.deprecated = None 620bf215546Sopenharmony_ci self.has_no_error_variant = False 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci # self.api_map[api] is a decimal value indicating the earliest 623bf215546Sopenharmony_ci # version of the given API in which ANY alias for the function 624bf215546Sopenharmony_ci # exists. The map only lists APIs which contain the function 625bf215546Sopenharmony_ci # in at least one version. For example, for the ClipPlanex 626bf215546Sopenharmony_ci # function, self.api_map == { 'es1': 627bf215546Sopenharmony_ci # Decimal('1.1') }. 628bf215546Sopenharmony_ci self.api_map = {} 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci self.assign_offset = False 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci self.static_entry_points = [] 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci # Track the parameter string (for the function prototype) 635bf215546Sopenharmony_ci # for each entry-point. This is done because some functions 636bf215546Sopenharmony_ci # change their prototype slightly when promoted from extension 637bf215546Sopenharmony_ci # to ARB extension to core. glTexImage3DEXT and glTexImage3D 638bf215546Sopenharmony_ci # are good examples of this. Scripts that need to generate 639bf215546Sopenharmony_ci # code for these differing aliases need to real prototype 640bf215546Sopenharmony_ci # for each entry-point. Otherwise, they may generate code 641bf215546Sopenharmony_ci # that won't compile. 642bf215546Sopenharmony_ci 643bf215546Sopenharmony_ci self.entry_point_parameters = {} 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci self.process_element( element ) 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci return 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci 650bf215546Sopenharmony_ci def process_element(self, element): 651bf215546Sopenharmony_ci name = element.get( "name" ) 652bf215546Sopenharmony_ci alias = element.get( "alias" ) 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci # marshal isn't allowed with alias 655bf215546Sopenharmony_ci assert not alias or not element.get('marshal') 656bf215546Sopenharmony_ci assert not alias or not element.get('marshal_count') 657bf215546Sopenharmony_ci assert not alias or not element.get('marshal_sync') 658bf215546Sopenharmony_ci assert not alias or not element.get('marshal_call_before') 659bf215546Sopenharmony_ci assert not alias or not element.get('marshal_call_after') 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci if name in static_data.functions: 662bf215546Sopenharmony_ci self.static_entry_points.append(name) 663bf215546Sopenharmony_ci 664bf215546Sopenharmony_ci self.entry_points.append( name ) 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_ci for api in ('es1', 'es2'): 667bf215546Sopenharmony_ci version_str = element.get(api, 'none') 668bf215546Sopenharmony_ci assert version_str is not None 669bf215546Sopenharmony_ci if version_str != 'none': 670bf215546Sopenharmony_ci version_decimal = Decimal(version_str) 671bf215546Sopenharmony_ci if api not in self.api_map or \ 672bf215546Sopenharmony_ci version_decimal < self.api_map[api]: 673bf215546Sopenharmony_ci self.api_map[api] = version_decimal 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci exec_flavor = element.get('exec') 676bf215546Sopenharmony_ci if exec_flavor: 677bf215546Sopenharmony_ci self.exec_flavor = exec_flavor 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci deprecated = element.get('deprecated', 'none') 680bf215546Sopenharmony_ci if deprecated != 'none': 681bf215546Sopenharmony_ci self.deprecated = Decimal(deprecated) 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci if not is_attr_true(element, 'desktop', 'true'): 684bf215546Sopenharmony_ci self.desktop = False 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci if self.has_no_error_variant or is_attr_true(element, 'no_error'): 687bf215546Sopenharmony_ci self.has_no_error_variant = True 688bf215546Sopenharmony_ci else: 689bf215546Sopenharmony_ci self.has_no_error_variant = False 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_ci if alias: 692bf215546Sopenharmony_ci true_name = alias 693bf215546Sopenharmony_ci else: 694bf215546Sopenharmony_ci true_name = name 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci # Only try to set the offset when a non-alias entry-point 697bf215546Sopenharmony_ci # is being processed. 698bf215546Sopenharmony_ci 699bf215546Sopenharmony_ci if name in static_data.offsets and static_data.offsets[name] <= static_data.MAX_OFFSETS: 700bf215546Sopenharmony_ci self.offset = static_data.offsets[name] 701bf215546Sopenharmony_ci elif name in static_data.offsets and static_data.offsets[name] > static_data.MAX_OFFSETS: 702bf215546Sopenharmony_ci self.offset = static_data.offsets[name] 703bf215546Sopenharmony_ci self.assign_offset = True 704bf215546Sopenharmony_ci else: 705bf215546Sopenharmony_ci if self.exec_flavor != "skip": 706bf215546Sopenharmony_ci raise RuntimeError("Entry-point %s is missing offset in static_data.py. Add one at the bottom of the list." % (name)) 707bf215546Sopenharmony_ci self.assign_offset = self.exec_flavor != "skip" or name in static_data.unused_functions 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ci if not self.name: 710bf215546Sopenharmony_ci self.name = true_name 711bf215546Sopenharmony_ci elif self.name != true_name: 712bf215546Sopenharmony_ci raise RuntimeError("Function true name redefined. Was %s, now %s." % (self.name, true_name)) 713bf215546Sopenharmony_ci 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci # There are two possible cases. The first time an entry-point 716bf215546Sopenharmony_ci # with data is seen, self.initialized will be 0. On that 717bf215546Sopenharmony_ci # pass, we just fill in the data. The next time an 718bf215546Sopenharmony_ci # entry-point with data is seen, self.initialized will be 1. 719bf215546Sopenharmony_ci # On that pass we have to make that the new values match the 720bf215546Sopenharmony_ci # valuse from the previous entry-point. 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci parameters = [] 723bf215546Sopenharmony_ci return_type = "void" 724bf215546Sopenharmony_ci for child in element: 725bf215546Sopenharmony_ci if child.tag == "return": 726bf215546Sopenharmony_ci return_type = child.get( "type", "void" ) 727bf215546Sopenharmony_ci elif child.tag == "param": 728bf215546Sopenharmony_ci param = self.context.factory.create_parameter(child, self.context) 729bf215546Sopenharmony_ci parameters.append( param ) 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci if self.initialized: 733bf215546Sopenharmony_ci if self.return_type != return_type: 734bf215546Sopenharmony_ci raise RuntimeError( "Return type changed in %s. Was %s, now %s." % (name, self.return_type, return_type)) 735bf215546Sopenharmony_ci 736bf215546Sopenharmony_ci if len(parameters) != len(self.parameters): 737bf215546Sopenharmony_ci raise RuntimeError( "Parameter count mismatch in %s. Was %d, now %d." % (name, len(self.parameters), len(parameters))) 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci for j in range(0, len(parameters)): 740bf215546Sopenharmony_ci p1 = parameters[j] 741bf215546Sopenharmony_ci p2 = self.parameters[j] 742bf215546Sopenharmony_ci if not p1.compatible( p2 ): 743bf215546Sopenharmony_ci raise RuntimeError( 'Parameter type mismatch in %s. "%s" was "%s", now "%s".' % (name, p2.name, p2.type_expr.original_string, p1.type_expr.original_string)) 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_ci if true_name == name or not self.initialized: 747bf215546Sopenharmony_ci self.return_type = return_type 748bf215546Sopenharmony_ci self.parameters = parameters 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci for param in self.parameters: 751bf215546Sopenharmony_ci if param.is_image(): 752bf215546Sopenharmony_ci self.images.append( param ) 753bf215546Sopenharmony_ci 754bf215546Sopenharmony_ci if list(element): 755bf215546Sopenharmony_ci self.initialized = 1 756bf215546Sopenharmony_ci self.entry_point_parameters[name] = parameters 757bf215546Sopenharmony_ci else: 758bf215546Sopenharmony_ci self.entry_point_parameters[name] = [] 759bf215546Sopenharmony_ci 760bf215546Sopenharmony_ci return 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_ci def filter_entry_points(self, entry_point_list): 763bf215546Sopenharmony_ci """Filter out entry points not in entry_point_list.""" 764bf215546Sopenharmony_ci if not self.initialized: 765bf215546Sopenharmony_ci raise RuntimeError('%s is not initialized yet' % self.name) 766bf215546Sopenharmony_ci 767bf215546Sopenharmony_ci entry_points = [] 768bf215546Sopenharmony_ci for ent in self.entry_points: 769bf215546Sopenharmony_ci if ent not in entry_point_list: 770bf215546Sopenharmony_ci if ent in self.static_entry_points: 771bf215546Sopenharmony_ci self.static_entry_points.remove(ent) 772bf215546Sopenharmony_ci self.entry_point_parameters.pop(ent) 773bf215546Sopenharmony_ci else: 774bf215546Sopenharmony_ci entry_points.append(ent) 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci if not entry_points: 777bf215546Sopenharmony_ci raise RuntimeError('%s has no entry point after filtering' % self.name) 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci self.entry_points = entry_points 780bf215546Sopenharmony_ci if self.name not in entry_points: 781bf215546Sopenharmony_ci # use the first remaining entry point 782bf215546Sopenharmony_ci self.name = entry_points[0] 783bf215546Sopenharmony_ci self.parameters = self.entry_point_parameters[entry_points[0]] 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci def get_images(self): 786bf215546Sopenharmony_ci """Return potentially empty list of input images.""" 787bf215546Sopenharmony_ci return self.images 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci def parameterIterator(self, name = None): 791bf215546Sopenharmony_ci if name is not None: 792bf215546Sopenharmony_ci return iter(self.entry_point_parameters[name]); 793bf215546Sopenharmony_ci else: 794bf215546Sopenharmony_ci return iter(self.parameters); 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci def get_parameter_string(self, entrypoint = None): 798bf215546Sopenharmony_ci if entrypoint: 799bf215546Sopenharmony_ci params = self.entry_point_parameters[ entrypoint ] 800bf215546Sopenharmony_ci else: 801bf215546Sopenharmony_ci params = self.parameters 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci return create_parameter_string( params, 1 ) 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci def get_called_parameter_string(self): 806bf215546Sopenharmony_ci p_string = "" 807bf215546Sopenharmony_ci comma = "" 808bf215546Sopenharmony_ci 809bf215546Sopenharmony_ci for p in self.parameterIterator(): 810bf215546Sopenharmony_ci if p.is_padding: 811bf215546Sopenharmony_ci continue 812bf215546Sopenharmony_ci p_string = p_string + comma + p.name 813bf215546Sopenharmony_ci comma = ", " 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_ci return p_string 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci def is_abi(self): 819bf215546Sopenharmony_ci return (self.offset >= 0 and not self.assign_offset) 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci def is_static_entry_point(self, name): 822bf215546Sopenharmony_ci return name in self.static_entry_points 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci def dispatch_name(self): 825bf215546Sopenharmony_ci if self.name in self.static_entry_points: 826bf215546Sopenharmony_ci return self.name 827bf215546Sopenharmony_ci else: 828bf215546Sopenharmony_ci return "_dispatch_stub_%u" % (self.offset) 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci def static_name(self, name): 831bf215546Sopenharmony_ci if name in self.static_entry_points: 832bf215546Sopenharmony_ci return name 833bf215546Sopenharmony_ci else: 834bf215546Sopenharmony_ci return "_dispatch_stub_%u" % (self.offset) 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_ciclass gl_item_factory(object): 837bf215546Sopenharmony_ci """Factory to create objects derived from gl_item.""" 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci def create_function(self, element, context): 840bf215546Sopenharmony_ci return gl_function(element, context) 841bf215546Sopenharmony_ci 842bf215546Sopenharmony_ci def create_type(self, element, context, category): 843bf215546Sopenharmony_ci return gl_type(element, context, category) 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci def create_enum(self, element, context, category): 846bf215546Sopenharmony_ci return gl_enum(element, context, category) 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci def create_parameter(self, element, context): 849bf215546Sopenharmony_ci return gl_parameter(element, context) 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_ci def create_api(self): 852bf215546Sopenharmony_ci return gl_api(self) 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci 855bf215546Sopenharmony_ciclass gl_api(object): 856bf215546Sopenharmony_ci def __init__(self, factory): 857bf215546Sopenharmony_ci self.functions_by_name = OrderedDict() 858bf215546Sopenharmony_ci self.enums_by_name = {} 859bf215546Sopenharmony_ci self.types_by_name = {} 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci self.category_dict = {} 862bf215546Sopenharmony_ci self.categories = [{}, {}, {}, {}] 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci self.factory = factory 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_ci self.next_offset = 0 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_ci typeexpr.create_initial_types() 869bf215546Sopenharmony_ci return 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci def parse_file(self, file_name): 872bf215546Sopenharmony_ci doc = ET.parse( file_name ) 873bf215546Sopenharmony_ci self.process_element(file_name, doc) 874bf215546Sopenharmony_ci 875bf215546Sopenharmony_ci 876bf215546Sopenharmony_ci def process_element(self, file_name, doc): 877bf215546Sopenharmony_ci element = doc.getroot() 878bf215546Sopenharmony_ci if element.tag == "OpenGLAPI": 879bf215546Sopenharmony_ci self.process_OpenGLAPI(file_name, element) 880bf215546Sopenharmony_ci return 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci def process_OpenGLAPI(self, file_name, element): 884bf215546Sopenharmony_ci for child in element: 885bf215546Sopenharmony_ci if child.tag == "category": 886bf215546Sopenharmony_ci self.process_category( child ) 887bf215546Sopenharmony_ci elif child.tag == "OpenGLAPI": 888bf215546Sopenharmony_ci self.process_OpenGLAPI( file_name, child ) 889bf215546Sopenharmony_ci elif child.tag == '{http://www.w3.org/2001/XInclude}include': 890bf215546Sopenharmony_ci href = child.get('href') 891bf215546Sopenharmony_ci href = os.path.join(os.path.dirname(file_name), href) 892bf215546Sopenharmony_ci self.parse_file(href) 893bf215546Sopenharmony_ci 894bf215546Sopenharmony_ci return 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci 897bf215546Sopenharmony_ci def process_category(self, cat): 898bf215546Sopenharmony_ci cat_name = cat.get( "name" ) 899bf215546Sopenharmony_ci cat_number = cat.get( "number" ) 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci [cat_type, key] = classify_category(cat_name, cat_number) 902bf215546Sopenharmony_ci self.categories[cat_type][key] = [cat_name, cat_number] 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci for child in cat: 905bf215546Sopenharmony_ci if child.tag == "function": 906bf215546Sopenharmony_ci func_name = real_function_name( child ) 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci temp_name = child.get( "name" ) 909bf215546Sopenharmony_ci self.category_dict[ temp_name ] = [cat_name, cat_number] 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci if func_name in self.functions_by_name: 912bf215546Sopenharmony_ci func = self.functions_by_name[ func_name ] 913bf215546Sopenharmony_ci func.process_element( child ) 914bf215546Sopenharmony_ci else: 915bf215546Sopenharmony_ci func = self.factory.create_function( child, self ) 916bf215546Sopenharmony_ci self.functions_by_name[ func_name ] = func 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci if func.offset >= self.next_offset: 919bf215546Sopenharmony_ci self.next_offset = func.offset + 1 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci elif child.tag == "enum": 923bf215546Sopenharmony_ci enum = self.factory.create_enum( child, self, cat_name ) 924bf215546Sopenharmony_ci self.enums_by_name[ enum.name ] = enum 925bf215546Sopenharmony_ci elif child.tag == "type": 926bf215546Sopenharmony_ci t = self.factory.create_type( child, self, cat_name ) 927bf215546Sopenharmony_ci self.types_by_name[ "GL" + t.name ] = t 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci return 930bf215546Sopenharmony_ci 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci def functionIterateByCategory(self, cat = None): 933bf215546Sopenharmony_ci """Iterate over functions by category. 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci If cat is None, all known functions are iterated in category 936bf215546Sopenharmony_ci order. See classify_category for details of the ordering. 937bf215546Sopenharmony_ci Within a category, functions are sorted by name. If cat is 938bf215546Sopenharmony_ci not None, then only functions in that category are iterated. 939bf215546Sopenharmony_ci """ 940bf215546Sopenharmony_ci lists = [{}, {}, {}, {}] 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci for func in self.functionIterateAll(): 943bf215546Sopenharmony_ci [cat_name, cat_number] = self.category_dict[func.name] 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci if (cat == None) or (cat == cat_name): 946bf215546Sopenharmony_ci [func_cat_type, key] = classify_category(cat_name, cat_number) 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci if key not in lists[func_cat_type]: 949bf215546Sopenharmony_ci lists[func_cat_type][key] = {} 950bf215546Sopenharmony_ci 951bf215546Sopenharmony_ci lists[func_cat_type][key][func.name] = func 952bf215546Sopenharmony_ci 953bf215546Sopenharmony_ci 954bf215546Sopenharmony_ci functions = [] 955bf215546Sopenharmony_ci for func_cat_type in range(0,4): 956bf215546Sopenharmony_ci keys = sorted(lists[func_cat_type].keys()) 957bf215546Sopenharmony_ci 958bf215546Sopenharmony_ci for key in keys: 959bf215546Sopenharmony_ci names = sorted(lists[func_cat_type][key].keys()) 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci for name in names: 962bf215546Sopenharmony_ci functions.append(lists[func_cat_type][key][name]) 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci return iter(functions) 965bf215546Sopenharmony_ci 966bf215546Sopenharmony_ci 967bf215546Sopenharmony_ci def functionIterateByOffset(self): 968bf215546Sopenharmony_ci max_offset = -1 969bf215546Sopenharmony_ci for func in self.functions_by_name.values(): 970bf215546Sopenharmony_ci if func.offset > max_offset: 971bf215546Sopenharmony_ci max_offset = func.offset 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci temp = [None for i in range(0, max_offset + 1)] 975bf215546Sopenharmony_ci for func in self.functions_by_name.values(): 976bf215546Sopenharmony_ci if func.offset != -1: 977bf215546Sopenharmony_ci temp[ func.offset ] = func 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci list = [] 981bf215546Sopenharmony_ci for i in range(0, max_offset + 1): 982bf215546Sopenharmony_ci if temp[i]: 983bf215546Sopenharmony_ci list.append(temp[i]) 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_ci return iter(list); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci 988bf215546Sopenharmony_ci def functionIterateAll(self): 989bf215546Sopenharmony_ci return self.functions_by_name.values() 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci def enumIterateByName(self): 993bf215546Sopenharmony_ci keys = sorted(self.enums_by_name.keys()) 994bf215546Sopenharmony_ci 995bf215546Sopenharmony_ci list = [] 996bf215546Sopenharmony_ci for enum in keys: 997bf215546Sopenharmony_ci list.append( self.enums_by_name[ enum ] ) 998bf215546Sopenharmony_ci 999bf215546Sopenharmony_ci return iter(list) 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci 1002bf215546Sopenharmony_ci def categoryIterate(self): 1003bf215546Sopenharmony_ci """Iterate over categories. 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci Iterate over all known categories in the order specified by 1006bf215546Sopenharmony_ci classify_category. Each iterated value is a tuple of the 1007bf215546Sopenharmony_ci name and number (which may be None) of the category. 1008bf215546Sopenharmony_ci """ 1009bf215546Sopenharmony_ci 1010bf215546Sopenharmony_ci list = [] 1011bf215546Sopenharmony_ci for cat_type in range(0,4): 1012bf215546Sopenharmony_ci keys = sorted(self.categories[cat_type].keys()) 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci for key in keys: 1015bf215546Sopenharmony_ci list.append(self.categories[cat_type][key]) 1016bf215546Sopenharmony_ci 1017bf215546Sopenharmony_ci return iter(list) 1018bf215546Sopenharmony_ci 1019bf215546Sopenharmony_ci 1020bf215546Sopenharmony_ci def get_category_for_name( self, name ): 1021bf215546Sopenharmony_ci if name in self.category_dict: 1022bf215546Sopenharmony_ci return self.category_dict[name] 1023bf215546Sopenharmony_ci else: 1024bf215546Sopenharmony_ci return ["<unknown category>", None] 1025bf215546Sopenharmony_ci 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci def typeIterate(self): 1028bf215546Sopenharmony_ci return self.types_by_name.values() 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_ci def find_type( self, type_name ): 1032bf215546Sopenharmony_ci if type_name in self.types_by_name: 1033bf215546Sopenharmony_ci return self.types_by_name[ type_name ].type_expr 1034bf215546Sopenharmony_ci else: 1035bf215546Sopenharmony_ci print("Unable to find base type matching \"%s\"." % (type_name)) 1036bf215546Sopenharmony_ci return None 1037