#!/usr/bin/env python

# This script assumes that the directories binutils/, gcc/, and 
# avr-libc/ are siblings of this file, as is the xmega.lst file.  These 
# trees were taken directly from svn trunk of each project as of Nov 29 
# 2012, though the sections changed are not in high flux.
#
# If rename = 0 (a few lines down from here), it will create the new 
# files leaving the old ones in place.  rename = 1 will move the temp 
# files over.

import os, math, textwrap

rename = 1

x = open("xmega.lst","r")

xmegas = []
byclass = {}

for line in x:
  line = line.strip()
  parts = line.split(",")
  parts[1] = int(parts[1])
  xmegas.append(parts)
  if not byclass.has_key(parts[1]):
    byclass[parts[1]] = []
  byclass[parts[1]].append(parts)


o = open("avr-libc/configure.ac","r")
n = open("avr-libc/configure.ac.new","w")
state = 0
avrclass = 0
for line in o:
  if state == 0:
    if line[:27] == "AM_CONDITIONAL(HAS_avrxmega":
      avrclass = int(line[27])
      n.write(line)
      n.write("\n")
      for parts in byclass[avrclass]:
        n.write("CHECK_AVR_DEVICE(atxmega%s)\nAM_CONDITIONAL(HAS_atxmega%s, test \"x$HAS_atxmega%s\" = \"xyes\")\n\n" % (parts[0],parts[0],parts[0]))
      state = 1
    elif line[:17] == "\tavr/lib/avrxmega":
      avrclass = int(line[17])
      n.write(line)
      for parts in byclass[avrclass]:
        n.write("\tavr/lib/avrxmega%d/atxmega%s/Makefile\n" % (avrclass,parts[0]))
      n.write("])\n\n")
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[0] == "#":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/configure.ac.new","avr-libc/configure.ac")



flags = {
	2: "${DEV_DEFS}:${CFLAGS_SPACE}:${DEV_ASFLAGS}",
	4: "${DEV_DEFS}:${CFLAGS_BIG_MEMORY}:${DEV_ASFLAGS}",
	5: "${DEV_DEFS}:${CFLAGS_BIG_MEMORY}:${DEV_ASFLAGS}",
	6: "${DEV_DEFS}:${CFLAGS_BIG_MEMORY}:${DEV_ASFLAGS}",
	7: "${DEV_DEFS}:${CFLAGS_BIG_MEMORY}:${DEV_ASFLAGS}",
}


o = open("avr-libc/devtools/gen-avr-lib-tree.sh","r")
n = open("avr-libc/devtools/gen-avr-lib-tree.sh.new","w")
state = 0
avrclass = 0
for line in o:
  if state == 0:
    if line[:8] == "AVRXMEGA":
      avrclass = int(line[8])
      n.write(line)
      for parts in byclass[avrclass]:
        n.write("atxmega%s:crtx%s.o:%s;\\\n" % (parts[0],parts[0],flags[avrclass]))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[0] == "\"":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/devtools/gen-avr-lib-tree.sh.new","avr-libc/devtools/gen-avr-lib-tree.sh")
if rename: os.chmod("avr-libc/devtools/gen-avr-lib-tree.sh", 0755)



