Added some in-code documentation. Modifed glParameter to be a
subclass of glItem.
This commit is contained in:
@@ -34,11 +34,6 @@ import sys, re
|
|||||||
class glItem:
|
class glItem:
|
||||||
"""Generic class on which all other API entity types are based."""
|
"""Generic class on which all other API entity types are based."""
|
||||||
|
|
||||||
name = ""
|
|
||||||
category = ""
|
|
||||||
context = None
|
|
||||||
tag_name = ""
|
|
||||||
|
|
||||||
def __init__(self, tag_name, name, context):
|
def __init__(self, tag_name, name, context):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.category = context.get_category_define()
|
self.category = context.get_category_define()
|
||||||
@@ -49,6 +44,13 @@ class glItem:
|
|||||||
return
|
return
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
|
"""Generic startElement handler.
|
||||||
|
|
||||||
|
The startElement handler is called for all elements except
|
||||||
|
the one that starts the object. For a foo element, the
|
||||||
|
XML "<foo><bar/></foo>" would cause the startElement handler
|
||||||
|
to be called once, but the endElement handler would be called
|
||||||
|
twice."""
|
||||||
return
|
return
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
@@ -62,7 +64,11 @@ class glItem:
|
|||||||
|
|
||||||
This fails if a tag can contain another tag with the same
|
This fails if a tag can contain another tag with the same
|
||||||
name. The XML "<foo><foo/><bar/></foo>" would fail. The
|
name. The XML "<foo><foo/><bar/></foo>" would fail. The
|
||||||
object would end before the bar tag was processed."""
|
object would end before the bar tag was processed.
|
||||||
|
|
||||||
|
The endElement handler is called for every end element
|
||||||
|
associated with an object, even the element that started the
|
||||||
|
object. See the description of startElement an example."""
|
||||||
|
|
||||||
if name == self.tag_name:
|
if name == self.tag_name:
|
||||||
return 1
|
return 1
|
||||||
@@ -70,8 +76,15 @@ class glItem:
|
|||||||
return 0
|
return 0
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def get_category_define(self):
|
||||||
|
return self.category
|
||||||
|
|
||||||
|
|
||||||
class glEnum( glItem ):
|
class glEnum( glItem ):
|
||||||
|
"""Subclass of glItem for representing GL enumerants.
|
||||||
|
|
||||||
|
This class is not complete, and is not really used yet."""
|
||||||
|
|
||||||
def __init__(self, context, name, attrs):
|
def __init__(self, context, name, attrs):
|
||||||
self.value = int(attrs.get('value', "0x0000"), 0)
|
self.value = int(attrs.get('value', "0x0000"), 0)
|
||||||
self.functions = {}
|
self.functions = {}
|
||||||
@@ -89,6 +102,8 @@ class glEnum( glItem ):
|
|||||||
|
|
||||||
|
|
||||||
class glType( glItem ):
|
class glType( glItem ):
|
||||||
|
"""Subclass of glItem for representing GL types."""
|
||||||
|
|
||||||
def __init__(self, context, name, attrs):
|
def __init__(self, context, name, attrs):
|
||||||
self.size = int(attrs.get('size', "0"))
|
self.size = int(attrs.get('size', "0"))
|
||||||
|
|
||||||
@@ -96,10 +111,10 @@ class glType( glItem ):
|
|||||||
glItem.__init__(self, name, type_name, context)
|
glItem.__init__(self, name, type_name, context)
|
||||||
|
|
||||||
|
|
||||||
class glParameter:
|
class glParameter( glItem ):
|
||||||
|
"""Parameter of a glFunction."""
|
||||||
p_type = None
|
p_type = None
|
||||||
p_type_string = ""
|
p_type_string = ""
|
||||||
p_name = None
|
|
||||||
p_count = 0
|
p_count = 0
|
||||||
p_count_parameters = None
|
p_count_parameters = None
|
||||||
counter = None
|
counter = None
|
||||||
@@ -107,34 +122,49 @@ class glParameter:
|
|||||||
is_counter = 0
|
is_counter = 0
|
||||||
is_pointer = 0
|
is_pointer = 0
|
||||||
|
|
||||||
def __init__(self, t, ts, n, c, p, is_output):
|
def __init__(self, context, name, attrs):
|
||||||
self.counter = None
|
p_name = attrs.get('name', None)
|
||||||
|
self.p_type_string = attrs.get('type', None)
|
||||||
|
self.p_count_parameters = attrs.get('variable_param', None)
|
||||||
|
|
||||||
|
self.p_type = context.context.find_type(self.p_type_string)
|
||||||
|
if self.p_type == None:
|
||||||
|
raise RuntimeError("Unknown type '%s' in function '%s'." % (self.p_type_string, context.name))
|
||||||
|
|
||||||
|
|
||||||
|
# The count tag can be either a numeric string or the name of
|
||||||
|
# a variable. If it is the name of a variable, the int(c)
|
||||||
|
# statement will throw an exception, and the except block will
|
||||||
|
# take over.
|
||||||
|
|
||||||
|
c = attrs.get('count', "0")
|
||||||
try:
|
try:
|
||||||
self.p_count = int(c)
|
self.p_count = int(c)
|
||||||
|
self.counter = None
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
self.p_count = 0
|
self.p_count = 0
|
||||||
self.counter = c
|
self.counter = c
|
||||||
|
|
||||||
if is_output == "true":
|
if attrs.get('counter', "false") == "true":
|
||||||
|
self.is_counter = 1
|
||||||
|
else:
|
||||||
|
self.is_counter = 0
|
||||||
|
|
||||||
|
if attrs.get('output', "false") == "true":
|
||||||
self.is_output = 1
|
self.is_output = 1
|
||||||
else:
|
else:
|
||||||
self.is_output = 0
|
self.is_output = 0
|
||||||
|
|
||||||
if self.p_count > 0 or self.counter != None or p != None :
|
if self.p_count > 0 or self.counter != None or self.p_count_parameters != None :
|
||||||
has_count = 1
|
has_count = 1
|
||||||
else:
|
else:
|
||||||
has_count = 0
|
has_count = 0
|
||||||
|
|
||||||
self.p_type = t
|
|
||||||
self.p_type_string = ts
|
|
||||||
self.p_name = n
|
|
||||||
self.p_count_parameters = p
|
|
||||||
|
|
||||||
# If there is a * anywhere in the parameter's type, then it
|
# If there is a * anywhere in the parameter's type, then it
|
||||||
# is a pointer.
|
# is a pointer.
|
||||||
|
|
||||||
if re.compile("[*]").search(ts):
|
if re.compile("[*]").search(self.p_type_string):
|
||||||
# We could do some other validation here. For
|
# We could do some other validation here. For
|
||||||
# example, an output parameter should not be const,
|
# example, an output parameter should not be const,
|
||||||
# but every non-output parameter should.
|
# but every non-output parameter should.
|
||||||
@@ -149,12 +179,28 @@ class glParameter:
|
|||||||
raise RuntimeError("Non-pointer type has count or is output.")
|
raise RuntimeError("Non-pointer type has count or is output.")
|
||||||
self.is_pointer = 0;
|
self.is_pointer = 0;
|
||||||
|
|
||||||
|
glItem.__init__(self, name, p_name, context)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def is_variable_length_array(self):
|
def is_variable_length_array(self):
|
||||||
|
"""Determine if a parameter is a variable length array.
|
||||||
|
|
||||||
|
A parameter is considered to be a variable length array if
|
||||||
|
its size depends on the value of another parameter that is
|
||||||
|
an enumerant. The params parameter to glTexEnviv is an
|
||||||
|
example of a variable length array parameter. Arrays whose
|
||||||
|
size depends on a count variable, such as the lists parameter
|
||||||
|
to glCallLists, are not variable length arrays in this
|
||||||
|
sense."""
|
||||||
|
|
||||||
return self.p_count_parameters != None
|
return self.p_count_parameters != None
|
||||||
|
|
||||||
|
|
||||||
def is_array(self):
|
def is_array(self):
|
||||||
return self.is_pointer
|
return self.is_pointer
|
||||||
|
|
||||||
|
|
||||||
def count_string(self):
|
def count_string(self):
|
||||||
"""Return a string representing the number of items
|
"""Return a string representing the number of items
|
||||||
|
|
||||||
@@ -175,6 +221,7 @@ class glParameter:
|
|||||||
else:
|
else:
|
||||||
return "1"
|
return "1"
|
||||||
|
|
||||||
|
|
||||||
def size(self):
|
def size(self):
|
||||||
if self.is_variable_length_array():
|
if self.is_variable_length_array():
|
||||||
return 0
|
return 0
|
||||||
@@ -183,7 +230,14 @@ class glParameter:
|
|||||||
else:
|
else:
|
||||||
return self.p_type.size * self.p_count
|
return self.p_type.size * self.p_count
|
||||||
|
|
||||||
|
|
||||||
class glParameterIterator:
|
class glParameterIterator:
|
||||||
|
"""Class to iterate over a list of glParameters.
|
||||||
|
|
||||||
|
Objects of this class are returned by the __iter__ method of the
|
||||||
|
glFunction class. They are used to iterate over the list of
|
||||||
|
parameters to the function."""
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
self.data = data
|
self.data = data
|
||||||
self.index = 0
|
self.index = 0
|
||||||
@@ -195,6 +249,7 @@ class glParameterIterator:
|
|||||||
self.index += 1
|
self.index += 1
|
||||||
return self.data[i]
|
return self.data[i]
|
||||||
|
|
||||||
|
|
||||||
class glFunction( glItem ):
|
class glFunction( glItem ):
|
||||||
real_name = ""
|
real_name = ""
|
||||||
fn_alias = None
|
fn_alias = None
|
||||||
@@ -228,42 +283,32 @@ class glFunction( glItem ):
|
|||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "param":
|
if name == "param":
|
||||||
p_name = attrs.get('name', None)
|
|
||||||
p_type = attrs.get('type', None)
|
|
||||||
p_count = attrs.get('count', "0")
|
|
||||||
p_param = attrs.get('variable_param', None)
|
|
||||||
is_output = attrs.get('output', "false")
|
|
||||||
is_counter = attrs.get('counter', "false")
|
|
||||||
|
|
||||||
t = self.context.find_type(p_type)
|
|
||||||
if t == None:
|
|
||||||
raise RuntimeError("Unknown type '%s' in function '%s'." % (p_type, self.name))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
p = glParameter(t, p_type, p_name, p_count, p_param, is_output)
|
glParameter(self, name, attrs)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
print "Error with parameter '%s' in function '%s'." \
|
print "Error with parameter '%s' in function '%s'." \
|
||||||
% (p_name, self.name)
|
% (attrs.get('name','(unknown)'), self.name)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if is_counter == "true": p.is_counter = 1
|
|
||||||
|
|
||||||
self.add_parameter(p)
|
|
||||||
elif name == "return":
|
elif name == "return":
|
||||||
self.set_return_type(attrs.get('type', None))
|
self.set_return_type(attrs.get('type', None))
|
||||||
|
|
||||||
|
|
||||||
def add_parameter(self, p):
|
def append(self, tag_name, p):
|
||||||
|
if tag_name != "param":
|
||||||
|
raise RuntimeError("Trying to append '%s' to parameter list of function '%s'." % (tag_name, self.name))
|
||||||
|
|
||||||
self.fn_parameters.append(p)
|
self.fn_parameters.append(p)
|
||||||
|
|
||||||
|
|
||||||
def set_return_type(self, t):
|
def set_return_type(self, t):
|
||||||
self.fn_return_type = t
|
self.fn_return_type = t
|
||||||
|
|
||||||
|
|
||||||
def get_parameter_string(self):
|
def get_parameter_string(self):
|
||||||
arg_string = ""
|
arg_string = ""
|
||||||
comma = ""
|
comma = ""
|
||||||
for p in self:
|
for p in self:
|
||||||
arg_string = arg_string + comma + p.p_type_string + " " + p.p_name
|
arg_string = arg_string + comma + p.p_type_string + " " + p.name
|
||||||
comma = ", "
|
comma = ", "
|
||||||
|
|
||||||
if arg_string == "":
|
if arg_string == "":
|
||||||
@@ -304,6 +349,7 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
self.xref = {}
|
self.xref = {}
|
||||||
self.factory = glItemFactory()
|
self.factory = glItemFactory()
|
||||||
|
|
||||||
|
|
||||||
def find_type(self,type_name):
|
def find_type(self,type_name):
|
||||||
for t in self.types:
|
for t in self.types:
|
||||||
if re.compile(t).search(type_name):
|
if re.compile(t).search(type_name):
|
||||||
@@ -311,10 +357,12 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
print "Unable to find base type matching \"%s\"." % (type_name)
|
print "Unable to find base type matching \"%s\"." % (type_name)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def find_function(self,function_name):
|
def find_function(self,function_name):
|
||||||
index = self.xref[function_name]
|
index = self.xref[function_name]
|
||||||
return self.functions[index]
|
return self.functions[index]
|
||||||
|
|
||||||
|
|
||||||
def printFunctions(self):
|
def printFunctions(self):
|
||||||
keys = self.functions.keys()
|
keys = self.functions.keys()
|
||||||
keys.sort()
|
keys.sort()
|
||||||
@@ -336,7 +384,10 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def printHeader(self):
|
def printHeader(self):
|
||||||
|
"""Print the header associated with all files and call the printRealHeader method."""
|
||||||
|
|
||||||
print '/* DO NOT EDIT - This file generated automatically by %s script */' \
|
print '/* DO NOT EDIT - This file generated automatically by %s script */' \
|
||||||
% (self.name)
|
% (self.name)
|
||||||
print ''
|
print ''
|
||||||
@@ -347,12 +398,17 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
self.printRealHeader();
|
self.printRealHeader();
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def printFooter(self):
|
def printFooter(self):
|
||||||
|
"""Print the header associated with all files and call the printRealFooter method."""
|
||||||
|
|
||||||
self.printFunctions()
|
self.printFunctions()
|
||||||
self.printRealFooter()
|
self.printRealFooter()
|
||||||
|
|
||||||
|
|
||||||
def get_category_define(self):
|
def get_category_define(self):
|
||||||
|
"""Convert the category name to the #define that would be found in glext.h"""
|
||||||
|
|
||||||
if re.compile("[1-9][0-9]*[.][0-9]+").match(self.current_category):
|
if re.compile("[1-9][0-9]*[.][0-9]+").match(self.current_category):
|
||||||
s = self.current_category
|
s = self.current_category
|
||||||
return "GL_VERSION_" + s.replace(".", "_")
|
return "GL_VERSION_" + s.replace(".", "_")
|
||||||
@@ -382,6 +438,21 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
|
"""Start a new element in the XML stream.
|
||||||
|
|
||||||
|
Starts a new element. There are three types of elements that
|
||||||
|
are specially handled by this function. When a "category"
|
||||||
|
element is encountered, the name of the category is saved.
|
||||||
|
If an element is encountered and no API object is
|
||||||
|
in-progress, a new object is created using the API factory.
|
||||||
|
Any future elements, until that API object is closed, are
|
||||||
|
passed to the current objects startElement method.
|
||||||
|
|
||||||
|
This paradigm was chosen becuase it allows subclasses of the
|
||||||
|
basic API types (i.e., glFunction, glEnum, etc.) to handle
|
||||||
|
additional XML data, GLX protocol information, that the base
|
||||||
|
classes do not know about."""
|
||||||
|
|
||||||
if self.current_object != None:
|
if self.current_object != None:
|
||||||
self.current_object.startElement(name, attrs)
|
self.current_object.startElement(name, attrs)
|
||||||
elif name == "category":
|
elif name == "category":
|
||||||
@@ -390,17 +461,33 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase):
|
|||||||
self.current_object = self.factory.create(self, name, attrs)
|
self.current_object = self.factory.create(self, name, attrs)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
if self.current_object != None:
|
if self.current_object != None:
|
||||||
if self.current_object.endElement(name):
|
if self.current_object.endElement(name):
|
||||||
self.current_object = None
|
self.current_object = None
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def printFunction(self,offset):
|
def printFunction(self,offset):
|
||||||
|
"""Print a single function.
|
||||||
|
|
||||||
|
In the base class, this function is empty. All derived
|
||||||
|
classes should over-ride this function."""
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def printRealHeader(self):
|
def printRealHeader(self):
|
||||||
|
"""Print the "real" header for the created file.
|
||||||
|
|
||||||
|
In the base class, this function is empty. All derived
|
||||||
|
classes should over-ride this function."""
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def printRealFooter(self):
|
def printRealFooter(self):
|
||||||
|
"""Print the "real" footer for the created file.
|
||||||
|
|
||||||
|
In the base class, this function is empty. All derived
|
||||||
|
classes should over-ride this function."""
|
||||||
return
|
return
|
||||||
|
@@ -62,8 +62,8 @@ class PrintGlOffsets(gl_XML.FilterGLAPISpecBase):
|
|||||||
t = "%d"
|
t = "%d"
|
||||||
|
|
||||||
t_string = t_string + comma + t
|
t_string = t_string + comma + t
|
||||||
p_string = p_string + comma + p.p_name
|
p_string = p_string + comma + p.name
|
||||||
o_string = o_string + comma + cast + p.p_name
|
o_string = o_string + comma + cast + p.name
|
||||||
comma = ", "
|
comma = ", "
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user