blob: 1771975e843a228031cdff2a18ed3b0e73ed4bad [file] [log] [blame]
Ian Romanick73f59b02004-05-18 18:33:40 +00001#!/usr/bin/python2
2
Ian Romanick5f1f2292005-01-07 02:39:09 +00003# (C) Copyright IBM Corporation 2004, 2005
Ian Romanick73f59b02004-05-18 18:33:40 +00004# 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@us.ibm.com>
27
28from xml.sax import saxutils
29from xml.sax import make_parser
30from xml.sax.handler import feature_namespaces
31
Brian Paul98fa2bf2004-10-28 21:11:02 +000032import re
Ian Romanick73f59b02004-05-18 18:33:40 +000033
34class glItem:
35 """Generic class on which all other API entity types are based."""
36
Ian Romanick73f59b02004-05-18 18:33:40 +000037 def __init__(self, tag_name, name, context):
38 self.name = name
39 self.category = context.get_category_define()
40 self.context = context
41 self.tag_name = tag_name
42
43 context.append(tag_name, self)
44 return
45
46 def startElement(self, name, attrs):
Ian Romanicka9d033c2004-05-19 23:33:08 +000047 """Generic startElement handler.
48
49 The startElement handler is called for all elements except
50 the one that starts the object. For a foo element, the
51 XML "<foo><bar/></foo>" would cause the startElement handler
52 to be called once, but the endElement handler would be called
53 twice."""
Ian Romanick73f59b02004-05-18 18:33:40 +000054 return
55
56 def endElement(self, name):
57 """Generic endElement handler.
58
59 Generic endElement handler. Returns 1 if the tag containing
60 the object is complete. Otherwise 0 is returned. All
61 derived class endElement handlers should call this method. If
62 the name of the ending tag is the same as the tag that
63 started this object, the object is assumed to be complete.
64
65 This fails if a tag can contain another tag with the same
66 name. The XML "<foo><foo/><bar/></foo>" would fail. The
Ian Romanicka9d033c2004-05-19 23:33:08 +000067 object would end before the bar tag was processed.
68
69 The endElement handler is called for every end element
70 associated with an object, even the element that started the
71 object. See the description of startElement an example."""
Ian Romanick73f59b02004-05-18 18:33:40 +000072
73 if name == self.tag_name:
74 return 1
75 else:
76 return 0
Ian Romanick73f59b02004-05-18 18:33:40 +000077
Ian Romanicka9d033c2004-05-19 23:33:08 +000078 def get_category_define(self):
79 return self.category
80
Ian Romanick73f59b02004-05-18 18:33:40 +000081
82class glEnum( glItem ):
Ian Romanicka9d033c2004-05-19 23:33:08 +000083 """Subclass of glItem for representing GL enumerants.
84
85 This class is not complete, and is not really used yet."""
86
Ian Romanick73f59b02004-05-18 18:33:40 +000087 def __init__(self, context, name, attrs):
88 self.value = int(attrs.get('value', "0x0000"), 0)
Ian Romanick73f59b02004-05-18 18:33:40 +000089
90 enum_name = "GL_" + attrs.get('name', None)
91 glItem.__init__(self, name, enum_name, context)
92
Ian Romanick85f0fa32005-01-25 01:20:11 +000093 temp = attrs.get('count', None)
94 if temp == None:
95 self.default_count = 0
96 else:
97 try:
98 c = int(temp)
99 except Exception,e:
100 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
101
102 self.default_count = c
103 return
104
Ian Romanick73f59b02004-05-18 18:33:40 +0000105
Ian Romanick5ff2b942005-01-24 21:29:13 +0000106 def process_attributes(self, attrs):
107 name = attrs.get('name', None)
108
109 temp = attrs.get('count', None)
Ian Romanick85f0fa32005-01-25 01:20:11 +0000110 if temp == None:
111 c = self.default_count
112 else:
113 try:
114 c = int(temp)
115 except Exception,e:
116 raise RuntimeError('Invalid count value "%s" for enum "%s" in function "%s" when an integer was expected.' % (temp, self.name, n))
Ian Romanick5ff2b942005-01-24 21:29:13 +0000117
Ian Romanick85f0fa32005-01-25 01:20:11 +0000118 mode_str = attrs.get('mode', "set")
119 if mode_str == "set":
120 mode = 1
121 elif mode_str == "get":
122 mode = 0
123 else:
124 raise RuntimeError("Invalid mode '%s' for function '%s' in enum '%s'." % (mode_str, self.context.name, self.name))
125
126 return [name, c, mode]
Ian Romanick73f59b02004-05-18 18:33:40 +0000127
128
129class glType( glItem ):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000130 """Subclass of glItem for representing GL types."""
131
Ian Romanick73f59b02004-05-18 18:33:40 +0000132 def __init__(self, context, name, attrs):
133 self.size = int(attrs.get('size', "0"))
Ian Romanicka285acb2005-01-07 03:22:56 +0000134 self.glx_name = attrs.get('glx_name', "")
Ian Romanick73f59b02004-05-18 18:33:40 +0000135
136 type_name = "GL" + attrs.get('name', None)
137 glItem.__init__(self, name, type_name, context)
138
139
Ian Romanicka9d033c2004-05-19 23:33:08 +0000140class glParameter( glItem ):
141 """Parameter of a glFunction."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000142 p_type = None
143 p_type_string = ""
Ian Romanick73f59b02004-05-18 18:33:40 +0000144 p_count = 0
145 p_count_parameters = None
146 counter = None
147 is_output = 0
148 is_counter = 0
149 is_pointer = 0
150
Ian Romanicka9d033c2004-05-19 23:33:08 +0000151 def __init__(self, context, name, attrs):
152 p_name = attrs.get('name', None)
153 self.p_type_string = attrs.get('type', None)
154 self.p_count_parameters = attrs.get('variable_param', None)
Ian Romanick73f59b02004-05-18 18:33:40 +0000155
Ian Romanickba09c192005-02-01 00:13:04 +0000156 if self.p_count_parameters:
157 temp = self.p_count_parameters.replace( ' ', '' )
158 self.count_parameter_list = temp.split( ',' )
159 else:
160 self.count_parameter_list = []
161
Ian Romanicka9d033c2004-05-19 23:33:08 +0000162 self.p_type = context.context.find_type(self.p_type_string)
163 if self.p_type == None:
164 raise RuntimeError("Unknown type '%s' in function '%s'." % (self.p_type_string, context.name))
165
166
167 # The count tag can be either a numeric string or the name of
168 # a variable. If it is the name of a variable, the int(c)
169 # statement will throw an exception, and the except block will
170 # take over.
171
172 c = attrs.get('count', "0")
Ian Romanick73f59b02004-05-18 18:33:40 +0000173 try:
174 self.p_count = int(c)
Ian Romanicka9d033c2004-05-19 23:33:08 +0000175 self.counter = None
Ian Romanick73f59b02004-05-18 18:33:40 +0000176 except Exception,e:
177 self.p_count = 0
178 self.counter = c
179
Ian Romanicka9d033c2004-05-19 23:33:08 +0000180 if attrs.get('counter', "false") == "true":
181 self.is_counter = 1
182 else:
183 self.is_counter = 0
184
185 if attrs.get('output', "false") == "true":
Ian Romanick73f59b02004-05-18 18:33:40 +0000186 self.is_output = 1
187 else:
188 self.is_output = 0
189
Ian Romanick5f1f2292005-01-07 02:39:09 +0000190
191 # Pixel data has special parameters.
192
193 self.width = attrs.get('img_width', None)
194 self.height = attrs.get('img_height', None)
195 self.depth = attrs.get('img_depth', None)
196 self.extent = attrs.get('img_extent', None)
197
198 self.img_xoff = attrs.get('img_xoff', None)
199 self.img_yoff = attrs.get('img_yoff', None)
200 self.img_zoff = attrs.get('img_zoff', None)
201 self.img_woff = attrs.get('img_woff', None)
202
203 self.img_format = attrs.get('img_format', None)
204 self.img_type = attrs.get('img_type', None)
205 self.img_target = attrs.get('img_target', None)
206
207 pad = attrs.get('img_pad_dimensions', "false")
208 if pad == "true":
209 self.img_pad_dimensions = 1
210 else:
211 self.img_pad_dimensions = 0
212
213
214 null_flag = attrs.get('img_null_flag', "false")
215 if null_flag == "true":
216 self.img_null_flag = 1
217 else:
218 self.img_null_flag = 0
219
220 send_null = attrs.get('img_send_null', "false")
221 if send_null == "true":
222 self.img_send_null = 1
223 else:
224 self.img_send_null = 0
225
226
227
228 if self.p_count > 0 or self.counter or self.p_count_parameters:
Ian Romanick73f59b02004-05-18 18:33:40 +0000229 has_count = 1
230 else:
231 has_count = 0
232
Ian Romanicka9d033c2004-05-19 23:33:08 +0000233
Ian Romanick73f59b02004-05-18 18:33:40 +0000234 # If there is a * anywhere in the parameter's type, then it
235 # is a pointer.
236
Ian Romanicka9d033c2004-05-19 23:33:08 +0000237 if re.compile("[*]").search(self.p_type_string):
Ian Romanick73f59b02004-05-18 18:33:40 +0000238 # We could do some other validation here. For
239 # example, an output parameter should not be const,
240 # but every non-output parameter should.
241
242 self.is_pointer = 1;
243 else:
244 # If a parameter is not a pointer, then there cannot
245 # be an associated count (either fixed size or
246 # variable) and the parameter cannot be an output.
247
248 if has_count or self.is_output:
249 raise RuntimeError("Non-pointer type has count or is output.")
250 self.is_pointer = 0;
251
Ian Romanicka9d033c2004-05-19 23:33:08 +0000252 glItem.__init__(self, name, p_name, context)
253 return
254
255
Ian Romanick73f59b02004-05-18 18:33:40 +0000256 def is_variable_length_array(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000257 """Determine if a parameter is a variable length array.
258
259 A parameter is considered to be a variable length array if
260 its size depends on the value of another parameter that is
261 an enumerant. The params parameter to glTexEnviv is an
262 example of a variable length array parameter. Arrays whose
263 size depends on a count variable, such as the lists parameter
264 to glCallLists, are not variable length arrays in this
265 sense."""
266
Ian Romanick5f1f2292005-01-07 02:39:09 +0000267 return self.p_count_parameters or self.counter or self.width
Ian Romanick73f59b02004-05-18 18:33:40 +0000268
Ian Romanicka9d033c2004-05-19 23:33:08 +0000269
Ian Romanick73f59b02004-05-18 18:33:40 +0000270 def is_array(self):
271 return self.is_pointer
272
Ian Romanicka9d033c2004-05-19 23:33:08 +0000273
Ian Romanick73f59b02004-05-18 18:33:40 +0000274 def count_string(self):
275 """Return a string representing the number of items
276
277 Returns a string representing the number of items in a
278 parameter. For scalar types this will always be "1". For
279 vector types, it will depend on whether or not it is a
280 fixed length vector (like the parameter of glVertex3fv),
281 a counted length (like the vector parameter of
282 glDeleteTextures), or a general variable length vector."""
283
284 if self.is_array():
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000285 if self.p_count_parameters != None:
Ian Romanick73f59b02004-05-18 18:33:40 +0000286 return "compsize"
287 elif self.counter != None:
288 return self.counter
289 else:
290 return str(self.p_count)
291 else:
292 return "1"
293
Ian Romanicka9d033c2004-05-19 23:33:08 +0000294
Ian Romanick73f59b02004-05-18 18:33:40 +0000295 def size(self):
Ian Romanick5f1f2292005-01-07 02:39:09 +0000296 if self.p_count_parameters or self.counter or self.width or self.is_output:
Ian Romanick73f59b02004-05-18 18:33:40 +0000297 return 0
298 elif self.p_count == 0:
299 return self.p_type.size
300 else:
301 return self.p_type.size * self.p_count
302
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000303 def size_string(self):
304 s = self.size()
305 if s == 0:
306 a_prod = "compsize"
307 b_prod = self.p_type.size
308
Ian Romanickba09c192005-02-01 00:13:04 +0000309 # Handle functions like glCompressedTexImage2D that
310 # have a counted 'void *' parameter.
311
312 if b_prod == 0: b_prod = 1
313
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000314 if self.p_count_parameters == None and self.counter != None:
315 a_prod = self.counter
316 elif self.p_count_parameters != None and self.counter == None:
317 pass
318 elif self.p_count_parameters != None and self.counter != None:
319 b_prod = self.counter
Ian Romanick5f1f2292005-01-07 02:39:09 +0000320 elif self.width:
321 return "compsize"
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000322 else:
323 raise RuntimeError("Parameter '%s' to function '%s' has size 0." % (self.name, self.context.name))
324
325 return "(%s * %s)" % (a_prod, b_prod)
326 else:
327 return str(s)
328
Ian Romanicka9d033c2004-05-19 23:33:08 +0000329
Ian Romanick73f59b02004-05-18 18:33:40 +0000330class glParameterIterator:
Ian Romanicka9d033c2004-05-19 23:33:08 +0000331 """Class to iterate over a list of glParameters.
332
Ian Romanick1d270842004-12-21 21:26:36 +0000333 Objects of this class are returned by the parameterIterator method of
334 the glFunction class. They are used to iterate over the list of
Ian Romanicka9d033c2004-05-19 23:33:08 +0000335 parameters to the function."""
336
Ian Romanick73f59b02004-05-18 18:33:40 +0000337 def __init__(self, data):
338 self.data = data
339 self.index = 0
Ian Romanick1d270842004-12-21 21:26:36 +0000340
341 def __iter__(self):
342 return self
343
Ian Romanick73f59b02004-05-18 18:33:40 +0000344 def next(self):
345 if self.index == len( self.data ):
346 raise StopIteration
347 i = self.index
348 self.index += 1
349 return self.data[i]
350
Ian Romanicka9d033c2004-05-19 23:33:08 +0000351
Ian Romanick73f59b02004-05-18 18:33:40 +0000352class glFunction( glItem ):
353 real_name = ""
354 fn_alias = None
355 fn_offset = -1
356 fn_return_type = "void"
357 fn_parameters = []
358
359 def __init__(self, context, name, attrs):
360 self.fn_alias = attrs.get('alias', None)
361 self.fn_parameters = []
Ian Romanick5f1f2292005-01-07 02:39:09 +0000362 self.image = None
Ian Romanickba09c192005-02-01 00:13:04 +0000363 self.count_parameter_list = []
Ian Romanick73f59b02004-05-18 18:33:40 +0000364
365 temp = attrs.get('offset', None)
366 if temp == None or temp == "?":
367 self.fn_offset = -1
368 else:
369 self.fn_offset = int(temp)
370
371 fn_name = attrs.get('name', None)
372 if self.fn_alias != None:
373 self.real_name = self.fn_alias
374 else:
375 self.real_name = fn_name
376
377 glItem.__init__(self, name, fn_name, context)
378 return
379
380
Ian Romanick1d270842004-12-21 21:26:36 +0000381 def parameterIterator(self):
Ian Romanick73f59b02004-05-18 18:33:40 +0000382 return glParameterIterator(self.fn_parameters)
383
384
385 def startElement(self, name, attrs):
386 if name == "param":
Ian Romanick73f59b02004-05-18 18:33:40 +0000387 try:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000388 self.context.factory.create(self, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000389 except RuntimeError:
390 print "Error with parameter '%s' in function '%s'." \
Ian Romanicka9d033c2004-05-19 23:33:08 +0000391 % (attrs.get('name','(unknown)'), self.name)
Ian Romanick73f59b02004-05-18 18:33:40 +0000392 raise
Ian Romanick73f59b02004-05-18 18:33:40 +0000393 elif name == "return":
394 self.set_return_type(attrs.get('type', None))
395
396
Ian Romanicka9d033c2004-05-19 23:33:08 +0000397 def append(self, tag_name, p):
398 if tag_name != "param":
399 raise RuntimeError("Trying to append '%s' to parameter list of function '%s'." % (tag_name, self.name))
400
Ian Romanick5f1f2292005-01-07 02:39:09 +0000401 if p.width:
402 self.image = p
403
Ian Romanick73f59b02004-05-18 18:33:40 +0000404 self.fn_parameters.append(p)
Ian Romanickba09c192005-02-01 00:13:04 +0000405 if p.count_parameter_list != []:
406 self.count_parameter_list.extend( p.count_parameter_list )
Ian Romanick73f59b02004-05-18 18:33:40 +0000407
Ian Romanicka9d033c2004-05-19 23:33:08 +0000408
Ian Romanick73f59b02004-05-18 18:33:40 +0000409 def set_return_type(self, t):
410 self.fn_return_type = t
411
Ian Romanicka9d033c2004-05-19 23:33:08 +0000412
Ian Romanick73f59b02004-05-18 18:33:40 +0000413 def get_parameter_string(self):
414 arg_string = ""
415 comma = ""
Ian Romanick1d270842004-12-21 21:26:36 +0000416 for p in glFunction.parameterIterator(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000417 arg_string = arg_string + comma + p.p_type_string + " " + p.name
Ian Romanick73f59b02004-05-18 18:33:40 +0000418 comma = ", "
419
420 if arg_string == "":
421 arg_string = "void"
422
423 return arg_string
424
425
426class glItemFactory:
427 """Factory to create objects derived from glItem."""
428
429 def create(self, context, name, attrs):
430 if name == "function":
431 return glFunction(context, name, attrs)
432 elif name == "type":
433 return glType(context, name, attrs)
434 elif name == "enum":
435 return glEnum(context, name, attrs)
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000436 elif name == "param":
437 return glParameter(context, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000438 else:
439 return None
440
441
Ian Romanick38e6e092005-01-25 23:53:13 +0000442class glFunctionIterator:
443 """Class to iterate over a list of glFunctions
444
445 Objects of this classare returned by
446 FilterGLAPISpecBase::functionIterator. This default version
447 iterates over the functions in order of dispatch table offset. All
448 of the "true" functions are iterated first, followed by the alias
449 functions."""
450
451 def __init__(self, context):
452 self.context = context
453 self.keys = context.functions.keys()
454 self.keys.sort()
455
456 self.prevk = -1
457 self.direction = 1
458
459 for self.index in range(0, len(self.keys)):
460 if self.keys[ self.index ] >= 0: break
461
462 if self.index == len(self.keys):
463 self.direction = -1
464 self.index -= 1
465
466 self.split = self.index - 1
467 return
468
469
470 def __iter__(self):
471 return self
472
473
474 def next(self):
475 if self.index < 0:
476 raise StopIteration
477
478 k = self.keys[ self.index ]
479
480 #if self.context.functions[k].fn_alias == None:
481 # if k != self.prevk + 1:
482 # print 'Missing offset %d' % (prevk)
483 # self.prevk = int(k)
484
485 self.index += self.direction
486
487 if self.index == len(self.keys):
488 self.index = self.split
489 self.direction = -1
490
491 return self.context.functions[k]
492
493
Ian Romanick73f59b02004-05-18 18:33:40 +0000494class FilterGLAPISpecBase(saxutils.XMLFilterBase):
495 name = "a"
496 license = "The license for this file is unspecified."
497 functions = {}
498 next_alias = -2
499 types = {}
500 xref = {}
501 current_object = None
502 factory = None
503 current_category = ""
504
505 def __init__(self):
506 saxutils.XMLFilterBase.__init__(self)
507 self.functions = {}
508 self.types = {}
509 self.xref = {}
510 self.factory = glItemFactory()
Ian Romanick16c3c742005-01-28 19:00:54 +0000511 self.header_tag = None
Ian Romanickc2803582005-02-01 00:28:47 +0000512 self.undef_list = []
Ian Romanick73f59b02004-05-18 18:33:40 +0000513
Ian Romanicka9d033c2004-05-19 23:33:08 +0000514
Ian Romanick73f59b02004-05-18 18:33:40 +0000515 def find_type(self,type_name):
516 for t in self.types:
517 if re.compile(t).search(type_name):
518 return self.types[t]
519 print "Unable to find base type matching \"%s\"." % (type_name)
520 return None
521
Ian Romanicka9d033c2004-05-19 23:33:08 +0000522
Ian Romanick73f59b02004-05-18 18:33:40 +0000523 def find_function(self,function_name):
524 index = self.xref[function_name]
525 return self.functions[index]
526
Ian Romanicka9d033c2004-05-19 23:33:08 +0000527
Ian Romanick38e6e092005-01-25 23:53:13 +0000528 def functionIterator(self):
529 return glFunctionIterator(self)
530
531
Ian Romanick73f59b02004-05-18 18:33:40 +0000532 def printFunctions(self):
Ian Romanick38e6e092005-01-25 23:53:13 +0000533 for f in self.functionIterator():
534 self.printFunction(f)
Ian Romanick73f59b02004-05-18 18:33:40 +0000535 return
536
Ian Romanicka9d033c2004-05-19 23:33:08 +0000537
Ian Romanick73f59b02004-05-18 18:33:40 +0000538 def printHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000539 """Print the header associated with all files and call the printRealHeader method."""
540
Ian Romanick73f59b02004-05-18 18:33:40 +0000541 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
542 % (self.name)
543 print ''
544 print '/*'
545 print ' * ' + self.license.replace('\n', '\n * ')
546 print ' */'
547 print ''
Ian Romanick16c3c742005-01-28 19:00:54 +0000548 if self.header_tag:
549 print '#if !defined( %s )' % (self.header_tag)
550 print '# define %s' % (self.header_tag)
551 print ''
Ian Romanick73f59b02004-05-18 18:33:40 +0000552 self.printRealHeader();
553 return
554
Ian Romanicka9d033c2004-05-19 23:33:08 +0000555
Ian Romanick73f59b02004-05-18 18:33:40 +0000556 def printFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000557 """Print the header associated with all files and call the printRealFooter method."""
558
Ian Romanick73f59b02004-05-18 18:33:40 +0000559 self.printFunctions()
560 self.printRealFooter()
Ian Romanick16c3c742005-01-28 19:00:54 +0000561 if self.header_tag:
Ian Romanickc2803582005-02-01 00:28:47 +0000562 if self.undef_list:
563 print ''
564 for u in self.undef_list:
565 print "# undef %s" % (u)
566 print ''
567 print '#endif /* !defined( %s ) */' % (self.header_tag)
Ian Romanick73f59b02004-05-18 18:33:40 +0000568
569
570 def get_category_define(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000571 """Convert the category name to the #define that would be found in glext.h"""
572
Ian Romanick73f59b02004-05-18 18:33:40 +0000573 if re.compile("[1-9][0-9]*[.][0-9]+").match(self.current_category):
574 s = self.current_category
575 return "GL_VERSION_" + s.replace(".", "_")
576 else:
577 return self.current_category
578
579
580 def append(self, object_type, obj):
581 if object_type == "function":
582 # If the function is not an alias and has a negative
583 # offset, then we do not need to track it. These are
584 # functions that don't have an assigned offset
585
586 if obj.fn_offset >= 0 or obj.fn_alias != None:
587 if obj.fn_offset >= 0:
588 index = obj.fn_offset
589 else:
590 index = self.next_alias
591 self.next_alias -= 1
592
593 self.functions[index] = obj
594 self.xref[obj.name] = index
595 elif object_type == "type":
596 self.types[obj.name] = obj
597
598 return
599
600
601 def startElement(self, name, attrs):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000602 """Start a new element in the XML stream.
603
604 Starts a new element. There are three types of elements that
605 are specially handled by this function. When a "category"
606 element is encountered, the name of the category is saved.
607 If an element is encountered and no API object is
608 in-progress, a new object is created using the API factory.
609 Any future elements, until that API object is closed, are
610 passed to the current objects startElement method.
611
612 This paradigm was chosen becuase it allows subclasses of the
613 basic API types (i.e., glFunction, glEnum, etc.) to handle
614 additional XML data, GLX protocol information, that the base
615 classes do not know about."""
616
Ian Romanick73f59b02004-05-18 18:33:40 +0000617 if self.current_object != None:
618 self.current_object.startElement(name, attrs)
619 elif name == "category":
620 self.current_category = attrs.get('name', "")
621 else:
622 self.current_object = self.factory.create(self, name, attrs)
623 return
624
Ian Romanicka9d033c2004-05-19 23:33:08 +0000625
Ian Romanick73f59b02004-05-18 18:33:40 +0000626 def endElement(self, name):
627 if self.current_object != None:
628 if self.current_object.endElement(name):
629 self.current_object = None
630 return
631
Ian Romanicka9d033c2004-05-19 23:33:08 +0000632
Ian Romanickc2803582005-02-01 00:28:47 +0000633 def printPure(self):
634 self.undef_list.append("PURE")
635 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
636# define PURE __attribute__((pure))
637# else
638# define PURE
639# endif"""
640
641 def printFastcall(self):
642 self.undef_list.append("FASTCALL")
643 print """# if defined(__i386__) && defined(__GNUC__)
644# define FASTCALL __attribute__((fastcall))
645# else
646# define FASTCALL
647# endif"""
648
649 def printVisibility(self, S, s):
650 self.undef_list.append(S)
651 print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
652# define %s __attribute__((visibility("%s")))
653# else
654# define %s
655# endif""" % (S, s, S)
656
657 def printNoinline(self):
658 self.undef_list.append("NOINLINE")
659 print """# if defined(__GNUC__)
660# define NOINLINE __attribute__((noinline))
661# else
662# define NOINLINE
663# endif"""
664
665 def printHaveAlias(self):
666 self.undef_list.append("HAVE_ALIAS")
667 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
668# define HAVE_ALIAS
669# endif"""
670
Ian Romanick73f59b02004-05-18 18:33:40 +0000671 def printFunction(self,offset):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000672 """Print a single function.
673
674 In the base class, this function is empty. All derived
675 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000676 return
677
Ian Romanicka9d033c2004-05-19 23:33:08 +0000678
Ian Romanick73f59b02004-05-18 18:33:40 +0000679 def printRealHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000680 """Print the "real" header for the created file.
681
682 In the base class, this function is empty. All derived
683 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000684 return
685
Ian Romanicka9d033c2004-05-19 23:33:08 +0000686
Ian Romanick73f59b02004-05-18 18:33:40 +0000687 def printRealFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000688 """Print the "real" footer for the created file.
689
690 In the base class, this function is empty. All derived
691 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000692 return