aboutsummaryrefslogtreecommitdiffstats
path: root/sw/cal/dbc.go
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2025-11-07 17:09:38 -0500
committerSam Anthony <sam@samanthony.xyz>2025-11-07 17:09:38 -0500
commit29da72a76d5e043a181f66e8758c4d511c3ef814 (patch)
tree1ee81d5d3f570fa7b4867fcd1fa77efd241f166a /sw/cal/dbc.go
parent4ef93d935d1b6ed707bd385b72c636d2795de680 (diff)
downloadcan-gauge-interface-29da72a76d5e043a181f66e8758c4d511c3ef814.zip
cal: refactor
Diffstat (limited to 'sw/cal/dbc.go')
-rw-r--r--sw/cal/dbc.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/sw/cal/dbc.go b/sw/cal/dbc.go
new file mode 100644
index 0000000..53ca852
--- /dev/null
+++ b/sw/cal/dbc.go
@@ -0,0 +1,81 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "slices"
+
+ "go.einride.tech/can/pkg/dbc"
+)
+
+// Extract signals from the DBC file.
+func parseSignals(filename string, names []string) ([]dbc.SignalDef, error) {
+ // Parse DBC file
+ msgDefs, err := parseDbcFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ // Search for signals
+ sigPtrs := make([]*dbc.SignalDef, len(names))
+ for _, msg := range msgDefs {
+ for i := range names {
+ j := slices.IndexFunc(msg.Signals, func(sig dbc.SignalDef) bool { return sig.Name == dbc.Identifier(names[i]) })
+ if j < 0 {
+ continue
+ }
+ if sigPtrs[i] != nil {
+ return nil, ErrDupSig{msg.Signals[j]}
+ }
+ sigPtrs[i] = &msg.Signals[j]
+ }
+ }
+
+ // Check all signals are present
+ if i := slices.IndexFunc(sigPtrs, func(sp *dbc.SignalDef) bool { return sp == nil }); i >= 0 {
+ return nil, ErrNoSig{filename, names[i]}
+ }
+
+ // Dereference
+ signals := make([]dbc.SignalDef, len(sigPtrs))
+ for i := range sigPtrs {
+ signals[i] = *sigPtrs[i]
+ }
+
+ return signals, nil
+}
+
+func parseDbcFile(filename string) ([]*dbc.MessageDef, error) {
+ // Read file
+ buf, err := os.ReadFile(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ // Parse file
+ parser := dbc.NewParser(filename, buf)
+ if err := parser.Parse(); err != nil {
+ return nil, err
+ }
+
+ // Filter message definitions
+ defs := parser.Defs()
+ msgDefs := make([]*dbc.MessageDef, 0, len(defs))
+ for _, def := range defs {
+ if msg, ok := def.(*dbc.MessageDef); ok {
+ msgDefs = append(msgDefs, msg)
+ }
+ }
+ return msgDefs, nil
+}
+
+func tryAssignSignal(dst **dbc.SignalDef, sig dbc.SignalDef, targetName string) error {
+ if targetName != "" && string(sig.Name) == targetName {
+ if *dst != nil {
+ return fmt.Errorf("%v: duplicate signal '%s'", sig.Pos, sig.Name)
+ }
+ *dst = &sig
+ }
+ return nil
+
+}