From a9d033c4603b9e5d5ed05fd4b3738e61f1ee4e72 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 19 May 2004 23:33:08 +0000 Subject: [PATCH] Added some in-code documentation. Modifed glParameter to be a subclass of glItem. --- src/mesa/glapi/gl_XML.py | 161 +++++++++++++++++++++++++++-------- src/mesa/glapi/gl_apitemp.py | 4 +- 2 files changed, 126 insertions(+), 39 deletions(-) diff --git a/src/mesa/glapi/gl_XML.py b/src/mesa/glapi/gl_XML.py index 17d45beb499..ff9bc8f4a4d 100644 --- a/src/mesa/glapi/gl_XML.py +++ b/src/mesa/glapi/gl_XML.py @@ -34,11 +34,6 @@ import sys, re class glItem: """Generic class on which all other API entity types are based.""" - name = "" - category = "" - context = None - tag_name = "" - def __init__(self, tag_name, name, context): self.name = name self.category = context.get_category_define() @@ -49,6 +44,13 @@ class glItem: return 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 "" would cause the startElement handler + to be called once, but the endElement handler would be called + twice.""" return def endElement(self, name): @@ -62,7 +64,11 @@ class glItem: This fails if a tag can contain another tag with the same name. The XML "" 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: return 1 @@ -70,8 +76,15 @@ class glItem: return 0 return + def get_category_define(self): + return self.category + 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): self.value = int(attrs.get('value', "0x0000"), 0) self.functions = {} @@ -89,6 +102,8 @@ class glEnum( glItem ): class glType( glItem ): + """Subclass of glItem for representing GL types.""" + def __init__(self, context, name, attrs): self.size = int(attrs.get('size', "0")) @@ -96,10 +111,10 @@ class glType( glItem ): glItem.__init__(self, name, type_name, context) -class glParameter: +class glParameter( glItem ): + """Parameter of a glFunction.""" p_type = None p_type_string = "" - p_name = None p_count = 0 p_count_parameters = None counter = None @@ -107,34 +122,49 @@ class glParameter: is_counter = 0 is_pointer = 0 - def __init__(self, t, ts, n, c, p, is_output): - self.counter = None + def __init__(self, context, name, attrs): + 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: self.p_count = int(c) + self.counter = None except Exception,e: self.p_count = 0 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 else: 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 else: 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 # is a pointer. - if re.compile("[*]").search(ts): + if re.compile("[*]").search(self.p_type_string): # We could do some other validation here. For # example, an output parameter should not be const, # but every non-output parameter should. @@ -149,12 +179,28 @@ class glParameter: raise RuntimeError("Non-pointer type has count or is output.") self.is_pointer = 0; + glItem.__init__(self, name, p_name, context) + return + + 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 + def is_array(self): return self.is_pointer + def count_string(self): """Return a string representing the number of items @@ -175,6 +221,7 @@ class glParameter: else: return "1" + def size(self): if self.is_variable_length_array(): return 0 @@ -183,7 +230,14 @@ class glParameter: else: return self.p_type.size * self.p_count + 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): self.data = data self.index = 0 @@ -195,6 +249,7 @@ class glParameterIterator: self.index += 1 return self.data[i] + class glFunction( glItem ): real_name = "" fn_alias = None @@ -228,42 +283,32 @@ class glFunction( glItem ): def startElement(self, name, attrs): 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: - p = glParameter(t, p_type, p_name, p_count, p_param, is_output) + glParameter(self, name, attrs) except RuntimeError: print "Error with parameter '%s' in function '%s'." \ - % (p_name, self.name) + % (attrs.get('name','(unknown)'), self.name) raise - - if is_counter == "true": p.is_counter = 1 - - self.add_parameter(p) elif name == "return": 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) + def set_return_type(self, t): self.fn_return_type = t + def get_parameter_string(self): arg_string = "" comma = "" 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 = ", " if arg_string == "": @@ -304,6 +349,7 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase): self.xref = {} self.factory = glItemFactory() + def find_type(self,type_name): for t in self.types: 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) return None + def find_function(self,function_name): index = self.xref[function_name] return self.functions[index] + def printFunctions(self): keys = self.functions.keys() keys.sort() @@ -336,7 +384,10 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase): return + 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 */' \ % (self.name) print '' @@ -347,12 +398,17 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase): self.printRealHeader(); return + def printFooter(self): + """Print the header associated with all files and call the printRealFooter method.""" + self.printFunctions() self.printRealFooter() 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): s = self.current_category return "GL_VERSION_" + s.replace(".", "_") @@ -382,6 +438,21 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase): 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: self.current_object.startElement(name, attrs) elif name == "category": @@ -390,17 +461,33 @@ class FilterGLAPISpecBase(saxutils.XMLFilterBase): self.current_object = self.factory.create(self, name, attrs) return + def endElement(self, name): if self.current_object != None: if self.current_object.endElement(name): self.current_object = None return + 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 + 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 + 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 diff --git a/src/mesa/glapi/gl_apitemp.py b/src/mesa/glapi/gl_apitemp.py index 59655a21793..b210c704a74 100644 --- a/src/mesa/glapi/gl_apitemp.py +++ b/src/mesa/glapi/gl_apitemp.py @@ -62,8 +62,8 @@ class PrintGlOffsets(gl_XML.FilterGLAPISpecBase): t = "%d" t_string = t_string + comma + t - p_string = p_string + comma + p.p_name - o_string = o_string + comma + cast + p.p_name + p_string = p_string + comma + p.name + o_string = o_string + comma + cast + p.name comma = ", "