summaryrefslogtreecommitdiff
path: root/src/mapi/mapi/mapi_abi.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mapi/mapi/mapi_abi.py')
-rw-r--r--src/mapi/mapi/mapi_abi.py449
1 files changed, 304 insertions, 145 deletions
diff --git a/src/mapi/mapi/mapi_abi.py b/src/mapi/mapi/mapi_abi.py
index 440eb4bb9c..3a872666f9 100644
--- a/src/mapi/mapi/mapi_abi.py
+++ b/src/mapi/mapi/mapi_abi.py
@@ -202,201 +202,360 @@ def abi_parse(filename):
return entries
-def abi_dynamics():
- """Return the dynamic entries."""
- entries = []
- for i in xrange(ABI_NUM_DYNAMIC_ENTRIES):
- cols = ['void', 'dynamic%d' % (i), 'void']
- attrs = { 'slot': -1, 'hidden': False, 'alias': None }
- entries.append(ABIEntry(cols, attrs))
- return entries
-
class ABIPrinter(object):
- """ABIEntry Printer"""
+ """MAPI Printer"""
- def __init__(self, entries, options):
+ def __init__(self, entries):
self.entries = entries
- self.options = options
- self._undefs = []
- def _add_undefs(self, undefs):
- self._undefs.extend(undefs)
+ # sort entries by their names
+ self.entries_sorted_by_names = self.entries[:]
+ self.entries_sorted_by_names.sort(lambda x, y: cmp(x.name, y.name))
- def output_header(self):
- print '/* This file is automatically generated. Do not modify. */'
- print
+ self.indent = ' ' * 3
+ self.noop_warn = 'noop_warn'
+ self.noop_generic = 'noop_generic'
- def output_footer(self):
- print '/* clean up */'
- for m in self._undefs:
- print '#undef %s' % (m)
+ self.api_defines = []
+ self.api_headers = ['"KHR/khrplatform.h"']
+ self.api_call = 'KHRONOS_APICALL'
+ self.api_entry = 'KHRONOS_APIENTRY'
+ self.api_attrs = 'KHRONOS_APIATTRIBUTES'
- def output_entry(self, ent):
- if ent.slot < 0:
- out_ent = 'MAPI_DYNAMIC_ENTRY(%s, %s, (%s))' % \
- (ent.c_return(), ent.name, ent.c_params())
- out_code = ''
- else:
+ def c_header(self):
+ return '/* This file is automatically generated by mapi_abi.py. Do not modify. */'
+
+ def c_includes(self):
+ """Return includes of the client API headers."""
+ defines = ['#define ' + d for d in self.api_defines]
+ includes = ['#include ' + h for h in self.api_headers]
+ return "\n".join(defines + includes)
+
+ def c_mapi_table(self):
+ """Return defines of the dispatch table size."""
+ num_static_entries = 0
+ for ent in self.entries:
+ if not ent.alias:
+ num_static_entries += 1
+
+ return ('#define MAPI_TABLE_NUM_STATIC %d\n' + \
+ '#define MAPI_TABLE_NUM_DYNAMIC %d') % (
+ num_static_entries, ABI_NUM_DYNAMIC_ENTRIES)
+
+ def c_mapi_table_initializer(self, prefix):
+ """Return the array initializer for mapi_table_fill."""
+ entries = [ent.name for ent in self.entries if not ent.alias]
+ pre = self.indent + '(mapi_proc) ' + prefix
+ return pre + (',\n' + pre).join(entries)
+
+ def c_mapi_table_spec(self):
+ """Return the spec for mapi_init."""
+ specv1 = []
+ line = '"1'
+ for ent in self.entries:
+ if not ent.alias:
+ line += '\\0"\n'
+ specv1.append(line)
+ line = '"'
+ line += '%s\\0' % ent.name
+ line += '";'
+ specv1.append(line)
+
+ return self.indent + self.indent.join(specv1)
+
+ def _c_decl(self, ent, prefix, need_attr=True):
+ """Return the C declaration for the entry."""
+ decl = '%s %s %s%s(%s)' % (ent.c_return(), self.api_entry,
+ prefix, ent.name, ent.c_params())
+ if need_attr and self.api_attrs:
+ decl += ' ' + self.api_attrs
+
+ return decl
+
+ def _c_cast(self, ent):
+ """Return the C cast for the entry."""
+ cast = '%s (%s *)(%s)' % (
+ ent.c_return(), self.api_entry, ent.c_params())
+
+ return cast
+
+ def c_private_declarations(self, prefix):
+ """Return the declarations of private functions."""
+ decls = [self._c_decl(ent, prefix)
+ for ent in self.entries if not ent.alias]
+
+ return ";\n".join(decls) + ";"
+
+ def c_public_dispatches(self, prefix):
+ """Return the public dispatch functions."""
+ dispatches = []
+ for ent in self.entries:
+ if ent.hidden:
+ continue
+
+ proto = self.api_call + ' ' + self._c_decl(ent, prefix)
+ cast = self._c_cast(ent)
+
+ ret = ''
+ if ent.ret:
+ ret = 'return '
+ stmt1 = self.indent
+ stmt1 += 'const struct mapi_table *tbl = u_current_get();'
+ stmt2 = self.indent
+ stmt2 += 'mapi_func func = ((const mapi_func *) tbl)[%d];' % (
+ ent.slot)
+ stmt3 = self.indent
+ stmt3 += '%s((%s) func)(%s);' % (ret, cast, ent.c_args())
+
+ disp = '%s\n{\n%s\n%s\n%s\n}' % (proto, stmt1, stmt2, stmt3)
+ dispatches.append(disp)
+
+ return '\n\n'.join(dispatches)
+
+ def c_stub_string_pool(self):
+ """Return the string pool for use by stubs."""
+ # sort entries by their names
+ sorted_entries = self.entries[:]
+ sorted_entries.sort(lambda x, y: cmp(x.name, y.name))
+
+ pool = []
+ offsets = {}
+ count = 0
+ for ent in sorted_entries:
+ offsets[ent] = count
+ pool.append('%s' % (ent.name))
+ count += len(ent.name) + 1
+
+ pool_str = self.indent + '"' + \
+ ('\\0"\n' + self.indent + '"').join(pool) + '";'
+ return (pool_str, offsets)
+
+ def c_stub_initializer(self, prefix, pool_offsets):
+ """Return the initializer for struct mapi_stub array."""
+ stubs = []
+ for ent in self.entries_sorted_by_names:
+ stubs.append('%s{ (mapi_func) %s%s, %d, (void *) %d }' % (
+ self.indent, prefix, ent.name, ent.slot, pool_offsets[ent]))
+
+ return ',\n'.join(stubs)
+
+ def c_noop_functions(self, prefix, warn_prefix):
+ """Return the noop functions."""
+ noops = []
+ for ent in self.entries:
if ent.alias:
- macro_ent = 'MAPI_ALIAS_ENTRY'
- macro_code = 'MAPI_ALIAS_CODE'
- else:
- macro_ent = 'MAPI_ABI_ENTRY'
- macro_code = 'MAPI_ABI_CODE'
+ continue
+
+ proto = 'static ' + self._c_decl(ent, prefix)
+
+ stmt1 = self.indent + '%s("%s%s");' % (
+ self.noop_warn, warn_prefix, ent.name)
if ent.ret:
- macro_code += '_RETURN'
+ stmt2 = self.indent + 'return (%s) 0;' % (ent.ret)
+ noop = '%s\n{\n%s\n%s\n}' % (proto, stmt1, stmt2)
+ else:
+ noop = '%s\n{\n%s\n}' % (proto, stmt1)
+
+ noops.append(noop)
+
+ return '\n\n'.join(noops)
+
+ def c_noop_initializer(self, prefix, use_generic):
+ """Return an initializer for the noop dispatch table."""
+ entries = [prefix + ent.name for ent in self.entries if not ent.alias]
+ if use_generic:
+ entries = [self.noop_generic] * len(entries)
+
+ entries.extend([self.noop_generic] * ABI_NUM_DYNAMIC_ENTRIES)
+
+ pre = self.indent + '(mapi_func) '
+ return pre + (',\n' + pre).join(entries)
+
+ def c_asm_gcc(self, prefix):
+ asm = []
+ to_name = None
+
+ asm.append('__asm__(')
+ for ent in self.entries:
+ name = prefix + ent.name
+
if ent.hidden:
- macro_ent += '_HIDDEN'
- macro_code += '_HIDDEN'
+ asm.append('".hidden %s\\n"' % (name))
if ent.alias:
- out_ent = '%s(%s, %s, %s, (%s))' % (macro_ent,
- ent.alias, ent.c_return(), ent.name, ent.c_params())
- out_code = '%s(%s, %s, %s, (%s))' % (macro_code,
- ent.alias, ent.c_return(), ent.name, ent.c_args())
- else:
- out_ent = '%s(%s, %s, (%s))' % (macro_ent,
- ent.c_return(), ent.name, ent.c_params())
- out_code = '%s(%s, %s, (%s))' % (macro_code,
- ent.c_return(), ent.name, ent.c_args())
-
- print out_ent
- if out_code:
- print ' ' + out_code
-
- def output_entries(self, pool_offsets):
- defs = [
- # normal entries
- ('MAPI_ABI_ENTRY', '(ret, name, params)', ''),
- ('MAPI_ABI_CODE', '(ret, name, args)', ''),
- ('MAPI_ABI_CODE_RETURN', '', 'MAPI_ABI_CODE'),
- # alias entries
- ('MAPI_ALIAS_ENTRY', '(alias, ret, name, params)', ''),
- ('MAPI_ALIAS_CODE', '(alias, ret, name, args)', ''),
- ('MAPI_ALIAS_CODE_RETURN', '', 'MAPI_ALIAS_CODE'),
- # hidden normal entries
- ('MAPI_ABI_ENTRY_HIDDEN', '', 'MAPI_ABI_ENTRY'),
- ('MAPI_ABI_CODE_HIDDEN', '', 'MAPI_ABI_CODE'),
- ('MAPI_ABI_CODE_RETURN_HIDDEN', '', 'MAPI_ABI_CODE_RETURN'),
- # hidden alias entries
- ('MAPI_ALIAS_ENTRY_HIDDEN', '', 'MAPI_ALIAS_ENTRY'),
- ('MAPI_ALIAS_CODE_HIDDEN', '', 'MAPI_ALIAS_CODE'),
- ('MAPI_ALIAS_CODE_RETURN_HIDDEN', '', 'MAPI_ALIAS_CODE_RETURN'),
- # dynamic entries
- ('MAPI_DYNAMIC_ENTRY', '(ret, name, params)', ''),
- ]
- undefs = [d[0] for d in defs]
-
- print '#if defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN)'
- print
- for d in defs:
- print '#ifndef %s' % (d[0])
- if d[2]:
- print '#define %s%s %s' % d
+ asm.append('".globl %s\\n"' % (name))
+ asm.append('".set %s, %s\\n"' % (name, to_name))
else:
- print '#define %s%s' % d[:2]
+ asm.append('STUB_ASM_ENTRY("%s")"\\n"' % (name))
+ asm.append('"\\t"STUB_ASM_CODE("%d")"\\n"' % (ent.slot))
+ to_name = name
+ asm.append(');')
- print '#endif'
+ return "\n".join(asm)
+
+ def output_for_lib(self):
+ print self.c_header()
+ print
+ print '#ifdef MAPI_TMP_DEFINES'
+ print self.c_includes()
+ print '#undef MAPI_TMP_DEFINES'
+ print '#endif /* MAPI_TMP_DEFINES */'
+ print
+ print '#ifdef MAPI_TMP_TABLE'
+ print self.c_mapi_table()
+ print '#undef MAPI_TMP_TABLE'
+ print '#endif /* MAPI_TMP_TABLE */'
print
- print '/* see MAPI_TMP_TABLE */'
- for ent in self.entries:
- print '#define MAPI_SLOT_%s %d' % (ent.name, ent.slot)
+ pool, pool_offsets = self.c_stub_string_pool()
+ print '#ifdef MAPI_TMP_PUBLIC_STUBS'
+ print 'static const char public_string_pool[] ='
+ print pool
print
- print '/* see MAPI_TMP_PUBLIC_STUBS */'
- for ent in self.entries:
- print '#define MAPI_POOL_%s %d' % (ent.name, pool_offsets[ent])
+ print 'static const struct mapi_stub public_stubs[] = {'
+ print self.c_stub_initializer(self.prefix_lib, pool_offsets)
+ print '};'
+ print '#undef MAPI_TMP_PUBLIC_STUBS'
+ print '#endif /* MAPI_TMP_PUBLIC_STUBS */'
print
- # define macros that generate code
- for ent in self.entries:
- self.output_entry(ent)
+ print '#ifdef MAPI_TMP_PUBLIC_ENTRIES'
+ print self.c_public_dispatches(self.prefix_lib)
+ print '#undef MAPI_TMP_PUBLIC_ENTRIES'
+ print '#endif /* MAPI_TMP_PUBLIC_ENTRIES */'
+ print
+
+ print '#ifdef MAPI_TMP_NOOP_ARRAY'
+ print '#ifdef DEBUG'
+ print
+ print self.c_noop_functions(self.prefix_noop, self.prefix_lib)
print
- dynamics = abi_dynamics()
- for ent in dynamics:
- self.output_entry(ent)
+ print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+ print self.c_noop_initializer(self.prefix_noop, False)
+ print '};'
+ print
+ print '#else /* DEBUG */'
+ print
+ print 'const mapi_func table_%s_array[] = {' % (self.prefix_noop)
+ print self.c_noop_initializer(self.prefix_noop, True)
+ print '};'
+ print '#endif /* DEBUG */'
+ print '#undef MAPI_TMP_NOOP_ARRAY'
+ print '#endif /* MAPI_TMP_NOOP_ARRAY */'
print
- for ent in self.entries:
- print '#undef MAPI_SLOT_%s' % (ent.name)
- for ent in self.entries:
- print '#undef MAPI_POOL_%s' % (ent.name)
+ print '#ifdef MAPI_TMP_STUB_ASM_GCC'
+ print self.c_asm_gcc(self.prefix_lib)
+ print '#undef MAPI_TMP_STUB_ASM_GCC'
+ print '#endif /* MAPI_TMP_STUB_ASM_GCC */'
+
+ def output_for_app(self):
+ print self.c_header()
+ print
+ print self.c_private_declarations(self.prefix_app)
print
- print '#endif /* defined(MAPI_ABI_ENTRY) || defined(MAPI_ABI_ENTRY_HIDDEN) */'
+ print '#ifdef API_TMP_DEFINE_SPEC'
print
+ print 'static const char %s_spec[] =' % (self.prefix_app)
+ print self.c_mapi_table_spec()
+ print
+ print 'static const mapi_proc %s_procs[] = {' % (self.prefix_app)
+ print self.c_mapi_table_initializer(self.prefix_app)
+ print '};'
+ print
+ print '#endif /* API_TMP_DEFINE_SPEC */'
- self._add_undefs(undefs)
+class GLAPIPrinter(ABIPrinter):
+ """OpenGL API Printer"""
- def _get_string_pool(self):
- """Get the string pool."""
- pool = []
- offsets = {}
+ def __init__(self, entries):
+ super(GLAPIPrinter, self).__init__(entries)
- count = 0
- for ent in self.entries:
- offsets[ent] = count
- pool.append(ent.name + '\\0')
- count += len(ent.name) + 1
+ self.api_defines = ['GL_GLEXT_PROTOTYPES']
+ self.api_headers = ['"GL/gl.h"', '"GL/glext.h"']
+ self.api_call = 'GLAPI'
+ self.api_entry = 'APIENTRY'
+ self.api_attrs = ''
- return (pool, offsets)
+ self.prefix_lib = 'gl'
+ self.prefix_app = '_mesa_'
+ self.prefix_noop = 'noop'
- def output_sorted_indices(self):
- entry_index_pairs = []
- for i in xrange(len(self.entries)):
- entry_index_pairs.append((self.entries[i], i))
- entry_index_pairs.sort(lambda x, y: cmp(x[0].name, y[0].name))
+ def output_for_app(self):
+ # not used
+ pass
- print '/* see MAPI_TMP_PUBLIC_STUBS */'
- print '#ifdef MAPI_ABI_SORTED_INDICES'
- print
- print 'static const int MAPI_ABI_SORTED_INDICES[] = {'
- for ent, idx in entry_index_pairs:
- print ' %d, /* %s */' % (idx, ent.name)
- print ' -1'
- print '};'
- print
- print '#endif /* MAPI_ABI_SORTED_INDICES */'
- print
+class ES1APIPrinter(GLAPIPrinter):
+ """OpenGL ES 1.x API Printer"""
- self._add_undefs(['MAPI_ABI_SORTED_INDICES'])
+ def __init__(self, entries):
+ super(ES1APIPrinter, self).__init__(entries)
- def output_defines(self):
- print '/* ABI defines */'
- print '#ifdef MAPI_ABI_DEFINES'
- print '#include "%s"' % (self.options.include)
- print '#endif /* MAPI_ABI_DEFINES */'
- print
+ self.api_headers = ['"GLES/gl.h"', '"GLES/glext.h"']
+ self.api_call = 'GL_API'
+ self.api_entry = 'GL_APIENTRY'
+
+class ES2APIPrinter(GLAPIPrinter):
+ """OpenGL ES 2.x API Printer"""
+
+ def __init__(self, entries):
+ super(ES2APIPrinter, self).__init__(entries)
+
+ self.api_headers = ['"GLES2/gl2.h"', '"GLES2/gl2ext.h"']
+ self.api_call = 'GL_APICALL'
+ self.api_entry = 'GL_APIENTRY'
- self._add_undefs(['MAPI_ABI_DEFINES'])
+class VGAPIPrinter(ABIPrinter):
+ """OpenVG API Printer"""
- def output(self):
- pool, pool_offsets = self._get_string_pool()
+ def __init__(self, entries):
+ super(VGAPIPrinter, self).__init__(entries)
- self.output_header()
- self.output_defines()
- self.output_entries(pool_offsets)
- self.output_sorted_indices()
- self.output_footer()
+ self.api_defines = ['VG_VGEXT_PROTOTYPES']
+ self.api_headers = ['"VG/openvg.h"', '"VG/vgext.h"']
+ self.api_call = 'VG_API_CALL'
+ self.api_entry = 'VG_API_ENTRY'
+ self.api_attrs = 'VG_API_EXIT'
+
+ self.prefix_lib = 'vg'
+ self.prefix_app = 'vega'
+ self.prefix_noop = 'noop'
def parse_args():
+ printers = ['glapi', 'es1api', 'es2api', 'vgapi']
+ modes = ['lib', 'app']
+
parser = OptionParser(usage='usage: %prog [options] <filename>')
- parser.add_option('-i', '--include', dest='include',
- help='include the header for API defines')
+ parser.add_option('-p', '--printer', dest='printer',
+ help='printer to use: %s' % (", ".join(printers)))
+ parser.add_option('-m', '--mode', dest='mode',
+ help='target user: %s' % (", ".join(modes)))
options, args = parser.parse_args()
- if not args or not options.include:
+ if not args or options.printer not in printers or \
+ options.mode not in modes:
parser.print_help()
sys.exit(1)
return (args[0], options)
def main():
+ printers = {
+ 'vgapi': VGAPIPrinter,
+ 'glapi': GLAPIPrinter,
+ 'es1api': ES1APIPrinter,
+ 'es2api': ES2APIPrinter
+ }
+
filename, options = parse_args()
entries = abi_parse(filename)
- printer = ABIPrinter(entries, options)
- printer.output()
+ printer = printers[options.printer](entries)
+ if options.mode == 'lib':
+ printer.output_for_lib()
+ else:
+ printer.output_for_app()
if __name__ == '__main__':
main()