diff options
Diffstat (limited to 'src/mapi/glapi/gen-es/gl_compare.py')
-rw-r--r-- | src/mapi/glapi/gen-es/gl_compare.py | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/src/mapi/glapi/gen-es/gl_compare.py b/src/mapi/glapi/gen-es/gl_compare.py new file mode 100644 index 00000000000..6b5e43bb98b --- /dev/null +++ b/src/mapi/glapi/gen-es/gl_compare.py @@ -0,0 +1,354 @@ +#!/usr/bin/python +# +# Copyright (C) 2009 Chia-I Wu <[email protected]> +# +# 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 + +GLAPI = "../../glapi/gen" +sys.path.append(GLAPI) + +import gl_XML +import glX_XML + +class ApiSet(object): + def __init__(self, api, elts=["enum", "type", "function"]): + self.api = api + self.elts = elts + + def _check_enum(self, e1, e2, strict=True): + if e1.name != e2.name: + raise ValueError("%s: name mismatch" % e1.name) + if e1.value != e2.value: + raise ValueError("%s: value 0x%04x != 0x%04x" + % (e1.name, e1.value, e2.value)) + + def _check_type(self, t1, t2, strict=True): + if t1.name != t2.name: + raise ValueError("%s: name mismatch" % t1.name) + if t1.type_expr.string() != t2.type_expr.string(): + raise ValueError("%s: type %s != %s" + % (t1.name, t1.type_expr.string(), t2.type_expr.string())) + + def _check_function(self, f1, f2, strict=True): + if f1.name != f2.name: + raise ValueError("%s: name mismatch" % f1.name) + if f1.return_type != f2.return_type: + raise ValueError("%s: return type %s != %s" + % (f1.name, f1.return_type, f2.return_type)) + # there might be padded parameters + if strict and len(f1.parameters) != len(f2.parameters): + raise ValueError("%s: parameter length %d != %d" + % (f1.name, len(f1.parameters), len(f2.parameters))) + if f1.assign_offset != f2.assign_offset: + if ((f1.assign_offset and f2.offset < 0) or + (f2.assign_offset and f1.offset < 0)): + raise ValueError("%s: assign offset %d != %d" + % (f1.name, f1.assign_offset, f2.assign_offset)) + elif not f1.assign_offset: + if f1.offset != f2.offset: + raise ValueError("%s: offset %d != %d" + % (f1.name, f1.offset, f2.offset)) + + if strict: + l1 = f1.entry_points + l2 = f2.entry_points + l1.sort() + l2.sort() + if l1 != l2: + raise ValueError("%s: entry points %s != %s" + % (f1.name, l1, l2)) + + l1 = f1.static_entry_points + l2 = f2.static_entry_points + l1.sort() + l2.sort() + if l1 != l2: + raise ValueError("%s: static entry points %s != %s" + % (f1.name, l1, l2)) + + pad = 0 + for i in xrange(len(f1.parameters)): + p1 = f1.parameters[i] + p2 = f2.parameters[i + pad] + + if not strict and p1.is_padding != p2.is_padding: + if p1.is_padding: + pad -= 1 + continue + else: + pad += 1 + p2 = f2.parameters[i + pad] + + if strict and p1.name != p2.name: + raise ValueError("%s: parameter %d name %s != %s" + % (f1.name, i, p1.name, p2.name)) + if p1.type_expr.string() != p2.type_expr.string(): + if (strict or + # special case + f1.name == "TexImage2D" and p1.name != "internalformat"): + raise ValueError("%s: parameter %s type %s != %s" + % (f1.name, p1.name, p1.type_expr.string(), + p2.type_expr.string())) + + def union(self, other): + union = gl_XML.gl_api(None) + + if "enum" in self.elts: + union.enums_by_name = other.enums_by_name.copy() + for key, val in self.api.enums_by_name.iteritems(): + if key not in union.enums_by_name: + union.enums_by_name[key] = val + else: + self._check_enum(val, other.enums_by_name[key]) + + if "type" in self.elts: + union.types_by_name = other.types_by_name.copy() + for key, val in self.api.types_by_name.iteritems(): + if key not in union.types_by_name: + union.types_by_name[key] = val + else: + self._check_type(val, other.types_by_name[key]) + + if "function" in self.elts: + union.functions_by_name = other.functions_by_name.copy() + for key, val in self.api.functions_by_name.iteritems(): + if key not in union.functions_by_name: + union.functions_by_name[key] = val + else: + self._check_function(val, other.functions_by_name[key]) + + return union + + def intersection(self, other): + intersection = gl_XML.gl_api(None) + + if "enum" in self.elts: + for key, val in self.api.enums_by_name.iteritems(): + if key in other.enums_by_name: + self._check_enum(val, other.enums_by_name[key]) + intersection.enums_by_name[key] = val + + if "type" in self.elts: + for key, val in self.api.types_by_name.iteritems(): + if key in other.types_by_name: + self._check_type(val, other.types_by_name[key]) + intersection.types_by_name[key] = val + + if "function" in self.elts: + for key, val in self.api.functions_by_name.iteritems(): + if key in other.functions_by_name: + self._check_function(val, other.functions_by_name[key]) + intersection.functions_by_name[key] = val + + return intersection + + def difference(self, other): + difference = gl_XML.gl_api(None) + + if "enum" in self.elts: + for key, val in self.api.enums_by_name.iteritems(): + if key not in other.enums_by_name: + difference.enums_by_name[key] = val + else: + self._check_enum(val, other.enums_by_name[key]) + + if "type" in self.elts: + for key, val in self.api.types_by_name.iteritems(): + if key not in other.types_by_name: + difference.types_by_name[key] = val + else: + self._check_type(val, other.types_by_name[key]) + + if "function" in self.elts: + for key, val in self.api.functions_by_name.iteritems(): + if key not in other.functions_by_name: + difference.functions_by_name[key] = val + else: + self._check_function(val, other.functions_by_name[key], False) + + return difference + +def cmp_enum(e1, e2): + if e1.value < e2.value: + return -1 + elif e1.value > e2.value: + return 1 + else: + return 0 + +def cmp_type(t1, t2): + return t1.size - t2.size + +def cmp_function(f1, f2): + if f1.name > f2.name: + return 1 + elif f1.name < f2.name: + return -1 + else: + return 0 + +def spaces(n, str=""): + spaces = n - len(str) + if spaces < 1: + spaces = 1 + return " " * spaces + +def output_enum(e, indent=0): + attrs = 'name="%s"' % e.name + if e.default_count > 0: + tab = spaces(37, attrs) + attrs += '%scount="%d"' % (tab, e.default_count) + tab = spaces(48, attrs) + val = "%04x" % e.value + val = "0x" + val.upper() + attrs += '%svalue="%s"' % (tab, val) + + # no child + if not e.functions: + print '%s<enum %s/>' % (spaces(indent), attrs) + return + + print '%s<enum %s>' % (spaces(indent), attrs) + for key, val in e.functions.iteritems(): + attrs = 'name="%s"' % key + if val[0] != e.default_count: + attrs += ' count="%d"' % val[0] + if not val[1]: + attrs += ' mode="get"' + + print '%s<size %s/>' % (spaces(indent * 2), attrs) + + print '%s</enum>' % spaces(indent) + +def output_type(t, indent=0): + tab = spaces(16, t.name) + attrs = 'name="%s"%ssize="%d"' % (t.name, tab, t.size) + ctype = t.type_expr.string() + if ctype.find("unsigned") != -1: + attrs += ' unsigned="true"' + elif ctype.find("signed") == -1: + attrs += ' float="true"' + print '%s<type %s/>' % (spaces(indent), attrs) + +def output_function(f, indent=0): + attrs = 'name="%s"' % f.name + if f.offset > 0: + if f.assign_offset: + attrs += ' offset="assign"' + else: + attrs += ' offset="%d"' % f.offset + print '%s<function %s>' % (spaces(indent), attrs) + + for p in f.parameters: + attrs = 'name="%s" type="%s"' \ + % (p.name, p.type_expr.original_string) + print '%s<param %s/>' % (spaces(indent * 2), attrs) + if f.return_type != "void": + attrs = 'type="%s"' % f.return_type + print '%s<return %s/>' % (spaces(indent * 2), attrs) + + print '%s</function>' % spaces(indent) + +def output_category(api, indent=0): + enums = api.enums_by_name.values() + enums.sort(cmp_enum) + types = api.types_by_name.values() + types.sort(cmp_type) + functions = api.functions_by_name.values() + functions.sort(cmp_function) + + for e in enums: + output_enum(e, indent) + if enums and types: + print + for t in types: + output_type(t, indent) + if enums or types: + print + for f in functions: + output_function(f, indent) + if f != functions[-1]: + print + +def is_api_empty(api): + return bool(not api.enums_by_name and + not api.types_by_name and + not api.functions_by_name) + +def show_usage(ops): + print "Usage: %s [-k elts] <%s> <file1> <file2>" % (sys.argv[0], "|".join(ops)) + print " -k elts A comma separated string of types of elements to" + print " skip. Possible types are enum, type, and function." + sys.exit(1) + +def main(): + ops = ["union", "intersection", "difference"] + elts = ["enum", "type", "function"] + + try: + options, args = getopt.getopt(sys.argv[1:], "k:") + except Exception, e: + show_usage(ops) + + if len(args) != 3: + show_usage(ops) + op, file1, file2 = args + if op not in ops: + show_usage(ops) + + skips = [] + for opt, val in options: + if opt == "-k": + skips = val.split(",") + + for elt in skips: + try: + elts.remove(elt) + except ValueError: + show_usage(ops) + + api1 = gl_XML.parse_GL_API(file1, glX_XML.glx_item_factory()) + api2 = gl_XML.parse_GL_API(file2, glX_XML.glx_item_factory()) + + set = ApiSet(api1, elts) + func = getattr(set, op) + result = func(api2) + + if not is_api_empty(result): + cat_name = "%s_of_%s_and_%s" \ + % (op, os.path.basename(file1), os.path.basename(file2)) + + print '<?xml version="1.0"?>' + print '<!DOCTYPE OpenGLAPI SYSTEM "%s/gl_API.dtd">' % GLAPI + print + print '<OpenGLAPI>' + print + print '<category name="%s">' % (cat_name) + output_category(result, 4) + print '</category>' + print + print '</OpenGLAPI>' + +if __name__ == "__main__": + main() |