cgen.py revision 1ed5e5768429f425f5bcb9f03bf04179dcca569f
1b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum########################################################################
2524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum# Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum# The Netherlands.
4524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum#
5b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum#                         All Rights Reserved
6524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum#
7524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum# Permission to use, copy, modify, and distribute this software and its
8524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum# documentation for any purpose and without fee is hereby granted,
9b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum# provided that the above copyright notice appear in all copies and that
10524b588553afb0759c5be590a7aa41db92dcd2aeGuido van Rossum# both that copyright notice and this permission notice appear in
11b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum# supporting documentation, and that the names of Stichting Mathematisch
12d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# Centrum or CWI or Corporation for National Research Initiatives or
13d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# CNRI not be used in advertising or publicity pertaining to
14d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# distribution of the software without specific, written prior
15d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# permission.
16d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum#
17d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# While CWI is the initial source for this software, a modified version
18d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# is made available by the Corporation for National Research Initiatives
19d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# (CNRI) at the Internet address ftp://ftp.python.org.
20d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum#
21d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28d266eb460e20ded087d01a29da0a230e235afc40Guido van Rossum# PERFORMANCE OF THIS SOFTWARE.
29b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum########################################################################
30b6775db241f5fe5e3dc2ca09fc6c9e6164d4b2afGuido van Rossum
3185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Python script to parse cstubs file for gl and generate C stubs.
32670690e2aad728aeac7d9fd496002e4b3b49a159Guido van Rossum# usage: python cgen.py <cstubs >glmodule.c
3385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
341242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum# NOTE: You  must first make a python binary without the "GL" option
351242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#	before you can run this, when building Python for the first time.
361242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#	See comments in the Makefile.
371242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#
3885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# XXX BUG return arrays generate wrong code
3985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# XXX need to change error returns into gotos to free mallocked arrays
4085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumimport string
4385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumimport sys
4485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to print to stderr
4785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
48064a62bc8a5b4e766dedc7afa83dc9b23267fcccGuido van Rossumdef err(*args):
4985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	savestdout = sys.stdout
5085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	try:
5185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		sys.stdout = sys.stderr
5285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		for i in args:
5385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print i,
5485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print
5585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	finally:
5685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		sys.stdout = savestdout
5785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
5885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
5985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# The set of digits that form a number
6085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
6185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdigits = '0123456789'
6285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
6385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
6485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to extract a string of digits from the front of the string.
6585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Returns the leading string of digits and the remaining string.
6685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# If no number is found, returns '' and the original string.
6785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
6885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef getnum(s):
6985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n = ''
703f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum	while s and s[0] in digits:
713f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum		n = n + s[0]
7285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		s = s[1:]
7385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return n, s
7485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
7585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
7685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to check if a string is a number
7785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
7885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef isnum(s):
7985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if not s: return 0
8085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for c in s:
8185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if not c in digits: return 0
8285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return 1
8385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
8485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
8585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Allowed function return types
8685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
8785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumreturn_types = ['void', 'short', 'long']
8885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
8985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Allowed function argument types
9185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
92c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderarg_types = ['char', 'string', 'short', 'u_short', 'float', 'long', 'double']
9385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Need to classify arguments as follows
9685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	simple input variable
9785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	simple output variable
9885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	input array
9985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	output array
10085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	input giving size of some array
10185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
10285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Array dimensions can be specified as follows
10385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant
10485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	argN
10585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant * argN
10685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	retval
10785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant * retval
10885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
10985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# The dimensions given as constants * something are really
11085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# arrays of points where points are 2- 3- or 4-tuples
11185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
11285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# We have to consider three lists:
11385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	python input arguments
11485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	C stub arguments (in & out)
11585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	python output arguments (really return values)
11685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
11785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# There is a mapping from python input arguments to the input arguments
11885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# of the C stub, and a further mapping from C stub arguments to the
11985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# python return values
12085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
12185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
12285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Exception raised by checkarg() and generate()
12385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
12485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumarg_error = 'bad arg'
12585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
12685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
12785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to check one argument.
12885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Arguments: the type and the arg "name" (really mode plus subscript).
12985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Raises arg_error if something's wrong.
13085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Return type, mode, factor, rest of subscript; factor and rest may be empty.
13185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
13285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef checkarg(type, arg):
13385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
13485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Turn "char *x" into "string x".
13585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
1362817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if type == 'char' and arg[0] == '*':
13785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		type = 'string'
13885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		arg = arg[1:]
13985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Check that the type is supported.
14185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type not in arg_types:
14385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad type', type)
144c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if type[:2] == 'u_':
145c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		type = 'unsigned ' + type[2:]
14685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Split it in the mode (first character) and the rest.
14885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	mode, rest = arg[:1], arg[1:]
15085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
15185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The mode must be 's' for send (= input) or 'r' for return argument.
15285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
15385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if mode not in ('r', 's'):
15485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad arg mode', mode)
15585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
15685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Is it a simple argument: if so, we are done.
15785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
15885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if not rest:
15985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		return type, mode, '', ''
16085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
16185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Not a simple argument; must be an array.
16285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The 'rest' must be a subscript enclosed in [ and ].
16385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The subscript must be one of the following forms,
16485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# otherwise we don't handle it (where N is a number):
16585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N
16685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	argN
16785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	retval
16885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N*argN
16985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N*retval
17085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
17185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if rest[:1] <> '[' or rest[-1:] <> ']':
17285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('subscript expected', rest)
17385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	sub = rest[1:-1]
17485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
17585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Is there a leading number?
17685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
17785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	num, sub = getnum(sub)
17885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if num:
17985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# There is a leading number
18085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if not sub:
18185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# The subscript is just a number
18285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			return type, mode, num, ''
1832817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if sub[:1] == '*':
18485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# There is a factor prefix
18585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			sub = sub[1:]
18685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
18785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('\'*\' expected', sub)
1882817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if sub == 'retval':
18985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# size is retval -- must be a reply argument
19085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if mode <> 'r':
19185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('non-r mode with [retval]', mode)
192c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	elif not isnum(sub) and (sub[:3] <> 'arg' or not isnum(sub[3:])):
19385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad subscript', sub)
19485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
19585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return type, mode, num, sub
19685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
19785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
19885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# List of functions for which we have generated stubs
19985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
20085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumfunctions = []
20185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
20285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
20385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Generate the stub for the given function, using the database of argument
20485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# information build by successive calls to checkarg()
20585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
20685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef generate(type, func, database):
20785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
20885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Check that we can handle this case:
20985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# no variable size reply arrays yet
21085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
21185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n_in_args = 0
21285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n_out_args = 0
21385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
21485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for a_type, a_mode, a_factor, a_sub in database:
2152817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's':
21685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_in_args = n_in_args + 1
2172817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		elif a_mode == 'r':
21885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_out_args = n_out_args + 1
21985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
22085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Can't happen
22185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('bad a_mode', a_mode)
2222817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if (a_mode == 'r' and a_sub) or a_sub == 'retval':
223064a62bc8a5b4e766dedc7afa83dc9b23267fcccGuido van Rossum			err('Function', func, 'too complicated:',
224064a62bc8a5b4e766dedc7afa83dc9b23267fcccGuido van Rossum			    a_type, a_mode, a_factor, a_sub)
22585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '/* XXX Too complicated to generate code for */'
22685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			return
22785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
22885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	functions.append(func)
22985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
23085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Stub header
23185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
23285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print
2330a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum	print 'static PyObject *'
23485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print 'gl_' + func + '(self, args)'
2350a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum	print '\tPyObject *self;'
2360a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum	print '\tPyObject *args;'
23785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '{'
23885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
23985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Declare return value if any
24085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
24185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type <> 'void':
24285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + type, 'retval;'
24385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
24485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Declare arguments
24585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
24685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
24785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
24885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + a_type,
249c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		brac = ket = ''
250c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_sub and not isnum(a_sub):
251c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if a_factor:
252c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				brac = '('
253c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				ket = ')'
254c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print brac + '*',
255c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		print 'arg' + `i+1` + ket,
256c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_sub and isnum(a_sub):
257c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print '[', a_sub, ']',
258c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_factor:
25985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '[', a_factor, ']',
26085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print ';'
26185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
26285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Find input arguments derived from array sizes
26385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
26485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
26585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
2662817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's' and a_sub[:3] == 'arg' and isnum(a_sub[3:]):
26785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Sending a variable-length array
26885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n = eval(a_sub[3:])
26985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if 1 <= n <= len(database):
27085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			    b_type, b_mode, b_factor, b_sub = database[n-1]
2712817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum			    if b_mode == 's':
27285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			        database[n-1] = b_type, 'i', a_factor, `i`
27385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			        n_in_args = n_in_args - 1
27485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
27585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Assign argument positions in the Python argument list
27685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
27785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	in_pos = []
27885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	i_in = 0
27985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
28085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
2812817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's':
28285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			in_pos.append(i_in)
28385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			i_in = i_in + 1
28485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
28585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			in_pos.append(-1)
28685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
28785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Get input arguments
28885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
28985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
29085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
291c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_type[:9] == 'unsigned ':
292c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			xtype = a_type[9:]
293c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		else:
294c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			xtype = a_type
2952817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 'i':
29685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
29785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Implicit argument;
29885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# a_factor is divisor if present,
29985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# a_sub indicates which arg (`database index`)
30085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
30185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			j = eval(a_sub)
30285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tif',
303c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print '(!geti' + xtype + 'arraysize(args,',
30485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print `n_in_args` + ',',
30585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print `in_pos[j]` + ',',
306c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if xtype <> a_type:
307c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '('+xtype+' *)',
30885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '&arg' + `i+1` + '))'
30985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t\treturn NULL;'
31085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if a_factor:
31185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\targ' + `i+1`,
31285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '= arg' + `i+1`,
31385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '/', a_factor + ';'
3142817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		elif a_mode == 's':
315c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if a_sub and not isnum(a_sub):
316c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				# Allocate memory for varsize array
31785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\tif ((arg' + `i+1`, '=',
318c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if a_factor:
319c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+a_type+'(*)['+a_factor+'])',
3200a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum				print 'PyMem_NEW(' + a_type, ',',
321c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if a_factor:
322c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print a_factor, '*',
32385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print a_sub, ')) == NULL)'
3240a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum				print '\t\treturn PyErr_NoMemory();'
32585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tif',
32685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if a_factor or a_sub: # Get a fixed-size array array
327c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '(!geti' + xtype + 'array(args,',
32885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `n_in_args` + ',',
32985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `in_pos[i]` + ',',
33085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_factor: print a_factor,
33185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_factor and a_sub: print '*',
33285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_sub: print a_sub,
333c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print ',',
334c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if (a_sub and a_factor) or xtype <> a_type:
335c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+xtype+' *)',
336c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print 'arg' + `i+1` + '))'
33785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else: # Get a simple variable
338c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '(!geti' + xtype + 'arg(args,',
33985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `n_in_args` + ',',
34085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `in_pos[i]` + ',',
341c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if xtype <> a_type:
342c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+xtype+' *)',
34385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '&arg' + `i+1` + '))'
34485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t\treturn NULL;'
34585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
34685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Begin of function call
34785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
34885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type <> 'void':
34985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\tretval =', func + '(',
35085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
35185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + func + '(',
35285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
35385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Argument list
35485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
35585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
35685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if i > 0: print ',',
35785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
3582817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 'r' and not a_factor:
35985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '&',
36085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print 'arg' + `i+1`,
36185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
36285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# End of function call
36385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
36485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print ');'
36585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
36685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Free varsize arrays
36785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
36885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
36985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
370c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_mode == 's' and a_sub and not isnum(a_sub):
3710a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum			print '\tPyMem_DEL(arg' + `i+1` + ');'
37285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
37385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Return
37485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
37585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if n_out_args:
37685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
37785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Multiple return values -- construct a tuple
37885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
37985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if type <> 'void':
38085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_out_args = n_out_args + 1
3812817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if n_out_args == 1:
38285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			for i in range(len(database)):
38385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				a_type, a_mode, a_factor, a_sub = database[i]
3842817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum				if a_mode == 'r':
38585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					break
38685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else:
38785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				raise arg_error, 'expected r arg not found'
38885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\treturn',
38985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print mkobject(a_type, 'arg' + `i+1`) + ';'
39085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
3910a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum			print '\t{ PyObject *v = PyTuple_New(',
39285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print n_out_args, ');'
39385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t  if (v == NULL) return NULL;'
39485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			i_out = 0
39585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if type <> 'void':
3960a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum				print '\t  PyTuple_SetItem(v,',
39785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `i_out` + ',',
39885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print mkobject(type, 'retval') + ');'
39985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				i_out = i_out + 1
40085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			for i in range(len(database)):
40185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				a_type, a_mode, a_factor, a_sub = database[i]
4022817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum				if a_mode == 'r':
4030a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum					print '\t  PyTuple_SetItem(v,',
40485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					print `i_out` + ',',
40585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					s = mkobject(a_type, 'arg' + `i+1`)
40685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					print s + ');'
40785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					i_out = i_out + 1
40885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t  return v;'
40985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t}'
41085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
41185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
41285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Simple function return
41385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Return None or return value
41485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
4152817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if type == 'void':
4160a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum			print '\tPy_INCREF(Py_None);'
4170a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossum			print '\treturn Py_None;'
41885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
41985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\treturn', mkobject(type, 'retval') + ';'
42085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
42185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Stub body closing brace
42285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
42385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '}'
42485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
42585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
42685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Subroutine to return a function call to mknew<type>object(<arg>)
42785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
42885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef mkobject(type, arg):
429c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if type[:9] == 'unsigned ':
430c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		type = type[9:]
431c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		return 'mknew' + type + 'object((' + type + ') ' + arg + ')'
43285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return 'mknew' + type + 'object(' + arg + ')'
43385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
43485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
435c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderdefined_archs = []
436c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender
437c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender# usage: cgen [ -Dmach ... ] [ file ]
438c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderfor arg in sys.argv[1:]:
439c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if arg[:2] == '-D':
440c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		defined_archs.append(arg[2:])
441c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	else:
442c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# Open optional file argument
443c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		sys.stdin = open(arg, 'r')
4445c85062e1ce4c7e51daaad1a4eb3f66f6b5a0ea8Guido van Rossum
4455c85062e1ce4c7e51daaad1a4eb3f66f6b5a0ea8Guido van Rossum
44685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Input line number
44785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumlno = 0
44885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
44985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
45085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Input is divided in two parts, separated by a line containing '%%'.
45185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	<part1>		-- literally copied to stdout
45285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	<part2>		-- stub definitions
45385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
45485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Variable indicating the current input part.
45585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
45685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumpart = 1
45785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
45885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Main loop over the input
45985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
46085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumwhile 1:
46185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	try:
46285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		line = raw_input()
46385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	except EOFError:
46485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		break
46585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
46685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	lno = lno+1
46785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	words = string.split(line)
46885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
4692817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if part == 1:
47085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
47185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# In part 1, copy everything literally
47285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# except look for a line of just '%%'
47385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
4742817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if words == ['%%']:
47585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			part = part + 1
47685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
47785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
47885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Look for names of manually written
47985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# stubs: a single percent followed by the name
48085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# of the function in Python.
48185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# The stub name is derived by prefixing 'gl_'.
48285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
4832817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum			if words and words[0][0] == '%':
48485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				func = words[0][1:]
48585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if (not func) and words[1:]:
48685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					func = words[1]
48785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if func:
48885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					functions.append(func)
48985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else:
49085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print line
491c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		continue
492c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if not words:
493c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		continue		# skip empty line
494c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	elif words[0] == 'if':
495c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# if XXX rest
496c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# if !XXX rest
497c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if words[1][0] == '!':
498c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if words[1][1:] in defined_archs:
499c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				continue
500c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		elif words[1] not in defined_archs:
501c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			continue
502c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		words = words[2:]
503c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if words[0] == '#include':
50485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print line
5052817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	elif words[0][:1] == '#':
50685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		pass			# ignore comment
50785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	elif words[0] not in return_types:
50885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		err('Line', lno, ': bad return type :', words[0])
50985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	elif len(words) < 2:
51085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		err('Line', lno, ': no funcname :', line)
51185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
51285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if len(words) % 2 <> 0:
51385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			err('Line', lno, ': odd argument list :', words[2:])
51485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
51585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			database = []
51685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			try:
51785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				for i in range(2, len(words), 2):
51885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					x = checkarg(words[i], words[i+1])
51985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					database.append(x)
52085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print
52185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '/*',
52285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				for w in words: print w,
52385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '*/'
52485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				generate(words[0], words[1], database)
52585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			except arg_error, msg:
52685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				err('Line', lno, ':', msg)
52785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
52885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
52985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint
5300a3eaf083882ad7448beaebe0c1e56702d9a1b4aGuido van Rossumprint 'static struct PyMethodDef gl_methods[] = {'
53185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumfor func in functions:
53285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '\t{"' + func + '", gl_' + func + '},'
53385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '\t{NULL, NULL} /* Sentinel */'
53485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '};'
53585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint
5367ce52be62748582247754c2cbb88bb81e39b6b98Guido van Rossumprint 'void'
53785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint 'initgl()'
53885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '{'
5391ed5e5768429f425f5bcb9f03bf04179dcca569fGuido van Rossumprint '\t(void) Py_InitModule("gl", gl_methods);'
54085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '}'
541