This commit is contained in:
deeaitch committed 2026-10-07 20:18:37 -04:00
1 parent ef8e21db2e
commit a6016248f8
11 files changed
+529 -252

No files matched your search

+155 -61
View File
@@ -20,8 +20,10 @@ The implementation follows a simple and practical design:
- Qt is not required at the parser or decoder level
- the same decode engine can be reused for live traffic and trace replay
The core library uses C++17 and has no Qt dependency. Qt Core and Qt Test are
used by the regression tests; the optional adapter requires Qt Core. Live CAN acquisition, trace-file readers,
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](changelog.md) for the release and development history,
@@ -396,7 +398,7 @@ alternative. Raw values remain exact across their full 64-bit ranges. Check
Use `std::get` when the numeric type is known, or `std::get_if` to handle both:
```cpp
if (const auto *value = std::get_if<std::int64_t>(&decodedSignal.rawValue)) {
if (const std::int64_t *value = std::get_if<std::int64_t>(&decodedSignal.rawValue)) {
std::cout << *value;
} else {
std::cout << std::get<std::uint64_t>(decodedSignal.rawValue);
@@ -854,6 +856,7 @@ lines:
- `SG_` → `DbcSignalHandler`
- `CM_` → `DbcCommentHandler`
- `VAL_` → `DbcValueDescriptionHandler`
- `SG_MUL_VAL_` → `DbcUnsupportedMultiplexingHandler`
Grammar implementations live in `core/dbc_statement_handler.cpp`; their interface,
context, and dispatcher live in `core/dbc_statement_handler.h`. `core/typefactory.h`
@@ -875,8 +878,8 @@ 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_` accepts spaces and tabs after its keyword; `CM_` retains its existing
policy requiring a literal space.
Unregistered keywords remain ignored. `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
@@ -960,8 +963,9 @@ Additional behavior to account for:
- unregistered DBC keywords are ignored
- an `SG_` statement before the first frame is rejected
- duplicate frame and signal definitions are not rejected globally; ambiguous
`VAL_` references to them are 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
databases are also checked for ambiguous `VAL_` references during resolution
- payload lengths are checked against storage bounds (`0..255`), rather than
CAN or CAN FD protocol limits
- comment handling is limited to the supported forms and already parsed targets
@@ -1025,12 +1029,15 @@ build also requires Qt Core and Qt Test development packages. Other build
systems can compile the sources listed in `core/core_files.pri`; no CMake
configuration is currently provided.
Qt-dependent qmake targets share `qt/qt_version.pri`, which rejects Qt versions
other than 6.8.2. The core library remains independent of Qt libraries.
Open `dbc.pro` in Qt Creator to see two subprojects: `core` and `tests`.
`core/core.pro` builds the C++17 static library `dbc_core` without a Qt dependency.
`tests/tests.pro` builds the QtTest executable `dbc_tests` and links that library.
The root project declares `tests.depends = core` for parallel builds.
Build out of source (Qt 6; use `qmake` for Qt 5):
Build out of source with Qt 6.8.2:
```sh
mkdir build
@@ -1061,8 +1068,15 @@ qmake is still the build tool; this target does not link Qt libraries.
### Optional Qt model adapter
Requires Qt 5.11 or newer (including Qt 6) for `QAbstractItemModelTester`.
The adapter itself links only Qt Core. Enable its library and focused QtTest suite:
The adapter and its `QAbstractItemModelTester` suite use Qt 6.8.2.
The adapter itself links only Qt Core.
The model test executable additionally links QtGui and uses QGuiApplication so
QAbstractItemModelTester can resolve graphical metatypes such as QPixmap. It
defaults to the `offscreen` platform when `QT_QPA_PLATFORM` is unset or empty;
no display server is required. An explicit platform setting is preserved.
Enable its library and focused QtTest suite:
```sh
mkdir -p build-qt
@@ -1086,7 +1100,7 @@ directories when building separately. A widget application also needs `QT += wid
// Run after constructing QApplication; view owns the model through QObject.
QTreeView view;
auto *model = new DbcTreeModel(&view);
DbcTreeModel *model = new DbcTreeModel(&view);
model->SetTree(DbcTreeBuilder().Build(DbcParser().ParseFile("example.dbc")));
view.setModel(model);
view.expandAll();
@@ -1207,7 +1221,7 @@ sudo apt install qtcreator
GCC supplies `gcov`; the `lcov` package supplies `lcov` and `genhtml`. Use the
`gcov` version matching the GCC used by the selected Qt Creator kit. These
instructions use GCC and Qt 6.
instructions use GCC and Qt 6.8.2.
From the repository root, create a fresh coverage build. `--coverage` must be
passed to both compilation and linking; Debug avoids optimization that can make
@@ -1271,12 +1285,16 @@ QtTest executables and the standalone tree test, yielded 97.8% line coverage
(724/740) and 70.7% branch coverage (833/1178). These are a snapshot, not fixed
expected values for later changes or other toolchains.
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](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html)
and the [LCOV project documentation](https://github.com/linux-test-project/lcov).
### Configure the GCC coverage build in Qt Creator
1. Open `dbc.pro` and select a GCC kit with Qt 6.
1. Open `dbc.pro` and select a GCC kit with Qt 6.8.2.
2. In **Projects > Build Settings**, clone **Debug** as **Coverage**.
3. Choose a separate build directory, such as `build-coverage`.
4. Expand the **qmake** build step and add these **Additional arguments**:
@@ -1292,64 +1310,140 @@ and the [LCOV project documentation](https://github.com/linux-test-project/lcov)
repository path if using a new terminal. `make check` runs both QtTest
executables; the standalone tree executable must be run separately.
7. View `html/index.html` in a browser. This workflow produces HTML reports;
the Coco plugin described below uses a different instrumentation toolchain.
it does not require a licensed coverage toolchain.
### Coco integration in Qt Creator
### Configure all build variants in Qt Creator
Coco is a separate licensed toolchain. The Qt Creator plugin alone does not
install CoverageScanner, CoverageBrowser, or activate a Coco license. Obtain a
Coco license or evaluation license and download the Linux installer from
[Qt Account downloads](https://account.qt.io/s/downloads).
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.
For this project's Debian/Ubuntu build, install the compiler, Qt development
tools, and IDE before installing Coco:
The local configuration set uses these independent build directories:
```sh
sudo apt install build-essential qt6-base-dev qt6-base-dev-tools qmake6 qtcreator
# Coco's installer uses locate to discover compilers on Unix:
sudo apt install plocate
sudo updatedb
```
| Configuration | Build directory example | Purpose |
| --- | --- | --- |
| Debug | `/tmp/build/dbc/Desktop-Debug` | Core library and parser/decoder/coverage regression tests |
| Release | `/tmp/build/dbc/Desktop-Release` | The same targets with release settings |
| Profile | `/tmp/build/dbc/Desktop-Profile` | Existing Qt Creator profiling configuration; not code coverage |
| Debug Qt Models | `/tmp/build/dbc/Desktop-Debug-Qt-Models` | Debug targets plus optional adapter and model tests |
| Release Qt Models | `/tmp/build/dbc/Desktop-Release-Qt-Models` | Release targets plus optional adapter and model tests |
| Debug Qt Models Strict | `/tmp/build/dbc/Desktop-Debug-Qt-Models-Strict` | Model build with `QT_FATAL_WARNINGS=1` for builds and runs |
| Coverage | `/tmp/build/dbc/Desktop-Coverage` | Instrumented core/model build, test execution, and LCOV HTML report |
| Core Only | `/tmp/build/dbc/Desktop-Core-Only` | The Qt-free core static library |
| Tree Tests | `/tmp/build/dbc/Desktop-Tree-Tests` | Standalone C++17 tree test without Qt |
| Demo | `/tmp/build/dbc/Desktop-Demo` | Core library and command-line demo |
Install Coco using the actual downloaded filename, for example:
The temporary paths are examples; choose permanent build directories if desired.
Do not share a build directory between these configurations.
```sh
bash /path/to/SquishCocoSetup_VERSION_Linux_x86_64.run
```
To add the ordinary qmake configurations:
The exact filename and supported Linux package depend on the downloaded release.
Coco's own tools come from this installer; `lcov` is not required for Coco.
Installing or configuring a new compiler later requires rerunning the installer
or using `cocosetup` to register the compiler.
1. Open `dbc.pro` with a GCC/Qt 6.8.2 kit.
2. Go to **Projects > Build Settings**. Keep the existing Debug, Release, and
Profile configurations. Remove or disable a Coco build step if one remains.
3. Select Debug, press **Clone**, and name the clone **Debug Qt Models**. Set
its build directory from the table and add `CONFIG+=dbc_qt` to the qmake
step's **Additional arguments**.
4. Clone Release as **Release Qt Models** with the same qmake argument and its
own build directory.
5. Clone Debug Qt Models as **Debug Qt Models Strict**. In **Build Environment**,
add `QT_FATAL_WARNINGS=1`. Run configurations should use the build environment.
6. Clone Debug Qt Models as **Coverage**. In qmake **Additional arguments**, use:
For Coco 7.4 or later, set up and check the Qt License Service using the installed
`cocolic` executable (use its full path if it is not on `PATH`):
```text
CONFIG+=dbc_qt CONFIG+=debug CONFIG-=release "QMAKE_CXXFLAGS+=--coverage -fprofile-abs-path" "QMAKE_LFLAGS+=--coverage"
```
```sh
cocolic --setup-qls
cocolic --check
```
7. For Coverage, select **Add Build Step > Custom Process Step** after qmake
and Make, then set:
Then configure Qt Creator:
| Field | Value |
| --- | --- |
| Command | `/bin/sh` |
| Arguments | `"%{sourceDir}/tests/coverage_report.sh" "%{sourceDir}" "%{buildDir}"` |
| Working directory | `%{buildDir}` |
1. Enable **Coco** in the plugin manager (**Help > About Plugins** on Linux) and
restart Qt Creator if requested. The Debian Qt Creator 16.0.1 package used for
this project's coverage check already includes `libCoco.so`.
2. In **Preferences > Coco**, set the Coco installation directory.
3. Clone **Debug** as **DebugCoco**, with its own build directory. Use an ordinary
Debug configuration as the starting point, without GCC `--coverage` flags.
4. In **Projects > Project Settings > Coco Code Coverage**, enable coverage for
this configuration and save/reconfigure. Depending on the Qt Creator version,
the **Coco code coverage** build step also offers **Enable Coverage**.
5. Exclude test sources and Qt/STL headers as appropriate for a library-only
report. Enable `CONFIG+=dbc_qt` to build the optional model tests.
6. Build using Coco's compiler wrappers, then run both test executables. Use the
Coco plugin's report view or CoverageBrowser to inspect the collected results.
This script compiles the standalone tree test, resets counters, runs both
QtTest executables and the tree test, and generates `%{buildDir}/html/index.html`.
It stops if any test fails. Therefore building Coverage also executes tests.
`lcov` and `genhtml` must be installed. Use this configuration with the GCC kit;
`gcov` and the compiler used for the standalone test must match that kit.
8. Run qmake and build each new configuration once. The default root builds
expose `dbc_tests`; model configurations also expose `dbc_model_tests`.
For qmake, the plugin generates `cocoplugin.prf` in the source directory. Coco
must instrument the library subprojects as well as the test executables.
The GCC/LCOV commands above do not collect Coco data.
Qt Creator expands `%{sourceDir}` and `%{buildDir}` in custom steps to the source
and active build directories. Use the field's variable chooser if needed.
See the official [Coco installation and license setup](https://doc.qt.io/coco/installation.html),
[Coco license requirements](https://doc.qt.io/coco/coco-license-utilization.html),
and [Qt Creator Coco configuration](https://doc.qt.io/qtcreator/creator-coco.html).
For the three independent builds, clone Debug, assign the name and build
directory from the table, and replace its qmake/Make build steps with the custom
process steps below. These steps are local IDE settings and do not change
`dbc.pro`. Give each step a descriptive name and retain the listed order.
For **Core Only**:
| Command | Arguments | Working directory |
| --- | --- | --- |
| `/usr/bin/mkdir` | `-p "%{buildDir}"` | `%{sourceDir}` |
| `/usr/bin/qmake6` | `"%{sourceDir}/core/core.pro" CONFIG+=debug CONFIG-=release` | `%{buildDir}` |
| `/usr/bin/make` | `-j4` | `%{buildDir}` |
Keep a clean step with `make clean` in `%{buildDir}`. Core Only creates a static
library, so there is no executable to run.
For **Tree Tests**:
1. Add a custom step with command `/usr/bin/mkdir`, arguments `-p "%{buildDir}"`,
and working directory `%{sourceDir}`.
2. Add a custom step with command `/usr/bin/c++`, working directory `%{buildDir}`,
and these arguments:
```text
-std=c++17 -O0 -g -I"%{sourceDir}/core" "%{sourceDir}/tests/tree_node_test.cpp" "%{sourceDir}/core/tree_node.cpp" "%{sourceDir}/core/dbc_tree_builder.cpp" -o "%{buildDir}/tree_node_tests"
```
3. Remove the default Make clean step: this direct compiler build creates no
Makefile. Run the resulting executable as described below.
For **Demo**:
| Command | Arguments | Working directory |
| --- | --- | --- |
| `/usr/bin/mkdir` | `-p "%{buildDir}/core" "%{buildDir}/examples"` | `%{sourceDir}` |
| `/usr/bin/qmake6` | `"%{sourceDir}/core/core.pro" CONFIG+=debug CONFIG-=release` | `%{buildDir}/core` |
| `/usr/bin/make` | `-j4` | `%{buildDir}/core` |
| `/usr/bin/qmake6` | `"%{sourceDir}/examples/demo.pro" "DBC_CORE_BUILD_DIR=%{buildDir}/core" CONFIG+=debug CONFIG-=release` | `%{buildDir}/examples` |
| `/usr/bin/make` | `-j4` | `%{buildDir}/examples` |
Replace the default clean step with two custom steps: `/usr/bin/make` with
arguments `clean`, first in `%{buildDir}/examples`, then in `%{buildDir}/core`.
To configure execution and switch variants:
1. Go to **Projects > Run Settings** and select the appropriate qmake target:
`dbc_tests` for ordinary builds or `dbc_model_tests` for model builds.
2. To run all QtTest suites together, add a **Custom Executable** named
**All QtTest suites**, with executable `/usr/bin/make`, arguments `check`,
and working directory `%{buildDir}`. Use it with an ordinary or model qmake
configuration. Coverage already runs every test in its final build step.
3. For Tree Tests, add a **Custom Executable** named **Standalone tree test**,
executable `%{buildDir}/tree_node_tests`, working directory `%{buildDir}`,
and no arguments.
4. For Demo, add a **Custom Executable** named **Demo**, executable
`%{buildDir}/examples/dbc_demo`, working directory `%{buildDir}/examples`.
Set **Command line arguments** to the quoted absolute path of your DBC file.
5. For Coverage on Linux, optionally add a **Custom Executable** named
**Coverage HTML report**, executable `/usr/bin/xdg-open`, arguments
`"%{buildDir}/html/index.html"`, working directory `%{buildDir}`. Running it
opens the generated report in the default browser.
6. Use the kit/build/run selector above the Run button to choose the build
configuration and its corresponding executable. Build with **Ctrl+B**,
then run with **Ctrl+R**. The Build Settings configuration list can also
switch the active build.
7. If `.user` was edited externally, close and reopen the project so Qt Creator
reads the new settings. Do not edit it while the project is open, because
Qt Creator can overwrite external changes when saving its session.
See Qt Creator's [build configuration guide](https://doc.qt.io/qtcreator/creator-build-settings.html)
and [run configuration guide](https://doc.qt.io/qtcreator/creator-run-settings.html).