8000 dbc: add semantic DBC round-tripping and database edits by tomrford · Pull Request #111 · tomrford/gocan · GitHub
[go: up one dir, main page]

Skip to content

dbc: add semantic DBC round-tripping and database edits - #111

Merged
tomrford merged 4 commits into
mainfrom
claude/dbc-edit
Nov 6, 2026
Merged

tomrford merged 4 commits into
mainfrom
claude/dbc-edit

Conversation

@tomrford
@tomrford tomrford commented Nov 6, 2026
Copy link
Copy Markdown
Owner

Why

Device-specific DBCs need identifier and name edits without stale lookups, codecs or source attachments. Add generic DBC writing and validated database derivation so the resulting database can also be embedded in a trace.

What changed

  • Retain database, node, message and signal comments. Quoted strings unescape only backslash-quote; other backslashes stay literal.
  • Add deterministic UTF-8 DBC writing for the supported model, including attributes, value descriptions, signal groups and multiplexing.
  • Add Database.Edit to derive an independent, reparsed database. Reject out-of-range identifiers before serialization and preserve numeric enum -1 values, including defaults with an empty choice label.
Lines
Code +487 / -43
Tests +477 / -5
Docs and config +1 / -1

Scope

Round-trips preserve supported model semantics. Source formatting, original encoding and records already dropped by parsing are not preserved. Windows-1252 output uses the existing charmap encoder; no dependencies are added.

Decisions

Message.Format remains derived from DBC declarations, including VFrameFormat and ProtocolType. The API documentation explains editing those declarations, and the device lifecycle test verifies a CAN FD edit through encoding and generated-source reparsing.

Risks

String parsing changes for existing callers that relied on C-style escapes: backslash-n, backslash-r, backslash-t and doubled backslashes now remain literal.

Verification

  • go test -race ./... and go vet ./... passed; gofmt -l . and diff checks were clean.
  • Added enum and identifier regressions failed before the fixes and passed afterward.
  • Device lifecycle coverage derives one-device and expanded databases, checks encoding and lookups, and writes a Windows-1252 DBC that parses back successfully.

Comments were dropped in #9 for lack of a consumer. A DBC written back out
(for example, one embedded in an MF4 trace) now needs them, so Database,
Node, Message and Signal carry CM_ text again. Comments on unknown objects
and environment variables are reported as diagnostics; a repeated comment for
one object replaces the earlier one, as cantools and canmatrix do, with a
diagnostic.

Quoted strings now unescape only \". cantools and canmatrix keep every other
backslash literal, including \\, so "C:\temp" no longer becomes a tab.
Database.Write writes the resolved model as UTF-8 DBC text. Parsing the text
gives a database equal to the original apart from Diagnostics and Source,
including its derived lookups, frame formats and codecs; writing that again
gives the same bytes. Records Parse dropped are not written, and formatting,
number spelling and encoding are not kept.

Write reads only exported fields, so an edited copy can be written and parsed
into a new resolved database. Names that would not lex as one identifier,
non-finite numbers, invalid UTF-8 and strings ending in a backslash are
rejected before anything is written. Windows-1252 output is available by
wrapping the writer with golang.org/x/text's charmap encoder.

Choices made for interoperability:
- Enum BA_ values are written as indexes (cantools rejects labels there);
  enum defaults use the label unless a repeated label would resolve to
  another index.
- Numbers use the shortest exact form, with an exponent only where Python's
  repr uses one.
- Multiplexing stays in simple mN form when it means "one root, one value",
  and otherwise lists every condition in SG_MUL_VAL_.

Checked once by hand: cantools 45.1.2 and canmatrix load the written text of
every fixture and of the GIC3 interface DBCs (25 and 400 messages) to the same
messages, signals, choices, comments and attributes as the originals.
A parsed Database is read-only: its lookups and codecs are built by Parse,
so changing Message.ID or a name in place leaves them stale, and Source still
returns the original text. Edit hands a callback an independent copy, then
writes and parses the result. The returned database is validated like any
parsed one: colliding or out-of-range identifiers and unwritable names are
errors. Its lookups follow the edits, and Source is the DBC text that
describes it, ready to embed in a trace. The original is never touched.

This covers deriving a per-device database from a single-device interface
DBC (shifting identifier bits and renaming messages) and expanding one DBC to
every device, as the GIC3 release tooling does with cantools. The test drives
both through a synthetic device fixture, encodes frames on the derived IDs,
and writes a Windows-1252 file that ParseFile reads back.
Keep numeric enum -1 values distinct from empty labels, including defaults. Validate resolved CAN identifiers before adding the extended DBC marker, so invalid edits cannot change frame identity.

Document frame format as derived from DBC attributes and exercise a CAN FD attribute edit through encoding and generated-source reparsing.
@chatgpt-codex-connector
chatgpt-codex-connector Bot commented Nov 6, 2026 •
Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T13:03:47.392971Z 0118b2d PR opened
ℹ️ About Codex in GitHub
8000

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

tomrford commented Nov 6, 2026
Copy link
Copy Markdown
Owner Author

Pre-merge checks complete for HEAD 0118b2d0f320ce0830cef639a0c0125b4650ce64 against main at 41bd980aa58ef5e5d13fa13f1b0b5c5fa01679da. Fresh independent review found no issues; an additional deterministic harness passed 10,000 DBC round trips. Local race tests, vet and formatting passed. GitHub CI passed, including Linux vcan coverage and Windows cross-compilation. Codex review completed with no findings on this HEAD, no review threads remain unresolved, and GitHub reports a clean merge state.

@tomrford
tomrford merged commit 0b385f9 into main Nov 6, 2026
1 check passed
@tomrford
tomrford deleted the claude/dbc-edit branch November 6, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0