summaryrefslogblamecommitdiff
path: root/helper/repair_annotation.py
blob: 822880ef50b9abd5829c097396927089bc1987b5 (plain) (tree)






































































































































                                                                                  
#
# 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)