451 lines
15 KiB
Python
451 lines
15 KiB
Python
|
#
|
||
|
# KiCad python module for interpreting generic netlists which can be used
|
||
|
# to generate Bills of materials, etc.
|
||
|
#
|
||
|
# No string formatting is used on purpose as the only string formatting that
|
||
|
# is current compatible with python 2.4+ to 3.0+ is the '%' method, and that
|
||
|
# is due to be deprecated in 3.0+ soon
|
||
|
#
|
||
|
|
||
|
import sys
|
||
|
import xml.sax as sax
|
||
|
|
||
|
|
||
|
class component():
|
||
|
"""Class for a set of component information"""
|
||
|
def __init__(self, element):
|
||
|
self.element = element
|
||
|
self.libpart = None
|
||
|
|
||
|
# Set to true when this component is included in a component group
|
||
|
self.grouped = False
|
||
|
|
||
|
def __eq__(self, other):
|
||
|
"""Equlivalency operator, remember this can be easily overloaded"""
|
||
|
result = False
|
||
|
if self.getValue() == other.getValue():
|
||
|
if self.getLib() == other.getLib():
|
||
|
if self.getPart() == other.getPart():
|
||
|
result = True
|
||
|
return result
|
||
|
|
||
|
def setPart(self, part):
|
||
|
self.libpart = part
|
||
|
|
||
|
def setValue(self, value):
|
||
|
"""Set the value of this component"""
|
||
|
v = self.element.getChild("value")
|
||
|
if v:
|
||
|
v.setChars(value)
|
||
|
|
||
|
def getValue(self):
|
||
|
return self.element.get("value")
|
||
|
|
||
|
def getRef(self):
|
||
|
return self.element.get("comp", "ref")
|
||
|
|
||
|
def getFootprint(self):
|
||
|
return self.element.get("footprint")
|
||
|
|
||
|
def getDatasheet(self):
|
||
|
return self.element.get("datasheet")
|
||
|
|
||
|
def getLib(self):
|
||
|
return self.element.get("libsource", "lib")
|
||
|
|
||
|
def getPart(self):
|
||
|
return self.element.get("libsource", "part")
|
||
|
|
||
|
def getTimestamp(self):
|
||
|
return self.element.get("tstamp")
|
||
|
|
||
|
def getDescription(self):
|
||
|
# When attempting to access the part, we must take care in case the part
|
||
|
# cannot be found in the netlist
|
||
|
try:
|
||
|
d = self.libpart.getDescription()
|
||
|
except AttributeError:
|
||
|
d = ""
|
||
|
return d
|
||
|
|
||
|
def getDatasheet(self):
|
||
|
# When attempting to access the part, we must take care in case the part
|
||
|
# cannot be found in the netlist
|
||
|
try:
|
||
|
d = self.libpart.getDatasheet()
|
||
|
except AttributeError:
|
||
|
d = ""
|
||
|
return d
|
||
|
|
||
|
def getField(self, name):
|
||
|
"""Return the value of a field named name. The component is first
|
||
|
checked for the field, and then the components library part is checked
|
||
|
for the field. If the field doesn't exist in either, an empty string is
|
||
|
returned
|
||
|
|
||
|
Keywords:
|
||
|
name -- The name of the field to return the value for
|
||
|
|
||
|
"""
|
||
|
field = self.element.get("field", "name", name)
|
||
|
if field == "":
|
||
|
try:
|
||
|
field = self.libpart.getField(name)
|
||
|
except AttributeError:
|
||
|
field = ""
|
||
|
return field
|
||
|
|
||
|
|
||
|
class netlistElement():
|
||
|
"""Generic netlist element. All elements for a netlist tree which can be
|
||
|
used to easily generate various output formats by propogating format
|
||
|
requests to all children
|
||
|
"""
|
||
|
def __init__(self, name, parent=None):
|
||
|
self.name = name
|
||
|
self.attributes = {}
|
||
|
self.parent = parent
|
||
|
self.chars = ""
|
||
|
self.children = []
|
||
|
self.indent = ""
|
||
|
|
||
|
def __str__(self):
|
||
|
"""String representation of this netlist element
|
||
|
|
||
|
"""
|
||
|
return (self.name + "[" + self.chars + "]" + " attr:" +
|
||
|
str(len(self.attributes[a])))
|
||
|
|
||
|
def formatXML(self, amChild=False):
|
||
|
"""Return this element formatted as XML
|
||
|
|
||
|
Keywords:
|
||
|
amChild -- If set to True, the start of document is not returned
|
||
|
|
||
|
"""
|
||
|
s = ""
|
||
|
|
||
|
if not amChild:
|
||
|
s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||
|
|
||
|
s += self.indent + "<" + self.name
|
||
|
for a in self.attributes:
|
||
|
s += " " + a + "=\"" + self.attributes[a] + "\""
|
||
|
|
||
|
if (len(self.chars) == 0) and (len(self.children) == 0):
|
||
|
s += "/>"
|
||
|
else:
|
||
|
s += ">" + self.chars
|
||
|
|
||
|
for c in self.children:
|
||
|
c.indent += self.indent + " "
|
||
|
s += "\n"
|
||
|
s += c.formatXML(True)
|
||
|
|
||
|
if (len(self.children) > 0):
|
||
|
s += "\n" + self.indent
|
||
|
|
||
|
if (len(self.children) > 0) or (len(self.chars) > 0):
|
||
|
s += "</" + self.name + ">"
|
||
|