o = open("avr-libc/include/avr/io.h","r")
n = open("avr-libc/include/avr/io.h.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:28] == "#elif defined (__AVR_ATxmega":
      for parts in xmegas:
        n.write("#elif defined (__AVR_ATxmega%s__)\n#  include <avr/iox%s.h>\n" % (parts[0].upper(),parts[0]))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[:23] == "#elif defined (__AVR_AT" and line[23:28] != "xmega":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/include/avr/io.h.new","avr-libc/include/avr/io.h")



o = open("avr-libc/include/avr/eeprom.h","r")
n = open("avr-libc/include/avr/eeprom.h.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:28] == "#elif defined (__AVR_ATxmega":
      for parts in xmegas:
        n.write("#elif defined (__AVR_ATxmega%s__)\n# define _EEPROM_SUFFIX %s\n" % (parts[0].upper(),parts[0]))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[:23] == "#elif defined (__AVR_AT" and line[23:28] != "xmega":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/include/avr/eeprom.h.new","avr-libc/include/avr/eeprom.h")


o = open("avr-libc/include/avr/sleep.h","r")
n = open("avr-libc/include/avr/sleep.h.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:27] == "#elif defined(__AVR_ATxmega":
      n.write("#elif defined(__AVR_ATxmega%s__) \\\n" % (xmegas[0][0].upper()))
      for parts in xmegas[1:-1]:
        n.write("|| defined(__AVR_ATxmega%s__) \\\n" % (parts[0].upper()))
      n.write("|| defined(__AVR_ATxmega%s__) \\\n" % (parts[-1].upper()))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[0] == "\n":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/include/avr/sleep.h.new","avr-libc/include/avr/sleep.h")


o = open("avr-libc/include/avr/wdt.h","r")
n = open("avr-libc/include/avr/wdt.h.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:25] == "#if defined(__AVR_ATxmega":
      n.write("#if defined(__AVR_ATxmega%s__) \\\n" % (xmegas[0][0].upper()))
      for parts in xmegas[1:-1]:
        n.write("|| defined(__AVR_ATxmega%s__) \\\n" % (parts[0].upper()))
      n.write("|| defined(__AVR_ATxmega%s__)\n" % (parts[-1].upper()))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[0] == "\n":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/include/avr/wdt.h.new","avr-libc/include/avr/wdt.h")



o = open("avr-libc/include/avr/Makefile.am","r")
n = open("avr-libc/include/avr/Makefile.am.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:7] == "    iox":
      for parts in xmegas[1:]:
        n.write("    iox%s.h \\\n" % (parts[0]))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[:7] != "    iox":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("avr-libc/include/avr/Makefile.am.new","avr-libc/include/avr/Makefile.am")




o = open("binutils/gas/config/tc-avr.c","r")
n = open("binutils/gas/config/tc-avr.c.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:11] == "  {\"atxmega":
      for parts in xmegas[1:]:
        n.write("  {\"atxmega%s\", AVR_ISA_XMEGA, bfd_mach_avrxmega%d},\n" % (parts[0],parts[1]	))
      state = 1
    else:
      n.write(line)
  elif state == 1:
    if line[:11] != "  {\"atxmega":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("binutils/gas/config/tc-avr.c.new","binutils/gas/config/tc-avr.c")



o = open("binutils/gas/doc/c-avr.texi","r")
n = open("binutils/gas/doc/c-avr.texi.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:24] == "Instruction set avrxmega":
      state = 1
      avrclass = int(line[24])
    n.write(line)
  elif state == 1:
    if line.find("MCU types:") != -1:
      line = line.split(":")[0]
      line += ": "
      if byclass.has_key(avrclass):
        for parts in byclass[avrclass]:
          type = "atxmega"+parts[0]
          line += type + ", "
        line = line[:-2] + ")."
        for subline in textwrap.wrap(line,80):
          n.write(subline+"\n")
      else:
        line += "none).\n"
        n.write(line)
      state = 2
  elif state == 2:
    if line[0] == "\n":
      n.write(line)
      state = 0
o.close()
n.flush()
n.close()
if rename: os.rename("binutils/gas/doc/c-avr.texi.new","binutils/gas/doc/c-avr.texi")



o = open("gcc/gcc/config/avr/avr-mcus.def","r")
n = open("gcc/gcc/config/avr/avr-mcus.def.new","w")
state = 0
for line in o:
  if state == 0:
    if line[:8] == "/* Xmega":
      state = 1
    n.write(line)
  elif state == 1:
    avrclass = int(line[18])
    if avrclass == 6: line = line[:87] + '7' + line[88:]
    n.write(line)
    for parts in byclass[avrclass]:
      if parts[0][2] in "abcd": ram = int(parts[0][:2])
      else: ram = int(parts[0][:3])
      blocks = int(math.ceil(float(ram+2)/64.0))
      n.write("AVR_MCU (\"atxmega%s\", \tARCH_AVRXMEGA%d,\"__AVR_ATxmega%s__\",\t0, 0, 0x2000, %d, \"x%s\")\n" % (parts[0],avrclass,parts[0].upper(),blocks,parts[0]))
    state = 2
  elif state == 2:
    if line[:8] == "/* Xmega":
      state = 1
    elif line[:7] == "AVR_MCU":
      continue
    else:
      state = 0
    n.write(line)

o.close()
n.flush()
n.close()
if rename: os.rename("gcc/gcc/config/avr/avr-mcus.def.new","gcc/gcc/config/avr/avr-mcus.def")
