Commit ce1e0896 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

library merging tool

parent 1ded260d
#!/usr/bin/python3
import sys
import re
import os
def assert_equal(a, b, message, path=None):
if a != b:
raise Exception("%s '%s' != '%s'%s" %
(message, a, b, path and " in '%s'" % path or ''))
raise Exception()
class Lib:
def __init__(self, path):
assert not os.path.exists(path), "'%s' already exists" % path
self.path = path
self.parsed = set()
self.defined = {}
self.component = {}
self.alias = {}
self.footprint = {}
pass
def add(self, path, name, component, alias, footprint):
if name in self.defined:
if (component == self.component[name] and
alias == self.alias[name] and
footprint == self.footprint[name]):
print("'%s' in '%s' is duplicate of '%s'" %
(name, path, sorted(self.defined[name])),
file=sys.stderr)
pass
else:
raise Exception("'%s' in '%s' already defined in '%s'" %
(name, path, self.defined[name]))
pass
if not name in self.defined:
self.defined[name] = set()
self.component[name] = component
self.alias[name] = alias
self.footprint[name] = footprint
pass
self.defined[name].add(path)
def merge(self, path):
if path in self.parsed:
print('Already parsed %s' % path, file=sys.stderr)
return
self.parsed.add(path)
component = []
fplist = None
footprint = set()
for l in open(path):
m = re.match('^EESchema-(\S+)\s+Version\s+([0-9.]+)\s*$', l)
if m:
assert_equal(m.group(1), 'LIBRARY', 'Unexpected kind', path)
assert_equal(m.group(2), '2.3', "Unexpected version", path)
continue
m = re.match('^#encoding utf-8', l)
if m:
continue
component.append(l)
m = re.match('^DEF\s+(\S+)', l)
if m:
name = m.group(1)
alias = set([name])
pass
m = re.match('^ALIAS\s+(.*)\s*$', l)
if m:
alias.update(m.group(1).split())
pass
m = re.match('^\$ENDFPLIST', l)
if m:
footprint = fplist
fplist = None
pass
if fplist != None:
fplist.add(l.strip())
pass
m = re.match('^\$FPLIST', l)
if m:
fplist = set()
pass
m = re.match('^ENDDEF', l)
if m:
self.add(path, name, component, alias, footprint)
component = []
fplist = None
footprint = set()
pass
pass
pass
def commit(self):
with open(self.path, 'w') as f:
f.write('EESchema-LIBRARY Version 2.3\n')
f.write('#encoding utf-8\n')
for c in sorted(self.component):
f.write(''.join(self.component[c]))
pass
pass
f.write('#\n')
f.write('#End Library\n')
pass
class DocLib:
def __init__(self, path):
assert not os.path.exists(path), "'%s' already exists" % path
self.path = path
self.parsed = set()
self.defined = {}
self.component = {}
pass
def add (self, path, name, component):
if name in self.defined:
if component == self.component[name]:
print("'%s' in '%s' is duplicate of '%s'" %
(name, path, sorted(self.defined[name])),
file=sys.stderr)
pass
else:
raise Exception("'%s' in '%s' already defined in '%s'" %
(name, path, self.defined[name]))
pass
if not name in self.defined:
self.defined[name] = set()
self.component[name] = component
pass
self.defined[name].add(path)
def merge(self, path):
if path in self.parsed:
print('Already parsed %s' % path, file=sys.stderr)
return
self.parsed.add(path)
component = None
for l in open(path):
m = re.match('^EESchema-(\S+)\s+Version\s+([0-9.]+)\s*$', l)
if m:
assert_equal(m.group(1), 'DOCLIB', 'Unexpected kind', path)
assert_equal(m.group(2), '2.0', "Unexpected version", path)
continue
m = re.match('^#encoding utf-8', l)
if m:
continue
m = re.match('^\$CMP\s+(\S+)', l)
if m:
name = m.group(1)
component = [ ]
pass
if component != None:
component.append(l)
m = re.match('^\$ENDCMP', l)
if m:
self.add(path, name, component)
component = None
pass
pass
pass
def commit(self):
with open(self.path, 'w') as f:
f.write('EESchema-DOCLIB Version 2.0\n')
f.write('#encoding utf-8\n')
for c in sorted(self.component):
f.write(''.join(self.component[c]))
f.write('#\n')
pass
pass
f.write('#End Doc Library\n')
pass
class FootPrint:
def __init__(self, path):
assert not os.path.exists(path), "'%s' already exists" % path
self.path = path
self.entries = {}
def merge(self, path):
for p in os.listdir(path):
m = re.match('^(.*).kicad_mod', p)
if not m:
continue
name = m.group(1)
pp = os.path.join(path, p)
for l in open(pp):
m = re.match('.*\(\s*module\s+(\S+)', l)
if m:
assert_equal(name, m.group(1), 'Wrong module name', pp)
pass
pass
self.entries[name] = pp
pass
def commit(self):
os.mkdir(self.path)
for k,v in self.entries.items():
with open(os.path.join(self.path, '%s.kicad_mod' % k), 'w') as f1:
with open(v) as f2:
f1.write(f2.read())
pass
pass
pass
pass
if __name__ == '__main__':
dest = sys.argv[1]
destdir = os.path.dirname(dest)
source = sys.argv[2:]
assert os.path.isdir(destdir), "Destination '%s' does not exist" % destdir
lib = Lib('%s.lib' % (dest))
dcm = DocLib('%s.dcm' % (dest))
fp = FootPrint('%s.pretty' % (dest))
for s in source:
for p in os.listdir(s):
if p.endswith('.lib'):
lib.merge(os.path.join(s, p))
pass
elif p.endswith('.dcm'):
dcm.merge(os.path.join(s, p))
pass
elif p.endswith('.pretty'):
fp.merge(os.path.join(s, p))
pass
pass
pass
# Sanity checks
alias = set()
for k in lib.alias:
for a in lib.alias[k]:
alias.add(a)
if not a in dcm.component:
print("'%s' doesn't have a description" % a, file=sys.stderr)
pass
pass
pass
for k in dcm.component:
if not k in alias:
print("description '%s' isn't used" % k, file=sys.stderr)
pass
pass
import fnmatch
used = set()
for k in lib.footprint:
for p in lib.footprint[k]:
ok = False
for f in fp.entries:
if fnmatch.fnmatch(f, p):
ok = True
used.add(f)
pass
pass
if not ok:
print("No match for '%s(%s)' in '%s'" %
(k, p, lib.defined[k]), file=sys.stderr)
pass
pass
pass
for u in set(fp.entries.keys()) - used:
print("Unmatched footprint '%s' in '%s'" %
(u, fp.entries[u]), file=sys.stderr)
pass
# Generate library
lib.commit()
dcm.commit()
fp.commit()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment