cgen.py revision c4f169cc5a990c9015782733b26bca4b2616ac24
185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Python script to parse cstubs file for gl and generate C stubs.
2670690e2aad728aeac7d9fd496002e4b3b49a159Guido van Rossum# usage: python cgen.py <cstubs >glmodule.c
385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
41242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum# NOTE: You  must first make a python binary without the "GL" option
51242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#	before you can run this, when building Python for the first time.
61242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#	See comments in the Makefile.
71242f1da6734c4660b3e557a4764d93783d85d51Guido van Rossum#
885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# XXX BUG return arrays generate wrong code
985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# XXX need to change error returns into gotos to free mallocked arrays
1085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
1185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
1285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumimport string
1385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumimport sys
1485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
1585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
1685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to print to stderr
1785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
1885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef err(args):
1985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	savestdout = sys.stdout
2085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	try:
2185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		sys.stdout = sys.stderr
2285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		for i in args:
2385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print i,
2485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print
2585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	finally:
2685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		sys.stdout = savestdout
2785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
2885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
2985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# The set of digits that form a number
3085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
3185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdigits = '0123456789'
3285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
3385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
3485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to extract a string of digits from the front of the string.
3585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Returns the leading string of digits and the remaining string.
3685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# If no number is found, returns '' and the original string.
3785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
3885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef getnum(s):
3985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n = ''
403f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum	while s and s[0] in digits:
413f5da24ea304e674a9abbdcffc4d671e32aa70f1Guido van Rossum		n = n + s[0]
4285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		s = s[1:]
4385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return n, s
4485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
4685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to check if a string is a number
4785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
4885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef isnum(s):
4985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if not s: return 0
5085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for c in s:
5185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if not c in digits: return 0
5285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return 1
5385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
5485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
5585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Allowed function return types
5685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
5785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumreturn_types = ['void', 'short', 'long']
5885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
5985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
6085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Allowed function argument types
6185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
62c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderarg_types = ['char', 'string', 'short', 'u_short', 'float', 'long', 'double']
6385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
6485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
6585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Need to classify arguments as follows
6685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	simple input variable
6785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	simple output variable
6885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	input array
6985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	output array
7085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	input giving size of some array
7185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
7285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Array dimensions can be specified as follows
7385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant
7485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	argN
7585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant * argN
7685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	retval
7785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	constant * retval
7885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
7985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# The dimensions given as constants * something are really
8085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# arrays of points where points are 2- 3- or 4-tuples
8185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
8285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# We have to consider three lists:
8385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	python input arguments
8485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	C stub arguments (in & out)
8585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	python output arguments (really return values)
8685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
8785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# There is a mapping from python input arguments to the input arguments
8885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# of the C stub, and a further mapping from C stub arguments to the
8985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# python return values
9085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Exception raised by checkarg() and generate()
9385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
9485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumarg_error = 'bad arg'
9585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
9785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Function to check one argument.
9885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Arguments: the type and the arg "name" (really mode plus subscript).
9985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Raises arg_error if something's wrong.
10085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Return type, mode, factor, rest of subscript; factor and rest may be empty.
10185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
10285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef checkarg(type, arg):
10385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
10485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Turn "char *x" into "string x".
10585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
1062817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if type == 'char' and arg[0] == '*':
10785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		type = 'string'
10885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		arg = arg[1:]
10985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
11085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Check that the type is supported.
11185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
11285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type not in arg_types:
11385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad type', type)
114c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if type[:2] == 'u_':
115c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		type = 'unsigned ' + type[2:]
11685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
11785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Split it in the mode (first character) and the rest.
11885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
11985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	mode, rest = arg[:1], arg[1:]
12085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
12185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The mode must be 's' for send (= input) or 'r' for return argument.
12285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
12385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if mode not in ('r', 's'):
12485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad arg mode', mode)
12585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
12685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Is it a simple argument: if so, we are done.
12785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
12885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if not rest:
12985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		return type, mode, '', ''
13085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
13185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Not a simple argument; must be an array.
13285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The 'rest' must be a subscript enclosed in [ and ].
13385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# The subscript must be one of the following forms,
13485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# otherwise we don't handle it (where N is a number):
13585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N
13685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	argN
13785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	retval
13885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N*argN
13985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#	N*retval
14085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if rest[:1] <> '[' or rest[-1:] <> ']':
14285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('subscript expected', rest)
14385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	sub = rest[1:-1]
14485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Is there a leading number?
14685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
14785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	num, sub = getnum(sub)
14885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if num:
14985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# There is a leading number
15085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if not sub:
15185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# The subscript is just a number
15285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			return type, mode, num, ''
1532817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if sub[:1] == '*':
15485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# There is a factor prefix
15585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			sub = sub[1:]
15685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
15785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('\'*\' expected', sub)
1582817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if sub == 'retval':
15985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# size is retval -- must be a reply argument
16085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if mode <> 'r':
16185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('non-r mode with [retval]', mode)
162c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	elif not isnum(sub) and (sub[:3] <> 'arg' or not isnum(sub[3:])):
16385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		raise arg_error, ('bad subscript', sub)
16485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
16585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return type, mode, num, sub
16685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
16785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
16885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# List of functions for which we have generated stubs
16985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
17085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumfunctions = []
17185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
17285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
17385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Generate the stub for the given function, using the database of argument
17485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# information build by successive calls to checkarg()
17585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
17685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef generate(type, func, database):
17785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
17885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Check that we can handle this case:
17985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# no variable size reply arrays yet
18085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
18185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n_in_args = 0
18285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	n_out_args = 0
18385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
18485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for a_type, a_mode, a_factor, a_sub in database:
1852817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's':
18685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_in_args = n_in_args + 1
1872817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		elif a_mode == 'r':
18885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_out_args = n_out_args + 1
18985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
19085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Can't happen
19185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			raise arg_error, ('bad a_mode', a_mode)
1922817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if (a_mode == 'r' and a_sub) or a_sub == 'retval':
19385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			e = 'Function', func, 'too complicated:'
19485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			err(e + (a_type, a_mode, a_factor, a_sub))
19585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '/* XXX Too complicated to generate code for */'
19685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			return
19785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
19885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	functions.append(func)
19985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
20085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Stub header
20185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
20285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print
20385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print 'static object *'
20485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print 'gl_' + func + '(self, args)'
20585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '\tobject *self;'
20685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '\tobject *args;'
20785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '{'
20885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
20985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Declare return value if any
21085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
21185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type <> 'void':
21285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + type, 'retval;'
21385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
21485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Declare arguments
21585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
21685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
21785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
21885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + a_type,
219c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		brac = ket = ''
220c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_sub and not isnum(a_sub):
221c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if a_factor:
222c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				brac = '('
223c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				ket = ')'
224c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print brac + '*',
225c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		print 'arg' + `i+1` + ket,
226c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_sub and isnum(a_sub):
227c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print '[', a_sub, ']',
228c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_factor:
22985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '[', a_factor, ']',
23085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print ';'
23185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
23285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Find input arguments derived from array sizes
23385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
23485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
23585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
2362817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's' and a_sub[:3] == 'arg' and isnum(a_sub[3:]):
23785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Sending a variable-length array
23885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n = eval(a_sub[3:])
23985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if 1 <= n <= len(database):
24085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			    b_type, b_mode, b_factor, b_sub = database[n-1]
2412817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum			    if b_mode == 's':
24285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			        database[n-1] = b_type, 'i', a_factor, `i`
24385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			        n_in_args = n_in_args - 1
24485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
24585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Assign argument positions in the Python argument list
24685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
24785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	in_pos = []
24885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	i_in = 0
24985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
25085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
2512817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 's':
25285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			in_pos.append(i_in)
25385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			i_in = i_in + 1
25485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
25585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			in_pos.append(-1)
25685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
25785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Get input arguments
25885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
25985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
26085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
261c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_type[:9] == 'unsigned ':
262c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			xtype = a_type[9:]
263c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		else:
264c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			xtype = a_type
2652817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 'i':
26685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
26785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Implicit argument;
26885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# a_factor is divisor if present,
26985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# a_sub indicates which arg (`database index`)
27085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
27185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			j = eval(a_sub)
27285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tif',
273c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			print '(!geti' + xtype + 'arraysize(args,',
27485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print `n_in_args` + ',',
27585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print `in_pos[j]` + ',',
276c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if xtype <> a_type:
277c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '('+xtype+' *)',
27885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '&arg' + `i+1` + '))'
27985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t\treturn NULL;'
28085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if a_factor:
28185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\targ' + `i+1`,
28285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '= arg' + `i+1`,
28385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '/', a_factor + ';'
2842817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		elif a_mode == 's':
285c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if a_sub and not isnum(a_sub):
286c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				# Allocate memory for varsize array
28785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\tif ((arg' + `i+1`, '=',
288c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if a_factor:
289c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+a_type+'(*)['+a_factor+'])',
290c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print 'NEW(' + a_type, ',',
291c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if a_factor:
292c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print a_factor, '*',
29385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print a_sub, ')) == NULL)'
29485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\t\treturn err_nomem();'
29585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tif',
29685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if a_factor or a_sub: # Get a fixed-size array array
297c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '(!geti' + xtype + 'array(args,',
29885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `n_in_args` + ',',
29985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `in_pos[i]` + ',',
30085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_factor: print a_factor,
30185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_factor and a_sub: print '*',
30285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if a_sub: print a_sub,
303c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print ',',
304c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if (a_sub and a_factor) or xtype <> a_type:
305c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+xtype+' *)',
306c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print 'arg' + `i+1` + '))'
30785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else: # Get a simple variable
308c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				print '(!geti' + xtype + 'arg(args,',
30985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `n_in_args` + ',',
31085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `in_pos[i]` + ',',
311c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				if xtype <> a_type:
312c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender					print '('+xtype+' *)',
31385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '&arg' + `i+1` + '))'
31485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t\treturn NULL;'
31585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
31685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Begin of function call
31785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
31885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if type <> 'void':
31985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\tretval =', func + '(',
32085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
32185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print '\t' + func + '(',
32285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
32385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Argument list
32485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
32585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
32685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if i > 0: print ',',
32785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
3282817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if a_mode == 'r' and not a_factor:
32985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '&',
33085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print 'arg' + `i+1`,
33185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
33285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# End of function call
33385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
33485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print ');'
33585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
33685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Free varsize arrays
33785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
33885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	for i in range(len(database)):
33985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		a_type, a_mode, a_factor, a_sub = database[i]
340c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if a_mode == 's' and a_sub and not isnum(a_sub):
34185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tDEL(arg' + `i+1` + ');'
34285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
34385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Return
34485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
34585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	if n_out_args:
34685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
34785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Multiple return values -- construct a tuple
34885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
34985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if type <> 'void':
35085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			n_out_args = n_out_args + 1
3512817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if n_out_args == 1:
35285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			for i in range(len(database)):
35385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				a_type, a_mode, a_factor, a_sub = database[i]
3542817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum				if a_mode == 'r':
35585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					break
35685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else:
35785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				raise arg_error, 'expected r arg not found'
35885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\treturn',
35985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print mkobject(a_type, 'arg' + `i+1`) + ';'
36085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
36185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t{ object *v = newtupleobject(',
36285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print n_out_args, ');'
36385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t  if (v == NULL) return NULL;'
36485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			i_out = 0
36585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			if type <> 'void':
36685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '\t  settupleitem(v,',
36785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print `i_out` + ',',
36885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print mkobject(type, 'retval') + ');'
36985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				i_out = i_out + 1
37085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			for i in range(len(database)):
37185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				a_type, a_mode, a_factor, a_sub = database[i]
3722817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum				if a_mode == 'r':
37385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					print '\t  settupleitem(v,',
37485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					print `i_out` + ',',
37585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					s = mkobject(a_type, 'arg' + `i+1`)
37685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					print s + ');'
37785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					i_out = i_out + 1
37885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t  return v;'
37985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\t}'
38085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
38185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
38285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Simple function return
38385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# Return None or return value
38485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
3852817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if type == 'void':
38685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\tINCREF(None);'
38785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\treturn None;'
38885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
38985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			print '\treturn', mkobject(type, 'retval') + ';'
39085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
39185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	# Stub body closing brace
39285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
39385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '}'
39485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
39585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
39685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Subroutine to return a function call to mknew<type>object(<arg>)
39785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
39885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumdef mkobject(type, arg):
399c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if type[:9] == 'unsigned ':
400c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		type = type[9:]
401c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		return 'mknew' + type + 'object((' + type + ') ' + arg + ')'
40285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	return 'mknew' + type + 'object(' + arg + ')'
40385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
40485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
405c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderdefined_archs = []
406c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender
407c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender# usage: cgen [ -Dmach ... ] [ file ]
408c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullenderfor arg in sys.argv[1:]:
409c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if arg[:2] == '-D':
410c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		defined_archs.append(arg[2:])
411c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	else:
412c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# Open optional file argument
413c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		sys.stdin = open(arg, 'r')
4145c85062e1ce4c7e51daaad1a4eb3f66f6b5a0ea8Guido van Rossum
4155c85062e1ce4c7e51daaad1a4eb3f66f6b5a0ea8Guido van Rossum
41685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Input line number
41785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumlno = 0
41885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
41985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
42085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Input is divided in two parts, separated by a line containing '%%'.
42185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	<part1>		-- literally copied to stdout
42285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#	<part2>		-- stub definitions
42385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
42485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Variable indicating the current input part.
42585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
42685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumpart = 1
42785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
42885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum# Main loop over the input
42985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum#
43085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumwhile 1:
43185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	try:
43285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		line = raw_input()
43385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	except EOFError:
43485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		break
43585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
43685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	lno = lno+1
43785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	words = string.split(line)
43885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	#
4392817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	if part == 1:
44085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
44185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# In part 1, copy everything literally
44285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		# except look for a line of just '%%'
44385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		#
4442817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum		if words == ['%%']:
44585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			part = part + 1
44685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
44785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
44885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# Look for names of manually written
44985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# stubs: a single percent followed by the name
45085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# of the function in Python.
45185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			# The stub name is derived by prefixing 'gl_'.
45285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			#
4532817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum			if words and words[0][0] == '%':
45485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				func = words[0][1:]
45585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if (not func) and words[1:]:
45685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					func = words[1]
45785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				if func:
45885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					functions.append(func)
45985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			else:
46085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print line
461c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		continue
462c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if not words:
463c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		continue		# skip empty line
464c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	elif words[0] == 'if':
465c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# if XXX rest
466c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		# if !XXX rest
467c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		if words[1][0] == '!':
468c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			if words[1][1:] in defined_archs:
469c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender				continue
470c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		elif words[1] not in defined_archs:
471c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender			continue
472c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender		words = words[2:]
473c4f169cc5a990c9015782733b26bca4b2616ac24Sjoerd Mullender	if words[0] == '#include':
47485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		print line
4752817875b2e8ad4b2ef6bb180c63e5bab56da8bc1Guido van Rossum	elif words[0][:1] == '#':
47685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		pass			# ignore comment
47785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	elif words[0] not in return_types:
47885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		err('Line', lno, ': bad return type :', words[0])
47985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	elif len(words) < 2:
48085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		err('Line', lno, ': no funcname :', line)
48185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	else:
48285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		if len(words) % 2 <> 0:
48385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			err('Line', lno, ': odd argument list :', words[2:])
48485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum		else:
48585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			database = []
48685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			try:
48785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				for i in range(2, len(words), 2):
48885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					x = checkarg(words[i], words[i+1])
48985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum					database.append(x)
49085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print
49185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '/*',
49285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				for w in words: print w,
49385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				print '*/'
49485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				generate(words[0], words[1], database)
49585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum			except arg_error, msg:
49685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum				err('Line', lno, ':', msg)
49785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
49885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum
49985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint
50085a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint 'static struct methodlist gl_methods[] = {'
50185a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumfor func in functions:
50285a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossum	print '\t{"' + func + '", gl_' + func + '},'
50385a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '\t{NULL, NULL} /* Sentinel */'
50485a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '};'
50585a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint
50685a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint 'initgl()'
50785a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '{'
50885a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '\tinitmodule("gl", gl_methods);'
50985a5fbbdfea617f6cc8fae82c9e8c2b5c424436dGuido van Rossumprint '}'
510