diff options
Diffstat (limited to 'mesalib/src/mapi/glapi/gen-es/gl_parse_header.py')
-rw-r--r-- | mesalib/src/mapi/glapi/gen-es/gl_parse_header.py | 450 |
1 files changed, 0 insertions, 450 deletions
diff --git a/mesalib/src/mapi/glapi/gen-es/gl_parse_header.py b/mesalib/src/mapi/glapi/gen-es/gl_parse_header.py deleted file mode 100644 index 5382eba35..000000000 --- a/mesalib/src/mapi/glapi/gen-es/gl_parse_header.py +++ /dev/null @@ -1,450 +0,0 @@ -#!/usr/bin/python -# -# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# on the rights to use, copy, modify, merge, publish, distribute, sub -# license, and/or sell copies of the Software, and to permit persons to whom -# the Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -import sys -import os.path -import getopt -import re - -GLAPI = "../../glapi/gen" -sys.path.append(GLAPI) - -class HeaderParser(object): - """Parser for GL header files.""" - - def __init__(self, verbose=0): - # match #if and #ifdef - self.IFDEF = re.compile('#\s*if(n?def\s+(?P<ifdef>\w+)|\s+(?P<if>.+))') - # match #endif - self.ENDIF = re.compile('#\s*endif') - # match typedef abc def; - self.TYPEDEF = re.compile('typedef\s+(?P<from>[\w ]+)\s+(?P<to>\w+);') - # match #define XYZ VAL - self.DEFINE = re.compile('#\s*define\s+(?P<key>\w+)(?P<value>\s+[\w"]*)?') - # match GLAPI - self.GLAPI = re.compile('^GL_?API(CALL)?\s+(?P<return>[\w\s*]+[\w*])\s+(GL)?_?APIENTRY\s+(?P<name>\w+)\s*\((?P<params>[\w\s(,*\[\])]+)\)\s*;') - - self.split_params = re.compile('\s*,\s*') - self.split_ctype = re.compile('(\W)') - # ignore GL_VERSION_X_Y - self.ignore_enum = re.compile('GL(_ES)?_VERSION(_ES_C[ML])?_\d_\d') - - self.verbose = verbose - self._reset() - - def _reset(self): - """Reset to initial state.""" - self.ifdef_levels = [] - self.need_char = False - - # use typeexpr? - def _format_ctype(self, ctype, fix=True): - """Format a ctype string, optionally fix it.""" - # split the type string - tmp = self.split_ctype.split(ctype) - tmp = [s for s in tmp if s and s != " "] - - pretty = "" - for i in xrange(len(tmp)): - # add missing GL prefix - if (fix and tmp[i] != "const" and tmp[i] != "*" and - not tmp[i].startswith("GL")): - tmp[i] = "GL" + tmp[i] - - if i == 0: - pretty = tmp[i] - else: - sep = " " - if tmp[i - 1] == "*": - sep = "" - pretty += sep + tmp[i] - return pretty - - # use typeexpr? - def _get_ctype_attrs(self, ctype): - """Get the attributes of a ctype.""" - is_float = (ctype.find("float") != -1 or ctype.find("double") != -1) - is_signed = not (ctype.find("unsigned") != -1) - - size = 0 - if ctype.find("char") != -1: - size = 1 - elif ctype.find("short") != -1: - size = 2 - elif ctype.find("int") != -1: - size = 4 - elif is_float: - if ctype.find("float") != -1: - size = 4 - else: - size = 8 - - return (size, is_float, is_signed) - - def _parse_define(self, line): - """Parse a #define line for an <enum>.""" - m = self.DEFINE.search(line) - if not m: - if self.verbose and line.find("#define") >= 0: - print "ignore %s" % (line) - return None - - key = m.group("key").strip() - val = m.group("value").strip() - - # enum must begin with GL_ and be all uppercase - if ((not (key.startswith("GL_") and key.isupper())) or - (self.ignore_enum.match(key) and val == "1")): - if self.verbose: - print "ignore enum %s" % (key) - return None - - return (key, val) - - def _parse_typedef(self, line): - """Parse a typedef line for a <type>.""" - m = self.TYPEDEF.search(line) - if not m: - if self.verbose and line.find("typedef") >= 0: - print "ignore %s" % (line) - return None - - f = m.group("from").strip() - t = m.group("to").strip() - if not t.startswith("GL"): - if self.verbose: - print "ignore type %s" % (t) - return None - attrs = self._get_ctype_attrs(f) - - return (f, t, attrs) - - def _parse_gl_api(self, line): - """Parse a GLAPI line for a <function>.""" - m = self.GLAPI.search(line) - if not m: - if self.verbose and line.find("APIENTRY") >= 0: - print "ignore %s" % (line) - return None - - rettype = m.group("return") - rettype = self._format_ctype(rettype) - if rettype == "GLvoid": - rettype = "" - - name = m.group("name") - - param_str = m.group("params") - chunks = self.split_params.split(param_str) - chunks = [s.strip() for s in chunks] - if len(chunks) == 1 and (chunks[0] == "void" or chunks[0] == "GLvoid"): - chunks = [] - - params = [] - for c in chunks: - # split type and variable name - idx = c.rfind("*") - if idx < 0: - idx = c.rfind(" ") - if idx >= 0: - idx += 1 - ctype = c[:idx] - var = c[idx:] - else: - ctype = c - var = "unnamed" - - # convert array to pointer - idx = var.find("[") - if idx >= 0: - var = var[:idx] - ctype += "*" - - ctype = self._format_ctype(ctype) - var = var.strip() - - if not self.need_char and ctype.find("GLchar") >= 0: - self.need_char = True - - params.append((ctype, var)) - - return (rettype, name, params) - - def _change_level(self, line): - """Parse a #ifdef line and change level.""" - m = self.IFDEF.search(line) - if m: - ifdef = m.group("ifdef") - if not ifdef: - ifdef = m.group("if") - self.ifdef_levels.append(ifdef) - return True - m = self.ENDIF.search(line) - if m: - self.ifdef_levels.pop() - return True - return False - - def _read_header(self, header): - """Open a header file and read its contents.""" - lines = [] - try: - fp = open(header, "rb") - lines = fp.readlines() - fp.close() - except IOError, e: - print "failed to read %s: %s" % (header, e) - return lines - - def _cmp_enum(self, enum1, enum2): - """Compare two enums.""" - # sort by length of the values as strings - val1 = enum1[1] - val2 = enum2[1] - ret = len(val1) - len(val2) - # sort by the values - if not ret: - val1 = int(val1, 16) - val2 = int(val2, 16) - ret = val1 - val2 - # in case int cannot hold the result - if ret > 0: - ret = 1 - elif ret < 0: - ret = -1 - # sort by the names - if not ret: - if enum1[0] < enum2[0]: - ret = -1 - elif enum1[0] > enum2[0]: - ret = 1 - return ret - - def _cmp_type(self, type1, type2): - """Compare two types.""" - attrs1 = type1[2] - attrs2 = type2[2] - # sort by type size - ret = attrs1[0] - attrs2[0] - # float is larger - if not ret: - ret = attrs1[1] - attrs2[1] - # signed is larger - if not ret: - ret = attrs1[2] - attrs2[2] - # reverse - ret = -ret - return ret - - def _cmp_function(self, func1, func2): - """Compare two functions.""" - name1 = func1[1] - name2 = func2[1] - ret = 0 - # sort by the names - if name1 < name2: - ret = -1 - elif name1 > name2: - ret = 1 - return ret - - def _postprocess_dict(self, hdict): - """Post-process a header dict and return an ordered list.""" - hlist = [] - largest = 0 - for key, cat in hdict.iteritems(): - size = len(cat["enums"]) + len(cat["types"]) + len(cat["functions"]) - # ignore empty category - if not size: - continue - - cat["enums"].sort(self._cmp_enum) - # remove duplicates - dup = [] - for i in xrange(1, len(cat["enums"])): - if cat["enums"][i] == cat["enums"][i - 1]: - dup.insert(0, i) - for i in dup: - e = cat["enums"].pop(i) - if self.verbose: - print "remove duplicate enum %s" % e[0] - - cat["types"].sort(self._cmp_type) - cat["functions"].sort(self._cmp_function) - - # largest category comes first - if size > largest: - hlist.insert(0, (key, cat)) - largest = size - else: - hlist.append((key, cat)) - return hlist - - def parse(self, header): - """Parse a header file.""" - self._reset() - - if self.verbose: - print "Parsing %s" % (header) - - hdict = {} - lines = self._read_header(header) - for line in lines: - if self._change_level(line): - continue - - # skip until the first ifdef (i.e. __gl_h_) - if not self.ifdef_levels: - continue - - cat_name = os.path.basename(header) - # check if we are in an extension - if (len(self.ifdef_levels) > 1 and - self.ifdef_levels[-1].startswith("GL_")): - cat_name = self.ifdef_levels[-1] - - try: - cat = hdict[cat_name] - except KeyError: - cat = { - "enums": [], - "types": [], - "functions": [] - } - hdict[cat_name] = cat - - key = "enums" - elem = self._parse_define(line) - if not elem: - key = "types" - elem = self._parse_typedef(line) - if not elem: - key = "functions" - elem = self._parse_gl_api(line) - - if elem: - cat[key].append(elem) - - if self.need_char: - if self.verbose: - print "define GLchar" - elem = self._parse_typedef("typedef char GLchar;") - cat["types"].append(elem) - return self._postprocess_dict(hdict) - -def spaces(n, str=""): - spaces = n - len(str) - if spaces < 1: - spaces = 1 - return " " * spaces - -def output_xml(name, hlist): - """Output a parsed header in OpenGLAPI XML.""" - - for i in xrange(len(hlist)): - cat_name, cat = hlist[i] - - print '<category name="%s">' % (cat_name) - indent = 4 - - for enum in cat["enums"]: - name = enum[0][3:] - value = enum[1] - tab = spaces(41, name) - attrs = 'name="%s"%svalue="%s"' % (name, tab, value) - print '%s<enum %s/>' % (spaces(indent), attrs) - - if cat["enums"] and cat["types"]: - print - - for type in cat["types"]: - ctype = type[0] - size, is_float, is_signed = type[2] - - attrs = 'name="%s"' % (type[1][2:]) - attrs += spaces(16, attrs) + 'size="%d"' % (size) - if is_float: - attrs += ' float="true"' - elif not is_signed: - attrs += ' unsigned="true"' - - print '%s<type %s/>' % (spaces(indent), attrs) - - for func in cat["functions"]: - print - ret = func[0] - name = func[1][2:] - params = func[2] - - attrs = 'name="%s" offset="assign"' % name - print '%s<function %s>' % (spaces(indent), attrs) - - for param in params: - attrs = 'name="%s" type="%s"' % (param[1], param[0]) - print '%s<param %s/>' % (spaces(indent * 2), attrs) - if ret: - attrs = 'type="%s"' % ret - print '%s<return %s/>' % (spaces(indent * 2), attrs) - - print '%s</function>' % spaces(indent) - - print '</category>' - print - -def show_usage(): - print "Usage: %s [-v] <header> ..." % sys.argv[0] - sys.exit(1) - -def main(): - try: - args, headers = getopt.getopt(sys.argv[1:], "v") - except Exception, e: - show_usage() - if not headers: - show_usage() - - verbose = 0 - for arg in args: - if arg[0] == "-v": - verbose += 1 - - need_xml_header = True - parser = HeaderParser(verbose) - for h in headers: - h = os.path.abspath(h) - hlist = parser.parse(h) - - if need_xml_header: - print '<?xml version="1.0"?>' - print '<!DOCTYPE OpenGLAPI SYSTEM "%s/gl_API.dtd">' % GLAPI - need_xml_header = False - - print - print '<!-- %s -->' % (h) - print '<OpenGLAPI>' - print - output_xml(h, hlist) - print '</OpenGLAPI>' - -if __name__ == '__main__': - main() |