diff --git a/examples/configuration_component_example/CMakeLists.txt b/examples/configuration_component_example/CMakeLists.txt index b1b1398..7912925 100644 --- a/examples/configuration_component_example/CMakeLists.txt +++ b/examples/configuration_component_example/CMakeLists.txt @@ -24,9 +24,18 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden) # Include link to export directory of SDV V-API development include files location include_directories(${SDV_FRAMEWORK_DEV_INCLUDE}) -# Add the dynamic library +# This component shows how to parse a toml file add_library(configuration_component_example SHARED src/configuration_comp.cpp) # Set extension to .sdv set_target_properties(configuration_component_example PROPERTIES PREFIX "") set_target_properties(configuration_component_example PROPERTIES SUFFIX ".sdv") + + + +# The second component shows that parsing is not required when SDV_PARAM_MAP is used +add_library(configuration_component_example_02 SHARED src/configuration_comp_02.cpp) + +# Set extension to .sdv +set_target_properties(configuration_component_example_02 PROPERTIES PREFIX "") +set_target_properties(configuration_component_example_02 PROPERTIES SUFFIX ".sdv") \ No newline at end of file diff --git a/examples/configuration_component_example/src/configuration_comp.cpp b/examples/configuration_component_example/src/configuration_comp.cpp index eccee7c..796d957 100644 --- a/examples/configuration_component_example/src/configuration_comp.cpp +++ b/examples/configuration_component_example/src/configuration_comp.cpp @@ -120,18 +120,21 @@ public: */ void PrintAllVariables() const { + std::cout << "\n***************************************************" << std::endl; + std::cout << "***** Component with parsing of the toml file *****" << std::endl; + std::cout << "***************************************************" << std::endl; std::cout << "\n----------\nValues from the parameter map:" << std::endl; std::cout << "Expect 7, got " << "initialized value - not changed because not in configuration file: " << std::to_string(m_InitializedValue) << std::endl; std::cout << "Expect 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl; std::cout << "\n----------\nValues parsed in OnInitialize():" << std::endl; std::cout << "Expect 'It's me', got " << "string: " << m_Message.c_str() << std::endl; - std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl; + std::cout << "Expect multiline string: " << m_JSONConfig.c_str() << std::endl; std::cout << "Expect 42, got " << "integer: " << std::to_string(m_Id) << std::endl; std::cout << "Expect 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl; std::cout << "Expect 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl; - std::cout << "Expect 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl; - std::cout << "Expect 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl; - std::cout << "Expect 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl; + std::cout << "Expect 77, got " << "table column a: " << std::to_string(m_TableA) << ", direct access: " << std::to_string(m_DirectTableA) << std::endl; + std::cout << "Expect 1.200000, got " << "table column b: " << std::to_string(m_TableB) << ", direct access: " << std::to_string(m_DirectTableB) << std::endl; + std::cout << "Expect 'this is a string', got " << "table column c: " << m_TableC.c_str() << ", direct access: " << m_DirectTableC.c_str() << std::endl; std::cout << "Expect 1, 2, 3, 5, 7, 11, 13, 17,\n got "; for (auto counter : m_Counters) { diff --git a/examples/configuration_component_example/src/configuration_comp_02.cpp b/examples/configuration_component_example/src/configuration_comp_02.cpp new file mode 100644 index 0000000..f954145 --- /dev/null +++ b/examples/configuration_component_example/src/configuration_comp_02.cpp @@ -0,0 +1,89 @@ + /******************************************************************************** + * Copyright (c) 2025-2026 ZF Friedrichshafen AG + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + +#include +#include +#include + +class DemoConfigurationComponent02 : public sdv::CSdvObject +{ +public: + DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device) + DECLARE_OBJECT_CLASS_NAME("Configuration_Example_02") + + // Parameter map + BEGIN_SDV_PARAM_MAP() + SDV_PARAM_ENABLE_LOCKING() // Parameters will be protected against writing when locked (e.g. after initialization). + SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.") + SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.") + SDV_PARAM_ENTRY(m_Message, "Message", "", "", "Example of type string.") + SDV_PARAM_ENTRY(m_JSONConfig, "JSONConfig", "", "", "Example of type string.") + SDV_PARAM_ENTRY(m_Id, "Id", 0, "", "Example of type unsigned int.") + SDV_PARAM_ENTRY(m_Pi, "Pi", 0.0f, "", "Example of type float.") + SDV_PARAM_ENTRY(m_IsValid, "Boolean", 0, "", "Example of type bool.") + SDV_PARAM_ENTRY(m_DirectTableA, "Table.a", 0, "", "Example of type unsigned int within a table.") + SDV_PARAM_ENTRY(m_DirectTableB, "Table.b", 0.0, "", "Example of type float within a table.") + SDV_PARAM_ENTRY(m_DirectTableC, "Table.c", "", "", "Example of type string within a table.") + END_SDV_PARAM_MAP() + + /** + * @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize. + * @return Returns 'true' when the initialization was successful, 'false' when not. + */ + virtual bool OnInitialize() override + { + PrintAllVariables(); + + return true; + }; + + /** + * @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown. + */ + virtual void OnShutdown() override + { + } + + /** + * @brief Print all global variables to console + */ + void PrintAllVariables() const + { + std::cout << "\n****************************************" << std::endl; + std::cout << "***** Component 2, without parsing *****" << std::endl; + std::cout << "****************************************" << std::endl; + std::cout << "\n----------\nValues from the parameter map:" << std::endl; + std::cout << "Expect 7, got " << "initialized value - not changed because not in configuration file: " << std::to_string(m_InitializedValue) << std::endl; + std::cout << "Expect 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl; + std::cout << "Expect 'It's me', got " << "string: " << m_Message.c_str() << std::endl; + std::cout << "Expect multiline string: " << m_JSONConfig.c_str() << std::endl; + std::cout << "Expect 42, got " << "integer: " << std::to_string(m_Id) << std::endl; + std::cout << "Expect 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl; + std::cout << "Expect 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl; + std::cout << "Expect 77, got " << "table column a: " << std::to_string(m_DirectTableA) << std::endl; + std::cout << "Expect 1.200000, got " << "table column b: " << std::to_string(m_DirectTableB) << std::endl; + std::cout << "Expect 'this is a string', got " << "table column c: " << m_DirectTableC.c_str() << std::endl; + std::cout << std::endl; + } + + private: + std::string m_Message { "" }; + std::string m_JSONConfig { "" }; + int32_t m_Id { -1 }; + float m_Pi { 0.0 }; + bool m_IsValid { false }; + uint32_t m_DirectTableA { 0 }; + float m_DirectTableB { 0.0 }; + std::string m_DirectTableC { "" }; + uint32_t m_InitializedValue { 0 }; + uint32_t m_UpdatableValue { 0 }; +}; + +DEFINE_SDV_OBJECT(DemoConfigurationComponent02) diff --git a/examples/configuration_example/config/test_configuration_example.toml b/examples/configuration_example/config/test_configuration_example.toml index 0ae7cf5..c18bbd2 100644 --- a/examples/configuration_example/config/test_configuration_example.toml +++ b/examples/configuration_example/config/test_configuration_example.toml @@ -19,3 +19,20 @@ Boolean = true Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ] Table = { a = 77, b = 1.2, c = "this is a string" } +[[Component]] +Path = "configuration_component_example_02.sdv" +Class = "Configuration_Example_02" +[Component.Parameters] +updatableValue = 13 +Message = "It's me" +### the following is a valid JSON structure in a muliline string +JSONConfig = """{ + "Logging": { + "Sinks": [ { "Type": "Stdout", "Level": "Info" } ] + }, + }""" +Id = 42 +Pi = 3.1415926 +Boolean = true +Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ] +Table = { a = 77, b = 1.2, c = "this is a string" } \ No newline at end of file diff --git a/sdv_executables/sdv_packager/environment.cpp b/sdv_executables/sdv_packager/environment.cpp index 96030ff..ef57ceb 100644 --- a/sdv_executables/sdv_packager/environment.cpp +++ b/sdv_executables/sdv_packager/environment.cpp @@ -414,6 +414,10 @@ void CSdvPackagerEnvironment::ReportInfo() const if (!m_pathPackage.empty()) rstreamVerbose << "Package: " << m_pathPackage.generic_u8string() << std::endl; break; + case EOperatingMode::configure: + rstreamNormal << "Configure system..." << std::endl; + break; + default: rstreamNormal << "Nothing to do..." << std::endl; break; @@ -969,6 +973,7 @@ bool CSdvPackagerEnvironment::ProcessCommandLine(const std::vector& fnGetProduct(); break; case EOperatingMode::configure: + if (!fnCheckSourceLocation()) return false; if (!fnGetConfigFiles()) return false; if (!fnConfigTargets()) return false; break; diff --git a/sdv_executables/sdv_packager/packager.cpp b/sdv_executables/sdv_packager/packager.cpp index 544f126..de03560 100644 --- a/sdv_executables/sdv_packager/packager.cpp +++ b/sdv_executables/sdv_packager/packager.cpp @@ -364,6 +364,9 @@ bool CPackager::Configure() } } + // CHANGE EVE 13.04.2026: Disabled this check. Unclear if necessary. + std::filesystem::path pathBaseSearch; + // If the pattern is defined using an absolute path, this path needs to correspond with the base path. std::filesystem::path pathConfigFile(ssSearchString); if (pathConfigFile.is_absolute()) @@ -374,19 +377,23 @@ bool CPackager::Configure() { if (itConfigPart == pathConfigFile.end() || *itBasePart != *itConfigPart) { - m_nError = CMDLN_SOURCE_LOCATION_ERROR; - m_ssArgError = CMDLN_SOURCE_LOCATION_ERROR_MSG; - return false; + //m_nError = CMDLN_SOURCE_LOCATION_ERROR; + //m_ssArgError = CMDLN_SOURCE_LOCATION_ERROR_MSG; + //return false; + break; } + pathBaseSearch /= *itBasePart; // Next part itBasePart++; itConfigPart++; } } + else + pathBaseSearch = pathBasePath; // Get the list of files - auto vecFiles = CollectWildcardPath(pathBasePath, ssSearchString, eAlgorithm); + auto vecFiles = CollectWildcardPath(pathBaseSearch, ssSearchString, eAlgorithm); // For each file, check whether the file is somewhere within the base path (if provided) and add the file to the file list. for (const std::filesystem::path& rpathFile : vecFiles) @@ -397,7 +404,7 @@ bool CPackager::Configure() continue; // Add the file - vecConfigFiles.push_back(rpathFile); + vecConfigFiles.push_back(pathBaseSearch / rpathFile); } } diff --git a/sdv_services/uds_win_sockets/connection.h b/sdv_services/uds_win_sockets/connection.h index 340fe6c..87a2064 100644 --- a/sdv_services/uds_win_sockets/connection.h +++ b/sdv_services/uds_win_sockets/connection.h @@ -35,7 +35,6 @@ # endif #endif - /// @brief Legacy framing markers for the old message header (not used by SDV envelope) constexpr uint32_t m_MsgStart = 0x01020304; ///< Value to mark the start of the legacy message header constexpr uint32_t m_MsgEnd = 0x05060708; ///< Value to mark the end of the legacy message header