17ec681f3Smrg#!/usr/bin/env python3
2a8bb7a65Smaya
3a8bb7a65Smaya# Copyright (C) 2010 LunarG Inc.
4a8bb7a65Smaya# (C) Copyright 2015, NVIDIA CORPORATION.
5a8bb7a65Smaya#
6a8bb7a65Smaya# Permission is hereby granted, free of charge, to any person obtaining a
7a8bb7a65Smaya# copy of this software and associated documentation files (the "Software"),
8a8bb7a65Smaya# to deal in the Software without restriction, including without limitation
9a8bb7a65Smaya# the rights to use, copy, modify, merge, publish, distribute, sublicense,
10a8bb7a65Smaya# and/or sell copies of the Software, and to permit persons to whom the
11a8bb7a65Smaya# Software is furnished to do so, subject to the following conditions:
12a8bb7a65Smaya#
13a8bb7a65Smaya# The above copyright notice and this permission notice shall be included
14a8bb7a65Smaya# in all copies or substantial portions of the Software.
15a8bb7a65Smaya#
16a8bb7a65Smaya# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17a8bb7a65Smaya# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18a8bb7a65Smaya# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19a8bb7a65Smaya# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20a8bb7a65Smaya# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21a8bb7a65Smaya# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22a8bb7a65Smaya# DEALINGS IN THE SOFTWARE.
23a8bb7a65Smaya#
24a8bb7a65Smaya# Authors:
25a8bb7a65Smaya#    Kyle Brenneman <kbrenneman@nvidia.com>
26a8bb7a65Smaya#
27a8bb7a65Smaya# Based on code ogiginally by:
28a8bb7a65Smaya#    Chia-I Wu <olv@lunarg.com>
29a8bb7a65Smaya
30a8bb7a65Smaya
31a8bb7a65Smaya"""
32a8bb7a65SmayaGenerates the glapi_mapi_tmp.h header file from Khronos's XML file.
33a8bb7a65Smaya"""
34a8bb7a65Smaya
35a8bb7a65Smayaimport sys
367ec681f3Smrgimport xml.etree.ElementTree as etree
37a8bb7a65Smaya
38a8bb7a65Smayaimport genCommon
39a8bb7a65Smaya
40a8bb7a65Smayadef _main():
41a8bb7a65Smaya    target = sys.argv[1]
42a8bb7a65Smaya    xmlFiles = sys.argv[2:]
43a8bb7a65Smaya
44a8bb7a65Smaya    roots = [ etree.parse(filename).getroot() for filename in xmlFiles ]
45a8bb7a65Smaya    allFunctions = genCommon.getFunctionsFromRoots(roots)
46a8bb7a65Smaya
47a8bb7a65Smaya    names = genCommon.getExportNamesFromRoots(target, roots)
48a8bb7a65Smaya    functions = [f for f in allFunctions if(f.name in names)]
49a8bb7a65Smaya
50a8bb7a65Smaya    if (target in ("gl", "gldispatch")):
51a8bb7a65Smaya        assert(len(functions) == len(allFunctions))
52a8bb7a65Smaya        assert(all(functions[i] == allFunctions[i] for i in range(len(functions))))
53a8bb7a65Smaya        assert(all(functions[i].slot == i for i in range(len(functions))))
54a8bb7a65Smaya
55a8bb7a65Smaya    print(r"""
56a8bb7a65Smaya/* This file is automatically generated by mapi_abi.py.  Do not modify. */
57a8bb7a65Smaya
58a8bb7a65Smaya#ifndef _GLAPI_TMP_H_
59a8bb7a65Smaya#define _GLAPI_TMP_H_
60a8bb7a65Smayatypedef int GLclampx;
61a8bb7a65Smaya#endif /* _GLAPI_TMP_H_ */
62a8bb7a65Smaya""".lstrip("\n"))
63a8bb7a65Smaya
64a8bb7a65Smaya    print(generate_defines(functions))
65a8bb7a65Smaya    if target == "gldispatch":
66a8bb7a65Smaya        print(generate_table(functions, allFunctions))
67a8bb7a65Smaya        print(generate_noop_array(functions))
68a8bb7a65Smaya        print(generate_public_stubs(functions))
69a8bb7a65Smaya    print(generate_public_entries(functions))
70a8bb7a65Smaya    if target == "gldispatch":
71a8bb7a65Smaya        print(generate_public_entries_table(functions))
72a8bb7a65Smaya    print(generate_undef_public_entries())
73a8bb7a65Smaya    print(generate_stub_asm_gcc(functions))
74a8bb7a65Smaya
75a8bb7a65Smayadef generate_defines(functions):
76a8bb7a65Smaya    text = r"""
77a8bb7a65Smaya#ifdef MAPI_TMP_DEFINES
78a8bb7a65Smaya#define GL_GLEXT_PROTOTYPES
79a8bb7a65Smaya#include "GL/gl.h"
80a8bb7a65Smaya#include "GL/glext.h"
81a8bb7a65Smaya
82a8bb7a65Smaya""".lstrip("\n")
83a8bb7a65Smaya    for func in functions:
84a8bb7a65Smaya        text += "GLAPI {f.rt} APIENTRY {f.name}({f.decArgs});\n".format(f=func)
85a8bb7a65Smaya    text += "#undef MAPI_TMP_DEFINES\n"
86a8bb7a65Smaya    text += "#endif /* MAPI_TMP_DEFINES */\n"
87a8bb7a65Smaya    return text
88a8bb7a65Smaya
89a8bb7a65Smayadef generate_table(functions, allFunctions):
90a8bb7a65Smaya    text = "#ifdef MAPI_TMP_TABLE\n"
91a8bb7a65Smaya    text += "#define MAPI_TABLE_NUM_STATIC %d\n" % (len(allFunctions))
92a8bb7a65Smaya    text += "#define MAPI_TABLE_NUM_DYNAMIC %d\n" % (genCommon.MAPI_TABLE_NUM_DYNAMIC,)
93a8bb7a65Smaya    text += "#undef MAPI_TMP_TABLE\n"
94a8bb7a65Smaya    text += "#endif /* MAPI_TMP_TABLE */\n"
95a8bb7a65Smaya    return text
96a8bb7a65Smaya
97a8bb7a65Smayadef generate_noop_array(functions):
98a8bb7a65Smaya    text = "#ifdef MAPI_TMP_NOOP_ARRAY\n"
99a8bb7a65Smaya    text += "#ifdef DEBUG\n\n"
100a8bb7a65Smaya
101a8bb7a65Smaya    for func in functions:
102a8bb7a65Smaya        text += "static {f.rt} APIENTRY noop{f.basename}({f.decArgs})\n".format(f=func)
103a8bb7a65Smaya        text += "{\n"
104a8bb7a65Smaya        if (len(func.args) > 0):
105a8bb7a65Smaya            text += "  "
106a8bb7a65Smaya            for arg in func.args:
107a8bb7a65Smaya                text += " (void) {a.name};".format(a=arg)
108a8bb7a65Smaya            text += "\n"
109a8bb7a65Smaya        text += "   noop_warn(\"{f.name}\");\n".format(f=func)
110a8bb7a65Smaya        if (func.hasReturn()):
111a8bb7a65Smaya            text += "   return ({f.rt}) 0;\n".format(f=func)
112a8bb7a65Smaya        text += "}\n\n"
113a8bb7a65Smaya
114a8bb7a65Smaya    text += "const mapi_func table_noop_array[] = {\n"
115a8bb7a65Smaya    for func in functions:
116a8bb7a65Smaya        text += "   (mapi_func) noop{f.basename},\n".format(f=func)
117a8bb7a65Smaya    for i in range(genCommon.MAPI_TABLE_NUM_DYNAMIC - 1):
118a8bb7a65Smaya        text += "   (mapi_func) noop_generic,\n"
119a8bb7a65Smaya    text += "   (mapi_func) noop_generic\n"
120a8bb7a65Smaya    text += "};\n\n"
121a8bb7a65Smaya    text += "#else /* DEBUG */\n\n"
122a8bb7a65Smaya    text += "const mapi_func table_noop_array[] = {\n"
123a8bb7a65Smaya    for i in range(len(functions) + genCommon.MAPI_TABLE_NUM_DYNAMIC - 1):
124a8bb7a65Smaya        text += "   (mapi_func) noop_generic,\n"
125a8bb7a65Smaya    text += "   (mapi_func) noop_generic\n"
126a8bb7a65Smaya
127a8bb7a65Smaya    text += "};\n\n"
128a8bb7a65Smaya    text += "#endif /* DEBUG */\n"
129a8bb7a65Smaya    text += "#undef MAPI_TMP_NOOP_ARRAY\n"
130a8bb7a65Smaya    text += "#endif /* MAPI_TMP_NOOP_ARRAY */\n"
131a8bb7a65Smaya    return text
132a8bb7a65Smaya
133a8bb7a65Smayadef generate_public_stubs(functions):
134a8bb7a65Smaya    text = "#ifdef MAPI_TMP_PUBLIC_STUBS\n"
135a8bb7a65Smaya
136a8bb7a65Smaya    text += "static const struct mapi_stub public_stubs[] = {\n"
137a8bb7a65Smaya    for func in functions:
138a8bb7a65Smaya        text += "   { \"%s\", %d, NULL },\n" % (func.name, func.slot)
139a8bb7a65Smaya    text += "};\n"
140a8bb7a65Smaya    text += "#undef MAPI_TMP_PUBLIC_STUBS\n"
141a8bb7a65Smaya    text += "#endif /* MAPI_TMP_PUBLIC_STUBS */\n"
142a8bb7a65Smaya    return text
143a8bb7a65Smaya
144a8bb7a65Smayadef generate_public_entries(functions):
145a8bb7a65Smaya    text = "#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN\n"
146a8bb7a65Smaya
147a8bb7a65Smaya    for func in functions:
148a8bb7a65Smaya        retStr = ("return " if func.hasReturn() else "")
149a8bb7a65Smaya        text += r"""
150a8bb7a65SmayaGLAPI {f.rt} APIENTRY {f.name}({f.decArgs})
151a8bb7a65Smaya{{
152a8bb7a65Smaya   const struct _glapi_table *_tbl = entry_current_get();
153a8bb7a65Smaya   mapi_func _func = ((const mapi_func *) _tbl)[{f.slot}];
154a8bb7a65Smaya   {retStr}(({f.rt} (APIENTRY *)({f.decArgs})) _func)({f.callArgs});
155a8bb7a65Smaya}}
156a8bb7a65Smaya
157a8bb7a65Smaya""".lstrip("\n").format(f=func, retStr=retStr)
158a8bb7a65Smaya
159a8bb7a65Smaya    text += "\n"
160a8bb7a65Smaya    text += "#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */\n"
161a8bb7a65Smaya    return text
162a8bb7a65Smaya
163a8bb7a65Smayadef generate_public_entries_table(functions):
164a8bb7a65Smaya    text = "#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN\n"
165a8bb7a65Smaya    text += "static const mapi_func public_entries[] = {\n"
166a8bb7a65Smaya    for func in functions:
167a8bb7a65Smaya        text += "   (mapi_func) %s,\n" % (func.name,)
168a8bb7a65Smaya    text += "};\n"
169a8bb7a65Smaya    text += "#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */\n"
170a8bb7a65Smaya    return text
171a8bb7a65Smaya
172a8bb7a65Smayadef generate_undef_public_entries():
173a8bb7a65Smaya    text = "#ifdef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN\n"
174a8bb7a65Smaya    text += "#undef MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN\n"
175a8bb7a65Smaya    text += "#endif /* MAPI_TMP_PUBLIC_ENTRIES_NO_HIDDEN */\n"
176a8bb7a65Smaya    return text
177a8bb7a65Smaya
178a8bb7a65Smayadef generate_stub_asm_gcc(functions):
179a8bb7a65Smaya    text = "#ifdef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN\n"
180a8bb7a65Smaya    text += "__asm__(\n"
181a8bb7a65Smaya
182a8bb7a65Smaya    for func in functions:
183a8bb7a65Smaya        text += 'STUB_ASM_ENTRY("%s")"\\n"\n' % (func.name,)
184a8bb7a65Smaya        text += '"\\t"STUB_ASM_CODE("%d")"\\n"\n\n' % (func.slot,)
185a8bb7a65Smaya
186a8bb7a65Smaya    text += ");\n"
187a8bb7a65Smaya    text += "#undef MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN\n"
188a8bb7a65Smaya    text += "#endif /* MAPI_TMP_STUB_ASM_GCC_NO_HIDDEN */\n"
189a8bb7a65Smaya    return text
190a8bb7a65Smaya
191a8bb7a65Smayaif (__name__ == "__main__"):
192a8bb7a65Smaya    _main()
193a8bb7a65Smaya
194