blob: 03aa982ac283c91bef79af42ea8015c776913ecd [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
Ian Romanickce77d372005-03-03 21:21:59 +0000370 self.parameters_by_name = {}
371 self.variable_length_parameters = []
372
Ian Romanick73f59b02004-05-18 18:33:40 +0000373 glItem.__init__(self, name, fn_name, context)
374 return
375
376
Ian Romanick1d270842004-12-21 21:26:36 +0000377 def parameterIterator(self):
Ian Romanick73f59b02004-05-18 18:33:40 +0000378 return glParameterIterator(self.fn_parameters)
379
380
381 def startElement(self, name, attrs):
382 if name == "param":
Ian Romanick73f59b02004-05-18 18:33:40 +0000383 try:
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000384 self.context.factory.create(self, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000385 except RuntimeError:
386 print "Error with parameter '%s' in function '%s'." \
Ian Romanicka9d033c2004-05-19 23:33:08 +0000387 % (attrs.get('name','(unknown)'), self.name)
Ian Romanick73f59b02004-05-18 18:33:40 +0000388 raise
Ian Romanick73f59b02004-05-18 18:33:40 +0000389 elif name == "return":
390 self.set_return_type(attrs.get('type', None))
391
392
Ian Romanickce77d372005-03-03 21:21:59 +0000393 def endElement(self, name):
394 """Handle the end of a <function> element.
395
396 At the end of a <function> element, there is some semantic
397 checking that can be done. This prevents some possible
398 exceptions from being thrown elsewhere in the code.
399 """
400
401 if name == "function":
402 for p in self.variable_length_parameters:
403 if p.counter:
404 counter = self.parameters_by_name[ p.counter ]
405 if not self.parameters_by_name.has_key( p.counter ):
406 raise RuntimeError("Parameter '%s' of function '%s' has counter '%s', but function has no such parameter." % (p.name, self.name, p.counter))
407 elif not self.parameters_by_name[ p.counter ].is_counter:
408 raise RuntimeError("Parameter '%s' of function '%s' has counter '%s', but '%s' is not marked as a counter." % (p.name, self.name, p.counter, p.counter))
409
410 for n in p.count_parameter_list:
411 if not self.parameters_by_name.has_key( n ):
412 raise RuntimeError("Parameter '%s' of function '%s' has size parameter '%s', but function has no such parameter." % (p.name, self.name, n))
413
414 return 1
415 else:
416 return 0
417
418
Ian Romanicka9d033c2004-05-19 23:33:08 +0000419 def append(self, tag_name, p):
420 if tag_name != "param":
421 raise RuntimeError("Trying to append '%s' to parameter list of function '%s'." % (tag_name, self.name))
422
Ian Romanick5f1f2292005-01-07 02:39:09 +0000423 if p.width:
424 self.image = p
425
Ian Romanick73f59b02004-05-18 18:33:40 +0000426 self.fn_parameters.append(p)
Ian Romanickba09c192005-02-01 00:13:04 +0000427 if p.count_parameter_list != []:
428 self.count_parameter_list.extend( p.count_parameter_list )
Ian Romanick73f59b02004-05-18 18:33:40 +0000429
Ian Romanickce77d372005-03-03 21:21:59 +0000430 if p.is_variable_length_array():
431 self.variable_length_parameters.append(p)
432
433 self.parameters_by_name[ p.name ] = p
434
Ian Romanicka9d033c2004-05-19 23:33:08 +0000435
Ian Romanick73f59b02004-05-18 18:33:40 +0000436 def set_return_type(self, t):
437 self.fn_return_type = t
438
Ian Romanicka9d033c2004-05-19 23:33:08 +0000439
Ian Romanick73f59b02004-05-18 18:33:40 +0000440 def get_parameter_string(self):
441 arg_string = ""
442 comma = ""
Ian Romanick1d270842004-12-21 21:26:36 +0000443 for p in glFunction.parameterIterator(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000444 arg_string = arg_string + comma + p.p_type_string + " " + p.name
Ian Romanick73f59b02004-05-18 18:33:40 +0000445 comma = ", "
446
447 if arg_string == "":
448 arg_string = "void"
449
450 return arg_string
451
452
453class glItemFactory:
454 """Factory to create objects derived from glItem."""
455
456 def create(self, context, name, attrs):
457 if name == "function":
458 return glFunction(context, name, attrs)
459 elif name == "type":
460 return glType(context, name, attrs)
461 elif name == "enum":
462 return glEnum(context, name, attrs)
Ian Romanick4f0a75e2004-12-01 00:29:48 +0000463 elif name == "param":
464 return glParameter(context, name, attrs)
Ian Romanick73f59b02004-05-18 18:33:40 +0000465 else:
466 return None
467
468
Ian Romanick38e6e092005-01-25 23:53:13 +0000469class glFunctionIterator:
470 """Class to iterate over a list of glFunctions
471
472 Objects of this classare returned by
473 FilterGLAPISpecBase::functionIterator. This default version
474 iterates over the functions in order of dispatch table offset. All
475 of the "true" functions are iterated first, followed by the alias
476 functions."""
477
478 def __init__(self, context):
479 self.context = context
480 self.keys = context.functions.keys()
481 self.keys.sort()
482
483 self.prevk = -1
484 self.direction = 1
485
486 for self.index in range(0, len(self.keys)):
487 if self.keys[ self.index ] >= 0: break
488
489 if self.index == len(self.keys):
490 self.direction = -1
491 self.index -= 1
492
493 self.split = self.index - 1
494 return
495
496
497 def __iter__(self):
498 return self
499
500
501 def next(self):
502 if self.index < 0:
503 raise StopIteration
504
505 k = self.keys[ self.index ]
506
507 #if self.context.functions[k].fn_alias == None:
508 # if k != self.prevk + 1:
509 # print 'Missing offset %d' % (prevk)
510 # self.prevk = int(k)
511
512 self.index += self.direction
513
514 if self.index == len(self.keys):
515 self.index = self.split
516 self.direction = -1
517
518 return self.context.functions[k]
519
520
Ian Romanick73f59b02004-05-18 18:33:40 +0000521class FilterGLAPISpecBase(saxutils.XMLFilterBase):
522 name = "a"
523 license = "The license for this file is unspecified."
524 functions = {}
525 next_alias = -2
526 types = {}
527 xref = {}
528 current_object = None
529 factory = None
530 current_category = ""
531
532 def __init__(self):
533 saxutils.XMLFilterBase.__init__(self)
534 self.functions = {}
535 self.types = {}
536 self.xref = {}
537 self.factory = glItemFactory()
Ian Romanick16c3c742005-01-28 19:00:54 +0000538 self.header_tag = None
Ian Romanickc2803582005-02-01 00:28:47 +0000539 self.undef_list = []
Ian Romanick73f59b02004-05-18 18:33:40 +0000540
Ian Romanicka9d033c2004-05-19 23:33:08 +0000541
Ian Romanick73f59b02004-05-18 18:33:40 +0000542 def find_type(self,type_name):
543 for t in self.types:
544 if re.compile(t).search(type_name):
545 return self.types[t]
546 print "Unable to find base type matching \"%s\"." % (type_name)
547 return None
548
Ian Romanicka9d033c2004-05-19 23:33:08 +0000549
Ian Romanick73f59b02004-05-18 18:33:40 +0000550 def find_function(self,function_name):
551 index = self.xref[function_name]
552 return self.functions[index]
553
Ian Romanicka9d033c2004-05-19 23:33:08 +0000554
Ian Romanick38e6e092005-01-25 23:53:13 +0000555 def functionIterator(self):
556 return glFunctionIterator(self)
557
558
Ian Romanick73f59b02004-05-18 18:33:40 +0000559 def printFunctions(self):
Ian Romanick38e6e092005-01-25 23:53:13 +0000560 for f in self.functionIterator():
561 self.printFunction(f)
Ian Romanick73f59b02004-05-18 18:33:40 +0000562 return
563
Ian Romanicka9d033c2004-05-19 23:33:08 +0000564
Ian Romanick73f59b02004-05-18 18:33:40 +0000565 def printHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000566 """Print the header associated with all files and call the printRealHeader method."""
567
Ian Romanick73f59b02004-05-18 18:33:40 +0000568 print '/* DO NOT EDIT - This file generated automatically by %s script */' \
569 % (self.name)
570 print ''
571 print '/*'
572 print ' * ' + self.license.replace('\n', '\n * ')
573 print ' */'
574 print ''
Ian Romanick16c3c742005-01-28 19:00:54 +0000575 if self.header_tag:
576 print '#if !defined( %s )' % (self.header_tag)
577 print '# define %s' % (self.header_tag)
578 print ''
Ian Romanick73f59b02004-05-18 18:33:40 +0000579 self.printRealHeader();
580 return
581
Ian Romanicka9d033c2004-05-19 23:33:08 +0000582
Ian Romanick73f59b02004-05-18 18:33:40 +0000583 def printFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000584 """Print the header associated with all files and call the printRealFooter method."""
585
Ian Romanick73f59b02004-05-18 18:33:40 +0000586 self.printFunctions()
587 self.printRealFooter()
Ian Romanick16c3c742005-01-28 19:00:54 +0000588 if self.header_tag:
Ian Romanickc2803582005-02-01 00:28:47 +0000589 if self.undef_list:
590 print ''
591 for u in self.undef_list:
592 print "# undef %s" % (u)
593 print ''
594 print '#endif /* !defined( %s ) */' % (self.header_tag)
Ian Romanick73f59b02004-05-18 18:33:40 +0000595
596
597 def get_category_define(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000598 """Convert the category name to the #define that would be found in glext.h"""
599
Ian Romanick73f59b02004-05-18 18:33:40 +0000600 if re.compile("[1-9][0-9]*[.][0-9]+").match(self.current_category):
601 s = self.current_category
602 return "GL_VERSION_" + s.replace(".", "_")
603 else:
604 return self.current_category
605
606
607 def append(self, object_type, obj):
608 if object_type == "function":
609 # If the function is not an alias and has a negative
610 # offset, then we do not need to track it. These are
611 # functions that don't have an assigned offset
612
613 if obj.fn_offset >= 0 or obj.fn_alias != None:
614 if obj.fn_offset >= 0:
615 index = obj.fn_offset
616 else:
617 index = self.next_alias
618 self.next_alias -= 1
619
620 self.functions[index] = obj
621 self.xref[obj.name] = index
622 elif object_type == "type":
623 self.types[obj.name] = obj
624
625 return
626
627
628 def startElement(self, name, attrs):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000629 """Start a new element in the XML stream.
630
631 Starts a new element. There are three types of elements that
632 are specially handled by this function. When a "category"
633 element is encountered, the name of the category is saved.
634 If an element is encountered and no API object is
635 in-progress, a new object is created using the API factory.
636 Any future elements, until that API object is closed, are
637 passed to the current objects startElement method.
638
639 This paradigm was chosen becuase it allows subclasses of the
640 basic API types (i.e., glFunction, glEnum, etc.) to handle
641 additional XML data, GLX protocol information, that the base
642 classes do not know about."""
643
Ian Romanick73f59b02004-05-18 18:33:40 +0000644 if self.current_object != None:
645 self.current_object.startElement(name, attrs)
646 elif name == "category":
647 self.current_category = attrs.get('name', "")
Ian Romanick6cfd4f72005-02-08 02:11:14 +0000648 elif name == "include":
649 self.next_include = attrs.get('name', "")
Ian Romanick73f59b02004-05-18 18:33:40 +0000650 else:
651 self.current_object = self.factory.create(self, name, attrs)
652 return
653
Ian Romanicka9d033c2004-05-19 23:33:08 +0000654
Ian Romanick73f59b02004-05-18 18:33:40 +0000655 def endElement(self, name):
656 if self.current_object != None:
657 if self.current_object.endElement(name):
658 self.current_object = None
Ian Romanick6cfd4f72005-02-08 02:11:14 +0000659 elif name == "include":
660 parser = make_parser()
661 parser.setFeature(feature_namespaces, 0)
662 parser.setContentHandler(self)
663
664 f = open(self.next_include)
665 parser.parse(f)
666
Ian Romanick73f59b02004-05-18 18:33:40 +0000667 return
668
Ian Romanicka9d033c2004-05-19 23:33:08 +0000669
Ian Romanickc2803582005-02-01 00:28:47 +0000670 def printPure(self):
671 self.undef_list.append("PURE")
672 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
673# define PURE __attribute__((pure))
674# else
675# define PURE
676# endif"""
677
678 def printFastcall(self):
679 self.undef_list.append("FASTCALL")
680 print """# if defined(__i386__) && defined(__GNUC__)
681# define FASTCALL __attribute__((fastcall))
682# else
683# define FASTCALL
684# endif"""
685
686 def printVisibility(self, S, s):
687 self.undef_list.append(S)
688 print """# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
689# define %s __attribute__((visibility("%s")))
690# else
691# define %s
692# endif""" % (S, s, S)
693
694 def printNoinline(self):
695 self.undef_list.append("NOINLINE")
696 print """# if defined(__GNUC__)
697# define NOINLINE __attribute__((noinline))
698# else
699# define NOINLINE
700# endif"""
701
702 def printHaveAlias(self):
703 self.undef_list.append("HAVE_ALIAS")
704 print """# if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
705# define HAVE_ALIAS
706# endif"""
707
Ian Romanick73f59b02004-05-18 18:33:40 +0000708 def printFunction(self,offset):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000709 """Print a single function.
710
711 In the base class, this function is empty. All derived
712 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000713 return
714
Ian Romanicka9d033c2004-05-19 23:33:08 +0000715
Ian Romanick73f59b02004-05-18 18:33:40 +0000716 def printRealHeader(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000717 """Print the "real" header for the created file.
718
719 In the base class, this function is empty. All derived
720 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000721 return
722
Ian Romanicka9d033c2004-05-19 23:33:08 +0000723
Ian Romanick73f59b02004-05-18 18:33:40 +0000724 def printRealFooter(self):
Ian Romanicka9d033c2004-05-19 23:33:08 +0000725 """Print the "real" footer for the created file.
726
727 In the base class, this function is empty. All derived
728 classes should over-ride this function."""
Ian Romanick73f59b02004-05-18 18:33:40 +0000729 return