| #!/usr/bin/env python |
| |
| # $Id: glapitemp.py,v 1.6 2004/06/29 19:08:20 idr Exp $ |
| |
| # Mesa 3-D graphics library |
| # Version: 4.1 |
| # |
| # Copyright (C) 1999-2001 Brian Paul All Rights Reserved. |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a |
| # copy of this software and associated documentation files (the "Software"), |
| # to deal in the Software without restriction, including without limitation |
| # the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| # and/or sell copies of the Software, and to permit persons to whom the |
| # Software is furnished to do so, subject to the following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included |
| # in all copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| # BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| |
| # Generate the glapitemp.h file. |
| # |
| # Usage: |
| # gloffsets.py >glapitemp.h |
| # |
| # Dependencies: |
| # The apispec file must be in the current directory. |
| |
| |
| import string |
| import apiparser; |
| |
| |
| def PrintHead(): |
| print """ |
| /* DO NOT EDIT! This file is generated by the glapitemp.py script. */ |
| |
| /* |
| * This file is a template which generates the OpenGL API entry point |
| * functions. It should be included by a .c file which first defines |
| * the following macros: |
| * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 |
| * KEYWORD2 - usually nothing, but might be __stdcall on Win32 |
| * NAME(n) - builds the final function name (usually add "gl" prefix) |
| * DISPATCH(func, args, msg) - code to do dispatch of named function. |
| * msg is a printf-style debug message. |
| * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value |
| * |
| * Here's an example which generates the usual OpenGL functions: |
| * #define KEYWORD1 |
| * #define KEYWORD2 |
| * #define NAME(func) gl##func |
| * #define DISPATCH(func, args, msg) \\ |
| * struct _glapi_table *dispatch = CurrentDispatch; \\ |
| * (*dispatch->func) args |
| * #define RETURN DISPATCH(func, args, msg) \\ |
| * struct _glapi_table *dispatch = CurrentDispatch; \\ |
| * return (*dispatch->func) args |
| * |
| */ |
| |
| |
| #if defined( NAME ) |
| #ifndef KEYWORD1 |
| #define KEYWORD1 |
| #endif |
| |
| #ifndef KEYWORD2 |
| #define KEYWORD2 |
| #endif |
| |
| #ifndef DISPATCH |
| #error DISPATCH must be defined |
| #endif |
| |
| #ifndef RETURN_DISPATCH |
| #error RETURN_DISPATCH must be defined |
| #endif |
| |
| GLAPI void GLAPIENTRY gl__unused413(void); /* silence warning */ |
| """ |
| |
| #enddef |
| |
| |
| def PrintTail(): |
| print""" |
| #undef KEYWORD1 |
| #undef KEYWORD2 |
| #undef NAME |
| #undef DISPATCH |
| #undef RETURN_DISPATCH |
| #undef DISPATCH_TABLE_NAME |
| #undef UNUSED_TABLE_NAME |
| #undef TABLE_ENTRY |
| """ |
| #endif |
| |
| |
| def MakeParamList(nameList): |
| n = len(nameList) |
| i = 1 |
| result = '' |
| for name in nameList: |
| result = result + name |
| if i < n: |
| result = result + ', ' |
| i = i + 1 |
| return result |
| #enddef |
| |
| |
| def Contains(haystack, needle): |
| if string.find(haystack, needle) >= 0: |
| return 1 |
| else: |
| return 0 |
| #enddef |
| |
| |
| def MakePrintfString(funcName, argTypeList, argNameList): |
| result = '(F, "gl%s(' % (funcName) |
| |
| n = len(argTypeList) |
| i = 1 |
| isPointer = {} |
| floatv = {} |
| for argType in argTypeList: |
| isPointer[i] = 0 |
| floatv[i] = 0 |
| if argType == 'GLenum': |
| result = result + '0x%x' |
| elif argType in ['GLfloat', 'GLdouble', 'GLclampf', 'GLclampd']: |
| result = result + '%f' |
| elif argType in ['GLbyte', 'GLubyte', 'GLshort', 'GLushort', 'GLint', 'GLuint', 'GLboolean', 'GLsizei']: |
| result = result + '%d' |
| else: |
| result = result + '%p' |
| isPointer[i] = 1 |
| if argType[0:13] == 'const GLfloat' or argType[0:14] == 'const GLdouble': |
| if Contains(funcName, '2fv') or Contains(funcName, '2dv'): |
| result = result + ' /* %g, %g */' |
| floatv[i] = 2 |
| elif Contains(funcName, '3fv') or Contains(funcName, '3dv'): |
| result = result + ' /* %g, %g, %g */' |
| floatv[i] = 3 |
| elif Contains(funcName, '4fv') or Contains(funcName, '4dv'): |
| result = result + ' /* %g, %g, %g, %g */' |
| floatv[i] = 4 |
| #endif |
| if i < n: |
| result = result + ', ' |
| i = i + 1 |
| #endfor |
| |
| result = result + ');\\n"' |
| |
| n = len(argNameList) |
| i = 1 |
| if n > 0: |
| result = result + ', ' |
| for pname in argNameList: |
| if isPointer[i]: |
| result = result + '(const void *) ' |
| result = result + pname |
| if floatv[i] == 2: |
| result = result + ', ' + pname + '[0], ' + pname + '[1]' |
| elif floatv[i] == 3: |
| result = result + ', ' + pname + '[0], ' + pname + '[1], ' + pname + '[2]' |
| elif floatv[i] == 4: |
| result = result + ', ' + pname + '[0], ' + pname + '[1], ' + pname + '[2], ' + pname + '[3]' |
| if i < n: |
| result = result + ', ' |
| i = i + 1 |
| result = result + ')' |
| return result |
| #enddef |
| |
| |
| records = [] |
| emittedFuncs = {} |
| aliasedFuncs = [] |
| |
| def FindOffset(funcName): |
| for (name, alias, offset) in records: |
| if name == funcName: |
| return offset |
| #endif |
| #endfor |
| return -1 |
| #enddef |
| |
| def EmitFunction(name, returnType, argTypeList, argNameList, alias, offset): |
| argList = apiparser.MakeArgList(argTypeList, argNameList) |
| parms = MakeParamList(argNameList) |
| printString = MakePrintfString(name, argTypeList, argNameList) |
| if alias == '': |
| dispatchName = name |
| else: |
| dispatchName = alias |
| if offset < 0: |
| offset = FindOffset(dispatchName) |
| if offset >= 0: |
| print 'KEYWORD1 %s KEYWORD2 NAME(%s)(%s)' % (returnType, name, argList) |
| print '{' |
| if returnType == 'void': |
| print ' DISPATCH(%s, (%s), %s);' % (dispatchName, parms, printString) |
| else: |
| print ' RETURN_DISPATCH(%s, (%s), %s);' % (dispatchName, parms, printString) |
| print '}' |
| print '' |
| records.append((name, dispatchName, offset)) |
| if not emittedFuncs.has_key(offset): |
| emittedFuncs[offset] = name |
| else: |
| aliasedFuncs.append(name) |
| else: |
| print '/* No dispatch for %s() */' % (name) |
| #endif |
| |
| |
| def PrintInitDispatch(): |
| print """ |
| #endif /* defined( NAME ) */ |
| |
| /* |
| * This is how a dispatch table can be initialized with all the functions |
| * we generated above. |
| */ |
| #ifdef DISPATCH_TABLE_NAME |
| |
| #ifndef TABLE_ENTRY |
| #error TABLE_ENTRY must be defined |
| #endif |
| |
| void *DISPATCH_TABLE_NAME[] = {""" |
| keys = emittedFuncs.keys() |
| keys.sort() |
| for k in keys: |
| print ' TABLE_ENTRY(%s),' % (emittedFuncs[k]) |
| |
| print ' /* A whole bunch of no-op functions. These might be called' |
| print ' * when someone tries to call a dynamically-registered' |
| print ' * extension function without a current rendering context.' |
| print ' */' |
| for i in range(1, 100): |
| print ' TABLE_ENTRY(Unused),' |
| |
| print '};' |
| print '#endif /* DISPATCH_TABLE_NAME */' |
| print '' |
| #enddef |
| |
| |
| |
| def PrintAliasedTable(): |
| print """ |
| /* |
| * This is just used to silence compiler warnings. |
| * We list the functions which aren't otherwise used. |
| */ |
| #ifdef UNUSED_TABLE_NAME |
| void *UNUSED_TABLE_NAME[] = {""" |
| for alias in aliasedFuncs: |
| print ' TABLE_ENTRY(%s),' % (alias) |
| #endfor |
| print '};' |
| print '#endif /*UNUSED_TABLE_NAME*/' |
| print '' |
| #enddef |
| |
| |
| |
| PrintHead() |
| apiparser.ProcessSpecFile("APIspec", EmitFunction) |
| PrintInitDispatch() |
| PrintAliasedTable() |
| PrintTail() |