new Python API generator scripts
authorBrian Paul <brian.paul@tungstengraphics.com>
Sun, 18 Nov 2001 22:42:57 +0000 (22:42 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sun, 18 Nov 2001 22:42:57 +0000 (22:42 +0000)
src/mesa/glapi/apiparser.py [new file with mode: 0644]
src/mesa/glapi/glapitemp.py [new file with mode: 0644]
src/mesa/glapi/gloffsets.py
src/mesa/glapi/glprocs.py [new file with mode: 0644]
src/mesa/glapi/glsparcasm.py
src/mesa/glapi/gltable.py
src/mesa/glapi/glx86asm.py

diff --git a/src/mesa/glapi/apiparser.py b/src/mesa/glapi/apiparser.py
new file mode 100644 (file)
index 0000000..0c14ab9
--- /dev/null
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+
+# $Id: apiparser.py,v 1.1 2001/11/18 22:42:57 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.
+
+
+# These helper functions are used by the other Mesa Python scripts.
+# The main function is ProcessSpecFile(spedFile, function) which parses
+# the named spec file and calls function() for each entry in the spec file.
+
+
+import string
+
+
+# Given parallel arrays of types and names, make a C-style parameter string
+def MakeArgList(typeList, nameList):
+       result = ''
+       i = 1
+       n = len(typeList)
+       for typ in typeList:
+               result = result + typ + ' ' + nameList[i - 1]
+               if i < n:
+                       result = result + ', '
+               i = i + 1
+       #endfor
+       if result == '':
+               result = 'void'
+       #endif
+       return result
+#enddef
+
+
+prevCatagory = ''
+
+#
+# Example callback function for ProcessSpecFile()
+#
+def PrintRecord(name, returnType, argTypeList, argNameList, alias, offset):
+       argList = MakeArgList(argTypeList, argNameList)
+       if category != prevCategory or prevCategory == '':
+               print '\n/* %s */' % category
+               prevCategory = category
+       #endif
+       print '%s gl%s(%s); /* %d */' % (returnType, name, argList, offset)
+#endfor
+
+
+#
+# Process the api spec file
+#
+def ProcessSpecFile(specFile, userFunc):
+
+       # init some vars
+       prevCategory = ''
+       funcName = ''
+       returnType = ''
+       argTypeList = [ ]
+       argNameList = [ ]
+       maxOffset = 0
+       table = { }
+       offset = -1
+       alias = ''
+
+       f = open(specFile)
+       for line in f.readlines():
+
+               # split line into tokens
+               tokens = string.split(line)
+
+               if len(tokens) > 0 and line[0] != '#':
+
+                       if tokens[0] == 'name':
+                               if funcName != '':
+                                       # Verify entry has offset or alias
+                                       pnts = 0
+                                       if offset == -2:
+                                               pnts = pnts + 1
+                                       if offset >= 0:
+                                               pnts = pnts + 1
+                                       if alias != '':
+                                               pnts = pnts + 1
+                                       if pnts != 1:
+                                               print 'XXXXXXXXXX bad entry for %s' % funcName
+                                               
+                                       # process the function now
+                                       userFunc (funcName, returnType, argTypeList, argNameList, alias, offset)
+                                       # reset the lists
+                                       argTypeList = [ ]
+                                       argNameList = [ ]
+                                       returnType = ''
+                                       offset = -1
+                                       alias = ''
+
+                               funcName = tokens[1]
+
+                       elif tokens[0] == 'return':
+                               returnType = tokens[1]
+                               if len(tokens) > 2:
+                                       returnType = returnType + ' ' + tokens[2]
+                               if len(tokens) > 3:
+                                       returnType = returnType + ' ' + tokens[3]
+                       
+                       elif tokens[0] == 'param':
+                               argNameList.append(tokens[1])
+                               type = tokens[2]
+                               if len(tokens) > 3:
+                                               type = type + ' ' + tokens[3]
+                               if len(tokens) > 4:
+                                               type = type + ' ' + tokens[4]
+                               argTypeList.append(type)
+
+                       elif tokens[0] == 'category':
+                               category = tokens[1]
+
+                       elif tokens[0] == 'offset':
+                               if tokens[1] == '?':
+                                       offset = -2
+                               else:
+                                       offset = int(tokens[1])
+                                       if offset > maxOffset:
+                                               maxOffset = offset
+#                              else:
+#                                      print 'Unassigned offset for %s' % funcName
+
+                       elif tokens[0] == 'alias':
+                               alias = tokens[1]
+
+                       else:
+                               print 'Invalid token %s after function %s' % (tokens[0], funcName)
+                       #endif
+               #endif
+       #endfor
+#enddef
diff --git a/src/mesa/glapi/glapitemp.py b/src/mesa/glapi/glapitemp.py
new file mode 100644 (file)
index 0000000..58b622a
--- /dev/null
@@ -0,0 +1,258 @@
+#!/usr/bin/env python
+
+# $Id: glapitemp.py,v 1.1 2001/11/18 22:42:57 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 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
+
+"""
+#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 MakePrintfString(funcName, argTypeList, argNameList):
+       result = '(F, "gl%s(' % (funcName)
+
+       n = len(argTypeList)
+       i = 1
+       isPointer = {}
+       for argType in argTypeList:
+               isPointer[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']:
+                       result = result + '%d'
+               else:
+                       result = result + '%p'
+                       isPointer[i] = 1
+               if i < n:
+                       result = result + ', '
+               i = i + 1
+       #endfor
+
+       result = result + ');"'
+       
+       n = len(argNameList)
+       i = 1
+       if n > 0:
+               result = result + ', '
+       for pname in argNameList:
+               if isPointer[i]:
+                       result = result + '(void *) '
+               result = result + pname
+               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()
index dd2b00c..7fa4a1b 100644 (file)
@@ -1,11 +1,11 @@
 #!/usr/bin/env python
 
-# $Id: gloffsets.py,v 1.4 2000/05/11 17:45:20 brianp Exp $
+# $Id: gloffsets.py,v 1.5 2001/11/18 22:42:57 brianp Exp $
 
 # Mesa 3-D graphics library
-# Version:  3.3
+# Version:  4.1
 # 
-# Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+# 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"),
 #    gloffsets.py >glapioffsets.h
 #
 # Dependencies:
-#    The gl.spec file from the SI must be in the current directory.
-#
-# Brian Paul  3 February 2000
+#    The apispec file must be in the current directory.
+
 
 
-import string
-import re
+import apiparser;
 
 
 def PrintHead():
@@ -46,75 +44,42 @@ def PrintHead():
        print '#define _GLAPI_OFFSETS_H_'
        print ''
        return
-#endif
+#enddef
 
 
 def PrintTail():
        print ''
        print '#endif'
-#endif
+#enddef
+
 
+records = {}
 
-def GenerateDefine(name, offset):
-       s = '#define _gloffset_' + name + ' ' + str(offset)
-       return s;
+def AddOffset(name, returnType, argTypeList, argNameList, alias, offset):
+       argList = apiparser.MakeArgList(argTypeList, argNameList)
+       if offset >= 0 and not records.has_key(offset):
+               records[offset] = name
+               #print '#define _gloffset_%s %d' % (name, offset)
 #enddef
 
 
-def PrintDefines():
-       functionPattern = re.compile('^[a-zA-Z0-9]+\(')
-       functionNamePattern = re.compile('^[a-zA-Z0-9]+')
-
-       funcName = ''
-
-       maxOffset = 0
-       offsetInfo = { }
-
-       f = open('gl.spec')
-       for line in f.readlines():
-
-               m = functionPattern.match(line)
-               if m:
-                       # extract funcName
-                       n = functionNamePattern.findall(line)
-                       funcName = n[0]
-
-               m = string.split(line)
-               if len(m) > 1:
-                       if m[0] == 'param':
-                               paramName = m[1]
-                       if m[0] == 'offset':
-                               if m[1] == '?':
-                                       #print 'WARNING skipping', funcName
-                                       noop = 0
-                               else:
-                                       funcOffset = int(m[1])
-                                       if funcOffset > maxOffset:
-                                               maxOffset = funcOffset
-                                       s = GenerateDefine(funcName, funcOffset)
-                                       if offsetInfo.has_key(funcOffset):
-                                               print 'ERROR: offset', funcOffset, 'already used!'
-                                               raise ERROR
-                                       else:
-                                               offsetInfo[funcOffset] = s;
-                                       #endif
-                               #endif
-                       #endif
-               #endif
-       #endfor
-
-       # Now print the #defines in order of dispatch offset
-       for i in range(0, maxOffset + 1):
-               if offsetInfo.has_key(i):
-                       print offsetInfo[i]
-               else:
-                       print 'ERROR: missing offset:', i
-                       raise ERROR
+def PrintRecords():
+       keys = records.keys()
+       keys.sort()
+       prevk = -1
+       for k in keys:
+               if k != prevk + 1:
+                       #print 'Missing offset %d' % (prevk)
+                       pass
+               prevk = int(k)
+               name = records[k]
+               print '#define _gloffset_%s %d' % (name, k)
+#endef
 
-#enddef
 
 
 
 PrintHead()
-PrintDefines()
+apiparser.ProcessSpecFile("APIspec", AddOffset)
+PrintRecords()
 PrintTail()
diff --git a/src/mesa/glapi/glprocs.py b/src/mesa/glapi/glprocs.py
new file mode 100644 (file)
index 0000000..2d29cb4
--- /dev/null
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+# $Id: glprocs.py,v 1.1 2001/11/18 22:42:57 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 glprocs.h file.
+#
+# Usage:
+#    gloffsets.py >glprocs.h
+#
+# Dependencies:
+#    The apispec file must be in the current directory.
+
+
+
+import apiparser
+import string
+
+
+def PrintHead():
+       print '/* DO NOT EDIT - This file generated automatically by glprocs.py script */'
+       print ''
+       print '/* This file is only included by glapi.c and is used for'
+       print ' * the GetProcAddress() function'
+       print ' */'
+       print ''
+       print 'static struct name_address_offset static_functions[] = {'
+       return
+#enddef
+
+
+def PrintTail():
+       print '   { NULL, NULL }  /* end of list marker */'
+       print '};'
+#enddef
+
+
+records = []
+
+def FindOffset(funcName):
+       for (name, alias, offset) in records:
+               if name == funcName:
+                       return offset
+               #endif
+       #endfor
+       return -1
+#enddef
+
+
+def EmitEntry(name, returnType, argTypeList, argNameList, alias, offset):
+       if alias == '':
+               dispatchName = name
+       else:
+               dispatchName = alias
+       if offset < 0:
+               offset = FindOffset(dispatchName)
+       if offset >= 0 and string.find(name, "unused") == -1:
+               print '   { "gl%s", (GLvoid *) gl%s, _gloffset_%s },' % (name, name, dispatchName)
+               # save this info in case we need to look up an alias later
+               records.append((name, dispatchName, offset))
+
+#enddef
+
+
+PrintHead()
+apiparser.ProcessSpecFile("APIspec", EmitEntry)
+PrintTail()
index 98cbd47..1964c15 100644 (file)
@@ -1,11 +1,11 @@
 #!/usr/bin/env python
 
-# $Id: glsparcasm.py,v 1.4 2001/08/03 13:16:31 davem69 Exp $
+# $Id: glsparcasm.py,v 1.5 2001/11/18 22:42:57 brianp Exp $
 
 # Mesa 3-D graphics library
-# Version:  3.5
+# Version:  4.1
 # 
-# Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+# 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"),
 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
-# Generate the glapi_sparc.S assembly language file.
+# Generate the src/SPARC/glapi_sparc.S file.
 #
 # Usage:
-#    glsparcasm.py >glapi_sparc.S
+#    gloffsets.py >glapi_sparc.S
 #
 # Dependencies:
-#    The gl.spec file from the SI must be in the current directory.
-#
-# Brian Paul      11 May 2000
-# David S. Miller  4 Jun 2001
+#    The apispec file must be in the current directory.
+
 
-import string
-import re
+import apiparser;
 
 
 def PrintHead():
@@ -45,7 +42,7 @@ def PrintHead():
        print '#include "glapioffsets.h"'
        print ''
        print '#define GL_PREFIX(n) gl##n'
-       print '#define GLOBL_FN(x) .globl x ; .type x,#function'
+       print '#define GLOBL_FN(x) .globl x'
        print ''
        print '/* The _glapi_Dispatch symbol addresses get relocated into the'
        print ' * sethi/or instruction sequences below at library init time.'
@@ -58,7 +55,7 @@ def PrintHead():
        print '__glapi_sparc_icache_flush: /* %o0 = insn_addr */'
        print '\tflush\t%o0'
        print '\tretl'
-       print '\t nop'
+       print '\tnop'
        print ''
        print '.data'
        print '.align 64'
@@ -66,7 +63,6 @@ def PrintHead():
        print '.globl _mesa_sparc_glapi_begin'
        print '.type _mesa_sparc_glapi_begin,#function'
        print '_mesa_sparc_glapi_begin:'
-       print ''
        return
 #endif
 
@@ -80,9 +76,43 @@ def PrintTail():
 #endif
 
 
-def GenerateDispatchCode(name, offset):
+
+records = []
+
+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)
+       if alias != '':
+               dispatchName = alias
+       else:
+               dispatchName = name
+       #endif
+       
+       if offset < 0:
+               # try to find offset from alias name
+               assert dispatchName != ''
+               offset = FindOffset(dispatchName)
+               if offset == -1:
+                       #print 'Cannot dispatch %s' % name
+                       return
+               #endif
+       #endif
+
+       # save this info in case we need to look up an alias later
+       records.append((name, dispatchName, offset))
+
+       # print the assembly code
        print ''
        print "GLOBL_FN(GL_PREFIX(%s))" % (name)
+       print '.type %s,#function' %(name)
        print "GL_PREFIX(%s):" % (name)
        print '#ifdef __sparc_v9__'
        print '\tsethi\t%hi(0x00000000), %g2'
@@ -91,79 +121,19 @@ def GenerateDispatchCode(name, offset):
        print '\tor\t%g1, %lo(0x00000000), %g1'
        print '\tsllx\t%g2, 32, %g2'
        print '\tldx\t[%g1 + %g2], %g1'
-       print "\tsethi\t%%hi(8 * _gloffset_%s), %%g2" % (offset)
-       print "\tor\t%%g2, %%lo(8 * _gloffset_%s), %%g2" % (offset)
+       print "\tsethi\t%%hi(8 * _gloffset_%s), %%g2" % (dispatchName)
+       print "\tor\t%%g2, %%lo(8 * _gloffset_%s), %%g2" % (dispatchName)
        print '\tldx\t[%g1 + %g2], %g3'
        print '#else'
        print '\tsethi\t%hi(0x00000000), %g1'
        print '\tld\t[%g1 + %lo(0x00000000)], %g1'
-       print "\tld\t[%%g1 + (4 * _gloffset_%s)], %%g3" % (offset)
+       print "\tld\t[%%g1 + (4 * _gloffset_%s)], %%g3" % (dispatchName)
        print '#endif'
        print '\tjmpl\t%g3, %g0'
+       print '\tnop'
 #enddef
 
 
-def FindAlias(list, funcName):
-       for i in range(0, len(list)):
-               entry = list[i]
-               if entry[0] == funcName:
-                       return entry[1]
-               #endif
-       #endfor
-       return ''
-#enddef
-
-
-
-def PrintDefines():
-       functionPattern = re.compile('^[a-zA-Z0-9]+\(')
-       functionNamePattern = re.compile('^[a-zA-Z0-9]+')
-
-       funcName = ''
-       functions = [ ]
-
-       f = open('gl.spec')
-       for line in f.readlines():
-
-               m = functionPattern.match(line)
-               if m:
-                       # extract funcName
-                       n = functionNamePattern.findall(line)
-                       funcName = n[0]
-
-               m = string.split(line)
-               if len(m) > 1:
-                       if m[0] == 'param':
-                               paramName = m[1]
-                       if m[0] == 'offset':
-                               if m[1] == '?':
-                                       #print 'WARNING skipping', funcName
-                                       noop = 0
-                               else:
-                                       entry = [ funcName, funcName ]
-                                       functions.append(entry)
-                               #endif
-                       elif m[0] == 'alias':
-                               aliasedName = FindAlias(functions, m[1])
-                               if aliasedName:
-                                       entry = [ funcName, aliasedName ]
-                                       functions.append(entry)
-                               else:
-                                       print 'WARNING: alias to unknown function:', aliasedName
-                               #endif
-                       #endif
-               #endif
-       #endfor
-
-       # Now generate the assembly dispatch code
-       for i in range(0, len(functions)):
-               entry = functions[i]
-               GenerateDispatchCode( entry[0], entry[1] )
-
-#enddef
-
-
-
 PrintHead()
-PrintDefines()
+apiparser.ProcessSpecFile("APIspec", EmitFunction)
 PrintTail()
index 8f48366..54dacb1 100644 (file)
@@ -1,11 +1,11 @@
 #!/usr/bin/env python
 
-# $Id: gltable.py,v 1.2 2000/05/11 17:44:42 brianp Exp $
+# $Id: gltable.py,v 1.3 2001/11/18 22:42:57 brianp Exp $
 
 # Mesa 3-D graphics library
-# Version:  3.3
+# Version:  4.1
 # 
-# Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+# 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"),
 # Generate the glapitable.h file.
 #
 # Usage:
-#    gltable.py >glapitable.h
+#    gloffsets.py >glapitable.h
 #
 # Dependencies:
-#    The gl.spec file from the SI must be in the current directory.
-#
-# Brian Paul  3 February 2000
-
-
-import string
-import re
-
-
-#
-# This table maps types from the gl.spec file to the OpenGL C types.
-#
-TypeTable = {
-       'AttribMask' : 'GLbitfield',
-       'Boolean' : 'GLboolean',
-       'CheckedFloat32' : 'GLfloat',
-       'CheckedInt32' : 'GLint',
-       'ClampedColorF' : 'GLclampf',
-       'ClampedFloat32' : 'GLclampf',
-       'ClampedFloat64' : 'GLclampd',
-       'ClampedStencilValue' : 'GLint',
-       'ClearBufferMask' : 'GLbitfield',
-       'ClientAttribMask' : 'GLbitfield',
-       'ColorB' : 'GLbyte',
-       'ColorD' : 'GLdouble',
-       'ColorF' : 'GLfloat',
-       'ColorI' : 'GLint',
-       'ColorIndexValueD' : 'GLdouble',
-       'ColorIndexValueF' : 'GLfloat',
-       'ColorIndexValueI' : 'GLint',
-       'ColorIndexValueS' : 'GLshort',
-       'ColorIndexValueUB' : 'GLubyte',
-       'ColorS' : 'GLshort',
-       'ColorUB' : 'GLubyte',
-       'ColorUI' : 'GLuint',
-       'ColorUS' : 'GLushort',
-       'CoordF' : 'GLfloat',
-       'CoordD' : 'GLdouble',
-       'CoordI' : 'GLint',
-       'CoordS' : 'GLshort',
-       'FeedbackElement' : 'GLfloat',
-       'Float32' : 'GLfloat',
-       'Float64' : 'GLdouble',
-       'Float32Pointer' : 'GLfloat',
-       'Float64Pointer' : 'GLdouble',
-       'Int8' : 'GLbyte',
-       'Int16' : 'GLshort',
-       'Int32' : 'GLint',
-       'LineStipple' : 'GLushort',
-       'List' : 'GLuint',
-       'MaskedColorIndexValueF' : 'GLfloat',
-       'MaskedColorIndexValueI' : 'GLuint',
-       'MaskedStencilValue' : 'GLuint',
-       'PixelInternalFormat' : 'GLenum',
-       'SelectName' : 'GLuint',
-       'SizeI' : 'GLsizei',
-       'StencilValue' : 'GLint',
-       'String' : 'const GLubyte *',
-       'TexelInternalFormat' : 'GLint',
-       'TextureComponentCount' : 'GLint',
-       'WinCoord' : 'GLint',
-       'UInt8' : 'GLubyte',
-       'UInt16' : 'GLushort',
-       'UInt32' : 'GLuint',
-       'Void' : 'GLvoid',
-       'VoidPointer' : 'GLvoid *',
-       'void' : 'void',
-}
-
-
-
-#
-# Return C-style argument type string.
-# Input:  t = a type like ListMode, Int16, CoordF, etc.
-#         pointerQual = '' or '*'
-#         constQual = '' or 'const '
-# Return:  a string like "const GLubyte *'
-#
-def ActualType(t, pointerQual, constQual):
-       if TypeTable.has_key(t):
-               type = TypeTable[t]
-       else:
-               type = 'GLenum'
-       if pointerQual == '':
-               s = constQual + type
-       else:
-               s = constQual + type + ' ' + pointerQual
-       return s
-#enddef
-
-
-
-#
-# Convert a Python list of arguments into a string.
-#
-def ArgListToString(argList):
-       result = ''
-       i = 1
-       n = len(argList)
-       for pair in argList:
-               result = result + pair[0] + ' ' + pair[1]
-               if i < n:
-                       result = result + ', '
-               i = i + 1
-
-       if result == '':
-               result = 'void'
-       return result
-#enddef
-
-
-#
-# Return a dispatch table entry, like "void (*Enable)(GLenum cap);"
-#
-def MakeTableEntry(retType, funcName, argList, offset):
-       s = '   '
-       s = s + ActualType(retType, '', '')
-       s = s + ' (*'
-       s = s + funcName
-       s = s + ')('
-       s = s + ArgListToString(argList)
-       s = s + '); /* '
-       s = s + str(offset)
-       s = s + ' */'
-       return s
-#enddef
+#    The apispec file must be in the current directory.
 
 
+import apiparser;
 
-def GroupFromCategory(category):
-       baseCats = [
-               'display-list',
-               'drawing',
-               'drawing-control',
-               'feedback',
-               'framebuf',
-               'misc',
-               'modeling',
-               'pixel-op',
-               'pixel-rw',
-               'state-req',
-               'xform'
-       ]
 
-       if baseCats.count(category) > 0:
-               return 'GL_1_0'
-       else:
-               return 'GL_' + category
-       #endif
+def PrintHead():
+        print '/* DO NOT EDIT - This file generated automatically with gltable.py script */'
+        print '#ifndef _GLAPI_TABLE_H_'
+        print '#define _GLAPI_TABLE_H_'
+        print ''
+        print '#include <GL/gl.h>'
+        print ''
+        print 'struct _glapi_table'
+        print '{'
+        return
 #endif
 
 
-def PrintGroup(group):
-       s = '   /* '
-       s = s + group
-       s = s + ' */'
-       print s
-#enddef
-
-
-
-#
-# Parse gl.spec to generate all the function pointers in the dispatch struct.
-#
-def PrintTableEntries():
-       functionPattern = re.compile('^[a-zA-Z0-9]+\(')
-       functionNamePattern = re.compile('^[a-zA-Z0-9]+')
-
-       prevGroup = ''
-       funcName = ''
-       returnType = ''
-       argList = [ ]
-       maxOffset = 0
-       table = { }
-
-       f = open('gl.spec')
-       for line in f.readlines():
-
-               m = functionPattern.match(line)
-               if m:
-                       # extract funcName
-                       n = functionNamePattern.findall(line)
-                       funcName = n[0]
-                       argList = [ ]
-               #endif
-
-               m = string.split(line)
-               if len(m) > 1:
-                       # return datatype
-                       if m[0] == 'return':
-                               returnType = m[1]
-                       #endif
-
-                       # function parameter
-                       if m[0] == 'param':
-                               constQual = ''
-                               pointerQual = ''
-                               if len(m) >= 5 and m[4] == 'array':
-                                       pointerQual = '*'
-                                       if m[3] == 'in':
-                                               constQual = 'const '
-                               paramName = m[1]
-                               paramType = ActualType(m[2], pointerQual, constQual)
-
-                               argList.append( (paramType, paramName) )
-                       #endif
-
-#                      # category
-                       if m[0] == 'category':
-                               category = m[1]
-                               group = GroupFromCategory(category)
-                               if group != prevGroup:
-#                                      PrintGroup(group)
-                                       prevGroup = group
-                       #endif
-
-                       # end of function spec
-                       if m[0] == 'offset':
-                               if m[1] == '?':
-                                       #print 'WARNING: skipping', funcName
-                                       noop = 0
-                               else:
-                                       funcOffset = int(m[1])
-                                       if funcOffset > maxOffset:
-                                               maxOffset = funcOffset
-                                       #PrintProto(returnType, funcName, argList)
-                                       s = MakeTableEntry(returnType, funcName, argList, funcOffset)
-#                                      print s
-                                       table[funcOffset] = s;
-                               #endif
-                       #endif
-               #endif
-       #endfor
-
-       # Now dump the table, this effectively does the sort by offset number
-       for i in range(0, maxOffset + 1):
-               if table.has_key(i):
-                       print table[i]
-
-#enddef
+def PrintTail():
+        print '};'
+        print ''
+        print '#endif'
+#endif
 
 
+records = {}
 
-def PrintHead():
-       print '/* DO NOT EDIT - This file generated automatically with gltable.py script */'
-       print '#ifndef _GLAPI_TABLE_H_'
-       print '#define _GLAPI_TABLE_H_'
-       print ''
-       print '#include <GL/gl.h>'
-       print ''
-       print 'struct _glapi_table'
-       print '{'
-       return
+def DoRecord(name, returnType, argTypeList, argNameList, alias, offset):
+       argList = apiparser.MakeArgList(argTypeList, argNameList)
+       if offset >= 0 and not records.has_key(offset):
+               records[offset] = (name, returnType, argList)
+               #print '#define _gloffset_%s %d' % (name, offset)
 #endif
 
 
-def PrintTail():
-       print '};'
-       print ''
-       print '#endif'
-#endif
+def PrintRecords():
+       keys = records.keys()
+       keys.sort()
+       prevk = -1
+       for k in keys:
+               if k != prevk + 1:
+                       #print 'Missing offset %d' % (prevk)
+                       pass
+               prevk = int(k)
+               (name, returnType, argList) = records[k]
+               print '   %s (*%s)(%s); /* %d */' % (returnType, name, argList, k)
+#endef
 
 
+PrintHead()
+apiparser.ProcessSpecFile("APIspec", DoRecord)
+PrintRecords()
+PrintTail()
 
-PrintHead()    
-PrintTableEntries()
-PrintTail()
\ No newline at end of file
index ce93279..2366730 100644 (file)
@@ -1,11 +1,11 @@
 #!/usr/bin/env python
 
-# $Id: glx86asm.py,v 1.3 2001/03/28 17:22:11 brianp Exp $
+# $Id: glx86asm.py,v 1.4 2001/11/18 22:42:57 brianp Exp $
 
 # Mesa 3-D graphics library
-# Version:  3.4
+# Version:  4.1
 # 
-# Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+# 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"),
 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
-# Generate the glapi_x86.S assembly language file.
+# Generate the src/X86/glapi_x86.S file.
 #
 # Usage:
-#    glx86asm.py >glapi_x86.S
+#    gloffsets.py >glapi_x86.S
 #
 # Dependencies:
-#    The gl.spec file from the SI must be in the current directory.
-#
-# Brian Paul  11 May 2000
+#    The apispec file must be in the current directory.
 
 
-import string
-import re
+import apiparser
 
 
 def PrintHead():
@@ -63,86 +60,60 @@ def PrintHead():
        print ''
        print ''
        return
-#endif
+#enddef
 
 
 def PrintTail():
        print ''
        print '#endif  /* __WIN32__ */'
-#endif
+#enddef
 
 
-def GenerateDispatchCode(name, offset):
-       print 'ALIGNTEXT16'
-       print "GLOBL_FN(GL_PREFIX(%s))" % (name)
-       print "GL_PREFIX(%s):" % (name)
-       print '\tMOV_L(GLNAME(_glapi_Dispatch), EAX)'
-       print "\tJMP(GL_OFFSET(_gloffset_%s))" % (offset)
-       print ''
-#enddef
 
+records = []
 
-def FindAlias(list, funcName):
-       for i in range(0, len(list)):
-               entry = list[i]
-               if entry[0] == funcName:
-                       return entry[1]
+def FindOffset(funcName):
+       for (name, alias, offset) in records:
+               if name == funcName:
+                       return offset
                #endif
        #endfor
-       return ''
+       return -1
 #enddef
 
-
-
-def PrintDefines():
-       functionPattern = re.compile('^[a-zA-Z0-9]+\(')
-       functionNamePattern = re.compile('^[a-zA-Z0-9]+')
-
-       funcName = ''
-       functions = [ ]
-
-       f = open('gl.spec')
-       for line in f.readlines():
-
-               m = functionPattern.match(line)
-               if m:
-                       # extract funcName
-                       n = functionNamePattern.findall(line)
-                       funcName = n[0]
-
-               m = string.split(line)
-               if len(m) > 1:
-                       if m[0] == 'param':
-                               paramName = m[1]
-                       if m[0] == 'offset':
-                               if m[1] == '?':
-                                       #print 'WARNING skipping', funcName
-                                       noop = 0
-                               else:
-                                       entry = [ funcName, funcName ]
-                                       functions.append(entry)
-                               #endif
-                       elif m[0] == 'alias':
-                               aliasedName = FindAlias(functions, m[1])
-                               if aliasedName:
-                                       entry = [ funcName, aliasedName ]
-                                       functions.append(entry)
-                               else:
-                                       print 'WARNING: alias to unknown function:', aliasedName
-                               #endif
-                       #endif
+def EmitFunction(name, returnType, argTypeList, argNameList, alias, offset):
+       argList = apiparser.MakeArgList(argTypeList, argNameList)
+       if alias != '':
+               dispatchName = alias
+       else:
+               dispatchName = name
+       #endif
+       
+       if offset < 0:
+               # try to find offset from alias name
+               assert dispatchName != ''
+               offset = FindOffset(dispatchName)
+               if offset == -1:
+                       #print 'Cannot dispatch %s' % name
+                       return
                #endif
-       #endfor
+       #endif
 
-       # Now generate the assembly dispatch code
-       for i in range(0, len(functions)):
-               entry = functions[i]
-               GenerateDispatchCode( entry[0], entry[1] )
+       # save this info in case we need to look up an alias later
+       records.append((name, dispatchName, offset))
+
+       # print the assembly code
+       print 'ALIGNTEXT16'
+       print "GLOBL_FN(GL_PREFIX(%s))" % (name)
+       print "GL_PREFIX(%s):" % (name)
+       print '\tMOV_L(GLNAME(_glapi_Dispatch), EAX)'
+       print "\tJMP(GL_OFFSET(_gloffset_%s))" % (dispatchName)
+       print ''
 
 #enddef
 
 
 
 PrintHead()
-PrintDefines()
+apiparser.ProcessSpecFile("APIspec", EmitFunction)
 PrintTail()