#
# quick and dirty script to fix eeschema -> pcbnew (forward) annotation
#
import os
import re
PROJ_DIR = "./KiCAD"
SCH_IN = "Cryptech Alpha.sch"
PCB_IN = "Cryptech Alpha BACKUP.kicad_pcb"
PCB_OUT = "Cryptech Alpha.kicad_pcb"
def parse_toc():
print("Parsing toc...")
toc = {}
re_u = re.compile("^U ([0-9A-F]{8})$")
re_p = re.compile('^F1 \"(rev02_\d+\.sch)\" \d+$')
with open("%s/%s" % (PROJ_DIR, SCH_IN), 'r') as f:
i, fls = 0, f.readlines()
while i < len(fls):
i, fl = i+1, fls[i].strip()
if fl.startswith('$Sheet'):
#
# $Sheet
# S 8700 3800 750 400
# U 57D84C55
# F0 "Real Time Clock" 60
# F1 "rev02_08.sch" 60
#
fl_s = fls[i+0].strip()
fl_u = fls[i+1].rstrip()
fl_f0 = fls[i+2].rstrip()
fl_f1 = fls[i+3].rstrip()
m_u = re.match(re_u, fl_u)
m_p = re.match(re_p, fl_f1)
if m_u is None:
raise RuntimeError(fl_u)
if m_p is None:
raise RuntimeError(fl_f1)
u = m_u.group(1)
p = m_p.group(1)
print(" page '%s' => '%s'" % (p, u))
toc[p] = u
i += 4
continue
return toc
def find_pages():
print("Finding pages...")
pgs = []
fs = os.listdir(PROJ_DIR)
re_sch = re.compile("^rev02_\d+.sch$")
for f in fs:
f_is_sch = re.match(re_sch, f)
if f_is_sch is None: continue
print(" page '%s'" % f)
pgs.append(f)
return pgs
def parse_syms(pgs):
#
# $Comp
# L <footprint> RefDes
# U <num> <num> ID
#
syms = {}
re_refdes = re.compile("^L \S+ ([#A-Z_\d]+)$")
re_id = re.compile("^U \d 1 ([0-9A-F]{8})$")
for pg in pgs:
with open("%s/%s" % (PROJ_DIR, pg), 'r') as f:
fls = f.readlines()
for i in range(len(fls)):
fl = fls[i].strip()
if fl == '$Comp':
fl_refdes = fls[i+1].strip()
fl_id = fls[i+2].strip()
m_refdes = re.match(re_refdes, fl_refdes)
m_id = re.match(re_id, fl_id)
if m_refdes is None:
raise RuntimeError(fl_refdes)
if m_id is None:
raise RuntimeError(fl_id)
refdes = m_refdes.group(1)
id = m_id.group(1)
if refdes.startswith('#'): continue
syms[refdes] = (pg, id)
print(" comp '%s' @ page '%s' => %s" % (refdes, pg, id))
return syms
def fix_pcb(syms, pids):
print("Fixing pcb...")
new_syms = syms.copy()
re_refdes = re.compile("^ \(fp_text reference (\S+)\s")
with open("%s/%s" % (PROJ_DIR, PCB_OUT), 'w') as fw:
with open("%s/%s" % (PROJ_DIR, PCB_IN), 'r') as fr:
fls = fr.readlines()
i = 0
while i < len(fls):
fl = fls[i].rstrip()
fw.write("%s\n" % fl)
i += 1
if fl.startswith(' (module'):
fl_at = fls[i+0].rstrip()
fl_path = fls[i+1].rstrip()
fl_attr = fls[i+2].rstrip()
fl_refdes = fls[i+3].rstrip()
#
if fl_refdes.startswith(' (fp_text reference ""'): continue
#
m_refdes = re.match(re_refdes, fl_refdes)
if m_refdes is None:
raise RuntimeError(fl_refdes)
refdes = m_refdes.group(1)
#
pg, id = new_syms[refdes]
pid = pids[pg]
del new_syms[refdes]
#
fw.write("%s\n" % fl_at)
#fw.write("%s\n" % (fl_path[:-1], '/'+id, fl_path[-1]))
fw.write(" (path /%s/%s)\n" % (pid, id))
i += 2
continue
return new_syms
if __name__ == "__main__":
pids = parse_toc()
pgs = find_pages()
syms = parse_syms(pgs)
new_syms = fix_pcb(syms, pids)
print("Leftover components:")
print(new_syms)