#!/usr/bin/python

import re
from sys import argv

startline = "/* autogenerated by update_header.py. Please check and uncomment.\n"
changedline = "// changed declarations:\n"
newline = "// new declarations:\n"
endline = "*/ // update_header.py end\n"

def parse_c(data):
	l=0
	while l!=len(data):
		l=len(data)
		data=re.sub(r"(?ms)\{[^{}]*\}",";",data)
	data = re.sub(r"(?ms)/\*.*?\*/","",data)
	data = re.sub(r"(?m)^#.*$","",data)
	data = data.split(";")
	data = map(lambda x:x.strip(), data)
	data = filter(None, data) # kill empty lines
	data = map(lambda x:re.sub(r"\s*=.*$","",x), data)
	return data
		

def make_symtable(data):
	symbols={}
	for i in data:
		symname=get_symname(i)
		symbols[symname] = i
	return symbols

def get_symname(line):
	try:
		r = re.search(r"(\w+)($|\(|\[)",line).groups()[0]
		return r
	except:
		raise 'Could not extract symbol from "%s".'%repr(line)

def update_header(filebase):
	data = file(filebase+".c").read()
	data = parse_c(data)
	header = file(filebase+".h").read()
	header = parse_c(header)
	headersyms = make_symtable(header)
	
	changed=[]
	new=[]
	for i in data:
		symname = get_symname(i)
		if symname not in headersyms:
			new.append(i)
			continue
		headerline = headersyms[symname]
		headerline = re.sub(r"extern\s+","",headerline)
		if headerline != i:
			changed.append(i)

	print changed
	print new

	if (not changed) and (not new):
		return # nothing to do

	fd=file(filebase+".h")
	header = fd.readlines()
	fd.close()
	if startline in header:
		try:
			print "foo"
			start=header.index(startline)
			stop=header.index(endline)
			print start, stop
			header = header[:start] + header[stop+1:]
			fd = file(filebase+".h","wb")
			fd.write("".join(header))
			fd.close()
		except:
			print "Error killing old entry"
	fd = file(filebase+".h","ab")

	fd.write("\n\n\n")
	fd.write(startline)
	if changed:
		fd.write("\n")
		fd.write(changedline)
		for i in changed:
			fd.write("extern "+i+";\n")
	if new:
		fd.write("\n")
		fd.write(newline)
		for i in new:
			fd.write("extern "+i+";\n")
	fd.write("\n")
	fd.write(endline)
	fd.write("\n\n\n")
	fd.close()









def main():
	for i in argv[1:]:
		i=re.sub(".[ch]$","",i)
		update_header(i)


if __name__=="__main__":
	main()
