aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mapi/glapi/gen-es/gl_parse_header.py
diff options
context:
space:
mode:
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.py450
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()