#!/usr/bin/env python # $Id: glapitemp.py,v 1.5 2002/11/30 17:18:46 brianp 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 * */ #ifndef KEYWORD1 #define KEYWORD1 #endif #ifndef KEYWORD2 #define KEYWORD2 #endif #ifndef NAME #error NAME must be defined #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 """ /* * 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()