Closes #13
This commit is contained in:
1 parent
bce707daf6
commit
51fcdb88ac
174 files changed
+5220
-2213
No files matched your search
+121
-80
@@ -93,8 +93,8 @@ $(document).ready(function(){initNavTree('md_README.html',''); initResizable();
|
||||
<div class="headertitle"><div class="title">DBC Parser and Runtime Decode Module Documentation</div></div>
|
||||
</div><!--header-->
|
||||
<div class="contents">
|
||||
<div class="textblock"><p><a class="anchor" id="autotoc_md20"></a> </p>
|
||||
<h1><a class="anchor" id="autotoc_md21"></a>
|
||||
<div class="textblock"><p><a class="anchor" id="autotoc_md23"></a> </p>
|
||||
<h1><a class="anchor" id="autotoc_md24"></a>
|
||||
Overview</h1>
|
||||
<p>This module provides a minimal but extensible DBC parser and runtime decode foundation for the <b>FrameTap</b> project.</p>
|
||||
<p>Its purpose is to:</p>
|
||||
@@ -116,10 +116,10 @@ Overview</h1>
|
||||
<p>The core library uses C++17 and has no Qt dependency. Qt integration targets the installed Qt 6.8.2, which is the only supported Qt version. Qt Core and Qt Test are used by the regression tests; model tests also link QtGui for graphical metatypes. The optional adapter requires only Qt Core. Live CAN acquisition, trace-file readers, are left to the consuming application. An optional Qt Core model adapter is provided in <code>qt/</code>.</p>
|
||||
<p>See <a class="el" href="md_changelog.html">changelog.md</a> for the release and development history, <a class="el" href="md_tests_2README.html">tests/README.md</a> for test instructions, and <a href="docs/html/index.html">generated API documentation</a> for the API reference.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md23"></a>
|
||||
<h1><a class="anchor" id="autotoc_md26"></a>
|
||||
High-Level Architecture</h1>
|
||||
<p>The module is divided into two main paths.</p>
|
||||
<h2><a class="anchor" id="autotoc_md24"></a>
|
||||
<h2><a class="anchor" id="autotoc_md27"></a>
|
||||
1. Parse and UI path</h2>
|
||||
<p>Used for:</p>
|
||||
<ul>
|
||||
@@ -139,7 +139,7 @@ High-Level Architecture</h1>
|
||||
<div class="line">TreeNode hierarchy</div>
|
||||
<div class="line"> ↓</div>
|
||||
<div class="line">DbcTreeModel → Qt views</div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md25"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md28"></a>
|
||||
2. Runtime decode path</h2>
|
||||
<p>Used for:</p>
|
||||
<ul>
|
||||
@@ -164,7 +164,7 @@ High-Level Architecture</h1>
|
||||
</div><!-- fragment --><p>This separation is intentional.</p>
|
||||
<p>The tree is useful for UI, but it is <b>not</b> the main data structure for runtime decoding.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md27"></a>
|
||||
<h1><a class="anchor" id="autotoc_md30"></a>
|
||||
Why the Runtime Decode Layer Exists</h1>
|
||||
<p>A tree structure is convenient for browsing, but a runtime decoder needs something different:</p>
|
||||
<ul>
|
||||
@@ -181,7 +181,7 @@ Why the Runtime Decode Layer Exists</h1>
|
||||
</ul>
|
||||
<p>This avoids forcing UI-oriented structures into a decode role they were not meant for.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md29"></a>
|
||||
<h1><a class="anchor" id="autotoc_md32"></a>
|
||||
Module Layout</h1>
|
||||
<div class="fragment"><div class="line">core/ C++17 parser, statement handlers, metadata, tree, and decoder</div>
|
||||
<div class="line">examples/ Command-line demo (built separately)</div>
|
||||
@@ -196,7 +196,7 @@ Module Layout</h1>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">Parsed metadata </td><td class="markdownTableBodyNone"><code><a class="el" href="dbc__database_8h.html" title="Created: 2026-03-13 Author: Deeaitch (Dim. Himro)">core/dbc_database.h</a></code>, <code><a class="el" href="frame__info_8h.html" title="Created: 2026-03-13 Author: Deeaitch (Dim. Himro)">core/frame_info.h</a></code>, <code><a class="el" href="signal__info_8h.html" title="Created: 2026-03-13 Author: Deeaitch (Dim. Himro)">core/signal_info.h</a></code> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone">Parser and dispatch </td><td class="markdownTableBodyNone"><code>core/dbc_parser.*</code>, <code>core/dbc_statement_handler.*</code>, <code><a class="el" href="typefactory_8h_source.html">core/typefactory.h</a></code> </td></tr>
|
||||
<td class="markdownTableBodyNone">Parser and dispatch </td><td class="markdownTableBodyNone"><code>core/dbc_parser.*</code>, <code><a class="el" href="dbc__diagnostic_8h_source.html">core/dbc_diagnostic.h</a></code>, <code>core/dbc_statement_handler.*</code>, <code><a class="el" href="typefactory_8h_source.html">core/typefactory.h</a></code> </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone">UI tree </td><td class="markdownTableBodyNone"><code>core/tree_node.*</code>, <code>core/dbc_tree_builder.*</code> </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
@@ -209,9 +209,9 @@ Module Layout</h1>
|
||||
<td class="markdownTableBodyNone">Build integration </td><td class="markdownTableBodyNone"><code>core/core.pro</code>, <code>core/core_files.pri</code>, <code>core/core.pri</code> </td></tr>
|
||||
</table>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md31"></a>
|
||||
<h1><a class="anchor" id="autotoc_md34"></a>
|
||||
Parsed Data Structures</h1>
|
||||
<h1><a class="anchor" id="autotoc_md32"></a>
|
||||
<h1><a class="anchor" id="autotoc_md35"></a>
|
||||
<tt>SignalInfo</tt></h1>
|
||||
<p>Represents one signal as parsed from the DBC file.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -238,7 +238,7 @@ Parsed Data Structures</h1>
|
||||
<p>Physical value rule:</p>
|
||||
<div class="fragment"><div class="line">physical = raw * factor + offset</div>
|
||||
</div><!-- fragment --><hr />
|
||||
<h1><a class="anchor" id="autotoc_md34"></a>
|
||||
<h1><a class="anchor" id="autotoc_md37"></a>
|
||||
<tt>FrameInfo</tt></h1>
|
||||
<p>Represents one frame as parsed from the DBC file.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -260,7 +260,7 @@ Parsed Data Structures</h1>
|
||||
<li><code>pgn</code> is derived using simplified J1939 logic when applicable</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md36"></a>
|
||||
<h1><a class="anchor" id="autotoc_md39"></a>
|
||||
<tt>DbcDatabase</tt></h1>
|
||||
<p>Top-level parsed DBC container.</p>
|
||||
<p>Conceptually:</p>
|
||||
@@ -268,9 +268,9 @@ Parsed Data Structures</h1>
|
||||
<div class="line"> └── vector<FrameInfo></div>
|
||||
</div><!-- fragment --><p>This is the central structure produced by <code><a class="el" href="classDbcParser.html" title="Minimal DBC parser.">DbcParser</a></code>.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md38"></a>
|
||||
<h1><a class="anchor" id="autotoc_md41"></a>
|
||||
UI Tree Layer</h1>
|
||||
<h1><a class="anchor" id="autotoc_md39"></a>
|
||||
<h1><a class="anchor" id="autotoc_md42"></a>
|
||||
<tt>TreeNode</tt></h1>
|
||||
<p>The UI tree contains three node types:</p>
|
||||
<ul>
|
||||
@@ -295,14 +295,14 @@ UI Tree Layer</h1>
|
||||
<p>The tree supports browsing through the optional <code><a class="el" href="classDbcTreeModel.html">DbcTreeModel</a></code> adapter.</p>
|
||||
<p>It is <b>not</b> the primary runtime decode structure.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md41"></a>
|
||||
<h1><a class="anchor" id="autotoc_md44"></a>
|
||||
Runtime Decode Layer</h1>
|
||||
<h1><a class="anchor" id="autotoc_md42"></a>
|
||||
<h1><a class="anchor" id="autotoc_md45"></a>
|
||||
Purpose</h1>
|
||||
<p>The decode layer exists so that decoding can be fast and independent from UI concerns.</p>
|
||||
<p>Instead of searching a tree, the decoder uses a prepared database with direct lookup.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md44"></a>
|
||||
<h1><a class="anchor" id="autotoc_md47"></a>
|
||||
<tt>ByteOrder</tt></h1>
|
||||
<p>Runtime byte order enum:</p>
|
||||
<ul>
|
||||
@@ -311,7 +311,7 @@ Purpose</h1>
|
||||
</ul>
|
||||
<p>This is better for decode code than passing around raw DBC characters.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md46"></a>
|
||||
<h1><a class="anchor" id="autotoc_md49"></a>
|
||||
<tt>ValueType</tt></h1>
|
||||
<p>Numeric type enum:</p>
|
||||
<ul>
|
||||
@@ -320,7 +320,7 @@ Purpose</h1>
|
||||
</ul>
|
||||
<p>This is clearer than combining multiple boolean flags during runtime logic.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md48"></a>
|
||||
<h1><a class="anchor" id="autotoc_md51"></a>
|
||||
<tt>DecodeSignal</tt></h1>
|
||||
<p>Represents one runtime-ready signal definition.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -340,7 +340,7 @@ Purpose</h1>
|
||||
</ul>
|
||||
<p>This structure contains all information required for extracting and converting a signal value from raw frame data.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md50"></a>
|
||||
<h1><a class="anchor" id="autotoc_md53"></a>
|
||||
<tt>DecodeFrame</tt></h1>
|
||||
<p>Represents one runtime-ready frame definition.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -357,7 +357,7 @@ Purpose</h1>
|
||||
</ul>
|
||||
<p>This structure is used directly by the decoder.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md52"></a>
|
||||
<h1><a class="anchor" id="autotoc_md55"></a>
|
||||
<tt>FrameKey</tt></h1>
|
||||
<p>Fast lookup key for runtime frame matching.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -367,7 +367,7 @@ Purpose</h1>
|
||||
</ul>
|
||||
<p>This matters because the same numeric identifier must not be confused between standard and extended frames.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md54"></a>
|
||||
<h1><a class="anchor" id="autotoc_md57"></a>
|
||||
<tt>DecodeDatabase</tt></h1>
|
||||
<p>Top-level runtime decode container.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -381,9 +381,9 @@ Purpose</h1>
|
||||
<div class="line"> └── unordered_map<FrameKey, index></div>
|
||||
</div><!-- fragment --><p>This gives the decoder fast access to a frame definition using CAN ID and frame type.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md56"></a>
|
||||
<h1><a class="anchor" id="autotoc_md59"></a>
|
||||
Decoder Layer</h1>
|
||||
<h1><a class="anchor" id="autotoc_md57"></a>
|
||||
<h1><a class="anchor" id="autotoc_md60"></a>
|
||||
<tt>RawCanFrame</tt></h1>
|
||||
<p>Represents a raw CAN frame to decode.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -399,7 +399,7 @@ Decoder Layer</h1>
|
||||
<li>unit tests</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md59"></a>
|
||||
<h1><a class="anchor" id="autotoc_md62"></a>
|
||||
<tt>DecodedSignalValue</tt></h1>
|
||||
<p>Represents one decoded signal result.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -411,7 +411,7 @@ Decoder Layer</h1>
|
||||
<li><code>status</code></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2><a class="anchor" id="autotoc_md61"></a>
|
||||
<h2><a class="anchor" id="autotoc_md64"></a>
|
||||
Raw value representation and precision</h2>
|
||||
<p><code><a class="el" href="structDecodedSignalValue.html#a503c90b4b1a610b8252c45e466367c28">DecodedSignalValue::rawValue</a></code> is a C++17 <code>std::variant<std::int64_t, std::uint64_t></code>. For a valid signal, signed definitions produce the <code>int64_t</code> alternative and unsigned definitions produce the <code>uint64_t</code> alternative. Raw values remain exact across their full 64-bit ranges. Check <code>valid</code> before using the value; an invalid result's default value is not decoded data.</p>
|
||||
<p>Use <code>std::get</code> when the numeric type is known, or <code>std::get_if</code> to handle both:</p>
|
||||
@@ -423,7 +423,7 @@ Raw value representation and precision</h2>
|
||||
</div><!-- fragment --><p>This replaces the previous <code>int64_t</code> field: consumers that read or print <code>rawValue</code> directly must handle the variant.</p>
|
||||
<p>Physical conversion uses the active numeric type: <code>physicalValue = static_cast<double>(raw) * factor + offset</code>. <code>physicalValue</code> remains a <code>double</code> and is approximate for large integers. On usual IEEE 754 binary64 implementations, integers are exactly representable through 2^53; above that, some integers round to the same floating-point value. For example, unsigned <code>UINT64_MAX</code> remains exact in <code>rawValue</code>, but converts to approximately 18446744073709551616 in binary64 before scaling. Use <code>rawValue</code> whenever exact integer values are required.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md63"></a>
|
||||
<h1><a class="anchor" id="autotoc_md66"></a>
|
||||
<tt>DecodedFrameValue</tt></h1>
|
||||
<p>Represents one decoded frame result.</p>
|
||||
<p>Fields:</p>
|
||||
@@ -435,7 +435,7 @@ Raw value representation and precision</h2>
|
||||
<p><code>valid</code> means a matching frame definition was found. Check each signal's <code>valid</code> separately: insufficient payload data can leave individual signals invalid even when the frame is valid. An unknown frame returns <code>valid == false</code>.</p>
|
||||
<p>The frame and signal <code>definition</code> pointers refer into <code><a class="el" href="structDecodeDatabase.html" title="Runtime decode database with fast lookup by CAN ID.">DecodeDatabase</a></code>. Keep that database alive and avoid changes that invalidate its frame or signal storage while using decoded results. The decoder applies factor and offset; it does not clamp physical values to the declared minimum and maximum.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md65"></a>
|
||||
<h1><a class="anchor" id="autotoc_md68"></a>
|
||||
<tt>DbcDecoder</tt></h1>
|
||||
<p>Main runtime decoder class.</p>
|
||||
<p>Responsibilities:</p>
|
||||
@@ -452,7 +452,7 @@ Raw value representation and precision</h2>
|
||||
<li><code>Decode(...)</code></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md67"></a>
|
||||
<h1><a class="anchor" id="autotoc_md70"></a>
|
||||
Parser Support</h1>
|
||||
<p>The current parser supports the following DBC elements:</p>
|
||||
<ul>
|
||||
@@ -463,10 +463,52 @@ Parser Support</h1>
|
||||
<li><code>VAL_</code> signal value descriptions</li>
|
||||
<li>basic <code>M</code> / <code>mN</code> multiplexing</li>
|
||||
</ul>
|
||||
<h2><a class="anchor" id="autotoc_md71"></a>
|
||||
Structured diagnostics</h2>
|
||||
<p><code>ParseFileWithDiagnostics(path)</code> returns <code><a class="el" href="structDbcParseResult.html">DbcParseResult</a></code> containing <code>database</code> and <code>diagnostics</code>. Each <code><a class="el" href="structDbcDiagnostic.html">DbcDiagnostic</a></code> has <code>severity</code>, <code>code</code>, <code>filePath</code>, <code>lineNumber</code>, and <code>message</code>. Paths preserve the caller's supplied spelling. Lines are one-based physical lines, including blank lines; file-level errors use zero.</p>
|
||||
<div class="fragment"><div class="line"><span class="keyword">const</span> <a class="code hl_class" href="classDbcParser.html">DbcParser</a> parser;</div>
|
||||
<div class="line"><span class="keyword">const</span> <a class="code hl_struct" href="structDbcParseResult.html">DbcParseResult</a> result = parser.<a class="code hl_function" href="classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc">ParseFileWithDiagnostics</a>(<span class="stringliteral">"example.dbc"</span>);</div>
|
||||
<div class="line"><span class="keywordflow">for</span> (<span class="keyword">const</span> <a class="code hl_struct" href="structDbcDiagnostic.html">DbcDiagnostic</a> &diagnostic : result.diagnostics) {</div>
|
||||
<div class="line"> std::cerr << diagnostic.filePath << <span class="stringliteral">":"</span> << diagnostic.lineNumber</div>
|
||||
<div class="line"> << <span class="stringliteral">": "</span> << diagnostic.message << <span class="charliteral">'\n'</span>;</div>
|
||||
<div class="line">}</div>
|
||||
<div class="line"><span class="keywordflow">if</span> (!result.HasErrors()) {</div>
|
||||
<div class="line"> <span class="keyword">const</span> <a class="code hl_struct" href="structDecodeDatabase.html">DecodeDatabase</a> runtime = <a class="code hl_class" href="classDbcDecodeBuilder.html">DbcDecodeBuilder</a>().<a class="code hl_function" href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b">Build</a>(result.database);</div>
|
||||
<div class="line"> <span class="comment">// Inspect warnings before relying on decoding results.</span></div>
|
||||
<div class="line">}</div>
|
||||
<div class="ttc" id="aclassDbcDecodeBuilder_html"><div class="ttname"><a href="classDbcDecodeBuilder.html">DbcDecodeBuilder</a></div><div class="ttdoc">Converts parsed DBC data into runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8h_source.html#l00021">dbc_decode_builder.h:21</a></div></div>
|
||||
<div class="ttc" id="aclassDbcDecodeBuilder_html_a2bc6386dfb5e58976c42e22c19ec471b"><div class="ttname"><a href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b">DbcDecodeBuilder::Build</a></div><div class="ttdeci">DecodeDatabase Build(const DbcDatabase &source) const</div><div class="ttdoc">Build runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8cpp_source.html#l00014">dbc_decode_builder.cpp:14</a></div></div>
|
||||
<div class="ttc" id="aclassDbcParser_html"><div class="ttname"><a href="classDbcParser.html">DbcParser</a></div><div class="ttdoc">Minimal DBC parser.</div><div class="ttdef"><b>Definition</b> <a href="dbc__parser_8h_source.html#l00033">dbc_parser.h:33</a></div></div>
|
||||
<div class="ttc" id="aclassDbcParser_html_a0e915ce79c2e3d4c95a5aaf2bf0409bc"><div class="ttname"><a href="classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc">DbcParser::ParseFileWithDiagnostics</a></div><div class="ttdeci">DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const</div><div class="ttdoc">Parse with warnings and a structured first error instead of throwing.</div><div class="ttdef"><b>Definition</b> <a href="dbc__parser_8cpp_source.html#l00044">dbc_parser.cpp:44</a></div></div>
|
||||
<div class="ttc" id="astructDbcDiagnostic_html"><div class="ttname"><a href="structDbcDiagnostic.html">DbcDiagnostic</a></div><div class="ttdef"><b>Definition</b> <a href="dbc__diagnostic_8h_source.html#l00025">dbc_diagnostic.h:25</a></div></div>
|
||||
<div class="ttc" id="astructDbcParseResult_html"><div class="ttname"><a href="structDbcParseResult.html">DbcParseResult</a></div><div class="ttdef"><b>Definition</b> <a href="dbc__diagnostic_8h_source.html#l00033">dbc_diagnostic.h:33</a></div></div>
|
||||
<div class="ttc" id="astructDecodeDatabase_html"><div class="ttname"><a href="structDecodeDatabase.html">DecodeDatabase</a></div><div class="ttdoc">Runtime decode database with fast lookup by CAN ID.</div><div class="ttdef"><b>Definition</b> <a href="decode__database_8h_source.html#l00109">decode_database.h:109</a></div></div>
|
||||
</div><!-- fragment --><table class="markdownTable">
|
||||
<tr class="markdownTableHead">
|
||||
<th class="markdownTableHeadNone">Severity / code </th><th class="markdownTableHeadNone">Meaning </th></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>FileOpenError</code> </td><td class="markdownTableBodyNone">Input cannot be opened </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>FileReadError</code> </td><td class="markdownTableBodyNone">Input cannot be read completely </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>InvalidStatement</code> </td><td class="markdownTableBodyNone">Invalid frame/signal definition, duplicate, or payload violation </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>InvalidValueDescription</code> </td><td class="markdownTableBodyNone">Invalid <code>VAL_</code> syntax, duplicate value, or unresolved reference </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>InvalidMultiplexing</code> </td><td class="markdownTableBodyNone">Selector, branch range, or signal overlap validation failed </td></tr>
|
||||
<tr class="markdownTableRowEven">
|
||||
<td class="markdownTableBodyNone"><code>Warning</code> / <code>UnsupportedStatement</code> </td><td class="markdownTableBodyNone">Unregistered statement skipped; decoding or metadata may be incomplete </td></tr>
|
||||
<tr class="markdownTableRowOdd">
|
||||
<td class="markdownTableBodyNone"><code>Error</code> / <code>UnsupportedStatement</code> </td><td class="markdownTableBodyNone">Extended multiplexing (<code>SG_MUL_VAL_</code>) rejected </td></tr>
|
||||
</table>
|
||||
<p>Parsing stops at the first error and returns an empty database, together with any preceding warnings and the error. Deferred <code>VAL_</code> and multiplexing errors retain their original source lines. Invalid signal markers use <code>InvalidStatement</code>. <code>HasErrors()</code> checks severity; warnings alone do not make a parse fail.</p>
|
||||
<p>Unknown statements are reported conservatively, including <code>SIG_VALTYPE_</code>, attributes (<code>BA_</code>, <code>BA_DEF_</code>, defaults and relation forms), signal types/references, environment variables, named <code>VAL_TABLE_</code> tables, and vendor extensions. For example, ignoring <code>SIG_VALTYPE_</code> may decode a floating-point signal as an integer. The parser does not implement the warned features; consumers should review warnings.</p>
|
||||
<p>Common <code>VERSION</code>, <code>NS_</code>, <code>BS_</code>, and <code>BU_</code> headers produce no diagnostics. Single-token symbols inside the <code>NS_</code> declaration list are quiet regardless of indentation, even when they name unsupported syntax. Frame, signal, bus, and node definitions or a line with arguments end the list. Actual unsupported statements outside that list are reported. Node and bus metadata are not stored. Other comment forms (<code>CM_</code>, <code>CM_ BU_</code>, <code>CM_ EV_</code>) are ignored by the comment handler; comments only attach to already parsed frames/signals. Supported statements currently require one physical line.</p>
|
||||
<p><code>ParseFile(path)</code> remains compatible: it returns the database, discards warnings, and throws <code>std::runtime_error</code> on the first error with the existing <code>path:line:</code> format. Use <code>ParseFileWithDiagnostics</code> to see skipped syntax. Resource failures such as allocation errors may still throw.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md69"></a>
|
||||
<h1><a class="anchor" id="autotoc_md73"></a>
|
||||
Supported DBC Syntax</h1>
|
||||
<h1><a class="anchor" id="autotoc_md70"></a>
|
||||
<h1><a class="anchor" id="autotoc_md74"></a>
|
||||
Frame definition</h1>
|
||||
<p>Example:</p>
|
||||
<div class="fragment"><div class="line">BO_ 256 EngineData: 8 EEC1</div>
|
||||
@@ -478,16 +520,16 @@ Frame definition</h1>
|
||||
<li>transmitter ECU</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2><a class="anchor" id="autotoc_md72"></a>
|
||||
<h2><a class="anchor" id="autotoc_md76"></a>
|
||||
Frame validation and parse errors</h2>
|
||||
<p><code>BO_</code> definitions require a decimal CAN ID, a nonempty single-token frame name, a colon, a decimal payload length, and a transmitter token. Spaces or tabs may separate fields, and whitespace before the colon is accepted. Additional trailing fields are rejected.</p>
|
||||
<p>Numeric fields must contain decimal digits only; signs, hexadecimal notation, fractional values, suffixes, and overflow are rejected. CAN IDs may contain the 29-bit identifier plus the optional DBC extended flag (bit 31). Bits 29 and 30 are rejected rather than silently discarded. For compatibility, unflagged IDs above <code>0x7FF</code> are still treated as extended.</p>
|
||||
<p>The payload length must fit <code>uint8_t</code> (<code>0..255</code>). This is a storage-range check, not CAN or CAN FD protocol validation; no new 8-byte or 64-byte limit is imposed.</p>
|
||||
<p>Parsing stops at the first detected error. Exceptions raised while parsing a line are reported as <code>std::runtime_error</code> with the supplied file path and the one-based physical line number, including blank lines:</p>
|
||||
<div class="fragment"><div class="line">example.dbc:3: Invalid CAN ID: invalid</div>
|
||||
</div><!-- fragment --><p>Frame and signal definitions are validated as described here; comprehensive DBC grammar coverage is still planned. File-open errors contain the path but have no line number.</p>
|
||||
</div><!-- fragment --><p>Frame and signal definitions are validated as described here; comprehensive DBC grammar coverage is still planned. File-open exceptions contain the path but no line number. The structured diagnostic API uses line zero for file-level errors.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md74"></a>
|
||||
<h1><a class="anchor" id="autotoc_md78"></a>
|
||||
Signal definition</h1>
|
||||
<p>Example:</p>
|
||||
<div class="fragment"><div class="line">SG_ EngineSpeed : 0|16@1+ (0.125,0) [0|8000] "rpm" ECU1,ECU2</div>
|
||||
@@ -506,15 +548,15 @@ Signal definition</h1>
|
||||
<li>receivers</li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h2><a class="anchor" id="autotoc_md76"></a>
|
||||
<h2><a class="anchor" id="autotoc_md80"></a>
|
||||
Signal validation and parse errors</h2>
|
||||
<p><code>SG_</code> statements are matched completely. Signal names must be nonempty and contain no whitespace. Spaces and tabs are accepted between syntax elements; byte order and signedness remain adjacent (<code>@0+</code>, <code>@0-</code>, <code>@1+</code>, or <code>@1-</code>). A quoted unit (which may be empty) and a nonempty comma-separated receiver list are required. Unexpected trailing fields are rejected.</p>
|
||||
<p>Start bits must be unsigned decimal integers fitting <code>uint32_t</code>; lengths must be within <code>1..64</code> bits. Signs, fractional values, numeric suffixes, and overflow are rejected for these fields. Every signal bit must fit within the frame's declared payload length, using Intel increasing bit positions or Motorola sawtooth traversal. This uses the stored payload length without introducing an additional CAN or CAN FD payload limit.</p>
|
||||
<p>Factor, offset, minimum, and maximum accept signed decimal numbers, fractions, and scientific notation. The entire numeric token must be valid; hexadecimal numbers, NaN, infinity, conversion overflow, and conversion underflow are rejected. Minimum must not exceed maximum. Zero and negative factors are allowed.</p>
|
||||
<p>Basic multiplexing markers <code>M</code> and <code>mN</code> are supported as described below. Overlapping signals are rejected unless their branch values differ. Duplicate frame/signal name detection remains separate work.</p>
|
||||
<p>Basic multiplexing markers <code>M</code> and <code>mN</code> are supported as described below. Overlapping signals are rejected unless their branch values differ. Duplicate frame keys and signal names within a frame are rejected.</p>
|
||||
<p>Invalid signal definitions stop parsing with <code>path:line: description</code>, including when the signal exceeds the declared payload length.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md78"></a>
|
||||
<h1><a class="anchor" id="autotoc_md82"></a>
|
||||
Basic multiplexing</h1>
|
||||
<div class="fragment"><div class="line">BO_ 256 Status: 3 ECU</div>
|
||||
<div class="line"> SG_ Mode M : 0|8@1+ (1,0) [0|255] "" ECU</div>
|
||||
@@ -541,7 +583,7 @@ Basic multiplexing</h1>
|
||||
</table>
|
||||
<p>All statuses except <code>Valid</code> have <code>valid == false</code>; their numeric fields contain no decoded data and <code>GetValueDescription()</code> returns nullptr. Check <code>status</code> to distinguish inactive branches from errors. Consumers constructing runtime metadata manually must obey the same non-overlap rules as the parser. Extended and nested multiplexing are outside this stage and are explicitly rejected, rather than silently decoded as unconditional signals.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md80"></a>
|
||||
<h1><a class="anchor" id="autotoc_md84"></a>
|
||||
Comments</h1>
|
||||
<p>Frame comment example:</p>
|
||||
<div class="fragment"><div class="line">CM_ BO_ 256 "Engine data frame";</div>
|
||||
@@ -553,7 +595,7 @@ Comments</h1>
|
||||
<li><code><a class="el" href="structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5">SignalInfo::comment</a></code></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md82"></a>
|
||||
<h1><a class="anchor" id="autotoc_md86"></a>
|
||||
CAN ID Normalization</h1>
|
||||
<p>The parser normalizes frame identifiers.</p>
|
||||
<p>Common DBC behavior:</p>
|
||||
@@ -568,7 +610,7 @@ CAN ID Normalization</h1>
|
||||
</ul>
|
||||
<p>This is important both for correct lookup and for future interoperability with live CAN APIs.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md84"></a>
|
||||
<h1><a class="anchor" id="autotoc_md88"></a>
|
||||
PGN Extraction</h1>
|
||||
<p>PGN is derived only when the frame is treated as extended.</p>
|
||||
<p>The current logic is simplified J1939 extraction:</p>
|
||||
@@ -579,7 +621,7 @@ PGN Extraction</h1>
|
||||
</ul>
|
||||
<p>This is enough for a practical start but should not be treated as full J1939 validation.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md86"></a>
|
||||
<h1><a class="anchor" id="autotoc_md90"></a>
|
||||
Decode Flow</h1>
|
||||
<p>Typical runtime decode flow:</p>
|
||||
<div class="fragment"><div class="line">RawCanFrame</div>
|
||||
@@ -594,7 +636,7 @@ Decode Flow</h1>
|
||||
<div class="line"> ↓</div>
|
||||
<div class="line">DecodedFrameValue</div>
|
||||
</div><!-- fragment --><hr />
|
||||
<h1><a class="anchor" id="autotoc_md88"></a>
|
||||
<h1><a class="anchor" id="autotoc_md92"></a>
|
||||
Intel and Motorola Extraction</h1>
|
||||
<p>The decoder currently has separate extraction paths:</p>
|
||||
<ul>
|
||||
@@ -605,7 +647,7 @@ Intel and Motorola Extraction</h1>
|
||||
<p>Intel and Motorola require different bit extraction logic.</p>
|
||||
<p>This is one of the main reasons why the runtime decode layer should be explicit and prepared in advance.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md90"></a>
|
||||
<h1><a class="anchor" id="autotoc_md94"></a>
|
||||
Example Usage</h1>
|
||||
<p>Include the public headers from the <code>core/</code> include directory supplied by <code>core/core.pri</code>:</p>
|
||||
<div class="fragment"><div class="line"><span class="preprocessor">#include "<a class="code" href="dbc__parser_8h.html">dbc_parser.h</a>"</span></div>
|
||||
@@ -616,27 +658,23 @@ Example Usage</h1>
|
||||
<div class="ttc" id="adbc__decoder_8h_html"><div class="ttname"><a href="dbc__decoder_8h.html">dbc_decoder.h</a></div><div class="ttdoc">Created: 2026-03-13 Author: Deeaitch (Dim. Himro)</div></div>
|
||||
<div class="ttc" id="adbc__parser_8h_html"><div class="ttname"><a href="dbc__parser_8h.html">dbc_parser.h</a></div><div class="ttdoc">Created: 2026-03-13 Author: Deeaitch (Dim. Himro)</div></div>
|
||||
<div class="ttc" id="adbc__tree__builder_8h_html"><div class="ttname"><a href="dbc__tree__builder_8h.html">dbc_tree_builder.h</a></div><div class="ttdoc">Created: 2026-03-13 Author: Deeaitch (Dim. Himro)</div></div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md91"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md95"></a>
|
||||
Parse DBC</h2>
|
||||
<div class="fragment"><div class="line"><a class="code hl_class" href="classDbcParser.html">DbcParser</a> parser;</div>
|
||||
<div class="line"><a class="code hl_struct" href="structDbcDatabase.html">DbcDatabase</a> database = parser.<a class="code hl_function" href="classDbcParser.html#aef72826942c9095d653fafa435855e56">ParseFile</a>(<span class="stringliteral">"example.dbc"</span>);</div>
|
||||
<div class="ttc" id="aclassDbcParser_html"><div class="ttname"><a href="classDbcParser.html">DbcParser</a></div><div class="ttdoc">Minimal DBC parser.</div><div class="ttdef"><b>Definition</b> <a href="dbc__parser_8h_source.html#l00034">dbc_parser.h:34</a></div></div>
|
||||
<div class="ttc" id="aclassDbcParser_html_aef72826942c9095d653fafa435855e56"><div class="ttname"><a href="classDbcParser.html#aef72826942c9095d653fafa435855e56">DbcParser::ParseFile</a></div><div class="ttdeci">DbcDatabase ParseFile(const std::string &filePath) const</div><div class="ttdoc">Parse DBC file.</div><div class="ttdef"><b>Definition</b> <a href="dbc__parser_8cpp_source.html#l00019">dbc_parser.cpp:19</a></div></div>
|
||||
<div class="ttc" id="aclassDbcParser_html_aef72826942c9095d653fafa435855e56"><div class="ttname"><a href="classDbcParser.html#aef72826942c9095d653fafa435855e56">DbcParser::ParseFile</a></div><div class="ttdeci">DbcDatabase ParseFile(const std::string &filePath) const</div><div class="ttdoc">Parse DBC file.</div><div class="ttdef"><b>Definition</b> <a href="dbc__parser_8cpp_source.html#l00031">dbc_parser.cpp:31</a></div></div>
|
||||
<div class="ttc" id="astructDbcDatabase_html"><div class="ttname"><a href="structDbcDatabase.html">DbcDatabase</a></div><div class="ttdoc">Parsed DBC content stored in a simple internal form.</div><div class="ttdef"><b>Definition</b> <a href="dbc__database_8h_source.html#l00022">dbc_database.h:22</a></div></div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md92"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md96"></a>
|
||||
Build UI tree</h2>
|
||||
<div class="fragment"><div class="line"><a class="code hl_class" href="classDbcTreeBuilder.html">DbcTreeBuilder</a> treeBuilder;</div>
|
||||
<div class="line">std::unique_ptr<TreeNode> root = treeBuilder.<a class="code hl_function" href="classDbcTreeBuilder.html#a7e57d067d831b14b383947fd125edd4b">Build</a>(database);</div>
|
||||
<div class="ttc" id="aclassDbcTreeBuilder_html"><div class="ttname"><a href="classDbcTreeBuilder.html">DbcTreeBuilder</a></div><div class="ttdoc">Builds a simple tree from parsed DBC database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__tree__builder_8h_source.html#l00023">dbc_tree_builder.h:23</a></div></div>
|
||||
<div class="ttc" id="aclassDbcTreeBuilder_html_a7e57d067d831b14b383947fd125edd4b"><div class="ttname"><a href="classDbcTreeBuilder.html#a7e57d067d831b14b383947fd125edd4b">DbcTreeBuilder::Build</a></div><div class="ttdeci">std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const</div><div class="ttdoc">Build tree representation of parsed DBC data.</div><div class="ttdef"><b>Definition</b> <a href="dbc__tree__builder_8cpp_source.html#l00014">dbc_tree_builder.cpp:14</a></div></div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md93"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md97"></a>
|
||||
Build runtime decode database</h2>
|
||||
<div class="fragment"><div class="line"><a class="code hl_class" href="classDbcDecodeBuilder.html">DbcDecodeBuilder</a> decodeBuilder;</div>
|
||||
<div class="line"><a class="code hl_struct" href="structDecodeDatabase.html">DecodeDatabase</a> decodeDatabase = decodeBuilder.<a class="code hl_function" href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b">Build</a>(database);</div>
|
||||
<div class="ttc" id="aclassDbcDecodeBuilder_html"><div class="ttname"><a href="classDbcDecodeBuilder.html">DbcDecodeBuilder</a></div><div class="ttdoc">Converts parsed DBC data into runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8h_source.html#l00021">dbc_decode_builder.h:21</a></div></div>
|
||||
<div class="ttc" id="aclassDbcDecodeBuilder_html_a2bc6386dfb5e58976c42e22c19ec471b"><div class="ttname"><a href="classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b">DbcDecodeBuilder::Build</a></div><div class="ttdeci">DecodeDatabase Build(const DbcDatabase &source) const</div><div class="ttdoc">Build runtime decode database.</div><div class="ttdef"><b>Definition</b> <a href="dbc__decode__builder_8cpp_source.html#l00014">dbc_decode_builder.cpp:14</a></div></div>
|
||||
<div class="ttc" id="astructDecodeDatabase_html"><div class="ttname"><a href="structDecodeDatabase.html">DecodeDatabase</a></div><div class="ttdoc">Runtime decode database with fast lookup by CAN ID.</div><div class="ttdef"><b>Definition</b> <a href="decode__database_8h_source.html#l00109">decode_database.h:109</a></div></div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md94"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md98"></a>
|
||||
Decode a raw frame</h2>
|
||||
<div class="fragment"><div class="line"><a class="code hl_struct" href="structRawCanFrame.html">RawCanFrame</a> rawFrame;</div>
|
||||
<div class="line">rawFrame.<a class="code hl_variable" href="structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4">canId</a> = 256; <span class="comment">// EngineData from the DBC example above</span></div>
|
||||
@@ -653,7 +691,7 @@ Decode a raw frame</h2>
|
||||
<div class="ttc" id="astructRawCanFrame_html_a2d0e7fa0e3d5c20bbed55ed8f7888ff4"><div class="ttname"><a href="structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4">RawCanFrame::canId</a></div><div class="ttdeci">std::uint32_t canId</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8h_source.html#l00025">dbc_decoder.h:25</a></div></div>
|
||||
<div class="ttc" id="astructRawCanFrame_html_a462193d275adc1dba8bd18ffa0e36bb7"><div class="ttname"><a href="structRawCanFrame.html#a462193d275adc1dba8bd18ffa0e36bb7">RawCanFrame::isExtended</a></div><div class="ttdeci">bool isExtended</div><div class="ttdef"><b>Definition</b> <a href="dbc__decoder_8h_source.html#l00026">dbc_decoder.h:26</a></div></div>
|
||||
</div><!-- fragment --><hr />
|
||||
<h1><a class="anchor" id="autotoc_md96"></a>
|
||||
<h1><a class="anchor" id="autotoc_md100"></a>
|
||||
Unified Decode Strategy</h1>
|
||||
<p>A key design goal is that the same decoder should work for both:</p>
|
||||
<ul>
|
||||
@@ -661,7 +699,7 @@ Unified Decode Strategy</h1>
|
||||
<li>trace replay frames</li>
|
||||
</ul>
|
||||
<p>That means this architecture supports:</p>
|
||||
<h2><a class="anchor" id="autotoc_md97"></a>
|
||||
<h2><a class="anchor" id="autotoc_md101"></a>
|
||||
live path</h2>
|
||||
<div class="fragment"><div class="line">live CAN input</div>
|
||||
<div class="line"> ↓</div>
|
||||
@@ -670,7 +708,7 @@ live path</h2>
|
||||
<div class="line">DbcDecoder</div>
|
||||
<div class="line"> ↓</div>
|
||||
<div class="line">decoded signal values</div>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md98"></a>
|
||||
</div><!-- fragment --><h2><a class="anchor" id="autotoc_md102"></a>
|
||||
trace path</h2>
|
||||
<div class="fragment"><div class="line">trace reader</div>
|
||||
<div class="line"> ↓</div>
|
||||
@@ -681,7 +719,7 @@ trace path</h2>
|
||||
<div class="line">decoded signal values</div>
|
||||
</div><!-- fragment --><p>This avoids duplicating decode logic in two separate parts of the application.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md100"></a>
|
||||
<h1><a class="anchor" id="autotoc_md104"></a>
|
||||
Intended Use in FrameTap</h1>
|
||||
<p>This module is meant to support at least the following FrameTap workflows:</p>
|
||||
<ul>
|
||||
@@ -707,7 +745,7 @@ Intended Use in FrameTap</h1>
|
||||
<div class="line"> - live frames</div>
|
||||
<div class="line"> - trace replay</div>
|
||||
</div><!-- fragment --><hr />
|
||||
<h1><a class="anchor" id="autotoc_md102"></a>
|
||||
<h1><a class="anchor" id="autotoc_md106"></a>
|
||||
Why the Tree Is Not Enough</h1>
|
||||
<p>The tree exists for browsing.</p>
|
||||
<p>However, runtime decode should not rely on tree traversal because that would introduce unnecessary coupling and inefficiency.</p>
|
||||
@@ -719,7 +757,7 @@ Why the Tree Is Not Enough</h1>
|
||||
</ul>
|
||||
<p>That is why <code><a class="el" href="structDecodeDatabase.html" title="Runtime decode database with fast lookup by CAN ID.">DecodeDatabase</a></code> is a separate layer.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md104"></a>
|
||||
<h1><a class="anchor" id="autotoc_md108"></a>
|
||||
Statement Handler Factory</h1>
|
||||
<p><code><a class="el" href="classDbcParser.html" title="Minimal DBC parser.">DbcParser</a></code> owns file reading, trimming, line numbers, and error reporting. Each <code>ParseFile()</code> call creates a fresh <code><a class="el" href="structDbcParseContext.html">DbcParseContext</a></code> and a <code><a class="el" href="classDbcStatementDispatcher.html">DbcStatementDispatcher</a></code>. The context contains the parsed database and current frame; handlers receive it by reference and retain no parsing state.</p>
|
||||
<p>The dispatcher uses <code><a class="el" href="classTypeFactory.html" title="Registry-based factory for creating objects by runtime identifier.">TypeFactory</a><std::string, <a class="el" href="classDbcStatementHandler.html">DbcStatementHandler</a>></code> to create registered handlers once per parsing session, then reuses them for all matching lines:</p>
|
||||
@@ -729,17 +767,18 @@ Statement Handler Factory</h1>
|
||||
<li><code>CM_</code> → <code><a class="el" href="classDbcCommentHandler.html">DbcCommentHandler</a></code></li>
|
||||
<li><code>VAL_</code> → <code><a class="el" href="classDbcValueDescriptionHandler.html">DbcValueDescriptionHandler</a></code></li>
|
||||
<li><code>SG_MUL_VAL_</code> → <code><a class="el" href="classDbcUnsupportedMultiplexingHandler.html">DbcUnsupportedMultiplexingHandler</a></code></li>
|
||||
<li><code>VERSION</code>, <code>NS_</code>, <code>BS_</code>, <code>BU_</code> → <code><a class="el" href="classDbcHeaderHandler.html">DbcHeaderHandler</a></code> (also accepts attached colons)</li>
|
||||
</ul>
|
||||
<p>Grammar implementations live in <code><a class="el" href="dbc__statement__handler_8cpp_source.html">core/dbc_statement_handler.cpp</a></code>; their interface, context, and dispatcher live in <code><a class="el" href="dbc__statement__handler_8h_source.html">core/dbc_statement_handler.h</a></code>. <code><a class="el" href="typefactory_8h_source.html">core/typefactory.h</a></code> provides the generic registry and object creation.</p>
|
||||
<p>To add a construct, implement a default-constructible handler deriving from <code><a class="el" href="classDbcStatementHandler.html">DbcStatementHandler</a></code> with:</p>
|
||||
<div class="fragment"><div class="line"><span class="keywordtype">void</span> Handle(<span class="keyword">const</span> std::string &line, <a class="code hl_struct" href="structDbcParseContext.html">DbcParseContext</a> &context) <span class="keyword">const override</span>;</div>
|
||||
<div class="ttc" id="astructDbcParseContext_html"><div class="ttname"><a href="structDbcParseContext.html">DbcParseContext</a></div><div class="ttdef"><b>Definition</b> <a href="dbc__statement__handler_8h_source.html#l00019">dbc_statement_handler.h:19</a></div></div>
|
||||
<div class="ttc" id="astructDbcParseContext_html"><div class="ttname"><a href="structDbcParseContext.html">DbcParseContext</a></div><div class="ttdef"><b>Definition</b> <a href="dbc__statement__handler_8h_source.html#l00032">dbc_statement_handler.h:32</a></div></div>
|
||||
</div><!-- fragment --><p>Register it in the dispatcher constructor:</p>
|
||||
<div class="fragment"><div class="line">RegisterType<MyCustomHandler>(<span class="stringliteral">"CUSTOM_"</span>); <span class="comment">// after implementing MyCustomHandler</span></div>
|
||||
</div><!-- fragment --><p>Registration creates one handler; replacing a registration replaces that instance. Register during initialization before dispatching. A line is routed using its full first whitespace-delimited keyword, so <code>BO_TX_BU_</code> cannot match <code>BO_</code>. Unregistered keywords remain ignored. <code>SG_</code> and <code>CM_</code> accept spaces and tabs after their keywords.</p>
|
||||
</div><!-- fragment --><p>Registration creates one handler; replacing a registration replaces that instance. Register during initialization before dispatching. A line is routed using its full first whitespace-delimited keyword, so <code>BO_TX_BU_</code> cannot match <code>BO_</code>. Unregistered keywords produce <code>UnsupportedStatement</code> warnings through <code>ParseFileWithDiagnostics</code>. <code>SG_</code> and <code>CM_</code> accept spaces and tabs after their keywords.</p>
|
||||
<p>This factory handles statements inside DBC files. A separate format-level factory can be introduced when another file format is implemented. The decoder and database builders remain independent of statement dispatch.</p>
|
||||
<hr />
|
||||
<h1><a class="anchor" id="autotoc_md106"></a>
|
||||
<h1><a class="anchor" id="autotoc_md110"></a>
|
||||
Signal value descriptions (<tt>VAL_</tt>)</h1>
|
||||
<p>Signal descriptions attach text to exact raw integer values:</p>
|
||||
<div class="fragment"><div class="line">BO_ 256 Status: 8 ECU</div>
|
||||
@@ -789,7 +828,7 @@ are outside this implementation; the optional Qt adapter exposes signal mappings
|
||||
|
||||
<hr>
|
||||
|
||||
@section autotoc_md108 Current Limitations
|
||||
@section autotoc_md112 Current Limitations
|
||||
|
||||
This is still a minimal implementation.
|
||||
|
||||
@@ -798,7 +837,9 @@ Not supported yet:
|
||||
- extended and nested multiplexing (<tt>SG_MUL_VAL_</tt>, <tt>mNM</tt>)
|
||||
- named <tt>VAL_TABLE_</tt> tables and environment-variable value descriptions
|
||||
- <tt>BA_</tt> attributes
|
||||
- <tt>BA_DEF_</tt> definitions
|
||||
- <tt>BA_DEF_</tt> definitions and attribute defaults
|
||||
- <tt>SIG_VALTYPE_</tt> floating-point signal types
|
||||
- signal types/references (<tt>SGTYPE_</tt>, <tt>SIG_TYPE_REF_</tt>) and environment variables
|
||||
- advanced comment handling
|
||||
- full DBC grammar coverage
|
||||
- full J1939 validation
|
||||
@@ -806,7 +847,7 @@ Not supported yet:
|
||||
|
||||
Additional behavior to account for:
|
||||
|
||||
- unregistered DBC keywords are ignored
|
||||
- unregistered DBC keywords are skipped with warnings in the diagnostic API
|
||||
- an <tt>SG_</tt> statement before the first frame is rejected
|
||||
- duplicate frame keys (normalized CAN ID and frame type) and repeated signal
|
||||
names within a frame are rejected at their definition lines; manually created
|
||||
@@ -821,11 +862,11 @@ byte boundaries, and 64-bit values.
|
||||
|
||||
<hr>
|
||||
|
||||
@section autotoc_md110 Recommended Next Steps
|
||||
@section autotoc_md114 Recommended Next Steps
|
||||
|
||||
A practical development order would be:
|
||||
|
||||
@subsection autotoc_md111 Stage 1 - already implemented
|
||||
@subsection autotoc_md115 Stage 1 - already implemented
|
||||
|
||||
- <tt>BO_</tt>
|
||||
- <tt>SG_</tt>
|
||||
@@ -840,13 +881,13 @@ A practical development order would be:
|
||||
- runtime decode database
|
||||
- runtime decoder
|
||||
|
||||
@subsection autotoc_md112 Stage 2
|
||||
@subsection autotoc_md116 Stage 2
|
||||
|
||||
Recommended additions:
|
||||
|
||||
- selective decoding of only chosen signals
|
||||
|
||||
@subsection autotoc_md113 Stage 3
|
||||
@subsection autotoc_md117 Stage 3
|
||||
|
||||
Recommended additions:
|
||||
|
||||
@@ -856,7 +897,7 @@ Recommended additions:
|
||||
- CSV export of decoded traces
|
||||
- optimized filtering and signal selection
|
||||
|
||||
@subsection autotoc_md114 Stage 4
|
||||
@subsection autotoc_md118 Stage 4
|
||||
|
||||
Advanced functionality:
|
||||
|
||||
@@ -867,7 +908,7 @@ Advanced functionality:
|
||||
|
||||
<hr>
|
||||
|
||||
@section autotoc_md116 Build Integration
|
||||
@section autotoc_md120 Build Integration
|
||||
|
||||
The repository supplies qmake projects. A C++17 compiler is required; the root
|
||||
build also requires Qt Core and Qt Test development packages. Other build
|
||||
@@ -898,7 +939,7 @@ source lists live in <tt>tests/parser_tests.pri</tt> and <tt>t
|
||||
When building a consumer separately, pass
|
||||
<tt>DBC_CORE_BUILD_DIR=/absolute/path/to/build/core</tt> to qmake.
|
||||
|
||||
@subsection autotoc_md117 Build core without Qt libraries
|
||||
@subsection autotoc_md121 Build core without Qt libraries
|
||||
|
||||
From the repository root:
|
||||
|
||||
@@ -911,7 +952,7 @@ make -j
|
||||
|
||||
qmake is still the build tool; this target does not link Qt libraries.
|
||||
|
||||
@subsection autotoc_md118 Optional Qt model adapter
|
||||
@subsection autotoc_md122 Optional Qt model adapter
|
||||
|
||||
The adapter and its <tt>QAbstractItemModelTester</tt> suite use Qt 6.8.2.
|
||||
The adapter itself links only Qt Core.
|
||||
@@ -1032,7 +1073,7 @@ Valid items are enabled and selectable, with no editing support.
|
||||
<p></code></p>
|
||||
<p><code>Each value-description entry contains <code>value</code> (qlonglong for negative keys, qulonglong for nonnegative keys) and <code>description</code> (QString). This preserves the full signed/unsigned 64-bit range without converting through double. An unmapped signal returns an empty list. Data comes from <code><a class="el" href="structSignalInfo.html#a43f47d0433d0cc39076bd7278b46af9c">SignalInfo::valueDescriptions</a></code>. Unsupported roles return invalid QVariant.</code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md119"></a>
|
||||
<h2><a class="anchor" id="autotoc_md123"></a>
|
||||
Standalone tree tests without Qt</h2>
|
||||
<p><code></code></p>
|
||||
<p><code>From the repository root, use only a C++17 compiler:</code></p>
|
||||
@@ -1041,7 +1082,7 @@ Standalone tree tests without Qt</h2>
|
||||
<div class="line">/tmp/dbc_tree_node_test</div>
|
||||
</div><!-- fragment --><p></code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md120"></a>
|
||||
<h2><a class="anchor" id="autotoc_md124"></a>
|
||||
Build and run the demo</h2>
|
||||
<p><code></code></p>
|
||||
<p><code>After building core, run these commands from the repository root:</code></p>
|
||||
@@ -1053,7 +1094,7 @@ Build and run the demo</h2>
|
||||
</div><!-- fragment --><p></code></p>
|
||||
<p><code>The demo prints the parsed tree and decodes eight zero bytes using the first frame definition. Replace that sample payload in <code><a class="el" href="examples_2main_8cpp.html" title="Created: 2026-03-13 Author: Deeaitch (Dim. Himro)">examples/main.cpp</a></code> to feed live CAN data or trace records.</code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md121"></a>
|
||||
<h2><a class="anchor" id="autotoc_md125"></a>
|
||||
Generate API documentation</h2>
|
||||
<p><code></code></p>
|
||||
<p><code>With Doxygen installed, run from the repository root:</code></p>
|
||||
@@ -1063,17 +1104,17 @@ Generate API documentation</h2>
|
||||
<p><code></p><hr />
|
||||
<p></code></p>
|
||||
<p><code></code></p>
|
||||
<h1><a class="anchor" id="autotoc_md123"></a>
|
||||
<h1><a class="anchor" id="autotoc_md127"></a>
|
||||
Regression tests</h1>
|
||||
<p><code></code></p>
|
||||
<p><code>See <a class="el" href="md_tests_2README.html">tests/README.md</a> for QtTest build and execution commands. Tests cover frame validation and error locations, Intel and Motorola extraction, signal syntax and payload bounds, <code>VAL_</code> syntax and reference validation, raw description lookup and preservation through both builders, statement dispatch, signed and unsigned 64-bit boundaries, physical conversion, numeric output, and invalid signal payloads.</code></p>
|
||||
<p><code></code></p>
|
||||
<h1><a class="anchor" id="autotoc_md124"></a>
|
||||
<h1><a class="anchor" id="autotoc_md128"></a>
|
||||
Measuring code coverage</h1>
|
||||
<p><code></code></p>
|
||||
<p><code>Coverage instrumentation is separate from the QtTest suite named <code>CoverageTest</code>: that suite runs extra regression checks, but coverage counters require a specially instrumented build. Use a separate build directory for each coverage tool.</code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md125"></a>
|
||||
<h2><a class="anchor" id="autotoc_md129"></a>
|
||||
GCC, gcov, and LCOV on Debian/Ubuntu</h2>
|
||||
<p><code></code></p>
|
||||
<p><code>Install the build and report tools:</code></p>
|
||||
@@ -1127,7 +1168,7 @@ GCC, gcov, and LCOV on Debian/Ubuntu</h2>
|
||||
<p><code>After adding direct comment-handler and ambiguous <code>VAL_</code> reference tests, the same configuration measured 98.4% line coverage (728/740) and 71.4% branch coverage (841/1178).</code></p>
|
||||
<p><code>See <a href="https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html">GCC instrumentation options</a> and the <a href="https://github.com/linux-test-project/lcov">LCOV project documentation</a>.</code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md126"></a>
|
||||
<h2><a class="anchor" id="autotoc_md130"></a>
|
||||
Configure the GCC coverage build in Qt Creator</h2>
|
||||
<p><code></code></p>
|
||||
<p><code></p><ol type="1">
|
||||
@@ -1143,7 +1184,7 @@ Configure the GCC coverage build in Qt Creator</h2>
|
||||
</ol>
|
||||
<p></code></p>
|
||||
<p><code></code></p>
|
||||
<h2><a class="anchor" id="autotoc_md127"></a>
|
||||
<h2><a class="anchor" id="autotoc_md131"></a>
|
||||
Configure all build variants in Qt Creator</h2>
|
||||
<p><code></code></p>
|
||||
<p><code>The local <code>dbc.pro.user</code> stores machine-specific kit IDs and build/run settings. It is ignored by Git (<code>*.user</code>) and should not be committed or copied between machines. Recreate the configurations below through the UI when setting up a new checkout. The <code>Qt4ProjectManager</code> identifiers inside <code>.user</code> are historical Qt Creator setting names; the project still requires Qt 6.8.2.</code></p>
|
||||
|
||||
Reference in new issue
Block a user