mapi: Rewrite mapi_abi.py to get rid of preprocessor magic.
authorChia-I Wu <olv@lunarg.com>
Mon, 6 Dec 2010 02:27:39 +0000 (10:27 +0800)
committerChia-I Wu <olv@lunarg.com>
Mon, 6 Dec 2010 07:40:37 +0000 (15:40 +0800)
The preprocessor magic in mapi was nothing but obfuscation.  Rewrite
mapi_abi.py to generate real C code.

This commit removes the hack added in
43121f20866bb89e8dac92bd92ec85a943704b7e.

13 files changed:
src/gallium/state_trackers/vega/.gitignore [new file with mode: 0644]
src/gallium/state_trackers/vega/Makefile
src/gallium/state_trackers/vega/SConscript
src/gallium/state_trackers/vega/api.c
src/gallium/state_trackers/vega/api.h
src/mapi/mapi/mapi.c
src/mapi/mapi/mapi_abi.py
src/mapi/mapi/mapi_tmp.h
src/mapi/mapi/stub.c
src/mapi/mapi/table.h
src/mapi/vgapi/Makefile
src/mapi/vgapi/SConscript
src/mapi/vgapi/vgapi_defines.h [deleted file]

diff --git a/src/gallium/state_trackers/vega/.gitignore b/src/gallium/state_trackers/vega/.gitignore
new file mode 100644 (file)
index 0000000..c452229
--- /dev/null
@@ -0,0 +1 @@
+api_tmp.h
index deafa39aa62f103b39316299456436543785bb4d..7342c124c287469a47de5b7cf2b19b7928373f1a 100644 (file)
@@ -42,4 +42,10 @@ C_SOURCES = \
            shader.c \
            shaders_cache.c
 
+GENERATED_SOURCES := api_tmp.h
+
 include ../../Makefile.template
+
+MAPI := $(TOP)/src/mapi
+api_tmp.h: $(MAPI)/mapi/mapi_abi.py $(MAPI)/vgapi/vgapi.csv
+       $(PYTHON2) $< --printer vgapi --mode app $(MAPI)/vgapi/vgapi.csv > $@
index a62783ab18e53152539019e5dd893bcc0f704803..4900135a1c53d5fdaa9b3ddb07bfd90bd16c6737 100644 (file)
@@ -3,6 +3,8 @@
 
 Import('*')
 
