diff --git a/README.md b/README.md index 13b1a6b..99aef63 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ Doxyfile API documentation configuration | Component | Source files | | --- | --- | | Parsed metadata | `core/dbc_database.h`, `core/frame_info.h`, `core/signal_info.h` | -| Parser and dispatch | `core/dbc_parser.*`, `core/dbc_statement_handler.*`, `core/typefactory.h` | +| Parser and dispatch | `core/dbc_parser.*`, `core/dbc_diagnostic.h`, `core/dbc_statement_handler.*`, `core/typefactory.h` | | UI tree | `core/tree_node.*`, `core/dbc_tree_builder.*` | | Runtime database | `core/decode_database.h`, `core/dbc_decode_builder.*` | | Decoder | `core/dbc_decoder.*` | @@ -470,6 +470,61 @@ The current parser supports the following DBC elements: - `VAL_` signal value descriptions - basic `M` / `mN` multiplexing +### Structured diagnostics + +`ParseFileWithDiagnostics(path)` returns `DbcParseResult` containing `database` +and `diagnostics`. Each `DbcDiagnostic` has `severity`, `code`, `filePath`, +`lineNumber`, and `message`. Paths preserve the caller's supplied spelling. +Lines are one-based physical lines, including blank lines; file-level errors use zero. + +```cpp +const DbcParser parser; +const DbcParseResult result = parser.ParseFileWithDiagnostics("example.dbc"); +for (const DbcDiagnostic &diagnostic : result.diagnostics) { + std::cerr << diagnostic.filePath << ":" << diagnostic.lineNumber + << ": " << diagnostic.message << '\n'; +} +if (!result.HasErrors()) { + const DecodeDatabase runtime = DbcDecodeBuilder().Build(result.database); + // Inspect warnings before relying on decoding results. +} +``` + +| Severity / code | Meaning | +| --- | --- | +| `Error` / `FileOpenError` | Input cannot be opened | +| `Error` / `FileReadError` | Input cannot be read completely | +| `Error` / `InvalidStatement` | Invalid frame/signal definition, duplicate, or payload violation | +| `Error` / `InvalidValueDescription` | Invalid `VAL_` syntax, duplicate value, or unresolved reference | +| `Error` / `InvalidMultiplexing` | Selector, branch range, or signal overlap validation failed | +| `Warning` / `UnsupportedStatement` | Unregistered statement skipped; decoding or metadata may be incomplete | +| `Error` / `UnsupportedStatement` | Extended multiplexing (`SG_MUL_VAL_`) rejected | + +Parsing stops at the first error and returns an empty database, together with +any preceding warnings and the error. Deferred `VAL_` and multiplexing errors +retain their original source lines. Invalid signal markers use `InvalidStatement`. +`HasErrors()` checks severity; warnings alone do not make a parse fail. + +Unknown statements are reported conservatively, including `SIG_VALTYPE_`, +attributes (`BA_`, `BA_DEF_`, defaults and relation forms), signal types/references, +environment variables, named `VAL_TABLE_` tables, and vendor extensions. For +example, ignoring `SIG_VALTYPE_` may decode a floating-point signal as an integer. +The parser does not implement the warned features; consumers should review warnings. + +Common `VERSION`, `NS_`, `BS_`, and `BU_` headers produce no diagnostics. +Single-token symbols inside the `NS_` 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 (`CM_`, `CM_ BU_`, +`CM_ EV_`) are ignored by the comment handler; comments only attach to already +parsed frames/signals. Supported statements currently require one physical line. + +`ParseFile(path)` remains compatible: it returns the database, discards warnings, +and throws `std::runtime_error` on the first error with the existing `path:line:` +format. Use `ParseFileWithDiagnostics` to see skipped syntax. Resource failures +such as allocation errors may still throw. + --- ## Supported DBC Syntax @@ -516,7 +571,8 @@ example.dbc:3: Invalid CAN ID: invalid ``` 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. +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. --- @@ -566,7 +622,7 @@ rejected. Minimum must not exceed maximum. Zero and negative factors are allowed Basic multiplexing markers `M` and `mN` are supported as described below. Overlapping signals are rejected unless their branch values differ. -Duplicate frame/signal name detection remains separate work. +Duplicate frame keys and signal names within a frame are rejected. Invalid signal definitions stop parsing with `path:line: description`, including when the signal exceeds the declared payload length. @@ -857,6 +913,7 @@ lines: - `CM_` → `DbcCommentHandler` - `VAL_` → `DbcValueDescriptionHandler` - `SG_MUL_VAL_` → `DbcUnsupportedMultiplexingHandler` +- `VERSION`, `NS_`, `BS_`, `BU_` → `DbcHeaderHandler` (also accepts attached colons) Grammar implementations live in `core/dbc_statement_handler.cpp`; their interface, context, and dispatcher live in `core/dbc_statement_handler.h`. `core/typefactory.h` @@ -878,8 +935,8 @@ RegisterType("CUSTOM_"); // after implementing MyCustomHandler 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 `BO_TX_BU_` cannot match `BO_`. -Unregistered keywords remain ignored. `SG_` and `CM_` accept spaces and tabs -after their keywords. +Unregistered keywords produce `UnsupportedStatement` warnings through +`ParseFileWithDiagnostics`. `SG_` and `CM_` accept spaces and tabs after their keywords. This factory handles statements inside DBC files. A separate format-level factory can be introduced when another file format is implemented. The decoder @@ -953,7 +1010,9 @@ Not supported yet: - extended and nested multiplexing (`SG_MUL_VAL_`, `mNM`) - named `VAL_TABLE_` tables and environment-variable value descriptions - `BA_` attributes -- `BA_DEF_` definitions +- `BA_DEF_` definitions and attribute defaults +- `SIG_VALTYPE_` floating-point signal types +- signal types/references (`SGTYPE_`, `SIG_TYPE_REF_`) and environment variables - advanced comment handling - full DBC grammar coverage - full J1939 validation @@ -961,7 +1020,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 `SG_` 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 diff --git a/changelog.md b/changelog.md index 316908a..309c2d3 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,31 @@ existing Git tag; subsequent changes are listed as unreleased. ## Unreleased +### 2026-10-11 + +#### Added + +- `ParseFileWithDiagnostics` and `DbcParseResult` with severity, stable error + code, supplied file path, physical line number, and message for each diagnostic. +- Warnings for unregistered statements, including floating-point signal types, + attributes, signal type references, environment variables, and vendor extensions. +- Quiet common DBC header handlers registered through TypeFactory; `NS_` symbol + declarations do not produce unsupported-statement warnings. +- Regression tests for warning locations, header handling, immediate/deferred + errors, file errors, empty results on failure, and legacy exception compatibility. + +#### Changed + +- Kept `ParseFile` compatible while sharing parsing with the diagnostic API. + Parsing stops at the first error and never returns a partial database. +- Deferred value-description and multiplexing errors carry structured source + locations without extracting them from exception messages. +- Documented supported syntax, warning behavior, diagnostic codes, and limitations. +- Audited diagnostic coverage and added unsupported-statement variants, namespace + termination, formatting/path handling, first-error stopping, deferred diagnostic + order, duplicate/overlap errors, and supported decoding preservation tests. + Linux file-read errors and legacy file-error messages are checked explicitly. + ### 2026-10-07 #### Added diff --git a/core/core_files.pri b/core/core_files.pri index 0fb9f27..da5a3df 100644 --- a/core/core_files.pri +++ b/core/core_files.pri @@ -7,6 +7,7 @@ SOURCES += \ $$PWD/tree_node.cpp HEADERS += \ + $$PWD/dbc_diagnostic.h \ $$PWD/multiplexing.h \ $$PWD/dbc_database.h \ $$PWD/dbc_decode_builder.h \ diff --git a/core/dbc_diagnostic.h b/core/dbc_diagnostic.h new file mode 100644 index 0000000..6eb1f11 --- /dev/null +++ b/core/dbc_diagnostic.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +#ifndef DBC_DIAGNOSTIC_H +#define DBC_DIAGNOSTIC_H + +#include "dbc_database.h" +#include +#include +#include + +enum class DbcDiagnosticSeverity { + Warning, + Error +}; + +/** Stable categories; messages provide the details. */ +enum class DbcDiagnosticCode { + FileOpenError, + FileReadError, + InvalidStatement, + InvalidValueDescription, + InvalidMultiplexing, + UnsupportedStatement +}; + +struct DbcDiagnostic { + DbcDiagnosticSeverity severity; + DbcDiagnosticCode code; + std::string filePath; + std::size_t lineNumber; // One-based physical line; zero for file-level errors. + std::string message; +}; + +struct DbcParseResult { + DbcDatabase database; + std::vector diagnostics; + + bool HasErrors() const { + for (const DbcDiagnostic &diagnostic : diagnostics) { + if (diagnostic.severity == DbcDiagnosticSeverity::Error) + return true; + } + return false; + } +}; + +#endif /* DBC_DIAGNOSTIC_H */ diff --git a/core/dbc_parser.cpp b/core/dbc_parser.cpp index ee10755..ea668d8 100644 --- a/core/dbc_parser.cpp +++ b/core/dbc_parser.cpp @@ -14,17 +14,47 @@ #include "text_utils.h" #include +#include #include +#include + +namespace { + DbcDiagnosticCode StatementErrorCode(const std::string &keyword) { + if (keyword == "SG_MUL_VAL_") + return DbcDiagnosticCode::UnsupportedStatement; + if (keyword == "VAL_") + return DbcDiagnosticCode::InvalidValueDescription; + return DbcDiagnosticCode::InvalidStatement; + } +} DbcDatabase DbcParser::ParseFile(const std::string &filePath) const { + DbcParseResult result = ParseFileWithDiagnostics(filePath); + for (const DbcDiagnostic &diagnostic : result.diagnostics) { + if (diagnostic.severity == DbcDiagnosticSeverity::Error) { + if (diagnostic.lineNumber == 0U) + throw std::runtime_error(diagnostic.message); + throw std::runtime_error(diagnostic.filePath + ":" + + std::to_string(diagnostic.lineNumber) + ": " + diagnostic.message); + } + } + return std::move(result.database); +} + +DbcParseResult DbcParser::ParseFileWithDiagnostics(const std::string &filePath) const { + DbcParseResult result; std::ifstream input(filePath.c_str()); - if (!input.is_open()) - throw std::runtime_error("Failed to open DBC file: " + filePath); + if (!input.is_open()) { + result.diagnostics.push_back({DbcDiagnosticSeverity::Error, + DbcDiagnosticCode::FileOpenError, filePath, 0U, + "Failed to open DBC file: " + filePath}); + return result; + } DbcDatabase database; DbcParseContext context{database, nullptr}; const DbcStatementDispatcher dispatcher; - + bool inNamespace = false; std::size_t lineNumber = 0U; std::string line; while (std::getline(input, line)) { @@ -33,16 +63,48 @@ DbcDatabase DbcParser::ParseFile(const std::string &filePath) const { if (line.empty()) continue; + std::istringstream tokens(line); + std::string keyword; + std::string argument; + tokens >> keyword; + const bool hasArgument = static_cast(tokens >> argument); + if (inNamespace && !hasArgument && keyword != "BO_" && keyword != "SG_" && + keyword != "BS_" && keyword != "BS_:" && + keyword != "BU_" && keyword != "BU_:") + continue; // NS_ lists syntax symbols; BO_, SG_, BS_ and BU_ end the list. + inNamespace = keyword == "NS_" || keyword == "NS_:"; + try { context.lineNumber = lineNumber; - dispatcher.Dispatch(line, context); + if (!dispatcher.Dispatch(line, context)) { + result.diagnostics.push_back({DbcDiagnosticSeverity::Warning, + DbcDiagnosticCode::UnsupportedStatement, + filePath, lineNumber, + "Unsupported statement '" + keyword + + "' is ignored; decoding or metadata may be incomplete."}); + } } catch (const std::exception &error) { - throw std::runtime_error(filePath + ":" + std::to_string(lineNumber) + - ": " + error.what()); + result.diagnostics.push_back({DbcDiagnosticSeverity::Error, + StatementErrorCode(keyword), filePath, + lineNumber, error.what()}); + return result; } } - context.ResolveValueDescriptions(filePath); - context.ValidateMultiplexing(filePath); - return database; + if (input.bad() || !input.eof()) { + result.diagnostics.push_back({DbcDiagnosticSeverity::Error, + DbcDiagnosticCode::FileReadError, filePath, 0U, + "Failed to read DBC file: " + filePath}); + return result; + } + + try { + context.ResolveValueDescriptions(filePath); + context.ValidateMultiplexing(filePath); + } catch (const DbcDiagnosticError &error) { + result.diagnostics.push_back(error.diagnostic); + return result; + } + result.database = std::move(database); + return result; } diff --git a/core/dbc_parser.h b/core/dbc_parser.h index 8cfaac2..2a3ef2f 100644 --- a/core/dbc_parser.h +++ b/core/dbc_parser.h @@ -14,7 +14,7 @@ #include -#include "dbc_database.h" +#include "dbc_diagnostic.h" /** * @brief Minimal DBC parser. @@ -27,9 +27,8 @@ * - basic M / mN multiplexing * - VAL_ signal value descriptions * - * Ignores: - * - attributes - * - named VAL_TABLE_ tables + * Reports unsupported statements as warnings, except SG_MUL_VAL_ which is + * an error. VERSION, NS_, BS_, BU_ and NS_ symbol declarations stay quiet. */ class DbcParser { public: @@ -44,6 +43,14 @@ public: */ DbcDatabase ParseFile(const std::string &filePath) const; + /** + * @brief Parse with warnings and a structured first error instead of throwing. + * @return Valid database with diagnostics; empty database on error. + * File errors use line zero; statement errors use physical one-based lines. + * Warnings indicate ignored syntax and possible incomplete decoding. + */ + DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const; + }; #endif /* DBC_PARSER_H */ diff --git a/core/dbc_statement_handler.cpp b/core/dbc_statement_handler.cpp index 8a44792..c72cb7c 100644 --- a/core/dbc_statement_handler.cpp +++ b/core/dbc_statement_handler.cpp @@ -372,6 +372,13 @@ void DbcCommentHandler::Handle(const std::string &line, DbcParseContext &context } DbcStatementDispatcher::DbcStatementDispatcher() { + RegisterType("VERSION"); + RegisterType("NS_"); + RegisterType("NS_:"); + RegisterType("BS_"); + RegisterType("BS_:"); + RegisterType("BU_"); + RegisterType("BU_:"); RegisterType("SG_MUL_VAL_"); RegisterType("BO_"); RegisterType("SG_"); @@ -379,6 +386,8 @@ DbcStatementDispatcher::DbcStatementDispatcher() { RegisterType("VAL_"); } +void DbcHeaderHandler::Handle(const std::string &, DbcParseContext &) const {} + bool DbcStatementDispatcher::Dispatch(const std::string &line, DbcParseContext &context) const { std::istringstream stream(line); @@ -434,7 +443,8 @@ void DbcParseContext::ResolveValueDescriptions(const std::string &filePath) { throw std::runtime_error("Duplicate VAL_ value key for signal: " + pending.signalName); } } catch (const std::exception &error) { - throw std::runtime_error(filePath + ":" + std::to_string(pending.lineNumber) + ": " + error.what()); + throw DbcDiagnosticError(DbcDiagnosticCode::InvalidValueDescription, + filePath, pending.lineNumber, error.what()); } } } @@ -479,8 +489,9 @@ namespace { if (signal.multiplexing.role != MultiplexRole::Selector) continue; if (selector != nullptr || signal.isSigned) - throw std::runtime_error(filePath + ":" + std::to_string(lines[index]) + - ": Multiplexing requires one unsigned selector per frame."); + throw DbcDiagnosticError(DbcDiagnosticCode::InvalidMultiplexing, + filePath, lines[index], + "Multiplexing requires one unsigned selector per frame."); selector = &signal; } return selector; @@ -512,7 +523,8 @@ void DbcParseContext::ValidateMultiplexing(const std::string &filePath) const { error = "Signals overlap without mutually exclusive multiplexing conditions."; } if (!error.empty()) - throw std::runtime_error(filePath + ":" + std::to_string(signalLines[frameIndex][index]) + ": " + error); + throw DbcDiagnosticError(DbcDiagnosticCode::InvalidMultiplexing, + filePath, signalLines[frameIndex][index], error); } } } diff --git a/core/dbc_statement_handler.h b/core/dbc_statement_handler.h index 9b141bf..c18e3cf 100644 --- a/core/dbc_statement_handler.h +++ b/core/dbc_statement_handler.h @@ -3,7 +3,9 @@ #define DBC_STATEMENT_HANDLER_H #include "dbc_database.h" +#include "dbc_diagnostic.h" #include "typefactory.h" +#include #include #include @@ -15,6 +17,17 @@ struct PendingValueDescriptions { std::size_t lineNumber; }; +/** Carries deferred validation locations without parsing exception text. */ +class DbcDiagnosticError : public std::runtime_error { +public: + DbcDiagnosticError(DbcDiagnosticCode code, const std::string &filePath, + std::size_t lineNumber, const std::string &message) + : std::runtime_error(filePath + ":" + std::to_string(lineNumber) + ": " + message), + diagnostic{DbcDiagnosticSeverity::Error, code, filePath, lineNumber, message} {} + + DbcDiagnostic diagnostic; +}; + /** Mutable state belonging to one file parse. Handlers do not retain it. */ struct DbcParseContext { DbcDatabase &database; @@ -68,6 +81,12 @@ public: void Handle(const std::string &line, DbcParseContext &context) const override; }; +/** Common header metadata does not change the supported decode definitions. */ +class DbcHeaderHandler : public DbcStatementHandler { +public: + void Handle(const std::string &line, DbcParseContext &context) const override; +}; + /** Exact-key dispatch to handlers created once per registration via TypeFactory. */ class DbcStatementDispatcher { public: diff --git a/docs/dbcframework.tag b/docs/dbcframework.tag index 5d274c9..ac810c0 100644 --- a/docs/dbcframework.tag +++ b/docs/dbcframework.tag @@ -47,7 +47,6 @@ dbc_parser.h core/ dbc__parser_8h.html - dbc_database.h DbcParser @@ -183,11 +182,24 @@ (const DecodeDatabase &database, const RawCanFrame &frame) const + + DbcDiagnostic + structDbcDiagnostic.html + + + DbcDiagnosticError + classDbcDiagnosticError.html + DbcFrameHandler classDbcFrameHandler.html DbcStatementHandler + + DbcHeaderHandler + classDbcHeaderHandler.html + DbcStatementHandler + DbcParseContext structDbcParseContext.html @@ -202,6 +214,17 @@ aef72826942c9095d653fafa435855e56 (const std::string &filePath) const + + DbcParseResult + ParseFileWithDiagnostics + classDbcParser.html + a0e915ce79c2e3d4c95a5aaf2bf0409bc + (const std::string &filePath) const + + + + DbcParseResult + structDbcParseResult.html DbcSignalHandler diff --git a/docs/doxygen_warnings.log b/docs/doxygen_warnings.log index fadf0cd..e271c1f 100644 --- a/docs/doxygen_warnings.log +++ b/docs/doxygen_warnings.log @@ -1,25 +1,38 @@ -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:53: warning: Compound DbcCommentHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:37: warning: Compound DbcFrameHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:45: warning: Compound DbcSignalHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:31: warning: Compound DbcStatementHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:66: warning: Compound DbcUnsupportedMultiplexingHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:61: warning: Compound DbcValueDescriptionHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:10: warning: Compound PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:66: warning: Compound DbcCommentHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:25: warning: Compound DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:50: warning: Compound DbcFrameHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:33: warning: Compound DbcParseResult is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:58: warning: Compound DbcSignalHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:44: warning: Compound DbcStatementHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:79: warning: Compound DbcUnsupportedMultiplexingHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:74: warning: Compound DbcValueDescriptionHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:12: warning: Compound PendingValueDescriptions is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_decoder.h:32: warning: Member SignalDecodeStatus (enumeration) of file dbc_decoder.h is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/examples/main.cpp:100: warning: Member main(int argc, char *argv[]) (function) of file examples/main.cpp is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/README.md:1450: warning: end of comment block while expecting command -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:55: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcCommentHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:39: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcFrameHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:26: warning: Member ValidateMultiplexing(const std::string &filePath) const (function) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:28: warning: Member ResolveValueDescriptions(const std::string &filePath) (function) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:20: warning: Member database (variable) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:21: warning: Member currentFrame (variable) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:22: warning: Member lineNumber (variable) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:23: warning: Member pendingValues (variable) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:25: warning: Member signalLines (variable) of struct DbcParseContext is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:47: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcSignalHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:77: warning: Member RegisterType(const std::string &keyword) (function) of class DbcStatementDispatcher is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:34: warning: Member Handle(const std::string &line, DbcParseContext &context) const =0 (function) of class DbcStatementHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/README.md:1509: warning: end of comment block while expecting command +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:68: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcCommentHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:26: warning: Member severity (variable) of struct DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:27: warning: Member code (variable) of struct DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:28: warning: Member filePath (variable) of struct DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:29: warning: Member lineNumber (variable) of struct DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:30: warning: Member message (variable) of struct DbcDiagnostic is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:23: warning: Member DbcDiagnosticError(DbcDiagnosticCode code, const std::string &filePath, std::size_t lineNumber, const std::string &message) (function) of class DbcDiagnosticError is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:28: warning: Member diagnostic (variable) of class DbcDiagnosticError is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:52: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcFrameHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:87: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcHeaderHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:39: warning: Member ValidateMultiplexing(const std::string &filePath) const (function) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:41: warning: Member ResolveValueDescriptions(const std::string &filePath) (function) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:33: warning: Member database (variable) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:34: warning: Member currentFrame (variable) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:35: warning: Member lineNumber (variable) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:36: warning: Member pendingValues (variable) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:38: warning: Member signalLines (variable) of struct DbcParseContext is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:37: warning: Member HasErrors() const (function) of struct DbcParseResult is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:34: warning: Member database (variable) of struct DbcParseResult is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_diagnostic.h:35: warning: Member diagnostics (variable) of struct DbcParseResult is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:60: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcSignalHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:96: warning: Member RegisterType(const std::string &keyword) (function) of class DbcStatementDispatcher is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:47: warning: Member Handle(const std::string &line, DbcParseContext &context) const =0 (function) of class DbcStatementHandler is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:13: warning: Member Column (enumeration) of class DbcTreeModel is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:24: warning: Member Role (enumeration) of class DbcTreeModel is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:36: warning: Member DbcTreeModel(QObject *parent=nullptr) (function) of class DbcTreeModel is not documented. @@ -31,8 +44,8 @@ /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:42: warning: Member data(const QModelIndex &index, int role=Qt::DisplayRole) const override (function) of class DbcTreeModel is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:43: warning: Member headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override (function) of class DbcTreeModel is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/qt/dbc_tree_model.h:44: warning: Member flags(const QModelIndex &index) const override (function) of class DbcTreeModel is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:68: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcUnsupportedMultiplexingHandler is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:63: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcValueDescriptionHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:81: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcUnsupportedMultiplexingHandler is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:76: warning: Member Handle(const std::string &line, DbcParseContext &context) const override (function) of class DbcValueDescriptionHandler is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/decode_database.h:110: warning: Member frames (variable) of struct DecodeDatabase is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/decode_database.h:111: warning: Member frameIndexByKey (variable) of struct DecodeDatabase is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_decoder.h:48: warning: Member status (variable) of struct DecodedSignalValue is not documented. @@ -44,11 +57,11 @@ /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/decode_database.h:99: warning: Member operator()(const FrameKey &key) const (function) of struct FrameKeyHasher is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/multiplexing.h:15: warning: Member role (variable) of struct Multiplexing is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/multiplexing.h:16: warning: Member value (variable) of struct Multiplexing is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:11: warning: Member canId (variable) of struct PendingValueDescriptions is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:12: warning: Member isExtended (variable) of struct PendingValueDescriptions is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:13: warning: Member signalName (variable) of struct PendingValueDescriptions is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:14: warning: Member descriptions (variable) of struct PendingValueDescriptions is not documented. -/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:15: warning: Member lineNumber (variable) of struct PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:13: warning: Member canId (variable) of struct PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:14: warning: Member isExtended (variable) of struct PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:15: warning: Member signalName (variable) of struct PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:16: warning: Member descriptions (variable) of struct PendingValueDescriptions is not documented. +/home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/dbc_statement_handler.h:17: warning: Member lineNumber (variable) of struct PendingValueDescriptions is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/signal_info.h:25: warning: Member multiplexing (variable) of struct SignalInfo is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/typefactory.h:61: warning: Member BasePtr (typedef) of class TypeFactory is not documented. /home/deeaitch/work/3.projects/git.himro.ca/automotive/dbc/core/typefactory.h:62: warning: Member CreatorFn (typedef) of class TypeFactory is not documented. diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 107b0a9..b4d65fe 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -99,30 +99,34 @@ $(document).ready(function(){initNavTree('annotated.html',''); initResizable();  CDbcDatabaseParsed DBC content stored in a simple internal form  CDbcDecodeBuilderConverts parsed DBC data into runtime decode database  CDbcDecoderRuntime CAN decoder using prebuilt decode database - CDbcFrameHandler - CDbcParseContext - CDbcParserMinimal DBC parser - CDbcSignalHandler - CDbcStatementDispatcher - CDbcStatementHandler - CDbcTreeBuilderBuilds a simple tree from parsed DBC database - CDbcTreeModel - CDbcUnsupportedMultiplexingHandler - CDbcValueDescriptionHandler - CDecodeDatabaseRuntime decode database with fast lookup by CAN ID - CDecodedFrameValueFully decoded frame - CDecodedSignalValueOne decoded signal value - CDecodeFrameRuntime-ready frame definition - CDecodeSignalRuntime-ready signal definition - CFrameInfoDescribes one CAN frame from a DBC file - CFrameKeyKey for fast frame lookup - CFrameKeyHasherHasher for frame key - CMultiplexing - CPendingValueDescriptions - CRawCanFrameRaw CAN frame used for runtime or trace decoding - CSignalInfoDescribes one signal inside a DBC frame - CTreeNodeTree node for later use in model/view or other hierarchy consumers - CTypeFactoryRegistry-based factory for creating objects by runtime identifier + CDbcDiagnostic + CDbcDiagnosticError + CDbcFrameHandler + CDbcHeaderHandler + CDbcParseContext + CDbcParserMinimal DBC parser + CDbcParseResult + CDbcSignalHandler + CDbcStatementDispatcher + CDbcStatementHandler + CDbcTreeBuilderBuilds a simple tree from parsed DBC database + CDbcTreeModel + CDbcUnsupportedMultiplexingHandler + CDbcValueDescriptionHandler + CDecodeDatabaseRuntime decode database with fast lookup by CAN ID + CDecodedFrameValueFully decoded frame + CDecodedSignalValueOne decoded signal value + CDecodeFrameRuntime-ready frame definition + CDecodeSignalRuntime-ready signal definition + CFrameInfoDescribes one CAN frame from a DBC file + CFrameKeyKey for fast frame lookup + CFrameKeyHasherHasher for frame key + CMultiplexing + CPendingValueDescriptions + CRawCanFrameRaw CAN frame used for runtime or trace decoding + CSignalInfoDescribes one signal inside a DBC frame + CTreeNodeTree node for later use in model/view or other hierarchy consumers + CTypeFactoryRegistry-based factory for creating objects by runtime identifier diff --git a/docs/html/annotated_dup.js b/docs/html/annotated_dup.js index 73f03e8..a227194 100644 --- a/docs/html/annotated_dup.js +++ b/docs/html/annotated_dup.js @@ -4,9 +4,13 @@ var annotated_dup = [ "DbcDatabase", "structDbcDatabase.html", "structDbcDatabase" ], [ "DbcDecodeBuilder", "classDbcDecodeBuilder.html", "classDbcDecodeBuilder" ], [ "DbcDecoder", "classDbcDecoder.html", "classDbcDecoder" ], + [ "DbcDiagnostic", "structDbcDiagnostic.html", null ], + [ "DbcDiagnosticError", "classDbcDiagnosticError.html", null ], [ "DbcFrameHandler", "classDbcFrameHandler.html", null ], + [ "DbcHeaderHandler", "classDbcHeaderHandler.html", null ], [ "DbcParseContext", "structDbcParseContext.html", null ], [ "DbcParser", "classDbcParser.html", "classDbcParser" ], + [ "DbcParseResult", "structDbcParseResult.html", null ], [ "DbcSignalHandler", "classDbcSignalHandler.html", null ], [ "DbcStatementDispatcher", "classDbcStatementDispatcher.html", "classDbcStatementDispatcher" ], [ "DbcStatementHandler", "classDbcStatementHandler.html", null ], diff --git a/docs/html/classDbcCommentHandler.html b/docs/html/classDbcCommentHandler.html index 080ffec..0bf77e9 100644 --- a/docs/html/classDbcCommentHandler.html +++ b/docs/html/classDbcCommentHandler.html @@ -111,7 +111,7 @@ Public Member Functions

Detailed Description

-

Definition at line 53 of file dbc_statement_handler.h.

+

Definition at line 66 of file dbc_statement_handler.h.

Member Function Documentation

◆ Handle()

diff --git a/docs/html/classDbcDiagnosticError-members.html b/docs/html/classDbcDiagnosticError-members.html new file mode 100644 index 0000000..b457fff --- /dev/null +++ b/docs/html/classDbcDiagnosticError-members.html @@ -0,0 +1,110 @@ + + + + + + + +DBC Framework: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
DBC Framework +
+
DBC parsing and CAN signal decoding framework
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
DbcDiagnosticError Member List
+
+
+ +

This is the complete list of members for DbcDiagnosticError, including all inherited members.

+ + + +
DbcDiagnosticError(DbcDiagnosticCode code, const std::string &filePath, std::size_t lineNumber, const std::string &message) (defined in DbcDiagnosticError)DbcDiagnosticErrorinline
diagnostic (defined in DbcDiagnosticError)DbcDiagnosticError
+
+ + + + diff --git a/docs/html/classDbcDiagnosticError.html b/docs/html/classDbcDiagnosticError.html new file mode 100644 index 0000000..91e3d36 --- /dev/null +++ b/docs/html/classDbcDiagnosticError.html @@ -0,0 +1,205 @@ + + + + + + + +DBC Framework: DbcDiagnosticError Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
DBC Framework +
+
DBC parsing and CAN signal decoding framework
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
DbcDiagnosticError Class Reference
+
+
+ +

#include <dbc_statement_handler.h>

+
+ + Inheritance diagram for DbcDiagnosticError:
+
+
+ + + + + +

+Public Member Functions

 DbcDiagnosticError (DbcDiagnosticCode code, const std::string &filePath, std::size_t lineNumber, const std::string &message)
 
+ + + +

+Public Attributes

DbcDiagnostic diagnostic
 
+

Detailed Description

+

Carries deferred validation locations without parsing exception text.

+ +

Definition at line 21 of file dbc_statement_handler.h.

+

Constructor & Destructor Documentation

+ +

◆ DbcDiagnosticError()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DbcDiagnosticError::DbcDiagnosticError (DbcDiagnosticCode code,
const std::string & filePath,
std::size_t lineNumber,
const std::string & message 
)
+
+inline
+
+ +

Definition at line 23 of file dbc_statement_handler.h.

+ +
+
+

Member Data Documentation

+ +

◆ diagnostic

+ +
+
+ + + + +
DbcDiagnostic DbcDiagnosticError::diagnostic
+
+ +

Definition at line 28 of file dbc_statement_handler.h.

+ +
+
+
The documentation for this class was generated from the following file: +
+
+ + + + diff --git a/docs/html/classDbcDiagnosticError__inherit__graph.map b/docs/html/classDbcDiagnosticError__inherit__graph.map new file mode 100644 index 0000000..8c02ffc --- /dev/null +++ b/docs/html/classDbcDiagnosticError__inherit__graph.map @@ -0,0 +1,7 @@ + + + + + + + diff --git a/docs/html/classDbcDiagnosticError__inherit__graph.md5 b/docs/html/classDbcDiagnosticError__inherit__graph.md5 new file mode 100644 index 0000000..c3b9861 --- /dev/null +++ b/docs/html/classDbcDiagnosticError__inherit__graph.md5 @@ -0,0 +1 @@ +2dc86eee0052fd3c477fa415ad03afd3 \ No newline at end of file diff --git a/docs/html/classDbcDiagnosticError__inherit__graph.svg b/docs/html/classDbcDiagnosticError__inherit__graph.svg new file mode 100644 index 0000000..0c8cd1b --- /dev/null +++ b/docs/html/classDbcDiagnosticError__inherit__graph.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + +DbcDiagnosticError + + +Node1 + + +DbcDiagnosticError ++ +diagnostic ++ +DbcDiagnosticError() + + + + + + + + + +Node2 + + +std::runtime_error +  +  + + + + + + + + +Node2->Node1 + + + + + + + + +Node3 + + +std::exception +  +  + + + + + + + + +Node3->Node2 + + + + + + + + + + + + + diff --git a/docs/html/classDbcDiagnosticError__inherit__graph_org.svg b/docs/html/classDbcDiagnosticError__inherit__graph_org.svg new file mode 100644 index 0000000..71ea269 --- /dev/null +++ b/docs/html/classDbcDiagnosticError__inherit__graph_org.svg @@ -0,0 +1,75 @@ + + + + + + +DbcDiagnosticError + + +Node1 + + +DbcDiagnosticError ++ +diagnostic ++ +DbcDiagnosticError() + + + + + + + + + +Node2 + + +std::runtime_error +  +  + + + + + + + + +Node2->Node1 + + + + + + + + +Node3 + + +std::exception +  +  + + + + + + + + +Node3->Node2 + + + + + + + + diff --git a/docs/html/classDbcFrameHandler.html b/docs/html/classDbcFrameHandler.html index 58440f4..d6f796b 100644 --- a/docs/html/classDbcFrameHandler.html +++ b/docs/html/classDbcFrameHandler.html @@ -111,7 +111,7 @@ Public Member Functions

Detailed Description

-

Definition at line 37 of file dbc_statement_handler.h.

+

Definition at line 50 of file dbc_statement_handler.h.

Member Function Documentation

◆ Handle()

diff --git a/docs/html/classDbcHeaderHandler-members.html b/docs/html/classDbcHeaderHandler-members.html new file mode 100644 index 0000000..6b7cde0 --- /dev/null +++ b/docs/html/classDbcHeaderHandler-members.html @@ -0,0 +1,110 @@ + + + + + + + +DBC Framework: Member List + + + + + + + + + + + + + +
+
+ + + + + + +
+
DBC Framework +
+
DBC parsing and CAN signal decoding framework
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+
DbcHeaderHandler Member List
+
+
+ +

This is the complete list of members for DbcHeaderHandler, including all inherited members.

+ + + +
Handle(const std::string &line, DbcParseContext &context) const override (defined in DbcHeaderHandler)DbcHeaderHandlervirtual
~DbcStatementHandler()=default (defined in DbcStatementHandler)DbcStatementHandlervirtual
+
+ + + + diff --git a/docs/html/classDbcHeaderHandler.html b/docs/html/classDbcHeaderHandler.html new file mode 100644 index 0000000..428ccca --- /dev/null +++ b/docs/html/classDbcHeaderHandler.html @@ -0,0 +1,173 @@ + + + + + + + +DBC Framework: DbcHeaderHandler Class Reference + + + + + + + + + + + + + +
+
+ + + + + + +
+
DBC Framework +
+
DBC parsing and CAN signal decoding framework
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
+
+ +
+ +
DbcHeaderHandler Class Reference
+
+
+ +

#include <dbc_statement_handler.h>

+
+ + Inheritance diagram for DbcHeaderHandler:
+
+
+ + + + + +

+Public Member Functions

void Handle (const std::string &line, DbcParseContext &context) const override
 
+

Detailed Description

+

Common header metadata does not change the supported decode definitions.

+ +

Definition at line 85 of file dbc_statement_handler.h.

+

Member Function Documentation

+ +

◆ Handle()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
void DbcHeaderHandler::Handle (const std::string & line,
DbcParseContext & context 
) const
+
+overridevirtual
+
+ +

Implements DbcStatementHandler.

+ +

Definition at line 389 of file dbc_statement_handler.cpp.

+ +
+
+
The documentation for this class was generated from the following files: +
+
+ + + + diff --git a/docs/html/classDbcHeaderHandler__inherit__graph.map b/docs/html/classDbcHeaderHandler__inherit__graph.map new file mode 100644 index 0000000..bc470b7 --- /dev/null +++ b/docs/html/classDbcHeaderHandler__inherit__graph.map @@ -0,0 +1,5 @@ + + + + + diff --git a/docs/html/classDbcHeaderHandler__inherit__graph.md5 b/docs/html/classDbcHeaderHandler__inherit__graph.md5 new file mode 100644 index 0000000..b3ba4b6 --- /dev/null +++ b/docs/html/classDbcHeaderHandler__inherit__graph.md5 @@ -0,0 +1 @@ +b906816fb2675b5eef3174ec5bac8679 \ No newline at end of file diff --git a/docs/html/classDbcHeaderHandler__inherit__graph.svg b/docs/html/classDbcHeaderHandler__inherit__graph.svg new file mode 100644 index 0000000..77c8390 --- /dev/null +++ b/docs/html/classDbcHeaderHandler__inherit__graph.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + +DbcHeaderHandler + + +Node1 + + +DbcHeaderHandler +  ++ +Handle() + + + + + + + + +Node2 + + +DbcStatementHandler +  ++ +~DbcStatementHandler() ++ +Handle() + + + + + + + + +Node2->Node1 + + + + + + + + + + + + + diff --git a/docs/html/classDbcHeaderHandler__inherit__graph_org.svg b/docs/html/classDbcHeaderHandler__inherit__graph_org.svg new file mode 100644 index 0000000..1575629 --- /dev/null +++ b/docs/html/classDbcHeaderHandler__inherit__graph_org.svg @@ -0,0 +1,53 @@ + + + + + + +DbcHeaderHandler + + +Node1 + + +DbcHeaderHandler +  ++ +Handle() + + + + + + + + +Node2 + + +DbcStatementHandler +  ++ +~DbcStatementHandler() ++ +Handle() + + + + + + + + +Node2->Node1 + + + + + + + + diff --git a/docs/html/classDbcParser-members.html b/docs/html/classDbcParser-members.html index b14ed11..1b5126d 100644 --- a/docs/html/classDbcParser-members.html +++ b/docs/html/classDbcParser-members.html @@ -97,6 +97,7 @@ $(document).ready(function(){initNavTree('classDbcParser.html',''); initResizabl

This is the complete list of members for DbcParser, including all inherited members.

+
ParseFile(const std::string &filePath) constDbcParser
ParseFileWithDiagnostics(const std::string &filePath) constDbcParser
diff --git a/docs/html/classDbcParser.html b/docs/html/classDbcParser.html index cce55d7..c562041 100644 --- a/docs/html/classDbcParser.html +++ b/docs/html/classDbcParser.html @@ -107,6 +107,9 @@ Public Member Functions DbcDatabase ParseFile (const std::string &filePath) const  Parse DBC file.
  +DbcParseResult ParseFileWithDiagnostics (const std::string &filePath) const + Parse with warnings and a structured first error instead of throwing.
+ 

Detailed Description

Minimal DBC parser.

@@ -118,12 +121,9 @@ Public Member Functions
  • basic M / mN multiplexing
  • VAL_ signal value descriptions
  • -

    Ignores:

      -
    • attributes
    • -
    • named VAL_TABLE_ tables
    • -
    +

    Reports unsupported statements as warnings, except SG_MUL_VAL_ which is an error. VERSION, NS_, BS_, BU_ and NS_ symbol declarations stay quiet.

    -

    Definition at line 34 of file dbc_parser.h.

    +

    Definition at line 33 of file dbc_parser.h.

    Member Function Documentation

    ◆ ParseFile()

    @@ -156,9 +156,36 @@ Public Member Functions -

    Definition at line 19 of file dbc_parser.cpp.

    +

    Definition at line 31 of file dbc_parser.cpp.

    -

    References DbcStatementDispatcher::Dispatch().

    +

    References ParseFileWithDiagnostics().

    + + + + +

    ◆ ParseFileWithDiagnostics()

    + +
    +
    + + + + + + + + +
    DbcParseResult DbcParser::ParseFileWithDiagnostics (const std::string & filePath) const
    +
    + +

    Parse with warnings and a structured first error instead of throwing.

    +
    Returns
    Valid database with diagnostics; empty database on error. File errors use line zero; statement errors use physical one-based lines. Warnings indicate ignored syntax and possible incomplete decoding.
    + +

    Definition at line 44 of file dbc_parser.cpp.

    + +

    References DbcStatementDispatcher::Dispatch().

    + +

    Referenced by ParseFile().

    diff --git a/docs/html/classDbcParser.js b/docs/html/classDbcParser.js index 46247c3..faf4277 100644 --- a/docs/html/classDbcParser.js +++ b/docs/html/classDbcParser.js @@ -1,4 +1,5 @@ var classDbcParser = [ - [ "ParseFile", "classDbcParser.html#aef72826942c9095d653fafa435855e56", null ] + [ "ParseFile", "classDbcParser.html#aef72826942c9095d653fafa435855e56", null ], + [ "ParseFileWithDiagnostics", "classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc", null ] ]; \ No newline at end of file diff --git a/docs/html/classDbcSignalHandler.html b/docs/html/classDbcSignalHandler.html index 3fb341b..00a94e2 100644 --- a/docs/html/classDbcSignalHandler.html +++ b/docs/html/classDbcSignalHandler.html @@ -111,7 +111,7 @@ Public Member Functions

    Detailed Description

    -

    Definition at line 45 of file dbc_statement_handler.h.

    +

    Definition at line 58 of file dbc_statement_handler.h.

    Member Function Documentation

    ◆ Handle()

    diff --git a/docs/html/classDbcStatementDispatcher.html b/docs/html/classDbcStatementDispatcher.html index 5c2d586..65672b4 100644 --- a/docs/html/classDbcStatementDispatcher.html +++ b/docs/html/classDbcStatementDispatcher.html @@ -110,7 +110,7 @@ Public Member Functions

    Detailed Description

    Exact-key dispatch to handlers created once per registration via TypeFactory.

    -

    Definition at line 72 of file dbc_statement_handler.h.

    +

    Definition at line 91 of file dbc_statement_handler.h.

    Constructor & Destructor Documentation

    ◆ DbcStatementDispatcher()

    @@ -158,7 +158,7 @@ template<class Handler >
    -

    Definition at line 77 of file dbc_statement_handler.h.

    +

    Definition at line 96 of file dbc_statement_handler.h.

    @@ -189,9 +189,9 @@ template<class Handler >

    Returns false for an unregistered keyword; input must be trimmed.

    -

    Definition at line 382 of file dbc_statement_handler.cpp.

    +

    Definition at line 391 of file dbc_statement_handler.cpp.

    -

    Referenced by DbcParser::ParseFile().

    +

    Referenced by DbcParser::ParseFileWithDiagnostics().

    diff --git a/docs/html/classDbcStatementHandler.html b/docs/html/classDbcStatementHandler.html index 3bbc66a..df2826e 100644 --- a/docs/html/classDbcStatementHandler.html +++ b/docs/html/classDbcStatementHandler.html @@ -112,7 +112,7 @@ virtual void Handle (c

    Detailed Description

    -

    Definition at line 31 of file dbc_statement_handler.h.

    +

    Definition at line 44 of file dbc_statement_handler.h.


    The documentation for this class was generated from the following file: diff --git a/docs/html/classDbcStatementHandler__inherit__graph.map b/docs/html/classDbcStatementHandler__inherit__graph.map index 9b5b7b2..d40520d 100644 --- a/docs/html/classDbcStatementHandler__inherit__graph.map +++ b/docs/html/classDbcStatementHandler__inherit__graph.map @@ -1,15 +1,17 @@ - + - + - + - - - - - - - + + + + + + + + + diff --git a/docs/html/classDbcStatementHandler__inherit__graph.md5 b/docs/html/classDbcStatementHandler__inherit__graph.md5 index 50fc735..e4afaae 100644 --- a/docs/html/classDbcStatementHandler__inherit__graph.md5 +++ b/docs/html/classDbcStatementHandler__inherit__graph.md5 @@ -1 +1 @@ -88ac50356cfeaecb76401f7ba1a3e39c \ No newline at end of file +9968b812b5276c7cad7a358f5120f96a \ No newline at end of file diff --git a/docs/html/classDbcStatementHandler__inherit__graph.svg b/docs/html/classDbcStatementHandler__inherit__graph.svg index 3f50954..d2e54f9 100644 --- a/docs/html/classDbcStatementHandler__inherit__graph.svg +++ b/docs/html/classDbcStatementHandler__inherit__graph.svg @@ -46,7 +46,7 @@ @@ -58,16 +58,16 @@ var sectionId = 'dynsection-0'; Node1 - -DbcStatementHandler -  -+ -~DbcStatementHandler() -+ -Handle() - - - + +DbcStatementHandler +  ++ +~DbcStatementHandler() ++ +Handle() + + + @@ -96,8 +96,8 @@ var sectionId = 'dynsection-0'; Node1->Node2 - - + + @@ -120,8 +120,8 @@ var sectionId = 'dynsection-0'; Node1->Node3 - - + + @@ -144,23 +144,23 @@ var sectionId = 'dynsection-0'; Node1->Node4 - - + + Node5 - - -DbcSignalHandler -  -+ -Handle() - - - + + +DbcHeaderHandler +  ++ +Handle() + + + @@ -168,24 +168,23 @@ var sectionId = 'dynsection-0'; Node1->Node5 - - + + Node6 - - -DbcUnsupportedMultiplexing -Handler -  -+ -Handle() - - - + + +DbcSignalHandler +  ++ +Handle() + + + @@ -193,23 +192,24 @@ var sectionId = 'dynsection-0'; Node1->Node6 - - + + Node7 - - -DbcValueDescriptionHandler -  -+ -Handle() - - - + + +DbcUnsupportedMultiplexing +Handler +  ++ +Handle() + + + @@ -217,8 +217,32 @@ var sectionId = 'dynsection-0'; Node1->Node7 - - + + + + + + + +Node8 + + +DbcValueDescriptionHandler +  ++ +Handle() + + + + + + + + +Node1->Node8 + + + diff --git a/docs/html/classDbcStatementHandler__inherit__graph_org.svg b/docs/html/classDbcStatementHandler__inherit__graph_org.svg index 87d2ee1..54a5175 100644 --- a/docs/html/classDbcStatementHandler__inherit__graph_org.svg +++ b/docs/html/classDbcStatementHandler__inherit__graph_org.svg @@ -4,24 +4,24 @@ - + DbcStatementHandler Node1 - -DbcStatementHandler -  -+ -~DbcStatementHandler() -+ -Handle() - - - + +DbcStatementHandler +  ++ +~DbcStatementHandler() ++ +Handle() + + + @@ -50,8 +50,8 @@ Node1->Node2 - - + + @@ -74,8 +74,8 @@ Node1->Node3 - - + + @@ -98,23 +98,23 @@ Node1->Node4 - - + + Node5 - - -DbcSignalHandler -  -+ -Handle() - - - + + +DbcHeaderHandler +  ++ +Handle() + + + @@ -122,24 +122,23 @@ Node1->Node5 - - + + Node6 - - -DbcUnsupportedMultiplexing -Handler -  -+ -Handle() - - - + + +DbcSignalHandler +  ++ +Handle() + + + @@ -147,23 +146,24 @@ Node1->Node6 - - + + Node7 - - -DbcValueDescriptionHandler -  -+ -Handle() - - - + + +DbcUnsupportedMultiplexing +Handler +  ++ +Handle() + + + @@ -171,8 +171,32 @@ Node1->Node7 - - + + + + + + + +Node8 + + +DbcValueDescriptionHandler +  ++ +Handle() + + + + + + + + +Node1->Node8 + + + diff --git a/docs/html/classDbcUnsupportedMultiplexingHandler.html b/docs/html/classDbcUnsupportedMultiplexingHandler.html index e567583..2ffee48 100644 --- a/docs/html/classDbcUnsupportedMultiplexingHandler.html +++ b/docs/html/classDbcUnsupportedMultiplexingHandler.html @@ -111,7 +111,7 @@ Public Member Functions

    Detailed Description

    -

    Definition at line 66 of file dbc_statement_handler.h.

    +

    Definition at line 79 of file dbc_statement_handler.h.

    Member Function Documentation

    ◆ Handle()

    @@ -149,7 +149,7 @@ Public Member Functions

    Implements DbcStatementHandler.

    -

    Definition at line 442 of file dbc_statement_handler.cpp.

    +

    Definition at line 452 of file dbc_statement_handler.cpp.

    diff --git a/docs/html/classDbcValueDescriptionHandler.html b/docs/html/classDbcValueDescriptionHandler.html index 4ccac29..4ced64b 100644 --- a/docs/html/classDbcValueDescriptionHandler.html +++ b/docs/html/classDbcValueDescriptionHandler.html @@ -111,7 +111,7 @@ Public Member Functions

    Detailed Description

    -

    Definition at line 61 of file dbc_statement_handler.h.

    +

    Definition at line 74 of file dbc_statement_handler.h.

    Member Function Documentation

    ◆ Handle()

    @@ -149,7 +149,7 @@ Public Member Functions

    Implements DbcStatementHandler.

    -

    Definition at line 394 of file dbc_statement_handler.cpp.

    +

    Definition at line 403 of file dbc_statement_handler.cpp.

    diff --git a/docs/html/classes.html b/docs/html/classes.html index 7315037..bdf0080 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -97,7 +97,7 @@ $(document).ready(function(){initNavTree('classes.html',''); initResizable(); })
    D
    -
    DbcCommentHandler
    DbcDatabase
    DbcDecodeBuilder
    DbcDecoder
    DbcFrameHandler
    DbcParseContext
    DbcParser
    DbcSignalHandler
    DbcStatementDispatcher
    DbcStatementHandler
    DbcTreeBuilder
    DbcTreeModel
    DbcUnsupportedMultiplexingHandler
    DbcValueDescriptionHandler
    DecodeDatabase
    DecodedFrameValue
    DecodedSignalValue
    DecodeFrame
    DecodeSignal
    +
    DbcCommentHandler
    DbcDatabase
    DbcDecodeBuilder
    DbcDecoder
    DbcDiagnostic
    DbcDiagnosticError
    DbcFrameHandler
    DbcHeaderHandler
    DbcParseContext
    DbcParser
    DbcParseResult
    DbcSignalHandler
    DbcStatementDispatcher
    DbcStatementHandler
    DbcTreeBuilder
    DbcTreeModel
    DbcUnsupportedMultiplexingHandler
    DbcValueDescriptionHandler
    DecodeDatabase
    DecodedFrameValue
    DecodedSignalValue
    DecodeFrame
    DecodeSignal
    F
    FrameInfo
    FrameKey
    FrameKeyHasher
    diff --git a/docs/html/dbc__coverage__test_8cpp_source.html b/docs/html/dbc__coverage__test_8cpp_source.html index 2606647..636d6de 100644 --- a/docs/html/dbc__coverage__test_8cpp_source.html +++ b/docs/html/dbc__coverage__test_8cpp_source.html @@ -843,17 +843,17 @@ $(document).ready(function(){initNavTree('dbc__coverage__test_8cpp_source.html',
    743 return QTest::qExec(&tests, argc, argv);
    744}
    745#include "dbc_coverage_test.moc"
    - +
    Converts parsed DBC data into runtime decode database.
    DecodeDatabase Build(const DbcDatabase &source) const
    Build runtime decode database.
    Runtime CAN decoder using prebuilt decode database.
    Definition dbc_decoder.h:72
    DecodedFrameValue Decode(const DecodeDatabase &database, const RawCanFrame &frame) const
    Decode one raw CAN frame.
    const DecodeFrame * FindFrame(const DecodeDatabase &database, std::uint32_t canId, bool isExtended) const
    Find frame definition by CAN ID.
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    Builds a simple tree from parsed DBC database.
    std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
    Build tree representation of parsed DBC data.
    - +
    Tree node for later use in model/view or other hierarchy consumers.
    Definition tree_node.h:35
    const SignalInfo * GetSignal() const
    Get signal payload if node is signal.
    Definition tree_node.cpp:64
    const TreeNode * GetChild(std::size_t index) const
    Get child by index.
    Definition tree_node.cpp:38
    @@ -874,7 +874,7 @@ $(document).ready(function(){initNavTree('dbc__coverage__test_8cpp_source.html',
    ValueType
    Signal numeric type.
    Parsed DBC content stored in a simple internal form.
    std::vector< FrameInfo > frames
    - +
    Runtime decode database with fast lookup by CAN ID.
    Runtime-ready frame definition.
    std::uint32_t pgn
    diff --git a/docs/html/dbc__diagnostic_8h_source.html b/docs/html/dbc__diagnostic_8h_source.html new file mode 100644 index 0000000..99156c7 --- /dev/null +++ b/docs/html/dbc__diagnostic_8h_source.html @@ -0,0 +1,164 @@ + + + + + + + +DBC Framework: dbc_diagnostic.h Source File + + + + + + + + + + + + + +
    +
    + + + + + + +
    +
    DBC Framework +
    +
    DBC parsing and CAN signal decoding framework
    +
    +
    + + + + + + + + +
    +
    + +
    +
    +
    + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    dbc_diagnostic.h
    +
    +
    +
    1// SPDX-License-Identifier: MIT
    +
    2#ifndef DBC_DIAGNOSTIC_H
    +
    3#define DBC_DIAGNOSTIC_H
    +
    4
    +
    5#include "dbc_database.h"
    +
    6#include <cstddef>
    +
    7#include <string>
    +
    8#include <vector>
    +
    9
    +
    10enum class DbcDiagnosticSeverity {
    +
    11 Warning,
    +
    12 Error
    +
    13};
    +
    14
    +
    16enum class DbcDiagnosticCode {
    +
    17 FileOpenError,
    +
    18 FileReadError,
    +
    19 InvalidStatement,
    +
    20 InvalidValueDescription,
    +
    21 InvalidMultiplexing,
    +
    22 UnsupportedStatement
    +
    23};
    +
    24
    +
    + +
    26 DbcDiagnosticSeverity severity;
    +
    27 DbcDiagnosticCode code;
    +
    28 std::string filePath;
    +
    29 std::size_t lineNumber; // One-based physical line; zero for file-level errors.
    +
    30 std::string message;
    +
    31};
    +
    +
    32
    +
    + +
    34 DbcDatabase database;
    +
    35 std::vector<DbcDiagnostic> diagnostics;
    +
    36
    +
    37 bool HasErrors() const {
    +
    38 for (const DbcDiagnostic &diagnostic : diagnostics) {
    +
    39 if (diagnostic.severity == DbcDiagnosticSeverity::Error)
    +
    40 return true;
    +
    41 }
    +
    42 return false;
    +
    43 }
    +
    44};
    +
    +
    45
    +
    46#endif /* DBC_DIAGNOSTIC_H */
    +
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    +
    Parsed DBC content stored in a simple internal form.
    + + +
    +
    + + + + diff --git a/docs/html/dbc__parser_8cpp.html b/docs/html/dbc__parser_8cpp.html index 0736a27..f8f5d70 100644 --- a/docs/html/dbc__parser_8cpp.html +++ b/docs/html/dbc__parser_8cpp.html @@ -100,7 +100,9 @@ $(document).ready(function(){initNavTree('dbc__parser_8cpp.html',''); initResiza #include "dbc_statement_handler.h"
    #include "text_utils.h"
    #include <fstream>
    +#include <sstream>
    #include <stdexcept>
    +#include <utility>

    Go to the source code of this file.

    Detailed Description

    diff --git a/docs/html/dbc__parser_8cpp_source.html b/docs/html/dbc__parser_8cpp_source.html index 82af67b..a1561be 100644 --- a/docs/html/dbc__parser_8cpp_source.html +++ b/docs/html/dbc__parser_8cpp_source.html @@ -104,46 +104,114 @@ $(document).ready(function(){initNavTree('dbc__parser_8cpp_source.html',''); ini
    14
    15#include "text_utils.h"
    16#include <fstream>
    -
    17#include <stdexcept>
    -
    18
    -
    -
    19DbcDatabase DbcParser::ParseFile(const std::string &filePath) const {
    -
    20 std::ifstream input(filePath.c_str());
    -
    21 if (!input.is_open())
    -
    22 throw std::runtime_error("Failed to open DBC file: " + filePath);
    -
    23
    -
    24 DbcDatabase database;
    -
    25 DbcParseContext context{database, nullptr};
    -
    26 const DbcStatementDispatcher dispatcher;
    -
    27
    -
    28 std::size_t lineNumber = 0U;
    -
    29 std::string line;
    -
    30 while (std::getline(input, line)) {
    -
    31 ++lineNumber;
    -
    32 line = dbc_detail::TrimText(line);
    -
    33 if (line.empty())
    -
    34 continue;
    -
    35
    -
    36 try {
    -
    37 context.lineNumber = lineNumber;
    -
    38 dispatcher.Dispatch(line, context);
    -
    39 } catch (const std::exception &error) {
    -
    40 throw std::runtime_error(filePath + ":" + std::to_string(lineNumber) +
    -
    41 ": " + error.what());
    -
    42 }
    -
    43 }
    -
    44
    -
    45 context.ResolveValueDescriptions(filePath);
    -
    46 context.ValidateMultiplexing(filePath);
    -
    47 return database;
    -
    48}
    +
    17#include <sstream>
    +
    18#include <stdexcept>
    +
    19#include <utility>
    +
    20
    +
    21namespace {
    +
    22 DbcDiagnosticCode StatementErrorCode(const std::string &keyword) {
    +
    23 if (keyword == "SG_MUL_VAL_")
    +
    24 return DbcDiagnosticCode::UnsupportedStatement;
    +
    25 if (keyword == "VAL_")
    +
    26 return DbcDiagnosticCode::InvalidValueDescription;
    +
    27 return DbcDiagnosticCode::InvalidStatement;
    +
    28 }
    +
    29}
    +
    30
    +
    +
    31DbcDatabase DbcParser::ParseFile(const std::string &filePath) const {
    + +
    33 for (const DbcDiagnostic &diagnostic : result.diagnostics) {
    +
    34 if (diagnostic.severity == DbcDiagnosticSeverity::Error) {
    +
    35 if (diagnostic.lineNumber == 0U)
    +
    36 throw std::runtime_error(diagnostic.message);
    +
    37 throw std::runtime_error(diagnostic.filePath + ":" +
    +
    38 std::to_string(diagnostic.lineNumber) + ": " + diagnostic.message);
    +
    39 }
    +
    40 }
    +
    41 return std::move(result.database);
    +
    42}
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    - -
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    +
    43
    +
    +
    44DbcParseResult DbcParser::ParseFileWithDiagnostics(const std::string &filePath) const {
    +
    45 DbcParseResult result;
    +
    46 std::ifstream input(filePath.c_str());
    +
    47 if (!input.is_open()) {
    +
    48 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
    +
    49 DbcDiagnosticCode::FileOpenError, filePath, 0U,
    +
    50 "Failed to open DBC file: " + filePath});
    +
    51 return result;
    +
    52 }
    +
    53
    +
    54 DbcDatabase database;
    +
    55 DbcParseContext context{database, nullptr};
    +
    56 const DbcStatementDispatcher dispatcher;
    +
    57 bool inNamespace = false;
    +
    58 std::size_t lineNumber = 0U;
    +
    59 std::string line;
    +
    60 while (std::getline(input, line)) {
    +
    61 ++lineNumber;
    +
    62 line = dbc_detail::TrimText(line);
    +
    63 if (line.empty())
    +
    64 continue;
    +
    65
    +
    66 std::istringstream tokens(line);
    +
    67 std::string keyword;
    +
    68 std::string argument;
    +
    69 tokens >> keyword;
    +
    70 const bool hasArgument = static_cast<bool>(tokens >> argument);
    +
    71 if (inNamespace && !hasArgument && keyword != "BO_" && keyword != "SG_" &&
    +
    72 keyword != "BS_" && keyword != "BS_:" &&
    +
    73 keyword != "BU_" && keyword != "BU_:")
    +
    74 continue; // NS_ lists syntax symbols; BO_, SG_, BS_ and BU_ end the list.
    +
    75 inNamespace = keyword == "NS_" || keyword == "NS_:";
    +
    76
    +
    77 try {
    +
    78 context.lineNumber = lineNumber;
    +
    79 if (!dispatcher.Dispatch(line, context)) {
    +
    80 result.diagnostics.push_back({DbcDiagnosticSeverity::Warning,
    +
    81 DbcDiagnosticCode::UnsupportedStatement,
    +
    82 filePath, lineNumber,
    +
    83 "Unsupported statement '" + keyword +
    +
    84 "' is ignored; decoding or metadata may be incomplete."});
    +
    85 }
    +
    86 } catch (const std::exception &error) {
    +
    87 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
    +
    88 StatementErrorCode(keyword), filePath,
    +
    89 lineNumber, error.what()});
    +
    90 return result;
    +
    91 }
    +
    92 }
    +
    93
    +
    94 if (input.bad() || !input.eof()) {
    +
    95 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
    +
    96 DbcDiagnosticCode::FileReadError, filePath, 0U,
    +
    97 "Failed to read DBC file: " + filePath});
    +
    98 return result;
    +
    99 }
    +
    100
    +
    101 try {
    +
    102 context.ResolveValueDescriptions(filePath);
    +
    103 context.ValidateMultiplexing(filePath);
    +
    104 } catch (const DbcDiagnosticError &error) {
    +
    105 result.diagnostics.push_back(error.diagnostic);
    +
    106 return result;
    +
    107 }
    +
    108 result.database = std::move(database);
    +
    109 return result;
    +
    110}
    +
    + +
    DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const
    Parse with warnings and a structured first error instead of throwing.
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    + +
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    Parsed DBC content stored in a simple internal form.
    - + + +
    diff --git a/docs/html/dbc__parser_8h.html b/docs/html/dbc__parser_8h.html index 524bbc7..d446179 100644 --- a/docs/html/dbc__parser_8h.html +++ b/docs/html/dbc__parser_8h.html @@ -99,7 +99,7 @@ $(document).ready(function(){initNavTree('dbc__parser_8h.html',''); initResizabl

    Created: 2026-03-13 Author: Deeaitch (Dim. Himro) More...

    #include <string>
    -#include "dbc_database.h"
    +#include "dbc_diagnostic.h"

    Go to the source code of this file.

    diff --git a/docs/html/dbc__parser_8h_source.html b/docs/html/dbc__parser_8h_source.html index b6c8066..d55f09e 100644 --- a/docs/html/dbc__parser_8h_source.html +++ b/docs/html/dbc__parser_8h_source.html @@ -104,21 +104,24 @@ $(document).ready(function(){initNavTree('dbc__parser_8h_source.html',''); initR
    14
    15#include <string>
    16
    -
    17#include "dbc_database.h"
    +
    17#include "dbc_diagnostic.h"
    18
    -
    -
    34class DbcParser {
    -
    35public:
    -
    45 DbcDatabase ParseFile(const std::string &filePath) const;
    -
    46
    -
    47};
    +
    +
    33class DbcParser {
    +
    34public:
    +
    44 DbcDatabase ParseFile(const std::string &filePath) const;
    +
    45
    +
    52 DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const;
    +
    53
    +
    54};
    -
    48
    -
    49#endif /* DBC_PARSER_H */
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    -
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    +
    55
    +
    56#endif /* DBC_PARSER_H */
    +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    +
    DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const
    Parse with warnings and a structured first error instead of throwing.
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    Parsed DBC content stored in a simple internal form.
    +
    diff --git a/docs/html/dbc__parser__test_8cpp_source.html b/docs/html/dbc__parser__test_8cpp_source.html index 16a20c3..4c2e305 100644 --- a/docs/html/dbc__parser__test_8cpp_source.html +++ b/docs/html/dbc__parser__test_8cpp_source.html @@ -163,580 +163,846 @@ $(document).ready(function(){initNavTree('dbc__parser__test_8cpp_source.html',''
    63 }
    64 }
    65private Q_SLOTS:
    -
    66 void multiplexing();
    -
    67 void multiplexingBoundaries();
    -
    68 void validFrames();
    -
    69 void invalidFrames();
    -
    70 void duplicateFrames();
    -
    71 void duplicateSignals();
    -
    72 void distinctDefinitions();
    -
    73 void integration();
    -
    74 void invalidSignals();
    -
    75 void validSignals();
    -
    76 void dispatch();
    -
    77 void independentSessions();
    -
    78 void valueDescriptions();
    -
    79 void invalidValueDescriptions();
    -
    80};
    -
    81
    -
    82void DbcParserTest::validFrames() {
    -
    83 Fixture fixture;
    -
    84 struct ValidCase {
    -
    85 const char *line;
    -
    86 std::uint32_t id;
    -
    87 bool extended;
    -
    88 unsigned length;
    -
    89 };
    -
    90 const ValidCase valid[] = {
    -
    91 {"BO_ 0 Frame: 0 ECU", 0U, false, 0U},
    -
    92 {"BO_ 2047 Frame: 8 ECU", 2047U, false, 8U},
    -
    93 {"BO_ 2048 Frame: 64 ECU", 2048U, true, 64U},
    -
    94 {"BO_ 536870911 Frame: 255 ECU", 0x1FFFFFFFU, true, 255U},
    -
    95 {"BO_ 2147483649 Frame: 8 ECU", 1U, true, 8U},
    -
    96 {"BO_ 2684354559 Frame: 8 ECU", 0x1FFFFFFFU, true, 8U},
    -
    97 {" BO_\t256\tFrame :\t8\tECU \r", 256U, false, 8U}};
    -
    98 for (const ValidCase &test: valid) {
    -
    99 fixture.Write(std::string(test.line) + '\n');
    -
    100 try {
    -
    101 const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
    -
    102 QCOMPARE(database.frames.size(), std::size_t(1U));
    -
    103 const FrameInfo &frame = database.frames[0];
    -
    104 QCOMPARE(frame.name, std::string("Frame"));
    -
    105 QCOMPARE(frame.canId, test.id);
    -
    106 QCOMPARE(frame.isExtended, test.extended);
    -
    107 QCOMPARE(static_cast<unsigned>(frame.dlc), test.length);
    -
    108 QCOMPARE(frame.transmitter, std::string("ECU"));
    -
    109 } catch (const std::exception &error) { CHECK(false, error.what()); }
    -
    110 }
    -
    111}
    -
    112
    -
    113void DbcParserTest::invalidFrames() {
    -
    114 Fixture fixture;
    -
    115 const char *invalid[] = {
    -
    116 "BO_ invalid", "BO_", "BO_ 1", "BO_ 1 : 8 ECU", "BO_ 1 Frame 8 ECU",
    -
    117 "BO_ 1 Frame:", "BO_ 1 Frame: 8", "BO_ 1 Frame: 8 ECU extra",
    -
    118 "BO_ 1 Two Names: 8 ECU", "BO_ -1 Frame: 8 ECU", "BO_ +1 Frame: 8 ECU",
    -
    119 "BO_ 1x Frame: 8 ECU", "BO_ 0x123 Frame: 8 ECU", "BO_ 1.5 Frame: 8 ECU",
    -
    120 "BO_ 4294967296 Frame: 8 ECU", "BO_ 999999999999999999999 Frame: 8 ECU",
    -
    121 "BO_ 536870912 Frame: 8 ECU", "BO_ 1073741824 Frame: 8 ECU",
    -
    122 "BO_ 2684354560 Frame: 8 ECU", "BO_ 4294967295 Frame: 8 ECU",
    -
    123 "BO_ 1 Frame: -1 ECU", "BO_ 1 Frame: +8 ECU", "BO_ 1 Frame: 8x ECU",
    -
    124 "BO_ 1 Frame: 8.5 ECU", "BO_ 1 Frame: 256 ECU",
    -
    125 "BO_ 1 Frame: 4294967296 ECU", "BO_\tinvalid"};
    -
    126 for (const char *line: invalid) {
    -
    127 fixture.Write(std::string("VERSION \"test\"\n\n") + line + '\n');
    -
    128 try {
    -
    129 DbcParser().ParseFile(fixture.path.string());
    -
    130 CHECK(false, line);
    -
    131 } catch (const std::runtime_error &error) {
    -
    132 const std::string prefix = fixture.path.string() + ":3: ";
    -
    133 CHECK(std::string(error.what()).find(prefix) == 0U &&
    -
    134 std::string(error.what()).size() > prefix.size(),
    -
    135 line);
    -
    136 }
    -
    137 }
    -
    138}
    -
    139
    -
    140void DbcParserTest::duplicateFrames() {
    -
    141 Fixture fixture;
    -
    142 struct DuplicateCase {
    -
    143 const char *firstId;
    -
    144 const char *duplicateId;
    -
    145 const char *message;
    -
    146 };
    -
    147 const DuplicateCase cases[] = {
    -
    148 {"1", "1", "Duplicate standard frame CAN ID: 1"},
    -
    149 {"2147483649", "2147483649", "Duplicate extended frame CAN ID: 1"},
    -
    150 {"2048", "2147485696", "Duplicate extended frame CAN ID: 2048"},
    -
    151 {"2147485696", "2048", "Duplicate extended frame CAN ID: 2048"},
    -
    152 {"536870911", "2684354559", "Duplicate extended frame CAN ID: 536870911"}
    -
    153 };
    -
    154 const DbcParser parser;
    -
    155 for (const DuplicateCase &test : cases) {
    -
    156 fixture.Write("BO_ " + std::string(test.firstId) + " First: 8 ECU\n"
    -
    157 "BO_ 2 Other: 8 ECU\n\n"
    -
    158 " BO_\t" + test.duplicateId + "\tSecond: 8 ECU\n");
    -
    159 try {
    -
    160 parser.ParseFile(fixture.path.string());
    -
    161 CHECK(false, "Duplicate frame must be rejected");
    -
    162 } catch (const std::runtime_error &error) {
    -
    163 QCOMPARE(std::string(error.what()), fixture.path.string() + ":4: " + test.message);
    -
    164 }
    -
    165 }
    -
    166 fixture.Write("BO_ 1 First: 8 ECU\n");
    -
    167 QCOMPARE(parser.ParseFile(fixture.path.string()).frames.size(), std::size_t(1U));
    -
    168}
    -
    169
    -
    170void DbcParserTest::duplicateSignals() {
    -
    171 Fixture fixture;
    -
    172 const std::string first = "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n";
    -
    173 const std::string duplicates[] = {
    -
    174 first,
    -
    175 " SG_\tState : 16|8@1+ (2,1) [0|511] \"V\" ECU\n",
    -
    176 "SG_ State m1 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    177 };
    -
    178 for (const std::string &duplicate : duplicates) {
    -
    179 fixture.Write("BO_ 1 Frame: 8 ECU\n" + first +
    -
    180 "SG_ Other : 8|8@1+ (1,0) [0|255] \"\" ECU\n\n" + duplicate);
    -
    181 try {
    -
    182 DbcParser().ParseFile(fixture.path.string());
    -
    183 CHECK(false, "Duplicate signal must be rejected");
    -
    184 } catch (const std::runtime_error &error) {
    -
    185 QCOMPARE(std::string(error.what()), fixture.path.string() +
    -
    186 ":5: Duplicate signal name 'State' in frame 'Frame'.");
    -
    187 }
    -
    188 }
    -
    189}
    -
    190
    -
    191void DbcParserTest::distinctDefinitions() {
    -
    192 Fixture fixture;
    -
    193 fixture.Write("BO_ 1 Shared: 1 ECU\n"
    -
    194 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    195 "BO_ 2147483649 Shared: 1 ECU\n"
    -
    196 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    197 "BO_ 2 Shared: 2 ECU\n"
    -
    198 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    199 "SG_ state : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    200 "CM_ BO_ 1 \"Standard\";\n"
    -
    201 "CM_ BO_ 2147483649 \"Extended\";\n"
    -
    202 "CM_ SG_ 1 State \"Standard state\";\n"
    -
    203 "CM_ SG_ 2147483649 State \"Extended state\";\n");
    -
    204 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    -
    205 QCOMPARE(parsed.frames.size(), std::size_t(3U));
    -
    206 QCOMPARE(parsed.frames[0].canId, parsed.frames[1].canId);
    -
    207 CHECK(!parsed.frames[0].isExtended && parsed.frames[1].isExtended,
    -
    208 "Standard and extended frames with the same numeric ID remain distinct");
    -
    209 QCOMPARE(parsed.frames[0].comment, std::string("Standard"));
    -
    210 QCOMPARE(parsed.frames[1].comment, std::string("Extended"));
    -
    211 QCOMPARE(parsed.frames[0].signals[0].comment, std::string("Standard state"));
    -
    212 QCOMPARE(parsed.frames[1].signals[0].comment, std::string("Extended state"));
    -
    213 QCOMPARE(parsed.frames[2].signals.size(), std::size_t(2U));
    -
    214 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    -
    215 RawCanFrame raw;
    -
    216 raw.canId = 1U;
    -
    217 raw.data = {7U};
    -
    218 const DecodedFrameValue standard = DbcDecoder().Decode(runtime, raw);
    -
    219 QVERIFY(standard.valid);
    -
    220 QCOMPARE(standard.definition->comment, std::string("Standard"));
    -
    221 raw.isExtended = true;
    -
    222 const DecodedFrameValue extended = DbcDecoder().Decode(runtime, raw);
    -
    223 QVERIFY(extended.valid);
    -
    224 QCOMPARE(extended.definition->comment, std::string("Extended"));
    -
    225}
    -
    226
    -
    227void DbcParserTest::integration() {
    -
    228 Fixture fixture;
    -
    229 fixture.Write(
    -
    230 "BO_TX_BU_ 256 : ECU;\nBO_ 256 Frame: 8 ECU\n"
    -
    231 " SG_ Speed : 0|16@1+ (0.5,1) [0|100] \"rpm\" ECU\n"
    -
    232 "CM_ BO_ 256 \"Frame comment\";\nCM_ SG_ 256 Speed \"Signal comment\";\n"
    -
    233 "BO_ 257 Second: 8 ECU\n");
    -
    234 const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
    -
    235 CHECK(database.frames.size() == 2U && database.frames[0].signals.size() == 1U &&
    -
    236 database.frames[0].comment == "Frame comment" &&
    -
    237 database.frames[0].signals[0].comment == "Signal comment",
    -
    238 "Integration");
    -
    239 fixture.Write("\nSG_ Speed : invalid\n");
    -
    240 try {
    -
    241 DbcParser().ParseFile(fixture.path.string());
    -
    242 CHECK(false, "Signal error location");
    -
    243 } catch (const std::runtime_error &error) {
    -
    244 CHECK(std::string(error.what()).find(fixture.path.string() + ":2: ") == 0U,
    -
    245 "Signal error location");
    -
    246 }
    -
    247}
    -
    248
    -
    249void DbcParserTest::multiplexing() {
    -
    250 Fixture fixture;
    -
    251 const std::string selector = "SG_ Mode M : 0|8@1+ (10,3) [0|255] \"\" ECU\n";
    -
    252 const std::string first = "SG_ First m1 : 8|8@1- (2,0) [-128|127] \"V\" ECU\n";
    -
    253 const std::string second = "SG_ Second m2 : 15|8@0+ (1,0) [0|255] \"\" ECU\n";
    -
    254 const std::string common = "SG_ Common : 16|8@1+ (1,0) [0|255] \"\" ECU\n";
    -
    255 fixture.Write("BO_ 1 Frame: 3 ECU\n" + first + second + common + selector +
    -
    256 "VAL_ 1 First -1 \"Negative\";\n");
    -
    257 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    -
    258 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    -
    259 CHECK(parsed.frames[0].signals[3].multiplexing.role == MultiplexRole::Selector,
    -
    260 "Selector declared after branches");
    -
    261 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
    -
    262 CHECK(tree->GetChild(0U)->GetChild(0U)->GetSignal()->multiplexing.value == 1U,
    -
    263 "Tree preserves multiplexing");
    -
    264 RawCanFrame raw;
    -
    265 raw.canId = 1U;
    -
    266 raw.data = {1U, 255U, 7U};
    -
    267 DecodedFrameValue result = DbcDecoder().Decode(runtime, raw);
    -
    268 CHECK(result.signals[0].valid && std::get<std::int64_t>(result.signals[0].rawValue) == -1 &&
    -
    269 result.signals[0].physicalValue == -2 && *result.signals[0].GetValueDescription() == "Negative",
    -
    270 "Active signed branch and VAL_ use exact raw selector");
    -
    271 CHECK(!result.signals[1].valid && result.signals[1].status == SignalDecodeStatus::Inactive &&
    -
    272 result.signals[1].GetValueDescription() == nullptr && result.signals[2].valid,
    -
    273 "Inactive branch and unconditional signal");
    -
    274 raw.data[0] = 2U;
    -
    275 result = DbcDecoder().Decode(runtime, raw);
    -
    276 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive && result.signals[1].valid &&
    -
    277 std::get<std::uint64_t>(result.signals[1].rawValue) == 255U,
    -
    278 "Motorola branch becomes active");
    -
    279 raw.data = {3U};
    -
    280 result = DbcDecoder().Decode(runtime, raw);
    -
    281 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive &&
    -
    282 result.signals[1].status == SignalDecodeStatus::Inactive &&
    -
    283 result.signals[2].status == SignalDecodeStatus::InsufficientPayload,
    -
    284 "Unmapped selector leaves branches inactive even with missing bytes");
    -
    285 raw.data = {1U};
    -
    286 result = DbcDecoder().Decode(runtime, raw);
    -
    287 CHECK(result.signals[0].status == SignalDecodeStatus::InsufficientPayload,
    -
    288 "Active branch requires payload");
    -
    289 raw.data.clear();
    -
    290 result = DbcDecoder().Decode(runtime, raw);
    -
    291 CHECK(result.signals[0].status == SignalDecodeStatus::SelectorUnavailable &&
    -
    292 result.signals[3].status == SignalDecodeStatus::InsufficientPayload,
    -
    293 "Unavailable selector does not imply inactive branch");
    -
    294
    -
    295 const std::vector<std::string> invalid = {
    -
    296 first,
    -
    297 selector + "SG_ Other M : 16|8@1+ (1,0) [0|255] \"\" ECU\n",
    -
    298 "SG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
    -
    299 selector + "SG_ TooLarge m256 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    -
    300 selector + first + "SG_ Same m1 : 15|8@0+ (1,0) [0|255] \"\" ECU\n",
    -
    301 selector + "SG_ Collision m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
    -
    302 selector + first + "SG_ Always : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    -
    303 "SG_MUL_VAL_ 1 First Mode 1-2;\n"
    -
    304 };
    -
    305 for (const std::string &signals : invalid) {
    -
    306 fixture.Write("BO_ 1 Frame: 3 ECU\n" + signals);
    -
    307 bool rejected = false;
    -
    308 try {
    -
    309 DbcParser().ParseFile(fixture.path.string());
    -
    310 } catch (const std::runtime_error &error) {
    -
    311 rejected = std::string(error.what()).find(fixture.path.string() + ":") == 0U;
    -
    312 }
    -
    313 CHECK(rejected, "Invalid multiplexing rejected with location");
    -
    314 }
    -
    315 for (const std::string marker : {"m", "m-1", "m+1", "m1M", "m18446744073709551616", "M m1"})
    -
    316 RejectSignal(fixture, "SG_ Bad " + marker + " : 8|8@1+ (1,0) [0|255] \"\" ECU");
    -
    317}
    -
    318
    -
    319void DbcParserTest::multiplexingBoundaries() {
    -
    320 Fixture fixture;
    -
    321 fixture.Write("BO_ 1 Frame: 9 ECU\n"
    -
    322 "SG_ Branch m18446744073709551615 : 64|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    323 "SG_ Mode M : 7|64@0+ (0,5) [0|1] \"\" ECU\n");
    -
    324 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    -
    325 DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    -
    326 CHECK(runtime.frames[0].signals[0].multiplexing.value == std::numeric_limits<std::uint64_t>::max(),
    -
    327 "Exact uint64 branch metadata");
    -
    328 RawCanFrame raw;
    -
    329 raw.canId = 1U;
    -
    330 raw.data = std::vector<std::uint8_t>(9U, 255U);
    -
    331 DecodedFrameValue result = DbcDecoder().Decode(runtime, raw);
    -
    332 CHECK(result.signals[0].valid && result.signals[1].valid &&
    -
    333 std::get<std::uint64_t>(result.signals[1].rawValue) == std::numeric_limits<std::uint64_t>::max(),
    -
    334 "Motorola uint64 selector compares raw value before zero scaling");
    -
    335 raw.data[7] = 254U;
    -
    336 result = DbcDecoder().Decode(runtime, raw);
    -
    337 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive,
    -
    338 "Adjacent large integers remain distinct");
    -
    339 runtime.frames[0].signals[1].length = 0U;
    -
    340 result = DbcDecoder().Decode(runtime, raw);
    -
    341 CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition &&
    -
    342 result.signals[1].status == SignalDecodeStatus::InvalidDefinition,
    -
    343 "Malformed runtime selector distinguished from payload errors");
    -
    344 runtime.frames[0].signals.pop_back();
    -
    345 result = DbcDecoder().Decode(runtime, raw);
    -
    346 CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition,
    -
    347 "Missing runtime selector");
    -
    348 fixture.Write("BO_ 1 Frame: 2 ECU\n\n"
    -
    349 "SG_ Branch m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    350 "SG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n");
    -
    351 bool rejected = false;
    -
    352 try {
    -
    353 DbcParser().ParseFile(fixture.path.string());
    -
    354 } catch (const std::runtime_error &error) {
    -
    355 rejected = std::string(error.what()).find(fixture.path.string() + ":3: ") == 0U;
    -
    356 }
    -
    357 CHECK(rejected, "Deferred validation reports branch source line");
    -
    358 fixture.Write("BO_ 1 Frame: 2 ECU\n"
    -
    359 "SG_ A : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    -
    360 "SG_ B : 15|8@0+ (1,0) [0|255] \"\" ECU\n");
    -
    361 rejected = false;
    -
    362 try {
    -
    363 DbcParser().ParseFile(fixture.path.string());
    -
    364 } catch (const std::runtime_error &) {
    -
    365 rejected = true;
    -
    366 }
    -
    367 CHECK(rejected, "Ordinary overlapping signals rejected");
    -
    368}
    -
    369
    -
    370void DbcParserTest::invalidSignals() {
    -
    371 Fixture fixture;
    -
    372 const std::string ordinary = SignalLine("0", "8", "1+", "1", "0", "0", "255");
    -
    373 for (const std::string value: {"-1", "+1", "0junk", "0x10", "1.5",
    -
    374 "4294967296", "999999999999999999999"}) {
    -
    375 RejectSignal(fixture, SignalLine(value, "8", "1+", "1", "0", "0", "255"));
    -
    376 RejectSignal(fixture, SignalLine("0", value, "1+", "1", "0", "0", "255"));
    -
    377 }
    -
    378 for (const std::string length: {"0", "65"})
    -
    379 RejectSignal(fixture, SignalLine("0", length, "1+", "1", "0", "0", "255"));
    -
    380 for (const std::string order: {"2+", "9-", "1", "1x", "1++", "01+"})
    -
    381 RejectSignal(fixture, SignalLine("0", "8", order, "1", "0", "0", "255"));
    -
    382 for (const std::string value: {"1junk", "nan", "NaN", "inf", "-inf", "1e999", "1e-999", "0x1p2", "", "1e", "1.2.3"}) {
    -
    383 RejectSignal(fixture, SignalLine("0", "8", "1+", value, "0", "0", "255"));
    -
    384 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", value, "0", "255"));
    -
    385 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", value, "255"));
    -
    386 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", "0", value));
    -
    387 }
    -
    388 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", "2", "1"));
    -
    389 for (const std::string name: {"", "Two Names", "Value m1M"}) {
    -
    390 std::string line = ordinary;
    -
    391 line.replace(4U, 5U, name);
    -
    392 RejectSignal(fixture, line);
    -
    393 }
    -
    394 for (const std::string broken: {
    -
    395 "SG_", "SG_ Value", "SG_ Value : 0|8@1+ (1,0) [0|255] ECU",
    -
    396 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\"",
    -
    397 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU,",
    -
    398 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU extra"})
    -
    399 RejectSignal(fixture, broken);
    -
    400 RejectSignal(fixture, SignalLine("64", "1", "1+", "1", "0", "0", "1"));
    -
    401 RejectSignal(fixture, SignalLine("63", "2", "1+", "1", "0", "0", "3"));
    -
    402 RejectSignal(fixture, SignalLine("56", "2", "0+", "1", "0", "0", "3"));
    -
    403 RejectSignal(fixture, SignalLine("4294967295", "64", "1+", "1", "0", "0", "1"));
    -
    404 RejectSignal(fixture, ordinary, 0U);
    -
    405 for (const char delimiter: {'|', '@', '(', ')', '[', ']', '"'}) {
    -
    406 std::string line = ordinary;
    -
    407 line.erase(line.find(delimiter), 1U);
    -
    408 RejectSignal(fixture, line);
    -
    409 }
    -
    410}
    -
    411
    -
    412void DbcParserTest::validSignals() {
    -
    413 Fixture fixture;
    -
    414 const DbcParser signalParser;
    -
    415 fixture.Write("BO_ 1 Frame: 8 ECU\n" +
    -
    416 SignalLine("0", "8", "1+", "0", "0", "0", "0") + "\n" +
    -
    417 SignalLine("8", "8", "1-", "-1", "0", "-255", "0", "Negative") + "\n");
    -
    418 const DbcDatabase factors = signalParser.ParseFile(fixture.path.string());
    -
    419 CHECK(factors.frames[0].signals.size() == 2U &&
    -
    420 factors.frames[0].signals[0].factor == 0.0 &&
    -
    421 factors.frames[0].signals[1].factor == -1.0,
    -
    422 "Zero and negative factors and equal range boundaries");
    -
    423
    -
    424 struct SignalCase {
    -
    425 const char *start;
    -
    426 const char *length;
    -
    427 const char *order;
    -
    428 unsigned payload;
    -
    429 };
    -
    430 const SignalCase validSignals[] = {
    -
    431 {"0", "1", "1+", 1U},
    -
    432 {"7", "1", "0-", 1U},
    -
    433 {"0", "64", "1+", 8U},
    -
    434 {"7", "64", "0-", 8U},
    -
    435 {"63", "1", "1+", 8U},
    -
    436 {"56", "1", "0+", 8U},
    -
    437 {"3", "12", "0+", 2U},
    -
    438 {"2039", "1", "1+", 255U}};
    -
    439 for (const SignalCase &test: validSignals) {
    -
    440 fixture.Write("BO_ 1 Frame: " + std::to_string(test.payload) + " ECU\n" +
    -
    441 SignalLine(test.start, test.length, test.order, ".5e+1", "-2.5E-1", "-1.", "+2e2") + "\n");
    -
    442 try {
    -
    443 const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
    -
    444 const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
    -
    445 QCOMPARE(signal.startBit, static_cast<std::uint32_t>(std::stoul(test.start)));
    -
    446 QCOMPARE(signal.length, static_cast<std::uint32_t>(std::stoul(test.length)));
    -
    447 QCOMPARE(signal.isLittleEndian, test.order[0] == '1');
    -
    448 QCOMPARE(signal.isSigned, test.order[1] == '-');
    -
    449 QCOMPARE(signal.factor, 5.0);
    -
    450 QCOMPARE(signal.offset, -0.25);
    -
    451 QCOMPARE(signal.minimum, -1.0);
    -
    452 QCOMPARE(signal.maximum, 200.0);
    -
    453 } catch (const std::exception &error) { CHECK(false, error.what()); }
    -
    454 }
    -
    455 fixture.Write("BO_ 1 Frame: 8 ECU\n"
    -
    456 "SG_\tValue\t:\t0 | 8 @1+ ( 1 , 0 ) [ 0 | 255 ] \"rpm\" ECU1,\tECU2\n");
    -
    457 try {
    -
    458 const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
    -
    459 const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
    -
    460 CHECK(signal.name == "Value" && signal.unit == "rpm" &&
    -
    461 signal.receivers == std::vector<std::string>({"ECU1", "ECU2"}),
    -
    462 "Signal tabs, spaces, and receiver list");
    -
    463 } catch (const std::exception &error) { CHECK(false, error.what()); }
    -
    464}
    -
    465
    -
    466void DbcParserTest::dispatch() {
    -
    467 CountingHandler::instances = 0;
    -
    468 CountingHandler::calls = 0;
    -
    469 DbcDatabase dispatchDatabase;
    -
    470 DbcParseContext context{dispatchDatabase, nullptr};
    -
    471 DbcStatementDispatcher dispatcher;
    -
    472 dispatcher.RegisterType<CountingHandler>("TEST_");
    -
    473 CHECK(dispatcher.Dispatch("TEST_ first", context) &&
    -
    474 dispatcher.Dispatch("TEST_ second", context) &&
    -
    475 CountingHandler::instances == 1 && CountingHandler::calls == 2 &&
    -
    476 dispatchDatabase.frames.size() == 2U,
    -
    477 "Factory dispatch and handler reuse");
    -
    478 CHECK(!dispatcher.Dispatch("TEST_OTHER data", context) &&
    -
    479 !dispatcher.Dispatch("BO_TX_BU_ 1 : ECU;", context) &&
    -
    480 !dispatcher.Dispatch("VAL_TABLE_ States 0 \"Stopped\";", context) &&
    -
    481 CountingHandler::calls == 2,
    -
    482 "Exact and unknown keyword dispatch");
    -
    483}
    -
    484
    -
    485void DbcParserTest::independentSessions() {
    -
    486 Fixture fixture;
    -
    487 const DbcParser parser;
    -
    488 fixture.Write("BO_ 1 First: 8 ECU\n");
    -
    489 CHECK(parser.ParseFile(fixture.path.string()).frames.size() == 1U, "First parse");
    -
    490 fixture.Write("SG_ Speed : invalid\n");
    -
    491 try {
    -
    492 parser.ParseFile(fixture.path.string());
    -
    493 CHECK(false, "Independent parse context");
    -
    494 } catch (const std::runtime_error &error) {
    -
    495 CHECK(std::string(error.what()).find("Signal found before any frame") !=
    -
    496 std::string::npos,
    -
    497 "Independent parse context");
    -
    498 }
    -
    499 fixture.Write("BO_ 2 Second: 8 ECU\n");
    -
    500 const DbcDatabase recovered = parser.ParseFile(fixture.path.string());
    -
    501 CHECK(recovered.frames.size() == 1U && recovered.frames[0].canId == 2U,
    -
    502 "Fresh parse after error");
    -
    503}
    -
    504
    -
    505
    -
    506void DbcParserTest::valueDescriptions() {
    -
    507 Fixture fixture;
    -
    508 fixture.Write(
    -
    509 "VAL_\t256\tState\t0\t\"Off\"\t1 \"On\" 2 \"Error with spaces; and \\\"quotes\\\"\";\n"
    -
    510 "BO_ 256 Status: 8 ECU\n"
    -
    511 "SG_ State : 0|8@1+ (2,10) [0|520] \"\" ECU\n"
    -
    512 "VAL_ 256 State 3 \"\";\n"
    -
    513 "VAL_ 2147483904 State -9223372036854775808 \"Minimum\" -1 \"Negative\" 9223372036854775807 \"Maximum\";\n"
    -
    514 "BO_ 2147483904 Extended: 8 ECU\n"
    -
    515 "SG_ State : 0|64@1- (1,0) [-1e20|1e20] \"\" ECU\n"
    -
    516 "BO_ 2048 Unsigned: 8 ECU\n"
    -
    517 "SG_ State : 0|64@1+ (1,0) [0|2e20] \"\" ECU\n"
    -
    518 "VAL_ 2147485696 State 9223372036854775808 \"High\" 18446744073709551615 \"Full\";\n");
    -
    519 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    -
    520 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    -
    521 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
    -
    522 CHECK(tree->GetChild(0)->GetSignal() == nullptr, "Frame node");
    -
    523 for (std::size_t index = 0; index < parsed.frames.size(); ++index) {
    -
    524 CHECK(tree->GetChild(index)->GetChild(0)->GetSignal()->valueDescriptions ==
    -
    525 parsed.frames[index].signals[0].valueDescriptions &&
    -
    526 runtime.frames[index].signals[0].valueDescriptions ==
    -
    527 parsed.frames[index].signals[0].valueDescriptions,
    -
    528 "All mappings survive both builders");
    -
    529 }
    -
    530 CHECK(tree->GetChild(0)->GetChild(0)->GetSignal()->valueDescriptions ==
    -
    531 runtime.frames[0].signals[0].valueDescriptions,
    -
    532 "Both builders preserve descriptions");
    -
    533 RawCanFrame frame;
    -
    534 frame.canId = 256;
    -
    535 frame.data.resize(8);
    -
    536 const std::string expected[] = {"Off", "On", "Error with spaces; and \"quotes\"", ""};
    -
    537 for (unsigned value = 0; value < 5; ++value) {
    -
    538 frame.data[0] = value;
    -
    539 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    -
    540 CHECK(decoded.valid && decoded.physicalValue == value * 2 + 10, "Numeric scaling unchanged");
    -
    541 const std::string *description = decoded.GetValueDescription();
    -
    542 CHECK(value < 4 ? description && *description == expected[value] : !description,
    -
    543 "Raw lookup and unknown value");
    -
    544 }
    -
    545 frame.isExtended = true;
    -
    546 struct Boundary {
    -
    547 std::uint64_t bits;
    -
    548 const char *description;
    -
    549 };
    -
    550 for (const Boundary &test: {Boundary{0x8000000000000000ULL, "Minimum"},
    -
    551 Boundary{0xFFFFFFFFFFFFFFFFULL, "Negative"},
    -
    552 Boundary{0x7FFFFFFFFFFFFFFFULL, "Maximum"}}) {
    -
    553 for (unsigned byte = 0; byte < 8; ++byte)
    -
    554 frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
    -
    555 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    -
    556 CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
    -
    557 "Signed boundaries and distinct extended frame");
    -
    558 }
    -
    559 frame.canId = 2048;
    -
    560 for (const Boundary &test: {Boundary{0x8000000000000000ULL, "High"},
    -
    561 Boundary{0xFFFFFFFFFFFFFFFFULL, "Full"}}) {
    -
    562 for (unsigned byte = 0; byte < 8; ++byte)
    -
    563 frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
    -
    564 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    -
    565 CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
    -
    566 "Unsigned boundaries");
    -
    567 }
    -
    568 CHECK(FindValueDescription(runtime.frames[0].signals[0].valueDescriptions, std::int64_t(1)) != nullptr,
    -
    569 "Nonnegative signed lookup matches unsigned key");
    -
    570 frame.data.clear();
    -
    571 CHECK(!DbcDecoder().Decode(runtime, frame).signals[0].GetValueDescription(), "Invalid decode has no description");
    -
    572}
    -
    573
    -
    574void DbcParserTest::invalidValueDescriptions() {
    -
    575 Fixture fixture;
    -
    576 const std::string definitions = "BO_ 1 Frame: 8 ECU\nSG_ State : 0|64@1+ (1,0) [0|2e20] \"\" ECU\n";
    -
    577 for (const std::string statement: {
    -
    578 "VAL_", "VAL_ 1 State;", "VAL_ 1 State ;", "VAL_ 1 State 0 \"Off\"",
    -
    579 "VAL_ 1 State 0 \"Off\"; junk", "VAL_ 1 State 0 Off;",
    -
    580 "VAL_ 1 State 0 \"Unclosed;", "VAL_ 1 State 0 \"Off\"1 \"On\";",
    -
    581 "VAL_ 1 State 0 \"Off\" 00 \"Duplicate\";",
    -
    582 "VAL_ 1 State 0 \"Off\" -0 \"Duplicate\";",
    -
    583 "VAL_ 1 State 0 \"Off\";\nVAL_ 1 State 0 \"Duplicate\";",
    -
    584 "VAL_ 2 State 0 \"Missing frame\";", "VAL_ 1 Missing 0 \"Missing signal\";",
    -
    585 "VAL_ -1 State 0 \"Bad ID\";", "VAL_ 536870912 State 0 \"Bad ID\";",
    -
    586 "VAL_ 4294967296 State 0 \"Bad ID\";", "VAL_ Environment 0 \"Unsupported\";",
    -
    587 "VAL_ 1 State 0 \"Bad\\q escape\";"}) {
    -
    588 fixture.Write(definitions + statement + '\n');
    -
    589 const int line = statement.find('\n') == std::string::npos ? 3 : 4;
    -
    590 try {
    -
    591 DbcParser().ParseFile(fixture.path.string());
    -
    592 CHECK(false, statement);
    -
    593 } catch (const std::runtime_error &error) {
    -
    594 CHECK(std::string(error.what()).find(fixture.path.string() + ":" + std::to_string(line) + ": ") == 0,
    -
    595 statement + " " + error.what());
    -
    596 }
    -
    597 }
    -
    598 for (const std::string suffix: {
    -
    599 "BO_ 1 Other: 8 ECU\n", // Duplicate frame definition.
    -
    600 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n",// Duplicate signal definition.
    -
    601 ""}) {
    -
    602 fixture.Write("VAL_ 1 " + std::string(suffix.empty() ? "Missing" : "State") +
    -
    603 " 0 \"Description\";\n" + definitions + suffix);
    -
    604 try {
    -
    605 DbcParser().ParseFile(fixture.path.string());
    -
    606 CHECK(false, "Missing reference or duplicate definition");
    -
    607 } catch (const std::runtime_error &error) {
    -
    608 const std::string line = suffix.empty() ? "1" : "4";
    -
    609 CHECK(std::string(error.what()).find(fixture.path.string() + ":" + line + ": ") == 0,
    -
    610 "Error retains the reference or duplicate definition source location");
    -
    611 }
    -
    612 }
    -
    613 for (const std::string number: {"+1", "1x", "0x10", "1.5", "1e2", "--1",
    -
    614 "-9223372036854775809", "18446744073709551616"}) {
    -
    615 fixture.Write("VAL_ 1 State " + number + " \"Bad\";\n" + definitions);
    -
    616 try {
    -
    617 DbcParser().ParseFile(fixture.path.string());
    -
    618 CHECK(false, number);
    -
    619 } catch (const std::runtime_error &error) {
    -
    620 CHECK(std::string(error.what()).find(fixture.path.string() + ":1: ") == 0, number);
    -
    621 }
    -
    622 }
    -
    623}
    -
    624
    -
    625int RunParserTests(int argc, char **argv) {
    -
    626 DbcParserTest tests;
    -
    627 return QTest::qExec(&tests, argc, argv);
    -
    628}
    -
    629
    -
    630#include "dbc_parser_test.moc"
    +
    66 void diagnostics();
    +
    67 void diagnosticErrors();
    +
    68 void diagnosticUnsupportedStatements();
    +
    69 void diagnosticNamespaceBoundaries();
    +
    70 void diagnosticFormatting();
    +
    71 void multiplexing();
    +
    72 void multiplexingBoundaries();
    +
    73 void validFrames();
    +
    74 void invalidFrames();
    +
    75 void duplicateFrames();
    +
    76 void duplicateSignals();
    +
    77 void distinctDefinitions();
    +
    78 void integration();
    +
    79 void invalidSignals();
    +
    80 void validSignals();
    +
    81 void dispatch();
    +
    82 void independentSessions();
    +
    83 void valueDescriptions();
    +
    84 void invalidValueDescriptions();
    +
    85};
    +
    86
    +
    87void DbcParserTest::diagnostics() {
    +
    88 Fixture fixture;
    +
    89 fixture.Write("VERSION \"test\"\n"
    +
    90 "NS_ :\n"
    +
    91 " CM_\n"
    +
    92 " BA_\n"
    +
    93 " SIG_VALTYPE_\n"
    +
    94 " SG_MUL_VAL_\n\n"
    +
    95 "BS_:\n"
    +
    96 "BU_: ECU\n"
    +
    97 "BO_ 1 Frame: 1 ECU\n"
    +
    98 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    99 "SIG_VALTYPE_ 1 Value : 1;\n"
    +
    100 "BA_ \"SignalType\" SG_ 1 Value 1;\n"
    +
    101 "VENDOR_EXTENSION_ data;\n");
    +
    102 const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    103 CHECK(!result.HasErrors() && result.database.frames.size() == 1U,
    +
    104 "Warnings preserve the supported database");
    +
    105 QCOMPARE(result.diagnostics.size(), std::size_t(3U));
    +
    106 for (std::size_t index = 0U; index < result.diagnostics.size(); ++index) {
    +
    107 const DbcDiagnostic &diagnostic = result.diagnostics[index];
    +
    108 CHECK(diagnostic.severity == DbcDiagnosticSeverity::Warning &&
    +
    109 diagnostic.code == DbcDiagnosticCode::UnsupportedStatement,
    +
    110 "Unsupported statements have structured warning severity and code");
    +
    111 QCOMPARE(diagnostic.filePath, fixture.path.string());
    +
    112 QCOMPARE(diagnostic.lineNumber, 12U + index);
    +
    113 CHECK(diagnostic.message.find("ignored") != std::string::npos,
    +
    114 "Warning explains unsupported syntax");
    +
    115 }
    +
    116 CHECK(DbcParser().ParseFile(fixture.path.string()).frames.size() == 1U,
    +
    117 "Legacy API accepts files with warnings");
    +
    118 fixture.Write("VERSION \"\"\nNS_:\nSIG_VALTYPE_\n\tBA_\n BS_ :\n BU_ : ECU\n");
    +
    119 const DbcParseResult headers = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    120 CHECK(headers.diagnostics.empty(), "Common header variants stay quiet");
    +
    121 fixture.Write("NS_ :\n BA_\n BO_\n");
    +
    122 CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).HasErrors(),
    +
    123 "Namespace handling does not swallow a malformed frame");
    +
    124}
    +
    125
    +
    126void DbcParserTest::diagnosticErrors() {
    +
    127 Fixture fixture;
    +
    128 struct ErrorCase {
    +
    129 const char *text;
    +
    130 DbcDiagnosticCode code;
    +
    131 std::size_t line;
    +
    132 };
    +
    133 const ErrorCase cases[] = {
    +
    134 {"UNKNOWN_ data;\n\nBO_ invalid Frame: 1 ECU\n",
    +
    135 DbcDiagnosticCode::InvalidStatement, 3U},
    +
    136 {"BO_ 1 Frame: 1 ECU\nSG_MUL_VAL_ 1 Value Mode 1-2;\n",
    +
    137 DbcDiagnosticCode::UnsupportedStatement, 2U},
    +
    138 {"BO_ 1 Frame: 1 ECU\nVAL_ 1 Missing 0 \"Off\";\n",
    +
    139 DbcDiagnosticCode::InvalidValueDescription, 2U},
    +
    140 {"BO_ 1 Frame: 1 ECU\nSG_ Value m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    141 DbcDiagnosticCode::InvalidMultiplexing, 2U},
    +
    142 {"BO_ 1 Frame: 1 ECU\nSG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
    +
    143 DbcDiagnosticCode::InvalidMultiplexing, 2U},
    +
    144 {"VAL_ broken\n", DbcDiagnosticCode::InvalidValueDescription, 1U},
    +
    145 {"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    146 DbcDiagnosticCode::InvalidStatement, 1U},
    +
    147 {"BO_ 1 Frame: 1 ECU\nBO_ 1 Duplicate: 1 ECU\n",
    +
    148 DbcDiagnosticCode::InvalidStatement, 2U},
    +
    149 {"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    150 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    151 DbcDiagnosticCode::InvalidStatement, 3U},
    +
    152 {"BO_ 1 Frame: 1 ECU\nSG_ Value : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    153 DbcDiagnosticCode::InvalidStatement, 2U},
    +
    154 {"BO_ 1 Frame: 1 ECU\nVAL_ 2 Missing 0 \"Off\";\n",
    +
    155 DbcDiagnosticCode::InvalidValueDescription, 2U},
    +
    156 {"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    157 "VAL_ 1 Value 0 \"Off\";\nVAL_ 1 Value 0 \"Duplicate\";\n",
    +
    158 DbcDiagnosticCode::InvalidValueDescription, 4U},
    +
    159 {"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n"
    +
    160 "SG_ Value m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    161 DbcDiagnosticCode::InvalidMultiplexing, 3U},
    +
    162 {"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    163 "SG_ Other M : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    164 DbcDiagnosticCode::InvalidMultiplexing, 3U},
    +
    165 {"BO_ 1 Frame: 1 ECU\nSG_ First : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    166 "SG_ Second : 7|8@0+ (1,0) [0|255] \"\" ECU\n",
    +
    167 DbcDiagnosticCode::InvalidMultiplexing, 3U}
    +
    168 };
    +
    169 for (const ErrorCase &test : cases) {
    +
    170 fixture.Write(test.text);
    +
    171 const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    172 CHECK(result.HasErrors() && result.database.frames.empty(),
    +
    173 "Failed parse never returns a partial database");
    +
    174 const DbcDiagnostic &diagnostic = result.diagnostics.back();
    +
    175 CHECK(diagnostic.severity == DbcDiagnosticSeverity::Error && diagnostic.code == test.code,
    +
    176 "Error has expected severity and code");
    +
    177 QCOMPARE(diagnostic.filePath, fixture.path.string());
    +
    178 QCOMPARE(diagnostic.lineNumber, test.line);
    +
    179 CHECK(!diagnostic.message.empty(), "Error includes a message");
    +
    180 const bool hasWarning = std::string(test.text).find("UNKNOWN_") == 0U;
    +
    181 QCOMPARE(result.diagnostics.size(), hasWarning ? std::size_t(2U) : std::size_t(1U));
    +
    182 try {
    +
    183 DbcParser().ParseFile(fixture.path.string());
    +
    184 CHECK(false, "Legacy parser must throw");
    +
    185 } catch (const std::runtime_error &error) {
    +
    186 QCOMPARE(std::string(error.what()), fixture.path.string() + ":" +
    +
    187 std::to_string(test.line) + ": " + diagnostic.message);
    +
    188 }
    +
    189 }
    +
    190 const std::string missingPath = fixture.path.string() + ".missing";
    +
    191 const DbcParseResult missing = DbcParser().ParseFileWithDiagnostics(missingPath);
    +
    192 CHECK(missing.HasErrors() && missing.database.frames.empty(), "Missing file returns error");
    +
    193 QCOMPARE(missing.diagnostics.size(), std::size_t(1U));
    +
    194 CHECK(missing.diagnostics[0].code == DbcDiagnosticCode::FileOpenError,
    +
    195 "Missing file has a distinct code");
    +
    196 QCOMPARE(missing.diagnostics[0].lineNumber, std::size_t(0U));
    +
    197 QCOMPARE(missing.diagnostics[0].filePath, missingPath);
    +
    198 QCOMPARE(missing.diagnostics[0].message, "Failed to open DBC file: " + missingPath);
    +
    199 try {
    +
    200 DbcParser().ParseFile(missingPath);
    +
    201 CHECK(false, "Legacy API throws on missing file");
    +
    202 } catch (const std::runtime_error &error) {
    +
    203 QCOMPARE(std::string(error.what()), missing.diagnostics[0].message);
    +
    204 }
    +
    205 const std::string directoryPath = fixture.path.parent_path().string();
    +
    206 const DbcParseResult directory = DbcParser().ParseFileWithDiagnostics(directoryPath);
    +
    207 CHECK(directory.HasErrors() && directory.database.frames.empty(),
    +
    208 "Directory cannot be parsed as a file");
    +
    209 QCOMPARE(directory.diagnostics.size(), std::size_t(1U));
    +
    210 CHECK(directory.diagnostics[0].code == DbcDiagnosticCode::FileReadError ||
    +
    211 directory.diagnostics[0].code == DbcDiagnosticCode::FileOpenError,
    +
    212 "Directory produces a file-level error on supported platforms");
    +
    213 QCOMPARE(directory.diagnostics[0].lineNumber, std::size_t(0U));
    +
    214 QCOMPARE(directory.diagnostics[0].filePath, directoryPath);
    +
    215#ifdef __linux__
    +
    216 CHECK(directory.diagnostics[0].code == DbcDiagnosticCode::FileReadError,
    +
    217 "Linux directory input exercises the read-error path");
    +
    218 QCOMPARE(directory.diagnostics[0].message, "Failed to read DBC file: " + directoryPath);
    +
    219#endif
    +
    220 try {
    +
    221 DbcParser().ParseFile(directoryPath);
    +
    222 CHECK(false, "Legacy API throws on unreadable input");
    +
    223 } catch (const std::runtime_error &error) {
    +
    224 QCOMPARE(std::string(error.what()), directory.diagnostics[0].message);
    +
    225 }
    +
    226 fixture.Write("BO_ 1 Frame: 1 ECU\n");
    +
    227 CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).diagnostics.empty(),
    +
    228 "Diagnostics belong to an independent parse session");
    +
    229}
    +
    230
    +
    231void DbcParserTest::diagnosticUnsupportedStatements() {
    +
    232 Fixture fixture;
    +
    233 const std::string definitions =
    +
    234 "BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (2,10) [10|520] \"V\" ECU\n"
    +
    235 "CM_ SG_ 1 Value \"Signal comment\";\nVAL_ 1 Value 1 \"On\";\n";
    +
    236 const std::vector<std::string> statements = {
    +
    237 "SIG_VALTYPE_ 1 Value : 1;", "SIG_VALTYPE_ 1 Value : 2;",
    +
    238 "BA_ \"SignalType\" SG_ 1 Value 1;",
    +
    239 "BA_DEF_ SG_ \"SignalType\" INT 0 1;",
    +
    240 "BA_DEF_DEF_ \"SignalType\" 0;",
    +
    241 "BA_DEF_REL_ BU_SG_REL_ \"Relation\" INT 0 1;",
    +
    242 "BA_REL_ \"Relation\" BU_SG_REL_ ECU SG_ 1 Value 1;",
    +
    243 "SGTYPE_ Type : 8@1+ (1,0) [0|255] \"\" 0, Table;",
    +
    244 "SIG_TYPE_REF_ 1 Value : Type;",
    +
    245 "EV_ Environment : 0 [0|1] \"\" 0 1 DUMMY_NODE_VECTOR0 ECU;",
    +
    246 "ENVVAR_DATA_ Environment : 4;",
    +
    247 "VAL_TABLE_ Table 0 \"Off\" 1 \"On\";",
    +
    248 "BO_TX_BU_ 1 : ECU;", "VENDOR_EXTENSION_ data;", "UNKNOWN_"
    +
    249 };
    +
    250 for (const std::string &statement : statements) {
    +
    251 fixture.Write(definitions + statement + '\n');
    +
    252 const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    253 CHECK(!result.HasErrors(), statement);
    +
    254 QCOMPARE(result.diagnostics.size(), std::size_t(1U));
    +
    255 const DbcDiagnostic &warning = result.diagnostics[0];
    +
    256 CHECK(warning.severity == DbcDiagnosticSeverity::Warning &&
    +
    257 warning.code == DbcDiagnosticCode::UnsupportedStatement, statement);
    +
    258 QCOMPARE(warning.filePath, fixture.path.string());
    +
    259 QCOMPARE(warning.lineNumber, std::size_t(5U));
    +
    260 const std::string keyword = statement.substr(0U, statement.find(' '));
    +
    261 CHECK(warning.message.find("'" + keyword + "'") != std::string::npos, statement);
    +
    262 const DecodeDatabase runtime = DbcDecodeBuilder().Build(result.database);
    +
    263 RawCanFrame raw;
    +
    264 raw.canId = 1U;
    +
    265 raw.data = {1U};
    +
    266 const DecodedFrameValue decoded = DbcDecoder().Decode(runtime, raw);
    +
    267 CHECK(decoded.valid && decoded.signals.size() == 1U && decoded.signals[0].valid,
    +
    268 "Warnings preserve supported signal decoding");
    +
    269 QCOMPARE(decoded.signals[0].physicalValue, 12.0);
    +
    270 CHECK(decoded.signals[0].GetValueDescription() &&
    +
    271 *decoded.signals[0].GetValueDescription() == "On",
    +
    272 "Warnings preserve VAL_ descriptions");
    +
    273 QCOMPARE(runtime.frames[0].signals[0].comment, std::string("Signal comment"));
    +
    274 }
    +
    275}
    +
    276
    +
    277void DbcParserTest::diagnosticNamespaceBoundaries() {
    +
    278 Fixture fixture;
    +
    279 const std::vector<std::string> endings = {
    +
    280 "BS_\n", "BS_:\n", "BS_ :\n", "BU_\n", "BU_:\n", "BU_ : ECU\n",
    +
    281 "BO_ 1 Frame: 1 ECU\n", "VENDOR_EXTENSION_ data;\n"
    +
    282 };
    +
    283 for (const std::string &ending : endings) {
    +
    284 fixture.Write("NS_ :\n\tSG_MUL_VAL_\n\nBA_\n" + ending + "SIG_VALTYPE_\n");
    +
    285 const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    286 CHECK(!result.HasErrors(), ending);
    +
    287 const std::size_t expectedWarnings = ending.find("VENDOR_") == 0U ? 2U : 1U;
    +
    288 QCOMPARE(result.diagnostics.size(), expectedWarnings);
    +
    289 QCOMPARE(result.diagnostics.back().lineNumber, std::size_t(6U));
    +
    290 CHECK(result.diagnostics.back().message.find("SIG_VALTYPE_") != std::string::npos,
    +
    291 "Unsupported keyword outside NS_ must produce a warning");
    +
    292 }
    +
    293 for (const std::string &definition : {std::string("BO_"), std::string("SG_")}) {
    +
    294 fixture.Write("NS_:\n\tBA_\n\t" + definition + '\n');
    +
    295 const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string());
    +
    296 CHECK(result.HasErrors(), "Malformed definition ends NS_ instead of being hidden");
    +
    297 QCOMPARE(result.diagnostics.size(), std::size_t(1U));
    +
    298 QCOMPARE(result.diagnostics[0].lineNumber, std::size_t(3U));
    +
    299 }
    +
    300}
    +
    301
    +
    302void DbcParserTest::diagnosticFormatting() {
    +
    303 Fixture fixture;
    +
    304 fixture.path += " with spaces";
    +
    305 const DbcParser parser;
    +
    306 for (const std::string &text : {std::string(), std::string(" \t\r\n\n")}) {
    +
    307 fixture.Write(text);
    +
    308 const DbcParseResult empty = parser.ParseFileWithDiagnostics(fixture.path.string());
    +
    309 CHECK(!empty.HasErrors() && empty.diagnostics.empty() && empty.database.frames.empty(),
    +
    310 "Empty and whitespace-only inputs are valid");
    +
    311 }
    +
    312 fixture.Write("\r\n\tVENDOR_EXTENSION_ data;\r\n\r\nUNKNOWN_");
    +
    313 const std::string relativePath = std::filesystem::relative(fixture.path).string();
    +
    314 const DbcParseResult warnings = parser.ParseFileWithDiagnostics(relativePath);
    +
    315 CHECK(!warnings.HasErrors() && warnings.database.frames.empty(), "Warnings-only input");
    +
    316 QCOMPARE(warnings.diagnostics.size(), std::size_t(2U));
    +
    317 QCOMPARE(warnings.diagnostics[0].lineNumber, std::size_t(2U));
    +
    318 QCOMPARE(warnings.diagnostics[1].lineNumber, std::size_t(4U));
    +
    319 for (const DbcDiagnostic &warning : warnings.diagnostics)
    +
    320 QCOMPARE(warning.filePath, relativePath);
    +
    321
    +
    322 fixture.Write("UNKNOWN_ first;\nBO_ invalid Frame: 1 ECU\n"
    +
    323 "UNKNOWN_ after_error;\nSG_ broken\n");
    +
    324 const DbcParseResult stopped = parser.ParseFileWithDiagnostics(relativePath);
    +
    325 CHECK(stopped.HasErrors() && stopped.database.frames.empty(), "First error stops parsing");
    +
    326 QCOMPARE(stopped.diagnostics.size(), std::size_t(2U));
    +
    327 QCOMPARE(stopped.diagnostics[0].lineNumber, std::size_t(1U));
    +
    328 QCOMPARE(stopped.diagnostics[1].lineNumber, std::size_t(2U));
    +
    329 QCOMPARE(stopped.diagnostics[1].filePath, relativePath);
    +
    330
    +
    331 fixture.Write("VAL_ 1 Missing 0 \"Off\";\nBO_ 1 Frame: 1 ECU\nUNKNOWN_ data;\n");
    +
    332 const DbcParseResult deferred = parser.ParseFileWithDiagnostics(relativePath);
    +
    333 CHECK(deferred.HasErrors() && deferred.database.frames.empty(), "Deferred error rejects database");
    +
    334 QCOMPARE(deferred.diagnostics.size(), std::size_t(2U));
    +
    335 CHECK(deferred.diagnostics[0].severity == DbcDiagnosticSeverity::Warning &&
    +
    336 deferred.diagnostics[1].severity == DbcDiagnosticSeverity::Error,
    +
    337 "Deferred errors follow warnings in detection order");
    +
    338 QCOMPARE(deferred.diagnostics[0].lineNumber, std::size_t(3U));
    +
    339 QCOMPARE(deferred.diagnostics[1].lineNumber, std::size_t(1U));
    +
    340 QCOMPARE(deferred.diagnostics[1].filePath, relativePath);
    +
    341 fixture.Write("BO_ 1 Frame: 1 ECU");
    +
    342 const DbcParseResult recovered = parser.ParseFileWithDiagnostics(relativePath);
    +
    343 CHECK(!recovered.HasErrors() && recovered.diagnostics.empty() && recovered.database.frames.size() == 1U,
    +
    344 "Same parser has clean state after errors and accepts missing final newline");
    +
    345}
    +
    346
    +
    347void DbcParserTest::validFrames() {
    +
    348 Fixture fixture;
    +
    349 struct ValidCase {
    +
    350 const char *line;
    +
    351 std::uint32_t id;
    +
    352 bool extended;
    +
    353 unsigned length;
    +
    354 };
    +
    355 const ValidCase valid[] = {
    +
    356 {"BO_ 0 Frame: 0 ECU", 0U, false, 0U},
    +
    357 {"BO_ 2047 Frame: 8 ECU", 2047U, false, 8U},
    +
    358 {"BO_ 2048 Frame: 64 ECU", 2048U, true, 64U},
    +
    359 {"BO_ 536870911 Frame: 255 ECU", 0x1FFFFFFFU, true, 255U},
    +
    360 {"BO_ 2147483649 Frame: 8 ECU", 1U, true, 8U},
    +
    361 {"BO_ 2684354559 Frame: 8 ECU", 0x1FFFFFFFU, true, 8U},
    +
    362 {" BO_\t256\tFrame :\t8\tECU \r", 256U, false, 8U}};
    +
    363 for (const ValidCase &test: valid) {
    +
    364 fixture.Write(std::string(test.line) + '\n');
    +
    365 try {
    +
    366 const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
    +
    367 QCOMPARE(database.frames.size(), std::size_t(1U));
    +
    368 const FrameInfo &frame = database.frames[0];
    +
    369 QCOMPARE(frame.name, std::string("Frame"));
    +
    370 QCOMPARE(frame.canId, test.id);
    +
    371 QCOMPARE(frame.isExtended, test.extended);
    +
    372 QCOMPARE(static_cast<unsigned>(frame.dlc), test.length);
    +
    373 QCOMPARE(frame.transmitter, std::string("ECU"));
    +
    374 } catch (const std::exception &error) { CHECK(false, error.what()); }
    +
    375 }
    +
    376}
    +
    377
    +
    378void DbcParserTest::invalidFrames() {
    +
    379 Fixture fixture;
    +
    380 const char *invalid[] = {
    +
    381 "BO_ invalid", "BO_", "BO_ 1", "BO_ 1 : 8 ECU", "BO_ 1 Frame 8 ECU",
    +
    382 "BO_ 1 Frame:", "BO_ 1 Frame: 8", "BO_ 1 Frame: 8 ECU extra",
    +
    383 "BO_ 1 Two Names: 8 ECU", "BO_ -1 Frame: 8 ECU", "BO_ +1 Frame: 8 ECU",
    +
    384 "BO_ 1x Frame: 8 ECU", "BO_ 0x123 Frame: 8 ECU", "BO_ 1.5 Frame: 8 ECU",
    +
    385 "BO_ 4294967296 Frame: 8 ECU", "BO_ 999999999999999999999 Frame: 8 ECU",
    +
    386 "BO_ 536870912 Frame: 8 ECU", "BO_ 1073741824 Frame: 8 ECU",
    +
    387 "BO_ 2684354560 Frame: 8 ECU", "BO_ 4294967295 Frame: 8 ECU",
    +
    388 "BO_ 1 Frame: -1 ECU", "BO_ 1 Frame: +8 ECU", "BO_ 1 Frame: 8x ECU",
    +
    389 "BO_ 1 Frame: 8.5 ECU", "BO_ 1 Frame: 256 ECU",
    +
    390 "BO_ 1 Frame: 4294967296 ECU", "BO_\tinvalid"};
    +
    391 for (const char *line: invalid) {
    +
    392 fixture.Write(std::string("VERSION \"test\"\n\n") + line + '\n');
    +
    393 try {
    +
    394 DbcParser().ParseFile(fixture.path.string());
    +
    395 CHECK(false, line);
    +
    396 } catch (const std::runtime_error &error) {
    +
    397 const std::string prefix = fixture.path.string() + ":3: ";
    +
    398 CHECK(std::string(error.what()).find(prefix) == 0U &&
    +
    399 std::string(error.what()).size() > prefix.size(),
    +
    400 line);
    +
    401 }
    +
    402 }
    +
    403}
    +
    404
    +
    405void DbcParserTest::duplicateFrames() {
    +
    406 Fixture fixture;
    +
    407 struct DuplicateCase {
    +
    408 const char *firstId;
    +
    409 const char *duplicateId;
    +
    410 const char *message;
    +
    411 };
    +
    412 const DuplicateCase cases[] = {
    +
    413 {"1", "1", "Duplicate standard frame CAN ID: 1"},
    +
    414 {"2147483649", "2147483649", "Duplicate extended frame CAN ID: 1"},
    +
    415 {"2048", "2147485696", "Duplicate extended frame CAN ID: 2048"},
    +
    416 {"2147485696", "2048", "Duplicate extended frame CAN ID: 2048"},
    +
    417 {"536870911", "2684354559", "Duplicate extended frame CAN ID: 536870911"}
    +
    418 };
    +
    419 const DbcParser parser;
    +
    420 for (const DuplicateCase &test : cases) {
    +
    421 fixture.Write("BO_ " + std::string(test.firstId) + " First: 8 ECU\n"
    +
    422 "BO_ 2 Other: 8 ECU\n\n"
    +
    423 " BO_\t" + test.duplicateId + "\tSecond: 8 ECU\n");
    +
    424 try {
    +
    425 parser.ParseFile(fixture.path.string());
    +
    426 CHECK(false, "Duplicate frame must be rejected");
    +
    427 } catch (const std::runtime_error &error) {
    +
    428 QCOMPARE(std::string(error.what()), fixture.path.string() + ":4: " + test.message);
    +
    429 }
    +
    430 }
    +
    431 fixture.Write("BO_ 1 First: 8 ECU\n");
    +
    432 QCOMPARE(parser.ParseFile(fixture.path.string()).frames.size(), std::size_t(1U));
    +
    433}
    +
    434
    +
    435void DbcParserTest::duplicateSignals() {
    +
    436 Fixture fixture;
    +
    437 const std::string first = "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n";
    +
    438 const std::string duplicates[] = {
    +
    439 first,
    +
    440 " SG_\tState : 16|8@1+ (2,1) [0|511] \"V\" ECU\n",
    +
    441 "SG_ State m1 : 16|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    442 };
    +
    443 for (const std::string &duplicate : duplicates) {
    +
    444 fixture.Write("BO_ 1 Frame: 8 ECU\n" + first +
    +
    445 "SG_ Other : 8|8@1+ (1,0) [0|255] \"\" ECU\n\n" + duplicate);
    +
    446 try {
    +
    447 DbcParser().ParseFile(fixture.path.string());
    +
    448 CHECK(false, "Duplicate signal must be rejected");
    +
    449 } catch (const std::runtime_error &error) {
    +
    450 QCOMPARE(std::string(error.what()), fixture.path.string() +
    +
    451 ":5: Duplicate signal name 'State' in frame 'Frame'.");
    +
    452 }
    +
    453 }
    +
    454}
    +
    455
    +
    456void DbcParserTest::distinctDefinitions() {
    +
    457 Fixture fixture;
    +
    458 fixture.Write("BO_ 1 Shared: 1 ECU\n"
    +
    459 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    460 "BO_ 2147483649 Shared: 1 ECU\n"
    +
    461 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    462 "BO_ 2 Shared: 2 ECU\n"
    +
    463 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    464 "SG_ state : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    465 "CM_ BO_ 1 \"Standard\";\n"
    +
    466 "CM_ BO_ 2147483649 \"Extended\";\n"
    +
    467 "CM_ SG_ 1 State \"Standard state\";\n"
    +
    468 "CM_ SG_ 2147483649 State \"Extended state\";\n");
    +
    469 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    +
    470 QCOMPARE(parsed.frames.size(), std::size_t(3U));
    +
    471 QCOMPARE(parsed.frames[0].canId, parsed.frames[1].canId);
    +
    472 CHECK(!parsed.frames[0].isExtended && parsed.frames[1].isExtended,
    +
    473 "Standard and extended frames with the same numeric ID remain distinct");
    +
    474 QCOMPARE(parsed.frames[0].comment, std::string("Standard"));
    +
    475 QCOMPARE(parsed.frames[1].comment, std::string("Extended"));
    +
    476 QCOMPARE(parsed.frames[0].signals[0].comment, std::string("Standard state"));
    +
    477 QCOMPARE(parsed.frames[1].signals[0].comment, std::string("Extended state"));
    +
    478 QCOMPARE(parsed.frames[2].signals.size(), std::size_t(2U));
    +
    479 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    +
    480 RawCanFrame raw;
    +
    481 raw.canId = 1U;
    +
    482 raw.data = {7U};
    +
    483 const DecodedFrameValue standard = DbcDecoder().Decode(runtime, raw);
    +
    484 QVERIFY(standard.valid);
    +
    485 QCOMPARE(standard.definition->comment, std::string("Standard"));
    +
    486 raw.isExtended = true;
    +
    487 const DecodedFrameValue extended = DbcDecoder().Decode(runtime, raw);
    +
    488 QVERIFY(extended.valid);
    +
    489 QCOMPARE(extended.definition->comment, std::string("Extended"));
    +
    490}
    +
    491
    +
    492void DbcParserTest::integration() {
    +
    493 Fixture fixture;
    +
    494 fixture.Write(
    +
    495 "BO_TX_BU_ 256 : ECU;\nBO_ 256 Frame: 8 ECU\n"
    +
    496 " SG_ Speed : 0|16@1+ (0.5,1) [0|100] \"rpm\" ECU\n"
    +
    497 "CM_ BO_ 256 \"Frame comment\";\nCM_ SG_ 256 Speed \"Signal comment\";\n"
    +
    498 "BO_ 257 Second: 8 ECU\n");
    +
    499 const DbcDatabase database = DbcParser().ParseFile(fixture.path.string());
    +
    500 CHECK(database.frames.size() == 2U && database.frames[0].signals.size() == 1U &&
    +
    501 database.frames[0].comment == "Frame comment" &&
    +
    502 database.frames[0].signals[0].comment == "Signal comment",
    +
    503 "Integration");
    +
    504 fixture.Write("\nSG_ Speed : invalid\n");
    +
    505 try {
    +
    506 DbcParser().ParseFile(fixture.path.string());
    +
    507 CHECK(false, "Signal error location");
    +
    508 } catch (const std::runtime_error &error) {
    +
    509 CHECK(std::string(error.what()).find(fixture.path.string() + ":2: ") == 0U,
    +
    510 "Signal error location");
    +
    511 }
    +
    512}
    +
    513
    +
    514void DbcParserTest::multiplexing() {
    +
    515 Fixture fixture;
    +
    516 const std::string selector = "SG_ Mode M : 0|8@1+ (10,3) [0|255] \"\" ECU\n";
    +
    517 const std::string first = "SG_ First m1 : 8|8@1- (2,0) [-128|127] \"V\" ECU\n";
    +
    518 const std::string second = "SG_ Second m2 : 15|8@0+ (1,0) [0|255] \"\" ECU\n";
    +
    519 const std::string common = "SG_ Common : 16|8@1+ (1,0) [0|255] \"\" ECU\n";
    +
    520 fixture.Write("BO_ 1 Frame: 3 ECU\n" + first + second + common + selector +
    +
    521 "VAL_ 1 First -1 \"Negative\";\n");
    +
    522 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    +
    523 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    +
    524 CHECK(parsed.frames[0].signals[3].multiplexing.role == MultiplexRole::Selector,
    +
    525 "Selector declared after branches");
    +
    526 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
    +
    527 CHECK(tree->GetChild(0U)->GetChild(0U)->GetSignal()->multiplexing.value == 1U,
    +
    528 "Tree preserves multiplexing");
    +
    529 RawCanFrame raw;
    +
    530 raw.canId = 1U;
    +
    531 raw.data = {1U, 255U, 7U};
    +
    532 DecodedFrameValue result = DbcDecoder().Decode(runtime, raw);
    +
    533 CHECK(result.signals[0].valid && std::get<std::int64_t>(result.signals[0].rawValue) == -1 &&
    +
    534 result.signals[0].physicalValue == -2 && *result.signals[0].GetValueDescription() == "Negative",
    +
    535 "Active signed branch and VAL_ use exact raw selector");
    +
    536 CHECK(!result.signals[1].valid && result.signals[1].status == SignalDecodeStatus::Inactive &&
    +
    537 result.signals[1].GetValueDescription() == nullptr && result.signals[2].valid,
    +
    538 "Inactive branch and unconditional signal");
    +
    539 raw.data[0] = 2U;
    +
    540 result = DbcDecoder().Decode(runtime, raw);
    +
    541 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive && result.signals[1].valid &&
    +
    542 std::get<std::uint64_t>(result.signals[1].rawValue) == 255U,
    +
    543 "Motorola branch becomes active");
    +
    544 raw.data = {3U};
    +
    545 result = DbcDecoder().Decode(runtime, raw);
    +
    546 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive &&
    +
    547 result.signals[1].status == SignalDecodeStatus::Inactive &&
    +
    548 result.signals[2].status == SignalDecodeStatus::InsufficientPayload,
    +
    549 "Unmapped selector leaves branches inactive even with missing bytes");
    +
    550 raw.data = {1U};
    +
    551 result = DbcDecoder().Decode(runtime, raw);
    +
    552 CHECK(result.signals[0].status == SignalDecodeStatus::InsufficientPayload,
    +
    553 "Active branch requires payload");
    +
    554 raw.data.clear();
    +
    555 result = DbcDecoder().Decode(runtime, raw);
    +
    556 CHECK(result.signals[0].status == SignalDecodeStatus::SelectorUnavailable &&
    +
    557 result.signals[3].status == SignalDecodeStatus::InsufficientPayload,
    +
    558 "Unavailable selector does not imply inactive branch");
    +
    559
    +
    560 const std::vector<std::string> invalid = {
    +
    561 first,
    +
    562 selector + "SG_ Other M : 16|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    563 "SG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n",
    +
    564 selector + "SG_ TooLarge m256 : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    565 selector + first + "SG_ Same m1 : 15|8@0+ (1,0) [0|255] \"\" ECU\n",
    +
    566 selector + "SG_ Collision m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    567 selector + first + "SG_ Always : 8|8@1+ (1,0) [0|255] \"\" ECU\n",
    +
    568 "SG_MUL_VAL_ 1 First Mode 1-2;\n"
    +
    569 };
    +
    570 for (const std::string &signals : invalid) {
    +
    571 fixture.Write("BO_ 1 Frame: 3 ECU\n" + signals);
    +
    572 bool rejected = false;
    +
    573 try {
    +
    574 DbcParser().ParseFile(fixture.path.string());
    +
    575 } catch (const std::runtime_error &error) {
    +
    576 rejected = std::string(error.what()).find(fixture.path.string() + ":") == 0U;
    +
    577 }
    +
    578 CHECK(rejected, "Invalid multiplexing rejected with location");
    +
    579 }
    +
    580 for (const std::string marker : {"m", "m-1", "m+1", "m1M", "m18446744073709551616", "M m1"})
    +
    581 RejectSignal(fixture, "SG_ Bad " + marker + " : 8|8@1+ (1,0) [0|255] \"\" ECU");
    +
    582}
    +
    583
    +
    584void DbcParserTest::multiplexingBoundaries() {
    +
    585 Fixture fixture;
    +
    586 fixture.Write("BO_ 1 Frame: 9 ECU\n"
    +
    587 "SG_ Branch m18446744073709551615 : 64|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    588 "SG_ Mode M : 7|64@0+ (0,5) [0|1] \"\" ECU\n");
    +
    589 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    +
    590 DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    +
    591 CHECK(runtime.frames[0].signals[0].multiplexing.value == std::numeric_limits<std::uint64_t>::max(),
    +
    592 "Exact uint64 branch metadata");
    +
    593 RawCanFrame raw;
    +
    594 raw.canId = 1U;
    +
    595 raw.data = std::vector<std::uint8_t>(9U, 255U);
    +
    596 DecodedFrameValue result = DbcDecoder().Decode(runtime, raw);
    +
    597 CHECK(result.signals[0].valid && result.signals[1].valid &&
    +
    598 std::get<std::uint64_t>(result.signals[1].rawValue) == std::numeric_limits<std::uint64_t>::max(),
    +
    599 "Motorola uint64 selector compares raw value before zero scaling");
    +
    600 raw.data[7] = 254U;
    +
    601 result = DbcDecoder().Decode(runtime, raw);
    +
    602 CHECK(result.signals[0].status == SignalDecodeStatus::Inactive,
    +
    603 "Adjacent large integers remain distinct");
    +
    604 runtime.frames[0].signals[1].length = 0U;
    +
    605 result = DbcDecoder().Decode(runtime, raw);
    +
    606 CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition &&
    +
    607 result.signals[1].status == SignalDecodeStatus::InvalidDefinition,
    +
    608 "Malformed runtime selector distinguished from payload errors");
    +
    609 runtime.frames[0].signals.pop_back();
    +
    610 result = DbcDecoder().Decode(runtime, raw);
    +
    611 CHECK(result.signals[0].status == SignalDecodeStatus::InvalidDefinition,
    +
    612 "Missing runtime selector");
    +
    613 fixture.Write("BO_ 1 Frame: 2 ECU\n\n"
    +
    614 "SG_ Branch m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    615 "SG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n");
    +
    616 bool rejected = false;
    +
    617 try {
    +
    618 DbcParser().ParseFile(fixture.path.string());
    +
    619 } catch (const std::runtime_error &error) {
    +
    620 rejected = std::string(error.what()).find(fixture.path.string() + ":3: ") == 0U;
    +
    621 }
    +
    622 CHECK(rejected, "Deferred validation reports branch source line");
    +
    623 fixture.Write("BO_ 1 Frame: 2 ECU\n"
    +
    624 "SG_ A : 8|8@1+ (1,0) [0|255] \"\" ECU\n"
    +
    625 "SG_ B : 15|8@0+ (1,0) [0|255] \"\" ECU\n");
    +
    626 rejected = false;
    +
    627 try {
    +
    628 DbcParser().ParseFile(fixture.path.string());
    +
    629 } catch (const std::runtime_error &) {
    +
    630 rejected = true;
    +
    631 }
    +
    632 CHECK(rejected, "Ordinary overlapping signals rejected");
    +
    633}
    +
    634
    +
    635void DbcParserTest::invalidSignals() {
    +
    636 Fixture fixture;
    +
    637 const std::string ordinary = SignalLine("0", "8", "1+", "1", "0", "0", "255");
    +
    638 for (const std::string value: {"-1", "+1", "0junk", "0x10", "1.5",
    +
    639 "4294967296", "999999999999999999999"}) {
    +
    640 RejectSignal(fixture, SignalLine(value, "8", "1+", "1", "0", "0", "255"));
    +
    641 RejectSignal(fixture, SignalLine("0", value, "1+", "1", "0", "0", "255"));
    +
    642 }
    +
    643 for (const std::string length: {"0", "65"})
    +
    644 RejectSignal(fixture, SignalLine("0", length, "1+", "1", "0", "0", "255"));
    +
    645 for (const std::string order: {"2+", "9-", "1", "1x", "1++", "01+"})
    +
    646 RejectSignal(fixture, SignalLine("0", "8", order, "1", "0", "0", "255"));
    +
    647 for (const std::string value: {"1junk", "nan", "NaN", "inf", "-inf", "1e999", "1e-999", "0x1p2", "", "1e", "1.2.3"}) {
    +
    648 RejectSignal(fixture, SignalLine("0", "8", "1+", value, "0", "0", "255"));
    +
    649 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", value, "0", "255"));
    +
    650 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", value, "255"));
    +
    651 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", "0", value));
    +
    652 }
    +
    653 RejectSignal(fixture, SignalLine("0", "8", "1+", "1", "0", "2", "1"));
    +
    654 for (const std::string name: {"", "Two Names", "Value m1M"}) {
    +
    655 std::string line = ordinary;
    +
    656 line.replace(4U, 5U, name);
    +
    657 RejectSignal(fixture, line);
    +
    658 }
    +
    659 for (const std::string broken: {
    +
    660 "SG_", "SG_ Value", "SG_ Value : 0|8@1+ (1,0) [0|255] ECU",
    +
    661 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\"",
    +
    662 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU,",
    +
    663 "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU extra"})
    +
    664 RejectSignal(fixture, broken);
    +
    665 RejectSignal(fixture, SignalLine("64", "1", "1+", "1", "0", "0", "1"));
    +
    666 RejectSignal(fixture, SignalLine("63", "2", "1+", "1", "0", "0", "3"));
    +
    667 RejectSignal(fixture, SignalLine("56", "2", "0+", "1", "0", "0", "3"));
    +
    668 RejectSignal(fixture, SignalLine("4294967295", "64", "1+", "1", "0", "0", "1"));
    +
    669 RejectSignal(fixture, ordinary, 0U);
    +
    670 for (const char delimiter: {'|', '@', '(', ')', '[', ']', '"'}) {
    +
    671 std::string line = ordinary;
    +
    672 line.erase(line.find(delimiter), 1U);
    +
    673 RejectSignal(fixture, line);
    +
    674 }
    +
    675}
    +
    676
    +
    677void DbcParserTest::validSignals() {
    +
    678 Fixture fixture;
    +
    679 const DbcParser signalParser;
    +
    680 fixture.Write("BO_ 1 Frame: 8 ECU\n" +
    +
    681 SignalLine("0", "8", "1+", "0", "0", "0", "0") + "\n" +
    +
    682 SignalLine("8", "8", "1-", "-1", "0", "-255", "0", "Negative") + "\n");
    +
    683 const DbcDatabase factors = signalParser.ParseFile(fixture.path.string());
    +
    684 CHECK(factors.frames[0].signals.size() == 2U &&
    +
    685 factors.frames[0].signals[0].factor == 0.0 &&
    +
    686 factors.frames[0].signals[1].factor == -1.0,
    +
    687 "Zero and negative factors and equal range boundaries");
    +
    688
    +
    689 struct SignalCase {
    +
    690 const char *start;
    +
    691 const char *length;
    +
    692 const char *order;
    +
    693 unsigned payload;
    +
    694 };
    +
    695 const SignalCase validSignals[] = {
    +
    696 {"0", "1", "1+", 1U},
    +
    697 {"7", "1", "0-", 1U},
    +
    698 {"0", "64", "1+", 8U},
    +
    699 {"7", "64", "0-", 8U},
    +
    700 {"63", "1", "1+", 8U},
    +
    701 {"56", "1", "0+", 8U},
    +
    702 {"3", "12", "0+", 2U},
    +
    703 {"2039", "1", "1+", 255U}};
    +
    704 for (const SignalCase &test: validSignals) {
    +
    705 fixture.Write("BO_ 1 Frame: " + std::to_string(test.payload) + " ECU\n" +
    +
    706 SignalLine(test.start, test.length, test.order, ".5e+1", "-2.5E-1", "-1.", "+2e2") + "\n");
    +
    707 try {
    +
    708 const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
    +
    709 const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
    +
    710 QCOMPARE(signal.startBit, static_cast<std::uint32_t>(std::stoul(test.start)));
    +
    711 QCOMPARE(signal.length, static_cast<std::uint32_t>(std::stoul(test.length)));
    +
    712 QCOMPARE(signal.isLittleEndian, test.order[0] == '1');
    +
    713 QCOMPARE(signal.isSigned, test.order[1] == '-');
    +
    714 QCOMPARE(signal.factor, 5.0);
    +
    715 QCOMPARE(signal.offset, -0.25);
    +
    716 QCOMPARE(signal.minimum, -1.0);
    +
    717 QCOMPARE(signal.maximum, 200.0);
    +
    718 } catch (const std::exception &error) { CHECK(false, error.what()); }
    +
    719 }
    +
    720 fixture.Write("BO_ 1 Frame: 8 ECU\n"
    +
    721 "SG_\tValue\t:\t0 | 8 @1+ ( 1 , 0 ) [ 0 | 255 ] \"rpm\" ECU1,\tECU2\n");
    +
    722 try {
    +
    723 const DbcDatabase parsed = signalParser.ParseFile(fixture.path.string());
    +
    724 const SignalInfo &signal = parsed.frames.at(0).signals.at(0);
    +
    725 CHECK(signal.name == "Value" && signal.unit == "rpm" &&
    +
    726 signal.receivers == std::vector<std::string>({"ECU1", "ECU2"}),
    +
    727 "Signal tabs, spaces, and receiver list");
    +
    728 } catch (const std::exception &error) { CHECK(false, error.what()); }
    +
    729}
    +
    730
    +
    731void DbcParserTest::dispatch() {
    +
    732 CountingHandler::instances = 0;
    +
    733 CountingHandler::calls = 0;
    +
    734 DbcDatabase dispatchDatabase;
    +
    735 DbcParseContext context{dispatchDatabase, nullptr};
    +
    736 DbcStatementDispatcher dispatcher;
    +
    737 dispatcher.RegisterType<CountingHandler>("TEST_");
    +
    738 CHECK(dispatcher.Dispatch("TEST_ first", context) &&
    +
    739 dispatcher.Dispatch("TEST_ second", context) &&
    +
    740 CountingHandler::instances == 1 && CountingHandler::calls == 2 &&
    +
    741 dispatchDatabase.frames.size() == 2U,
    +
    742 "Factory dispatch and handler reuse");
    +
    743 CHECK(!dispatcher.Dispatch("TEST_OTHER data", context) &&
    +
    744 !dispatcher.Dispatch("BO_TX_BU_ 1 : ECU;", context) &&
    +
    745 !dispatcher.Dispatch("VAL_TABLE_ States 0 \"Stopped\";", context) &&
    +
    746 CountingHandler::calls == 2,
    +
    747 "Exact and unknown keyword dispatch");
    +
    748}
    +
    749
    +
    750void DbcParserTest::independentSessions() {
    +
    751 Fixture fixture;
    +
    752 const DbcParser parser;
    +
    753 fixture.Write("BO_ 1 First: 8 ECU\n");
    +
    754 CHECK(parser.ParseFile(fixture.path.string()).frames.size() == 1U, "First parse");
    +
    755 fixture.Write("SG_ Speed : invalid\n");
    +
    756 try {
    +
    757 parser.ParseFile(fixture.path.string());
    +
    758 CHECK(false, "Independent parse context");
    +
    759 } catch (const std::runtime_error &error) {
    +
    760 CHECK(std::string(error.what()).find("Signal found before any frame") !=
    +
    761 std::string::npos,
    +
    762 "Independent parse context");
    +
    763 }
    +
    764 fixture.Write("BO_ 2 Second: 8 ECU\n");
    +
    765 const DbcDatabase recovered = parser.ParseFile(fixture.path.string());
    +
    766 CHECK(recovered.frames.size() == 1U && recovered.frames[0].canId == 2U,
    +
    767 "Fresh parse after error");
    +
    768}
    +
    769
    +
    770
    +
    771void DbcParserTest::valueDescriptions() {
    +
    772 Fixture fixture;
    +
    773 fixture.Write(
    +
    774 "VAL_\t256\tState\t0\t\"Off\"\t1 \"On\" 2 \"Error with spaces; and \\\"quotes\\\"\";\n"
    +
    775 "BO_ 256 Status: 8 ECU\n"
    +
    776 "SG_ State : 0|8@1+ (2,10) [0|520] \"\" ECU\n"
    +
    777 "VAL_ 256 State 3 \"\";\n"
    +
    778 "VAL_ 2147483904 State -9223372036854775808 \"Minimum\" -1 \"Negative\" 9223372036854775807 \"Maximum\";\n"
    +
    779 "BO_ 2147483904 Extended: 8 ECU\n"
    +
    780 "SG_ State : 0|64@1- (1,0) [-1e20|1e20] \"\" ECU\n"
    +
    781 "BO_ 2048 Unsigned: 8 ECU\n"
    +
    782 "SG_ State : 0|64@1+ (1,0) [0|2e20] \"\" ECU\n"
    +
    783 "VAL_ 2147485696 State 9223372036854775808 \"High\" 18446744073709551615 \"Full\";\n");
    +
    784 const DbcDatabase parsed = DbcParser().ParseFile(fixture.path.string());
    +
    785 const DecodeDatabase runtime = DbcDecodeBuilder().Build(parsed);
    +
    786 const std::unique_ptr<TreeNode> tree = DbcTreeBuilder().Build(parsed);
    +
    787 CHECK(tree->GetChild(0)->GetSignal() == nullptr, "Frame node");
    +
    788 for (std::size_t index = 0; index < parsed.frames.size(); ++index) {
    +
    789 CHECK(tree->GetChild(index)->GetChild(0)->GetSignal()->valueDescriptions ==
    +
    790 parsed.frames[index].signals[0].valueDescriptions &&
    +
    791 runtime.frames[index].signals[0].valueDescriptions ==
    +
    792 parsed.frames[index].signals[0].valueDescriptions,
    +
    793 "All mappings survive both builders");
    +
    794 }
    +
    795 CHECK(tree->GetChild(0)->GetChild(0)->GetSignal()->valueDescriptions ==
    +
    796 runtime.frames[0].signals[0].valueDescriptions,
    +
    797 "Both builders preserve descriptions");
    +
    798 RawCanFrame frame;
    +
    799 frame.canId = 256;
    +
    800 frame.data.resize(8);
    +
    801 const std::string expected[] = {"Off", "On", "Error with spaces; and \"quotes\"", ""};
    +
    802 for (unsigned value = 0; value < 5; ++value) {
    +
    803 frame.data[0] = value;
    +
    804 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    +
    805 CHECK(decoded.valid && decoded.physicalValue == value * 2 + 10, "Numeric scaling unchanged");
    +
    806 const std::string *description = decoded.GetValueDescription();
    +
    807 CHECK(value < 4 ? description && *description == expected[value] : !description,
    +
    808 "Raw lookup and unknown value");
    +
    809 }
    +
    810 frame.isExtended = true;
    +
    811 struct Boundary {
    +
    812 std::uint64_t bits;
    +
    813 const char *description;
    +
    814 };
    +
    815 for (const Boundary &test: {Boundary{0x8000000000000000ULL, "Minimum"},
    +
    816 Boundary{0xFFFFFFFFFFFFFFFFULL, "Negative"},
    +
    817 Boundary{0x7FFFFFFFFFFFFFFFULL, "Maximum"}}) {
    +
    818 for (unsigned byte = 0; byte < 8; ++byte)
    +
    819 frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
    +
    820 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    +
    821 CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
    +
    822 "Signed boundaries and distinct extended frame");
    +
    823 }
    +
    824 frame.canId = 2048;
    +
    825 for (const Boundary &test: {Boundary{0x8000000000000000ULL, "High"},
    +
    826 Boundary{0xFFFFFFFFFFFFFFFFULL, "Full"}}) {
    +
    827 for (unsigned byte = 0; byte < 8; ++byte)
    +
    828 frame.data[byte] = static_cast<std::uint8_t>(test.bits >> (byte * 8));
    +
    829 const DecodedSignalValue decoded = DbcDecoder().Decode(runtime, frame).signals[0];
    +
    830 CHECK(decoded.GetValueDescription() && *decoded.GetValueDescription() == test.description,
    +
    831 "Unsigned boundaries");
    +
    832 }
    +
    833 CHECK(FindValueDescription(runtime.frames[0].signals[0].valueDescriptions, std::int64_t(1)) != nullptr,
    +
    834 "Nonnegative signed lookup matches unsigned key");
    +
    835 frame.data.clear();
    +
    836 CHECK(!DbcDecoder().Decode(runtime, frame).signals[0].GetValueDescription(), "Invalid decode has no description");
    +
    837}
    +
    838
    +
    839void DbcParserTest::invalidValueDescriptions() {
    +
    840 Fixture fixture;
    +
    841 const std::string definitions = "BO_ 1 Frame: 8 ECU\nSG_ State : 0|64@1+ (1,0) [0|2e20] \"\" ECU\n";
    +
    842 for (const std::string statement: {
    +
    843 "VAL_", "VAL_ 1 State;", "VAL_ 1 State ;", "VAL_ 1 State 0 \"Off\"",
    +
    844 "VAL_ 1 State 0 \"Off\"; junk", "VAL_ 1 State 0 Off;",
    +
    845 "VAL_ 1 State 0 \"Unclosed;", "VAL_ 1 State 0 \"Off\"1 \"On\";",
    +
    846 "VAL_ 1 State 0 \"Off\" 00 \"Duplicate\";",
    +
    847 "VAL_ 1 State 0 \"Off\" -0 \"Duplicate\";",
    +
    848 "VAL_ 1 State 0 \"Off\";\nVAL_ 1 State 0 \"Duplicate\";",
    +
    849 "VAL_ 2 State 0 \"Missing frame\";", "VAL_ 1 Missing 0 \"Missing signal\";",
    +
    850 "VAL_ -1 State 0 \"Bad ID\";", "VAL_ 536870912 State 0 \"Bad ID\";",
    +
    851 "VAL_ 4294967296 State 0 \"Bad ID\";", "VAL_ Environment 0 \"Unsupported\";",
    +
    852 "VAL_ 1 State 0 \"Bad\\q escape\";"}) {
    +
    853 fixture.Write(definitions + statement + '\n');
    +
    854 const int line = statement.find('\n') == std::string::npos ? 3 : 4;
    +
    855 try {
    +
    856 DbcParser().ParseFile(fixture.path.string());
    +
    857 CHECK(false, statement);
    +
    858 } catch (const std::runtime_error &error) {
    +
    859 CHECK(std::string(error.what()).find(fixture.path.string() + ":" + std::to_string(line) + ": ") == 0,
    +
    860 statement + " " + error.what());
    +
    861 }
    +
    862 }
    +
    863 for (const std::string suffix: {
    +
    864 "BO_ 1 Other: 8 ECU\n", // Duplicate frame definition.
    +
    865 "SG_ State : 0|8@1+ (1,0) [0|255] \"\" ECU\n",// Duplicate signal definition.
    +
    866 ""}) {
    +
    867 fixture.Write("VAL_ 1 " + std::string(suffix.empty() ? "Missing" : "State") +
    +
    868 " 0 \"Description\";\n" + definitions + suffix);
    +
    869 try {
    +
    870 DbcParser().ParseFile(fixture.path.string());
    +
    871 CHECK(false, "Missing reference or duplicate definition");
    +
    872 } catch (const std::runtime_error &error) {
    +
    873 const std::string line = suffix.empty() ? "1" : "4";
    +
    874 CHECK(std::string(error.what()).find(fixture.path.string() + ":" + line + ": ") == 0,
    +
    875 "Error retains the reference or duplicate definition source location");
    +
    876 }
    +
    877 }
    +
    878 for (const std::string number: {"+1", "1x", "0x10", "1.5", "1e2", "--1",
    +
    879 "-9223372036854775809", "18446744073709551616"}) {
    +
    880 fixture.Write("VAL_ 1 State " + number + " \"Bad\";\n" + definitions);
    +
    881 try {
    +
    882 DbcParser().ParseFile(fixture.path.string());
    +
    883 CHECK(false, number);
    +
    884 } catch (const std::runtime_error &error) {
    +
    885 CHECK(std::string(error.what()).find(fixture.path.string() + ":1: ") == 0, number);
    +
    886 }
    +
    887 }
    +
    888}
    +
    889
    +
    890int RunParserTests(int argc, char **argv) {
    +
    891 DbcParserTest tests;
    +
    892 return QTest::qExec(&tests, argc, argv);
    +
    893}
    +
    894
    +
    895#include "dbc_parser_test.moc"
    Converts parsed DBC data into runtime decode database.
    DecodeDatabase Build(const DbcDatabase &source) const
    Build runtime decode database.
    Runtime CAN decoder using prebuilt decode database.
    Definition dbc_decoder.h:72
    DecodedFrameValue Decode(const DecodeDatabase &database, const RawCanFrame &frame) const
    Decode one raw CAN frame.
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    - -
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    - +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    +
    DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const
    Parse with warnings and a structured first error instead of throwing.
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    + +
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    +
    Builds a simple tree from parsed DBC database.
    std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
    Build tree representation of parsed DBC data.
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    @@ -745,7 +1011,9 @@ $(document).ready(function(){initNavTree('dbc__parser__test_8cpp_source.html',''
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    Parsed DBC content stored in a simple internal form.
    std::vector< FrameInfo > frames
    - + + +
    Runtime decode database with fast lookup by CAN ID.
    std::string comment
    Fully decoded frame.
    Definition dbc_decoder.h:61
    diff --git a/docs/html/dbc__statement__handler_8cpp_source.html b/docs/html/dbc__statement__handler_8cpp_source.html index 97e7cb9..b515b56 100644 --- a/docs/html/dbc__statement__handler_8cpp_source.html +++ b/docs/html/dbc__statement__handler_8cpp_source.html @@ -472,157 +472,170 @@ $(document).ready(function(){initNavTree('dbc__statement__handler_8cpp_source.ht
    372}
    373
    374DbcStatementDispatcher::DbcStatementDispatcher() {
    -
    375 RegisterType<DbcUnsupportedMultiplexingHandler>("SG_MUL_VAL_");
    -
    376 RegisterType<DbcFrameHandler>("BO_");
    -
    377 RegisterType<DbcSignalHandler>("SG_");
    -
    378 RegisterType<DbcCommentHandler>("CM_");
    -
    379 RegisterType<DbcValueDescriptionHandler>("VAL_");
    -
    380}
    -
    381
    -
    -
    382bool DbcStatementDispatcher::Dispatch(const std::string &line,
    -
    383 DbcParseContext &context) const {
    -
    384 std::istringstream stream(line);
    -
    385 std::string keyword;
    -
    386 stream >> keyword;
    -
    387 const HandlerMap::const_iterator handler = m_handlers.find(keyword);
    -
    388 if (handler == m_handlers.end())
    -
    389 return false;
    -
    390 handler->second->Handle(line, context);
    -
    391 return true;
    -
    392}
    +
    375 RegisterType<DbcHeaderHandler>("VERSION");
    +
    376 RegisterType<DbcHeaderHandler>("NS_");
    +
    377 RegisterType<DbcHeaderHandler>("NS_:");
    +
    378 RegisterType<DbcHeaderHandler>("BS_");
    +
    379 RegisterType<DbcHeaderHandler>("BS_:");
    +
    380 RegisterType<DbcHeaderHandler>("BU_");
    +
    381 RegisterType<DbcHeaderHandler>("BU_:");
    +
    382 RegisterType<DbcUnsupportedMultiplexingHandler>("SG_MUL_VAL_");
    +
    383 RegisterType<DbcFrameHandler>("BO_");
    +
    384 RegisterType<DbcSignalHandler>("SG_");
    +
    385 RegisterType<DbcCommentHandler>("CM_");
    +
    386 RegisterType<DbcValueDescriptionHandler>("VAL_");
    +
    387}
    +
    388
    +
    389void DbcHeaderHandler::Handle(const std::string &, DbcParseContext &) const {}
    +
    390
    +
    +
    391bool DbcStatementDispatcher::Dispatch(const std::string &line,
    +
    392 DbcParseContext &context) const {
    +
    393 std::istringstream stream(line);
    +
    394 std::string keyword;
    +
    395 stream >> keyword;
    +
    396 const HandlerMap::const_iterator handler = m_handlers.find(keyword);
    +
    397 if (handler == m_handlers.end())
    +
    398 return false;
    +
    399 handler->second->Handle(line, context);
    +
    400 return true;
    +
    401}
    -
    393
    -
    394void DbcValueDescriptionHandler::Handle(const std::string &line, DbcParseContext &context) const {
    -
    395 static const std::regex header(R"(^VAL_[ \t]+([^ \t]+)[ \t]+([^ \t;]+)[ \t]+(.*)$)");
    -
    396 static const std::regex pair(R"dbc(^([^ \t]+)[ \t]+"((?:[^"\\]|\\["\\])*)")dbc");
    -
    397 std::smatch fields;
    -
    398 if (!std::regex_match(line, fields, header))
    -
    399 throw std::runtime_error("Malformed or unsupported VAL_ statement.");
    -
    400 const std::uint32_t rawId = ParseDecimal(fields[1].str(), std::numeric_limits<std::uint32_t>::max(), "VAL_ CAN ID");
    -
    401 if ((rawId & 0x60000000U) != 0U)
    -
    402 throw std::runtime_error("VAL_ CAN ID exceeds the 29-bit identifier range.");
    - -
    404 NormalizeCanId(rawId, pending.canId, pending.isExtended);
    -
    405 pending.signalName = fields[2].str();
    -
    406 pending.lineNumber = context.lineNumber;
    -
    407 std::string rest = fields[3].str();
    -
    408 while (rest != ";") {
    -
    409 if (!std::regex_search(rest, fields, pair))
    -
    410 throw std::runtime_error("Malformed VAL_ value/description pair or missing semicolon.");
    -
    411 const std::string number = fields[1].str();
    -
    412 const RawSignalValue key = ParseValueKey(number);
    -
    413 const std::string description = UnescapeDescription(fields[2].str());
    -
    414 if (!pending.descriptions.emplace(key, description).second)
    -
    415 throw std::runtime_error("Duplicate VAL_ value key: " + number);
    -
    416 const std::size_t consumed = static_cast<std::size_t>(fields.length());
    -
    417 rest.erase(0, consumed);
    -
    418 if (!rest.empty() && rest[0] != ';' && rest[0] != ' ' && rest[0] != '\t')
    -
    419 throw std::runtime_error("Missing whitespace between VAL_ pairs.");
    -
    420 rest = dbc_detail::TrimText(rest);
    -
    421 }
    -
    422 if (pending.descriptions.empty())
    -
    423 throw std::runtime_error("VAL_ requires at least one value/description pair.");
    -
    424 context.pendingValues.push_back(std::move(pending));
    -
    425}
    -
    426
    -
    427void DbcParseContext::ResolveValueDescriptions(const std::string &filePath) {
    -
    428 for (const PendingValueDescriptions &pending: pendingValues) {
    -
    429 try {
    -
    430 FrameInfo *frame = FindUniqueFrame(database, pending.canId, pending.isExtended);
    -
    431 SignalInfo *signal = FindUniqueSignal(*frame, pending.signalName);
    -
    432 for (const ValueDescriptions::value_type &entry: pending.descriptions) {
    -
    433 if (!signal->valueDescriptions.insert(entry).second)
    -
    434 throw std::runtime_error("Duplicate VAL_ value key for signal: " + pending.signalName);
    -
    435 }
    -
    436 } catch (const std::exception &error) {
    -
    437 throw std::runtime_error(filePath + ":" + std::to_string(pending.lineNumber) + ": " + error.what());
    -
    438 }
    -
    439 }
    -
    440}
    -
    441
    -
    442void DbcUnsupportedMultiplexingHandler::Handle(const std::string &, DbcParseContext &) const {
    -
    443 throw std::runtime_error("Extended and nested multiplexing are unsupported.");
    -
    444}
    -
    445
    -
    446namespace {
    -
    447 std::vector<std::uint64_t> SignalBits(const SignalInfo &signal) {
    -
    448 std::vector<std::uint64_t> bits;
    -
    449 std::uint64_t bit = signal.startBit;
    -
    450 for (std::uint32_t index = 0U; index < signal.length; ++index) {
    -
    451 bits.push_back(bit);
    -
    452 bit = NextSignalBit(bit, signal.isLittleEndian);
    -
    453 }
    -
    454 return bits;
    -
    455 }
    -
    456
    -
    457 bool AreMutuallyExclusive(const SignalInfo &first, const SignalInfo &second) {
    -
    458 return first.multiplexing.role == MultiplexRole::Branch &&
    -
    459 second.multiplexing.role == MultiplexRole::Branch &&
    -
    460 first.multiplexing.value != second.multiplexing.value;
    -
    461 }
    -
    462
    -
    463 std::string ValidateBranch(const SignalInfo &signal, const SignalInfo *selector) {
    -
    464 if (signal.multiplexing.role != MultiplexRole::Branch)
    -
    465 return {};
    -
    466 if (selector == nullptr)
    -
    467 return "Multiplexed branch has no selector.";
    -
    468 if (selector->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector->length))
    -
    469 return "Branch value exceeds selector raw range.";
    -
    470 return {};
    +
    402
    +
    403void DbcValueDescriptionHandler::Handle(const std::string &line, DbcParseContext &context) const {
    +
    404 static const std::regex header(R"(^VAL_[ \t]+([^ \t]+)[ \t]+([^ \t;]+)[ \t]+(.*)$)");
    +
    405 static const std::regex pair(R"dbc(^([^ \t]+)[ \t]+"((?:[^"\\]|\\["\\])*)")dbc");
    +
    406 std::smatch fields;
    +
    407 if (!std::regex_match(line, fields, header))
    +
    408 throw std::runtime_error("Malformed or unsupported VAL_ statement.");
    +
    409 const std::uint32_t rawId = ParseDecimal(fields[1].str(), std::numeric_limits<std::uint32_t>::max(), "VAL_ CAN ID");
    +
    410 if ((rawId & 0x60000000U) != 0U)
    +
    411 throw std::runtime_error("VAL_ CAN ID exceeds the 29-bit identifier range.");
    + +
    413 NormalizeCanId(rawId, pending.canId, pending.isExtended);
    +
    414 pending.signalName = fields[2].str();
    +
    415 pending.lineNumber = context.lineNumber;
    +
    416 std::string rest = fields[3].str();
    +
    417 while (rest != ";") {
    +
    418 if (!std::regex_search(rest, fields, pair))
    +
    419 throw std::runtime_error("Malformed VAL_ value/description pair or missing semicolon.");
    +
    420 const std::string number = fields[1].str();
    +
    421 const RawSignalValue key = ParseValueKey(number);
    +
    422 const std::string description = UnescapeDescription(fields[2].str());
    +
    423 if (!pending.descriptions.emplace(key, description).second)
    +
    424 throw std::runtime_error("Duplicate VAL_ value key: " + number);
    +
    425 const std::size_t consumed = static_cast<std::size_t>(fields.length());
    +
    426 rest.erase(0, consumed);
    +
    427 if (!rest.empty() && rest[0] != ';' && rest[0] != ' ' && rest[0] != '\t')
    +
    428 throw std::runtime_error("Missing whitespace between VAL_ pairs.");
    +
    429 rest = dbc_detail::TrimText(rest);
    +
    430 }
    +
    431 if (pending.descriptions.empty())
    +
    432 throw std::runtime_error("VAL_ requires at least one value/description pair.");
    +
    433 context.pendingValues.push_back(std::move(pending));
    +
    434}
    +
    435
    +
    436void DbcParseContext::ResolveValueDescriptions(const std::string &filePath) {
    +
    437 for (const PendingValueDescriptions &pending: pendingValues) {
    +
    438 try {
    +
    439 FrameInfo *frame = FindUniqueFrame(database, pending.canId, pending.isExtended);
    +
    440 SignalInfo *signal = FindUniqueSignal(*frame, pending.signalName);
    +
    441 for (const ValueDescriptions::value_type &entry: pending.descriptions) {
    +
    442 if (!signal->valueDescriptions.insert(entry).second)
    +
    443 throw std::runtime_error("Duplicate VAL_ value key for signal: " + pending.signalName);
    +
    444 }
    +
    445 } catch (const std::exception &error) {
    +
    446 throw DbcDiagnosticError(DbcDiagnosticCode::InvalidValueDescription,
    +
    447 filePath, pending.lineNumber, error.what());
    +
    448 }
    +
    449 }
    +
    450}
    +
    451
    +
    452void DbcUnsupportedMultiplexingHandler::Handle(const std::string &, DbcParseContext &) const {
    +
    453 throw std::runtime_error("Extended and nested multiplexing are unsupported.");
    +
    454}
    +
    455
    +
    456namespace {
    +
    457 std::vector<std::uint64_t> SignalBits(const SignalInfo &signal) {
    +
    458 std::vector<std::uint64_t> bits;
    +
    459 std::uint64_t bit = signal.startBit;
    +
    460 for (std::uint32_t index = 0U; index < signal.length; ++index) {
    +
    461 bits.push_back(bit);
    +
    462 bit = NextSignalBit(bit, signal.isLittleEndian);
    +
    463 }
    +
    464 return bits;
    +
    465 }
    +
    466
    +
    467 bool AreMutuallyExclusive(const SignalInfo &first, const SignalInfo &second) {
    +
    468 return first.multiplexing.role == MultiplexRole::Branch &&
    +
    469 second.multiplexing.role == MultiplexRole::Branch &&
    +
    470 first.multiplexing.value != second.multiplexing.value;
    471 }
    472
    -
    473 const SignalInfo *FindSelector(const FrameInfo &frame,
    -
    474 const std::vector<std::size_t> &lines,
    -
    475 const std::string &filePath) {
    -
    476 const SignalInfo *selector = nullptr;
    -
    477 for (std::size_t index = 0U; index < frame.signals.size(); ++index) {
    -
    478 const SignalInfo &signal = frame.signals[index];
    -
    479 if (signal.multiplexing.role != MultiplexRole::Selector)
    -
    480 continue;
    -
    481 if (selector != nullptr || signal.isSigned)
    -
    482 throw std::runtime_error(filePath + ":" + std::to_string(lines[index]) +
    -
    483 ": Multiplexing requires one unsigned selector per frame.");
    -
    484 selector = &signal;
    -
    485 }
    -
    486 return selector;
    -
    487 }
    -
    488
    -
    489 bool SignalsOverlap(const SignalInfo &first, const SignalInfo &second) {
    -
    490 const std::vector<std::uint64_t> firstBits = SignalBits(first);
    -
    491 const std::vector<std::uint64_t> secondBits = SignalBits(second);
    -
    492 for (const std::uint64_t firstBit : firstBits) {
    -
    493 for (const std::uint64_t secondBit : secondBits) {
    -
    494 if (firstBit == secondBit)
    -
    495 return true;
    -
    496 }
    -
    497 }
    -
    498 return false;
    -
    499 }
    -
    500}
    -
    501
    -
    502void DbcParseContext::ValidateMultiplexing(const std::string &filePath) const {
    -
    503 for (std::size_t frameIndex = 0U; frameIndex < database.frames.size(); ++frameIndex) {
    -
    504 const FrameInfo &frame = database.frames[frameIndex];
    -
    505 const SignalInfo *selector = FindSelector(frame, signalLines[frameIndex], filePath);
    -
    506 for (std::size_t index = 0U; index < frame.signals.size(); ++index) {
    -
    507 const SignalInfo &signal = frame.signals[index];
    -
    508 std::string error = ValidateBranch(signal, selector);
    -
    509 for (std::size_t previous = 0U; previous < index && error.empty(); ++previous) {
    -
    510 const SignalInfo &other = frame.signals[previous];
    -
    511 if (!AreMutuallyExclusive(signal, other) && SignalsOverlap(signal, other))
    -
    512 error = "Signals overlap without mutually exclusive multiplexing conditions.";
    -
    513 }
    -
    514 if (!error.empty())
    -
    515 throw std::runtime_error(filePath + ":" + std::to_string(signalLines[frameIndex][index]) + ": " + error);
    -
    516 }
    -
    517 }
    -
    518}
    -
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    +
    473 std::string ValidateBranch(const SignalInfo &signal, const SignalInfo *selector) {
    +
    474 if (signal.multiplexing.role != MultiplexRole::Branch)
    +
    475 return {};
    +
    476 if (selector == nullptr)
    +
    477 return "Multiplexed branch has no selector.";
    +
    478 if (selector->length < 64U && signal.multiplexing.value >= (std::uint64_t(1U) << selector->length))
    +
    479 return "Branch value exceeds selector raw range.";
    +
    480 return {};
    +
    481 }
    +
    482
    +
    483 const SignalInfo *FindSelector(const FrameInfo &frame,
    +
    484 const std::vector<std::size_t> &lines,
    +
    485 const std::string &filePath) {
    +
    486 const SignalInfo *selector = nullptr;
    +
    487 for (std::size_t index = 0U; index < frame.signals.size(); ++index) {
    +
    488 const SignalInfo &signal = frame.signals[index];
    +
    489 if (signal.multiplexing.role != MultiplexRole::Selector)
    +
    490 continue;
    +
    491 if (selector != nullptr || signal.isSigned)
    +
    492 throw DbcDiagnosticError(DbcDiagnosticCode::InvalidMultiplexing,
    +
    493 filePath, lines[index],
    +
    494 "Multiplexing requires one unsigned selector per frame.");
    +
    495 selector = &signal;
    +
    496 }
    +
    497 return selector;
    +
    498 }
    +
    499
    +
    500 bool SignalsOverlap(const SignalInfo &first, const SignalInfo &second) {
    +
    501 const std::vector<std::uint64_t> firstBits = SignalBits(first);
    +
    502 const std::vector<std::uint64_t> secondBits = SignalBits(second);
    +
    503 for (const std::uint64_t firstBit : firstBits) {
    +
    504 for (const std::uint64_t secondBit : secondBits) {
    +
    505 if (firstBit == secondBit)
    +
    506 return true;
    +
    507 }
    +
    508 }
    +
    509 return false;
    +
    510 }
    +
    511}
    +
    512
    +
    513void DbcParseContext::ValidateMultiplexing(const std::string &filePath) const {
    +
    514 for (std::size_t frameIndex = 0U; frameIndex < database.frames.size(); ++frameIndex) {
    +
    515 const FrameInfo &frame = database.frames[frameIndex];
    +
    516 const SignalInfo *selector = FindSelector(frame, signalLines[frameIndex], filePath);
    +
    517 for (std::size_t index = 0U; index < frame.signals.size(); ++index) {
    +
    518 const SignalInfo &signal = frame.signals[index];
    +
    519 std::string error = ValidateBranch(signal, selector);
    +
    520 for (std::size_t previous = 0U; previous < index && error.empty(); ++previous) {
    +
    521 const SignalInfo &other = frame.signals[previous];
    +
    522 if (!AreMutuallyExclusive(signal, other) && SignalsOverlap(signal, other))
    +
    523 error = "Signals overlap without mutually exclusive multiplexing conditions.";
    +
    524 }
    +
    525 if (!error.empty())
    +
    526 throw DbcDiagnosticError(DbcDiagnosticCode::InvalidMultiplexing,
    +
    527 filePath, signalLines[frameIndex][index], error);
    +
    528 }
    +
    529 }
    +
    530}
    + +
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    ByteOrder
    Signal byte order used for runtime decoding.
    Parsed DBC content stored in a simple internal form.
    std::vector< FrameInfo > frames
    - +
    Describes one CAN frame from a DBC file.
    Definition frame_info.h:24
    bool isExtended
    Definition frame_info.h:27
    bool hasPgn
    Definition frame_info.h:29
    @@ -633,7 +646,7 @@ $(document).ready(function(){initNavTree('dbc__statement__handler_8cpp_source.ht
    std::uint32_t pgn
    Definition frame_info.h:28
    std::uint32_t canId
    Definition frame_info.h:26
    - +
    Describes one signal inside a DBC frame.
    Definition signal_info.h:24
    std::uint32_t length
    Definition signal_info.h:28
    std::string unit
    Definition signal_info.h:35
    diff --git a/docs/html/dbc__statement__handler_8h_source.html b/docs/html/dbc__statement__handler_8h_source.html index 1aa4f62..139f96a 100644 --- a/docs/html/dbc__statement__handler_8h_source.html +++ b/docs/html/dbc__statement__handler_8h_source.html @@ -103,123 +103,147 @@ $(document).ready(function(){initNavTree('dbc__statement__handler_8h_source.html
    3#define DBC_STATEMENT_HANDLER_H
    4
    5#include "dbc_database.h"
    -
    6#include "typefactory.h"
    -
    7#include <string>
    -
    8#include <unordered_map>
    -
    9
    -
    - -
    11 std::uint32_t canId;
    -
    12 bool isExtended;
    -
    13 std::string signalName;
    -
    14 ValueDescriptions descriptions;
    -
    15 std::size_t lineNumber;
    -
    16};
    +
    6#include "dbc_diagnostic.h"
    +
    7#include "typefactory.h"
    +
    8#include <stdexcept>
    +
    9#include <string>
    +
    10#include <unordered_map>
    +
    11
    +
    + +
    13 std::uint32_t canId;
    +
    14 bool isExtended;
    +
    15 std::string signalName;
    +
    16 ValueDescriptions descriptions;
    +
    17 std::size_t lineNumber;
    +
    18};
    -
    17
    -
    - -
    20 DbcDatabase &database;
    -
    21 FrameInfo *currentFrame = nullptr;
    -
    22 std::size_t lineNumber = 0U;
    -
    23 std::vector<PendingValueDescriptions> pendingValues = {};
    -
    24
    -
    25 std::vector<std::vector<std::size_t>> signalLines = {};
    -
    26 void ValidateMultiplexing(const std::string &filePath) const;
    +
    19
    +
    +
    21class DbcDiagnosticError : public std::runtime_error {
    +
    22public:
    +
    23 DbcDiagnosticError(DbcDiagnosticCode code, const std::string &filePath,
    +
    24 std::size_t lineNumber, const std::string &message)
    +
    25 : std::runtime_error(filePath + ":" + std::to_string(lineNumber) + ": " + message),
    +
    26 diagnostic{DbcDiagnosticSeverity::Error, code, filePath, lineNumber, message} {}
    27
    -
    28 void ResolveValueDescriptions(const std::string &filePath);
    +
    28 DbcDiagnostic diagnostic;
    29};
    30
    -
    - -
    32public:
    -
    33 virtual ~DbcStatementHandler() = default;
    -
    34 virtual void Handle(const std::string &line, DbcParseContext &context) const = 0;
    -
    35};
    -
    -
    36
    -
    - -
    38public:
    -
    39 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    + +
    33 DbcDatabase &database;
    +
    34 FrameInfo *currentFrame = nullptr;
    +
    35 std::size_t lineNumber = 0U;
    +
    36 std::vector<PendingValueDescriptions> pendingValues = {};
    +
    37
    +
    38 std::vector<std::vector<std::size_t>> signalLines = {};
    +
    39 void ValidateMultiplexing(const std::string &filePath) const;
    40
    -
    41private:
    -
    42 static FrameInfo ParseFrameLine(const std::string &line);
    -
    43};
    +
    41 void ResolveValueDescriptions(const std::string &filePath);
    +
    42};
    -
    44
    -
    - -
    46public:
    -
    47 void Handle(const std::string &line, DbcParseContext &context) const override;
    -
    48
    -
    49private:
    -
    50 static SignalInfo ParseSignalLine(const std::string &line);
    -
    51};
    +
    43
    +
    + +
    45public:
    +
    46 virtual ~DbcStatementHandler() = default;
    +
    47 virtual void Handle(const std::string &line, DbcParseContext &context) const = 0;
    +
    48};
    -
    52
    -
    - -
    54public:
    -
    55 void Handle(const std::string &line, DbcParseContext &context) const override;
    -
    56
    -
    57private:
    -
    58 static void ParseCommentLine(const std::string &line, DbcDatabase &database);
    -
    59};
    +
    49
    +
    + +
    51public:
    +
    52 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    53
    +
    54private:
    +
    55 static FrameInfo ParseFrameLine(const std::string &line);
    +
    56};
    -
    60
    -
    - -
    62public:
    -
    63 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    57
    +
    + +
    59public:
    +
    60 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    61
    +
    62private:
    +
    63 static SignalInfo ParseSignalLine(const std::string &line);
    64};
    65
    - +
    67public:
    68 void Handle(const std::string &line, DbcParseContext &context) const override;
    -
    69};
    +
    69
    +
    70private:
    +
    71 static void ParseCommentLine(const std::string &line, DbcDatabase &database);
    +
    72};
    -
    70
    -
    - -
    73public:
    - -
    75
    -
    76 template<class Handler>
    -
    77 void RegisterType(const std::string &keyword) {
    -
    78 m_factory.registerType<Handler>(keyword);
    -
    79 m_handlers.insert_or_assign(keyword, m_factory.create(keyword));
    -
    80 }
    -
    81
    -
    83 bool Dispatch(const std::string &line, DbcParseContext &context) const;
    -
    84
    -
    85private:
    -
    86 using HandlerMap = std::unordered_map<std::string, std::shared_ptr<DbcStatementHandler>>;
    - -
    88 HandlerMap m_handlers;
    -
    89};
    +
    73
    +
    + +
    75public:
    +
    76 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    77};
    -
    90
    -
    91#endif /* DBC_STATEMENT_HANDLER_H */
    - - - - -
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    - - - +
    78
    +
    + +
    80public:
    +
    81 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    82};
    +
    +
    83
    +
    + +
    86public:
    +
    87 void Handle(const std::string &line, DbcParseContext &context) const override;
    +
    88};
    +
    +
    89
    +
    + +
    92public:
    + +
    94
    +
    95 template<class Handler>
    +
    96 void RegisterType(const std::string &keyword) {
    +
    97 m_factory.registerType<Handler>(keyword);
    +
    98 m_handlers.insert_or_assign(keyword, m_factory.create(keyword));
    +
    99 }
    +
    100
    +
    102 bool Dispatch(const std::string &line, DbcParseContext &context) const;
    +
    103
    +
    104private:
    +
    105 using HandlerMap = std::unordered_map<std::string, std::shared_ptr<DbcStatementHandler>>;
    + +
    107 HandlerMap m_handlers;
    +
    108};
    +
    +
    109
    +
    110#endif /* DBC_STATEMENT_HANDLER_H */
    + + + + + + +
    bool Dispatch(const std::string &line, DbcParseContext &context) const
    + + +
    Registry-based factory for creating objects by runtime identifier.
    Definition typefactory.h:59
    BasePtr create(const ClassId &id, Args... args) const
    Creates an instance for the given id using provided arguments.
    Definition typefactory.h:97
    void registerType(const ClassId &id)
    Registers a Derived type under the given id.
    Definition typefactory.h:76
    Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
    Parsed DBC content stored in a simple internal form.
    - + +
    Describes one CAN frame from a DBC file.
    Definition frame_info.h:24
    - +
    Describes one signal inside a DBC frame.
    Definition signal_info.h:24
    diff --git a/docs/html/dbc__tree__model__test_8cpp_source.html b/docs/html/dbc__tree__model__test_8cpp_source.html index b9f0e3a..86ccde7 100644 --- a/docs/html/dbc__tree__model__test_8cpp_source.html +++ b/docs/html/dbc__tree__model__test_8cpp_source.html @@ -313,7 +313,7 @@ $(document).ready(function(){initNavTree('dbc__tree__model__test_8cpp_source.htm
    213 return QTest::qExec(&tests, argc, argv);
    214}
    215#include "dbc_tree_model_test.moc"
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    Builds a simple tree from parsed DBC database.
    std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
    Build tree representation of parsed DBC data.
    diff --git a/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.html b/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.html index f1e7fbf..f56e574 100644 --- a/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.html +++ b/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.html @@ -111,6 +111,8 @@ Files
    + + diff --git a/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.js b/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.js index 6438c68..33f3e57 100644 --- a/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.js +++ b/docs/html/dir_4270bfced15e0e73154b13468c7c9ad9.js @@ -5,6 +5,7 @@ var dir_4270bfced15e0e73154b13468c7c9ad9 = [ "dbc_decode_builder.h", "dbc__decode__builder_8h.html", "dbc__decode__builder_8h" ], [ "dbc_decoder.cpp", "dbc__decoder_8cpp.html", null ], [ "dbc_decoder.h", "dbc__decoder_8h.html", "dbc__decoder_8h" ], + [ "dbc_diagnostic.h", "dbc__diagnostic_8h_source.html", null ], [ "dbc_parser.cpp", "dbc__parser_8cpp.html", null ], [ "dbc_parser.h", "dbc__parser_8h.html", "dbc__parser_8h" ], [ "dbc_statement_handler.cpp", "dbc__statement__handler_8cpp_source.html", null ], diff --git a/docs/html/examples_2main_8cpp_source.html b/docs/html/examples_2main_8cpp_source.html index 83a67a3..9f0ec34 100644 --- a/docs/html/examples_2main_8cpp_source.html +++ b/docs/html/examples_2main_8cpp_source.html @@ -231,8 +231,8 @@ $(document).ready(function(){initNavTree('examples_2main_8cpp_source.html','');
    DecodeDatabase Build(const DbcDatabase &source) const
    Build runtime decode database.
    Runtime CAN decoder using prebuilt decode database.
    Definition dbc_decoder.h:72
    DecodedFrameValue Decode(const DecodeDatabase &database, const RawCanFrame &frame) const
    Decode one raw CAN frame.
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    Builds a simple tree from parsed DBC database.
    std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
    Build tree representation of parsed DBC data.
    Tree node for later use in model/view or other hierarchy consumers.
    Definition tree_node.h:35
    diff --git a/docs/html/files.html b/docs/html/files.html index b221261..10f4bd5 100644 --- a/docs/html/files.html +++ b/docs/html/files.html @@ -101,33 +101,34 @@ $(document).ready(function(){initNavTree('files.html',''); initResizable(); }); - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     dbc_decoder.h
     Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
     
     dbc_diagnostic.h
     
     dbc_parser.cpp
     Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
     
     dbc_decode_builder.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_decoder.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_decoder.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_parser.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_parser.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_statement_handler.cpp
     dbc_statement_handler.h
     dbc_tree_builder.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_tree_builder.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     decode_database.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     frame_info.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     multiplexing.h
     signal_info.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     text_utils.h
     tree_node.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     tree_node.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     typefactory.h
     value_descriptions.h
     ▼ examples
     main.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     ▼ qt
     dbc_tree_model.cpp
     dbc_tree_model.h
     ▼ tests
     dbc_coverage_test.cpp
     dbc_decoder_test.cpp
     dbc_parser_test.cpp
     dbc_tree_model_test.cpp
     main.cpp
     tree_node_test.cpp
     dbc_diagnostic.h
     dbc_parser.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_parser.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_statement_handler.cpp
     dbc_statement_handler.h
     dbc_tree_builder.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     dbc_tree_builder.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     decode_database.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     frame_info.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     multiplexing.h
     signal_info.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     text_utils.h
     tree_node.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     tree_node.hCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     typefactory.h
     value_descriptions.h
     ▼ examples
     main.cppCreated: 2026-03-13 Author: Deeaitch (Dim. Himro)
     ▼ qt
     dbc_tree_model.cpp
     dbc_tree_model.h
     ▼ tests
     dbc_coverage_test.cpp
     dbc_decoder_test.cpp
     dbc_parser_test.cpp
     dbc_tree_model_test.cpp
     main.cpp
     tree_node_test.cpp
    diff --git a/docs/html/functions.html b/docs/html/functions.html index 88236c5..2ddb63d 100644 --- a/docs/html/functions.html +++ b/docs/html/functions.html @@ -176,6 +176,7 @@ $(document).ready(function(){initNavTree('functions.html',''); initResizable();

    - p -

    diff --git a/docs/html/hierarchy.html b/docs/html/hierarchy.html index 6f9a9f6..fee79e2 100644 --- a/docs/html/hierarchy.html +++ b/docs/html/hierarchy.html @@ -96,37 +96,43 @@ $(document).ready(function(){initNavTree('hierarchy.html',''); initResizable();

    Go to the graphical class hierarchy

    This inheritance list is sorted roughly, but not completely, alphabetically:
    -
    [detail level 12]
    +
    [detail level 123]
    - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     CDbcDatabaseParsed DBC content stored in a simple internal form
     CDbcDecodeBuilderConverts parsed DBC data into runtime decode database
     CDbcDecoderRuntime CAN decoder using prebuilt decode database
     CDbcParseContext
     CDbcParserMinimal DBC parser
     CDbcStatementDispatcher
     ▼CDbcStatementHandler
     CDbcCommentHandler
     CDbcFrameHandler
     CDbcSignalHandler
     CDbcUnsupportedMultiplexingHandler
     CDbcValueDescriptionHandler
     CDbcTreeBuilderBuilds a simple tree from parsed DBC database
     CDecodeDatabaseRuntime decode database with fast lookup by CAN ID
     CDecodedFrameValueFully decoded frame
     CDecodedSignalValueOne decoded signal value
     CDecodeFrameRuntime-ready frame definition
     CDecodeSignalRuntime-ready signal definition
     CFrameInfoDescribes one CAN frame from a DBC file
     CFrameKeyKey for fast frame lookup
     CFrameKeyHasherHasher for frame key
     CMultiplexing
     CPendingValueDescriptions
     ▼CQAbstractItemModel
     CDbcTreeModel
     CRawCanFrameRaw CAN frame used for runtime or trace decoding
     CSignalInfoDescribes one signal inside a DBC frame
     CTreeNodeTree node for later use in model/view or other hierarchy consumers
     CTypeFactory< ClassId, BaseClass, Args >Registry-based factory for creating objects by runtime identifier
     CTypeFactory< std::string, DbcStatementHandler >
     CDbcDiagnostic
     CDbcParseContext
     CDbcParserMinimal DBC parser
     CDbcParseResult
     CDbcStatementDispatcher
     ▼CDbcStatementHandler
     CDbcCommentHandler
     CDbcFrameHandler
     CDbcHeaderHandler
     CDbcSignalHandler
     CDbcUnsupportedMultiplexingHandler
     CDbcValueDescriptionHandler
     CDbcTreeBuilderBuilds a simple tree from parsed DBC database
     CDecodeDatabaseRuntime decode database with fast lookup by CAN ID
     CDecodedFrameValueFully decoded frame
     CDecodedSignalValueOne decoded signal value
     CDecodeFrameRuntime-ready frame definition
     CDecodeSignalRuntime-ready signal definition
     ▼Cstd::exceptionSTL class
     ▼Cstd::runtime_errorSTL class
     CDbcDiagnosticError
     CFrameInfoDescribes one CAN frame from a DBC file
     CFrameKeyKey for fast frame lookup
     CFrameKeyHasherHasher for frame key
     CMultiplexing
     CPendingValueDescriptions
     ▼CQAbstractItemModel
     CDbcTreeModel
     CRawCanFrameRaw CAN frame used for runtime or trace decoding
     CSignalInfoDescribes one signal inside a DBC frame
     CTreeNodeTree node for later use in model/view or other hierarchy consumers
     CTypeFactory< ClassId, BaseClass, Args >Registry-based factory for creating objects by runtime identifier
     CTypeFactory< std::string, DbcStatementHandler >
    diff --git a/docs/html/hierarchy.js b/docs/html/hierarchy.js index ba5fae1..e2a8401 100644 --- a/docs/html/hierarchy.js +++ b/docs/html/hierarchy.js @@ -3,12 +3,15 @@ var hierarchy = [ "DbcDatabase", "structDbcDatabase.html", null ], [ "DbcDecodeBuilder", "classDbcDecodeBuilder.html", null ], [ "DbcDecoder", "classDbcDecoder.html", null ], + [ "DbcDiagnostic", "structDbcDiagnostic.html", null ], [ "DbcParseContext", "structDbcParseContext.html", null ], [ "DbcParser", "classDbcParser.html", null ], + [ "DbcParseResult", "structDbcParseResult.html", null ], [ "DbcStatementDispatcher", "classDbcStatementDispatcher.html", null ], [ "DbcStatementHandler", "classDbcStatementHandler.html", [ [ "DbcCommentHandler", "classDbcCommentHandler.html", null ], [ "DbcFrameHandler", "classDbcFrameHandler.html", null ], + [ "DbcHeaderHandler", "classDbcHeaderHandler.html", null ], [ "DbcSignalHandler", "classDbcSignalHandler.html", null ], [ "DbcUnsupportedMultiplexingHandler", "classDbcUnsupportedMultiplexingHandler.html", null ], [ "DbcValueDescriptionHandler", "classDbcValueDescriptionHandler.html", null ] @@ -19,6 +22,11 @@ var hierarchy = [ "DecodedSignalValue", "structDecodedSignalValue.html", null ], [ "DecodeFrame", "structDecodeFrame.html", null ], [ "DecodeSignal", "structDecodeSignal.html", null ], + [ "std::exception", null, [ + [ "std::runtime_error", null, [ + [ "DbcDiagnosticError", "classDbcDiagnosticError.html", null ] + ] ] + ] ], [ "FrameInfo", "structFrameInfo.html", null ], [ "FrameKey", "structFrameKey.html", null ], [ "FrameKeyHasher", "structFrameKeyHasher.html", null ], diff --git a/docs/html/index.qhp b/docs/html/index.qhp index 9bae6a3..b1fbab3 100644 --- a/docs/html/index.qhp +++ b/docs/html/index.qhp @@ -14,115 +14,121 @@
    -
    +
    -
    -
    -
    +
    +
    +
    +
    -
    -
    -
    -
    +
    +
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    -
    -
    -
    -
    +
    +
    +
    +
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    -
    -
    +
    +
    +
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    +
    +
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    +
    +
    +
    -
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    -
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    -
    -
    -
    -
    +
    +
    +
    +
    @@ -138,12 +144,21 @@
    +
    +
    +
    +
    +
    +
    +
    +
    +
    @@ -267,12 +282,15 @@
    +
    +
    +
    @@ -283,6 +301,11 @@
    +
    +
    +
    +
    +
    @@ -341,10 +364,12 @@
    +
    +
    @@ -484,9 +509,13 @@ + + + + @@ -570,6 +599,7 @@ + @@ -617,9 +647,15 @@ classDbcDecodeBuilder.html classDbcDecoder-members.html classDbcDecoder.html +classDbcDiagnosticError-members.html +classDbcDiagnosticError.html +classDbcDiagnosticError__inherit__graph.svg classDbcFrameHandler-members.html classDbcFrameHandler.html classDbcFrameHandler__inherit__graph.svg +classDbcHeaderHandler-members.html +classDbcHeaderHandler.html +classDbcHeaderHandler__inherit__graph.svg classDbcParser-members.html classDbcParser.html classDbcSignalHandler-members.html @@ -660,6 +696,7 @@ dbc__decoder_8h.html dbc__decoder_8h_source.html dbc__decoder__test_8cpp_source.html +dbc__diagnostic_8h_source.html dbc__parser_8cpp.html dbc__parser_8cpp_source.html dbc__parser_8h.html @@ -714,6 +751,9 @@ inherit_graph_21.svg inherit_graph_22.svg inherit_graph_23.svg +inherit_graph_24.svg +inherit_graph_25.svg +inherit_graph_26.svg inherit_graph_3.svg inherit_graph_4.svg inherit_graph_5.svg @@ -825,8 +865,12 @@ splitbard.png structDbcDatabase-members.html structDbcDatabase.html +structDbcDiagnostic-members.html +structDbcDiagnostic.html structDbcParseContext-members.html structDbcParseContext.html +structDbcParseResult-members.html +structDbcParseResult.html structDecodeDatabase-members.html structDecodeDatabase.html structDecodeFrame-members.html diff --git a/docs/html/inherit_graph_10.map b/docs/html/inherit_graph_10.map index 7c65891..849ced6 100644 --- a/docs/html/inherit_graph_10.map +++ b/docs/html/inherit_graph_10.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_10.md5 b/docs/html/inherit_graph_10.md5 index c9a02c7..92a0f01 100644 --- a/docs/html/inherit_graph_10.md5 +++ b/docs/html/inherit_graph_10.md5 @@ -1 +1 @@ -b05671a6a0ebf993e1d536e18c8222f0 \ No newline at end of file +7b890cf55980a81b2aa2570b6e5b0f21 \ No newline at end of file diff --git a/docs/html/inherit_graph_10.svg b/docs/html/inherit_graph_10.svg index ae6af8c..2907443 100644 --- a/docs/html/inherit_graph_10.svg +++ b/docs/html/inherit_graph_10.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DecodedSignalValue + + +DecodeDatabase diff --git a/docs/html/inherit_graph_11.map b/docs/html/inherit_graph_11.map index c05e6d1..c4d2de0 100644 --- a/docs/html/inherit_graph_11.map +++ b/docs/html/inherit_graph_11.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_11.md5 b/docs/html/inherit_graph_11.md5 index 3bb982e..63d3ebd 100644 --- a/docs/html/inherit_graph_11.md5 +++ b/docs/html/inherit_graph_11.md5 @@ -1 +1 @@ -d60a3b51249015f2f62123f47f8f38c1 \ No newline at end of file +f4d6da699c0f627067cdac840c9a773b \ No newline at end of file diff --git a/docs/html/inherit_graph_11.svg b/docs/html/inherit_graph_11.svg index 4795e2c..7695237 100644 --- a/docs/html/inherit_graph_11.svg +++ b/docs/html/inherit_graph_11.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DecodeFrame + + +DecodedFrameValue diff --git a/docs/html/inherit_graph_12.map b/docs/html/inherit_graph_12.map index 3c6225b..7c65891 100644 --- a/docs/html/inherit_graph_12.map +++ b/docs/html/inherit_graph_12.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_12.md5 b/docs/html/inherit_graph_12.md5 index 36d0d9e..c9a02c7 100644 --- a/docs/html/inherit_graph_12.md5 +++ b/docs/html/inherit_graph_12.md5 @@ -1 +1 @@ -b82865126817889e464d1e7bbdc44e1d \ No newline at end of file +b05671a6a0ebf993e1d536e18c8222f0 \ No newline at end of file diff --git a/docs/html/inherit_graph_12.svg b/docs/html/inherit_graph_12.svg index cba2eae..ae6af8c 100644 --- a/docs/html/inherit_graph_12.svg +++ b/docs/html/inherit_graph_12.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DecodeSignal + + +DecodedSignalValue diff --git a/docs/html/inherit_graph_13.map b/docs/html/inherit_graph_13.map index e9866f7..c05e6d1 100644 --- a/docs/html/inherit_graph_13.map +++ b/docs/html/inherit_graph_13.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_13.md5 b/docs/html/inherit_graph_13.md5 index 32124be..3bb982e 100644 --- a/docs/html/inherit_graph_13.md5 +++ b/docs/html/inherit_graph_13.md5 @@ -1 +1 @@ -628e8fa4bf75287517a27c2bb42129ea \ No newline at end of file +d60a3b51249015f2f62123f47f8f38c1 \ No newline at end of file diff --git a/docs/html/inherit_graph_13.svg b/docs/html/inherit_graph_13.svg index 97171b9..4795e2c 100644 --- a/docs/html/inherit_graph_13.svg +++ b/docs/html/inherit_graph_13.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -FrameInfo + + +DecodeFrame diff --git a/docs/html/inherit_graph_14.map b/docs/html/inherit_graph_14.map index 51fec7c..3c6225b 100644 --- a/docs/html/inherit_graph_14.map +++ b/docs/html/inherit_graph_14.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_14.md5 b/docs/html/inherit_graph_14.md5 index 26c0d3e..36d0d9e 100644 --- a/docs/html/inherit_graph_14.md5 +++ b/docs/html/inherit_graph_14.md5 @@ -1 +1 @@ -ab35c84b554d480a0ee1155c1179d2db \ No newline at end of file +b82865126817889e464d1e7bbdc44e1d \ No newline at end of file diff --git a/docs/html/inherit_graph_14.svg b/docs/html/inherit_graph_14.svg index 23a807a..cba2eae 100644 --- a/docs/html/inherit_graph_14.svg +++ b/docs/html/inherit_graph_14.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -FrameKey + + +DecodeSignal diff --git a/docs/html/inherit_graph_15.map b/docs/html/inherit_graph_15.map index 4cf64cb..e9866f7 100644 --- a/docs/html/inherit_graph_15.map +++ b/docs/html/inherit_graph_15.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_15.md5 b/docs/html/inherit_graph_15.md5 index 0b133d4..32124be 100644 --- a/docs/html/inherit_graph_15.md5 +++ b/docs/html/inherit_graph_15.md5 @@ -1 +1 @@ -03ff8d0fe772fd10da3721a519f78bc4 \ No newline at end of file +628e8fa4bf75287517a27c2bb42129ea \ No newline at end of file diff --git a/docs/html/inherit_graph_15.svg b/docs/html/inherit_graph_15.svg index afe2243..97171b9 100644 --- a/docs/html/inherit_graph_15.svg +++ b/docs/html/inherit_graph_15.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -FrameKeyHasher + + +FrameInfo diff --git a/docs/html/inherit_graph_16.map b/docs/html/inherit_graph_16.map index 6d8239d..51fec7c 100644 --- a/docs/html/inherit_graph_16.map +++ b/docs/html/inherit_graph_16.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_16.md5 b/docs/html/inherit_graph_16.md5 index 4493996..26c0d3e 100644 --- a/docs/html/inherit_graph_16.md5 +++ b/docs/html/inherit_graph_16.md5 @@ -1 +1 @@ -9c7c19c49bb06cf85d4a0f4383b32c46 \ No newline at end of file +ab35c84b554d480a0ee1155c1179d2db \ No newline at end of file diff --git a/docs/html/inherit_graph_16.svg b/docs/html/inherit_graph_16.svg index 427ad14..23a807a 100644 --- a/docs/html/inherit_graph_16.svg +++ b/docs/html/inherit_graph_16.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -Multiplexing + + +FrameKey diff --git a/docs/html/inherit_graph_17.map b/docs/html/inherit_graph_17.map index ad0caff..4cf64cb 100644 --- a/docs/html/inherit_graph_17.map +++ b/docs/html/inherit_graph_17.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_17.md5 b/docs/html/inherit_graph_17.md5 index d203585..0b133d4 100644 --- a/docs/html/inherit_graph_17.md5 +++ b/docs/html/inherit_graph_17.md5 @@ -1 +1 @@ -1e7e1326294370b50e12696033f3e108 \ No newline at end of file +03ff8d0fe772fd10da3721a519f78bc4 \ No newline at end of file diff --git a/docs/html/inherit_graph_17.svg b/docs/html/inherit_graph_17.svg index 049d797..afe2243 100644 --- a/docs/html/inherit_graph_17.svg +++ b/docs/html/inherit_graph_17.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -PendingValueDescriptions + + +FrameKeyHasher diff --git a/docs/html/inherit_graph_18.map b/docs/html/inherit_graph_18.map index 9b4887e..6d8239d 100644 --- a/docs/html/inherit_graph_18.map +++ b/docs/html/inherit_graph_18.map @@ -1,5 +1,3 @@ - - - + diff --git a/docs/html/inherit_graph_18.md5 b/docs/html/inherit_graph_18.md5 index f104abb..4493996 100644 --- a/docs/html/inherit_graph_18.md5 +++ b/docs/html/inherit_graph_18.md5 @@ -1 +1 @@ -5ba14f6059c5b08d2880d5c03ee0eed4 \ No newline at end of file +9c7c19c49bb06cf85d4a0f4383b32c46 \ No newline at end of file diff --git a/docs/html/inherit_graph_18.svg b/docs/html/inherit_graph_18.svg index 6f057cf..427ad14 100644 --- a/docs/html/inherit_graph_18.svg +++ b/docs/html/inherit_graph_18.svg @@ -4,34 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -QAbstractItemModel - - - - - -Node1 - - -DbcTreeModel - - - - - -Node0->Node1 - - - + + +Multiplexing diff --git a/docs/html/inherit_graph_19.map b/docs/html/inherit_graph_19.map index baccc4c..ad0caff 100644 --- a/docs/html/inherit_graph_19.map +++ b/docs/html/inherit_graph_19.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_19.md5 b/docs/html/inherit_graph_19.md5 index 8e49fd2..d203585 100644 --- a/docs/html/inherit_graph_19.md5 +++ b/docs/html/inherit_graph_19.md5 @@ -1 +1 @@ -a0ca65c977c3eeaa49d3a753e2b425f7 \ No newline at end of file +1e7e1326294370b50e12696033f3e108 \ No newline at end of file diff --git a/docs/html/inherit_graph_19.svg b/docs/html/inherit_graph_19.svg index ac9b694..049d797 100644 --- a/docs/html/inherit_graph_19.svg +++ b/docs/html/inherit_graph_19.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -RawCanFrame + + +PendingValueDescriptions diff --git a/docs/html/inherit_graph_20.map b/docs/html/inherit_graph_20.map index 27221de..d2e07bb 100644 --- a/docs/html/inherit_graph_20.map +++ b/docs/html/inherit_graph_20.map @@ -1,3 +1,5 @@ - + + + diff --git a/docs/html/inherit_graph_20.md5 b/docs/html/inherit_graph_20.md5 index c4410a4..b51d107 100644 --- a/docs/html/inherit_graph_20.md5 +++ b/docs/html/inherit_graph_20.md5 @@ -1 +1 @@ -f2e229631b6e08e3f933a80cf3a704df \ No newline at end of file +ad47da0d18c55e4eff4ff453c2dbe21f \ No newline at end of file diff --git a/docs/html/inherit_graph_20.svg b/docs/html/inherit_graph_20.svg index 7b67e3e..2afd5db 100644 --- a/docs/html/inherit_graph_20.svg +++ b/docs/html/inherit_graph_20.svg @@ -4,16 +4,34 @@ - + Graphical Class Hierarchy Node0 - - -SignalInfo + + +QAbstractItemModel + + + + + +Node1 + + +DbcTreeModel + + + + + +Node0->Node1 + + + diff --git a/docs/html/inherit_graph_21.map b/docs/html/inherit_graph_21.map index d2067d8..baccc4c 100644 --- a/docs/html/inherit_graph_21.map +++ b/docs/html/inherit_graph_21.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_21.md5 b/docs/html/inherit_graph_21.md5 index 53a15e0..8e49fd2 100644 --- a/docs/html/inherit_graph_21.md5 +++ b/docs/html/inherit_graph_21.md5 @@ -1 +1 @@ -0e692ac66fcc5782f37efa2f3d64c466 \ No newline at end of file +a0ca65c977c3eeaa49d3a753e2b425f7 \ No newline at end of file diff --git a/docs/html/inherit_graph_21.svg b/docs/html/inherit_graph_21.svg index a741e27..ac9b694 100644 --- a/docs/html/inherit_graph_21.svg +++ b/docs/html/inherit_graph_21.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -TreeNode + + +RawCanFrame diff --git a/docs/html/inherit_graph_22.map b/docs/html/inherit_graph_22.map index cc8fd2d..27221de 100644 --- a/docs/html/inherit_graph_22.map +++ b/docs/html/inherit_graph_22.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_22.md5 b/docs/html/inherit_graph_22.md5 index feef5c8..c4410a4 100644 --- a/docs/html/inherit_graph_22.md5 +++ b/docs/html/inherit_graph_22.md5 @@ -1 +1 @@ -fd991ac56e8b35f6def7a3942058b044 \ No newline at end of file +f2e229631b6e08e3f933a80cf3a704df \ No newline at end of file diff --git a/docs/html/inherit_graph_22.svg b/docs/html/inherit_graph_22.svg index 1e19eb8..7b67e3e 100644 --- a/docs/html/inherit_graph_22.svg +++ b/docs/html/inherit_graph_22.svg @@ -4,17 +4,16 @@ - - + + Graphical Class Hierarchy Node0 - - -TypeFactory< ClassId, - BaseClass, Args > + + +SignalInfo diff --git a/docs/html/inherit_graph_23.map b/docs/html/inherit_graph_23.map index f89295a..f17e7e3 100644 --- a/docs/html/inherit_graph_23.map +++ b/docs/html/inherit_graph_23.map @@ -1,3 +1,7 @@ - + + + + + diff --git a/docs/html/inherit_graph_23.md5 b/docs/html/inherit_graph_23.md5 index 0956862..9cbfdde 100644 --- a/docs/html/inherit_graph_23.md5 +++ b/docs/html/inherit_graph_23.md5 @@ -1 +1 @@ -2e92ed9cb6b5a27ab688cfd97eafecca \ No newline at end of file +fcc3a46e0f291589c12d6b87f268a06f \ No newline at end of file diff --git a/docs/html/inherit_graph_23.svg b/docs/html/inherit_graph_23.svg index cb57a17..f99f5c0 100644 --- a/docs/html/inherit_graph_23.svg +++ b/docs/html/inherit_graph_23.svg @@ -4,17 +4,52 @@ - - + + Graphical Class Hierarchy Node0 - - -TypeFactory< std::string, - DbcStatementHandler > + + +std::exception + + + + + +Node1 + + +std::runtime_error + + + + + +Node0->Node1 + + + + + + + + +Node2 + + +DbcDiagnosticError + + + + + +Node1->Node2 + + + diff --git a/docs/html/inherit_graph_24.map b/docs/html/inherit_graph_24.map new file mode 100644 index 0000000..d2067d8 --- /dev/null +++ b/docs/html/inherit_graph_24.map @@ -0,0 +1,3 @@ + + + diff --git a/docs/html/inherit_graph_24.md5 b/docs/html/inherit_graph_24.md5 new file mode 100644 index 0000000..53a15e0 --- /dev/null +++ b/docs/html/inherit_graph_24.md5 @@ -0,0 +1 @@ +0e692ac66fcc5782f37efa2f3d64c466 \ No newline at end of file diff --git a/docs/html/inherit_graph_24.svg b/docs/html/inherit_graph_24.svg new file mode 100644 index 0000000..a741e27 --- /dev/null +++ b/docs/html/inherit_graph_24.svg @@ -0,0 +1,21 @@ + + + + + + +Graphical Class Hierarchy + + +Node0 + + +TreeNode + + + + + diff --git a/docs/html/inherit_graph_25.map b/docs/html/inherit_graph_25.map new file mode 100644 index 0000000..cc8fd2d --- /dev/null +++ b/docs/html/inherit_graph_25.map @@ -0,0 +1,3 @@ + + + diff --git a/docs/html/inherit_graph_25.md5 b/docs/html/inherit_graph_25.md5 new file mode 100644 index 0000000..feef5c8 --- /dev/null +++ b/docs/html/inherit_graph_25.md5 @@ -0,0 +1 @@ +fd991ac56e8b35f6def7a3942058b044 \ No newline at end of file diff --git a/docs/html/inherit_graph_25.svg b/docs/html/inherit_graph_25.svg new file mode 100644 index 0000000..1e19eb8 --- /dev/null +++ b/docs/html/inherit_graph_25.svg @@ -0,0 +1,22 @@ + + + + + + +Graphical Class Hierarchy + + +Node0 + + +TypeFactory< ClassId, + BaseClass, Args > + + + + + diff --git a/docs/html/inherit_graph_26.map b/docs/html/inherit_graph_26.map new file mode 100644 index 0000000..f89295a --- /dev/null +++ b/docs/html/inherit_graph_26.map @@ -0,0 +1,3 @@ + + + diff --git a/docs/html/inherit_graph_26.md5 b/docs/html/inherit_graph_26.md5 new file mode 100644 index 0000000..0956862 --- /dev/null +++ b/docs/html/inherit_graph_26.md5 @@ -0,0 +1 @@ +2e92ed9cb6b5a27ab688cfd97eafecca \ No newline at end of file diff --git a/docs/html/inherit_graph_26.svg b/docs/html/inherit_graph_26.svg new file mode 100644 index 0000000..cb57a17 --- /dev/null +++ b/docs/html/inherit_graph_26.svg @@ -0,0 +1,22 @@ + + + + + + +Graphical Class Hierarchy + + +Node0 + + +TypeFactory< std::string, + DbcStatementHandler > + + + + + diff --git a/docs/html/inherit_graph_3.map b/docs/html/inherit_graph_3.map index 4590e15..d893319 100644 --- a/docs/html/inherit_graph_3.map +++ b/docs/html/inherit_graph_3.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_3.md5 b/docs/html/inherit_graph_3.md5 index ffd6e48..a2a10b1 100644 --- a/docs/html/inherit_graph_3.md5 +++ b/docs/html/inherit_graph_3.md5 @@ -1 +1 @@ -2674130f4d66049ef34375ec57054882 \ No newline at end of file +d6d90b711187d0d808df175139af753e \ No newline at end of file diff --git a/docs/html/inherit_graph_3.svg b/docs/html/inherit_graph_3.svg index ad34d29..1d59989 100644 --- a/docs/html/inherit_graph_3.svg +++ b/docs/html/inherit_graph_3.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DbcParseContext + + +DbcDiagnostic diff --git a/docs/html/inherit_graph_4.map b/docs/html/inherit_graph_4.map index 1af950d..4590e15 100644 --- a/docs/html/inherit_graph_4.map +++ b/docs/html/inherit_graph_4.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_4.md5 b/docs/html/inherit_graph_4.md5 index 63d492a..ffd6e48 100644 --- a/docs/html/inherit_graph_4.md5 +++ b/docs/html/inherit_graph_4.md5 @@ -1 +1 @@ -debfb9bdb327669e1f39bd750d473c06 \ No newline at end of file +2674130f4d66049ef34375ec57054882 \ No newline at end of file diff --git a/docs/html/inherit_graph_4.svg b/docs/html/inherit_graph_4.svg index 47e2173..ad34d29 100644 --- a/docs/html/inherit_graph_4.svg +++ b/docs/html/inherit_graph_4.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DbcParser + + +DbcParseContext diff --git a/docs/html/inherit_graph_5.map b/docs/html/inherit_graph_5.map index 5fb9bd5..1af950d 100644 --- a/docs/html/inherit_graph_5.map +++ b/docs/html/inherit_graph_5.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_5.md5 b/docs/html/inherit_graph_5.md5 index 89aeb1e..63d492a 100644 --- a/docs/html/inherit_graph_5.md5 +++ b/docs/html/inherit_graph_5.md5 @@ -1 +1 @@ -e32f14f6883118a9bd63a5fa32e3e6db \ No newline at end of file +debfb9bdb327669e1f39bd750d473c06 \ No newline at end of file diff --git a/docs/html/inherit_graph_5.svg b/docs/html/inherit_graph_5.svg index ed39b7b..47e2173 100644 --- a/docs/html/inherit_graph_5.svg +++ b/docs/html/inherit_graph_5.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DbcStatementDispatcher + + +DbcParser diff --git a/docs/html/inherit_graph_6.map b/docs/html/inherit_graph_6.map index a378fba..c552d7b 100644 --- a/docs/html/inherit_graph_6.map +++ b/docs/html/inherit_graph_6.map @@ -1,13 +1,3 @@ - - - - - - - - - - - + diff --git a/docs/html/inherit_graph_6.md5 b/docs/html/inherit_graph_6.md5 index 87f50ed..044d2e6 100644 --- a/docs/html/inherit_graph_6.md5 +++ b/docs/html/inherit_graph_6.md5 @@ -1 +1 @@ -d6b2623682e815727c850a0a9a35ec54 \ No newline at end of file +f92f99071c369af7be9b6720e317d236 \ No newline at end of file diff --git a/docs/html/inherit_graph_6.svg b/docs/html/inherit_graph_6.svg index 4d46883..7776a12 100644 --- a/docs/html/inherit_graph_6.svg +++ b/docs/html/inherit_graph_6.svg @@ -4,107 +4,16 @@ - - + + Graphical Class Hierarchy Node0 - - -DbcStatementHandler - - - - - -Node1 - - -DbcCommentHandler - - - - - -Node0->Node1 - - - - - - - - -Node2 - - -DbcFrameHandler - - - - - -Node0->Node2 - - - - - - - - -Node3 - - -DbcSignalHandler - - - - - -Node0->Node3 - - - - - - - - -Node4 - - -DbcUnsupportedMultiplexing -Handler - - - - - -Node0->Node4 - - - - - - - - -Node5 - - -DbcValueDescriptionHandler - - - - - -Node0->Node5 - - - + + +DbcParseResult diff --git a/docs/html/inherit_graph_7.map b/docs/html/inherit_graph_7.map index 7cbafa0..5fb9bd5 100644 --- a/docs/html/inherit_graph_7.map +++ b/docs/html/inherit_graph_7.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_7.md5 b/docs/html/inherit_graph_7.md5 index f202ac5..89aeb1e 100644 --- a/docs/html/inherit_graph_7.md5 +++ b/docs/html/inherit_graph_7.md5 @@ -1 +1 @@ -caff685aaef8276b6a7bdc7c6f2f9efa \ No newline at end of file +e32f14f6883118a9bd63a5fa32e3e6db \ No newline at end of file diff --git a/docs/html/inherit_graph_7.svg b/docs/html/inherit_graph_7.svg index 0044598..ed39b7b 100644 --- a/docs/html/inherit_graph_7.svg +++ b/docs/html/inherit_graph_7.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DbcTreeBuilder + + +DbcStatementDispatcher diff --git a/docs/html/inherit_graph_8.map b/docs/html/inherit_graph_8.map index 849ced6..8fac8e4 100644 --- a/docs/html/inherit_graph_8.map +++ b/docs/html/inherit_graph_8.map @@ -1,3 +1,15 @@ - + + + + + + + + + + + + + diff --git a/docs/html/inherit_graph_8.md5 b/docs/html/inherit_graph_8.md5 index 92a0f01..49aad1c 100644 --- a/docs/html/inherit_graph_8.md5 +++ b/docs/html/inherit_graph_8.md5 @@ -1 +1 @@ -7b890cf55980a81b2aa2570b6e5b0f21 \ No newline at end of file +50d8eccddc248eb5342377b1e19abb04 \ No newline at end of file diff --git a/docs/html/inherit_graph_8.svg b/docs/html/inherit_graph_8.svg index 2907443..3df3846 100644 --- a/docs/html/inherit_graph_8.svg +++ b/docs/html/inherit_graph_8.svg @@ -4,16 +4,125 @@ - - + + Graphical Class Hierarchy Node0 - - -DecodeDatabase + + +DbcStatementHandler + + + + + +Node1 + + +DbcCommentHandler + + + + + +Node0->Node1 + + + + + + + + +Node2 + + +DbcFrameHandler + + + + + +Node0->Node2 + + + + + + + + +Node3 + + +DbcHeaderHandler + + + + + +Node0->Node3 + + + + + + + + +Node4 + + +DbcSignalHandler + + + + + +Node0->Node4 + + + + + + + + +Node5 + + +DbcUnsupportedMultiplexing +Handler + + + + + +Node0->Node5 + + + + + + + + +Node6 + + +DbcValueDescriptionHandler + + + + + +Node0->Node6 + + + diff --git a/docs/html/inherit_graph_9.map b/docs/html/inherit_graph_9.map index c4d2de0..7cbafa0 100644 --- a/docs/html/inherit_graph_9.map +++ b/docs/html/inherit_graph_9.map @@ -1,3 +1,3 @@ - + diff --git a/docs/html/inherit_graph_9.md5 b/docs/html/inherit_graph_9.md5 index 63d3ebd..f202ac5 100644 --- a/docs/html/inherit_graph_9.md5 +++ b/docs/html/inherit_graph_9.md5 @@ -1 +1 @@ -f4d6da699c0f627067cdac840c9a773b \ No newline at end of file +caff685aaef8276b6a7bdc7c6f2f9efa \ No newline at end of file diff --git a/docs/html/inherit_graph_9.svg b/docs/html/inherit_graph_9.svg index 7695237..0044598 100644 --- a/docs/html/inherit_graph_9.svg +++ b/docs/html/inherit_graph_9.svg @@ -4,16 +4,16 @@ - + Graphical Class Hierarchy Node0 - - -DecodedFrameValue + + +DbcTreeBuilder diff --git a/docs/html/inherits.html b/docs/html/inherits.html index dab4e30..26e32f1 100644 --- a/docs/html/inherits.html +++ b/docs/html/inherits.html @@ -99,27 +99,30 @@ $(document).ready(function(){initNavTree('hierarchy.html',''); initResizable();

    This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.

    - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/html/md_README.html b/docs/html/md_README.html index d015406..fd5b40c 100644 --- a/docs/html/md_README.html +++ b/docs/html/md_README.html @@ -93,8 +93,8 @@ $(document).ready(function(){initNavTree('md_README.html',''); initResizable();
    DBC Parser and Runtime Decode Module Documentation
    -

    -

    +

    +

    Overview

    This module provides a minimal but extensible DBC parser and runtime decode foundation for the FrameTap project.

    Its purpose is to:

    @@ -116,10 +116,10 @@ Overview

    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 qt/.

    See changelog.md for the release and development history, tests/README.md for test instructions, and generated API documentation for the API reference.


    -

    +

    High-Level Architecture

    The module is divided into two main paths.

    -

    +

    1. Parse and UI path

    Used for:

      @@ -139,7 +139,7 @@ High-Level Architecture
      TreeNode hierarchy
      ↓
      DbcTreeModel → Qt views
      -

    +

    2. Runtime decode path

    Used for:

      @@ -164,7 +164,7 @@ High-Level Architecture

      This separation is intentional.

      The tree is useful for UI, but it is not the main data structure for runtime decoding.


      -

      +

      Why the Runtime Decode Layer Exists

      A tree structure is convenient for browsing, but a runtime decoder needs something different:

        @@ -181,7 +181,7 @@ Why the Runtime Decode Layer Exists

      This avoids forcing UI-oriented structures into a decode role they were not meant for.


      -

      +

      Module Layout

      core/ C++17 parser, statement handlers, metadata, tree, and decoder
      examples/ Command-line demo (built separately)
      @@ -196,7 +196,7 @@ Module Layout Parsed metadata core/dbc_database.h, core/frame_info.h, core/signal_info.h -Parser and dispatch core/dbc_parser.*, core/dbc_statement_handler.*, core/typefactory.h +Parser and dispatch core/dbc_parser.*, core/dbc_diagnostic.h, core/dbc_statement_handler.*, core/typefactory.h UI tree core/tree_node.*, core/dbc_tree_builder.* @@ -209,9 +209,9 @@ Module Layout Build integration core/core.pro, core/core_files.pri, core/core.pri
      -

      +

      Parsed Data Structures

      -

      +

      <tt>SignalInfo</tt>

      Represents one signal as parsed from the DBC file.

      Fields:

      @@ -238,7 +238,7 @@ Parsed Data Structures

      Physical value rule:

      physical = raw * factor + offset

      -

      +

      <tt>FrameInfo</tt>

      Represents one frame as parsed from the DBC file.

      Fields:

      @@ -260,7 +260,7 @@ Parsed Data Structures
    • pgn is derived using simplified J1939 logic when applicable

    -

    +

    <tt>DbcDatabase</tt>

    Top-level parsed DBC container.

    Conceptually:

    @@ -268,9 +268,9 @@ Parsed Data Structures
    └── vector<FrameInfo>

    This is the central structure produced by DbcParser.


    -

    +

    UI Tree Layer

    -

    +

    <tt>TreeNode</tt>

    The UI tree contains three node types:

      @@ -295,14 +295,14 @@ UI Tree Layer

      The tree supports browsing through the optional DbcTreeModel adapter.

      It is not the primary runtime decode structure.


      -

      +

      Runtime Decode Layer

      -

      +

      Purpose

      The decode layer exists so that decoding can be fast and independent from UI concerns.

      Instead of searching a tree, the decoder uses a prepared database with direct lookup.


      -

      +

      <tt>ByteOrder</tt>

      Runtime byte order enum:

        @@ -311,7 +311,7 @@ Purpose

      This is better for decode code than passing around raw DBC characters.


      -

      +

      <tt>ValueType</tt>

      Numeric type enum:

        @@ -320,7 +320,7 @@ Purpose

      This is clearer than combining multiple boolean flags during runtime logic.


      -

      +

      <tt>DecodeSignal</tt>

      Represents one runtime-ready signal definition.

      Fields:

      @@ -340,7 +340,7 @@ Purpose

    This structure contains all information required for extracting and converting a signal value from raw frame data.


    -

    +

    <tt>DecodeFrame</tt>

    Represents one runtime-ready frame definition.

    Fields:

    @@ -357,7 +357,7 @@ Purpose

    This structure is used directly by the decoder.


    -

    +

    <tt>FrameKey</tt>

    Fast lookup key for runtime frame matching.

    Fields:

    @@ -367,7 +367,7 @@ Purpose

    This matters because the same numeric identifier must not be confused between standard and extended frames.


    -

    +

    <tt>DecodeDatabase</tt>

    Top-level runtime decode container.

    Fields:

    @@ -381,9 +381,9 @@ Purpose
    └── unordered_map<FrameKey, index>

    This gives the decoder fast access to a frame definition using CAN ID and frame type.


    -

    +

    Decoder Layer

    -

    +

    <tt>RawCanFrame</tt>

    Represents a raw CAN frame to decode.

    Fields:

    @@ -399,7 +399,7 @@ Decoder Layer
  • unit tests

  • -

    +

    <tt>DecodedSignalValue</tt>

    Represents one decoded signal result.

    Fields:

    @@ -411,7 +411,7 @@ Decoder Layer
  • status

  • -

    +

    Raw value representation and precision

    DecodedSignalValue::rawValue is a C++17 std::variant<std::int64_t, std::uint64_t>. For a valid signal, signed definitions produce the int64_t alternative and unsigned definitions produce the uint64_t alternative. Raw values remain exact across their full 64-bit ranges. Check valid before using the value; an invalid result's default value is not decoded data.

    Use std::get when the numeric type is known, or std::get_if to handle both:

    @@ -423,7 +423,7 @@ Raw value representation and precision

    This replaces the previous int64_t field: consumers that read or print rawValue directly must handle the variant.

    Physical conversion uses the active numeric type: physicalValue = static_cast<double>(raw) * factor + offset. physicalValue remains a double 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 UINT64_MAX remains exact in rawValue, but converts to approximately 18446744073709551616 in binary64 before scaling. Use rawValue whenever exact integer values are required.


    -

    +

    <tt>DecodedFrameValue</tt>

    Represents one decoded frame result.

    Fields:

    @@ -435,7 +435,7 @@ Raw value representation and precision

    valid means a matching frame definition was found. Check each signal's valid separately: insufficient payload data can leave individual signals invalid even when the frame is valid. An unknown frame returns valid == false.

    The frame and signal definition pointers refer into DecodeDatabase. 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.


    -

    +

    <tt>DbcDecoder</tt>

    Main runtime decoder class.

    Responsibilities:

    @@ -452,7 +452,7 @@ Raw value representation and precision
  • Decode(...)

  • -

    +

    Parser Support

    The current parser supports the following DBC elements:

      @@ -463,10 +463,52 @@ Parser Support
    • VAL_ signal value descriptions
    • basic M / mN multiplexing
    +

    +Structured diagnostics

    +

    ParseFileWithDiagnostics(path) returns DbcParseResult containing database and diagnostics. Each DbcDiagnostic has severity, code, filePath, lineNumber, and message. Paths preserve the caller's supplied spelling. Lines are one-based physical lines, including blank lines; file-level errors use zero.

    +
    const DbcParser parser;
    +
    const DbcParseResult result = parser.ParseFileWithDiagnostics("example.dbc");
    +
    for (const DbcDiagnostic &diagnostic : result.diagnostics) {
    +
    std::cerr << diagnostic.filePath << ":" << diagnostic.lineNumber
    +
    << ": " << diagnostic.message << '\n';
    +
    }
    +
    if (!result.HasErrors()) {
    +
    const DecodeDatabase runtime = DbcDecodeBuilder().Build(result.database);
    +
    // Inspect warnings before relying on decoding results.
    +
    }
    +
    Converts parsed DBC data into runtime decode database.
    +
    DecodeDatabase Build(const DbcDatabase &source) const
    Build runtime decode database.
    +
    Minimal DBC parser.
    Definition dbc_parser.h:33
    +
    DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const
    Parse with warnings and a structured first error instead of throwing.
    + + +
    Runtime decode database with fast lookup by CAN ID.
    +
    + + + + + + + + + + + + + + + + +
    Severity / code Meaning
    Error / FileOpenError Input cannot be opened
    Error / FileReadError Input cannot be read completely
    Error / InvalidStatement Invalid frame/signal definition, duplicate, or payload violation
    Error / InvalidValueDescription Invalid VAL_ syntax, duplicate value, or unresolved reference
    Error / InvalidMultiplexing Selector, branch range, or signal overlap validation failed
    Warning / UnsupportedStatement Unregistered statement skipped; decoding or metadata may be incomplete
    Error / UnsupportedStatement Extended multiplexing (SG_MUL_VAL_) rejected
    +

    Parsing stops at the first error and returns an empty database, together with any preceding warnings and the error. Deferred VAL_ and multiplexing errors retain their original source lines. Invalid signal markers use InvalidStatement. HasErrors() checks severity; warnings alone do not make a parse fail.

    +

    Unknown statements are reported conservatively, including SIG_VALTYPE_, attributes (BA_, BA_DEF_, defaults and relation forms), signal types/references, environment variables, named VAL_TABLE_ tables, and vendor extensions. For example, ignoring SIG_VALTYPE_ may decode a floating-point signal as an integer. The parser does not implement the warned features; consumers should review warnings.

    +

    Common VERSION, NS_, BS_, and BU_ headers produce no diagnostics. Single-token symbols inside the NS_ 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 (CM_, CM_ BU_, CM_ EV_) are ignored by the comment handler; comments only attach to already parsed frames/signals. Supported statements currently require one physical line.

    +

    ParseFile(path) remains compatible: it returns the database, discards warnings, and throws std::runtime_error on the first error with the existing path:line: format. Use ParseFileWithDiagnostics to see skipped syntax. Resource failures such as allocation errors may still throw.


    -

    +

    Supported DBC Syntax

    -

    +

    Frame definition

    Example:

    BO_ 256 EngineData: 8 EEC1
    @@ -478,16 +520,16 @@ Frame definition
  • transmitter ECU

  • -

    +

    Frame validation and parse errors

    BO_ 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.

    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 0x7FF are still treated as extended.

    The payload length must fit uint8_t (0..255). This is a storage-range check, not CAN or CAN FD protocol validation; no new 8-byte or 64-byte limit is imposed.

    Parsing stops at the first detected error. Exceptions raised while parsing a line are reported as std::runtime_error with the supplied file path and the one-based physical line number, including blank lines:

    example.dbc:3: Invalid CAN ID: invalid
    -

    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.

    +

    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.


    -

    +

    Signal definition

    Example:

    SG_ EngineSpeed : 0|16@1+ (0.125,0) [0|8000] "rpm" ECU1,ECU2
    @@ -506,15 +548,15 @@ Signal definition
  • receivers

  • -

    +

    Signal validation and parse errors

    SG_ 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 (@0+, @0-, @1+, or @1-). A quoted unit (which may be empty) and a nonempty comma-separated receiver list are required. Unexpected trailing fields are rejected.

    Start bits must be unsigned decimal integers fitting uint32_t; lengths must be within 1..64 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.

    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.

    -

    Basic multiplexing markers M and mN are supported as described below. Overlapping signals are rejected unless their branch values differ. Duplicate frame/signal name detection remains separate work.

    +

    Basic multiplexing markers M and mN 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.

    Invalid signal definitions stop parsing with path:line: description, including when the signal exceeds the declared payload length.


    -

    +

    Basic multiplexing

    BO_ 256 Status: 3 ECU
    SG_ Mode M : 0|8@1+ (1,0) [0|255] "" ECU
    @@ -541,7 +583,7 @@ Basic multiplexing

    All statuses except Valid have valid == false; their numeric fields contain no decoded data and GetValueDescription() returns nullptr. Check status 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.


    -

    +

    Comments

    Frame comment example:

    CM_ BO_ 256 "Engine data frame";
    @@ -553,7 +595,7 @@ Comments
  • SignalInfo::comment

  • -

    +

    CAN ID Normalization

    The parser normalizes frame identifiers.

    Common DBC behavior:

    @@ -568,7 +610,7 @@ CAN ID Normalization

    This is important both for correct lookup and for future interoperability with live CAN APIs.


    -

    +

    PGN Extraction

    PGN is derived only when the frame is treated as extended.

    The current logic is simplified J1939 extraction:

    @@ -579,7 +621,7 @@ PGN Extraction

    This is enough for a practical start but should not be treated as full J1939 validation.


    -

    +

    Decode Flow

    Typical runtime decode flow:

    RawCanFrame
    @@ -594,7 +636,7 @@ Decode Flow
    ↓
    DecodedFrameValue

    -

    +

    Intel and Motorola Extraction

    The decoder currently has separate extraction paths:

      @@ -605,7 +647,7 @@ Intel and Motorola Extraction

      Intel and Motorola require different bit extraction logic.

      This is one of the main reasons why the runtime decode layer should be explicit and prepared in advance.


      -

      +

      Example Usage

      Include the public headers from the core/ include directory supplied by core/core.pri:

      #include "dbc_parser.h"
      @@ -616,27 +658,23 @@ Example Usage
      Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
      Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
      Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
      -

      +

    Parse DBC

    DbcParser parser;
    DbcDatabase database = parser.ParseFile("example.dbc");
    -
    Minimal DBC parser.
    Definition dbc_parser.h:34
    -
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    +
    DbcDatabase ParseFile(const std::string &filePath) const
    Parse DBC file.
    Parsed DBC content stored in a simple internal form.
    -

    +

    Build UI tree

    DbcTreeBuilder treeBuilder;
    std::unique_ptr<TreeNode> root = treeBuilder.Build(database);
    Builds a simple tree from parsed DBC database.
    std::unique_ptr< TreeNode > Build(const DbcDatabase &database) const
    Build tree representation of parsed DBC data.
    -

    +

    Build runtime decode database

    DbcDecodeBuilder decodeBuilder;
    DecodeDatabase decodeDatabase = decodeBuilder.Build(database);
    -
    Converts parsed DBC data into runtime decode database.
    -
    DecodeDatabase Build(const DbcDatabase &source) const
    Build runtime decode database.
    -
    Runtime decode database with fast lookup by CAN ID.
    -

    +

    Decode a raw frame

    RawCanFrame rawFrame;
    rawFrame.canId = 256; // EngineData from the DBC example above
    @@ -653,7 +691,7 @@ Decode a raw frame
    std::uint32_t canId
    Definition dbc_decoder.h:25
    bool isExtended
    Definition dbc_decoder.h:26

    -

    +

    Unified Decode Strategy

    A key design goal is that the same decoder should work for both:

      @@ -661,7 +699,7 @@ Unified Decode Strategy
    • trace replay frames

    That means this architecture supports:

    -

    +

    live path

    live CAN input
    ↓
    @@ -670,7 +708,7 @@ live path
    DbcDecoder
    ↓
    decoded signal values
    -

    +

    trace path

    trace reader
    ↓
    @@ -681,7 +719,7 @@ trace path
    decoded signal values

    This avoids duplicating decode logic in two separate parts of the application.


    -

    +

    Intended Use in FrameTap

    This module is meant to support at least the following FrameTap workflows:

      @@ -707,7 +745,7 @@ Intended Use in FrameTap
      - live frames
      - trace replay

      -

      +

      Why the Tree Is Not Enough

      The tree exists for browsing.

      However, runtime decode should not rely on tree traversal because that would introduce unnecessary coupling and inefficiency.

      @@ -719,7 +757,7 @@ Why the Tree Is Not Enough

    That is why DecodeDatabase is a separate layer.


    -

    +

    Statement Handler Factory

    DbcParser owns file reading, trimming, line numbers, and error reporting. Each ParseFile() call creates a fresh DbcParseContext and a DbcStatementDispatcher. The context contains the parsed database and current frame; handlers receive it by reference and retain no parsing state.

    The dispatcher uses TypeFactory<std::string, DbcStatementHandler> to create registered handlers once per parsing session, then reuses them for all matching lines:

    @@ -729,17 +767,18 @@ Statement Handler Factory
  • CM_ → DbcCommentHandler
  • VAL_ → DbcValueDescriptionHandler
  • SG_MUL_VAL_ → DbcUnsupportedMultiplexingHandler
  • +
  • VERSION, NS_, BS_, BU_ → DbcHeaderHandler (also accepts attached colons)
  • Grammar implementations live in core/dbc_statement_handler.cpp; their interface, context, and dispatcher live in core/dbc_statement_handler.h. core/typefactory.h provides the generic registry and object creation.

    To add a construct, implement a default-constructible handler deriving from DbcStatementHandler with:

    void Handle(const std::string &line, DbcParseContext &context) const override;
    - +

    Register it in the dispatcher constructor:

    RegisterType<MyCustomHandler>("CUSTOM_"); // after implementing MyCustomHandler
    -

    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 BO_TX_BU_ cannot match BO_. Unregistered keywords remain ignored. SG_ and CM_ accept spaces and tabs after their keywords.

    +

    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 BO_TX_BU_ cannot match BO_. Unregistered keywords produce UnsupportedStatement warnings through ParseFileWithDiagnostics. SG_ and CM_ accept spaces and tabs after their keywords.

    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.


    -

    +

    Signal value descriptions (<tt>VAL_</tt>)

    Signal descriptions attach text to exact raw integer values:

    BO_ 256 Status: 8 ECU
    @@ -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.

    Each value-description entry contains value (qlonglong for negative keys, qulonglong for nonnegative keys) and description (QString). This preserves the full signed/unsigned 64-bit range without converting through double. An unmapped signal returns an empty list. Data comes from SignalInfo::valueDescriptions. Unsupported roles return invalid QVariant.

    -

    +

    Standalone tree tests without Qt

    From the repository root, use only a C++17 compiler:

    @@ -1041,7 +1082,7 @@ Standalone tree tests without Qt
    /tmp/dbc_tree_node_test

    -

    +

    Build and run the demo

    After building core, run these commands from the repository root:

    @@ -1053,7 +1094,7 @@ Build and run the demo

    The demo prints the parsed tree and decodes eight zero bytes using the first frame definition. Replace that sample payload in examples/main.cpp to feed live CAN data or trace records.

    -

    +

    Generate API documentation

    With Doxygen installed, run from the repository root:

    @@ -1063,17 +1104,17 @@ Generate API documentation


    -

    +

    Regression tests

    See tests/README.md for QtTest build and execution commands. Tests cover frame validation and error locations, Intel and Motorola extraction, signal syntax and payload bounds, VAL_ 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.

    -

    +

    Measuring code coverage

    Coverage instrumentation is separate from the QtTest suite named CoverageTest: that suite runs extra regression checks, but coverage counters require a specially instrumented build. Use a separate build directory for each coverage tool.

    -

    +

    GCC, gcov, and LCOV on Debian/Ubuntu

    Install the build and report tools:

    @@ -1127,7 +1168,7 @@ GCC, gcov, and LCOV on Debian/Ubuntu

    After adding direct comment-handler and ambiguous VAL_ reference tests, the same configuration measured 98.4% line coverage (728/740) and 71.4% branch coverage (841/1178).

    See GCC instrumentation options and the LCOV project documentation.

    -

    +

    Configure the GCC coverage build in Qt Creator

      @@ -1143,7 +1184,7 @@ Configure the GCC coverage build in Qt Creator

    -

    +

    Configure all build variants in Qt Creator

    The local dbc.pro.user stores machine-specific kit IDs and build/run settings. It is ignored by Git (*.user) and should not be committed or copied between machines. Recreate the configurations below through the UI when setting up a new checkout. The Qt4ProjectManager identifiers inside .user are historical Qt Creator setting names; the project still requires Qt 6.8.2.

    diff --git a/docs/html/md_changelog.html b/docs/html/md_changelog.html index ceb9b7d..d740b6b 100644 --- a/docs/html/md_changelog.html +++ b/docs/html/md_changelog.html @@ -97,10 +97,28 @@ $(document).ready(function(){initNavTree('md_changelog.html',''); initResizable(

    Unreleased

    -2026-10-07

    +2026-10-11

    Added

      +
    • ParseFileWithDiagnostics and DbcParseResult with severity, stable error code, supplied file path, physical line number, and message for each diagnostic.
    • +
    • Warnings for unregistered statements, including floating-point signal types, attributes, signal type references, environment variables, and vendor extensions.
    • +
    • Quiet common DBC header handlers registered through TypeFactory; NS_ symbol declarations do not produce unsupported-statement warnings.
    • +
    • Regression tests for warning locations, header handling, immediate/deferred errors, file errors, empty results on failure, and legacy exception compatibility.
    • +
    +

    +Changed

    +
      +
    • Kept ParseFile compatible while sharing parsing with the diagnostic API. Parsing stops at the first error and never returns a partial database.
    • +
    • Deferred value-description and multiplexing errors carry structured source locations without extracting them from exception messages.
    • +
    • Documented supported syntax, warning behavior, diagnostic codes, and limitations.
    • +
    • Audited diagnostic coverage and added unsupported-statement variants, namespace termination, formatting/path handling, first-error stopping, deferred diagnostic order, duplicate/overlap errors, and supported decoding preservation tests. Linux file-read errors and legacy file-error messages are checked explicitly.
    • +
    +

    +2026-10-07

    +

    +Added

    +
    • Added regression coverage for signed bit-length boundaries, deterministic Intel/Motorola extraction, lookup failures, runtime validation, PGN, comments, file formatting, metadata copying/lifetime, and TypeFactory behavior.
    • Added direct-handler and resolver tests for unsupported comments and ambiguous VAL_ references in manually constructed databases.
    • Documented GCC/gcov/LCOV instrumentation, Qt Creator setup, and HTML reports. Coverage after the added tests: 98.4% of lines and 71.4% of branches with GCC 14.2 and Qt 6.8.2, including the standalone tree test.
    • @@ -110,7 +128,7 @@ Added
    • Selector-first decoding using exact raw values, preserving definition order and unconditional signals. Explicit statuses distinguish inactive branches, missing selector data, insufficient payloads, and malformed runtime metadata.
    • Registered SG_MUL_VAL_ rejection through TypeFactory; extended and nested multiplexing remain unsupported. Added parser/decoder regression coverage and documented supported syntax and consumer behavior.
    -

    +

    Changed

    • Qt-dependent targets now require the installed Qt 6.8.2 through a shared qmake version check; removed Qt 5 compatibility instructions. Core remains Qt-free.
    • @@ -118,7 +136,7 @@ Changed
    • Coverage documentation now describes the selected open GCC/LCOV toolchain.
    • Overlapping unconditional signals are now rejected during parsing.
    -

    +

    Fixed

    • Linked QtGui only in the optional model tests and used QGuiApplication with an offscreen default, resolving the QAbstractItemModelTester invalid QPixmap metatype warning without adding QtGui to the adapter library.
    • @@ -126,9 +144,9 @@ Fixed
    • Removed test compiler warnings by using QVERIFY_THROWS_EXCEPTION and explicitly discarding nodiscard return values in exception checks.
    • Reject duplicate frames by normalized CAN ID and frame type, including equivalent extended ID encodings, and duplicate signal names within a frame. Errors report the file path and line of the repeated definition. Standard and extended frames may share a numeric ID; separate frames may reuse signal names. Added regression coverage and updated parser documentation.
    -

    +

    2026-10-06

    -

    +

    Added

    • Added non-owning TreeNode parent navigation and stable sibling positions; disabled node moves to preserve links while retaining unique_ptr ownership.
    • @@ -138,61 +156,61 @@ Added
    • Preserved descriptions in parsed metadata, runtime decode definitions, and UI tree metadata. Added DecodedSignalValue::GetValueDescription() and FindValueDescription() for raw integer lookup before physical scaling. Unknown values retain normal numeric decoding.
    • Added regression coverage for syntax, quoting, whitespace, integer boundaries, declaration order, invalid references, duplicates, scaling, and both builders; documented syntax, lookup behavior, and limitations in README.
    -

    +

    2026-10-05

    -

    +

    Changed

    • Split the qmake project into a reusable static library in core/, a demo in examples/, and a combined regression test executable in tests/. Added shared .pri files and updated build instructions. (f17ddb6, #11)
    • Added .clang-format and applied consistent formatting to the source code and tests. (b91cf4a, #7)
    • Replaced lambdas with explicit functions and simpler code in statement handlers, the decoder, the demo, and regression tests. (03dc8f2)
    -

    +

    Fixed

    • Added complete validation of SG_ signal statements, including syntax, receivers, numeric fields, lengths of 1–64 bits, physical ranges, and signal bounds within the declared frame payload for Intel and Motorola bit order. Invalid definitions report the file path and line number. Multiplexing markers are explicitly rejected. Added regression tests and documentation. (8d82b13, #6)
    -

    +

    Documentation and maintenance

    • Regenerated Doxygen documentation after code changes and the project restructuring. (6cd9976, 0067cb4, f17ddb6)
    • Removed the temporary signal-validation issue document. (1163277)
    -

    +

    2026-10-01

    -

    +

    Changed

    • Moved DBC statement parsing into TypeFactory-registered handlers for BO_, SG_, and CM_, with a shared parse context and keyword dispatcher. Added tests for dispatch and handler replacement, and documented how to register additional handlers. (88b5883, #4)
    • API change: DecodedSignalValue::rawValue now uses std::variant<std::int64_t, std::uint64_t> instead of int64_t. Consumers must handle the appropriate variant alternative. Physical values remain double and may lose precision for large integers. (69074e3, #2)
    -

    +

    Fixed

    • Corrected Motorola signal extraction within bytes and across byte boundaries using DBC sawtooth bit numbering. Added decoder regression tests and build instructions; introduced the TypeFactory utility. (2c057b6)
    • Preserved the full unsigned 64-bit raw-value range, including values above INT64_MAX, and updated physical conversion and demo output. Added tests for signed and unsigned boundaries and numeric output. (69074e3, #2)
    • Validated BO_ frame syntax, CAN identifiers, payload lengths, numeric overflow, and unexpected trailing fields. Parsing errors now include the file path and physical line number. Added parser regression tests. (3bd9339, #3)
    -

    +

    v1.0 — 2026-06-14

    Tag v1.0 points to 38ce043 and includes the initial implementation below.

    -

    +

    Documentation

    • Added source-file headers with author information and MIT license references. (e2ffa97)
    • Added and subsequently simplified the Doxygen configuration. (e2c07dd, 4c8af9f)
    • Generated API documentation and refreshed the generated documentation. (dfec39d, 38ce043)
    -

    +

    Initial implementation — 2026-03-13

    -

    +

    Added

    • Initialized the repository with a README and MIT license. (4270459)
    • Added the DBC parser, frame and signal metadata, a tree representation and builder, a demonstration program, and a qmake project. (2a90b2d)
    • Added runtime decoding through DbcDecodeBuilder, DecodeDatabase, and DbcDecoder, including CAN-frame lookup, Intel and Motorola extraction, signed and unsigned signals, and factor/offset conversion. Updated parser metadata and the demo to support decoding. (a53a5df)
    -

    +

    Documentation and maintenance

    • Added .gitignore and expanded the README with architecture, data structures, parsing behavior, decoding examples, and usage documentation. (efc57d6, f2aa10c, cb20f5f, f0e7065)
    • diff --git a/docs/html/md_tests_2README.html b/docs/html/md_tests_2README.html index 00f4d32..7f9937b 100644 --- a/docs/html/md_tests_2README.html +++ b/docs/html/md_tests_2README.html @@ -93,7 +93,7 @@ $(document).ready(function(){initNavTree('md_tests_2README.html',''); initResiza
      QtTest regression tests
      -

      For instrumented builds, LCOV HTML reports, and Qt Creator coverage configuration, see Measuring code coverage. For the complete IDE build/run configuration set, see Configure all build variants in Qt Creator. The Coverage configuration uses coverage_report.sh after its instrumented build; the script takes the source and build directories as its two arguments.

      +

      For instrumented builds, LCOV HTML reports, and Qt Creator coverage configuration, see Measuring code coverage. For the complete IDE build/run configuration set, see Configure all build variants in Qt Creator. The Coverage configuration uses coverage_report.sh after its instrumented build; the script takes the source and build directories as its two arguments.

      Open the repository's root dbc.pro in Qt Creator. It contains core (a static C++17 library) and tests (the dbc_tests QtTest executable). Core is built first; tests link its archive rather than compiling its implementation again. Qt Core and Qt Test development packages are required for tests only. The optional model tests also link QtGui, which is provided by Qt base development packages. The adapter library itself still links only QtCore.

      Build from the repository root with the installed Qt 6.8.2:

      mkdir build
      @@ -110,19 +110,20 @@ $(document).ready(function(){initNavTree('md_tests_2README.html',''); initResiza
      make
      make check

      parser_tests.pri and decoder_tests.pri include the original test sources; tests.pro also includes dbc_coverage_test.cpp. ../core/core.pri supplies the library include path and linkage.

      -

      +

      Decoder coverage

      Coverage includes Motorola bit numbering within and across bytes, unaligned signals, signed values, scaling, 64-bit extraction, signed/unsigned boundary values (including INT64_MIN, INT64_MAX, and UINT64_MAX), numeric output, invalid lengths, insufficient payloads, and Intel regression cases. Frame validity means the definition was found; insufficient payloads are checked through signal validity.

      -

      +

      Parser coverage

      +

      Structured diagnostic tests cover severity, code, supplied path, and physical line numbers for skipped syntax and immediate/deferred errors; warnings preceding an error are retained, and failed parses return an empty database. Common headers and namespace symbol lists stay quiet. Tests also check file-open errors, fresh parse sessions, and compatibility with the legacy throwing API. The diagnostic audit also covers 15 unsupported-statement variants, all namespace termination forms, CRLF and missing final newlines, relative paths with spaces, first-error stopping, deferred diagnostic ordering, duplicate definitions/values, selector ranges, overlaps, and preservation of supported decoding and metadata. On Linux, reading a directory exercises the distinct FileReadError path.

      Parser tests cover standard and extended CAN IDs, whitespace, payload storage boundaries, missing fields, malformed and overflowing numbers, reserved ID bits, error paths and line numbers, and integration with signals and comments. Duplicate definitions are rejected at their source lines, including equivalent extended ID encodings and repeated signal names within a frame. Standard and extended frames may share a numeric ID, and separate frames may reuse signal names. Signal tests cover complete syntax and numeric validation, scientific notation, finite physical parameters and ordered ranges, spaces and tabs, receiver lists, unsupported multiplexing, and Intel/Motorola declared-payload boundaries. Value-description tests cover full VAL_ syntax, whitespace, escaped quotes, empty text, exact integer boundaries, duplicate keys within and across statements, deferred and normalized frame references, missing targets, error locations, raw lookup with scaling, unknown/invalid values, and both database builders. Temporary DBC fixtures are created in the system temporary directory and removed automatically.

      Dispatch tests also verify exact keyword matching, handler construction and reuse, unknown statements, and independent parsing sessions, including recovery after errors.

      -

      +

      Tree and optional model tests

      tree_node_test.cpp is a standalone C++17 executable without Qt; see the root README for its compiler command. It checks parents, sibling positions, null children, bounds, and unique_ptr transfer.

      Enable CONFIG+=dbc_qt in the root qmake invocation to build dbc_qt and dbc_model_tests alongside existing tests. Qt 6.8.2 is required. make check runs all suites. Model tests parse a temporary DBC fixture and use QAbstractItemModelTester, verify navigation across columns, invalid/foreign indexes, metadata and exact VAL_ integers, and persistent-index invalidation when reloading or clearing the tree. Their QGuiApplication registers graphical metatypes used by QAbstractItemModelTester, avoiding the invalid QPixmap type warning in Qt 6.8.2. The test executable defaults to QT_QPA_PLATFORM=offscreen when the variable is unset or empty, so no display server is needed. An explicit platform setting is preserved.

      Basic multiplexing coverage includes selector declarations after branches, Intel/Motorola branch overlap, signed active values and VAL_ lookup, unconditional signals, inactive branches, missing selector/branch payloads, exact UINT64_MAX selector matching, malformed runtime selectors, source locations, and rejection of invalid markers, selector references/ranges, overlaps, and SG_MUL_VAL_.

      -

      +

      Additional regression coverage

      dbc_coverage_test.cpp runs as part of dbc_tests. It covers signed boundaries below 64 bits, deterministic extraction comparisons for both byte orders across lengths 1–64, frame lookup failures, exact decode statuses, malformed runtime multiplexing, PGN boundaries, comment handling, file formatting, metadata copying and source lifetime, physical conversion, and TypeFactory registration/creation. Direct resolver tests construct ambiguous databases through the public metadata API, verify source locations, and check that ambiguous targets receive no values.

      All QtTest targets use Qt 6.8.2 and QVERIFY_THROWS_EXCEPTION. Exception tests explicitly discard nodiscard results when only the exception is being checked. The standalone tree test requires only a C++17 compiler.

      diff --git a/docs/html/navtreedata.js b/docs/html/navtreedata.js index 3683755..654e3ad 100644 --- a/docs/html/navtreedata.js +++ b/docs/html/navtreedata.js @@ -27,115 +27,121 @@ var NAVTREE = [ "DBC Framework", "index.html", [ [ "Changelog", "md_changelog.html", [ [ "Unreleased", "md_changelog.html#autotoc_md1", [ - [ "2026-10-07", "md_changelog.html#autotoc_md2", [ + [ "2026-10-11", "md_changelog.html#autotoc_md2", [ [ "Added", "md_changelog.html#autotoc_md3", null ], - [ "Changed", "md_changelog.html#autotoc_md4", null ], - [ "Fixed", "md_changelog.html#autotoc_md5", null ] + [ "Changed", "md_changelog.html#autotoc_md4", null ] ] ], - [ "2026-10-06", "md_changelog.html#autotoc_md6", [ - [ "Added", "md_changelog.html#autotoc_md7", null ] + [ "2026-10-07", "md_changelog.html#autotoc_md5", [ + [ "Added", "md_changelog.html#autotoc_md6", null ], + [ "Changed", "md_changelog.html#autotoc_md7", null ], + [ "Fixed", "md_changelog.html#autotoc_md8", null ] ] ], - [ "2026-10-05", "md_changelog.html#autotoc_md8", [ - [ "Changed", "md_changelog.html#autotoc_md9", null ], - [ "Fixed", "md_changelog.html#autotoc_md10", null ], - [ "Documentation and maintenance", "md_changelog.html#autotoc_md11", null ] + [ "2026-10-06", "md_changelog.html#autotoc_md9", [ + [ "Added", "md_changelog.html#autotoc_md10", null ] ] ], - [ "2026-10-01", "md_changelog.html#autotoc_md12", [ - [ "Changed", "md_changelog.html#autotoc_md13", null ], - [ "Fixed", "md_changelog.html#autotoc_md14", null ] + [ "2026-10-05", "md_changelog.html#autotoc_md11", [ + [ "Changed", "md_changelog.html#autotoc_md12", null ], + [ "Fixed", "md_changelog.html#autotoc_md13", null ], + [ "Documentation and maintenance", "md_changelog.html#autotoc_md14", null ] + ] ], + [ "2026-10-01", "md_changelog.html#autotoc_md15", [ + [ "Changed", "md_changelog.html#autotoc_md16", null ], + [ "Fixed", "md_changelog.html#autotoc_md17", null ] ] ] ] ], - [ "v1.0 — 2026-06-14", "md_changelog.html#autotoc_md15", [ - [ "Documentation", "md_changelog.html#autotoc_md16", null ], - [ "Initial implementation — 2026-03-13", "md_changelog.html#autotoc_md17", [ - [ "Added", "md_changelog.html#autotoc_md18", null ], - [ "Documentation and maintenance", "md_changelog.html#autotoc_md19", null ] + [ "v1.0 — 2026-06-14", "md_changelog.html#autotoc_md18", [ + [ "Documentation", "md_changelog.html#autotoc_md19", null ], + [ "Initial implementation — 2026-03-13", "md_changelog.html#autotoc_md20", [ + [ "Added", "md_changelog.html#autotoc_md21", null ], + [ "Documentation and maintenance", "md_changelog.html#autotoc_md22", null ] ] ] ] ] ] ], [ "DBC Parser and Runtime Decode Module Documentation", "md_README.html", [ - [ "Overview", "md_README.html#autotoc_md21", null ], - [ "High-Level Architecture", "md_README.html#autotoc_md23", [ - [ "1. Parse and UI path", "md_README.html#autotoc_md24", null ], - [ "2. Runtime decode path", "md_README.html#autotoc_md25", null ] + [ "Overview", "md_README.html#autotoc_md24", null ], + [ "High-Level Architecture", "md_README.html#autotoc_md26", [ + [ "1. Parse and UI path", "md_README.html#autotoc_md27", null ], + [ "2. Runtime decode path", "md_README.html#autotoc_md28", null ] ] ], - [ "Why the Runtime Decode Layer Exists", "md_README.html#autotoc_md27", null ], - [ "Module Layout", "md_README.html#autotoc_md29", null ], - [ "Parsed Data Structures", "md_README.html#autotoc_md31", null ], - [ "SignalInfo", "md_README.html#autotoc_md32", null ], - [ "FrameInfo", "md_README.html#autotoc_md34", null ], - [ "DbcDatabase", "md_README.html#autotoc_md36", null ], - [ "UI Tree Layer", "md_README.html#autotoc_md38", null ], - [ "TreeNode", "md_README.html#autotoc_md39", null ], - [ "Runtime Decode Layer", "md_README.html#autotoc_md41", null ], - [ "Purpose", "md_README.html#autotoc_md42", null ], - [ "ByteOrder", "md_README.html#autotoc_md44", null ], - [ "ValueType", "md_README.html#autotoc_md46", null ], - [ "DecodeSignal", "md_README.html#autotoc_md48", null ], - [ "DecodeFrame", "md_README.html#autotoc_md50", null ], - [ "FrameKey", "md_README.html#autotoc_md52", null ], - [ "DecodeDatabase", "md_README.html#autotoc_md54", null ], - [ "Decoder Layer", "md_README.html#autotoc_md56", null ], - [ "RawCanFrame", "md_README.html#autotoc_md57", null ], - [ "DecodedSignalValue", "md_README.html#autotoc_md59", [ - [ "Raw value representation and precision", "md_README.html#autotoc_md61", null ] + [ "Why the Runtime Decode Layer Exists", "md_README.html#autotoc_md30", null ], + [ "Module Layout", "md_README.html#autotoc_md32", null ], + [ "Parsed Data Structures", "md_README.html#autotoc_md34", null ], + [ "SignalInfo", "md_README.html#autotoc_md35", null ], + [ "FrameInfo", "md_README.html#autotoc_md37", null ], + [ "DbcDatabase", "md_README.html#autotoc_md39", null ], + [ "UI Tree Layer", "md_README.html#autotoc_md41", null ], + [ "TreeNode", "md_README.html#autotoc_md42", null ], + [ "Runtime Decode Layer", "md_README.html#autotoc_md44", null ], + [ "Purpose", "md_README.html#autotoc_md45", null ], + [ "ByteOrder", "md_README.html#autotoc_md47", null ], + [ "ValueType", "md_README.html#autotoc_md49", null ], + [ "DecodeSignal", "md_README.html#autotoc_md51", null ], + [ "DecodeFrame", "md_README.html#autotoc_md53", null ], + [ "FrameKey", "md_README.html#autotoc_md55", null ], + [ "DecodeDatabase", "md_README.html#autotoc_md57", null ], + [ "Decoder Layer", "md_README.html#autotoc_md59", null ], + [ "RawCanFrame", "md_README.html#autotoc_md60", null ], + [ "DecodedSignalValue", "md_README.html#autotoc_md62", [ + [ "Raw value representation and precision", "md_README.html#autotoc_md64", null ] ] ], - [ "DecodedFrameValue", "md_README.html#autotoc_md63", null ], - [ "DbcDecoder", "md_README.html#autotoc_md65", null ], - [ "Parser Support", "md_README.html#autotoc_md67", null ], - [ "Supported DBC Syntax", "md_README.html#autotoc_md69", null ], - [ "Frame definition", "md_README.html#autotoc_md70", [ - [ "Frame validation and parse errors", "md_README.html#autotoc_md72", null ] + [ "DecodedFrameValue", "md_README.html#autotoc_md66", null ], + [ "DbcDecoder", "md_README.html#autotoc_md68", null ], + [ "Parser Support", "md_README.html#autotoc_md70", [ + [ "Structured diagnostics", "md_README.html#autotoc_md71", null ] ] ], - [ "Signal definition", "md_README.html#autotoc_md74", [ - [ "Signal validation and parse errors", "md_README.html#autotoc_md76", null ] + [ "Supported DBC Syntax", "md_README.html#autotoc_md73", null ], + [ "Frame definition", "md_README.html#autotoc_md74", [ + [ "Frame validation and parse errors", "md_README.html#autotoc_md76", null ] ] ], - [ "Basic multiplexing", "md_README.html#autotoc_md78", null ], - [ "Comments", "md_README.html#autotoc_md80", null ], - [ "CAN ID Normalization", "md_README.html#autotoc_md82", null ], - [ "PGN Extraction", "md_README.html#autotoc_md84", null ], - [ "Decode Flow", "md_README.html#autotoc_md86", null ], - [ "Intel and Motorola Extraction", "md_README.html#autotoc_md88", null ], - [ "Example Usage", "md_README.html#autotoc_md90", [ - [ "Parse DBC", "md_README.html#autotoc_md91", null ], - [ "Build UI tree", "md_README.html#autotoc_md92", null ], - [ "Build runtime decode database", "md_README.html#autotoc_md93", null ], - [ "Decode a raw frame", "md_README.html#autotoc_md94", null ] + [ "Signal definition", "md_README.html#autotoc_md78", [ + [ "Signal validation and parse errors", "md_README.html#autotoc_md80", null ] ] ], - [ "Unified Decode Strategy", "md_README.html#autotoc_md96", [ - [ "live path", "md_README.html#autotoc_md97", null ], - [ "trace path", "md_README.html#autotoc_md98", null ] + [ "Basic multiplexing", "md_README.html#autotoc_md82", null ], + [ "Comments", "md_README.html#autotoc_md84", null ], + [ "CAN ID Normalization", "md_README.html#autotoc_md86", null ], + [ "PGN Extraction", "md_README.html#autotoc_md88", null ], + [ "Decode Flow", "md_README.html#autotoc_md90", null ], + [ "Intel and Motorola Extraction", "md_README.html#autotoc_md92", null ], + [ "Example Usage", "md_README.html#autotoc_md94", [ + [ "Parse DBC", "md_README.html#autotoc_md95", null ], + [ "Build UI tree", "md_README.html#autotoc_md96", null ], + [ "Build runtime decode database", "md_README.html#autotoc_md97", null ], + [ "Decode a raw frame", "md_README.html#autotoc_md98", null ] ] ], - [ "Intended Use in FrameTap", "md_README.html#autotoc_md100", null ], - [ "Why the Tree Is Not Enough", "md_README.html#autotoc_md102", null ], - [ "Statement Handler Factory", "md_README.html#autotoc_md104", null ], - [ "Signal value descriptions (VAL_)", "md_README.html#autotoc_md106", null ], - [ "Current Limitations", "md_README.html#autotoc_md108", null ], - [ "Recommended Next Steps", "md_README.html#autotoc_md110", [ - [ "Stage 1 - already implemented", "md_README.html#autotoc_md111", null ], - [ "Stage 2", "md_README.html#autotoc_md112", null ], - [ "Stage 3", "md_README.html#autotoc_md113", null ], - [ "Stage 4", "md_README.html#autotoc_md114", null ] + [ "Unified Decode Strategy", "md_README.html#autotoc_md100", [ + [ "live path", "md_README.html#autotoc_md101", null ], + [ "trace path", "md_README.html#autotoc_md102", null ] ] ], - [ "Build Integration", "md_README.html#autotoc_md116", [ - [ "Build core without Qt libraries", "md_README.html#autotoc_md117", null ], - [ "Optional Qt model adapter", "md_README.html#autotoc_md118", null ], - [ "Standalone tree tests without Qt", "md_README.html#autotoc_md119", null ], - [ "Build and run the demo", "md_README.html#autotoc_md120", null ], - [ "Generate API documentation", "md_README.html#autotoc_md121", null ] + [ "Intended Use in FrameTap", "md_README.html#autotoc_md104", null ], + [ "Why the Tree Is Not Enough", "md_README.html#autotoc_md106", null ], + [ "Statement Handler Factory", "md_README.html#autotoc_md108", null ], + [ "Signal value descriptions (VAL_)", "md_README.html#autotoc_md110", null ], + [ "Current Limitations", "md_README.html#autotoc_md112", null ], + [ "Recommended Next Steps", "md_README.html#autotoc_md114", [ + [ "Stage 1 - already implemented", "md_README.html#autotoc_md115", null ], + [ "Stage 2", "md_README.html#autotoc_md116", null ], + [ "Stage 3", "md_README.html#autotoc_md117", null ], + [ "Stage 4", "md_README.html#autotoc_md118", null ] ] ], - [ "Regression tests", "md_README.html#autotoc_md123", null ], - [ "Measuring code coverage", "md_README.html#autotoc_md124", [ - [ "GCC, gcov, and LCOV on Debian/Ubuntu", "md_README.html#autotoc_md125", null ], - [ "Configure the GCC coverage build in Qt Creator", "md_README.html#autotoc_md126", null ], - [ "Configure all build variants in Qt Creator", "md_README.html#autotoc_md127", null ] + [ "Build Integration", "md_README.html#autotoc_md120", [ + [ "Build core without Qt libraries", "md_README.html#autotoc_md121", null ], + [ "Optional Qt model adapter", "md_README.html#autotoc_md122", null ], + [ "Standalone tree tests without Qt", "md_README.html#autotoc_md123", null ], + [ "Build and run the demo", "md_README.html#autotoc_md124", null ], + [ "Generate API documentation", "md_README.html#autotoc_md125", null ] + ] ], + [ "Regression tests", "md_README.html#autotoc_md127", null ], + [ "Measuring code coverage", "md_README.html#autotoc_md128", [ + [ "GCC, gcov, and LCOV on Debian/Ubuntu", "md_README.html#autotoc_md129", null ], + [ "Configure the GCC coverage build in Qt Creator", "md_README.html#autotoc_md130", null ], + [ "Configure all build variants in Qt Creator", "md_README.html#autotoc_md131", null ] ] ] ] ], [ "QtTest regression tests", "md_tests_2README.html", [ - [ "Decoder coverage", "md_tests_2README.html#autotoc_md129", null ], - [ "Parser coverage", "md_tests_2README.html#autotoc_md130", null ], - [ "Tree and optional model tests", "md_tests_2README.html#autotoc_md131", null ], - [ "Additional regression coverage", "md_tests_2README.html#autotoc_md132", null ] + [ "Decoder coverage", "md_tests_2README.html#autotoc_md133", null ], + [ "Parser coverage", "md_tests_2README.html#autotoc_md134", null ], + [ "Tree and optional model tests", "md_tests_2README.html#autotoc_md135", null ], + [ "Additional regression coverage", "md_tests_2README.html#autotoc_md136", null ] ] ], [ "Classes", "annotated.html", [ [ "Class List", "annotated.html", "annotated_dup" ], @@ -160,7 +166,7 @@ var NAVTREE = var NAVTREEINDEX = [ "annotated.html", -"structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5" +"structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4" ]; var SYNCONMSG = 'click to disable panel synchronisation'; diff --git a/docs/html/navtreeindex0.js b/docs/html/navtreeindex0.js index 72e4a71..5a99e1b 100644 --- a/docs/html/navtreeindex0.js +++ b/docs/html/navtreeindex0.js @@ -7,37 +7,40 @@ var NAVTREEINDEX0 = "classDbcDecoder.html":[3,0,3], "classDbcDecoder.html#a345951ffe5d943a70d3a1ea1f39e74f7":[3,0,3,1], "classDbcDecoder.html#ab2cfb2fb711c95d3a29365546b89f3da":[3,0,3,0], -"classDbcFrameHandler.html":[3,0,4], -"classDbcParser.html":[3,0,6], -"classDbcParser.html#aef72826942c9095d653fafa435855e56":[3,0,6,0], -"classDbcSignalHandler.html":[3,0,7], -"classDbcStatementDispatcher.html":[3,0,8], -"classDbcStatementDispatcher.html#a495c2d5c7ebb8103b1987cdd87c142ed":[3,0,8,0], -"classDbcStatementHandler.html":[3,0,9], -"classDbcTreeBuilder.html":[3,0,10], -"classDbcTreeBuilder.html#a7e57d067d831b14b383947fd125edd4b":[3,0,10,0], -"classDbcTreeModel.html":[3,0,11], -"classDbcUnsupportedMultiplexingHandler.html":[3,0,12], -"classDbcValueDescriptionHandler.html":[3,0,13], -"classTreeNode.html":[3,0,26], -"classTreeNode.html#a226518612d0d00b5988a2c44fc21d3f1":[3,0,26,12], -"classTreeNode.html#a4727ff801a2d1b9323c5ae50a35457a6":[3,0,26,7], -"classTreeNode.html#a6161f2ebb92184eab4215d121870e788":[3,0,26,3], -"classTreeNode.html#a81047bd7d2a4cc96b9ef5e20d0d63b5f":[3,0,26,8], -"classTreeNode.html#a8e38dd591d8801d7ee3a7dbad90c67fc":[3,0,26,1], -"classTreeNode.html#a984a98d5ccf7ef1f5a18094c6821f35d":[3,0,26,0], -"classTreeNode.html#aa48fbc17903eb8cfa40353e29f853c6f":[3,0,26,4], -"classTreeNode.html#aaac5b8d9dc9e5ae1f367d1adbcf20e18":[3,0,26,10], -"classTreeNode.html#ab9f00f5253d56461bb2d420fd639c5ae":[3,0,26,2], -"classTreeNode.html#abdd82460187dca8d3e5d66f5d5c529ea":[3,0,26,6], -"classTreeNode.html#ad501f97eeec7f7d3353bfae838fbb6a8":[3,0,26,5], -"classTreeNode.html#afa2f4b0aafa12d3d41ed00df8e0250c9":[3,0,26,9], -"classTreeNode.html#afc503b40004764163605d6dbdb4ef811":[3,0,26,11], -"classTypeFactory.html":[3,0,27], -"classTypeFactory.html#a1a119ad2956abe146213c6ca124d8dd4":[3,0,27,3], -"classTypeFactory.html#a3f43b03d6e3a0fd503fdec01ecf62e9f":[3,0,27,2], -"classTypeFactory.html#ad6d85795285ee21193ac03e1b24762d3":[3,0,27,0], -"classTypeFactory.html#ad82f537569ece3d3a4a376523fa94473":[3,0,27,1], +"classDbcDiagnosticError.html":[3,0,5], +"classDbcFrameHandler.html":[3,0,6], +"classDbcHeaderHandler.html":[3,0,7], +"classDbcParser.html":[3,0,9], +"classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc":[3,0,9,1], +"classDbcParser.html#aef72826942c9095d653fafa435855e56":[3,0,9,0], +"classDbcSignalHandler.html":[3,0,11], +"classDbcStatementDispatcher.html":[3,0,12], +"classDbcStatementDispatcher.html#a495c2d5c7ebb8103b1987cdd87c142ed":[3,0,12,0], +"classDbcStatementHandler.html":[3,0,13], +"classDbcTreeBuilder.html":[3,0,14], +"classDbcTreeBuilder.html#a7e57d067d831b14b383947fd125edd4b":[3,0,14,0], +"classDbcTreeModel.html":[3,0,15], +"classDbcUnsupportedMultiplexingHandler.html":[3,0,16], +"classDbcValueDescriptionHandler.html":[3,0,17], +"classTreeNode.html":[3,0,30], +"classTreeNode.html#a226518612d0d00b5988a2c44fc21d3f1":[3,0,30,12], +"classTreeNode.html#a4727ff801a2d1b9323c5ae50a35457a6":[3,0,30,7], +"classTreeNode.html#a6161f2ebb92184eab4215d121870e788":[3,0,30,3], +"classTreeNode.html#a81047bd7d2a4cc96b9ef5e20d0d63b5f":[3,0,30,8], +"classTreeNode.html#a8e38dd591d8801d7ee3a7dbad90c67fc":[3,0,30,1], +"classTreeNode.html#a984a98d5ccf7ef1f5a18094c6821f35d":[3,0,30,0], +"classTreeNode.html#aa48fbc17903eb8cfa40353e29f853c6f":[3,0,30,4], +"classTreeNode.html#aaac5b8d9dc9e5ae1f367d1adbcf20e18":[3,0,30,10], +"classTreeNode.html#ab9f00f5253d56461bb2d420fd639c5ae":[3,0,30,2], +"classTreeNode.html#abdd82460187dca8d3e5d66f5d5c529ea":[3,0,30,6], +"classTreeNode.html#ad501f97eeec7f7d3353bfae838fbb6a8":[3,0,30,5], +"classTreeNode.html#afa2f4b0aafa12d3d41ed00df8e0250c9":[3,0,30,9], +"classTreeNode.html#afc503b40004764163605d6dbdb4ef811":[3,0,30,11], +"classTypeFactory.html":[3,0,31], +"classTypeFactory.html#a1a119ad2956abe146213c6ca124d8dd4":[3,0,31,3], +"classTypeFactory.html#a3f43b03d6e3a0fd503fdec01ecf62e9f":[3,0,31,2], +"classTypeFactory.html#ad6d85795285ee21193ac03e1b24762d3":[3,0,31,0], +"classTypeFactory.html#ad82f537569ece3d3a4a376523fa94473":[3,0,31,1], "classes.html":[3,1], "dbc__coverage__test_8cpp_source.html":[4,0,3,0], "dbc__database_8h.html":[4,0,0,0], @@ -51,28 +54,29 @@ var NAVTREEINDEX0 = "dbc__decoder_8h.html":[4,0,0,4], "dbc__decoder_8h_source.html":[4,0,0,4], "dbc__decoder__test_8cpp_source.html":[4,0,3,1], -"dbc__parser_8cpp.html":[4,0,0,5], -"dbc__parser_8cpp_source.html":[4,0,0,5], -"dbc__parser_8h.html":[4,0,0,6], -"dbc__parser_8h_source.html":[4,0,0,6], +"dbc__diagnostic_8h_source.html":[4,0,0,5], +"dbc__parser_8cpp.html":[4,0,0,6], +"dbc__parser_8cpp_source.html":[4,0,0,6], +"dbc__parser_8h.html":[4,0,0,7], +"dbc__parser_8h_source.html":[4,0,0,7], "dbc__parser__test_8cpp_source.html":[4,0,3,2], -"dbc__statement__handler_8cpp_source.html":[4,0,0,7], -"dbc__statement__handler_8h_source.html":[4,0,0,8], -"dbc__tree__builder_8cpp.html":[4,0,0,9], -"dbc__tree__builder_8cpp_source.html":[4,0,0,9], -"dbc__tree__builder_8h.html":[4,0,0,10], -"dbc__tree__builder_8h_source.html":[4,0,0,10], +"dbc__statement__handler_8cpp_source.html":[4,0,0,8], +"dbc__statement__handler_8h_source.html":[4,0,0,9], +"dbc__tree__builder_8cpp.html":[4,0,0,10], +"dbc__tree__builder_8cpp_source.html":[4,0,0,10], +"dbc__tree__builder_8h.html":[4,0,0,11], +"dbc__tree__builder_8h_source.html":[4,0,0,11], "dbc__tree__model_8cpp_source.html":[4,0,2,0], "dbc__tree__model_8h_source.html":[4,0,2,1], "dbc__tree__model__test_8cpp_source.html":[4,0,3,3], -"decode__database_8h.html":[4,0,0,11], -"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142b":[4,0,0,11,5], -"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142ba2ed1afe3c9215523e4272f46e6186b31":[4,0,0,11,5,1], -"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142baff97a9fdede09eaf6e1c8ec9f6a61dd5":[4,0,0,11,5,0], -"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1":[4,0,0,11,6], -"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1a71fed0c3428bf1a2e19af257c4bac379":[4,0,0,11,6,1], -"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1aa1a914735b205424ba6c40b85528d78a":[4,0,0,11,6,0], -"decode__database_8h_source.html":[4,0,0,11], +"decode__database_8h.html":[4,0,0,12], +"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142b":[4,0,0,12,5], +"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142ba2ed1afe3c9215523e4272f46e6186b31":[4,0,0,12,5,1], +"decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142baff97a9fdede09eaf6e1c8ec9f6a61dd5":[4,0,0,12,5,0], +"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1":[4,0,0,12,6], +"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1a71fed0c3428bf1a2e19af257c4bac379":[4,0,0,12,6,1], +"decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1aa1a914735b205424ba6c40b85528d78a":[4,0,0,12,6,0], +"decode__database_8h_source.html":[4,0,0,12], "dir_0f63d6441a2c250919e1e8723011eb2f.html":[4,0,2], "dir_4270bfced15e0e73154b13468c7c9ad9.html":[4,0,0], "dir_59425e443f801f1f2fd8bbe4959a3ccf.html":[4,0,3], @@ -80,8 +84,8 @@ var NAVTREEINDEX0 = "examples_2main_8cpp.html":[4,0,1,0], "examples_2main_8cpp_source.html":[4,0,1,0], "files.html":[4,0], -"frame__info_8h.html":[4,0,0,12], -"frame__info_8h_source.html":[4,0,0,12], +"frame__info_8h.html":[4,0,0,13], +"frame__info_8h_source.html":[4,0,0,13], "functions.html":[3,3,0], "functions_func.html":[3,3,1], "functions_vars.html":[3,3,2], @@ -90,164 +94,160 @@ var NAVTREEINDEX0 = "hierarchy.html":[3,2], "index.html":[], "md_README.html":[1], -"md_README.html#autotoc_md100":[1,35], -"md_README.html#autotoc_md102":[1,36], -"md_README.html#autotoc_md104":[1,37], -"md_README.html#autotoc_md106":[1,38], -"md_README.html#autotoc_md108":[1,39], -"md_README.html#autotoc_md110":[1,40], -"md_README.html#autotoc_md111":[1,40,0], -"md_README.html#autotoc_md112":[1,40,1], -"md_README.html#autotoc_md113":[1,40,2], -"md_README.html#autotoc_md114":[1,40,3], -"md_README.html#autotoc_md116":[1,41], -"md_README.html#autotoc_md117":[1,41,0], -"md_README.html#autotoc_md118":[1,41,1], -"md_README.html#autotoc_md119":[1,41,2], -"md_README.html#autotoc_md120":[1,41,3], -"md_README.html#autotoc_md121":[1,41,4], -"md_README.html#autotoc_md123":[1,42], -"md_README.html#autotoc_md124":[1,43], -"md_README.html#autotoc_md125":[1,43,0], -"md_README.html#autotoc_md126":[1,43,1], -"md_README.html#autotoc_md127":[1,43,2], -"md_README.html#autotoc_md21":[1,0], -"md_README.html#autotoc_md23":[1,1], -"md_README.html#autotoc_md24":[1,1,0], -"md_README.html#autotoc_md25":[1,1,1], -"md_README.html#autotoc_md27":[1,2], -"md_README.html#autotoc_md29":[1,3], -"md_README.html#autotoc_md31":[1,4], -"md_README.html#autotoc_md32":[1,5], -"md_README.html#autotoc_md34":[1,6], -"md_README.html#autotoc_md36":[1,7], -"md_README.html#autotoc_md38":[1,8], -"md_README.html#autotoc_md39":[1,9], -"md_README.html#autotoc_md41":[1,10], -"md_README.html#autotoc_md42":[1,11], -"md_README.html#autotoc_md44":[1,12], -"md_README.html#autotoc_md46":[1,13], -"md_README.html#autotoc_md48":[1,14], -"md_README.html#autotoc_md50":[1,15], -"md_README.html#autotoc_md52":[1,16], -"md_README.html#autotoc_md54":[1,17], -"md_README.html#autotoc_md56":[1,18], -"md_README.html#autotoc_md57":[1,19], -"md_README.html#autotoc_md59":[1,20], -"md_README.html#autotoc_md61":[1,20,0], -"md_README.html#autotoc_md63":[1,21], -"md_README.html#autotoc_md65":[1,22], -"md_README.html#autotoc_md67":[1,23], -"md_README.html#autotoc_md69":[1,24], -"md_README.html#autotoc_md70":[1,25], -"md_README.html#autotoc_md72":[1,25,0], -"md_README.html#autotoc_md74":[1,26], -"md_README.html#autotoc_md76":[1,26,0], -"md_README.html#autotoc_md78":[1,27], -"md_README.html#autotoc_md80":[1,28], -"md_README.html#autotoc_md82":[1,29], -"md_README.html#autotoc_md84":[1,30], -"md_README.html#autotoc_md86":[1,31], -"md_README.html#autotoc_md88":[1,32], -"md_README.html#autotoc_md90":[1,33], -"md_README.html#autotoc_md91":[1,33,0], -"md_README.html#autotoc_md92":[1,33,1], -"md_README.html#autotoc_md93":[1,33,2], -"md_README.html#autotoc_md94":[1,33,3], -"md_README.html#autotoc_md96":[1,34], -"md_README.html#autotoc_md97":[1,34,0], -"md_README.html#autotoc_md98":[1,34,1], +"md_README.html#autotoc_md100":[1,34], +"md_README.html#autotoc_md101":[1,34,0], +"md_README.html#autotoc_md102":[1,34,1], +"md_README.html#autotoc_md104":[1,35], +"md_README.html#autotoc_md106":[1,36], +"md_README.html#autotoc_md108":[1,37], +"md_README.html#autotoc_md110":[1,38], +"md_README.html#autotoc_md112":[1,39], +"md_README.html#autotoc_md114":[1,40], +"md_README.html#autotoc_md115":[1,40,0], +"md_README.html#autotoc_md116":[1,40,1], +"md_README.html#autotoc_md117":[1,40,2], +"md_README.html#autotoc_md118":[1,40,3], +"md_README.html#autotoc_md120":[1,41], +"md_README.html#autotoc_md121":[1,41,0], +"md_README.html#autotoc_md122":[1,41,1], +"md_README.html#autotoc_md123":[1,41,2], +"md_README.html#autotoc_md124":[1,41,3], +"md_README.html#autotoc_md125":[1,41,4], +"md_README.html#autotoc_md127":[1,42], +"md_README.html#autotoc_md128":[1,43], +"md_README.html#autotoc_md129":[1,43,0], +"md_README.html#autotoc_md130":[1,43,1], +"md_README.html#autotoc_md131":[1,43,2], +"md_README.html#autotoc_md24":[1,0], +"md_README.html#autotoc_md26":[1,1], +"md_README.html#autotoc_md27":[1,1,0], +"md_README.html#autotoc_md28":[1,1,1], +"md_README.html#autotoc_md30":[1,2], +"md_README.html#autotoc_md32":[1,3], +"md_README.html#autotoc_md34":[1,4], +"md_README.html#autotoc_md35":[1,5], +"md_README.html#autotoc_md37":[1,6], +"md_README.html#autotoc_md39":[1,7], +"md_README.html#autotoc_md41":[1,8], +"md_README.html#autotoc_md42":[1,9], +"md_README.html#autotoc_md44":[1,10], +"md_README.html#autotoc_md45":[1,11], +"md_README.html#autotoc_md47":[1,12], +"md_README.html#autotoc_md49":[1,13], +"md_README.html#autotoc_md51":[1,14], +"md_README.html#autotoc_md53":[1,15], +"md_README.html#autotoc_md55":[1,16], +"md_README.html#autotoc_md57":[1,17], +"md_README.html#autotoc_md59":[1,18], +"md_README.html#autotoc_md60":[1,19], +"md_README.html#autotoc_md62":[1,20], +"md_README.html#autotoc_md64":[1,20,0], +"md_README.html#autotoc_md66":[1,21], +"md_README.html#autotoc_md68":[1,22], +"md_README.html#autotoc_md70":[1,23], +"md_README.html#autotoc_md71":[1,23,0], +"md_README.html#autotoc_md73":[1,24], +"md_README.html#autotoc_md74":[1,25], +"md_README.html#autotoc_md76":[1,25,0], +"md_README.html#autotoc_md78":[1,26], +"md_README.html#autotoc_md80":[1,26,0], +"md_README.html#autotoc_md82":[1,27], +"md_README.html#autotoc_md84":[1,28], +"md_README.html#autotoc_md86":[1,29], +"md_README.html#autotoc_md88":[1,30], +"md_README.html#autotoc_md90":[1,31], +"md_README.html#autotoc_md92":[1,32], +"md_README.html#autotoc_md94":[1,33], +"md_README.html#autotoc_md95":[1,33,0], +"md_README.html#autotoc_md96":[1,33,1], +"md_README.html#autotoc_md97":[1,33,2], +"md_README.html#autotoc_md98":[1,33,3], "md_changelog.html":[0], "md_changelog.html#autotoc_md1":[0,0], -"md_changelog.html#autotoc_md10":[0,0,2,1], -"md_changelog.html#autotoc_md11":[0,0,2,2], -"md_changelog.html#autotoc_md12":[0,0,3], -"md_changelog.html#autotoc_md13":[0,0,3,0], -"md_changelog.html#autotoc_md14":[0,0,3,1], -"md_changelog.html#autotoc_md15":[0,1], -"md_changelog.html#autotoc_md16":[0,1,0], -"md_changelog.html#autotoc_md17":[0,1,1], -"md_changelog.html#autotoc_md18":[0,1,1,0], -"md_changelog.html#autotoc_md19":[0,1,1,1], +"md_changelog.html#autotoc_md10":[0,0,2,0], +"md_changelog.html#autotoc_md11":[0,0,3], +"md_changelog.html#autotoc_md12":[0,0,3,0], +"md_changelog.html#autotoc_md13":[0,0,3,1], +"md_changelog.html#autotoc_md14":[0,0,3,2], +"md_changelog.html#autotoc_md15":[0,0,4], +"md_changelog.html#autotoc_md16":[0,0,4,0], +"md_changelog.html#autotoc_md17":[0,0,4,1], +"md_changelog.html#autotoc_md18":[0,1], +"md_changelog.html#autotoc_md19":[0,1,0], "md_changelog.html#autotoc_md2":[0,0,0], +"md_changelog.html#autotoc_md20":[0,1,1], +"md_changelog.html#autotoc_md21":[0,1,1,0], +"md_changelog.html#autotoc_md22":[0,1,1,1], "md_changelog.html#autotoc_md3":[0,0,0,0], "md_changelog.html#autotoc_md4":[0,0,0,1], -"md_changelog.html#autotoc_md5":[0,0,0,2], -"md_changelog.html#autotoc_md6":[0,0,1], -"md_changelog.html#autotoc_md7":[0,0,1,0], -"md_changelog.html#autotoc_md8":[0,0,2], -"md_changelog.html#autotoc_md9":[0,0,2,0], +"md_changelog.html#autotoc_md5":[0,0,1], +"md_changelog.html#autotoc_md6":[0,0,1,0], +"md_changelog.html#autotoc_md7":[0,0,1,1], +"md_changelog.html#autotoc_md8":[0,0,1,2], +"md_changelog.html#autotoc_md9":[0,0,2], "md_tests_2README.html":[2], -"md_tests_2README.html#autotoc_md129":[2,0], -"md_tests_2README.html#autotoc_md130":[2,1], -"md_tests_2README.html#autotoc_md131":[2,2], -"md_tests_2README.html#autotoc_md132":[2,3], -"multiplexing_8h_source.html":[4,0,0,13], +"md_tests_2README.html#autotoc_md133":[2,0], +"md_tests_2README.html#autotoc_md134":[2,1], +"md_tests_2README.html#autotoc_md135":[2,2], +"md_tests_2README.html#autotoc_md136":[2,3], +"multiplexing_8h_source.html":[4,0,0,14], "pages.html":[], -"signal__info_8h.html":[4,0,0,14], -"signal__info_8h_source.html":[4,0,0,14], +"signal__info_8h.html":[4,0,0,15], +"signal__info_8h_source.html":[4,0,0,15], "structDbcDatabase.html":[3,0,1], "structDbcDatabase.html#a2cade5d0234ee816132127542f8c612b":[3,0,1,0], -"structDbcParseContext.html":[3,0,5], -"structDecodeDatabase.html":[3,0,14], -"structDecodeFrame.html":[3,0,17], -"structDecodeFrame.html#a1d3c54055c0cbceb73adf551f7067f23":[3,0,17,4], -"structDecodeFrame.html#a2551102670c4a540fced4c71da0b369d":[3,0,17,5], -"structDecodeFrame.html#a25819ef907a32391af5c9f7cae9cdb22":[3,0,17,7], -"structDecodeFrame.html#a3ee2348d781f8f15aaf87e8dcf57ec41":[3,0,17,2], -"structDecodeFrame.html#a51111ac13988be372d5673d12cf3e060":[3,0,17,3], -"structDecodeFrame.html#a52e10215388db7df8b541b9d9909edcf":[3,0,17,1], -"structDecodeFrame.html#a7f4e71bbdec3f424b625e724e3dfbf14":[3,0,17,8], -"structDecodeFrame.html#aa0a7f8fd5bfde2148dfd0d838328f579":[3,0,17,0], -"structDecodeFrame.html#ad78241dc40c793aabb8495b6989b81a9":[3,0,17,6], -"structDecodeSignal.html":[3,0,18], -"structDecodeSignal.html#a0fb84e19a0ab3bd50b6f65c1075ebc25":[3,0,18,7], -"structDecodeSignal.html#a38eed9ca7581423fd8bfbedcffc12092":[3,0,18,9], -"structDecodeSignal.html#a428c39913a366a8476dd291061354391":[3,0,18,5], -"structDecodeSignal.html#a4a6ba87142a9badbf0ca830e9e709cb7":[3,0,18,8], -"structDecodeSignal.html#a58cf5844f2272a23dcb9687d912e4780":[3,0,18,0], -"structDecodeSignal.html#a822155d9bf4ed5f3300c9e9befe606ff":[3,0,18,11], -"structDecodeSignal.html#a92db637af4e224a0ae70173050dc3f74":[3,0,18,6], -"structDecodeSignal.html#a9d37638129263b8902ba5be59baf39a8":[3,0,18,4], -"structDecodeSignal.html#aaf5d7527ddf65b6355c2b4f3626df22d":[3,0,18,1], -"structDecodeSignal.html#abdbae62a64d2df716bf60c6b67b30eaa":[3,0,18,10], -"structDecodeSignal.html#abdc4c4bb4a67a6d61d6ca81e8a52833d":[3,0,18,3], -"structDecodeSignal.html#acd4ef5ee30421d117b5756854302debb":[3,0,18,2], -"structDecodeSignal.html#ae28c905d4a2bc86419c2a8361bfea473":[3,0,18,12], -"structDecodedFrameValue.html":[3,0,15], -"structDecodedFrameValue.html#a4f51c31110dba1f73a763c596372beb0":[3,0,15,2], -"structDecodedFrameValue.html#a60dda1cc352d2c8087f0bdbc81dd266c":[3,0,15,0], -"structDecodedFrameValue.html#adae123ac7fbb4a5c314b64b01109f4a8":[3,0,15,1], -"structDecodedSignalValue.html":[3,0,16], -"structDecodedSignalValue.html#a503c90b4b1a610b8252c45e466367c28":[3,0,16,2], -"structDecodedSignalValue.html#a6847d05b3cb00d5e0f6c611968f57978":[3,0,16,3], -"structDecodedSignalValue.html#aac0ed361af545cde48d0e6f41a859686":[3,0,16,4], -"structDecodedSignalValue.html#acadc3b3bb21dd6b0412d342c7e6b20d7":[3,0,16,1], -"structDecodedSignalValue.html#affc38af1bf31bcb6f2c33044bce92bd2":[3,0,16,0], -"structFrameInfo.html":[3,0,19], -"structFrameInfo.html#a34b726afaad2ac5c697fdb2ac070cdaf":[3,0,19,2], -"structFrameInfo.html#a3f7e25d67ddae22f2ed50823a5a26084":[3,0,19,8], -"structFrameInfo.html#a4737a5420213ad4304724e39f3a4e55d":[3,0,19,4], -"structFrameInfo.html#a92749ec3798d4211a505860fb389a9e8":[3,0,19,6], -"structFrameInfo.html#aa2b198ea0f55e560c123d35e7b3ecab9":[3,0,19,5], -"structFrameInfo.html#abb53a7f93ed7abc0ea1ae4a8ccafcdcb":[3,0,19,0], -"structFrameInfo.html#ace75121294f9d89b762080ab5643293c":[3,0,19,7], -"structFrameInfo.html#aee518b33f1000bf0b7f6e4a87474c943":[3,0,19,3], -"structFrameInfo.html#af470b0742c05bfbffc31c51a68f5c05e":[3,0,19,1], -"structFrameKey.html":[3,0,20], -"structFrameKeyHasher.html":[3,0,21], -"structMultiplexing.html":[3,0,22], -"structPendingValueDescriptions.html":[3,0,23], -"structRawCanFrame.html":[3,0,24], -"structRawCanFrame.html#a0acb487612104c99c9907344c035df83":[3,0,24,2], -"structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4":[3,0,24,0], -"structRawCanFrame.html#a462193d275adc1dba8bd18ffa0e36bb7":[3,0,24,1], -"structSignalInfo.html":[3,0,25], -"structSignalInfo.html#a1008b5201f71848177217bd52fb84baa":[3,0,25,2], -"structSignalInfo.html#a1f214f03e94ef5794de2d3367bfcbd01":[3,0,25,9], -"structSignalInfo.html#a2c95562fd0b29327a7fd7b1e6feee7f3":[3,0,25,10], -"structSignalInfo.html#a379e422a00cad56f896cacf60455b088":[3,0,25,0], -"structSignalInfo.html#a43f47d0433d0cc39076bd7278b46af9c":[3,0,25,11], -"structSignalInfo.html#a52a52b320eef92fbcb4626307f9a498f":[3,0,25,4], -"structSignalInfo.html#ab7d0769f47aa540656b22e4e49db517e":[3,0,25,6] +"structDbcDiagnostic.html":[3,0,4], +"structDbcParseContext.html":[3,0,8], +"structDbcParseResult.html":[3,0,10], +"structDecodeDatabase.html":[3,0,18], +"structDecodeFrame.html":[3,0,21], +"structDecodeFrame.html#a1d3c54055c0cbceb73adf551f7067f23":[3,0,21,4], +"structDecodeFrame.html#a2551102670c4a540fced4c71da0b369d":[3,0,21,5], +"structDecodeFrame.html#a25819ef907a32391af5c9f7cae9cdb22":[3,0,21,7], +"structDecodeFrame.html#a3ee2348d781f8f15aaf87e8dcf57ec41":[3,0,21,2], +"structDecodeFrame.html#a51111ac13988be372d5673d12cf3e060":[3,0,21,3], +"structDecodeFrame.html#a52e10215388db7df8b541b9d9909edcf":[3,0,21,1], +"structDecodeFrame.html#a7f4e71bbdec3f424b625e724e3dfbf14":[3,0,21,8], +"structDecodeFrame.html#aa0a7f8fd5bfde2148dfd0d838328f579":[3,0,21,0], +"structDecodeFrame.html#ad78241dc40c793aabb8495b6989b81a9":[3,0,21,6], +"structDecodeSignal.html":[3,0,22], +"structDecodeSignal.html#a0fb84e19a0ab3bd50b6f65c1075ebc25":[3,0,22,7], +"structDecodeSignal.html#a38eed9ca7581423fd8bfbedcffc12092":[3,0,22,9], +"structDecodeSignal.html#a428c39913a366a8476dd291061354391":[3,0,22,5], +"structDecodeSignal.html#a4a6ba87142a9badbf0ca830e9e709cb7":[3,0,22,8], +"structDecodeSignal.html#a58cf5844f2272a23dcb9687d912e4780":[3,0,22,0], +"structDecodeSignal.html#a822155d9bf4ed5f3300c9e9befe606ff":[3,0,22,11], +"structDecodeSignal.html#a92db637af4e224a0ae70173050dc3f74":[3,0,22,6], +"structDecodeSignal.html#a9d37638129263b8902ba5be59baf39a8":[3,0,22,4], +"structDecodeSignal.html#aaf5d7527ddf65b6355c2b4f3626df22d":[3,0,22,1], +"structDecodeSignal.html#abdbae62a64d2df716bf60c6b67b30eaa":[3,0,22,10], +"structDecodeSignal.html#abdc4c4bb4a67a6d61d6ca81e8a52833d":[3,0,22,3], +"structDecodeSignal.html#acd4ef5ee30421d117b5756854302debb":[3,0,22,2], +"structDecodeSignal.html#ae28c905d4a2bc86419c2a8361bfea473":[3,0,22,12], +"structDecodedFrameValue.html":[3,0,19], +"structDecodedFrameValue.html#a4f51c31110dba1f73a763c596372beb0":[3,0,19,2], +"structDecodedFrameValue.html#a60dda1cc352d2c8087f0bdbc81dd266c":[3,0,19,0], +"structDecodedFrameValue.html#adae123ac7fbb4a5c314b64b01109f4a8":[3,0,19,1], +"structDecodedSignalValue.html":[3,0,20], +"structDecodedSignalValue.html#a503c90b4b1a610b8252c45e466367c28":[3,0,20,2], +"structDecodedSignalValue.html#a6847d05b3cb00d5e0f6c611968f57978":[3,0,20,3], +"structDecodedSignalValue.html#aac0ed361af545cde48d0e6f41a859686":[3,0,20,4], +"structDecodedSignalValue.html#acadc3b3bb21dd6b0412d342c7e6b20d7":[3,0,20,1], +"structDecodedSignalValue.html#affc38af1bf31bcb6f2c33044bce92bd2":[3,0,20,0], +"structFrameInfo.html":[3,0,23], +"structFrameInfo.html#a34b726afaad2ac5c697fdb2ac070cdaf":[3,0,23,2], +"structFrameInfo.html#a3f7e25d67ddae22f2ed50823a5a26084":[3,0,23,8], +"structFrameInfo.html#a4737a5420213ad4304724e39f3a4e55d":[3,0,23,4], +"structFrameInfo.html#a92749ec3798d4211a505860fb389a9e8":[3,0,23,6], +"structFrameInfo.html#aa2b198ea0f55e560c123d35e7b3ecab9":[3,0,23,5], +"structFrameInfo.html#abb53a7f93ed7abc0ea1ae4a8ccafcdcb":[3,0,23,0], +"structFrameInfo.html#ace75121294f9d89b762080ab5643293c":[3,0,23,7], +"structFrameInfo.html#aee518b33f1000bf0b7f6e4a87474c943":[3,0,23,3], +"structFrameInfo.html#af470b0742c05bfbffc31c51a68f5c05e":[3,0,23,1], +"structFrameKey.html":[3,0,24], +"structFrameKeyHasher.html":[3,0,25], +"structMultiplexing.html":[3,0,26], +"structPendingValueDescriptions.html":[3,0,27], +"structRawCanFrame.html":[3,0,28], +"structRawCanFrame.html#a0acb487612104c99c9907344c035df83":[3,0,28,2] }; diff --git a/docs/html/navtreeindex1.js b/docs/html/navtreeindex1.js index 4c6cf8a..2a072e1 100644 --- a/docs/html/navtreeindex1.js +++ b/docs/html/navtreeindex1.js @@ -1,22 +1,32 @@ var NAVTREEINDEX1 = { -"structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5":[3,0,25,12], -"structSignalInfo.html#ace290724f9801521609aedaa946d61f1":[3,0,25,1], -"structSignalInfo.html#ada7bf94fbeaa26bd08c73982b5af255b":[3,0,25,7], -"structSignalInfo.html#adf1c4331b9eabced0d7fdda40ff0eb52":[3,0,25,8], -"structSignalInfo.html#ae4f78d99a2750aa564d7eba860171499":[3,0,25,5], -"structSignalInfo.html#af363b1563fb4c7cc8973f9a80c06846c":[3,0,25,3], +"structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4":[3,0,28,0], +"structRawCanFrame.html#a462193d275adc1dba8bd18ffa0e36bb7":[3,0,28,1], +"structSignalInfo.html":[3,0,29], +"structSignalInfo.html#a1008b5201f71848177217bd52fb84baa":[3,0,29,2], +"structSignalInfo.html#a1f214f03e94ef5794de2d3367bfcbd01":[3,0,29,9], +"structSignalInfo.html#a2c95562fd0b29327a7fd7b1e6feee7f3":[3,0,29,10], +"structSignalInfo.html#a379e422a00cad56f896cacf60455b088":[3,0,29,0], +"structSignalInfo.html#a43f47d0433d0cc39076bd7278b46af9c":[3,0,29,11], +"structSignalInfo.html#a52a52b320eef92fbcb4626307f9a498f":[3,0,29,4], +"structSignalInfo.html#ab7d0769f47aa540656b22e4e49db517e":[3,0,29,6], +"structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5":[3,0,29,12], +"structSignalInfo.html#ace290724f9801521609aedaa946d61f1":[3,0,29,1], +"structSignalInfo.html#ada7bf94fbeaa26bd08c73982b5af255b":[3,0,29,7], +"structSignalInfo.html#adf1c4331b9eabced0d7fdda40ff0eb52":[3,0,29,8], +"structSignalInfo.html#ae4f78d99a2750aa564d7eba860171499":[3,0,29,5], +"structSignalInfo.html#af363b1563fb4c7cc8973f9a80c06846c":[3,0,29,3], "tests_2main_8cpp_source.html":[4,0,3,4], -"text__utils_8h_source.html":[4,0,0,15], -"tree__node_8cpp.html":[4,0,0,16], -"tree__node_8cpp_source.html":[4,0,0,16], -"tree__node_8h.html":[4,0,0,17], -"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16":[4,0,0,17,1], -"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16a085fea7abdc5d904fe69a3081efd7398":[4,0,0,17,1,2], -"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16a3bb3e8c8a24891ba0f7608bcc96f8b0a":[4,0,0,17,1,1], -"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16afa03eb688ad8aa1db593d33dabd89bad":[4,0,0,17,1,0], -"tree__node_8h_source.html":[4,0,0,17], +"text__utils_8h_source.html":[4,0,0,16], +"tree__node_8cpp.html":[4,0,0,17], +"tree__node_8cpp_source.html":[4,0,0,17], +"tree__node_8h.html":[4,0,0,18], +"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16":[4,0,0,18,1], +"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16a085fea7abdc5d904fe69a3081efd7398":[4,0,0,18,1,2], +"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16a3bb3e8c8a24891ba0f7608bcc96f8b0a":[4,0,0,18,1,1], +"tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16afa03eb688ad8aa1db593d33dabd89bad":[4,0,0,18,1,0], +"tree__node_8h_source.html":[4,0,0,18], "tree__node__test_8cpp_source.html":[4,0,3,5], -"typefactory_8h_source.html":[4,0,0,18], -"value__descriptions_8h_source.html":[4,0,0,19] +"typefactory_8h_source.html":[4,0,0,19], +"value__descriptions_8h_source.html":[4,0,0,20] }; diff --git a/docs/html/search/all_0.js b/docs/html/search/all_0.js index e9fa341..90954db 100644 --- a/docs/html/search/all_0.js +++ b/docs/html/search/all_0.js @@ -1,10 +1,10 @@ var searchData= [ - ['0_20—_202026_2006_2014_0',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]], - ['01_1',['2026-10-01',['../md_changelog.html#autotoc_md12',1,'']]], - ['03_2013_2',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['05_3',['2026-10-05',['../md_changelog.html#autotoc_md8',1,'']]], - ['06_4',['2026-10-06',['../md_changelog.html#autotoc_md6',1,'']]], - ['06_2014_5',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]], - ['07_6',['2026-10-07',['../md_changelog.html#autotoc_md2',1,'']]] + ['0_20—_202026_2006_2014_0',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]], + ['01_1',['2026-10-01',['../md_changelog.html#autotoc_md15',1,'']]], + ['03_2013_2',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['05_3',['2026-10-05',['../md_changelog.html#autotoc_md11',1,'']]], + ['06_4',['2026-10-06',['../md_changelog.html#autotoc_md9',1,'']]], + ['06_2014_5',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]], + ['07_6',['2026-10-07',['../md_changelog.html#autotoc_md5',1,'']]] ]; diff --git a/docs/html/search/all_1.js b/docs/html/search/all_1.js index 6d35b2f..5fe8838 100644 --- a/docs/html/search/all_1.js +++ b/docs/html/search/all_1.js @@ -1,11 +1,13 @@ var searchData= [ - ['1_20already_20implemented_0',['Stage 1 - already implemented',['../md_README.html#autotoc_md111',1,'']]], - ['1_20parse_20and_20ui_20path_1',['1. Parse and UI path',['../md_README.html#autotoc_md24',1,'']]], - ['10_2001_2',['2026-10-01',['../md_changelog.html#autotoc_md12',1,'']]], - ['10_2005_3',['2026-10-05',['../md_changelog.html#autotoc_md8',1,'']]], - ['10_2006_4',['2026-10-06',['../md_changelog.html#autotoc_md6',1,'']]], - ['10_2007_5',['2026-10-07',['../md_changelog.html#autotoc_md2',1,'']]], - ['13_6',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['14_7',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]] + ['1_20already_20implemented_0',['Stage 1 - already implemented',['../md_README.html#autotoc_md115',1,'']]], + ['1_20parse_20and_20ui_20path_1',['1. Parse and UI path',['../md_README.html#autotoc_md27',1,'']]], + ['10_2001_2',['2026-10-01',['../md_changelog.html#autotoc_md15',1,'']]], + ['10_2005_3',['2026-10-05',['../md_changelog.html#autotoc_md11',1,'']]], + ['10_2006_4',['2026-10-06',['../md_changelog.html#autotoc_md9',1,'']]], + ['10_2007_5',['2026-10-07',['../md_changelog.html#autotoc_md5',1,'']]], + ['10_2011_6',['2026-10-11',['../md_changelog.html#autotoc_md2',1,'']]], + ['11_7',['2026-10-11',['../md_changelog.html#autotoc_md2',1,'']]], + ['13_8',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['14_9',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]] ]; diff --git a/docs/html/search/all_10.js b/docs/html/search/all_10.js index 8e48a81..a9d8425 100644 --- a/docs/html/search/all_10.js +++ b/docs/html/search/all_10.js @@ -1,8 +1,8 @@ var searchData= [ ['name_0',['name',['../structDecodeSignal.html#a58cf5844f2272a23dcb9687d912e4780',1,'DecodeSignal::name'],['../structDecodeFrame.html#aa0a7f8fd5bfde2148dfd0d838328f579',1,'DecodeFrame::name'],['../structFrameInfo.html#abb53a7f93ed7abc0ea1ae4a8ccafcdcb',1,'FrameInfo::name'],['../structSignalInfo.html#a379e422a00cad56f896cacf60455b088',1,'SignalInfo::name']]], - ['next_20steps_1',['Recommended Next Steps',['../md_README.html#autotoc_md110',1,'']]], + ['next_20steps_1',['Recommended Next Steps',['../md_README.html#autotoc_md114',1,'']]], ['nodetype_2',['NodeType',['../tree__node_8h.html#acac9cbaeea226ed297804c012dc12b16',1,'tree_node.h']]], - ['normalization_3',['CAN ID Normalization',['../md_README.html#autotoc_md82',1,'']]], - ['not_20enough_4',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]] + ['normalization_3',['CAN ID Normalization',['../md_README.html#autotoc_md86',1,'']]], + ['not_20enough_4',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]] ]; diff --git a/docs/html/search/all_11.js b/docs/html/search/all_11.js index d6878b9..2f4e13f 100644 --- a/docs/html/search/all_11.js +++ b/docs/html/search/all_11.js @@ -1,8 +1,8 @@ var searchData= [ ['offset_0',['offset',['../structDecodeSignal.html#a92db637af4e224a0ae70173050dc3f74',1,'DecodeSignal::offset'],['../structSignalInfo.html#ab7d0769f47aa540656b22e4e49db517e',1,'SignalInfo::offset']]], - ['on_20debian_20ubuntu_1',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['optional_20model_20tests_2',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md131',1,'']]], - ['optional_20qt_20model_20adapter_3',['Optional Qt model adapter',['../md_README.html#autotoc_md118',1,'']]], - ['overview_4',['Overview',['../md_README.html#autotoc_md21',1,'']]] + ['on_20debian_20ubuntu_1',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['optional_20model_20tests_2',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md135',1,'']]], + ['optional_20qt_20model_20adapter_3',['Optional Qt model adapter',['../md_README.html#autotoc_md122',1,'']]], + ['overview_4',['Overview',['../md_README.html#autotoc_md24',1,'']]] ]; diff --git a/docs/html/search/all_12.js b/docs/html/search/all_12.js index 9bc5df7..aa6131a 100644 --- a/docs/html/search/all_12.js +++ b/docs/html/search/all_12.js @@ -1,19 +1,20 @@ var searchData= [ - ['parse_20and_20ui_20path_0',['1. Parse and UI path',['../md_README.html#autotoc_md24',1,'']]], - ['parse_20dbc_1',['Parse DBC',['../md_README.html#autotoc_md91',1,'']]], - ['parse_20errors_2',['parse errors',['../md_README.html#autotoc_md72',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md76',1,'Signal validation and parse errors']]], - ['parsed_20data_20structures_3',['Parsed Data Structures',['../md_README.html#autotoc_md31',1,'']]], + ['parse_20and_20ui_20path_0',['1. Parse and UI path',['../md_README.html#autotoc_md27',1,'']]], + ['parse_20dbc_1',['Parse DBC',['../md_README.html#autotoc_md95',1,'']]], + ['parse_20errors_2',['parse errors',['../md_README.html#autotoc_md76',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md80',1,'Signal validation and parse errors']]], + ['parsed_20data_20structures_3',['Parsed Data Structures',['../md_README.html#autotoc_md34',1,'']]], ['parsefile_4',['ParseFile',['../classDbcParser.html#aef72826942c9095d653fafa435855e56',1,'DbcParser']]], - ['parser_20and_20runtime_20decode_20module_20documentation_5',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['parser_20coverage_6',['Parser coverage',['../md_tests_2README.html#autotoc_md130',1,'']]], - ['parser_20support_7',['Parser Support',['../md_README.html#autotoc_md67',1,'']]], - ['path_8',['path',['../md_README.html#autotoc_md24',1,'1. Parse and UI path'],['../md_README.html#autotoc_md25',1,'2. Runtime decode path'],['../md_README.html#autotoc_md97',1,'live path'],['../md_README.html#autotoc_md98',1,'trace path']]], - ['pendingvaluedescriptions_9',['PendingValueDescriptions',['../structPendingValueDescriptions.html',1,'']]], - ['pgn_10',['pgn',['../structFrameInfo.html#aee518b33f1000bf0b7f6e4a87474c943',1,'FrameInfo::pgn'],['../structDecodeFrame.html#a1d3c54055c0cbceb73adf551f7067f23',1,'DecodeFrame::pgn']]], - ['pgn_20extraction_11',['PGN Extraction',['../md_README.html#autotoc_md84',1,'']]], - ['physicalvalue_12',['physicalValue',['../structDecodedSignalValue.html#a6847d05b3cb00d5e0f6c611968f57978',1,'DecodedSignalValue']]], - ['precision_13',['Raw value representation and precision',['../md_README.html#autotoc_md61',1,'']]], - ['public_14',['public',['../structFrameInfo.html#a3f7e25d67ddae22f2ed50823a5a26084',1,'FrameInfo::public'],['../structDecodeFrame.html#a7f4e71bbdec3f424b625e724e3dfbf14',1,'DecodeFrame::public'],['../structDecodedFrameValue.html#adae123ac7fbb4a5c314b64b01109f4a8',1,'DecodedFrameValue::public']]], - ['purpose_15',['Purpose',['../md_README.html#autotoc_md42',1,'']]] + ['parsefilewithdiagnostics_5',['ParseFileWithDiagnostics',['../classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc',1,'DbcParser']]], + ['parser_20and_20runtime_20decode_20module_20documentation_6',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], + ['parser_20coverage_7',['Parser coverage',['../md_tests_2README.html#autotoc_md134',1,'']]], + ['parser_20support_8',['Parser Support',['../md_README.html#autotoc_md70',1,'']]], + ['path_9',['path',['../md_README.html#autotoc_md27',1,'1. Parse and UI path'],['../md_README.html#autotoc_md28',1,'2. Runtime decode path'],['../md_README.html#autotoc_md101',1,'live path'],['../md_README.html#autotoc_md102',1,'trace path']]], + ['pendingvaluedescriptions_10',['PendingValueDescriptions',['../structPendingValueDescriptions.html',1,'']]], + ['pgn_11',['pgn',['../structFrameInfo.html#aee518b33f1000bf0b7f6e4a87474c943',1,'FrameInfo::pgn'],['../structDecodeFrame.html#a1d3c54055c0cbceb73adf551f7067f23',1,'DecodeFrame::pgn']]], + ['pgn_20extraction_12',['PGN Extraction',['../md_README.html#autotoc_md88',1,'']]], + ['physicalvalue_13',['physicalValue',['../structDecodedSignalValue.html#a6847d05b3cb00d5e0f6c611968f57978',1,'DecodedSignalValue']]], + ['precision_14',['Raw value representation and precision',['../md_README.html#autotoc_md64',1,'']]], + ['public_15',['public',['../structFrameInfo.html#a3f7e25d67ddae22f2ed50823a5a26084',1,'FrameInfo::public'],['../structDecodeFrame.html#a7f4e71bbdec3f424b625e724e3dfbf14',1,'DecodeFrame::public'],['../structDecodedFrameValue.html#adae123ac7fbb4a5c314b64b01109f4a8',1,'DecodedFrameValue::public']]], + ['purpose_16',['Purpose',['../md_README.html#autotoc_md45',1,'']]] ]; diff --git a/docs/html/search/all_13.js b/docs/html/search/all_13.js index 6fe6db3..4c40f73 100644 --- a/docs/html/search/all_13.js +++ b/docs/html/search/all_13.js @@ -1,8 +1,8 @@ var searchData= [ - ['qt_0',['Standalone tree tests without Qt',['../md_README.html#autotoc_md119',1,'']]], - ['qt_20creator_1',['qt creator',['../md_README.html#autotoc_md127',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md126',1,'Configure the GCC coverage build in Qt Creator']]], - ['qt_20libraries_2',['Build core without Qt libraries',['../md_README.html#autotoc_md117',1,'']]], - ['qt_20model_20adapter_3',['Optional Qt model adapter',['../md_README.html#autotoc_md118',1,'']]], + ['qt_0',['Standalone tree tests without Qt',['../md_README.html#autotoc_md123',1,'']]], + ['qt_20creator_1',['qt creator',['../md_README.html#autotoc_md131',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md130',1,'Configure the GCC coverage build in Qt Creator']]], + ['qt_20libraries_2',['Build core without Qt libraries',['../md_README.html#autotoc_md121',1,'']]], + ['qt_20model_20adapter_3',['Optional Qt model adapter',['../md_README.html#autotoc_md122',1,'']]], ['qttest_20regression_20tests_4',['QtTest regression tests',['../md_tests_2README.html',1,'']]] ]; diff --git a/docs/html/search/all_14.js b/docs/html/search/all_14.js index b042d63..4a1f61e 100644 --- a/docs/html/search/all_14.js +++ b/docs/html/search/all_14.js @@ -1,20 +1,20 @@ var searchData= [ - ['raw_20frame_0',['Decode a raw frame',['../md_README.html#autotoc_md94',1,'']]], - ['raw_20value_20representation_20and_20precision_1',['Raw value representation and precision',['../md_README.html#autotoc_md61',1,'']]], + ['raw_20frame_0',['Decode a raw frame',['../md_README.html#autotoc_md98',1,'']]], + ['raw_20value_20representation_20and_20precision_1',['Raw value representation and precision',['../md_README.html#autotoc_md64',1,'']]], ['rawcanframe_2',['RawCanFrame',['../structRawCanFrame.html',1,'']]], - ['rawcanframe_20tt_3',['<tt>RawCanFrame</tt>',['../md_README.html#autotoc_md57',1,'']]], + ['rawcanframe_20tt_3',['<tt>RawCanFrame</tt>',['../md_README.html#autotoc_md60',1,'']]], ['rawvalue_4',['rawValue',['../structDecodedSignalValue.html#a503c90b4b1a610b8252c45e466367c28',1,'DecodedSignalValue']]], ['receivers_5',['receivers',['../structDecodeSignal.html#abdbae62a64d2df716bf60c6b67b30eaa',1,'DecodeSignal::receivers'],['../structSignalInfo.html#a2c95562fd0b29327a7fd7b1e6feee7f3',1,'SignalInfo::receivers']]], - ['recommended_20next_20steps_6',['Recommended Next Steps',['../md_README.html#autotoc_md110',1,'']]], + ['recommended_20next_20steps_6',['Recommended Next Steps',['../md_README.html#autotoc_md114',1,'']]], ['registertype_7',['registerType',['../classTypeFactory.html#ad6d85795285ee21193ac03e1b24762d3',1,'TypeFactory']]], - ['regression_20coverage_8',['Additional regression coverage',['../md_tests_2README.html#autotoc_md132',1,'']]], - ['regression_20tests_9',['regression tests',['../md_tests_2README.html',1,'QtTest regression tests'],['../md_README.html#autotoc_md123',1,'Regression tests']]], - ['representation_20and_20precision_10',['Raw value representation and precision',['../md_README.html#autotoc_md61',1,'']]], - ['run_20the_20demo_11',['Build and run the demo',['../md_README.html#autotoc_md120',1,'']]], - ['runtime_20decode_20database_12',['Build runtime decode database',['../md_README.html#autotoc_md93',1,'']]], - ['runtime_20decode_20layer_13',['Runtime Decode Layer',['../md_README.html#autotoc_md41',1,'']]], - ['runtime_20decode_20layer_20exists_14',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], + ['regression_20coverage_8',['Additional regression coverage',['../md_tests_2README.html#autotoc_md136',1,'']]], + ['regression_20tests_9',['regression tests',['../md_tests_2README.html',1,'QtTest regression tests'],['../md_README.html#autotoc_md127',1,'Regression tests']]], + ['representation_20and_20precision_10',['Raw value representation and precision',['../md_README.html#autotoc_md64',1,'']]], + ['run_20the_20demo_11',['Build and run the demo',['../md_README.html#autotoc_md124',1,'']]], + ['runtime_20decode_20database_12',['Build runtime decode database',['../md_README.html#autotoc_md97',1,'']]], + ['runtime_20decode_20layer_13',['Runtime Decode Layer',['../md_README.html#autotoc_md44',1,'']]], + ['runtime_20decode_20layer_20exists_14',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], ['runtime_20decode_20module_20documentation_15',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['runtime_20decode_20path_16',['2. Runtime decode path',['../md_README.html#autotoc_md25',1,'']]] + ['runtime_20decode_20path_16',['2. Runtime decode path',['../md_README.html#autotoc_md28',1,'']]] ]; diff --git a/docs/html/search/all_15.js b/docs/html/search/all_15.js index 8142f02..ee54676 100644 --- a/docs/html/search/all_15.js +++ b/docs/html/search/all_15.js @@ -1,22 +1,23 @@ var searchData= [ - ['signal_20definition_0',['Signal definition',['../md_README.html#autotoc_md74',1,'']]], - ['signal_20validation_20and_20parse_20errors_1',['Signal validation and parse errors',['../md_README.html#autotoc_md76',1,'']]], - ['signal_20value_20descriptions_20tt_20val_5f_20tt_2',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md106',1,'']]], + ['signal_20definition_0',['Signal definition',['../md_README.html#autotoc_md78',1,'']]], + ['signal_20validation_20and_20parse_20errors_1',['Signal validation and parse errors',['../md_README.html#autotoc_md80',1,'']]], + ['signal_20value_20descriptions_20tt_20val_5f_20tt_2',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md110',1,'']]], ['signal_5finfo_2eh_3',['signal_info.h',['../signal__info_8h.html',1,'']]], ['signalinfo_4',['SignalInfo',['../structSignalInfo.html',1,'']]], - ['signalinfo_20tt_5',['<tt>SignalInfo</tt>',['../md_README.html#autotoc_md32',1,'']]], - ['stage_201_20already_20implemented_6',['Stage 1 - already implemented',['../md_README.html#autotoc_md111',1,'']]], - ['stage_202_7',['Stage 2',['../md_README.html#autotoc_md112',1,'']]], - ['stage_203_8',['Stage 3',['../md_README.html#autotoc_md113',1,'']]], - ['stage_204_9',['Stage 4',['../md_README.html#autotoc_md114',1,'']]], - ['standalone_20tree_20tests_20without_20qt_10',['Standalone tree tests without Qt',['../md_README.html#autotoc_md119',1,'']]], - ['startbit_11',['startbit',['../structSignalInfo.html#ace290724f9801521609aedaa946d61f1',1,'SignalInfo::startBit'],['../structDecodeSignal.html#aaf5d7527ddf65b6355c2b4f3626df22d',1,'DecodeSignal::startBit']]], - ['statement_20handler_20factory_12',['Statement Handler Factory',['../md_README.html#autotoc_md104',1,'']]], - ['steps_13',['Recommended Next Steps',['../md_README.html#autotoc_md110',1,'']]], - ['strategy_14',['Unified Decode Strategy',['../md_README.html#autotoc_md96',1,'']]], - ['structures_15',['Parsed Data Structures',['../md_README.html#autotoc_md31',1,'']]], - ['support_16',['Parser Support',['../md_README.html#autotoc_md67',1,'']]], - ['supported_20dbc_20syntax_17',['Supported DBC Syntax',['../md_README.html#autotoc_md69',1,'']]], - ['syntax_18',['Supported DBC Syntax',['../md_README.html#autotoc_md69',1,'']]] + ['signalinfo_20tt_5',['<tt>SignalInfo</tt>',['../md_README.html#autotoc_md35',1,'']]], + ['stage_201_20already_20implemented_6',['Stage 1 - already implemented',['../md_README.html#autotoc_md115',1,'']]], + ['stage_202_7',['Stage 2',['../md_README.html#autotoc_md116',1,'']]], + ['stage_203_8',['Stage 3',['../md_README.html#autotoc_md117',1,'']]], + ['stage_204_9',['Stage 4',['../md_README.html#autotoc_md118',1,'']]], + ['standalone_20tree_20tests_20without_20qt_10',['Standalone tree tests without Qt',['../md_README.html#autotoc_md123',1,'']]], + ['startbit_11',['startbit',['../structDecodeSignal.html#aaf5d7527ddf65b6355c2b4f3626df22d',1,'DecodeSignal::startBit'],['../structSignalInfo.html#ace290724f9801521609aedaa946d61f1',1,'SignalInfo::startBit']]], + ['statement_20handler_20factory_12',['Statement Handler Factory',['../md_README.html#autotoc_md108',1,'']]], + ['steps_13',['Recommended Next Steps',['../md_README.html#autotoc_md114',1,'']]], + ['strategy_14',['Unified Decode Strategy',['../md_README.html#autotoc_md100',1,'']]], + ['structured_20diagnostics_15',['Structured diagnostics',['../md_README.html#autotoc_md71',1,'']]], + ['structures_16',['Parsed Data Structures',['../md_README.html#autotoc_md34',1,'']]], + ['support_17',['Parser Support',['../md_README.html#autotoc_md70',1,'']]], + ['supported_20dbc_20syntax_18',['Supported DBC Syntax',['../md_README.html#autotoc_md73',1,'']]], + ['syntax_19',['Supported DBC Syntax',['../md_README.html#autotoc_md73',1,'']]] ]; diff --git a/docs/html/search/all_16.js b/docs/html/search/all_16.js index f8d928a..3bfccda 100644 --- a/docs/html/search/all_16.js +++ b/docs/html/search/all_16.js @@ -1,37 +1,37 @@ var searchData= [ - ['tests_0',['tests',['../md_tests_2README.html',1,'QtTest regression tests'],['../md_README.html#autotoc_md123',1,'Regression tests'],['../md_tests_2README.html#autotoc_md131',1,'Tree and optional model tests']]], - ['tests_20without_20qt_1',['Standalone tree tests without Qt',['../md_README.html#autotoc_md119',1,'']]], - ['the_20demo_2',['Build and run the demo',['../md_README.html#autotoc_md120',1,'']]], - ['the_20gcc_20coverage_20build_20in_20qt_20creator_3',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md126',1,'']]], - ['the_20runtime_20decode_20layer_20exists_4',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], - ['the_20tree_20is_20not_20enough_5',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]], - ['trace_20path_6',['trace path',['../md_README.html#autotoc_md98',1,'']]], + ['tests_0',['tests',['../md_tests_2README.html',1,'QtTest regression tests'],['../md_README.html#autotoc_md127',1,'Regression tests'],['../md_tests_2README.html#autotoc_md135',1,'Tree and optional model tests']]], + ['tests_20without_20qt_1',['Standalone tree tests without Qt',['../md_README.html#autotoc_md123',1,'']]], + ['the_20demo_2',['Build and run the demo',['../md_README.html#autotoc_md124',1,'']]], + ['the_20gcc_20coverage_20build_20in_20qt_20creator_3',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md130',1,'']]], + ['the_20runtime_20decode_20layer_20exists_4',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], + ['the_20tree_20is_20not_20enough_5',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]], + ['trace_20path_6',['trace path',['../md_README.html#autotoc_md102',1,'']]], ['transmitter_7',['transmitter',['../structFrameInfo.html#a92749ec3798d4211a505860fb389a9e8',1,'FrameInfo::transmitter'],['../structDecodeFrame.html#ad78241dc40c793aabb8495b6989b81a9',1,'DecodeFrame::transmitter']]], - ['tree_8',['Build UI tree',['../md_README.html#autotoc_md92',1,'']]], - ['tree_20and_20optional_20model_20tests_9',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md131',1,'']]], - ['tree_20is_20not_20enough_10',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]], - ['tree_20layer_11',['UI Tree Layer',['../md_README.html#autotoc_md38',1,'']]], - ['tree_20tests_20without_20qt_12',['Standalone tree tests without Qt',['../md_README.html#autotoc_md119',1,'']]], + ['tree_8',['Build UI tree',['../md_README.html#autotoc_md96',1,'']]], + ['tree_20and_20optional_20model_20tests_9',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md135',1,'']]], + ['tree_20is_20not_20enough_10',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]], + ['tree_20layer_11',['UI Tree Layer',['../md_README.html#autotoc_md41',1,'']]], + ['tree_20tests_20without_20qt_12',['Standalone tree tests without Qt',['../md_README.html#autotoc_md123',1,'']]], ['tree_5fnode_2ecpp_13',['tree_node.cpp',['../tree__node_8cpp.html',1,'']]], ['tree_5fnode_2eh_14',['tree_node.h',['../tree__node_8h.html',1,'']]], ['treenode_15',['treenode',['../classTreeNode.html#ab9f00f5253d56461bb2d420fd639c5ae',1,'TreeNode::TreeNode()'],['../classTreeNode.html',1,'TreeNode'],['../classTreeNode.html#a984a98d5ccf7ef1f5a18094c6821f35d',1,'TreeNode::TreeNode()'],['../classTreeNode.html#a8e38dd591d8801d7ee3a7dbad90c67fc',1,'TreeNode::TreeNode(const FrameInfo &frame)']]], - ['treenode_20tt_16',['<tt>TreeNode</tt>',['../md_README.html#autotoc_md39',1,'']]], - ['tt_20byteorder_20tt_17',['<tt>ByteOrder</tt>',['../md_README.html#autotoc_md44',1,'']]], - ['tt_20dbcdatabase_20tt_18',['<tt>DbcDatabase</tt>',['../md_README.html#autotoc_md36',1,'']]], - ['tt_20dbcdecoder_20tt_19',['<tt>DbcDecoder</tt>',['../md_README.html#autotoc_md65',1,'']]], - ['tt_20decodedatabase_20tt_20',['<tt>DecodeDatabase</tt>',['../md_README.html#autotoc_md54',1,'']]], - ['tt_20decodedframevalue_20tt_21',['<tt>DecodedFrameValue</tt>',['../md_README.html#autotoc_md63',1,'']]], - ['tt_20decodedsignalvalue_20tt_22',['<tt>DecodedSignalValue</tt>',['../md_README.html#autotoc_md59',1,'']]], - ['tt_20decodeframe_20tt_23',['<tt>DecodeFrame</tt>',['../md_README.html#autotoc_md50',1,'']]], - ['tt_20decodesignal_20tt_24',['<tt>DecodeSignal</tt>',['../md_README.html#autotoc_md48',1,'']]], - ['tt_20frameinfo_20tt_25',['<tt>FrameInfo</tt>',['../md_README.html#autotoc_md34',1,'']]], - ['tt_20framekey_20tt_26',['<tt>FrameKey</tt>',['../md_README.html#autotoc_md52',1,'']]], - ['tt_20rawcanframe_20tt_27',['<tt>RawCanFrame</tt>',['../md_README.html#autotoc_md57',1,'']]], - ['tt_20signalinfo_20tt_28',['<tt>SignalInfo</tt>',['../md_README.html#autotoc_md32',1,'']]], - ['tt_20treenode_20tt_29',['<tt>TreeNode</tt>',['../md_README.html#autotoc_md39',1,'']]], - ['tt_20val_5f_20tt_30',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md106',1,'']]], - ['tt_20valuetype_20tt_31',['<tt>ValueType</tt>',['../md_README.html#autotoc_md46',1,'']]], + ['treenode_20tt_16',['<tt>TreeNode</tt>',['../md_README.html#autotoc_md42',1,'']]], + ['tt_20byteorder_20tt_17',['<tt>ByteOrder</tt>',['../md_README.html#autotoc_md47',1,'']]], + ['tt_20dbcdatabase_20tt_18',['<tt>DbcDatabase</tt>',['../md_README.html#autotoc_md39',1,'']]], + ['tt_20dbcdecoder_20tt_19',['<tt>DbcDecoder</tt>',['../md_README.html#autotoc_md68',1,'']]], + ['tt_20decodedatabase_20tt_20',['<tt>DecodeDatabase</tt>',['../md_README.html#autotoc_md57',1,'']]], + ['tt_20decodedframevalue_20tt_21',['<tt>DecodedFrameValue</tt>',['../md_README.html#autotoc_md66',1,'']]], + ['tt_20decodedsignalvalue_20tt_22',['<tt>DecodedSignalValue</tt>',['../md_README.html#autotoc_md62',1,'']]], + ['tt_20decodeframe_20tt_23',['<tt>DecodeFrame</tt>',['../md_README.html#autotoc_md53',1,'']]], + ['tt_20decodesignal_20tt_24',['<tt>DecodeSignal</tt>',['../md_README.html#autotoc_md51',1,'']]], + ['tt_20frameinfo_20tt_25',['<tt>FrameInfo</tt>',['../md_README.html#autotoc_md37',1,'']]], + ['tt_20framekey_20tt_26',['<tt>FrameKey</tt>',['../md_README.html#autotoc_md55',1,'']]], + ['tt_20rawcanframe_20tt_27',['<tt>RawCanFrame</tt>',['../md_README.html#autotoc_md60',1,'']]], + ['tt_20signalinfo_20tt_28',['<tt>SignalInfo</tt>',['../md_README.html#autotoc_md35',1,'']]], + ['tt_20treenode_20tt_29',['<tt>TreeNode</tt>',['../md_README.html#autotoc_md42',1,'']]], + ['tt_20val_5f_20tt_30',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md110',1,'']]], + ['tt_20valuetype_20tt_31',['<tt>ValueType</tt>',['../md_README.html#autotoc_md49',1,'']]], ['typefactory_32',['TypeFactory',['../classTypeFactory.html',1,'']]], ['typefactory_3c_20std_3a_3astring_2c_20dbcstatementhandler_20_3e_33',['TypeFactory< std::string, DbcStatementHandler >',['../classTypeFactory.html',1,'']]] ]; diff --git a/docs/html/search/all_17.js b/docs/html/search/all_17.js index 27f635c..2581eed 100644 --- a/docs/html/search/all_17.js +++ b/docs/html/search/all_17.js @@ -1,12 +1,12 @@ var searchData= [ - ['ubuntu_0',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['ui_20path_1',['1. Parse and UI path',['../md_README.html#autotoc_md24',1,'']]], - ['ui_20tree_2',['Build UI tree',['../md_README.html#autotoc_md92',1,'']]], - ['ui_20tree_20layer_3',['UI Tree Layer',['../md_README.html#autotoc_md38',1,'']]], - ['unified_20decode_20strategy_4',['Unified Decode Strategy',['../md_README.html#autotoc_md96',1,'']]], + ['ubuntu_0',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['ui_20path_1',['1. Parse and UI path',['../md_README.html#autotoc_md27',1,'']]], + ['ui_20tree_2',['Build UI tree',['../md_README.html#autotoc_md96',1,'']]], + ['ui_20tree_20layer_3',['UI Tree Layer',['../md_README.html#autotoc_md41',1,'']]], + ['unified_20decode_20strategy_4',['Unified Decode Strategy',['../md_README.html#autotoc_md100',1,'']]], ['unit_5',['unit',['../structDecodeSignal.html#a38eed9ca7581423fd8bfbedcffc12092',1,'DecodeSignal::unit'],['../structSignalInfo.html#a1f214f03e94ef5794de2d3367bfcbd01',1,'SignalInfo::unit']]], ['unreleased_6',['Unreleased',['../md_changelog.html#autotoc_md1',1,'']]], - ['usage_7',['Example Usage',['../md_README.html#autotoc_md90',1,'']]], - ['use_20in_20frametap_8',['Intended Use in FrameTap',['../md_README.html#autotoc_md100',1,'']]] + ['usage_7',['Example Usage',['../md_README.html#autotoc_md94',1,'']]], + ['use_20in_20frametap_8',['Intended Use in FrameTap',['../md_README.html#autotoc_md104',1,'']]] ]; diff --git a/docs/html/search/all_18.js b/docs/html/search/all_18.js index dae948f..7f92ea5 100644 --- a/docs/html/search/all_18.js +++ b/docs/html/search/all_18.js @@ -1,13 +1,13 @@ var searchData= [ - ['v1_200_20—_202026_2006_2014_0',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]], - ['val_5f_20tt_1',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md106',1,'']]], + ['v1_200_20—_202026_2006_2014_0',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]], + ['val_5f_20tt_1',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md110',1,'']]], ['valid_2',['valid',['../structDecodedSignalValue.html#aac0ed361af545cde48d0e6f41a859686',1,'DecodedSignalValue::valid'],['../structDecodedFrameValue.html#a4f51c31110dba1f73a763c596372beb0',1,'DecodedFrameValue::valid']]], - ['validation_20and_20parse_20errors_3',['validation and parse errors',['../md_README.html#autotoc_md72',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md76',1,'Signal validation and parse errors']]], - ['value_20descriptions_20tt_20val_5f_20tt_4',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md106',1,'']]], - ['value_20representation_20and_20precision_5',['Raw value representation and precision',['../md_README.html#autotoc_md61',1,'']]], + ['validation_20and_20parse_20errors_3',['validation and parse errors',['../md_README.html#autotoc_md76',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md80',1,'Signal validation and parse errors']]], + ['value_20descriptions_20tt_20val_5f_20tt_4',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md110',1,'']]], + ['value_20representation_20and_20precision_5',['Raw value representation and precision',['../md_README.html#autotoc_md64',1,'']]], ['valuedescriptions_6',['valuedescriptions',['../structDecodeSignal.html#a822155d9bf4ed5f3300c9e9befe606ff',1,'DecodeSignal::valueDescriptions'],['../structSignalInfo.html#a43f47d0433d0cc39076bd7278b46af9c',1,'SignalInfo::valueDescriptions']]], ['valuetype_7',['valuetype',['../structDecodeSignal.html#a9d37638129263b8902ba5be59baf39a8',1,'DecodeSignal::valueType'],['../decode__database_8h.html#ad9971b6ef33e02ba2c75d19c1d2518a1',1,'ValueType: decode_database.h']]], - ['valuetype_20tt_8',['<tt>ValueType</tt>',['../md_README.html#autotoc_md46',1,'']]], - ['variants_20in_20qt_20creator_9',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md127',1,'']]] + ['valuetype_20tt_8',['<tt>ValueType</tt>',['../md_README.html#autotoc_md49',1,'']]], + ['variants_20in_20qt_20creator_9',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md131',1,'']]] ]; diff --git a/docs/html/search/all_19.js b/docs/html/search/all_19.js index 79d959e..2c45351 100644 --- a/docs/html/search/all_19.js +++ b/docs/html/search/all_19.js @@ -1,7 +1,7 @@ var searchData= [ - ['why_20the_20runtime_20decode_20layer_20exists_0',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], - ['why_20the_20tree_20is_20not_20enough_1',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]], - ['without_20qt_2',['Standalone tree tests without Qt',['../md_README.html#autotoc_md119',1,'']]], - ['without_20qt_20libraries_3',['Build core without Qt libraries',['../md_README.html#autotoc_md117',1,'']]] + ['why_20the_20runtime_20decode_20layer_20exists_0',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], + ['why_20the_20tree_20is_20not_20enough_1',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]], + ['without_20qt_2',['Standalone tree tests without Qt',['../md_README.html#autotoc_md123',1,'']]], + ['without_20qt_20libraries_3',['Build core without Qt libraries',['../md_README.html#autotoc_md121',1,'']]] ]; diff --git a/docs/html/search/all_1a.js b/docs/html/search/all_1a.js index 46abc98..f1c1625 100644 --- a/docs/html/search/all_1a.js +++ b/docs/html/search/all_1a.js @@ -1,5 +1,5 @@ var searchData= [ - ['—_202026_2003_2013_0',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['—_202026_2006_2014_1',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]] + ['—_202026_2003_2013_0',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['—_202026_2006_2014_1',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]] ]; diff --git a/docs/html/search/all_2.js b/docs/html/search/all_2.js index e74d65d..63282d0 100644 --- a/docs/html/search/all_2.js +++ b/docs/html/search/all_2.js @@ -1,11 +1,12 @@ var searchData= [ - ['2_0',['Stage 2',['../md_README.html#autotoc_md112',1,'']]], - ['2_20runtime_20decode_20path_1',['2. Runtime decode path',['../md_README.html#autotoc_md25',1,'']]], - ['2026_2003_2013_2',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['2026_2006_2014_3',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md15',1,'']]], - ['2026_2010_2001_4',['2026-10-01',['../md_changelog.html#autotoc_md12',1,'']]], - ['2026_2010_2005_5',['2026-10-05',['../md_changelog.html#autotoc_md8',1,'']]], - ['2026_2010_2006_6',['2026-10-06',['../md_changelog.html#autotoc_md6',1,'']]], - ['2026_2010_2007_7',['2026-10-07',['../md_changelog.html#autotoc_md2',1,'']]] + ['2_0',['Stage 2',['../md_README.html#autotoc_md116',1,'']]], + ['2_20runtime_20decode_20path_1',['2. Runtime decode path',['../md_README.html#autotoc_md28',1,'']]], + ['2026_2003_2013_2',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['2026_2006_2014_3',['v1.0 — 2026-06-14',['../md_changelog.html#autotoc_md18',1,'']]], + ['2026_2010_2001_4',['2026-10-01',['../md_changelog.html#autotoc_md15',1,'']]], + ['2026_2010_2005_5',['2026-10-05',['../md_changelog.html#autotoc_md11',1,'']]], + ['2026_2010_2006_6',['2026-10-06',['../md_changelog.html#autotoc_md9',1,'']]], + ['2026_2010_2007_7',['2026-10-07',['../md_changelog.html#autotoc_md5',1,'']]], + ['2026_2010_2011_8',['2026-10-11',['../md_changelog.html#autotoc_md2',1,'']]] ]; diff --git a/docs/html/search/all_3.js b/docs/html/search/all_3.js index 6b2dc85..f80e8ca 100644 --- a/docs/html/search/all_3.js +++ b/docs/html/search/all_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['3_0',['Stage 3',['../md_README.html#autotoc_md113',1,'']]] + ['3_0',['Stage 3',['../md_README.html#autotoc_md117',1,'']]] ]; diff --git a/docs/html/search/all_4.js b/docs/html/search/all_4.js index e823a76..20df124 100644 --- a/docs/html/search/all_4.js +++ b/docs/html/search/all_4.js @@ -1,4 +1,4 @@ var searchData= [ - ['4_0',['Stage 4',['../md_README.html#autotoc_md114',1,'']]] + ['4_0',['Stage 4',['../md_README.html#autotoc_md118',1,'']]] ]; diff --git a/docs/html/search/all_5.js b/docs/html/search/all_5.js index 2242a54..816a080 100644 --- a/docs/html/search/all_5.js +++ b/docs/html/search/all_5.js @@ -1,21 +1,21 @@ var searchData= [ - ['a_20raw_20frame_0',['Decode a raw frame',['../md_README.html#autotoc_md94',1,'']]], - ['adapter_1',['Optional Qt model adapter',['../md_README.html#autotoc_md118',1,'']]], + ['a_20raw_20frame_0',['Decode a raw frame',['../md_README.html#autotoc_md98',1,'']]], + ['adapter_1',['Optional Qt model adapter',['../md_README.html#autotoc_md122',1,'']]], ['addchild_2',['AddChild',['../classTreeNode.html#a6161f2ebb92184eab4215d121870e788',1,'TreeNode']]], - ['added_3',['added',['../md_changelog.html#autotoc_md3',1,'Added'],['../md_changelog.html#autotoc_md7',1,'Added'],['../md_changelog.html#autotoc_md18',1,'Added']]], - ['additional_20regression_20coverage_4',['Additional regression coverage',['../md_tests_2README.html#autotoc_md132',1,'']]], - ['all_20build_20variants_20in_20qt_20creator_5',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md127',1,'']]], - ['already_20implemented_6',['Stage 1 - already implemented',['../md_README.html#autotoc_md111',1,'']]], - ['and_20lcov_20on_20debian_20ubuntu_7',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['and_20maintenance_8',['and maintenance',['../md_changelog.html#autotoc_md11',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md19',1,'Documentation and maintenance']]], - ['and_20motorola_20extraction_9',['Intel and Motorola Extraction',['../md_README.html#autotoc_md88',1,'']]], - ['and_20optional_20model_20tests_10',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md131',1,'']]], - ['and_20parse_20errors_11',['and parse errors',['../md_README.html#autotoc_md72',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md76',1,'Signal validation and parse errors']]], - ['and_20precision_12',['Raw value representation and precision',['../md_README.html#autotoc_md61',1,'']]], - ['and_20run_20the_20demo_13',['Build and run the demo',['../md_README.html#autotoc_md120',1,'']]], + ['added_3',['added',['../md_changelog.html#autotoc_md3',1,'Added'],['../md_changelog.html#autotoc_md6',1,'Added'],['../md_changelog.html#autotoc_md10',1,'Added'],['../md_changelog.html#autotoc_md21',1,'Added']]], + ['additional_20regression_20coverage_4',['Additional regression coverage',['../md_tests_2README.html#autotoc_md136',1,'']]], + ['all_20build_20variants_20in_20qt_20creator_5',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md131',1,'']]], + ['already_20implemented_6',['Stage 1 - already implemented',['../md_README.html#autotoc_md115',1,'']]], + ['and_20lcov_20on_20debian_20ubuntu_7',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['and_20maintenance_8',['and maintenance',['../md_changelog.html#autotoc_md14',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md22',1,'Documentation and maintenance']]], + ['and_20motorola_20extraction_9',['Intel and Motorola Extraction',['../md_README.html#autotoc_md92',1,'']]], + ['and_20optional_20model_20tests_10',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md135',1,'']]], + ['and_20parse_20errors_11',['and parse errors',['../md_README.html#autotoc_md76',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md80',1,'Signal validation and parse errors']]], + ['and_20precision_12',['Raw value representation and precision',['../md_README.html#autotoc_md64',1,'']]], + ['and_20run_20the_20demo_13',['Build and run the demo',['../md_README.html#autotoc_md124',1,'']]], ['and_20runtime_20decode_20module_20documentation_14',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['and_20ui_20path_15',['1. Parse and UI path',['../md_README.html#autotoc_md24',1,'']]], - ['api_20documentation_16',['Generate API documentation',['../md_README.html#autotoc_md121',1,'']]], - ['architecture_17',['High-Level Architecture',['../md_README.html#autotoc_md23',1,'']]] + ['and_20ui_20path_15',['1. Parse and UI path',['../md_README.html#autotoc_md27',1,'']]], + ['api_20documentation_16',['Generate API documentation',['../md_README.html#autotoc_md125',1,'']]], + ['architecture_17',['High-Level Architecture',['../md_README.html#autotoc_md26',1,'']]] ]; diff --git a/docs/html/search/all_6.js b/docs/html/search/all_6.js index 147aa2a..3319821 100644 --- a/docs/html/search/all_6.js +++ b/docs/html/search/all_6.js @@ -1,14 +1,14 @@ var searchData= [ - ['basic_20multiplexing_0',['Basic multiplexing',['../md_README.html#autotoc_md78',1,'']]], + ['basic_20multiplexing_0',['Basic multiplexing',['../md_README.html#autotoc_md82',1,'']]], ['build_1',['build',['../classDbcDecodeBuilder.html#a2bc6386dfb5e58976c42e22c19ec471b',1,'DbcDecodeBuilder::Build()'],['../classDbcTreeBuilder.html#a7e57d067d831b14b383947fd125edd4b',1,'DbcTreeBuilder::Build()']]], - ['build_20and_20run_20the_20demo_2',['Build and run the demo',['../md_README.html#autotoc_md120',1,'']]], - ['build_20core_20without_20qt_20libraries_3',['Build core without Qt libraries',['../md_README.html#autotoc_md117',1,'']]], - ['build_20in_20qt_20creator_4',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md126',1,'']]], - ['build_20integration_5',['Build Integration',['../md_README.html#autotoc_md116',1,'']]], - ['build_20runtime_20decode_20database_6',['Build runtime decode database',['../md_README.html#autotoc_md93',1,'']]], - ['build_20ui_20tree_7',['Build UI tree',['../md_README.html#autotoc_md92',1,'']]], - ['build_20variants_20in_20qt_20creator_8',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md127',1,'']]], + ['build_20and_20run_20the_20demo_2',['Build and run the demo',['../md_README.html#autotoc_md124',1,'']]], + ['build_20core_20without_20qt_20libraries_3',['Build core without Qt libraries',['../md_README.html#autotoc_md121',1,'']]], + ['build_20in_20qt_20creator_4',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md130',1,'']]], + ['build_20integration_5',['Build Integration',['../md_README.html#autotoc_md120',1,'']]], + ['build_20runtime_20decode_20database_6',['Build runtime decode database',['../md_README.html#autotoc_md97',1,'']]], + ['build_20ui_20tree_7',['Build UI tree',['../md_README.html#autotoc_md96',1,'']]], + ['build_20variants_20in_20qt_20creator_8',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md131',1,'']]], ['byteorder_9',['byteorder',['../structDecodeSignal.html#abdc4c4bb4a67a6d61d6ca81e8a52833d',1,'DecodeSignal::byteOrder'],['../decode__database_8h.html#aaeb92d42f5a6e27b8ba19f18d69d142b',1,'ByteOrder: decode_database.h']]], - ['byteorder_20tt_10',['<tt>ByteOrder</tt>',['../md_README.html#autotoc_md44',1,'']]] + ['byteorder_20tt_10',['<tt>ByteOrder</tt>',['../md_README.html#autotoc_md47',1,'']]] ]; diff --git a/docs/html/search/all_7.js b/docs/html/search/all_7.js index 9c430c9..00e4a67 100644 --- a/docs/html/search/all_7.js +++ b/docs/html/search/all_7.js @@ -1,19 +1,19 @@ var searchData= [ - ['can_20id_20normalization_0',['CAN ID Normalization',['../md_README.html#autotoc_md82',1,'']]], + ['can_20id_20normalization_0',['CAN ID Normalization',['../md_README.html#autotoc_md86',1,'']]], ['canid_1',['canid',['../structDecodeFrame.html#a52e10215388db7df8b541b9d9909edcf',1,'DecodeFrame::canId'],['../structFrameInfo.html#af470b0742c05bfbffc31c51a68f5c05e',1,'FrameInfo::canId'],['../structRawCanFrame.html#a2d0e7fa0e3d5c20bbed55ed8f7888ff4',1,'RawCanFrame::canId']]], - ['changed_2',['changed',['../md_changelog.html#autotoc_md4',1,'Changed'],['../md_changelog.html#autotoc_md9',1,'Changed'],['../md_changelog.html#autotoc_md13',1,'Changed']]], + ['changed_2',['changed',['../md_changelog.html#autotoc_md16',1,'Changed'],['../md_changelog.html#autotoc_md12',1,'Changed'],['../md_changelog.html#autotoc_md7',1,'Changed'],['../md_changelog.html#autotoc_md4',1,'Changed']]], ['changelog_3',['Changelog',['../md_changelog.html',1,'']]], - ['code_20coverage_4',['Measuring code coverage',['../md_README.html#autotoc_md124',1,'']]], - ['comment_5',['comment',['../structDecodeSignal.html#ae28c905d4a2bc86419c2a8361bfea473',1,'DecodeSignal::comment'],['../structDecodeFrame.html#a25819ef907a32391af5c9f7cae9cdb22',1,'DecodeFrame::comment'],['../structFrameInfo.html#ace75121294f9d89b762080ab5643293c',1,'FrameInfo::comment'],['../structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5',1,'SignalInfo::comment']]], - ['comments_6',['Comments',['../md_README.html#autotoc_md80',1,'']]], - ['configure_20all_20build_20variants_20in_20qt_20creator_7',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md127',1,'']]], - ['configure_20the_20gcc_20coverage_20build_20in_20qt_20creator_8',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md126',1,'']]], + ['code_20coverage_4',['Measuring code coverage',['../md_README.html#autotoc_md128',1,'']]], + ['comment_5',['comment',['../structSignalInfo.html#ac99ba7563a5dad01e39c4257216953f5',1,'SignalInfo::comment'],['../structFrameInfo.html#ace75121294f9d89b762080ab5643293c',1,'FrameInfo::comment'],['../structDecodeFrame.html#a25819ef907a32391af5c9f7cae9cdb22',1,'DecodeFrame::comment'],['../structDecodeSignal.html#ae28c905d4a2bc86419c2a8361bfea473',1,'DecodeSignal::comment']]], + ['comments_6',['Comments',['../md_README.html#autotoc_md84',1,'']]], + ['configure_20all_20build_20variants_20in_20qt_20creator_7',['Configure all build variants in Qt Creator',['../md_README.html#autotoc_md131',1,'']]], + ['configure_20the_20gcc_20coverage_20build_20in_20qt_20creator_8',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md130',1,'']]], ['contains_9',['contains',['../classTypeFactory.html#a1a119ad2956abe146213c6ca124d8dd4',1,'TypeFactory']]], - ['core_20without_20qt_20libraries_10',['Build core without Qt libraries',['../md_README.html#autotoc_md117',1,'']]], - ['coverage_11',['coverage',['../md_tests_2README.html#autotoc_md132',1,'Additional regression coverage'],['../md_tests_2README.html#autotoc_md129',1,'Decoder coverage'],['../md_README.html#autotoc_md124',1,'Measuring code coverage'],['../md_tests_2README.html#autotoc_md130',1,'Parser coverage']]], - ['coverage_20build_20in_20qt_20creator_12',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md126',1,'']]], + ['core_20without_20qt_20libraries_10',['Build core without Qt libraries',['../md_README.html#autotoc_md121',1,'']]], + ['coverage_11',['coverage',['../md_tests_2README.html#autotoc_md136',1,'Additional regression coverage'],['../md_tests_2README.html#autotoc_md133',1,'Decoder coverage'],['../md_README.html#autotoc_md128',1,'Measuring code coverage'],['../md_tests_2README.html#autotoc_md134',1,'Parser coverage']]], + ['coverage_20build_20in_20qt_20creator_12',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md130',1,'']]], ['create_13',['create',['../classTypeFactory.html#a3f43b03d6e3a0fd503fdec01ecf62e9f',1,'TypeFactory']]], - ['creator_14',['creator',['../md_README.html#autotoc_md127',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md126',1,'Configure the GCC coverage build in Qt Creator'],['../classTypeFactory.html#ad82f537569ece3d3a4a376523fa94473',1,'TypeFactory::creator()']]], - ['current_20limitations_15',['Current Limitations',['../md_README.html#autotoc_md108',1,'']]] + ['creator_14',['creator',['../md_README.html#autotoc_md131',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md130',1,'Configure the GCC coverage build in Qt Creator'],['../classTypeFactory.html#ad82f537569ece3d3a4a376523fa94473',1,'TypeFactory::creator()']]], + ['current_20limitations_15',['Current Limitations',['../md_README.html#autotoc_md112',1,'']]] ]; diff --git a/docs/html/search/all_8.js b/docs/html/search/all_8.js index ef40159..c65644a 100644 --- a/docs/html/search/all_8.js +++ b/docs/html/search/all_8.js @@ -1,11 +1,11 @@ var searchData= [ ['data_0',['data',['../structRawCanFrame.html#a0acb487612104c99c9907344c035df83',1,'RawCanFrame']]], - ['data_20structures_1',['Parsed Data Structures',['../md_README.html#autotoc_md31',1,'']]], - ['database_2',['Build runtime decode database',['../md_README.html#autotoc_md93',1,'']]], - ['dbc_3',['Parse DBC',['../md_README.html#autotoc_md91',1,'']]], + ['data_20structures_1',['Parsed Data Structures',['../md_README.html#autotoc_md34',1,'']]], + ['database_2',['Build runtime decode database',['../md_README.html#autotoc_md97',1,'']]], + ['dbc_3',['Parse DBC',['../md_README.html#autotoc_md95',1,'']]], ['dbc_20parser_20and_20runtime_20decode_20module_20documentation_4',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['dbc_20syntax_5',['Supported DBC Syntax',['../md_README.html#autotoc_md69',1,'']]], + ['dbc_20syntax_5',['Supported DBC Syntax',['../md_README.html#autotoc_md73',1,'']]], ['dbc_5fdatabase_2eh_6',['dbc_database.h',['../dbc__database_8h.html',1,'']]], ['dbc_5fdecode_5fbuilder_2ecpp_7',['dbc_decode_builder.cpp',['../dbc__decode__builder_8cpp.html',1,'']]], ['dbc_5fdecode_5fbuilder_2eh_8',['dbc_decode_builder.h',['../dbc__decode__builder_8h.html',1,'']]], @@ -17,48 +17,53 @@ var searchData= ['dbc_5ftree_5fbuilder_2eh_14',['dbc_tree_builder.h',['../dbc__tree__builder_8h.html',1,'']]], ['dbccommenthandler_15',['DbcCommentHandler',['../classDbcCommentHandler.html',1,'']]], ['dbcdatabase_16',['DbcDatabase',['../structDbcDatabase.html',1,'']]], - ['dbcdatabase_20tt_17',['<tt>DbcDatabase</tt>',['../md_README.html#autotoc_md36',1,'']]], + ['dbcdatabase_20tt_17',['<tt>DbcDatabase</tt>',['../md_README.html#autotoc_md39',1,'']]], ['dbcdecodebuilder_18',['DbcDecodeBuilder',['../classDbcDecodeBuilder.html',1,'']]], ['dbcdecoder_19',['DbcDecoder',['../classDbcDecoder.html',1,'']]], - ['dbcdecoder_20tt_20',['<tt>DbcDecoder</tt>',['../md_README.html#autotoc_md65',1,'']]], - ['dbcframehandler_21',['DbcFrameHandler',['../classDbcFrameHandler.html',1,'']]], - ['dbcparsecontext_22',['DbcParseContext',['../structDbcParseContext.html',1,'']]], - ['dbcparser_23',['DbcParser',['../classDbcParser.html',1,'']]], - ['dbcsignalhandler_24',['DbcSignalHandler',['../classDbcSignalHandler.html',1,'']]], - ['dbcstatementdispatcher_25',['DbcStatementDispatcher',['../classDbcStatementDispatcher.html',1,'']]], - ['dbcstatementhandler_26',['DbcStatementHandler',['../classDbcStatementHandler.html',1,'']]], - ['dbctreebuilder_27',['DbcTreeBuilder',['../classDbcTreeBuilder.html',1,'']]], - ['dbctreemodel_28',['DbcTreeModel',['../classDbcTreeModel.html',1,'']]], - ['dbcunsupportedmultiplexinghandler_29',['DbcUnsupportedMultiplexingHandler',['../classDbcUnsupportedMultiplexingHandler.html',1,'']]], - ['dbcvaluedescriptionhandler_30',['DbcValueDescriptionHandler',['../classDbcValueDescriptionHandler.html',1,'']]], - ['debian_20ubuntu_31',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['decode_32',['Decode',['../classDbcDecoder.html#a345951ffe5d943a70d3a1ea1f39e74f7',1,'DbcDecoder']]], - ['decode_20a_20raw_20frame_33',['Decode a raw frame',['../md_README.html#autotoc_md94',1,'']]], - ['decode_20database_34',['Build runtime decode database',['../md_README.html#autotoc_md93',1,'']]], - ['decode_20flow_35',['Decode Flow',['../md_README.html#autotoc_md86',1,'']]], - ['decode_20layer_36',['Runtime Decode Layer',['../md_README.html#autotoc_md41',1,'']]], - ['decode_20layer_20exists_37',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], - ['decode_20module_20documentation_38',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['decode_20path_39',['2. Runtime decode path',['../md_README.html#autotoc_md25',1,'']]], - ['decode_20strategy_40',['Unified Decode Strategy',['../md_README.html#autotoc_md96',1,'']]], - ['decode_5fdatabase_2eh_41',['decode_database.h',['../decode__database_8h.html',1,'']]], - ['decodedatabase_42',['DecodeDatabase',['../structDecodeDatabase.html',1,'']]], - ['decodedatabase_20tt_43',['<tt>DecodeDatabase</tt>',['../md_README.html#autotoc_md54',1,'']]], - ['decodedframevalue_44',['DecodedFrameValue',['../structDecodedFrameValue.html',1,'']]], - ['decodedframevalue_20tt_45',['<tt>DecodedFrameValue</tt>',['../md_README.html#autotoc_md63',1,'']]], - ['decodedsignalvalue_46',['DecodedSignalValue',['../structDecodedSignalValue.html',1,'']]], - ['decodedsignalvalue_20tt_47',['<tt>DecodedSignalValue</tt>',['../md_README.html#autotoc_md59',1,'']]], - ['decodeframe_48',['DecodeFrame',['../structDecodeFrame.html',1,'']]], - ['decodeframe_20tt_49',['<tt>DecodeFrame</tt>',['../md_README.html#autotoc_md50',1,'']]], - ['decoder_20coverage_50',['Decoder coverage',['../md_tests_2README.html#autotoc_md129',1,'']]], - ['decoder_20layer_51',['Decoder Layer',['../md_README.html#autotoc_md56',1,'']]], - ['decodesignal_52',['DecodeSignal',['../structDecodeSignal.html',1,'']]], - ['decodesignal_20tt_53',['<tt>DecodeSignal</tt>',['../md_README.html#autotoc_md48',1,'']]], - ['definition_54',['definition',['../structDecodedFrameValue.html#a60dda1cc352d2c8087f0bdbc81dd266c',1,'DecodedFrameValue::definition'],['../structDecodedSignalValue.html#acadc3b3bb21dd6b0412d342c7e6b20d7',1,'DecodedSignalValue::definition'],['../md_README.html#autotoc_md70',1,'Frame definition'],['../md_README.html#autotoc_md74',1,'Signal definition']]], - ['demo_55',['Build and run the demo',['../md_README.html#autotoc_md120',1,'']]], - ['descriptions_20tt_20val_5f_20tt_56',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md106',1,'']]], - ['dispatch_57',['Dispatch',['../classDbcStatementDispatcher.html#a495c2d5c7ebb8103b1987cdd87c142ed',1,'DbcStatementDispatcher']]], - ['dlc_58',['dlc',['../structFrameInfo.html#aa2b198ea0f55e560c123d35e7b3ecab9',1,'FrameInfo::dlc'],['../structDecodeFrame.html#a51111ac13988be372d5673d12cf3e060',1,'DecodeFrame::dlc']]], - ['documentation_59',['documentation',['../md_README.html',1,'DBC Parser and Runtime Decode Module Documentation'],['../md_changelog.html#autotoc_md16',1,'Documentation'],['../md_README.html#autotoc_md121',1,'Generate API documentation']]], - ['documentation_20and_20maintenance_60',['documentation and maintenance',['../md_changelog.html#autotoc_md11',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md19',1,'Documentation and maintenance']]] + ['dbcdecoder_20tt_20',['<tt>DbcDecoder</tt>',['../md_README.html#autotoc_md68',1,'']]], + ['dbcdiagnostic_21',['DbcDiagnostic',['../structDbcDiagnostic.html',1,'']]], + ['dbcdiagnosticerror_22',['DbcDiagnosticError',['../classDbcDiagnosticError.html',1,'']]], + ['dbcframehandler_23',['DbcFrameHandler',['../classDbcFrameHandler.html',1,'']]], + ['dbcheaderhandler_24',['DbcHeaderHandler',['../classDbcHeaderHandler.html',1,'']]], + ['dbcparsecontext_25',['DbcParseContext',['../structDbcParseContext.html',1,'']]], + ['dbcparser_26',['DbcParser',['../classDbcParser.html',1,'']]], + ['dbcparseresult_27',['DbcParseResult',['../structDbcParseResult.html',1,'']]], + ['dbcsignalhandler_28',['DbcSignalHandler',['../classDbcSignalHandler.html',1,'']]], + ['dbcstatementdispatcher_29',['DbcStatementDispatcher',['../classDbcStatementDispatcher.html',1,'']]], + ['dbcstatementhandler_30',['DbcStatementHandler',['../classDbcStatementHandler.html',1,'']]], + ['dbctreebuilder_31',['DbcTreeBuilder',['../classDbcTreeBuilder.html',1,'']]], + ['dbctreemodel_32',['DbcTreeModel',['../classDbcTreeModel.html',1,'']]], + ['dbcunsupportedmultiplexinghandler_33',['DbcUnsupportedMultiplexingHandler',['../classDbcUnsupportedMultiplexingHandler.html',1,'']]], + ['dbcvaluedescriptionhandler_34',['DbcValueDescriptionHandler',['../classDbcValueDescriptionHandler.html',1,'']]], + ['debian_20ubuntu_35',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['decode_36',['Decode',['../classDbcDecoder.html#a345951ffe5d943a70d3a1ea1f39e74f7',1,'DbcDecoder']]], + ['decode_20a_20raw_20frame_37',['Decode a raw frame',['../md_README.html#autotoc_md98',1,'']]], + ['decode_20database_38',['Build runtime decode database',['../md_README.html#autotoc_md97',1,'']]], + ['decode_20flow_39',['Decode Flow',['../md_README.html#autotoc_md90',1,'']]], + ['decode_20layer_40',['Runtime Decode Layer',['../md_README.html#autotoc_md44',1,'']]], + ['decode_20layer_20exists_41',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], + ['decode_20module_20documentation_42',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], + ['decode_20path_43',['2. Runtime decode path',['../md_README.html#autotoc_md28',1,'']]], + ['decode_20strategy_44',['Unified Decode Strategy',['../md_README.html#autotoc_md100',1,'']]], + ['decode_5fdatabase_2eh_45',['decode_database.h',['../decode__database_8h.html',1,'']]], + ['decodedatabase_46',['DecodeDatabase',['../structDecodeDatabase.html',1,'']]], + ['decodedatabase_20tt_47',['<tt>DecodeDatabase</tt>',['../md_README.html#autotoc_md57',1,'']]], + ['decodedframevalue_48',['DecodedFrameValue',['../structDecodedFrameValue.html',1,'']]], + ['decodedframevalue_20tt_49',['<tt>DecodedFrameValue</tt>',['../md_README.html#autotoc_md66',1,'']]], + ['decodedsignalvalue_50',['DecodedSignalValue',['../structDecodedSignalValue.html',1,'']]], + ['decodedsignalvalue_20tt_51',['<tt>DecodedSignalValue</tt>',['../md_README.html#autotoc_md62',1,'']]], + ['decodeframe_52',['DecodeFrame',['../structDecodeFrame.html',1,'']]], + ['decodeframe_20tt_53',['<tt>DecodeFrame</tt>',['../md_README.html#autotoc_md53',1,'']]], + ['decoder_20coverage_54',['Decoder coverage',['../md_tests_2README.html#autotoc_md133',1,'']]], + ['decoder_20layer_55',['Decoder Layer',['../md_README.html#autotoc_md59',1,'']]], + ['decodesignal_56',['DecodeSignal',['../structDecodeSignal.html',1,'']]], + ['decodesignal_20tt_57',['<tt>DecodeSignal</tt>',['../md_README.html#autotoc_md51',1,'']]], + ['definition_58',['definition',['../structDecodedFrameValue.html#a60dda1cc352d2c8087f0bdbc81dd266c',1,'DecodedFrameValue::definition'],['../structDecodedSignalValue.html#acadc3b3bb21dd6b0412d342c7e6b20d7',1,'DecodedSignalValue::definition'],['../md_README.html#autotoc_md74',1,'Frame definition'],['../md_README.html#autotoc_md78',1,'Signal definition']]], + ['demo_59',['Build and run the demo',['../md_README.html#autotoc_md124',1,'']]], + ['descriptions_20tt_20val_5f_20tt_60',['Signal value descriptions (<tt>VAL_</tt>)',['../md_README.html#autotoc_md110',1,'']]], + ['diagnostics_61',['Structured diagnostics',['../md_README.html#autotoc_md71',1,'']]], + ['dispatch_62',['Dispatch',['../classDbcStatementDispatcher.html#a495c2d5c7ebb8103b1987cdd87c142ed',1,'DbcStatementDispatcher']]], + ['dlc_63',['dlc',['../structFrameInfo.html#aa2b198ea0f55e560c123d35e7b3ecab9',1,'FrameInfo::dlc'],['../structDecodeFrame.html#a51111ac13988be372d5673d12cf3e060',1,'DecodeFrame::dlc']]], + ['documentation_64',['documentation',['../md_README.html',1,'DBC Parser and Runtime Decode Module Documentation'],['../md_changelog.html#autotoc_md19',1,'Documentation'],['../md_README.html#autotoc_md125',1,'Generate API documentation']]], + ['documentation_20and_20maintenance_65',['documentation and maintenance',['../md_changelog.html#autotoc_md14',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md22',1,'Documentation and maintenance']]] ]; diff --git a/docs/html/search/all_9.js b/docs/html/search/all_9.js index 05abbd8..ccf20df 100644 --- a/docs/html/search/all_9.js +++ b/docs/html/search/all_9.js @@ -1,9 +1,9 @@ var searchData= [ - ['enough_0',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]], - ['errors_1',['errors',['../md_README.html#autotoc_md72',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md76',1,'Signal validation and parse errors']]], - ['example_20usage_2',['Example Usage',['../md_README.html#autotoc_md90',1,'']]], + ['enough_0',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]], + ['errors_1',['errors',['../md_README.html#autotoc_md76',1,'Frame validation and parse errors'],['../md_README.html#autotoc_md80',1,'Signal validation and parse errors']]], + ['example_20usage_2',['Example Usage',['../md_README.html#autotoc_md94',1,'']]], ['examples_2fmain_2ecpp_3',['main.cpp',['../examples_2main_8cpp.html',1,'']]], - ['exists_4',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], - ['extraction_5',['extraction',['../md_README.html#autotoc_md88',1,'Intel and Motorola Extraction'],['../md_README.html#autotoc_md84',1,'PGN Extraction']]] + ['exists_4',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], + ['extraction_5',['extraction',['../md_README.html#autotoc_md92',1,'Intel and Motorola Extraction'],['../md_README.html#autotoc_md88',1,'PGN Extraction']]] ]; diff --git a/docs/html/search/all_a.js b/docs/html/search/all_a.js index 2b38936..48a09a6 100644 --- a/docs/html/search/all_a.js +++ b/docs/html/search/all_a.js @@ -1,19 +1,19 @@ var searchData= [ ['factor_0',['factor',['../structDecodeSignal.html#a428c39913a366a8476dd291061354391',1,'DecodeSignal::factor'],['../structSignalInfo.html#ae4f78d99a2750aa564d7eba860171499',1,'SignalInfo::factor']]], - ['factory_1',['Statement Handler Factory',['../md_README.html#autotoc_md104',1,'']]], + ['factory_1',['Statement Handler Factory',['../md_README.html#autotoc_md108',1,'']]], ['findframe_2',['FindFrame',['../classDbcDecoder.html#ab2cfb2fb711c95d3a29365546b89f3da',1,'DbcDecoder']]], - ['fixed_3',['fixed',['../md_changelog.html#autotoc_md10',1,'Fixed'],['../md_changelog.html#autotoc_md14',1,'Fixed'],['../md_changelog.html#autotoc_md5',1,'Fixed']]], - ['flow_4',['Decode Flow',['../md_README.html#autotoc_md86',1,'']]], - ['frame_5',['Decode a raw frame',['../md_README.html#autotoc_md94',1,'']]], - ['frame_20definition_6',['Frame definition',['../md_README.html#autotoc_md70',1,'']]], - ['frame_20validation_20and_20parse_20errors_7',['Frame validation and parse errors',['../md_README.html#autotoc_md72',1,'']]], + ['fixed_3',['fixed',['../md_changelog.html#autotoc_md13',1,'Fixed'],['../md_changelog.html#autotoc_md17',1,'Fixed'],['../md_changelog.html#autotoc_md8',1,'Fixed']]], + ['flow_4',['Decode Flow',['../md_README.html#autotoc_md90',1,'']]], + ['frame_5',['Decode a raw frame',['../md_README.html#autotoc_md98',1,'']]], + ['frame_20definition_6',['Frame definition',['../md_README.html#autotoc_md74',1,'']]], + ['frame_20validation_20and_20parse_20errors_7',['Frame validation and parse errors',['../md_README.html#autotoc_md76',1,'']]], ['frame_5finfo_2eh_8',['frame_info.h',['../frame__info_8h.html',1,'']]], ['frameinfo_9',['FrameInfo',['../structFrameInfo.html',1,'']]], - ['frameinfo_20tt_10',['<tt>FrameInfo</tt>',['../md_README.html#autotoc_md34',1,'']]], + ['frameinfo_20tt_10',['<tt>FrameInfo</tt>',['../md_README.html#autotoc_md37',1,'']]], ['framekey_11',['FrameKey',['../structFrameKey.html',1,'']]], - ['framekey_20tt_12',['<tt>FrameKey</tt>',['../md_README.html#autotoc_md52',1,'']]], + ['framekey_20tt_12',['<tt>FrameKey</tt>',['../md_README.html#autotoc_md55',1,'']]], ['framekeyhasher_13',['FrameKeyHasher',['../structFrameKeyHasher.html',1,'']]], ['frames_14',['frames',['../structDbcDatabase.html#a2cade5d0234ee816132127542f8c612b',1,'DbcDatabase']]], - ['frametap_15',['Intended Use in FrameTap',['../md_README.html#autotoc_md100',1,'']]] + ['frametap_15',['Intended Use in FrameTap',['../md_README.html#autotoc_md104',1,'']]] ]; diff --git a/docs/html/search/all_b.js b/docs/html/search/all_b.js index 780d60a..f81d884 100644 --- a/docs/html/search/all_b.js +++ b/docs/html/search/all_b.js @@ -1,9 +1,9 @@ var searchData= [ - ['gcc_20coverage_20build_20in_20qt_20creator_0',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md126',1,'']]], - ['gcc_20gcov_20and_20lcov_20on_20debian_20ubuntu_1',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['gcov_20and_20lcov_20on_20debian_20ubuntu_2',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], - ['generate_20api_20documentation_3',['Generate API documentation',['../md_README.html#autotoc_md121',1,'']]], + ['gcc_20coverage_20build_20in_20qt_20creator_0',['Configure the GCC coverage build in Qt Creator',['../md_README.html#autotoc_md130',1,'']]], + ['gcc_20gcov_20and_20lcov_20on_20debian_20ubuntu_1',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['gcov_20and_20lcov_20on_20debian_20ubuntu_2',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], + ['generate_20api_20documentation_3',['Generate API documentation',['../md_README.html#autotoc_md125',1,'']]], ['getchild_4',['getchild',['../classTreeNode.html#a4727ff801a2d1b9323c5ae50a35457a6',1,'TreeNode::GetChild(std::size_t index) const'],['../classTreeNode.html#a81047bd7d2a4cc96b9ef5e20d0d63b5f',1,'TreeNode::GetChild(std::size_t index)']]], ['getchildcount_5',['GetChildCount',['../classTreeNode.html#abdd82460187dca8d3e5d66f5d5c529ea',1,'TreeNode']]], ['getframe_6',['GetFrame',['../classTreeNode.html#afc503b40004764163605d6dbdb4ef811',1,'TreeNode']]], diff --git a/docs/html/search/all_c.js b/docs/html/search/all_c.js index a93d108..fc978ee 100644 --- a/docs/html/search/all_c.js +++ b/docs/html/search/all_c.js @@ -1,6 +1,6 @@ var searchData= [ - ['handler_20factory_0',['Statement Handler Factory',['../md_README.html#autotoc_md104',1,'']]], + ['handler_20factory_0',['Statement Handler Factory',['../md_README.html#autotoc_md108',1,'']]], ['haspgn_1',['haspgn',['../structDecodeFrame.html#a2551102670c4a540fced4c71da0b369d',1,'DecodeFrame::hasPgn'],['../structFrameInfo.html#a4737a5420213ad4304724e39f3a4e55d',1,'FrameInfo::hasPgn']]], - ['high_20level_20architecture_2',['High-Level Architecture',['../md_README.html#autotoc_md23',1,'']]] + ['high_20level_20architecture_2',['High-Level Architecture',['../md_README.html#autotoc_md26',1,'']]] ]; diff --git a/docs/html/search/all_d.js b/docs/html/search/all_d.js index 237f272..0feaf0e 100644 --- a/docs/html/search/all_d.js +++ b/docs/html/search/all_d.js @@ -1,15 +1,15 @@ var searchData= [ - ['id_20normalization_0',['CAN ID Normalization',['../md_README.html#autotoc_md82',1,'']]], - ['implementation_20—_202026_2003_2013_1',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['implemented_2',['Stage 1 - already implemented',['../md_README.html#autotoc_md111',1,'']]], - ['in_20frametap_3',['Intended Use in FrameTap',['../md_README.html#autotoc_md100',1,'']]], - ['in_20qt_20creator_4',['in qt creator',['../md_README.html#autotoc_md127',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md126',1,'Configure the GCC coverage build in Qt Creator']]], - ['initial_20implementation_20—_202026_2003_2013_5',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md17',1,'']]], - ['integration_6',['Build Integration',['../md_README.html#autotoc_md116',1,'']]], - ['intel_20and_20motorola_20extraction_7',['Intel and Motorola Extraction',['../md_README.html#autotoc_md88',1,'']]], - ['intended_20use_20in_20frametap_8',['Intended Use in FrameTap',['../md_README.html#autotoc_md100',1,'']]], - ['is_20not_20enough_9',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md102',1,'']]], + ['id_20normalization_0',['CAN ID Normalization',['../md_README.html#autotoc_md86',1,'']]], + ['implementation_20—_202026_2003_2013_1',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['implemented_2',['Stage 1 - already implemented',['../md_README.html#autotoc_md115',1,'']]], + ['in_20frametap_3',['Intended Use in FrameTap',['../md_README.html#autotoc_md104',1,'']]], + ['in_20qt_20creator_4',['in qt creator',['../md_README.html#autotoc_md131',1,'Configure all build variants in Qt Creator'],['../md_README.html#autotoc_md130',1,'Configure the GCC coverage build in Qt Creator']]], + ['initial_20implementation_20—_202026_2003_2013_5',['Initial implementation — 2026-03-13',['../md_changelog.html#autotoc_md20',1,'']]], + ['integration_6',['Build Integration',['../md_README.html#autotoc_md120',1,'']]], + ['intel_20and_20motorola_20extraction_7',['Intel and Motorola Extraction',['../md_README.html#autotoc_md92',1,'']]], + ['intended_20use_20in_20frametap_8',['Intended Use in FrameTap',['../md_README.html#autotoc_md104',1,'']]], + ['is_20not_20enough_9',['Why the Tree Is Not Enough',['../md_README.html#autotoc_md106',1,'']]], ['isextended_10',['isextended',['../structRawCanFrame.html#a462193d275adc1dba8bd18ffa0e36bb7',1,'RawCanFrame::isExtended'],['../structDecodeFrame.html#a3ee2348d781f8f15aaf87e8dcf57ec41',1,'DecodeFrame::isExtended'],['../structFrameInfo.html#a34b726afaad2ac5c697fdb2ac070cdaf',1,'FrameInfo::isExtended']]], ['islittleendian_11',['isLittleEndian',['../structSignalInfo.html#af363b1563fb4c7cc8973f9a80c06846c',1,'SignalInfo']]], ['issigned_12',['isSigned',['../structSignalInfo.html#a52a52b320eef92fbcb4626307f9a498f',1,'SignalInfo']]] diff --git a/docs/html/search/all_e.js b/docs/html/search/all_e.js index 7006849..78ca020 100644 --- a/docs/html/search/all_e.js +++ b/docs/html/search/all_e.js @@ -1,12 +1,12 @@ var searchData= [ - ['layer_0',['layer',['../md_README.html#autotoc_md56',1,'Decoder Layer'],['../md_README.html#autotoc_md41',1,'Runtime Decode Layer'],['../md_README.html#autotoc_md38',1,'UI Tree Layer']]], - ['layer_20exists_1',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md27',1,'']]], - ['layout_2',['Module Layout',['../md_README.html#autotoc_md29',1,'']]], - ['lcov_20on_20debian_20ubuntu_3',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md125',1,'']]], + ['layer_0',['layer',['../md_README.html#autotoc_md59',1,'Decoder Layer'],['../md_README.html#autotoc_md44',1,'Runtime Decode Layer'],['../md_README.html#autotoc_md41',1,'UI Tree Layer']]], + ['layer_20exists_1',['Why the Runtime Decode Layer Exists',['../md_README.html#autotoc_md30',1,'']]], + ['layout_2',['Module Layout',['../md_README.html#autotoc_md32',1,'']]], + ['lcov_20on_20debian_20ubuntu_3',['GCC, gcov, and LCOV on Debian/Ubuntu',['../md_README.html#autotoc_md129',1,'']]], ['length_4',['length',['../structDecodeSignal.html#acd4ef5ee30421d117b5756854302debb',1,'DecodeSignal::length'],['../structSignalInfo.html#a1008b5201f71848177217bd52fb84baa',1,'SignalInfo::length']]], - ['level_20architecture_5',['High-Level Architecture',['../md_README.html#autotoc_md23',1,'']]], - ['libraries_6',['Build core without Qt libraries',['../md_README.html#autotoc_md117',1,'']]], - ['limitations_7',['Current Limitations',['../md_README.html#autotoc_md108',1,'']]], - ['live_20path_8',['live path',['../md_README.html#autotoc_md97',1,'']]] + ['level_20architecture_5',['High-Level Architecture',['../md_README.html#autotoc_md26',1,'']]], + ['libraries_6',['Build core without Qt libraries',['../md_README.html#autotoc_md121',1,'']]], + ['limitations_7',['Current Limitations',['../md_README.html#autotoc_md112',1,'']]], + ['live_20path_8',['live path',['../md_README.html#autotoc_md101',1,'']]] ]; diff --git a/docs/html/search/all_f.js b/docs/html/search/all_f.js index 7f95947..21542a3 100644 --- a/docs/html/search/all_f.js +++ b/docs/html/search/all_f.js @@ -1,13 +1,13 @@ var searchData= [ - ['maintenance_0',['maintenance',['../md_changelog.html#autotoc_md11',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md19',1,'Documentation and maintenance']]], + ['maintenance_0',['maintenance',['../md_changelog.html#autotoc_md14',1,'Documentation and maintenance'],['../md_changelog.html#autotoc_md22',1,'Documentation and maintenance']]], ['maximum_1',['maximum',['../structDecodeSignal.html#a4a6ba87142a9badbf0ca830e9e709cb7',1,'DecodeSignal::maximum'],['../structSignalInfo.html#adf1c4331b9eabced0d7fdda40ff0eb52',1,'SignalInfo::maximum']]], - ['measuring_20code_20coverage_2',['Measuring code coverage',['../md_README.html#autotoc_md124',1,'']]], + ['measuring_20code_20coverage_2',['Measuring code coverage',['../md_README.html#autotoc_md128',1,'']]], ['minimum_3',['minimum',['../structDecodeSignal.html#a0fb84e19a0ab3bd50b6f65c1075ebc25',1,'DecodeSignal::minimum'],['../structSignalInfo.html#ada7bf94fbeaa26bd08c73982b5af255b',1,'SignalInfo::minimum']]], - ['model_20adapter_4',['Optional Qt model adapter',['../md_README.html#autotoc_md118',1,'']]], - ['model_20tests_5',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md131',1,'']]], + ['model_20adapter_4',['Optional Qt model adapter',['../md_README.html#autotoc_md122',1,'']]], + ['model_20tests_5',['Tree and optional model tests',['../md_tests_2README.html#autotoc_md135',1,'']]], ['module_20documentation_6',['DBC Parser and Runtime Decode Module Documentation',['../md_README.html',1,'']]], - ['module_20layout_7',['Module Layout',['../md_README.html#autotoc_md29',1,'']]], - ['motorola_20extraction_8',['Intel and Motorola Extraction',['../md_README.html#autotoc_md88',1,'']]], - ['multiplexing_9',['multiplexing',['../md_README.html#autotoc_md78',1,'Basic multiplexing'],['../structMultiplexing.html',1,'Multiplexing']]] + ['module_20layout_7',['Module Layout',['../md_README.html#autotoc_md32',1,'']]], + ['motorola_20extraction_8',['Intel and Motorola Extraction',['../md_README.html#autotoc_md92',1,'']]], + ['multiplexing_9',['multiplexing',['../md_README.html#autotoc_md82',1,'Basic multiplexing'],['../structMultiplexing.html',1,'Multiplexing']]] ]; diff --git a/docs/html/search/classes_0.js b/docs/html/search/classes_0.js index 017a291..751a4fe 100644 --- a/docs/html/search/classes_0.js +++ b/docs/html/search/classes_0.js @@ -4,19 +4,23 @@ var searchData= ['dbcdatabase_1',['DbcDatabase',['../structDbcDatabase.html',1,'']]], ['dbcdecodebuilder_2',['DbcDecodeBuilder',['../classDbcDecodeBuilder.html',1,'']]], ['dbcdecoder_3',['DbcDecoder',['../classDbcDecoder.html',1,'']]], - ['dbcframehandler_4',['DbcFrameHandler',['../classDbcFrameHandler.html',1,'']]], - ['dbcparsecontext_5',['DbcParseContext',['../structDbcParseContext.html',1,'']]], - ['dbcparser_6',['DbcParser',['../classDbcParser.html',1,'']]], - ['dbcsignalhandler_7',['DbcSignalHandler',['../classDbcSignalHandler.html',1,'']]], - ['dbcstatementdispatcher_8',['DbcStatementDispatcher',['../classDbcStatementDispatcher.html',1,'']]], - ['dbcstatementhandler_9',['DbcStatementHandler',['../classDbcStatementHandler.html',1,'']]], - ['dbctreebuilder_10',['DbcTreeBuilder',['../classDbcTreeBuilder.html',1,'']]], - ['dbctreemodel_11',['DbcTreeModel',['../classDbcTreeModel.html',1,'']]], - ['dbcunsupportedmultiplexinghandler_12',['DbcUnsupportedMultiplexingHandler',['../classDbcUnsupportedMultiplexingHandler.html',1,'']]], - ['dbcvaluedescriptionhandler_13',['DbcValueDescriptionHandler',['../classDbcValueDescriptionHandler.html',1,'']]], - ['decodedatabase_14',['DecodeDatabase',['../structDecodeDatabase.html',1,'']]], - ['decodedframevalue_15',['DecodedFrameValue',['../structDecodedFrameValue.html',1,'']]], - ['decodedsignalvalue_16',['DecodedSignalValue',['../structDecodedSignalValue.html',1,'']]], - ['decodeframe_17',['DecodeFrame',['../structDecodeFrame.html',1,'']]], - ['decodesignal_18',['DecodeSignal',['../structDecodeSignal.html',1,'']]] + ['dbcdiagnostic_4',['DbcDiagnostic',['../structDbcDiagnostic.html',1,'']]], + ['dbcdiagnosticerror_5',['DbcDiagnosticError',['../classDbcDiagnosticError.html',1,'']]], + ['dbcframehandler_6',['DbcFrameHandler',['../classDbcFrameHandler.html',1,'']]], + ['dbcheaderhandler_7',['DbcHeaderHandler',['../classDbcHeaderHandler.html',1,'']]], + ['dbcparsecontext_8',['DbcParseContext',['../structDbcParseContext.html',1,'']]], + ['dbcparser_9',['DbcParser',['../classDbcParser.html',1,'']]], + ['dbcparseresult_10',['DbcParseResult',['../structDbcParseResult.html',1,'']]], + ['dbcsignalhandler_11',['DbcSignalHandler',['../classDbcSignalHandler.html',1,'']]], + ['dbcstatementdispatcher_12',['DbcStatementDispatcher',['../classDbcStatementDispatcher.html',1,'']]], + ['dbcstatementhandler_13',['DbcStatementHandler',['../classDbcStatementHandler.html',1,'']]], + ['dbctreebuilder_14',['DbcTreeBuilder',['../classDbcTreeBuilder.html',1,'']]], + ['dbctreemodel_15',['DbcTreeModel',['../classDbcTreeModel.html',1,'']]], + ['dbcunsupportedmultiplexinghandler_16',['DbcUnsupportedMultiplexingHandler',['../classDbcUnsupportedMultiplexingHandler.html',1,'']]], + ['dbcvaluedescriptionhandler_17',['DbcValueDescriptionHandler',['../classDbcValueDescriptionHandler.html',1,'']]], + ['decodedatabase_18',['DecodeDatabase',['../structDecodeDatabase.html',1,'']]], + ['decodedframevalue_19',['DecodedFrameValue',['../structDecodedFrameValue.html',1,'']]], + ['decodedsignalvalue_20',['DecodedSignalValue',['../structDecodedSignalValue.html',1,'']]], + ['decodeframe_21',['DecodeFrame',['../structDecodeFrame.html',1,'']]], + ['decodesignal_22',['DecodeSignal',['../structDecodeSignal.html',1,'']]] ]; diff --git a/docs/html/search/functions_6.js b/docs/html/search/functions_6.js index 514d33b..3aebbee 100644 --- a/docs/html/search/functions_6.js +++ b/docs/html/search/functions_6.js @@ -1,4 +1,5 @@ var searchData= [ - ['parsefile_0',['ParseFile',['../classDbcParser.html#aef72826942c9095d653fafa435855e56',1,'DbcParser']]] + ['parsefile_0',['ParseFile',['../classDbcParser.html#aef72826942c9095d653fafa435855e56',1,'DbcParser']]], + ['parsefilewithdiagnostics_1',['ParseFileWithDiagnostics',['../classDbcParser.html#a0e915ce79c2e3d4c95a5aaf2bf0409bc',1,'DbcParser']]] ]; diff --git a/docs/html/structDbcDiagnostic-members.html b/docs/html/structDbcDiagnostic-members.html new file mode 100644 index 0000000..3d4eb3f --- /dev/null +++ b/docs/html/structDbcDiagnostic-members.html @@ -0,0 +1,113 @@ + + + + + + + +DBC Framework: Member List + + + + + + + + + + + + + +
      +
      + + + + + + +
      +
      DBC Framework +
      +
      DBC parsing and CAN signal decoding framework
      +
      +
      + + + + + + + +
      +
      + +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      Loading...
      +
      Searching...
      +
      No Matches
      +
      +
      +
      +
      + +
      +
      DbcDiagnostic Member List
      +
      +
      + +

      This is the complete list of members for DbcDiagnostic, including all inherited members.

      + + + + + + +
      code (defined in DbcDiagnostic)DbcDiagnostic
      filePath (defined in DbcDiagnostic)DbcDiagnostic
      lineNumber (defined in DbcDiagnostic)DbcDiagnostic
      message (defined in DbcDiagnostic)DbcDiagnostic
      severity (defined in DbcDiagnostic)DbcDiagnostic
      +
      + + + + diff --git a/docs/html/structDbcDiagnostic.html b/docs/html/structDbcDiagnostic.html new file mode 100644 index 0000000..07fa2e2 --- /dev/null +++ b/docs/html/structDbcDiagnostic.html @@ -0,0 +1,210 @@ + + + + + + + +DBC Framework: DbcDiagnostic Struct Reference + + + + + + + + + + + + + +
      +
      + + + + + + +
      +
      DBC Framework +
      +
      DBC parsing and CAN signal decoding framework
      +
      +
      + + + + + + + +
      +
      + +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      Loading...
      +
      Searching...
      +
      No Matches
      +
      +
      +
      +
      + +
      + +
      DbcDiagnostic Struct Reference
      +
      +
      + + + + + + + + + + + + +

      +Public Attributes

      DbcDiagnosticSeverity severity
       
      DbcDiagnosticCode code
       
      std::string filePath
       
      std::size_t lineNumber
       
      std::string message
       
      +

      Detailed Description

      +
      +

      Definition at line 25 of file dbc_diagnostic.h.

      +

      Member Data Documentation

      + +

      ◆ severity

      + +
      +
      + + + + +
      DbcDiagnosticSeverity DbcDiagnostic::severity
      +
      + +

      Definition at line 26 of file dbc_diagnostic.h.

      + +
      +
      + +

      ◆ code

      + +
      +
      + + + + +
      DbcDiagnosticCode DbcDiagnostic::code
      +
      + +

      Definition at line 27 of file dbc_diagnostic.h.

      + +
      +
      + +

      ◆ filePath

      + +
      +
      + + + + +
      std::string DbcDiagnostic::filePath
      +
      + +

      Definition at line 28 of file dbc_diagnostic.h.

      + +
      +
      + +

      ◆ lineNumber

      + +
      +
      + + + + +
      std::size_t DbcDiagnostic::lineNumber
      +
      + +

      Definition at line 29 of file dbc_diagnostic.h.

      + +
      +
      + +

      ◆ message

      + +
      +
      + + + + +
      std::string DbcDiagnostic::message
      +
      + +

      Definition at line 30 of file dbc_diagnostic.h.

      + +
      +
      +
      The documentation for this struct was generated from the following file: +
      +
      + + + + diff --git a/docs/html/structDbcParseContext.html b/docs/html/structDbcParseContext.html index 39c8a9c..e41f72f 100644 --- a/docs/html/structDbcParseContext.html +++ b/docs/html/structDbcParseContext.html @@ -123,7 +123,7 @@ Public Attributes

      Detailed Description

      Mutable state belonging to one file parse. Handlers do not retain it.

      -

      Definition at line 19 of file dbc_statement_handler.h.

      +

      Definition at line 32 of file dbc_statement_handler.h.

      Member Function Documentation

      ◆ ValidateMultiplexing()

      @@ -141,7 +141,7 @@ Public Attributes
      -

      Definition at line 502 of file dbc_statement_handler.cpp.

      +

      Definition at line 513 of file dbc_statement_handler.cpp.

      @@ -161,7 +161,7 @@ Public Attributes
      -

      Definition at line 427 of file dbc_statement_handler.cpp.

      +

      Definition at line 436 of file dbc_statement_handler.cpp.

      @@ -178,7 +178,7 @@ Public Attributes
      -

      Definition at line 20 of file dbc_statement_handler.h.

      +

      Definition at line 33 of file dbc_statement_handler.h.

      @@ -194,7 +194,7 @@ Public Attributes
      -

      Definition at line 21 of file dbc_statement_handler.h.

      +

      Definition at line 34 of file dbc_statement_handler.h.

      @@ -210,7 +210,7 @@ Public Attributes
      -

      Definition at line 22 of file dbc_statement_handler.h.

      +

      Definition at line 35 of file dbc_statement_handler.h.

      @@ -226,7 +226,7 @@ Public Attributes
      -

      Definition at line 23 of file dbc_statement_handler.h.

      +

      Definition at line 36 of file dbc_statement_handler.h.

      @@ -242,7 +242,7 @@ Public Attributes
      -

      Definition at line 25 of file dbc_statement_handler.h.

      +

      Definition at line 38 of file dbc_statement_handler.h.

      diff --git a/docs/html/structDbcParseResult-members.html b/docs/html/structDbcParseResult-members.html new file mode 100644 index 0000000..c5524e3 --- /dev/null +++ b/docs/html/structDbcParseResult-members.html @@ -0,0 +1,111 @@ + + + + + + + +DBC Framework: Member List + + + + + + + + + + + + + +
      +
      + + + + + + +
      +
      DBC Framework +
      +
      DBC parsing and CAN signal decoding framework
      +
      +
      + + + + + + + +
      +
      + +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      Loading...
      +
      Searching...
      +
      No Matches
      +
      +
      +
      +
      + +
      +
      DbcParseResult Member List
      +
      +
      + +

      This is the complete list of members for DbcParseResult, including all inherited members.

      + + + + +
      database (defined in DbcParseResult)DbcParseResult
      diagnostics (defined in DbcParseResult)DbcParseResult
      HasErrors() const (defined in DbcParseResult)DbcParseResultinline
      +
      + + + + diff --git a/docs/html/structDbcParseResult.html b/docs/html/structDbcParseResult.html new file mode 100644 index 0000000..b3125de --- /dev/null +++ b/docs/html/structDbcParseResult.html @@ -0,0 +1,190 @@ + + + + + + + +DBC Framework: DbcParseResult Struct Reference + + + + + + + + + + + + + +
      +
      + + + + + + +
      +
      DBC Framework +
      +
      DBC parsing and CAN signal decoding framework
      +
      +
      + + + + + + + +
      +
      + +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      +
      +
      +
      Loading...
      +
      Searching...
      +
      No Matches
      +
      +
      +
      +
      + +
      + +
      DbcParseResult Struct Reference
      +
      +
      + + + + +

      +Public Member Functions

      bool HasErrors () const
       
      + + + + + +

      +Public Attributes

      DbcDatabase database
       
      std::vector< DbcDiagnostic > diagnostics
       
      +

      Detailed Description

      +
      +

      Definition at line 33 of file dbc_diagnostic.h.

      +

      Member Function Documentation

      + +

      ◆ HasErrors()

      + +
      +
      + + + + + +
      + + + + + + + +
      bool DbcParseResult::HasErrors () const
      +
      +inline
      +
      + +

      Definition at line 37 of file dbc_diagnostic.h.

      + +
      +
      +

      Member Data Documentation

      + +

      ◆ database

      + +
      +
      + + + + +
      DbcDatabase DbcParseResult::database
      +
      + +

      Definition at line 34 of file dbc_diagnostic.h.

      + +
      +
      + +

      ◆ diagnostics

      + +
      +
      + + + + +
      std::vector<DbcDiagnostic> DbcParseResult::diagnostics
      +
      + +

      Definition at line 35 of file dbc_diagnostic.h.

      + +
      +
      +
      The documentation for this struct was generated from the following file: +
      +
      + + + + diff --git a/docs/html/structPendingValueDescriptions.html b/docs/html/structPendingValueDescriptions.html index 3987e78..8015830 100644 --- a/docs/html/structPendingValueDescriptions.html +++ b/docs/html/structPendingValueDescriptions.html @@ -112,7 +112,7 @@ Public Attributes

      Detailed Description

      -

      Definition at line 10 of file dbc_statement_handler.h.

      +

      Definition at line 12 of file dbc_statement_handler.h.

      Member Data Documentation

      ◆ canId

      @@ -126,7 +126,7 @@ Public Attributes
      -

      Definition at line 11 of file dbc_statement_handler.h.

      +

      Definition at line 13 of file dbc_statement_handler.h.

      @@ -142,7 +142,7 @@ Public Attributes
      -

      Definition at line 12 of file dbc_statement_handler.h.

      +

      Definition at line 14 of file dbc_statement_handler.h.

      @@ -158,7 +158,7 @@ Public Attributes
      -

      Definition at line 13 of file dbc_statement_handler.h.

      +

      Definition at line 15 of file dbc_statement_handler.h.

      @@ -174,7 +174,7 @@ Public Attributes
      -

      Definition at line 14 of file dbc_statement_handler.h.

      +

      Definition at line 16 of file dbc_statement_handler.h.

      @@ -190,7 +190,7 @@ Public Attributes
      -

      Definition at line 15 of file dbc_statement_handler.h.

      +

      Definition at line 17 of file dbc_statement_handler.h.

      diff --git a/tests/README.md b/tests/README.md index a706300..f4d1ac3 100644 --- a/tests/README.md +++ b/tests/README.md @@ -54,6 +54,17 @@ found; insufficient payloads are checked through signal validity. ## Parser coverage +Structured diagnostic tests cover severity, code, supplied path, and physical +line numbers for skipped syntax and immediate/deferred errors; warnings preceding +an error are retained, and failed parses return an empty database. Common headers +and namespace symbol lists stay quiet. Tests also check file-open errors, fresh +parse sessions, and compatibility with the legacy throwing API. +The diagnostic audit also covers 15 unsupported-statement variants, all namespace +termination forms, CRLF and missing final newlines, relative paths with spaces, +first-error stopping, deferred diagnostic ordering, duplicate definitions/values, +selector ranges, overlaps, and preservation of supported decoding and metadata. +On Linux, reading a directory exercises the distinct `FileReadError` path. + Parser tests cover standard and extended CAN IDs, whitespace, payload storage boundaries, missing fields, malformed and overflowing numbers, reserved ID bits, error paths and line numbers, and integration with signals and comments. diff --git a/tests/dbc_parser_test.cpp b/tests/dbc_parser_test.cpp index ae7414e..d146424 100644 --- a/tests/dbc_parser_test.cpp +++ b/tests/dbc_parser_test.cpp @@ -63,6 +63,11 @@ private: } } private Q_SLOTS: + void diagnostics(); + void diagnosticErrors(); + void diagnosticUnsupportedStatements(); + void diagnosticNamespaceBoundaries(); + void diagnosticFormatting(); void multiplexing(); void multiplexingBoundaries(); void validFrames(); @@ -79,6 +84,266 @@ private Q_SLOTS: void invalidValueDescriptions(); }; +void DbcParserTest::diagnostics() { + Fixture fixture; + fixture.Write("VERSION \"test\"\n" + "NS_ :\n" + " CM_\n" + " BA_\n" + " SIG_VALTYPE_\n" + " SG_MUL_VAL_\n\n" + "BS_:\n" + "BU_: ECU\n" + "BO_ 1 Frame: 1 ECU\n" + "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n" + "SIG_VALTYPE_ 1 Value : 1;\n" + "BA_ \"SignalType\" SG_ 1 Value 1;\n" + "VENDOR_EXTENSION_ data;\n"); + const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(!result.HasErrors() && result.database.frames.size() == 1U, + "Warnings preserve the supported database"); + QCOMPARE(result.diagnostics.size(), std::size_t(3U)); + for (std::size_t index = 0U; index < result.diagnostics.size(); ++index) { + const DbcDiagnostic &diagnostic = result.diagnostics[index]; + CHECK(diagnostic.severity == DbcDiagnosticSeverity::Warning && + diagnostic.code == DbcDiagnosticCode::UnsupportedStatement, + "Unsupported statements have structured warning severity and code"); + QCOMPARE(diagnostic.filePath, fixture.path.string()); + QCOMPARE(diagnostic.lineNumber, 12U + index); + CHECK(diagnostic.message.find("ignored") != std::string::npos, + "Warning explains unsupported syntax"); + } + CHECK(DbcParser().ParseFile(fixture.path.string()).frames.size() == 1U, + "Legacy API accepts files with warnings"); + fixture.Write("VERSION \"\"\nNS_:\nSIG_VALTYPE_\n\tBA_\n BS_ :\n BU_ : ECU\n"); + const DbcParseResult headers = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(headers.diagnostics.empty(), "Common header variants stay quiet"); + fixture.Write("NS_ :\n BA_\n BO_\n"); + CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).HasErrors(), + "Namespace handling does not swallow a malformed frame"); +} + +void DbcParserTest::diagnosticErrors() { + Fixture fixture; + struct ErrorCase { + const char *text; + DbcDiagnosticCode code; + std::size_t line; + }; + const ErrorCase cases[] = { + {"UNKNOWN_ data;\n\nBO_ invalid Frame: 1 ECU\n", + DbcDiagnosticCode::InvalidStatement, 3U}, + {"BO_ 1 Frame: 1 ECU\nSG_MUL_VAL_ 1 Value Mode 1-2;\n", + DbcDiagnosticCode::UnsupportedStatement, 2U}, + {"BO_ 1 Frame: 1 ECU\nVAL_ 1 Missing 0 \"Off\";\n", + DbcDiagnosticCode::InvalidValueDescription, 2U}, + {"BO_ 1 Frame: 1 ECU\nSG_ Value m1 : 0|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidMultiplexing, 2U}, + {"BO_ 1 Frame: 1 ECU\nSG_ Mode M : 0|8@1- (1,0) [-128|127] \"\" ECU\n", + DbcDiagnosticCode::InvalidMultiplexing, 2U}, + {"VAL_ broken\n", DbcDiagnosticCode::InvalidValueDescription, 1U}, + {"SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidStatement, 1U}, + {"BO_ 1 Frame: 1 ECU\nBO_ 1 Duplicate: 1 ECU\n", + DbcDiagnosticCode::InvalidStatement, 2U}, + {"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n" + "SG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidStatement, 3U}, + {"BO_ 1 Frame: 1 ECU\nSG_ Value : 8|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidStatement, 2U}, + {"BO_ 1 Frame: 1 ECU\nVAL_ 2 Missing 0 \"Off\";\n", + DbcDiagnosticCode::InvalidValueDescription, 2U}, + {"BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (1,0) [0|255] \"\" ECU\n" + "VAL_ 1 Value 0 \"Off\";\nVAL_ 1 Value 0 \"Duplicate\";\n", + DbcDiagnosticCode::InvalidValueDescription, 4U}, + {"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|1@1+ (1,0) [0|1] \"\" ECU\n" + "SG_ Value m2 : 8|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidMultiplexing, 3U}, + {"BO_ 1 Frame: 2 ECU\nSG_ Mode M : 0|8@1+ (1,0) [0|255] \"\" ECU\n" + "SG_ Other M : 8|8@1+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidMultiplexing, 3U}, + {"BO_ 1 Frame: 1 ECU\nSG_ First : 0|8@1+ (1,0) [0|255] \"\" ECU\n" + "SG_ Second : 7|8@0+ (1,0) [0|255] \"\" ECU\n", + DbcDiagnosticCode::InvalidMultiplexing, 3U} + }; + for (const ErrorCase &test : cases) { + fixture.Write(test.text); + const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(result.HasErrors() && result.database.frames.empty(), + "Failed parse never returns a partial database"); + const DbcDiagnostic &diagnostic = result.diagnostics.back(); + CHECK(diagnostic.severity == DbcDiagnosticSeverity::Error && diagnostic.code == test.code, + "Error has expected severity and code"); + QCOMPARE(diagnostic.filePath, fixture.path.string()); + QCOMPARE(diagnostic.lineNumber, test.line); + CHECK(!diagnostic.message.empty(), "Error includes a message"); + const bool hasWarning = std::string(test.text).find("UNKNOWN_") == 0U; + QCOMPARE(result.diagnostics.size(), hasWarning ? std::size_t(2U) : std::size_t(1U)); + try { + DbcParser().ParseFile(fixture.path.string()); + CHECK(false, "Legacy parser must throw"); + } catch (const std::runtime_error &error) { + QCOMPARE(std::string(error.what()), fixture.path.string() + ":" + + std::to_string(test.line) + ": " + diagnostic.message); + } + } + const std::string missingPath = fixture.path.string() + ".missing"; + const DbcParseResult missing = DbcParser().ParseFileWithDiagnostics(missingPath); + CHECK(missing.HasErrors() && missing.database.frames.empty(), "Missing file returns error"); + QCOMPARE(missing.diagnostics.size(), std::size_t(1U)); + CHECK(missing.diagnostics[0].code == DbcDiagnosticCode::FileOpenError, + "Missing file has a distinct code"); + QCOMPARE(missing.diagnostics[0].lineNumber, std::size_t(0U)); + QCOMPARE(missing.diagnostics[0].filePath, missingPath); + QCOMPARE(missing.diagnostics[0].message, "Failed to open DBC file: " + missingPath); + try { + DbcParser().ParseFile(missingPath); + CHECK(false, "Legacy API throws on missing file"); + } catch (const std::runtime_error &error) { + QCOMPARE(std::string(error.what()), missing.diagnostics[0].message); + } + const std::string directoryPath = fixture.path.parent_path().string(); + const DbcParseResult directory = DbcParser().ParseFileWithDiagnostics(directoryPath); + CHECK(directory.HasErrors() && directory.database.frames.empty(), + "Directory cannot be parsed as a file"); + QCOMPARE(directory.diagnostics.size(), std::size_t(1U)); + CHECK(directory.diagnostics[0].code == DbcDiagnosticCode::FileReadError || + directory.diagnostics[0].code == DbcDiagnosticCode::FileOpenError, + "Directory produces a file-level error on supported platforms"); + QCOMPARE(directory.diagnostics[0].lineNumber, std::size_t(0U)); + QCOMPARE(directory.diagnostics[0].filePath, directoryPath); +#ifdef __linux__ + CHECK(directory.diagnostics[0].code == DbcDiagnosticCode::FileReadError, + "Linux directory input exercises the read-error path"); + QCOMPARE(directory.diagnostics[0].message, "Failed to read DBC file: " + directoryPath); +#endif + try { + DbcParser().ParseFile(directoryPath); + CHECK(false, "Legacy API throws on unreadable input"); + } catch (const std::runtime_error &error) { + QCOMPARE(std::string(error.what()), directory.diagnostics[0].message); + } + fixture.Write("BO_ 1 Frame: 1 ECU\n"); + CHECK(DbcParser().ParseFileWithDiagnostics(fixture.path.string()).diagnostics.empty(), + "Diagnostics belong to an independent parse session"); +} + +void DbcParserTest::diagnosticUnsupportedStatements() { + Fixture fixture; + const std::string definitions = + "BO_ 1 Frame: 1 ECU\nSG_ Value : 0|8@1+ (2,10) [10|520] \"V\" ECU\n" + "CM_ SG_ 1 Value \"Signal comment\";\nVAL_ 1 Value 1 \"On\";\n"; + const std::vector statements = { + "SIG_VALTYPE_ 1 Value : 1;", "SIG_VALTYPE_ 1 Value : 2;", + "BA_ \"SignalType\" SG_ 1 Value 1;", + "BA_DEF_ SG_ \"SignalType\" INT 0 1;", + "BA_DEF_DEF_ \"SignalType\" 0;", + "BA_DEF_REL_ BU_SG_REL_ \"Relation\" INT 0 1;", + "BA_REL_ \"Relation\" BU_SG_REL_ ECU SG_ 1 Value 1;", + "SGTYPE_ Type : 8@1+ (1,0) [0|255] \"\" 0, Table;", + "SIG_TYPE_REF_ 1 Value : Type;", + "EV_ Environment : 0 [0|1] \"\" 0 1 DUMMY_NODE_VECTOR0 ECU;", + "ENVVAR_DATA_ Environment : 4;", + "VAL_TABLE_ Table 0 \"Off\" 1 \"On\";", + "BO_TX_BU_ 1 : ECU;", "VENDOR_EXTENSION_ data;", "UNKNOWN_" + }; + for (const std::string &statement : statements) { + fixture.Write(definitions + statement + '\n'); + const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(!result.HasErrors(), statement); + QCOMPARE(result.diagnostics.size(), std::size_t(1U)); + const DbcDiagnostic &warning = result.diagnostics[0]; + CHECK(warning.severity == DbcDiagnosticSeverity::Warning && + warning.code == DbcDiagnosticCode::UnsupportedStatement, statement); + QCOMPARE(warning.filePath, fixture.path.string()); + QCOMPARE(warning.lineNumber, std::size_t(5U)); + const std::string keyword = statement.substr(0U, statement.find(' ')); + CHECK(warning.message.find("'" + keyword + "'") != std::string::npos, statement); + const DecodeDatabase runtime = DbcDecodeBuilder().Build(result.database); + RawCanFrame raw; + raw.canId = 1U; + raw.data = {1U}; + const DecodedFrameValue decoded = DbcDecoder().Decode(runtime, raw); + CHECK(decoded.valid && decoded.signals.size() == 1U && decoded.signals[0].valid, + "Warnings preserve supported signal decoding"); + QCOMPARE(decoded.signals[0].physicalValue, 12.0); + CHECK(decoded.signals[0].GetValueDescription() && + *decoded.signals[0].GetValueDescription() == "On", + "Warnings preserve VAL_ descriptions"); + QCOMPARE(runtime.frames[0].signals[0].comment, std::string("Signal comment")); + } +} + +void DbcParserTest::diagnosticNamespaceBoundaries() { + Fixture fixture; + const std::vector endings = { + "BS_\n", "BS_:\n", "BS_ :\n", "BU_\n", "BU_:\n", "BU_ : ECU\n", + "BO_ 1 Frame: 1 ECU\n", "VENDOR_EXTENSION_ data;\n" + }; + for (const std::string &ending : endings) { + fixture.Write("NS_ :\n\tSG_MUL_VAL_\n\nBA_\n" + ending + "SIG_VALTYPE_\n"); + const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(!result.HasErrors(), ending); + const std::size_t expectedWarnings = ending.find("VENDOR_") == 0U ? 2U : 1U; + QCOMPARE(result.diagnostics.size(), expectedWarnings); + QCOMPARE(result.diagnostics.back().lineNumber, std::size_t(6U)); + CHECK(result.diagnostics.back().message.find("SIG_VALTYPE_") != std::string::npos, + "Unsupported keyword outside NS_ must produce a warning"); + } + for (const std::string &definition : {std::string("BO_"), std::string("SG_")}) { + fixture.Write("NS_:\n\tBA_\n\t" + definition + '\n'); + const DbcParseResult result = DbcParser().ParseFileWithDiagnostics(fixture.path.string()); + CHECK(result.HasErrors(), "Malformed definition ends NS_ instead of being hidden"); + QCOMPARE(result.diagnostics.size(), std::size_t(1U)); + QCOMPARE(result.diagnostics[0].lineNumber, std::size_t(3U)); + } +} + +void DbcParserTest::diagnosticFormatting() { + Fixture fixture; + fixture.path += " with spaces"; + const DbcParser parser; + for (const std::string &text : {std::string(), std::string(" \t\r\n\n")}) { + fixture.Write(text); + const DbcParseResult empty = parser.ParseFileWithDiagnostics(fixture.path.string()); + CHECK(!empty.HasErrors() && empty.diagnostics.empty() && empty.database.frames.empty(), + "Empty and whitespace-only inputs are valid"); + } + fixture.Write("\r\n\tVENDOR_EXTENSION_ data;\r\n\r\nUNKNOWN_"); + const std::string relativePath = std::filesystem::relative(fixture.path).string(); + const DbcParseResult warnings = parser.ParseFileWithDiagnostics(relativePath); + CHECK(!warnings.HasErrors() && warnings.database.frames.empty(), "Warnings-only input"); + QCOMPARE(warnings.diagnostics.size(), std::size_t(2U)); + QCOMPARE(warnings.diagnostics[0].lineNumber, std::size_t(2U)); + QCOMPARE(warnings.diagnostics[1].lineNumber, std::size_t(4U)); + for (const DbcDiagnostic &warning : warnings.diagnostics) + QCOMPARE(warning.filePath, relativePath); + + fixture.Write("UNKNOWN_ first;\nBO_ invalid Frame: 1 ECU\n" + "UNKNOWN_ after_error;\nSG_ broken\n"); + const DbcParseResult stopped = parser.ParseFileWithDiagnostics(relativePath); + CHECK(stopped.HasErrors() && stopped.database.frames.empty(), "First error stops parsing"); + QCOMPARE(stopped.diagnostics.size(), std::size_t(2U)); + QCOMPARE(stopped.diagnostics[0].lineNumber, std::size_t(1U)); + QCOMPARE(stopped.diagnostics[1].lineNumber, std::size_t(2U)); + QCOMPARE(stopped.diagnostics[1].filePath, relativePath); + + fixture.Write("VAL_ 1 Missing 0 \"Off\";\nBO_ 1 Frame: 1 ECU\nUNKNOWN_ data;\n"); + const DbcParseResult deferred = parser.ParseFileWithDiagnostics(relativePath); + CHECK(deferred.HasErrors() && deferred.database.frames.empty(), "Deferred error rejects database"); + QCOMPARE(deferred.diagnostics.size(), std::size_t(2U)); + CHECK(deferred.diagnostics[0].severity == DbcDiagnosticSeverity::Warning && + deferred.diagnostics[1].severity == DbcDiagnosticSeverity::Error, + "Deferred errors follow warnings in detection order"); + QCOMPARE(deferred.diagnostics[0].lineNumber, std::size_t(3U)); + QCOMPARE(deferred.diagnostics[1].lineNumber, std::size_t(1U)); + QCOMPARE(deferred.diagnostics[1].filePath, relativePath); + fixture.Write("BO_ 1 Frame: 1 ECU"); + const DbcParseResult recovered = parser.ParseFileWithDiagnostics(relativePath); + CHECK(!recovered.HasErrors() && recovered.diagnostics.empty() && recovered.database.frames.size() == 1U, + "Same parser has clean state after errors and accepts missing final newline"); +} + void DbcParserTest::validFrames() { Fixture fixture; struct ValidCase {