| 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | """ |
| 4 | License statement applies to this file (glgen.py) only. |
| 5 | |
| 6 | Permission is hereby granted, free of charge, |
| 7 | to any person obtaining a copy of this software and associated documentation files (the "Software"), |
| 8 | to deal in the Software without restriction, including without limitation the rights to |
| 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, |
| 10 | and to permit persons to whom the Software is furnished to do so, subject to the following conditions: |
| 11 | |
| 12 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. |
| 13 | |
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, |
| 15 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| 18 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 20 | """ |
| 21 | |
| 22 | import sys |
| 23 | import os |
| 24 | import re |
| 25 | |
| 26 | banned_ext = [ 'AMD', 'APPLE', 'NV', 'NVX', 'ATI', '3DLABS', 'SUN', 'SGI', 'SGIX', 'SGIS', 'INTEL', '3DFX', 'IBM', 'MESA', 'GREMEDY', 'OML', 'PGI', 'I3D', 'INGL', 'MTX', 'QCOM', 'IMG', 'ANGLE', 'SUNX', 'INGR' ] |
| 27 | |
| 28 | def noext(sym): |
| 29 | for ext in banned_ext: |
| 30 | if sym.endswith(ext): |
| 31 | return False |
| 32 | return True |
| 33 | |
| 34 | def fix_multiline_functions(lines): |
| 35 | fixed_lines = [] |
| 36 | temp_lines = [] |
| 37 | for line in lines: |
| 38 | if line.count('(') > line.count(')'): |
| 39 | temp_lines.append(line) |
| 40 | else: |
| 41 | if len(temp_lines) > 0: |
| 42 | if line.count(')') > line.count('('): |
| 43 | temp_lines.append(line) |
| 44 | fixed_line = re.sub(' +',' ', ''.join(temp_lines).replace('\n','').replace('\t','')) |
| 45 | fixed_lines.append(fixed_line) |
| 46 | temp_lines = [] |
| 47 | else: |
| 48 | temp_lines.append(line) |
| 49 | else: |
| 50 | fixed_lines.append(line) |
| 51 | return fixed_lines |
| 52 | |
| 53 | def find_gl_symbols(lines): |
| 54 | typedefs = [] |
| 55 | syms = [] |
| 56 | for line in lines: |
| 57 | m = re.search(r'^typedef.+PFN(\S+)PROC.+$', line) |
| 58 | g = re.search(r'^.+(gl\S+)\W*\(.+\).*$', line) |
| 59 | if m and noext(m.group(1)): |
| 60 | typedefs.append(m.group(0).replace('PFN', 'RGLSYM').replace('GLDEBUGPROC', 'RGLGENGLDEBUGPROC')) |
| 61 | if g and noext(g.group(1)): |
| 62 | syms.append(g.group(1)) |
| 63 | return (typedefs, syms) |
| 64 | |
| 65 | def generate_defines(gl_syms): |
| 66 | res = [] |
| 67 | for line in gl_syms: |
| 68 | res.append('#define {} __rglgen_{}'.format(line, line)) |
| 69 | return res |
| 70 | |
| 71 | def generate_declarations(gl_syms): |
| 72 | return ['RGLSYM' + x.upper() + 'PROC ' + '__rglgen_' + x + ';' for x in gl_syms] |
| 73 | |
| 74 | def generate_macros(gl_syms): |
| 75 | return [' SYM(' + x.replace('gl', '') + '),' for x in gl_syms] |
| 76 | |
| 77 | def dump(f, lines): |
| 78 | f.write('\n'.join(lines)) |
| 79 | f.write('\n\n') |
| 80 | |
| 81 | if __name__ == '__main__': |
| 82 | |
| 83 | if len(sys.argv) > 4: |
| 84 | for banned in sys.argv[4:]: |
| 85 | banned_ext.append(banned) |
| 86 | |
| 87 | with open(sys.argv[1], 'r') as f: |
| 88 | lines = fix_multiline_functions(f.readlines()) |
| 89 | typedefs, syms = find_gl_symbols(lines) |
| 90 | |
| 91 | overrides = generate_defines(syms) |
| 92 | declarations = generate_declarations(syms) |
| 93 | externs = ['extern ' + x for x in declarations] |
| 94 | |
| 95 | macros = generate_macros(syms) |
| 96 | |
| 97 | with open(sys.argv[2], 'w') as f: |
| 98 | f.write('#ifndef RGLGEN_DECL_H__\n') |
| 99 | f.write('#define RGLGEN_DECL_H__\n') |
| 100 | |
| 101 | f.write('#ifdef __cplusplus\n') |
| 102 | f.write('extern "C" {\n') |
| 103 | f.write('#endif\n') |
| 104 | |
| 105 | f.write('#ifdef GL_APIENTRY\n') |
| 106 | f.write('typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') |
| 107 | f.write('#else\n') |
| 108 | f.write('#ifndef APIENTRY\n') |
| 109 | f.write('#define APIENTRY\n') |
| 110 | f.write('#endif\n') |
| 111 | f.write('#ifndef APIENTRYP\n') |
| 112 | f.write('#define APIENTRYP APIENTRY *\n') |
| 113 | f.write('#endif\n') |
| 114 | f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') |
| 115 | f.write('typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);\n') |
| 116 | f.write('#endif\n') |
| 117 | |
| 118 | f.write('#ifndef GL_OES_EGL_image\n') |
| 119 | f.write('typedef void *GLeglImageOES;\n') |
| 120 | f.write('#endif\n') |
| 121 | |
| 122 | f.write('#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)\n') |
| 123 | f.write('typedef GLint GLfixed;\n') |
| 124 | f.write('#endif\n') |
| 125 | |
| 126 | dump(f, typedefs) |
| 127 | dump(f, overrides) |
| 128 | dump(f, externs) |
| 129 | |
| 130 | f.write('struct rglgen_sym_map { const char *sym; void *ptr; };\n') |
| 131 | f.write('extern const struct rglgen_sym_map rglgen_symbol_map[];\n') |
| 132 | |
| 133 | f.write('#ifdef __cplusplus\n') |
| 134 | f.write('}\n') |
| 135 | f.write('#endif\n') |
| 136 | |
| 137 | f.write('#endif\n') |
| 138 | |
| 139 | with open(sys.argv[3], 'w') as f: |
| 140 | f.write('#include "glsym/glsym.h"\n') |
| 141 | f.write('#include <stddef.h>\n') |
| 142 | f.write('#define SYM(x) { "gl" #x, &(gl##x) }\n') |
| 143 | f.write('const struct rglgen_sym_map rglgen_symbol_map[] = {\n') |
| 144 | dump(f, macros) |
| 145 | f.write(' { NULL, NULL },\n') |
| 146 | f.write('};\n') |
| 147 | dump(f, declarations) |