Home | History | Annotate | Download | only in gen
      1 #!/usr/bin/env python
      2 
      3 # (C) Copyright IBM Corporation 2004, 2005
      4 # All Rights Reserved.
      5 #
      6 # Permission is hereby granted, free of charge, to any person obtaining a
      7 # copy of this software and associated documentation files (the "Software"),
      8 # to deal in the Software without restriction, including without limitation
      9 # on the rights to use, copy, modify, merge, publish, distribute, sub
     10 # license, and/or sell copies of the Software, and to permit persons to whom
     11 # the Software is furnished to do so, subject to the following conditions:
     12 #
     13 # The above copyright notice and this permission notice (including the next
     14 # paragraph) shall be included in all copies or substantial portions of the
     15 # Software.
     16 #
     17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     20 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     23 # IN THE SOFTWARE.
     24 #
     25 # Authors:
     26 #    Ian Romanick <idr (at] us.ibm.com>
     27 
     28 import gl_XML, glX_XML
     29 import license
     30 import sys, getopt, copy, string
     31 
     32 
     33 class glx_enum_function:
     34 	def __init__(self, func_name, enum_dict):
     35 		self.name = func_name
     36 		self.mode = 1
     37 		self.sig = None
     38 
     39 		# "enums" is a set of lists.  The element in the set is the
     40 		# value of the enum.  The list is the list of names for that
     41 		# value.  For example, [0x8126] = {"POINT_SIZE_MIN",
     42 		# "POINT_SIZE_MIN_ARB", "POINT_SIZE_MIN_EXT",
     43 		# "POINT_SIZE_MIN_SGIS"}.
     44 
     45 		self.enums = {}
     46 
     47 		# "count" is indexed by count values.  Each element of count
     48 		# is a list of index to "enums" that have that number of
     49 		# associated data elements.  For example, [4] = 
     50 		# {GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION,
     51 		# GL_AMBIENT_AND_DIFFUSE} (the enum names are used here,
     52 		# but the actual hexadecimal values would be in the array).
     53 
     54 		self.count = {}
     55 
     56 
     57 		# Fill self.count and self.enums using the dictionary of enums
     58 		# that was passed in.  The generic Get functions (e.g.,
     59 		# GetBooleanv and friends) are handled specially here.  In
     60 		# the data the generic Get functions are refered to as "Get".
     61 
     62 		if func_name in ["GetIntegerv", "GetBooleanv", "GetFloatv", "GetDoublev"]:
     63 			match_name = "Get"
     64 		else:
     65 			match_name = func_name
     66 
     67 		mode_set = 0
     68 		for enum_name in enum_dict:
     69 			e = enum_dict[ enum_name ]
     70 
     71 			if e.functions.has_key( match_name ):
     72 				[count, mode] = e.functions[ match_name ]
     73 
     74 				if mode_set and mode != self.mode:
     75 					raise RuntimeError("Not all enums for %s have the same mode." % (func_name))
     76 
     77 				self.mode = mode
     78 
     79 				if self.enums.has_key( e.value ):
     80 					if e.name not in self.enums[ e.value ]:
     81 						self.enums[ e.value ].append( e )
     82 				else:
     83 					if not self.count.has_key( count ):
     84 						self.count[ count ] = []
     85 
     86 					self.enums[ e.value ] = [ e ]
     87 					self.count[ count ].append( e.value )
     88 
     89 
     90 		return
     91 
     92 
     93 	def signature( self ):
     94 		if self.sig == None:
     95 			self.sig = ""
     96 			for i in self.count:
     97 				if i == None:
     98 					raise RuntimeError("i is None.  WTF?")
     99 
    100 				self.count[i].sort()
    101 				for e in self.count[i]:
    102 					self.sig += "%04x,%d," % (e, i)
    103 
    104 		return self.sig
    105 
    106 
    107 	def is_set( self ):
    108 		return self.mode
    109 
    110 
    111 	def PrintUsingTable(self):
    112 		"""Emit the body of the __gl*_size function using a pair
    113 		of look-up tables and a mask.  The mask is calculated such
    114 		that (e & mask) is unique for all the valid values of e for
    115 		this function.  The result of (e & mask) is used as an index
    116 		into the first look-up table.  If it matches e, then the
    117 		same entry of the second table is returned.  Otherwise zero
    118 		is returned.
    119 		
    120 		It seems like this should cause better code to be generated.
    121 		However, on x86 at least, the resulting .o file is about 20%
    122 		larger then the switch-statment version.  I am leaving this
    123 		code in because the results may be different on other
    124 		platforms (e.g., PowerPC or x86-64)."""
    125 
    126 		return 0
    127 		count = 0
    128 		for a in self.enums:
    129 			count += 1
    130 
    131 		if self.count.has_key(-1):
    132 			return 0
    133 
    134 		# Determine if there is some mask M, such that M = (2^N) - 1,
    135 		# that will generate unique values for all of the enums.
    136 
    137 		mask = 0
    138 		for i in [1, 2, 3, 4, 5, 6, 7, 8]:
    139 			mask = (1 << i) - 1
    140 
    141 			fail = 0;
    142 			for a in self.enums:
    143 				for b in self.enums:
    144 					if a != b:
    145 						if (a & mask) == (b & mask):
    146 							fail = 1;
    147 
    148 			if not fail:
    149 				break;
    150 			else:
    151 				mask = 0
    152 
    153 		if (mask != 0) and (mask < (2 * count)):
    154 			masked_enums = {}
    155 			masked_count = {}
    156 
    157 			for i in range(0, mask + 1):
    158 				masked_enums[i] = "0";
    159 				masked_count[i] = 0;
    160 
    161 			for c in self.count:
    162 				for e in self.count[c]:
    163 					i = e & mask
    164 					enum_obj = self.enums[e][0]
    165 					masked_enums[i] = '0x%04x /* %s */' % (e, enum_obj.name )
    166 					masked_count[i] = c
    167 
    168 
    169 			print '    static const GLushort a[%u] = {' % (mask + 1)
    170 			for e in masked_enums:
    171 				print '        %s, ' % (masked_enums[e])
    172 			print '    };'
    173 
    174 			print '    static const GLubyte b[%u] = {' % (mask + 1)
    175 			for c in masked_count:
    176 				print '        %u, ' % (masked_count[c])
    177 			print '    };'
    178 
    179 			print '    const unsigned idx = (e & 0x%02xU);' % (mask)
    180 			print ''
    181 			print '    return (e == a[idx]) ? (GLint) b[idx] : 0;'
    182 			return 1;
    183 		else:
    184 			return 0;
    185 
    186 
    187 	def PrintUsingSwitch(self, name):
    188 		"""Emit the body of the __gl*_size function using a 
    189 		switch-statement."""
    190 
    191 		print '    switch( e ) {'
    192 
    193 		for c in self.count:
    194 			for e in self.count[c]:
    195 				first = 1
    196 
    197 				# There may be multiple enums with the same
    198 				# value.  This happens has extensions are
    199 				# promoted from vendor-specific or EXT to
    200 				# ARB and to the core.  Emit the first one as
    201 				# a case label, and emit the others as
    202 				# commented-out case labels.
    203 
    204 				list = {}
    205 				for enum_obj in self.enums[e]:
    206 					list[ enum_obj.priority() ] = enum_obj.name
    207 
    208 				keys = list.keys()
    209 				keys.sort()
    210 				for k in keys:
    211 					j = list[k]
    212 					if first:
    213 						print '        case GL_%s:' % (j)
    214 						first = 0
    215 					else:
    216 						print '/*      case GL_%s:*/' % (j)
    217 					
    218 			if c == -1:
    219 				print '            return __gl%s_variable_size( e );' % (name)
    220 			else:
    221 				print '            return %u;' % (c)
    222 					
    223 		print '        default: return 0;'
    224 		print '    }'
    225 
    226 
    227 	def Print(self, name):
    228 		print '_X_INTERNAL PURE FASTCALL GLint'
    229 		print '__gl%s_size( GLenum e )' % (name)
    230 		print '{'
    231 
    232 		if not self.PrintUsingTable():
    233 			self.PrintUsingSwitch(name)
    234 
    235 		print '}'
    236 		print ''
    237 
    238 
    239 class glx_server_enum_function(glx_enum_function):
    240 	def __init__(self, func, enum_dict):
    241 		glx_enum_function.__init__(self, func.name, enum_dict)
    242 		
    243 		self.function = func
    244 		return
    245 
    246 
    247 	def signature( self ):
    248 		if self.sig == None:
    249 			sig = glx_enum_function.signature(self)
    250 
    251 			p = self.function.variable_length_parameter()
    252 			if p:
    253 				sig += "%u" % (p.size())
    254 
    255 			self.sig = sig
    256 
    257 		return self.sig;
    258 
    259 
    260 	def Print(self, name, printer):
    261 		f = self.function
    262 		printer.common_func_print_just_header( f )
    263 
    264 		fixup = []
    265 		
    266 		foo = {}
    267 		for param_name in f.count_parameter_list:
    268 			o = f.offset_of( param_name )
    269 			foo[o] = param_name
    270 
    271 		for param_name in f.counter_list:
    272 			o = f.offset_of( param_name )
    273 			foo[o] = param_name
    274 
    275 		keys = foo.keys()
    276 		keys.sort()
    277 		for o in keys:
    278 			p = f.parameters_by_name[ foo[o] ]
    279 
    280 			printer.common_emit_one_arg(p, "pc", 0)
    281 			fixup.append( p.name )
    282 
    283 
    284 		print '    GLsizei compsize;'
    285 		print ''
    286 
    287 		printer.common_emit_fixups(fixup)
    288 
    289 		print ''
    290 		print '    compsize = __gl%s_size(%s);' % (f.name, string.join(f.count_parameter_list, ","))
    291 		p = f.variable_length_parameter()
    292 		print '    return __GLX_PAD(%s);' % (p.size_string())
    293 
    294 		print '}'
    295 		print ''
    296 
    297 
    298 class PrintGlxSizeStubs_common(gl_XML.gl_print_base):
    299 	do_get = (1 << 0)
    300 	do_set = (1 << 1)
    301 
    302 	def __init__(self, which_functions):
    303 		gl_XML.gl_print_base.__init__(self)
    304 
    305 		self.name = "glX_proto_size.py (from Mesa)"
    306 		self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004", "IBM")
    307 
    308 		self.emit_set = ((which_functions & PrintGlxSizeStubs_common.do_set) != 0)
    309 		self.emit_get = ((which_functions & PrintGlxSizeStubs_common.do_get) != 0)
    310 		return
    311 
    312 
    313 class PrintGlxSizeStubs_c(PrintGlxSizeStubs_common):
    314 	def printRealHeader(self):
    315 		print ''
    316 		print '#include <X11/Xfuncproto.h>'
    317 		print '#include <GL/gl.h>'
    318 		if self.emit_get:
    319 			print '#include "indirect_size_get.h"'
    320 			print '#include "glxserver.h"'
    321 			print '#include "indirect_util.h"'
    322 		
    323 		print '#include "indirect_size.h"'
    324 
    325 		print ''
    326 		self.printPure()
    327 		print ''
    328 		self.printFastcall()
    329 		print ''
    330 		print ''
    331 		print '#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(GLX_USE_APPLEGL)'
    332 		print '#  undef HAVE_ALIAS'
    333 		print '#endif'
    334 		print '#ifdef HAVE_ALIAS'
    335 		print '#  define ALIAS2(from,to) \\'
    336 		print '    _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
    337 		print '        __attribute__ ((alias( # to )));'
    338 		print '#  define ALIAS(from,to) ALIAS2( from, __gl ## to ## _size )'
    339 		print '#else'
    340 		print '#  define ALIAS(from,to) \\'
    341 		print '    _X_INTERNAL PURE FASTCALL GLint __gl ## from ## _size( GLenum e ) \\'
    342 		print '    { return __gl ## to ## _size( e ); }'
    343 		print '#endif'
    344 		print ''
    345 		print ''
    346 
    347 
    348 	def printBody(self, api):
    349 		enum_sigs = {}
    350 		aliases = []
    351 
    352 		for func in api.functionIterateGlx():
    353 			ef = glx_enum_function( func.name, api.enums_by_name )
    354 			if len(ef.enums) == 0:
    355 				continue
    356 
    357 			if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get):
    358 				sig = ef.signature()
    359 				if enum_sigs.has_key( sig ):
    360 					aliases.append( [func.name, enum_sigs[ sig ]] )
    361 				else:
    362 					enum_sigs[ sig ] = func.name
    363 					ef.Print( func.name )
    364 
    365 
    366 		for [alias_name, real_name] in aliases:
    367 			print 'ALIAS( %s, %s )' % (alias_name, real_name)
    368 
    369 
    370 				
    371 class PrintGlxSizeStubs_h(PrintGlxSizeStubs_common):
    372 	def printRealHeader(self):
    373 		print """/**
    374  * \\file
    375  * Prototypes for functions used to determine the number of data elements in
    376  * various GLX protocol messages.
    377  *
    378  * \\author Ian Romanick <idr (at] us.ibm.com>
    379  */
    380 """
    381 		print '#include <X11/Xfuncproto.h>'
    382 		print ''
    383 		self.printPure();
    384 		print ''
    385 		self.printFastcall();
    386 		print ''
    387 
    388 
    389 	def printBody(self, api):
    390 		for func in api.functionIterateGlx():
    391 			ef = glx_enum_function( func.name, api.enums_by_name )
    392 			if len(ef.enums) == 0:
    393 				continue
    394 
    395 			if (ef.is_set() and self.emit_set) or (not ef.is_set() and self.emit_get):
    396 				print 'extern _X_INTERNAL PURE FASTCALL GLint __gl%s_size(GLenum);' % (func.name)
    397 
    398 
    399 class PrintGlxReqSize_common(gl_XML.gl_print_base):
    400 	"""Common base class for PrintGlxSizeReq_h and PrintGlxSizeReq_h.
    401 
    402 	The main purpose of this common base class is to provide the infrastructure
    403 	for the derrived classes to iterate over the same set of functions.
    404 	"""
    405 
    406 	def __init__(self):
    407 		gl_XML.gl_print_base.__init__(self)
    408 
    409 		self.name = "glX_proto_size.py (from Mesa)"
    410 		self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
    411 
    412 
    413 class PrintGlxReqSize_h(PrintGlxReqSize_common):
    414 	def __init__(self):
    415 		PrintGlxReqSize_common.__init__(self)
    416 		self.header_tag = "_INDIRECT_REQSIZE_H_"
    417 
    418 
    419 	def printRealHeader(self):
    420 		print '#include <X11/Xfuncproto.h>'
    421 		print ''
    422 		self.printPure()
    423 		print ''
    424 
    425 
    426 	def printBody(self, api):
    427 		for func in api.functionIterateGlx():
    428 			if not func.ignore and func.has_variable_size_request():
    429 				print 'extern PURE _X_HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap);' % (func.name)
    430 
    431 
    432 class PrintGlxReqSize_c(PrintGlxReqSize_common):
    433 	"""Create the server-side 'request size' functions.
    434 
    435 	Create the server-side functions that are used to determine what the
    436 	size of a varible length command should be.  The server then uses
    437 	this value to determine if the incoming command packed it malformed.
    438 	"""
    439 
    440 	def __init__(self):
    441 		PrintGlxReqSize_common.__init__(self)
    442 		self.counter_sigs = {}
    443 
    444 
    445 	def printRealHeader(self):
    446 		print ''
    447 		print '#include <GL/gl.h>'
    448 		print '#include "glxserver.h"'
    449 		print '#include "glxbyteorder.h"'
    450 		print '#include "indirect_size.h"'
    451 		print '#include "indirect_reqsize.h"'
    452 		print ''
    453 		print '#define __GLX_PAD(x)  (((x) + 3) & ~3)'
    454 		print ''
    455 		print '#if defined(__CYGWIN__) || defined(__MINGW32__)'
    456 		print '#  undef HAVE_ALIAS'
    457 		print '#endif'
    458 		print '#ifdef HAVE_ALIAS'
    459 		print '#  define ALIAS2(from,to) \\'
    460 		print '    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
    461 		print '        __attribute__ ((alias( # to )));'
    462 		print '#  define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )'
    463 		print '#else'
    464 		print '#  define ALIAS(from,to) \\'
    465 		print '    GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \\'
    466 		print '    { return __glX ## to ## ReqSize( pc, swap ); }'
    467 		print '#endif'
    468 		print ''
    469 		print ''
    470 
    471 
    472 	def printBody(self, api):
    473 		aliases = []
    474 		enum_functions = {}
    475 		enum_sigs = {}
    476 
    477 		for func in api.functionIterateGlx():
    478 			if not func.has_variable_size_request(): continue
    479 
    480 			ef = glx_server_enum_function( func, api.enums_by_name )
    481 			if len(ef.enums) == 0: continue
    482 
    483 			sig = ef.signature()
    484 
    485 			if not enum_functions.has_key(func.name):
    486 				enum_functions[ func.name ] = sig
    487 
    488 			if not enum_sigs.has_key( sig ):
    489 				enum_sigs[ sig ] = ef
    490 			
    491 
    492 
    493 		for func in api.functionIterateGlx():
    494 			# Even though server-handcode fuctions are on "the
    495 			# list", and prototypes are generated for them, there
    496 			# isn't enough information to generate a size
    497 			# function.  If there was enough information, they
    498 			# probably wouldn't need to be handcoded in the first
    499 			# place!
    500 
    501 			if func.server_handcode: continue
    502 			if not func.has_variable_size_request(): continue
    503 
    504 			if enum_functions.has_key(func.name):
    505 				sig = enum_functions[func.name]
    506 				ef = enum_sigs[ sig ]
    507 
    508 				if ef.name != func.name:
    509 					aliases.append( [func.name, ef.name] )
    510 				else:
    511 					ef.Print( func.name, self )
    512 
    513 			elif func.images:
    514 				self.printPixelFunction(func)
    515 			elif func.has_variable_size_request():
    516 				a = self.printCountedFunction(func)
    517 				if a: aliases.append(a)
    518 
    519 
    520 		for [alias_name, real_name] in aliases:
    521 			print 'ALIAS( %s, %s )' % (alias_name, real_name)
    522 
    523 		return
    524 
    525 
    526 	def common_emit_fixups(self, fixup):
    527 		"""Utility function to emit conditional byte-swaps."""
    528 
    529 		if fixup:
    530 			print '    if (swap) {'
    531 			for name in fixup:
    532 				print '        %s = bswap_32(%s);' % (name, name)
    533 			print '    }'
    534 
    535 		return
    536 
    537 
    538 	def common_emit_one_arg(self, p, pc, adjust):
    539 		offset = p.offset
    540 		dst = p.string()
    541 		src = '(%s *)' % (p.type_string())
    542 		print '%-18s = *%11s(%s + %u);' % (dst, src, pc, offset + adjust);
    543 		return
    544 
    545 
    546 	def common_func_print_just_header(self, f):
    547 		print 'int'
    548 		print '__glX%sReqSize( const GLbyte * pc, Bool swap )' % (f.name)
    549 		print '{'
    550 
    551 
    552 	def printPixelFunction(self, f):
    553 		self.common_func_print_just_header(f)
    554 		
    555 		f.offset_of( f.parameters[0].name )
    556 		[dim, w, h, d, junk] = f.get_images()[0].get_dimensions()
    557 
    558 		print '    GLint row_length   = *  (GLint *)(pc +  4);'
    559 
    560 		if dim < 3:
    561 			fixup = ['row_length', 'skip_rows', 'alignment']
    562 			print '    GLint image_height = 0;'
    563 			print '    GLint skip_images  = 0;'
    564 			print '    GLint skip_rows    = *  (GLint *)(pc +  8);'
    565 			print '    GLint alignment    = *  (GLint *)(pc + 16);'
    566 		else:
    567 			fixup = ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment']
    568 			print '    GLint image_height = *  (GLint *)(pc +  8);'
    569 			print '    GLint skip_rows    = *  (GLint *)(pc + 16);'
    570 			print '    GLint skip_images  = *  (GLint *)(pc + 20);'
    571 			print '    GLint alignment    = *  (GLint *)(pc + 32);'
    572 
    573 		img = f.images[0]
    574 		for p in f.parameterIterateGlxSend():
    575 			if p.name in [w, h, d, img.img_format, img.img_type, img.img_target]:
    576 				self.common_emit_one_arg(p, "pc", 0)
    577 				fixup.append( p.name )
    578 
    579 		print ''
    580 
    581 		self.common_emit_fixups(fixup)
    582 
    583 		if img.img_null_flag:
    584 			print ''
    585 			print '	   if (*(CARD32 *) (pc + %s))' % (img.offset - 4)
    586 			print '	       return 0;'
    587 
    588 		print ''
    589 		print '    return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (img.img_format, img.img_type, img.img_target, w, h, d )
    590 		print '                          image_height, row_length, skip_images,'
    591 		print '                          skip_rows, alignment);'
    592 		print '}'
    593 		print ''
    594 		return
    595 
    596 
    597 	def printCountedFunction(self, f):
    598 
    599 		sig = ""
    600 		offset = 0
    601 		fixup = []
    602 		params = []
    603 		plus = ''
    604 		size = ''
    605 		param_offsets = {}
    606 
    607 		# Calculate the offset of each counter parameter and the
    608 		# size string for the variable length parameter(s).  While
    609 		# that is being done, calculate a unique signature for this
    610 		# function.
    611 
    612 		for p in f.parameterIterateGlxSend():
    613 			if p.is_counter:
    614 				fixup.append( p.name )
    615 				params.append( p )
    616 			elif p.counter:
    617 				s = p.size()
    618 				if s == 0: s = 1
    619 
    620 				sig += "(%u,%u)" % (f.offset_of(p.counter), s)
    621 				size += '%s%s' % (plus, p.size_string())
    622 				plus = ' + '
    623 
    624 
    625 		# If the calculated signature matches a function that has
    626 		# already be emitted, don't emit this function.  Instead, add
    627 		# it to the list of function aliases.
    628 
    629 		if self.counter_sigs.has_key(sig):
    630 			n = self.counter_sigs[sig];
    631 			alias = [f.name, n]
    632 		else:
    633 			alias = None
    634 			self.counter_sigs[sig] = f.name
    635 
    636 			self.common_func_print_just_header(f)
    637 
    638 			for p in params:
    639 				self.common_emit_one_arg(p, "pc", 0)
    640 
    641 
    642 			print ''
    643 			self.common_emit_fixups(fixup)
    644 			print ''
    645 
    646 			print '    return __GLX_PAD(%s);' % (size)
    647 			print '}'
    648 			print ''
    649 
    650 		return alias
    651 
    652 
    653 def show_usage():
    654 	print "Usage: %s [-f input_file_name] -m output_mode [--only-get | --only-set] [--get-alias-set]" % sys.argv[0]
    655 	print "    -m output_mode   Output mode can be one of 'size_c' or 'size_h'."
    656 	print "    --only-get       Only emit 'get'-type functions."
    657 	print "    --only-set       Only emit 'set'-type functions."
    658 	print ""
    659 	print "By default, both 'get' and 'set'-type functions are emitted."
    660 	sys.exit(1)
    661 
    662 
    663 if __name__ == '__main__':
    664 	file_name = "gl_API.xml"
    665 
    666 	try:
    667 		(args, trail) = getopt.getopt(sys.argv[1:], "f:m:h:", ["only-get", "only-set", "header-tag"])
    668 	except Exception,e:
    669 		show_usage()
    670 
    671 	mode = None
    672 	header_tag = None
    673 	which_functions = PrintGlxSizeStubs_common.do_get | PrintGlxSizeStubs_common.do_set
    674 
    675 	for (arg,val) in args:
    676 		if arg == "-f":
    677 			file_name = val
    678 		elif arg == "-m":
    679 			mode = val
    680 		elif arg == "--only-get":
    681 			which_functions = PrintGlxSizeStubs_common.do_get
    682 		elif arg == "--only-set":
    683 			which_functions = PrintGlxSizeStubs_common.do_set
    684 		elif (arg == '-h') or (arg == "--header-tag"):
    685 			header_tag = val
    686 
    687 	if mode == "size_c":
    688 		printer = PrintGlxSizeStubs_c( which_functions )
    689 	elif mode == "size_h":
    690 		printer = PrintGlxSizeStubs_h( which_functions )
    691 		if header_tag:
    692 			printer.header_tag = header_tag
    693 	elif mode == "reqsize_c":
    694 		printer = PrintGlxReqSize_c()
    695 	elif mode == "reqsize_h":
    696 		printer = PrintGlxReqSize_h()
    697 	else:
    698 		show_usage()
    699 
    700 	api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
    701 
    702 
    703 	printer.Print( api )
    704