#!/usr/bin/python

import sys
import random

def main(argv):
	if len(argv) < 3 or argv[1] == "-h" or argv[1] == "--help":
		print """mkbin.py

A script to replace memMapCreate32. Creates input files for XMT-C.

Usage: mkbin.py source.in.h out
(will produce out.h, out.32b)

Input:
The input takes the form of a C header file with special comments denoting the
initial values of the variables. Each line should have a format similar to the
following, with one variable per line:

int demo[4];	// Data: 1 3 2 4

Options for input include:
	- Data		--	a space-seperated list of inital values
	- Source	--	a filename containing a newline-seperated list of values
	- Fill		--	a single value to fill the entire array OR "Random" and a
					value M, yeilding random integers in the range [0, M]

int a;			// Data: 1
int b[8]		// Source: b.txt
int c[4][4]		// Fill: 5
int d[12]		// Fill: Random
"""
		return 1

	source = open(argv[1], "r")
	outname = argv[2]
	header = open(outname+".h", "w")
	binary = open(outname+".32b", "w")

	header.write("""/****************************************
 Automatically Generated Header File


          DO NOT MODIFY 

 Contains following Variables :""")
	header.write("*/")
	header.write("\n\n")

	while 1:
		line = source.readline()
		line.strip()
		if line.startswith("//"):
			continue
		if line == "":
			break

		print "Processing variable...",

		(t, line) = line.split(" ", 1)
		
		mod = None
		if t == 'volatile':
			mod = t
			(t, line) = line.split(" ", 1)

		cast = None
		if t == 'int':
			cast = int
		else:
			print "Unsupported type", t
			return 1

		length = 1
		name = ""
		dims = []

		if line.find("[") != -1:
			index = line.find("[")
			name = line[:index]
			line = line[index:]
			while line.find("[") != -1:
				(foo,line) = line.split("[",1)
				(dim,line) = line.split("]",1)
				dims.append(int(dim))
		else:
			(name,line) = line.split(";")
		for i in dims:
			if i != 0:
				length *= i

		data = ""

		line = line.split("//")[1]
		line = line.strip()
		(key, val) = line.split(": ")
		## Data
		if key[0] == "D":
			data = val.split(" ")
			data = map(cast, data)
		## Source
		elif key[0] == "S":
			data = open(val, "r").readlines()
			data = map((lambda s: s.strip()), data)
			data = map(cast, data)
		## Fill
		elif key[0] == "F":
			## Random
			if val.find(" ") != -1 and val[0] == "R":
				data = [random.randint(0,int(val.split(" ")[1])) for i in range(length)]
			else:
				data = [cast(val)] * length
		else:
			print "ooops... no data found..."

		if mod:
			header.write(mod + " ")
		header.write(t + " ")
		header.write(name)
		for d in dims:
			header.write("[" + str(d) + "]")
		header.write(";\n")
		for i in range(len(dims)):
			header.write("int " + name + "_dim" + str(i) + "_size;\n")
		header.write("\n")

		## Byte order (1=least, 4=greatest significance):
		## 2 1 4 3 
		for i in data:
			bytes = []
			#print i,
			if t == 'int':
				for n in range(4):
					bytes.append(i%256)
					i = i >> 8
			#print bytes
			#for j in (1, 0, 3, 2):
			for j in (0, 1, 2, 3):
				binary.write(chr(bytes[j]))
		
		for i in dims:
			bytes = []
			#print i,
			for n in range(4):
				bytes.append(i%256)
				i = i >> 8
			#print bytes
			#for j in (1, 0, 3, 2):
			for j in (0, 1, 2, 3):
				binary.write(chr(bytes[j]))

		print "done with "+str(name)+"!"
			
		#(type, line) = line.split(" ", 1)

if __name__ == "__main__":
	sys.exit(main(sys.argv))

