summaryrefslogtreecommitdiff
path: root/helper/repair_annotation.py
blob: 822880ef50b9abd5829c097396927089bc1987b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#
# 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)