#!/usr/bin/env python

# Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>
# All Rights Reserved.
#
# This is based on extension_helper.py by Ian Romanick.
#
# 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
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, 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 (including the next
# paragraph) 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS 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.

import gl_XML
import license
import sys, getopt, string

def get_function_spec(func):
	sig = ""
	# derive parameter signature
	for p in func.parameterIterator():
		if p.is_padding:
			continue
		# FIXME: This is a *really* ugly hack. :(
		tn = p.type_expr.get_base_type_node()
		if p.is_pointer():
			sig += 'p'
		elif tn.integer:
			sig += 'i'
		elif tn.size == 4:
			sig += 'f'
		else:
			sig += 'd'

	spec = [sig]
	for ent in func.entry_points:
		spec.append("gl" + ent)

	# spec is terminated by an empty string
	spec.append('')

	return spec

class PrintGlRemap(gl_XML.gl_print_base):
	def __init__(self):
		gl_XML.gl_print_base.__init__(self)

		self.name = "remap_helper.py (from Mesa)"
		self.license = license.bsd_license_template % ("Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>", "Chia-I Wu")
		return


	def printRealHeader(self):
		print '#include "glapi/dispatch.h"'
		print ''
		return


	def printBody(self, api):
		print 'struct gl_function_remap {'
		print '   GLint func_index;'
		print '   GLint dispatch_offset; /* for sanity check */'
		print '};'
		print ''

		pool_indices = {}

		print '/* this is internal to remap.c */'
		print '#ifdef need_MESA_remap_table'
		print ''
		print 'static const char _mesa_function_pool[] ='

		# output string pool
		index = 0;
		for f in api.functionIterateAll():
			pool_indices[f] = index

			spec = get_function_spec(f)

			# a function has either assigned offset, fixed offset,
			# or no offset
			if f.assign_offset:
				comments = "will be remapped"
			elif f.offset > 0:
				comments = "offset %d" % f.offset
			else:
				comments = "dynamic"

			print '   /* _mesa_function_pool[%d]: %s (%s) */' \
					% (index, f.name, comments)
			for line in spec:
				print '   "%s\\0"' % line
				index += len(line) + 1
		print '   ;'
		print ''

		print '/* these functions need to be remapped */'
		print 'static const struct {'
		print '   GLint pool_index;'
		print '   GLint remap_index;'
		print '} MESA_remap_table_functions[] = {'
		# output all functions that need to be remapped
		# iterate by offsets so that they are sorted by remap indices
		for f in api.functionIterateByOffset():
			if not f.assign_offset:
				continue
			print '   { %5d, %s_remap_index },' \
					% (pool_indices[f], f.name)
		print '   {    -1, -1 }'
		print '};'
		print ''

		abi = [ "1.0", "1.1", "1.2", "GL_ARB_multitexture" ]
		extension_functions = {}

		# collect non-ABI functions
		for f in api.functionIterateAll():
			for n in f.entry_points:
				category, num = api.get_category_for_name(n)
				if category not in abi:
					c = gl_XML.real_category_name(category)
					if not extension_functions.has_key(c):
						extension_functions[c] = []
					extension_functions[c].append(f)
		extensions = extension_functions.keys()
		extensions.sort()

		# output ABI functions that have alternative names (with ext suffix)
		print '/* these functions are in the ABI, but have alternative names */'
		print 'static const struct gl_function_remap MESA_alt_functions[] = {'
		for ext in extensions:
			funcs = []
			for f in extension_functions[ext]:
				# test if the function is in the ABI
				if not f.assign_offset and f.offset >= 0:
					funcs.append(f)
			if not funcs:
				continue
			print '   /* from %s */' % ext
			for f in funcs:
				print '   { %5d, _gloffset_%s },' \
						% (pool_indices[f], f.name)
		print '   {    -1, -1 }'
		print '};'
		print ''

		print '#endif /* need_MESA_remap_table */'
		print ''

		# output remap helpers for DRI drivers

		for ext in extensions:
			funcs = []
			remapped = []
			for f in extension_functions[ext]:
				if f.assign_offset:
					# these are handled above
					remapped.append(f)
				else:
					# these functions are either in the
                                        # abi, or have offset -1
					funcs.append(f)

			print '#if defined(need_%s)' % (ext)
			if remapped:
				print '/* functions defined in MESA_remap_table_functions are excluded */'

			# output extension functions that need to be mapped
			print 'static const struct gl_function_remap %s_functions[] = {' % (ext)
			for f in funcs:
				if f.offset >= 0:
					print '   { %5d, _gloffset_%s },' \
							% (pool_indices[f], f.name)
				else:
					print '   { %5d, -1 }, /* %s */' % \
							(pool_indices[f], f.name)
			print '   {    -1, -1 }'
			print '};'

			print '#endif'
			print ''

		return


def show_usage():
	print "Usage: %s [-f input_file_name]" % sys.argv[0]
	sys.exit(1)

if __name__ == '__main__':
	file_name = "gl_API.xml"

	try:
		(args, trail) = getopt.getopt(sys.argv[1:], "f:")
	except Exception,e:
		show_usage()

	for (arg,val) in args:
		if arg == "-f":
			file_name = val

	api = gl_XML.parse_GL_API( file_name )

	printer = PrintGlRemap()
	printer.Print( api )
