aboutsummaryrefslogtreecommitdiff
path: root/src/ee/kicad/pcb/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ee/kicad/pcb/__init__.py')
-rw-r--r--src/ee/kicad/pcb/__init__.py128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py
new file mode 100644
index 0000000..bfd352f
--- /dev/null
+++ b/src/ee/kicad/pcb/__init__.py
@@ -0,0 +1,128 @@
+from .. import sexpr
+
+def auto_str(cls):
+ def __str__(self):
+ return str({k: [str(x) for x in v] if isinstance(v, list) else str(v) for k, v in vars(self).items()})
+
+ cls.__str__ = __str__
+ return cls
+
+@auto_str
+class KicadPcb(object):
+ def __init__(self, **kwargs):
+ for k, v in kwargs.items():
+ setattr(self, k, v)
+
+@auto_str
+class General(object):
+ def __init__(self, **kwargs):
+ for k, v in kwargs.items():
+ setattr(self, k, v)
+
+@auto_str
+class Module(object):
+ def __init__(self, **kwargs):
+ for k, v in kwargs.items():
+ setattr(self, k, v)
+
+def parse(path):
+ count = 0
+ p = sexpr.parse(path)
+ p = sexpr.logging_parser(p)
+ (event, token) = next(p)
+ assert event == sexpr.EVENT_LPAREN
+
+ (event, token) = next(p)
+ assert event == sexpr.EVENT_TEXT and token == "kicad_pcb"
+
+ idx = 0
+ def _consume():
+ nonlocal idx
+ idx = idx + 1
+# print("consume: idx={}".format(idx))
+ (event, token) = next(p)
+# print("consume: event={}".format(event))
+ while event != sexpr.EVENT_RPAREN:
+ if event == sexpr.EVENT_LPAREN:
+ _consume()
+ elif event == sexpr.EVENT_TEXT:
+ pass
+ (event, token) = next(p)
+# print("consume: event={}".format(event))
+# print("consume: done".format())
+ idx = idx - 1
+
+ def _parse_kicad_pcb():
+ modules = []
+ args = {"modules": modules}
+
+ (event, token) = next(p)
+ while event == sexpr.EVENT_LPAREN:
+ (event, token) = next(p)
+ if token == "version":
+ args[token] = _parse_text(rparen = True)
+ elif token == "general":
+ args[token] = _parse_general()
+ elif token == "module":
+ modules.append(_parse_module())
+ else:
+ _consume()
+ (event, token) = next(p)
+
+ return KicadPcb(**args)
+
+ def _parse_text(optional = False, rparen = False):
+ (event, token) = next(p)
+ if not optional:
+ assert event == sexpr.EVENT_TEXT
+ else:
+ assert event == sexpr.EVENT_TEXT or event == sexpr.EVENT_RPAREN
+ if event == sexpr.EVENT_RPAREN:
+ return None
+ text = token
+ if rparen:
+ (event, token) = next(p)
+ assert event == sexpr.EVENT_RPAREN
+ return text
+
+ def _parse_general():
+ args = {}
+
+ (event, token) = next(p)
+ while event == sexpr.EVENT_LPAREN:
+ (event, token) = next(p)
+ if token == "no_connects":
+ args[token] =_parse_text(rparen = True)
+ elif token == "area":
+ args[token] = (_parse_text(), _parse_text(), _parse_text(), _parse_text(rparen = True))
+ elif token == "thickness":
+ args[token] = _parse_text(rparen = True)
+ else:
+ _consume()
+ (event, token) = next(p)
+ return General(**args)
+
+ def _parse_module():
+ args = {}
+
+ args["footprint"] = _parse_text()
+
+ (event, token) = next(p)
+ while event == sexpr.EVENT_LPAREN:
+ (event, token) = next(p)
+ if token == "layer":
+ args[token] = _parse_text(rparen = True)
+ elif token == "at":
+ x = _parse_text()
+ y = _parse_text()
+ rot = _parse_text(optional = True, rparen = True)
+ args[token] = (x, y, rot or 0)
+ else:
+ _consume()
+ (event, token) = next(p)
+ return Module(**args)
+
+ kicad_pcb = _parse_kicad_pcb()
+# (event, token) = next(p)
+# assert event == sexpr.EVENT_END
+ return kicad_pcb