Commit c66f287
Changed files (5)
internal/component.go
@@ -11,6 +11,7 @@ type Circuit struct {
Version string `yaml:"cddx2yamlVersion"`
CircuitDiagramVersion string `yaml:"circuitDiagramVersion"`
Components []Component `yaml:"components"`
+ Connections [][]string `yaml:"connections"`
}
type Component struct {
@@ -34,12 +35,18 @@ func documentFromXML(c *xmlCircuit) *Circuit {
counters := make(idCounters)
components := make([]Component, 0, len(c.Components))
for _, xc := range c.Components {
- components = append(components, xc.toComponent(types, counters))
+ comp := xc.toComponent(types, counters)
+ for _, cn := range xc.Conns {
+ comp.addPin(xc.resolvePin(cn.Pin))
+ }
+ components = append(components, comp)
}
+
return &Circuit{
Version: "0.1",
CircuitDiagramVersion: c.Version,
Components: components,
+ Connections: collectConnections(c.Components, components),
}
}
@@ -74,7 +81,7 @@ func (c xmlComponent) toComponent(types typeCatalog, counters idCounters) Compon
return Component{
ID: counters.next(idPrefix(typeName)),
Type: typeName,
- Label: label,
+ Label: label,
Value: c.electricalValue(),
Pins: c.pins(),
}
@@ -100,7 +107,7 @@ func (c xmlComponent) electricalValue() string {
func (c xmlComponent) pins() []string {
pinByIndex := make(map[int]string)
for _, p := range c.Props {
- idx, ok := pinIndexFromPropKey(p.Key)
+ idx, ok := pinIndex(p.Key)
if !ok {
continue
}
@@ -118,6 +125,7 @@ func (c xmlComponent) pins() []string {
for _, idx := range indices {
name := pinByIndex[idx]
if seen[name] {
+ fmt.Printf("Warning: duplicate pin name %q for component %q\n", name, c.DefinitionID)
continue
}
seen[name] = true
@@ -126,8 +134,8 @@ func (c xmlComponent) pins() []string {
return pins
}
-func pinIndexFromPropKey(key string) (int, bool) {
- for _, prefix := range []string{"p", "#"} {
+func pinIndex(key string) (int, bool) {
+ for _, prefix := range []string{"pin", "p", "#"} {
rest, ok := strings.CutPrefix(key, prefix)
if !ok {
continue
internal/connections.go
@@ -0,0 +1,71 @@
+package internal
+
+import (
+ "fmt"
+ "slices"
+ "strconv"
+)
+
+type netRef struct {
+ componentID string
+ pin string
+}
+
+func (r netRef) String() string {
+ return r.componentID + "." + r.pin
+}
+
+func (c xmlComponent) resolvePin(pt string) string {
+ idx, ok := pinIndex(pt)
+ if !ok {
+ return pt
+ }
+ if v, ok := c.prop("p" + strconv.Itoa(idx)); ok && v != "" {
+ return v
+ }
+ if v, ok := c.prop("#" + strconv.Itoa(idx)); ok && v != "" {
+ return v
+ }
+ return pt
+}
+
+func (c *Component) addPin(name string) {
+ if name == "" {
+ return
+ }
+ if slices.Contains(c.Pins, name) {
+ return
+ }
+ c.Pins = append(c.Pins, name)
+}
+
+func collectConnections(xmlComps []xmlComponent, components []Component) [][]string {
+ nets := make(map[string][]netRef)
+ var order []string
+
+ for i, xc := range xmlComps {
+ id := components[i].ID
+ for _, cn := range xc.Conns {
+ pin := xc.resolvePin(cn.Pin)
+ if _, seen := nets[cn.ID]; !seen {
+ order = append(order, cn.ID)
+ }
+ nets[cn.ID] = append(nets[cn.ID], netRef{componentID: id, pin: pin})
+ }
+ }
+
+ connections := make([][]string, 0, len(order))
+ for _, netID := range order {
+ refs := nets[netID]
+ if len(refs) < 2 {
+ fmt.Printf("Warning: Circuit has a dangling connection %v\n", refs)
+ continue
+ }
+ row := make([]string, len(refs))
+ for i, ref := range refs {
+ row[i] = ref.String()
+ }
+ connections = append(connections, row)
+ }
+ return connections
+}
internal/utils.go
@@ -1,9 +0,0 @@
-package internal
-
-func Set(items ...string) map[string]bool {
- m := make(map[string]bool, len(items))
- for _, it := range items {
- m[it] = true
- }
- return m
-}
go.mod
@@ -1,3 +1,5 @@
module cddx2yaml
go 1.26.5
+
+require gopkg.in/yaml.v3 v3.0.1
go.sum
@@ -0,0 +1,4 @@
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=