+from sys import executable as python_cmd
+
 env = env.Clone()
 
 env.Append(CPPPATH = [
@@ -40,10 +42,16 @@ vega_sources = [
     'mask.c',
     'shader.c',
     'shaders_cache.c',
+    'text.c',
 ]
 
-# vgapi_header must be generated first
-env.Depends(vega_sources, vgapi_header)
+api_tmp = env.CodeGenerate(
+        target = '#/src/gallium/state_trackers/vega/api_tmp.h',
+        script = '#src/mapi/mapi/mapi_abi.py',
+        source = '#src/mapi/vgapi/vgapi.csv',
+        command = python_cmd + ' $SCRIPT --printer vgapi --mode app $SOURCE > $TARGET'
+)
+env.Depends(vega_sources, api_tmp)
 
 st_vega = env.ConvenienceLibrary(
     target = 'st_vega',
index bf1d37493af7296cd235011e0e889e14afb4ba13..4bf7c71d45346c186fa83b4916b2fd91be5d9241 100644 (file)
 
 #include "mapi/mapi.h"
 
+/* define vega_spec and vega_procs for use with mapi */
+#define API_TMP_DEFINE_SPEC
 #include "api.h"
 
-static const char vega_spec[] =
-   "1"
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   "\0" #name "\0"
-#define MAPI_ALIAS_ENTRY(alias, ret, name, params) \
-   #name "\0"
-#include "vgapi/vgapi_tmp.h"
-   "\0";
-
-static const mapi_proc vega_procs[] = {
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   (mapi_proc) vega ## name,
-#include "vgapi/vgapi_tmp.h"
-};
-
 static void api_init(void)
 {
    static boolean initialized = FALSE;
index 955508dae9a0418eae1183eb917b1c55ae816fe3..459dafb4bb01f76d943a9db77abd4647faa3b228 100644 (file)
 #include "VG/vgext.h"
 #include "vg_manager.h"
 
-/* declare the prototypes */
-#define MAPI_ABI_ENTRY(ret, name, params) \
-   ret VG_API_ENTRY vega ## name params;
-#include "vgapi/vgapi_tmp.h"
+#include "api_tmp.h"
 
 struct mapi_table;
 
index 2f1c3fff6ccee372a73be77420e250742f42f9a7..5476d37fdc9fc931a74ed6fa3fbd287fda993001 100644 (file)
@@ -36,8 +36,7 @@
 #include "table.h"
 
 /* dynamic stubs will run out before this array */
-#define MAPI_MAX_STUBS (sizeof(struct mapi_table) / sizeof(mapi_func))
-static const struct mapi_stub *mapi_stub_map[MAPI_MAX_STUBS];
+static const struct mapi_stub *mapi_stub_map[MAPI_TABLE_NUM_SLOTS];
 static int mapi_num_stubs;
 
 static const struct mapi_stub *
@@ -145,9 +144,9 @@ mapi_table_create(void)
    const struct mapi_table *noop = table_get_noop();
    struct mapi_table *tbl;
 
-   tbl = malloc(sizeof(*tbl));
+   tbl = malloc(MAPI_TABLE_SIZE);
    if (tbl)
-      memcpy(tbl, noop, sizeof(*tbl));
+      memcpy(tbl, noop, MAPI_TABLE_SIZE);
 
    return tbl;
 }
index 440eb4bb9c06e059ced9b7938d890bcd7565548f..3a872666f965959d70cb1135adcf679129df3372 100644 (file)
@@ -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()
index 79beca47d2a1e038aa5690867ab0254b743563ec..a1b067fb73ce41fa9d5cedde60a6de59160b3938 100644 (file)
  *    Chia-I Wu <olv@lunarg.com>
  */
 
-#include "u_macros.h"
-
 #ifndef MAPI_ABI_HEADER
 #error "MAPI_ABI_HEADER must be defined"
 #endif
 
-
-/**
- * Get API defines.
- */
-#ifdef MAPI_TMP_DEFINES
-#   define MAPI_ABI_DEFINES
-#   include MAPI_ABI_HEADER
-
-#ifndef MAPI_ABI_PREFIX
-#error "MAPI_ABI_PREFIX must be defined"
-#endif
-#ifndef MAPI_ABI_PUBLIC
-#error "MAPI_ABI_PUBLIC must be defined"
-#endif
-#ifndef MAPI_ABI_ATTR
-#error "MAPI_ABI_ATTR must be defined"
-#endif
-
-#undef MAPI_TMP_DEFINES
-#endif /* MAPI_TMP_DEFINES */
-
-
-/**
- * Generate fields of struct mapi_table.
- */
-#ifdef MAPI_TMP_TABLE
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      ret (MAPI_ABI_ATTR *name) params;
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      ret (MAPI_ABI_ATTR *name) params;
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_TABLE
-#endif /* MAPI_TMP_TABLE */
-
-
-/**
- * Declare public entries.
- */
-#ifdef MAPI_TMP_PUBLIC_DECLARES
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      MAPI_ABI_PUBLIC ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params);
-#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)            \
-      HIDDEN ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params;
-#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)   \
-      MAPI_ABI_ENTRY_HIDDEN(ret, name, params)
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_PUBLIC_DECLARES
-#endif /* MAPI_TMP_PUBLIC_DECLARES */
-
-
-/**
- * Generate string pool and public stubs.
- */
-#ifdef MAPI_TMP_PUBLIC_STUBS
-/* define the string pool */
-static const char public_string_pool[] =
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      U_STRINGIFY(name) "\0"
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   include MAPI_ABI_HEADER
-   ;
-/* define public_sorted_indices */
-#   define MAPI_ABI_SORTED_INDICES public_sorted_indices
-#   include MAPI_ABI_HEADER
-
-/* define public_stubs */
-static const struct mapi_stub public_stubs[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      { (mapi_func) U_CONCAT(MAPI_ABI_PREFIX, name),           \
-         MAPI_SLOT_ ## name, (void *) MAPI_POOL_ ## name },
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   include MAPI_ABI_HEADER
-   { NULL, -1, (void *) -1 }
-};
-
-#undef MAPI_TMP_PUBLIC_STUBS
-#endif /* MAPI_TMP_PUBLIC_STUBS */
-
-
-/**
- * Generate public entries.
- */
-#ifdef MAPI_TMP_PUBLIC_ENTRIES
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      ret MAPI_ABI_ATTR U_CONCAT(MAPI_ABI_PREFIX, name) params
-#   define MAPI_ABI_CODE(ret, name, args)                      \
-      {                                                        \
-         const struct mapi_table *tbl = u_current_get();       \
-         tbl->name args;                                       \
-      }
-#   define MAPI_ABI_CODE_RETURN(ret, name, args)               \
-      {                                                        \
-         const struct mapi_table *tbl = u_current_get();       \
-         return tbl->name args;                                \
-      }
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)          \
-      MAPI_ABI_ENTRY(ret, name, params)
-#   define MAPI_ALIAS_CODE(alias, ret, name, args)             \
-      MAPI_ABI_CODE(ret, alias, args)
-#   define MAPI_ALIAS_CODE_RETURN(alias, ret, name, args)      \
-      MAPI_ABI_CODE_RETURN(ret, alias, args)
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_PUBLIC_ENTRIES
-#endif /* MAPI_TMP_PUBLIC_ENTRIES */
-
-
-/**
- * Generate noop entries.
- */
-#ifdef MAPI_TMP_NOOP_ARRAY
-#ifdef DEBUG
-#   define MAPI_ABI_ENTRY(ret, name, params)                         \
-      static ret MAPI_ABI_ATTR U_CONCAT(noop_, name) params
-#   define MAPI_ABI_CODE(ret, name, args)                            \
-      {                                                              \
-         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
-      }
-#   define MAPI_ABI_CODE_RETURN(ret, name, args)                     \
-      {                                                              \
-         noop_warn(U_CONCAT_STR(MAPI_ABI_PREFIX, name));             \
-         return (ret) 0;                                             \
-      }
-#   include MAPI_ABI_HEADER
-
-/* define the noop function array that may be casted to mapi_table */
-const mapi_func table_noop_array[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      (mapi_func) U_CONCAT(noop_, name),
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      (mapi_func) noop_generic,
-#   include MAPI_ABI_HEADER
-      (mapi_func) noop_generic
-};
-
-#else /* DEBUG */
-
-const mapi_func table_noop_array[] = {
-#   define MAPI_ABI_ENTRY(ret, name, params)                   \
-      (mapi_func) noop_generic,
-#   define MAPI_DYNAMIC_ENTRY(ret, name, params)               \
-      (mapi_func) noop_generic,
-#   include MAPI_ABI_HEADER
-      (mapi_func) noop_generic
-};
-
-#endif /* DEBUG */
-#undef MAPI_TMP_NOOP_ARRAY
-#endif /* MAPI_TMP_NOOP_ARRAY */
-
-
-#ifdef MAPI_TMP_STUB_ASM_GCC
-#   define STUB_ASM_ALIAS(func, to)    \
-      ".globl " func "\n"              \
-      ".set " func ", " to
-#   define STUB_ASM_HIDE(func)         \
-      ".hidden " func
-
-#   define MAPI_ABI_ENTRY(ret, name, params)                         \
-      __asm__(STUB_ASM_ENTRY(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));
-#   define MAPI_ABI_CODE(ret, name, args)                            \
-      __asm__(STUB_ASM_CODE(U_STRINGIFY(MAPI_SLOT_ ## name)));
-#   define MAPI_ALIAS_ENTRY(alias, ret, name, params)                \
-      __asm__(STUB_ASM_ALIAS(U_CONCAT_STR(MAPI_ABI_PREFIX, name),    \
-            U_CONCAT_STR(MAPI_ABI_PREFIX, alias)));
-#   define MAPI_ABI_ENTRY_HIDDEN(ret, name, params)                  \
-      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
-      MAPI_ABI_ENTRY(ret, name, params);
-#   define MAPI_ALIAS_ENTRY_HIDDEN(alias, ret, name, params)         \
-      __asm__(STUB_ASM_HIDE(U_CONCAT_STR(MAPI_ABI_PREFIX, name)));   \
-      MAPI_ALIAS_ENTRY(alias, ret, name, params);
-#   include MAPI_ABI_HEADER
-#undef MAPI_TMP_STUB_ASM_GCC
-#endif /* MAPI_TMP_STUB_ASM_GCC */
+#include MAPI_ABI_HEADER
index 53d800f3c2aac5d39dbda3a8934b53d6d519b266..3594eacb4ecabb0e359b2ca0f0619b2ea5ae4dac 100644 (file)
 #include "stub.h"
 #include "table.h"
 
-/* XXX: Hack to avoid vgCreateFont being generated as vgCreateFontA */
-#undef CreateFont
-
-#define MAPI_TABLE_FIRST_DYNAMIC \
-   (offsetof(struct mapi_table, dynamic0) / sizeof(mapi_func))
-#define MAPI_TABLE_NUM_DYNAMIC \
-   ((offsetof(struct mapi_table, last) - \
-     offsetof(struct mapi_table, dynamic0)) / sizeof(mapi_func))
 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
 
-/*
- * This will define public_string_pool, public_sorted_indices, and
- * public_stubs.
- */
+/* define public_string_pool and public_stubs */
 #define MAPI_TMP_PUBLIC_STUBS
 #include "mapi_tmp.h"
 
 static struct mapi_stub dynamic_stubs[MAPI_TABLE_NUM_DYNAMIC];
 static int num_dynamic_stubs;
-static int next_dynamic_slot = MAPI_TABLE_FIRST_DYNAMIC;
+static int next_dynamic_slot = MAPI_TABLE_NUM_STATIC;
 
 void
 stub_init_once(void)
@@ -77,11 +66,9 @@ static int
 stub_compare(const void *key, const void *elem)
 {
    const char *name = (const char *) key;
-   const int *index = (const int *) elem;
-   const struct mapi_stub *stub;
+   const struct mapi_stub *stub = (const struct mapi_stub *) elem;
    const char *stub_name;
 
-   stub = &public_stubs[*index];
    stub_name = &public_string_pool[(unsigned long) stub->name];
 
    return strcmp(name, stub_name);
@@ -93,13 +80,8 @@ stub_compare(const void *key, const void *elem)
 const struct mapi_stub *
 stub_find_public(const char *name)
 {
-   const int *index;
-
-   index = (const int *) bsearch(name, public_sorted_indices,
-         ARRAY_SIZE(public_sorted_indices) - 1,
-         sizeof(public_sorted_indices[0]), stub_compare);
-
-   return (index) ? &public_stubs[*index] : NULL;
+   return (const struct mapi_stub *) bsearch(name, public_stubs,
+         ARRAY_SIZE(public_stubs), sizeof(public_stubs[0]), stub_compare);
 }
 
 /**
@@ -112,14 +94,15 @@ stub_add_dynamic(const char *name)
    int idx;
 
    idx = num_dynamic_stubs;
-   if (idx >= MAPI_TABLE_NUM_DYNAMIC)
+   /* minus 1 to make sure we can never reach the last slot */
+   if (idx >= MAPI_TABLE_NUM_DYNAMIC - 1)
       return NULL;
 
    stub = &dynamic_stubs[idx];
 
-   /* dispatch to mapi_table->last, which is always no-op */
-   stub->addr =
-      entry_generate(MAPI_TABLE_FIRST_DYNAMIC + MAPI_TABLE_NUM_DYNAMIC);
+   /* dispatch to the last slot, which is reserved for no-op */
+   stub->addr = entry_generate(
+         MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC - 1);
    if (!stub->addr)
       return NULL;
 
index 48c99018aa39828189859274fe793bb5d0a8ef47..ca2be568c705d4a18f1bbd7724bc46a74f847262 100644 (file)
 #include "stub.h"
 
 #define MAPI_TMP_DEFINES
-#include "mapi_tmp.h"
-
-struct mapi_table {
 #define MAPI_TMP_TABLE
 #include "mapi_tmp.h"
-   mapi_func last;
-};
+
+#define MAPI_TABLE_NUM_SLOTS (MAPI_TABLE_NUM_STATIC + MAPI_TABLE_NUM_DYNAMIC)
+#define MAPI_TABLE_SIZE (MAPI_TABLE_NUM_SLOTS * sizeof(mapi_func))
 
 extern const mapi_func table_noop_array[];
 
index 702db03d1542aae9e526cbce53d4dff8d1f51ec0..e239e20987e7d80ba720f623fd1c39cab1ef15f6 100644 (file)
@@ -44,7 +44,7 @@ $(VGAPI_OBJECTS): %.o: $(MAPI)/%.c
 
 vgapi_tmp.h: vgapi.csv $(MAPI)/mapi_abi.py
        $(PYTHON2) $(PYTHON_FLAGS) $(MAPI)/mapi_abi.py \
-               -i vgapi/vgapi_defines.h $< > $@
+               --printer vgapi --mode lib $< > $@
 
 .PHONY: clean
 clean:
@@ -87,3 +87,5 @@ depend: $(VGAPI_SOURCES)
        @$(MKDEP) $(MKDEP_OPTIONS) -f- $(DEFINES) $(INCLUDE_DIRS) \
                $(VGAPI_CPPFLAGS) $(VGAPI_SOURCES) 2>/dev/null | \
                sed -e 's,^$(MAPI)/,,' > depend
+
+-include depend
index 20d7f2744d09c3605fe0895dc179d411b76ec104..42d86b69eefa40fdf5c4785ba2598f8048868b1f 100644 (file)
@@ -13,7 +13,7 @@ if env['platform'] != 'winddk':
                target = '#src/mapi/vgapi/vgapi_tmp.h',
                script = '../mapi/mapi_abi.py',
                source = 'vgapi.csv',
-               command = python_cmd + ' $SCRIPT -i vgapi/vgapi_defines.h $SOURCE > $TARGET'
+               command = python_cmd + ' $SCRIPT --printer vgapi --mode lib $SOURCE > $TARGET'
        )
 
        env.Append(CPPDEFINES = [
@@ -53,4 +53,4 @@ if env['platform'] != 'winddk':
 
        vgapi = [env.FindIxes(openvg, 'LIBPREFIX', 'LIBSUFFIX')]
 
-       Export(['vgapi', 'vgapi_header'])
+       Export(['vgapi'])
diff --git a/src/mapi/vgapi/vgapi_defines.h b/src/mapi/vgapi/vgapi_defines.h
deleted file mode 100644 (file)
index fb9f68c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef VGAPI_DEFINES_H
-#define VGAPI_DEFINES_H
-
-#include "VG/openvg.h"
-#include "VG/vgext.h"
-
-#define MAPI_ABI_PREFIX vg
-#define MAPI_ABI_PUBLIC VG_API_CALL
-#define MAPI_ABI_ATTR VG_API_ENTRY
-
-#endif /* VGAPI_DEFINES_H */