summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <olv@lunarg.com>2010-12-07 10:15:50 +0800
committerChia-I Wu <olv@lunarg.com>2011-01-20 17:15:49 +0800
commitf71a9acf59a2cd6396fb57afe57d7808df0bb82b (patch)
tree610ebdbccd6bfd717f411a4f2afe823095e752d9 /src
parent323b5e323adad55a0f941c0765b9d1224927cacb (diff)
mapi: Add the ability to parse GLAPI XML.
A prerequisite if we want to convert vgapi.csv to vgapi.xml, or to use mapi for glapi.
Diffstat (limited to 'src')
-rw-r--r--src/mapi/mapi/mapi_abi.py81
1 files changed, 76 insertions, 5 deletions
diff --git a/src/mapi/mapi/mapi_abi.py b/src/mapi/mapi/mapi_abi.py
index 5c212420a8..1db6cf3911 100644
--- a/src/mapi/mapi/mapi_abi.py
+++ b/src/mapi/mapi/mapi_abi.py
@@ -126,6 +126,61 @@ class ABIEntry(object):
return res
+def abi_parse_xml(xml):
+ """Parse a GLAPI XML file for ABI entries."""
+ import os
+ GLAPI = "./%s/../glapi/gen" % (os.path.dirname(sys.argv[0]))
+ sys.path.append(GLAPI)
+ import gl_XML, glX_XML
+
+ api = gl_XML.parse_GL_API(xml, glX_XML.glx_item_factory())
+
+ entry_dict = {}
+ for func in api.functionIterateByOffset():
+ # make sure func.name appear first
+ entry_points = func.entry_points[:]
+ entry_points.remove(func.name)
+ entry_points.insert(0, func.name)
+
+ for name in entry_points:
+ attrs = {
+ 'slot': func.offset,
+ 'hidden': not func.is_static_entry_point(name),
+ 'alias': None if name == func.name else func.name,
+ 'handcode': bool(func.has_different_protocol(name)),
+ }
+
+ # post-process attrs
+ if attrs['alias']:
+ try:
+ alias = entry_dict[attrs['alias']]
+ except KeyError:
+ raise Exception('failed to alias %s' % attrs['alias'])
+ if alias.alias:
+ raise Exception('recursive alias %s' % ent.name)
+ attrs['alias'] = alias
+ if attrs['handcode']:
+ attrs['handcode'] = func.static_glx_name(name)
+ else:
+ attrs['handcode'] = None
+
+ if entry_dict.has_key(name):
+ raise Exception('%s is duplicated' % (name))
+
+ cols = []
+ cols.append(func.return_type)
+ cols.append(name)
+ params = func.get_parameter_string(name)
+ cols.extend([p.strip() for p in params.split(',')])
+
+ ent = ABIEntry(cols, attrs)
+ entry_dict[ent.name] = ent
+
+ entries = entry_dict.values()
+ entries.sort()
+
+ return entries
+
def abi_parse_line(line):
cols = [col.strip() for col in line.split(',')]
@@ -194,9 +249,16 @@ def abi_parse(filename):
entries = entry_dict.values()
entries.sort()
- # sanity check
+ return entries
+
+def abi_sanity_check(entries):
+ if not entries:
+ return
+
+ all_names = []
+ last_slot = entries[-1].slot
i = 0
- for slot in xrange(next_slot):
+ for slot in xrange(last_slot + 1):
if entries[i].slot != slot:
raise Exception('entries are not ordered by slots')
if entries[i].alias:
@@ -210,12 +272,16 @@ def abi_parse(filename):
elif ent.handcode != handcode:
raise Exception('two aliases with handcode %s != %s',
ent.handcode, handcode)
+
+ if ent.name in all_names:
+ raise Exception('%s is duplicated' % (ent.name))
+ if ent.alias and ent.alias.name not in all_names:
+ raise Exception('failed to alias %s' % (ent.alias.name))
+ all_names.append(ent.name)
i += 1
if i < len(entries):
raise Exception('there are %d invalid entries' % (len(entries) - 1))
- return entries
-
class ABIPrinter(object):
"""MAPI Printer"""
@@ -651,7 +717,12 @@ def main():
filename, options = parse_args()
- entries = abi_parse(filename)
+ if filename.endswith('.xml'):
+ entries = abi_parse_xml(filename)
+ else:
+ entries = abi_parse(filename)
+ abi_sanity_check(entries)
+
printer = printers[options.printer](entries)
if options.mode == 'lib':
printer.output_for_lib()