new Python API generator scripts
diff --git a/src/mesa/glapi/apiparser.py b/src/mesa/glapi/apiparser.py
new file mode 100644
index 0000000..0c14ab9
--- /dev/null
+++ b/src/mesa/glapi/apiparser.py
@@ -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
index 0000000..58b622a
--- /dev/null
+++ b/src/mesa/glapi/glapitemp.py
@@ -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()
diff --git a/src/mesa/glapi/gloffsets.py b/src/mesa/glapi/gloffsets.py
index dd2b00c..7fa4a1b 100644
--- a/src/mesa/glapi/gloffsets.py
+++ b/src/mesa/glapi/gloffsets.py
@@ -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"),
@@ -31,13 +31,11 @@
 #    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 @@
 	print '#define _GLAPI_OFFSETS_H_'
 	print ''
 	return
-#endif
+#enddef
 
 
 def PrintTail():
 	print ''
 	print '#endif'
-#endif
-
-
-def GenerateDefine(name, offset):
-	s = '#define _gloffset_' + name + ' ' + str(offset)
-	return s;
 #enddef
 
 
-def PrintDefines():
-	functionPattern = re.compile('^[a-zA-Z0-9]+\(')
-	functionNamePattern = re.compile('^[a-zA-Z0-9]+')
+records = {}
 
-	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 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 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
+
+
+
 
 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
index 0000000..2d29cb4
--- /dev/null
+++ b/src/mesa/glapi/glprocs.py
@@ -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()
diff --git a/src/mesa/glapi/glsparcasm.py b/src/mesa/glapi/glsparcasm.py
index 98cbd47..1964c15 100644
--- a/src/mesa/glapi/glsparcasm.py
+++ b/src/mesa/glapi/glsparcasm.py
@@ -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"),
@@ -25,19 +25,16 @@
 # 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 @@
 	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 @@
 	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 @@
 	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 @@
 #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 @@
 	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()
diff --git a/src/mesa/glapi/gltable.py b/src/mesa/glapi/gltable.py
index 8f48366..54dacb1 100644
--- a/src/mesa/glapi/gltable.py
+++ b/src/mesa/glapi/gltable.py
@@ -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"),
@@ -28,273 +28,61 @@
 # 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
+#    The apispec file must be in the current directory.
 
 
-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
-
-
-
-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
-#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
-
+import apiparser;
 
 
 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
+        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 PrintTail():
-	print '};'
-	print ''
-	print '#endif'
+        print '};'
+        print ''
+        print '#endif'
 #endif
 
 
+records = {}
 
-PrintHead()	
-PrintTableEntries()
-PrintTail()
\ No newline at end of file
+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 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()
+
diff --git a/src/mesa/glapi/glx86asm.py b/src/mesa/glapi/glx86asm.py
index ce93279..2366730 100644
--- a/src/mesa/glapi/glx86asm.py
+++ b/src/mesa/glapi/glx86asm.py
@@ -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"),
@@ -25,19 +25,16 @@
 # 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 @@
 	print ''
 	print ''
 	return
-#endif
+#enddef
 
 
 def PrintTail():
 	print ''
 	print '#endif  /* __WIN32__ */'
-#endif
+#enddef
 
 
-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 '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 "\tJMP(GL_OFFSET(_gloffset_%s))" % (dispatchName)
 	print ''
-#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()