From 102614dc8fe2f5aefd0fd92c1b6e48107a9629b0 Mon Sep 17 00:00:00 2001
From: Trygve Laugstøl <trygvis@inamo.no>
Date: Tue, 12 Dec 2017 12:02:29 +0100
Subject: o Adding a kicad-make-pos tool.

---
 src/ee/kicad/__init__.py     | 18 +++++++++++-------
 src/ee/kicad/pcb/__init__.py | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 49 insertions(+), 10 deletions(-)

(limited to 'src/ee/kicad')

diff --git a/src/ee/kicad/__init__.py b/src/ee/kicad/__init__.py
index 8d5acd1..1492fc4 100644
--- a/src/ee/kicad/__init__.py
+++ b/src/ee/kicad/__init__.py
@@ -3,6 +3,7 @@ from typing import Any
 from ee import EeException
 from ee.kicad.read_schematic import read_schematic, read_schematics
 from ee.kicad.to_bom import to_bom, to_bom_xml
+from .._utils import run_filters
 from .model import *
 
 __all__ = [
@@ -17,17 +18,20 @@ __all__ = [
     "to_pandas",
 ]
 
+def parse_ref(ref):
+    m = parse_ref.r.match(ref)
+    if not m:
+        return
+    g = m.groups()
+#    print("groups={}".format(g))
+    return (g[0], None if g[1] == "?" else int(g[1]))
+
+parse_ref.r = re.compile("([^0-9]+)([0-9]+|\?)$")
 
 def to_pandas(obj: Any, **kwarg):
     import pandas
     import numpy as np
 
-    def run_filter(filters, obj):
-        for f in filters:
-            if not f(obj):
-                return False
-        return True
-
     def to_pandas_schematics(ss: Schematics):
         dfs = [to_pandas_schematic(schematic) for schematic in ss.schematics]
 
@@ -65,7 +69,7 @@ def to_pandas(obj: Any, **kwarg):
         if not include_flg:
             filters.append(lambda c: c.ref_type != "#FLG")
 
-        data = [make_dict(c) for c in components if run_filter(filters, c)]
+        data = [make_dict(c) for c in components if run_filters(filters, c)]
         columns = set([key for row in data for key in list(row)]) - set(special_fields)
         columns = special_fields + list(columns)
 
diff --git a/src/ee/kicad/pcb/__init__.py b/src/ee/kicad/pcb/__init__.py
index 10350c3..679c5ea 100644
--- a/src/ee/kicad/pcb/__init__.py
+++ b/src/ee/kicad/pcb/__init__.py
@@ -1,4 +1,5 @@
 from .. import sexpr
+from ..._utils import run_filters
 
 def auto_str(cls):
     def __str__(self):
@@ -25,16 +26,32 @@ class Module(object):
         for k, v in kwargs.items():
             setattr(self, k, v)
 
+        self.fp_texts = self.fp_texts or []
+
+    def filter_fp_text(self, kind = None):
+        filters = []
+
+        if kind:
+            filters.append(lambda fp_text: fp_text.kind == kind)
+
+        return (fp_text for fp_text in self.fp_texts if run_filters(filters, fp_text))
+
 @auto_str
 class Pad(object):
     def __init__(self, **kwargs):
         for k, v in kwargs.items():
             setattr(self, k, v)
 
+@auto_str
+class FpText(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)
+    #p = sexpr.logging_parser(p)
     (event, token) = next(p)
     assert event == sexpr.EVENT_LPAREN
 
@@ -111,10 +128,12 @@ def parse(path):
 
     def _parse_module():
         pads = []
+        fp_texts = []
 
         args = {}
         args["footprint"] = _parse_text()
         args["pads"] = pads
+        args["fp_texts"] = fp_texts
 
         (event, token) = next(p)
         while event == sexpr.EVENT_TEXT:
@@ -128,6 +147,8 @@ def parse(path):
                 args[token] = _parse_at()
             elif token == "pad":
                 pads.append(_parse_pad())
+            elif token == "fp_text":
+                fp_texts.append(_parse_fp_text())
             else:
                 _consume()
             (event, token) = next(p)
@@ -155,6 +176,21 @@ def parse(path):
 
         return Pad(**args)
 
+    def _parse_fp_text():
+        args = {
+            "kind": _parse_text(),
+            "value": _parse_text(),
+        }
+        (event, token) = next(p)
+        while event == sexpr.EVENT_LPAREN:
+            (event, token) = next(p)
+            if token == "at":
+                args[token] = _parse_at()
+            if token == "layer":
+                args[token] = _parse_text()
+            else:
+                _consume()
+        return FpText(**args)
 
     def _parse_at():
         x = _parse_text(to=float)
@@ -163,6 +199,5 @@ def parse(path):
         return (x, y, rot or 0)
 
     kicad_pcb = _parse_kicad_pcb()
-#    (event, token) = next(p)
-#    assert event == sexpr.EVENT_END
+    assert next(p, None) == None
     return kicad_pcb
-- 
cgit v1.2.3