aboutsummaryrefslogtreecommitdiff
path: root/sort-library.py
blob: aa6af3b9b7b5649d635e8a7d025fb237053b12ce (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
#!/usr/bin/env python

"""
Sort the library file like KiCad does, to minimize diffs
"""

import os
import re
import sys
import pprint


def get_groups_in_order(lines):
    order = ['#', 'DEF', 'F0' , 'F1', 'F2', 'F3', 'DRAW',
             'A', 'S', 'T', 'P', 'X',
             'ENDDRAW', 'ENDDEF',
    ]
    for this in order:
        yield([x for x in lines if x.startswith(this)])

def sort_chunk(lines):
    res = []
    for this in get_groups_in_order(lines):
        if not this:
            continue
        if this[0].startswith('#'):
            res += this
        else:
            # secondary sort of elements in a group
            sortfun = None
            if this[0].startswith('T'):
                sortfun = lambda x: (x.split(' ')[8])  # text
            if this[0].startswith('X'):
                sortfun = lambda x: (x.split(' ')[2])  # pin
            if this[0].startswith('S'):
                sortfun = lambda x: (int(x.split(' ')[1]),
                                     int(x.split(' ')[2]),
                                     int(x.split(' ')[3]),
                                     int(x.split(' ')[4]),
                )
            if this[0].startswith('P'):
                sortfun = lambda x: (int(x.split(' ')[1]),
                                     int(x.split(' ')[5]),
                                     int(x.split(' ')[6]),
                                     int(x.split(' ')[7]),
                                     int(x.split(' ')[8]),
                )
            if this[0].startswith('A'):
                sortfun = lambda x: (int(x.split(' ')[1]),
                                     int(x.split(' ')[2]),
                                     )
            if sortfun:
                try:
                    this = sorted(this, key=sortfun)
                except ValueError:
                    pass
            #if this[0].startswith('P'):
            #    # XXX HACK WHILE DEVELOPING TO MINIMIZE DIFF
            #    for t in range(len(this)):
            #        if not this[t][-3:] in [' N\n', ' f\n', ' F\n'):
            #            this[t] = this[t][:-1] + ' N\n'
            res += this
    return res

def chunk_file(fd):
    res = []
    for this in fd.readlines():
        res += [this]
        if this.startswith('ENDDEF'):
            if res[0] != '#\n':
                res = ['#\n'] + res
            name = res[1].split(' ')[1][:-1]
            sorted_lines = sort_chunk(res)
            yield(name, ''.join(sorted_lines))
            res = []


def sort_symbols(fn_in, fn_out, refdes):
    in_ = open(fn_in)
    out = open(fn_out, 'w')
    fn = os.path.basename(fn_in)
    print('Remapping symbols in in {}'.format(fn))
    header = in_.readline() + in_.readline()
    symbols = {}
    for k, v in sorted(chunk_file(in_)):
        symbols[k] = v

    out.write(header)
    for k in sorted(symbols.keys()):
        out.write(symbols[k])
    out.write('#\n#End Library\n')
    return True


def main(libs):
    refdes = {}
    for this in sorted(libs):
        if sort_symbols(this, this + '.tmp', refdes):
            os.rename(this + '.tmp', this)

    return True


if __name__ == '__main__':
    try:
        if len(sys.argv) == 0:
            sys.stderr.write('Syntax: sort-symbols.py *.lib\n')
            sys.exit(1)
        libs = [x for x in sys.argv if x.endswith('.lib')]
        res = main(libs)
        if res:
            sys.exit(0)
        sys.exit(1)
    except KeyboardInterrupt:
        pass