#! /usr/bin/env python

# Read #define's and translate to Python code.
# Handle #include statements.
# Handle #define macros with one argument.
# Anything that isn't recognized or doesn't translate into valid
# Python is ignored.

# Without filename arguments, acts as a filter.
# If one or more filenames are given, output is written to corresponding
# filenames in the local directory, translated to all uppercase, with
# the extension replaced by ".py".

# By passing one or more options of the form "-i regular_expression"
# you can specify additional strings to be ignored.  This is useful
# e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".

# XXX To do:
# - turn trailing C comments into Python comments
# - turn C Boolean operators "&& || !" into Python "and or not"
# - what to do about #if(def)?
# - what to do about macros with multiple parameters?

import sys, regex, regsub, string, getopt, os

p_define = regex.compile('^[\t ]*#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+')

p_macro = regex.compile(
  '^[\t ]*#[\t ]*define[\t ]+'
  '\([a-zA-Z0-9_]+\)(\([_a-zA-Z][_a-zA-Z0-9]*\))[\t ]+')

p_include = regex.compile('^[\t ]*#[\t ]*include[\t ]+<\([a-zA-Z0-9_/\.]+\)')

p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?')
p_cpp_comment = regex.compile('//.*')

ignores = [p_comment, p_cpp_comment]

p_char = regex.compile("'\(\\\\.[^\\\\]*\|[^\\\\]\)'")

filedict = {}

try:
	searchdirs=string.splitfields(os.environ['include'],';')
except KeyError:
	try:
		searchdirs=string.splitfields(os.environ['INCLUDE'],';')
	except KeyError:
		try:
			if string.find( sys.platform, "beos" ) == 0:
				searchdirs=string.splitfields(os.environ['BEINCLUDES'],';')
			else:
				raise KeyError
		except KeyError:
			searchdirs=['/usr/include']

def main():
	global filedict
	opts, args = getopt.getopt(sys.argv[1:], 'i:')
	for o, a in opts:
		if o == '-i':
			ignores.append(regex.compile(a))
	if not args:
		args = ['-']
	for filename in args:
		if filename == '-':
			sys.stdout.write('# Generated by h2py from stdin\n')
			process(sys.stdin, sys.stdout)
		else:
			fp = open(filename, 'r')
			outfile = os.path.basename(filename)
			i = string.rfind(outfile, '.')
			if i > 0: outfile = outfile[:i]
			outfile = string.upper(outfile)
			outfile = outfile + '.py'
			outfp = open(outfile, 'w')
			outfp.write('# Generated by h2py from %s\n' % filename)
			filedict = {}
			for dir in searchdirs:
				if filename[:len(dir)] == dir:
					filedict[filename[len(dir)+1:]] = None	# no '/' trailing
					break
			process(fp, outfp)
			outfp.close()
			fp.close()

def process(fp, outfp, env = {}):
	lineno = 0
	while 1:
		line = fp.readline()
		if not line: break
		lineno = lineno + 1
		n = p_define.match(line)
		if n >= 0:
			# gobble up continuation lines
			while line[-2:] == '\\\n':
				nextline = fp.readline()
				if not nextline: break
				lineno = lineno + 1
				line = line + nextline
			name = p_define.group(1)
			body = line[n:]
			# replace ignored patterns by spaces
			for p in ignores:
				body = regsub.gsub(p, ' ', body)
			# replace char literals by ord(...)
			body = regsub.gsub(p_char, 'ord(\\0)', body)
			stmt = '%s = %s\n' % (name, string.strip(body))
			ok = 0
			try:
				exec stmt in env
			except:
				sys.stderr.write('Skipping: %s' % stmt)
			else:
				outfp.write(stmt)
		n =p_macro.match(line)
		if n >= 0:
			macro, arg = p_macro.group(1, 2)
			body = line[n:]
			for p in ignores:
				body = regsub.gsub(p, ' ', body)
			body = regsub.gsub(p_char, 'ord(\\0)', body)
			stmt = 'def %s(%s): return %s\n' % (macro, arg, body)
			try:
				exec stmt in env
			except:
				sys.stderr.write('Skipping: %s' % stmt)
			else:
				outfp.write(stmt)
		if p_include.match(line) >= 0:
			regs = p_include.regs
			a, b = regs[1]
			filename = line[a:b]
			if not filedict.has_key(filename):
				filedict[filename] = None
				inclfp = None
				for dir in searchdirs:
					try:
						inclfp = open(dir + '/' + filename, 'r')
						break
					except IOError:
						pass
				if inclfp:
					outfp.write(
						'\n# Included from %s\n' % filename)
					process(inclfp, outfp, env)
				else:
					sys.stderr.write('Warning - could not find file %s' % filename)

main()
