blob: a24a8450a1f78bb27ba054670780880c2a99ced7 [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
Ian Romanick73f59b02004-05-18 18:33:40 +0000145 counter = None
146 is_output = 0
147 is_counter = 0
148 is_pointer = 0
149
Ian Romanicka9d033c2004-05-19 23:33:08 +0000150 def __init__(self, context, name, attrs):
151 p_name = attrs.get('name', None)
152 self.p_type_string = attrs.get('type', None)
Ian Romanick73f59b02004-05-18 18:33:40 +0000153
Ian Romanick3fec8c22005-02-02 00:54:45 +0000154 temp = attrs.get('variable_param', None)
155 if temp:
156 self.count_parameter_list = temp.replace( ' ', '' ).split( ',' )
Ian Romanickba09c192005-02-01 00:13:04 +0000157 else:
158 self.count_parameter_list = []
159
Ian Romanicka9d033c2004-05-19 23:33:08 +0000160 self.p_type = context.context.find_type(self.p_type_string)
161 if self.p_type == None:
162 raise RuntimeError("Unknown type '%s' in function '%s'." % (self.p_type_string, context.name))
163
164
165 # The count tag can be either a numeric string or the name of
166 # a variable. If it is the name of a variable, the int(c)
167 # statement will throw an exception, and the except block will
168 # take over.
169
170 c = attrs.get('count', "0")
Ian Romanick73f59b02004-05-18 18:33:40 +0000171 try:
172 self.p_count = int(c)
Ian Romanicka9d033c2004-05-19 23:33:08 +0000173 self.counter = None
Ian Romanick73f59b02004-05-18 18:33:40 +0000174 except Exception,e:
175 self.p_count = 0
176 self.counter = c
177
Ian Romanicka9d033c2004-05-19 23:33:08 +0000178 if attrs.get('counter', "false") == "true":
179 self.is_counter = 1
180 else:
181 self.is_counter = 0
182
183 if attrs.get('output', "false") == "true":
Ian Romanick73f59b02004-05-18 18:33:40 +0000184 self.is_output = 1
185 else:
186 self.is_output = 0
187
Ian Romanick5f1f2292005-01-07 02:39:09 +0000188
189 # Pixel data has special parameters.
190
191 self.width = attrs.get('img_width', None)
192 self.height = attrs.get('img_height', None)
193 self.depth = attrs.get('img_depth', None)
194 self.extent = attrs.get('img_extent', None)
195
196 self.img_xoff = attrs.get('img_xoff', None)
197 self.img_yoff = attrs.get('img_yoff', None)
198 self.img_zoff = attrs.get('img_zoff', None)
199 self.img_woff = attrs.get('img_woff', None)
200
201 self.img_format = attrs.get('img_format', None)
202 self.img_type = attrs.get('img_type', None)
203 self.img_target = attrs.get('img_target', None)
204
205 pad = attrs.get('img_pad_dimensions', "false")
206 if pad == "true":
207 self.img_pad_dimensions = 1
208 else:
209 self.img_pad_dimensions = 0
210
211
212 null_flag = attrs.get('img_null_flag', "false")
213 if null_flag == "true":
214 self.img_null_flag = 1
215 else:
216 self.img_null_flag = 0
217
218 send_null = attrs.get('img_send_null', "false")
219 if send_null == "true":
220 self.img_send_null = 1
221 else:
222 self.img_send_null = 0
223
224
225
Ian Romanick3fec8c22005-02-02 00:54:45 +0000226 if self.p_count > 0 or self.counter or self.count_parameter_list:
Ian Romanick73f59b02004-05-18 18:33:40 +0000227 has_count = 1
228 else:
229 has_count = 0
230
Ian Romanicka9d033c2004-05-19 23:33:08 +0000231
Ian Romanick73f59b02004-05-18 18:33:40 +0000232 # If there is a * anywhere in the parameter's type, then it
233 # is a pointer.
234
Ian Romanicka9d033c2004-05-19 23:33:08 +0000235 if re.compile("[*]").search(self.p_type_string):
Ian Romanick73f59b02004-05-18 18:33:40 +0000236 # We could do some other validation here. For
237 # example, an output parameter should not be const,
238 # but every non-output parameter should.
239
240 self.is_pointer = 1;
241 else:
242 # If a parameter is not a pointer, then there cannot
243 # be an associated count (either fixed size or
244 # variable) and the parameter cannot be an output.
245
246 if has_count or self.is_output:
247 raise RuntimeError("Non-pointer type has count or is output.")
248 self.is_pointer = 0;
249
Ian Romanicka9d033c2004-05-19 23:33:08 +0000250 glItem.__init__(self, name, p_name, context)
251 return
252
253
Ian Romanick73f59b02004-05-18 18:33:40 +0000254 def is_variable_length_array(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000255 """Determine if a parameter is a variable length array.
256
257 A parameter is considered to be a variable length array if
258 its size depends on the value of another parameter that is
259 an enumerant. The params parameter to glTexEnviv is an
260 example of a variable length array parameter. Arrays whose
261 size depends on a count variable, such as the lists parameter
262 to glCallLists, are not variable length arrays in this
263 sense."""
264
Ian Romanick3fec8c22005-02-02 00:54:45 +0000265 return self.count_parameter_list or self.counter or self.width
Ian Romanick73f59b02004-05-18 18:33:40 +0000266
Ian Romanicka9d033c2004-05-19 23:33:08 +0000267
Ian Romanick73f59b02004-05-18 18:33:40 +0000268 def is_array(self):
269 return self.is_pointer
270
Ian Romanicka9d033c2004-05-19 23:33:08 +0000271
Ian Romanick73f59b02004-05-18 18:33:40 +0000272 def count_string(self):
273 """Return a string representing the number of items
274
275 Returns a string representing the number of items in a
276 parameter. For scalar types this will always be "1". For
277 vector types, it will depend on whether or not it is a
278 fixed length vector (like the parameter of glVertex3fv),
279 a counted length (like the vector parameter of
280 glDeleteTextures), or a general variable length vector."""
281
282 if self.is_array():
Ian Romanick3fec8c22005-02-02 00:54:45 +0000283 if self.count_parameter_list:
Ian Romanick73f59b02004-05-18 18:33:40 +0000284 return "compsize"
285 elif self.counter != None:
286 return self.counter
287 else:
288 return str(self.p_count)
289 else:
290 return "1"
291
Ian Romanicka9d033c2004-05-19 23:33:08 +0000292
Ian Romanick73f59b02004-05-18 18:33:40 +0000293 def size(self):
Ian Romanick3fec8c22005-02-02 00:54:45 +0000294 if self.count_parameter_list or self.counter or self.width or self.is_output:
Ian Romanick73f59b02004-05-18 18:33:40 +0000295 return 0
296 elif self.p_count == 0:
297 return self.p_type.size
298 else:
299 return self.p_type.size * self.p_count
300
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000301 def size_string(self):
302 s = self.size()
303 if s == 0:
304 a_prod = "compsize"
305 b_prod = self.p_type.size
306
Ian Romanickba09c192005-02-01 00:13:04 +0000307 # Handle functions like glCompressedTexImage2D that
308 # have a counted 'void *' parameter.
309
310 if b_prod == 0: b_prod = 1
311
Ian Romanick3fec8c22005-02-02 00:54:45 +0000312 if not self.count_parameter_list and self.counter != None:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000313 a_prod = self.counter
Ian Romanick3fec8c22005-02-02 00:54:45 +0000314 elif self.count_parameter_list and self.counter == None:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000315 pass
Ian Romanick3fec8c22005-02-02 00:54:45 +0000316 elif self.count_parameter_list and self.counter != None:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000317 b_prod = self.counter
Ian Romanick5f1f2292005-01-07 02:39:09 +0000318 elif self.width:
319 return "compsize"
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000320 else:
321 raise RuntimeError("Parameter '%s' to function '%s' has size 0." % (self.name, self.context.name))
322
323 return "(%s * %s)" % (a_prod, b_prod)
324 else:
325 return str(s)
326
Ian Romanicka9d033c2004-05-19 23:33:08 +0000327
Ian Romanick73f59b02004-05-18 18:33:40 +0000328class glParameterIterator:
Ian Romanicka9d033c2004-05-19 23:33:08 +0000329 """Class to iterate over a list of glParameters.
330
Ian Romanick1d270842004-12-21 21:26:36 +0000331 Objects of this class are returned by the parameterIterator method of
332 the glFunction class. They are used to iterate over the list of
Ian Romanicka9d033c2004-05-19 23:33:08 +0000333 parameters to the function."""
334
Ian Romanick73f59b02004-05-18 18:33:40 +0000335 def __init__(self, data):
336 self.data = data
337 self.index = 0
Ian Romanick1d270842004-12-21 21:26:36 +0000338
339 def __iter__(self):
340 return self
341
Ian Romanick73f59b02004-05-18 18:33:40 +0000342 def next(self):
343 if self.index == len( self.data ):
344 raise StopIteration
345 i = self.index
346 self.index += 1
347 return self.data[i]
348
Ian Romanicka9d033c2004-05-19 23:33:08 +0000349
Ian Romanick73f59b02004-05-18 18:33:40 +0000350class glFunction( glItem ):
Ian Romanick73f59b02004-05-18 18:33:40 +0000351 def __init__(self, context, name, attrs):
352 self.fn_alias = attrs.get('alias', None)
353 self.fn_parameters = []
Ian Romanick5f1f2292005-01-07 02:39:09 +0000354 self.image = None
Ian Romanickba09c192005-02-01 00:13:04 +0000355 self.count_parameter_list = []
Ian Romanick3fec8c22005-02-02 00:54:45 +0000356 self.fn_return_type = "void"
Ian Romanick73f59b02004-05-18 18:33:40 +0000357
358 temp = attrs.get('offset', None)
359 if temp == None or temp == "?":
360 self.fn_offset = -1
361 else:
362 self.fn_offset = int(temp)
363
364 fn_name = attrs.get('name', None)
365 if self.fn_alias != None:
366 self.real_name = self.fn_alias
367 else:
368 self.real_name = fn_name
369
370 glItem.__init__(self, name, fn_name, context)
371 return
372
373
Ian Romanick1d270842004-12-21 21:26:36 +0000374 def parameterIterator(self):
Ian Romanick73f59b02004-05-18 18:33:40 +0000375 return glParameterIterator(self.fn_parameters)
376
377
378 def startElement(self, name, attrs):
379 if name == "param":
Ian Romanick73f59b02004-05-18 18:33:40 +0000380 try:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000381 self.context.factory.create(self, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000382 except RuntimeError:
383 print "Error with parameter '%s' in function '%s'." \
Ian Romanicka9d033c2004-05-19 23:33:08 +0000384 % (attrs.get('name','(unknown)'), self.name)
Ian Romanick73f59b02004-05-18 18:33:40 +0000385 raise
Ian Romanick73f59b02004-05-18 18:33:40 +0000386 elif name == "return":
387 self.set_return_type(attrs.get('type', None))
388
389
Ian Romanicka9d033c2004-05-19 23:33:08 +0000390 def append(self, tag_name, p):
391 if tag_name != "param":
392 raise RuntimeError("Trying to append '%s' to parameter list of function '%s'." % (tag_name, self.name))
393
Ian Romanick5f1f2292005-01-07 02:39:09 +0000394 if p.width:
395 self.image = p
396
Ian Romanick73f59b02004-05-18 18:33:40 +0000397 self.fn_parameters.append(p)
Ian Romanickba09c192005-02-01 00:13:04 +0000398 if p.count_parameter_list != []:
399 self.count_parameter_list.extend( p.count_parameter_list )
Ian Romanick73f59b02004-05-18 18:33:40 +0000400
Ian Romanicka9d033c2004-05-19 23:33:08 +0000401
Ian Romanick73f59b02004-05-18 18:33:40 +0000402 def set_return_type(self, t):
403 self.fn_return_type = t
404
Ian Romanicka9d033c2004-05-19 23:33:08 +0000405
Ian Romanick73f59b02004-05-18 18:33:40 +0000406 def get_parameter_string(self):
407 arg_string = ""
408 comma = ""
Ian Romanick1d270842004-12-21 21:26:36 +0000409 for p in glFunction.parameterIterator(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000410 arg_string = arg_string + comma + p.p_type_string + " " + p.name
Ian Romanick73f59b02004-05-18 18:33:40 +0000411 comma = ", "
412
413 if arg_string == "":
414 arg_string = "void"
415
416 return arg_string
417
418
419class glItemFactory:
420 """Factory to create objects derived from glItem."""
421
422 def create(self, context, name, attrs):
423 if name == "function":
424 return glFunction(context, name, attrs)
425 elif name == "type":
426 return glType(context, name, attrs)
427 elif name == "enum":
428 return glEnum(context, name, attrs)
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000429 elif name == "param":
430 return glParameter(context, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000431 else:
432 return None
433
434
Ian Romanick38e6e092005-01-25 23:53:13 +0000435class glFunctionIterator:
436 """Class to iterate over a list of glFunctions
437
438 Objects of this classare returned by
439 FilterGLAPISpecBase::functionIterator. This default version
440 iterates over the functions in order of dispatch table offset. All
441 of the "true" functions are iterated first, followed by the alias
442 functions."""
443
444 def __init__(self, context):
445 self.context = context
446 self.keys = context.functions.keys()
447 self.keys.sort()
448
449 self.prevk = -1
450 self.direction = 1
451
452 for self.index in range(0, len(self.keys)):
453 if self.keys[ self.index ] >= 0: break
454
455 if self.index == len(self.keys):
456 self.direction = -1
457 self.index -= 1
458
459 self.split = self.index - 1
460 return
461
462
463 def __iter__(self):
464 return self
465
466
467 def next(self):
468 if self.index < 0:
469 raise StopIteration
470
471 k = self.keys[ self.index ]
472
473 #if self.context.functions[k].fn_alias == None:
474 # if k != self.prevk + 1:
475 # print 'Missing offset %d' % (prevk)
476 # self.prevk = int(k)
477
478 self.index += self.direction
479
480 if self.index == len(self.keys):
481 self.index = self.split
482 self.direction = -1
483
484 return self.context.functions[k]
485
486
Ian Romanick73f59b02004-05-18 18:33:40 +0000487class FilterGLAPISpecBase(saxutils.XMLFilterBase):
488 name = "a"
489 license = "The license for this file is unspecified."
490 functions = {}
491 next_alias = -2
492 types = {}
493 xref = {}
494 current_object = None
495 factory = None
496 current_category = ""
497
498 def __init__(self):
499 saxutils.XMLFilterBase.__init__(self)
500 self.functions = {}
501 self.types = {}
502 self.xref = {}
503 self.factory = glItemFactory()
Ian Romanick16c3c742005-01-28 19:00:54 +0000504 self.header_tag = None
Ian Romanickc2803582005-02-01 00:28:47 +0000505 self.undef_list = []
Ian Romanick73f59b02004-05-18 18:33:40 +0000506
Ian Romanicka9d033c2004-05-19 23:33:08 +0000507
Ian Romanick73f59b02004-05-18 18:33:40 +0000508 def find_type(self,type_name):
509 for t in self.types:
510 if re.compile(t).search(type_name):
511 return self.types[t]
512 print "Unable to find base type matching \"%s\"." % (type_name)
513 return None
514
Ian Romanicka9d033c2004-05-19 23:33:08 +0000515
Ian Romanick73f59b02004-05-18 18:33:40 +0000516 def find_function(self,function_name):
517 index = self.xref[function_name]
518 return self.functions[index]
519
Ian Romanicka9d033c2004-05-19 23:33:08 +0000520
Ian Romanick38e6e092005-01-25 23:53:13 +0000521 def functionIterator(self):
522 return glFunctionIterator(self)
523
524
Ian Romanick73f59b02004-05-18 18:33:40 +0000525 def printFunctions(self):
Ian Romanick38e6e092005-01-25 23:53:13 +0000526 for f in self.functionIterator():
527 self.printFunction(f)
Ian Romanick73f59b02004-05-18 18:33:40 +0000528 return
529
Ian Romanicka9d033c2004-05-19 23:33:08 +0000530
Ian Romanick73f59b02004-05-18 18:33:40 +0000531 def printHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000532 """Print the header associated with all files and call the printRealHeader method."""
533
Ian Romanick73f59b02004-05-18 18:33:40 +0000534 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
535 % (self.name)
536 print ''
537 print '/*'
538 print ' * ' + self.license.replace('\n', '\n * ')
539 print ' */'
540 print ''
Ian Romanick16c3c742005-01-28 19:00:54 +0000541 if self.header_tag:
542 print '#if !defined( %s )' % (self.header_tag)
543 print '# define %s' % (self.header_tag)
544 print ''
Ian Romanick73f59b02004-05-18 18:33:40 +0000545 self.printRealHeader();
546 return
547
Ian Romanicka9d033c2004-05-19 23:33:08 +0000548
Ian Romanick73f59b02004-05-18 18:33:40 +0000549 def printFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000550 """Print the header associated with all files and call the printRealFooter method."""
551
Ian Romanick73f59b02004-05-18 18:33:40 +0000552 self.printFunctions()
553 self.printRealFooter()
Ian Romanick16c3c742005-01-28 19:00:54 +0000554 if self.header_tag:
Ian Romanickc2803582005-02-01 00:28:47 +0000555 if self.undef_list:
556 print ''
557 for u in self.undef_list:
558 print "# undef %s" % (u)
559 print ''
560 print '#endif /* !defined( %s ) */' % (self.header_tag)
Ian Romanick73f59b02004-05-18 18:33:40 +0000561
562
563 def get_category_define(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000564 """Convert the category name to the #define that would be found in glext.h"""
565
Ian Romanick73f59b02004-05-18 18:33:40 +0000566 if re.compile("[1-9][0-9]*[.][0-9]+").match(self.current_category):
567 s = self.current_category
568 return "GL_VERSION_" + s.replace(".", "_")
569 else:
570 return self.current_category
571
572
573 def append(self, object_type, obj):
574 if object_type == "function":
575 # If the function is not an alias and has a negative
576 # offset, then we do not need to track it. These are
577 # functions that don't have an assigned offset
578
579 if obj.fn_offset >= 0 or obj.fn_alias != None:
580 if obj.fn_offset >= 0:
581 index = obj.fn_offset
582 else:
583 index = self.next_alias
584 self.next_alias -= 1
585
586 self.functions[index] = obj
587 self.xref[obj.name] = index
588 elif object_type == "type":
589 self.types[obj.name] = obj
590
591 return
592
593
594 def startElement(self, name, attrs):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000595 """Start a new element in the XML stream.
596
597 Starts a new element. There are three types of elements that
598 are specially handled by this function. When a "category"
599 element is encountered, the name of the category is saved.
600 If an element is encountered and no API object is
601 in-progress, a new object is created using the API factory.
602 Any future elements, until that API object is closed, are
603 passed to the current objects startElement method.
604
605 This paradigm was chosen becuase it allows subclasses of the
606 basic API types (i.e., glFunction, glEnum, etc.) to handle
607 additional XML data, GLX protocol information, that the base
608 classes do not know about."""
609
Ian Romanick73f59b02004-05-18 18:33:40 +0000610 if self.current_object != None:
611 self.current_object.startElement(name, attrs)
612 elif name == "category":
613 self.current_category = attrs.get('name', "")
614 else:
615 self.current_object = self.factory.create(self, name, attrs)
616 return
617
Ian Romanicka9d033c2004-05-19 23:33:08 +0000618
Ian Romanick73f59b02004-05-18 18:33:40 +0000619 def endElement(self, name):
620 if self.current_object != None:
621 if self.current_object.endElement(name):
622 self.current_object = None
623 return
624
Ian Romanicka9d033c2004-05-19 23:33:08 +0000625
Ian Romanickc2803582005-02-01 00:28:47 +0000626 def printPure(self):
627 self.undef_list.append("PURE")
628 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
629# define PURE __attribute__((pure))
630# else
631# define PURE
632# endif"""
633
634 def printFastcall(self):
635 self.undef_list.append("FASTCALL")
636 print """# if defined(__i386__) && defined(__GNUC__)
637# define FASTCALL __attribute__((fastcall))
638# else
639# define FASTCALL
640# endif"""
641
642 def printVisibility(self, S, s):
643 self.undef_list.append(S)
644 print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
645# define %s __attribute__((visibility("%s")))
646# else
647# define %s
648# endif""" % (S, s, S)
649
650 def printNoinline(self):
651 self.undef_list.append("NOINLINE")
652 print """# if defined(__GNUC__)
653# define NOINLINE __attribute__((noinline))
654# else
655# define NOINLINE
656# endif"""
657
658 def printHaveAlias(self):
659 self.undef_list.append("HAVE_ALIAS")
660 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
661# define HAVE_ALIAS
662# endif"""
663
Ian Romanick73f59b02004-05-18 18:33:40 +0000664 def printFunction(self,offset):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000665 """Print a single function.
666
667 In the base class, this function is empty. All derived
668 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000669 return
670
Ian Romanicka9d033c2004-05-19 23:33:08 +0000671
Ian Romanick73f59b02004-05-18 18:33:40 +0000672 def printRealHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000673 """Print the "real" header for the created file.
674
675 In the base class, this function is empty. All derived
676 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000677 return
678
Ian Romanicka9d033c2004-05-19 23:33:08 +0000679
Ian Romanick73f59b02004-05-18 18:33:40 +0000680 def printRealFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000681 """Print the "real" footer for the created file.
682
683 In the base class, this function is empty. All derived
684 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000685 return