Skip to content
Snippets Groups Projects
Commit ce1e0896 authored by Anders Blomdell's avatar Anders Blomdell
Browse files

library merging tool

parent 1ded260d
Branches
No related tags found
No related merge requests found
#!/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()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment