From 57da1f7aa29c09828a9835c02f4d9f8f69dcd3ad Mon Sep 17 00:00:00 2001 From: Stefan Gerlach Date: Fri, 10 May 2024 00:08:14 +0200 Subject: [PATCH 01/14] Update CMakeLists.txt (#26) Fix CMake error "install DIRECTORY given no DESTINATION!" --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf2d37..ea27c35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,7 @@ if(DBC_GENERATE_SINGLE_HEADER) endif() ## Installation +include(GNUInstallDirs) # install lib install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) From f08e688e6162fa227f0367d591ce9e15d99e7ee4 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:32:38 -0400 Subject: [PATCH 02/14] fix: Set the ubuntu runner to 22.04 to keep the same compiler version Probably should setup the job to setup the gcc version instead but for now this works. --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 49c3b6e..bb94b75 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -9,7 +9,7 @@ env: jobs: linux-builds: name: linux ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: From eea0184f4d919d364bec5b9b27e9d42f6121ec9c Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:40:13 -0400 Subject: [PATCH 03/14] fix(CI): Bump gcc to 14, add debug print, and set the mac os to 12 --- .github/workflows/pipeline.yml | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index bb94b75..29e1951 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -14,13 +14,13 @@ jobs: fail-fast: false matrix: cxx: - - g++-13 + - g++-14 - clang++-16 build_type: [Debug, Release] std: [11] include: - - cxx: g++-13 - cc: gcc-13 + - cxx: g++-14 + cc: gcc-14 - cxx: clang++-16 cc: clang-16 llvm_version: 16 @@ -48,6 +48,11 @@ jobs: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source "$HOME/.cargo/env" + - name: Print gcc version + run: | + which gcc + gcc --version + - name: Configure build env: CC: ${{matrix.cc}} @@ -114,7 +119,7 @@ jobs: macos-builds: name: macos ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} - runs-on: macos-latest + runs-on: macos-12 strategy: fail-fast: false matrix: From c79a284ccf68947818130f467c50d02716244b24 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:41:56 -0400 Subject: [PATCH 04/14] fix(CI): Change gcc to 11 which is default installed on ubuntu 22 --- .github/workflows/pipeline.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 29e1951..cc0cf9e 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -14,13 +14,13 @@ jobs: fail-fast: false matrix: cxx: - - g++-14 + - g++-11 - clang++-16 build_type: [Debug, Release] std: [11] include: - - cxx: g++-14 - cc: gcc-14 + - cxx: g++-11 + cc: gcc-11 - cxx: clang++-16 cc: clang-16 llvm_version: 16 @@ -49,9 +49,7 @@ jobs: source "$HOME/.cargo/env" - name: Print gcc version - run: | - which gcc - gcc --version + run: gcc --version - name: Configure build env: From a58f04c0448ba71d9b725fb3a2119df0f35d425b Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:49:33 -0400 Subject: [PATCH 05/14] feat(CI): Run cmake install for all OS --- .github/workflows/pipeline.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index cc0cf9e..881138c 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -73,6 +73,10 @@ jobs: CTEST_OUTPUT_ON_FAILURE: 1 run: ctest --output-on-failure --test-dir build -j `nproc` + - name: Run install + run: cmake --install . + + windows-build: name: ${{matrix.os}}, ${{matrix.std}}, ${{matrix.build_type}}, ${{matrix.platform}} runs-on: ${{matrix.os}} @@ -115,6 +119,9 @@ jobs: run: ctest --output-on-failure --test-dir build -j %NUMBER_OF_PROCESSORS% shell: cmd + - name: Run install + run: cmake --install . + macos-builds: name: macos ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} runs-on: macos-12 @@ -162,6 +169,9 @@ jobs: working-directory: ${{runner.workspace}} run: ctest --output-on-failure --test-dir build -j `sysctl -n hw.ncpu` -V + - name: Run install + run: cmake --install . + format-check: runs-on: ubuntu-latest From 2e974178f598e615f65a6ad1a00f7d926823deb2 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:53:50 -0400 Subject: [PATCH 06/14] fix(CI): fix the cmake build path for the install command --- .github/workflows/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 881138c..15f21e4 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -74,7 +74,7 @@ jobs: run: ctest --output-on-failure --test-dir build -j `nproc` - name: Run install - run: cmake --install . + run: cmake --install build windows-build: @@ -120,7 +120,7 @@ jobs: shell: cmd - name: Run install - run: cmake --install . + run: cmake --install build macos-builds: name: macos ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} @@ -170,7 +170,7 @@ jobs: run: ctest --output-on-failure --test-dir build -j `sysctl -n hw.ncpu` -V - name: Run install - run: cmake --install . + run: cmake --install build format-check: runs-on: ubuntu-latest From 6d6288550fb0226c8b9c65a69c6421b25f4ab42f Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Tue, 21 May 2024 17:58:04 -0400 Subject: [PATCH 07/14] fix(CI): In the pipeline we only can install on linux and need to pass the prefix to avoid permission issues --- .github/workflows/pipeline.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 15f21e4..f36b26d 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -74,7 +74,7 @@ jobs: run: ctest --output-on-failure --test-dir build -j `nproc` - name: Run install - run: cmake --install build + run: cmake --install build --prefix . windows-build: @@ -119,9 +119,6 @@ jobs: run: ctest --output-on-failure --test-dir build -j %NUMBER_OF_PROCESSORS% shell: cmd - - name: Run install - run: cmake --install build - macos-builds: name: macos ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} runs-on: macos-12 @@ -169,9 +166,6 @@ jobs: working-directory: ${{runner.workspace}} run: ctest --output-on-failure --test-dir build -j `sysctl -n hw.ncpu` -V - - name: Run install - run: cmake --install build - format-check: runs-on: ubuntu-latest From 0dbe4541e99b81049ef7109d1670e37a67b41a8a Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Sun, 26 May 2024 16:38:42 -0400 Subject: [PATCH 08/14] feat: Parse dbc with istream (#30) * feat: Add an istream interface to the avoid the ifstream creation given a file name * fix: formatting the code base to fix checks and clang-tidy errors --- include/libdbc/dbc.hpp | 4 +++- src/dbc.cpp | 19 +++++++++------ .../test_single_header.cpp | 24 +++++++++++++++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/include/libdbc/dbc.hpp b/include/libdbc/dbc.hpp index 2dfe7bf..5e0e9e4 100644 --- a/include/libdbc/dbc.hpp +++ b/include/libdbc/dbc.hpp @@ -15,6 +15,7 @@ class Parser { virtual ~Parser() = default; virtual void parse_file(const std::string& file) = 0; + virtual void parse_file(std::istream& file) = 0; protected: }; @@ -23,7 +24,8 @@ class DbcParser : public Parser { public: DbcParser(); - void parse_file(const std::string& file) override; + void parse_file(const std::string& file_name) override; + void parse_file(std::istream& stream) override; std::string get_version() const; std::vector get_nodes() const; diff --git a/src/dbc.cpp b/src/dbc.cpp index 108ab7e..c6baae5 100644 --- a/src/dbc.cpp +++ b/src/dbc.cpp @@ -70,18 +70,12 @@ DbcParser::DbcParser() + whiteSpace + receiverPattern) { } -void DbcParser::parse_file(const std::string& file) { - std::ifstream stream(file.c_str()); +void DbcParser::parse_file(std::istream& stream) { std::string line; std::vector lines; messages.clear(); - auto extension = get_extension(file); - if (extension != ".dbc") { - throw NonDbcFileFormatError(file, extension); - } - parse_dbc_header(stream); parse_dbc_nodes(stream); @@ -93,6 +87,17 @@ void DbcParser::parse_file(const std::string& file) { parse_dbc_messages(lines); } +void DbcParser::parse_file(const std::string& file_name) { + auto extension = get_extension(file_name); + if (extension != ".dbc") { + throw NonDbcFileFormatError(file_name, extension); + } + + std::ifstream stream(file_name.c_str()); + + parse_file(stream); +} + std::string DbcParser::get_extension(const std::string& file_name) { std::size_t dot = file_name.find_last_of("."); if (dot != std::string::npos) { diff --git a/test/single_header_testing/test_single_header.cpp b/test/single_header_testing/test_single_header.cpp index e4abc6c..c512d35 100644 --- a/test/single_header_testing/test_single_header.cpp +++ b/test/single_header_testing/test_single_header.cpp @@ -54,3 +54,27 @@ TEST_CASE("Testing big endian, little endian") { REQUIRE(signal.is_bigendian == false); } } + +TEST_CASE("Testing file stream mirrors the filename interface") { + std::string dbc_contents = PRIMITIVE_DBC + R"(BO_ 234 MSG1: 8 Vector__XXX + SG_ Sig1 : 55|16@0- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX + SG_ Sig2 : 39|16@1- (0.1,0) [-3276.8|-3276.7] "C" Vector__XXX)"; + const auto filename = create_temporary_dbc_with(dbc_contents.c_str()); + std::ifstream file(filename.c_str()); + + auto parser = Libdbc::DbcParser(); + parser.parse_file(file); + + REQUIRE(parser.get_messages().size() == 1); + REQUIRE(parser.get_messages().at(0).name() == "MSG1"); + REQUIRE(parser.get_messages().at(0).size() == 8); + REQUIRE(parser.get_messages().at(0).get_signals().size() == 2); + { + const auto signal = parser.get_messages().at(0).get_signals().at(0); + REQUIRE(signal.is_bigendian == true); + } + { + const auto signal = parser.get_messages().at(0).get_signals().at(1); + REQUIRE(signal.is_bigendian == false); + } +} From 1bfead321ec4f10a5dd371c8d05769da6a0a78a2 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Sun, 26 May 2024 16:45:59 -0400 Subject: [PATCH 09/14] fix: Crashed when BO_ and the message content were on different lines --- src/dbc.cpp | 4 ++-- test/test_parse_message.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/dbc.cpp b/src/dbc.cpp index 108ab7e..f19fe25 100644 --- a/src/dbc.cpp +++ b/src/dbc.cpp @@ -176,7 +176,7 @@ void DbcParser::parse_dbc_messages(const std::vector& lines) { continue; } - if (std::regex_search(line, match, signal_re)) { + if (std::regex_search(line, match, signal_re) && messages.size() > 0) { std::string name = match.str(SIGNAL_NAME_GROUP); bool is_multiplexed = false; // No support yet uint32_t start_bit = static_cast(std::stoul(match.str(SIGNAL_START_BIT_GROUP))); @@ -199,7 +199,7 @@ void DbcParser::parse_dbc_messages(const std::vector& lines) { continue; } - if (std::regex_search(line, match, value_re)) { + if (std::regex_search(line, match, value_re) && messages.size() > 0) { uint32_t message_id = static_cast(std::stoul(match.str(2))); std::string signal_name = match.str(3); diff --git a/test/test_parse_message.cpp b/test/test_parse_message.cpp index aad3b1c..08d68f3 100644 --- a/test/test_parse_message.cpp +++ b/test/test_parse_message.cpp @@ -173,3 +173,39 @@ TEST_CASE("Parse Message data length < 8 unsigned") { REQUIRE(Catch::Approx(result_values.at(0)) == 0x1); REQUIRE(Catch::Approx(result_values.at(1)) == 0x2); } + +TEST_CASE("Parse message with BO_ on single line should fail.") { + std::string dbc_contents = PRIMITIVE_DBC + R"(BO_ +234 MSG1: 8 Vector__XXX + SG_ State1 : 0|8@1+ (1,0) [0|200] "Km/h" DEVICE1,DEVICE2,DEVICE3 + SG_ State2 : 0|8@1+ (1,0) [0|204] "" DEVICE1,DEVICE2,DEVICE3 +VAL_ 234 State1 123 "Description 1" 0 "Description 2" 90903489 "Big value and special characters &$§())!")"; + const auto filename = create_temporary_dbc_with(dbc_contents.c_str()); + + Libdbc::DbcParser p; + p.parse_file(filename); + + std::vector data{0x1, 0x2}; + std::vector result_values; + REQUIRE(p.get_messages().size() == 0); + REQUIRE(p.parse_message(234, data, result_values) == Libdbc::Message::ParseSignalsStatus::ErrorUnknownID); +} + +TEST_CASE("Parse signal with SG_ on single line should fail.") { + std::string dbc_contents = PRIMITIVE_DBC + R"(BO_ 234 MSG1: 8 Vector__XXX + SG_ +State1 : 0|8@1+ (1,0) [0|200] "Km/h" DEVICE1,DEVICE2,DEVICE3 + SG_ State2 : 0|8@1+ (1,0) [0|204] "" DEVICE1,DEVICE2,DEVICE3 +VAL_ 234 State1 123 "Description 1" 0 "Description 2" 90903489 "Big value and special characters &$§())!")"; + const auto filename = create_temporary_dbc_with(dbc_contents.c_str()); + + Libdbc::DbcParser p; + p.parse_file(filename); + + std::vector data{0x1, 0x2}; + std::vector result_values; + REQUIRE(p.get_messages().size() == 1); + REQUIRE(p.parse_message(234, data, result_values) == Libdbc::Message::ParseSignalsStatus::Success); + REQUIRE(result_values.size() == 1); + REQUIRE(Catch::Approx(result_values.at(0)) == 0x1); +} From ceeef752101dccfa045106592f17dedaf64c9656 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Thu, 27 Jun 2024 18:17:25 -0400 Subject: [PATCH 10/14] fix(checks): Fixing clang warnings about size comparison on the vector. Should have been just a empty check. --- src/dbc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dbc.cpp b/src/dbc.cpp index 2d999da..89e8c24 100644 --- a/src/dbc.cpp +++ b/src/dbc.cpp @@ -181,7 +181,7 @@ void DbcParser::parse_dbc_messages(const std::vector& lines) { continue; } - if (std::regex_search(line, match, signal_re) && messages.size() > 0) { + if (std::regex_search(line, match, signal_re) && !messages.empty()) { std::string name = match.str(SIGNAL_NAME_GROUP); bool is_multiplexed = false; // No support yet uint32_t start_bit = static_cast(std::stoul(match.str(SIGNAL_START_BIT_GROUP))); @@ -204,7 +204,7 @@ void DbcParser::parse_dbc_messages(const std::vector& lines) { continue; } - if (std::regex_search(line, match, value_re) && messages.size() > 0) { + if (std::regex_search(line, match, value_re) && !messages.empty()) { uint32_t message_id = static_cast(std::stoul(match.str(2))); std::string signal_name = match.str(3); From 887d779fbf416032f539675f74360a5a43a93f86 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Thu, 27 Jun 2024 18:19:17 -0400 Subject: [PATCH 11/14] chore(version): Version bump to v0.5.0 --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea27c35..551af92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) # Keep this on one line for release checking -project(dbc VERSION 0.4.0 DESCRIPTION "C++ DBC Parser") +project(dbc VERSION 0.5.0 DESCRIPTION "C++ DBC Parser") # -- PROJECT OPTIONS -- # option(DBC_ENABLE_TESTS "Enable Unittests" ON) @@ -95,7 +95,6 @@ if(DBC_GENERATE_SINGLE_HEADER) endif() ## Installation -include(GNUInstallDirs) # install lib install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) From 17b3e3dd121f3dc13f07a3cc0d9a19ce7b138ece Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Wed, 10 Sep 2025 21:52:33 -0400 Subject: [PATCH 12/14] Add manual workflow dispatch to CI pipeline --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index f36b26d..0947cd6 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,6 +1,6 @@ name: Libdbc Pipeline -on: [push, workflow_call] +on: [push, workflow_call, workflow_dispatch] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) From 316686831a1a064fedebdd77f8fd4e6d9b183db3 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Wed, 10 Sep 2025 21:54:48 -0400 Subject: [PATCH 13/14] Enable pull_request to trigger CI pipeline --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 0947cd6..d24e09a 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,6 +1,6 @@ name: Libdbc Pipeline -on: [push, workflow_call, workflow_dispatch] +on: [push, pull_request, workflow_call, workflow_dispatch] env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) From 2c8acdbd2d1ea33545f99f9a0d23e10b7f8e0852 Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Fri, 12 Sep 2025 10:29:36 -0400 Subject: [PATCH 14/14] Update windows runner to 2025 and mac runners to 15 (#35) --- .github/workflows/pipeline.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index d24e09a..3f96f40 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -83,7 +83,7 @@ jobs: strategy: fail-fast: false matrix: - os: [windows-2019, windows-2022] + os: [windows-2025, windows-2022] platform: [Win32, x64] build_type: [Debug, Release] std: [11] @@ -120,11 +120,12 @@ jobs: shell: cmd macos-builds: - name: macos ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} - runs-on: macos-12 + name: ${{matrix.os}}, ${{matrix.cxx}}, C++${{matrix.std}}, ${{matrix.build_type}} + runs-on: ${{matrix.os}} strategy: fail-fast: false matrix: + os: [macos-15-large] cxx: - g++ - clang++