supermario/bin/splice.py

94 lines
3.8 KiB
Python

import glob
import re
import os
from os import path
def splice(directory):
OVERDIR = 'AmphibianDNA'
try:
overs = [n for n in os.listdir(path.join(directory, OVERDIR)) if path.splitext(n)[1].lower() not in ('.idump', '.rdump')]
except FileNotFoundError:
overs = []
all_makefiles = list(glob.glob(path.join(glob.escape(directory), '**', '*.[Mm][Aa][Kk][Ee]'), recursive=True))
overs_re = '|'.join(re.escape(x) for x in overs)
overs_re = r'^[^#\s]*\b(Thing.lib)"?\s*ƒ\s*'.replace('Thing.lib', overs_re)
overs_re = re.compile(overs_re, re.IGNORECASE)
if overs:
remaining = list(overs)
# Method 1: replace an existing build rule
for f in all_makefiles:
mfile = open(f).read().split('\n')
havechanged = False
newmfile = []
idx = -1
while idx + 1 < len(mfile):
idx += 1
m = overs_re.match(mfile[idx])
if m:
thefile = m.group(1)
havechanged = True
newmfile.append('# Rule replaced at build time by ' + path.basename(__file__))
remaining = [x for x in remaining if x.upper() != thefile.upper()]
srcfile = '{Sources}%s:%s' % (OVERDIR, thefile)
newmfile.append(m.group(0) + srcfile)
newmfile.append('\tDuplicate -y {Deps} {Targ}')
lastidx = idx # how many "old" lines should be commented out?
if mfile[idx].endswith(''):
while lastidx + 1 < len(mfile) and mfile[lastidx + 1].endswith(''):
lastidx += 1 # capture continuations of first line
while lastidx + 1 < len(mfile) and mfile[lastidx + 1].startswith('\t'):
lastidx += 1 # capture build lines starting with tab
while idx <= lastidx:
newmfile.append('#\t' + mfile[idx])
idx += 1
else:
newmfile.append(mfile[idx])
if havechanged:
open(f, 'w').write('\n'.join(newmfile))
if remaining:
found_locations = {k: [] for k in remaining}
overs_re = '|'.join(re.escape(x) for x in remaining)
overs_re = r'^[^#]*(?:"|\s)({\w+}(?:\w+:)*)(Thing.lib)(?:"|\s)'.replace('Thing.lib', overs_re)
overs_re = re.compile(overs_re, re.IGNORECASE)
main_makefiles = []
for f in all_makefiles:
mfile = open(f).read().split('\n')
if any(l.startswith('BuildDir') for l in mfile):
main_makefiles.append(f)
for line in mfile:
m = overs_re.match(line)
if m:
orig_name = next(x for x in remaining if x.upper() == m.group(2).upper())
found_loc = m.group(1)+m.group(2)
if found_loc.upper() not in (x.upper() for x in found_locations[orig_name]):
found_locations[orig_name].append(found_loc)
for f in main_makefiles:
with open(f, 'a') as fd:
fd.write('\n# Rules created at build time by %s\n' % path.basename(__file__))
for orig_name, found_locs in found_locations.items():
if len(found_locs) == 1:
remaining = [x for x in remaining if x != orig_name]
fd.write(found_locs[0])
fd.write(' ƒ {Sources}%s:%s\n' % (OVERDIR, orig_name))
fd.write('\tDuplicate -y {Deps} {Targ}\n')
if remaining:
print('Failed to splice:', *remaining)