From b11767260edcab52afb53bcefb95358e23f6db6c Mon Sep 17 00:00:00 2001 From: Michael D Starch Date: Wed, 29 Jan 2025 17:11:49 -0800 Subject: [PATCH 1/5] Making string formatting into a fprime implementation choice --- Fw/Types/CMakeLists.txt | 6 +++++ Fw/Types/StringBase.cpp | 32 ++++--------------------- Fw/Types/StringBase.hpp | 10 +------- Fw/Types/format.hpp | 46 ++++++++++++++++++++++++++++++++++++ Fw/Types/snprintf_format.cpp | 34 ++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 37 deletions(-) create mode 100644 Fw/Types/format.hpp create mode 100644 Fw/Types/snprintf_format.cpp diff --git a/Fw/Types/CMakeLists.txt b/Fw/Types/CMakeLists.txt index 6c3c54334f..87ad8a3917 100644 --- a/Fw/Types/CMakeLists.txt +++ b/Fw/Types/CMakeLists.txt @@ -23,6 +23,7 @@ set(MOD_DEPS Fw/Cfg ) register_fprime_module() +require_fprime_implementation("Fw_StringFormat") ### UTs ### set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/test/ut/ExternalSerializeBufferTest.cpp" @@ -35,3 +36,8 @@ register_fprime_ut() # Non-test directory add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/GTest") + +# Create an empty interface library and use it to register an implementation +add_library(snprintf-format INTERFACE) +register_fprime_implementation(Fw_StringFormat snprintf-format "${CMAKE_CURRENT_LIST_DIR}/snprintf_format.cpp") +choose_fprime_implementation(Fw_StringFormat snprintf-format "${FPRIME_PLATFORM}") # Default choice is snprintf diff --git a/Fw/Types/StringBase.cpp b/Fw/Types/StringBase.cpp index b86effa3e9..81d222743b 100644 --- a/Fw/Types/StringBase.cpp +++ b/Fw/Types/StringBase.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include namespace Fw { @@ -65,33 +64,10 @@ FormatStatus StringBase::vformat(const CHAR* formatString, va_list args) { CHAR* us = const_cast(this->toChar()); SizeType cap = this->getCapacity(); FW_ASSERT(us != nullptr); - - // Check format string - if (formatString == nullptr) { - return FormatStatus::INVALID_FORMAT_STRING; - } - FwSizeType total_needed_size = 0; -#if FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING - // Check that the API size type fits in fprime size type - static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), - "Range of PlatformIntType does not fit within range of FwSizeType"); - PlatformIntType total_needed_size_api = vsnprintf(us, cap, formatString, args); - // Check for error return, or a type overflow - if (total_needed_size_api < 0) { - return FormatStatus::OTHER_ERROR; - } - total_needed_size = static_cast(total_needed_size_api); -#else - total_needed_size = StringUtils::string_length(format_string, cap); - *this = formatString; -#endif - // Force null terminate - us[cap - 1] = 0; - // Check for overflow - if (total_needed_size >= cap) { - return FormatStatus::OVERFLOWED; - } - return FormatStatus::SUCCESS; + // Needed until SizeType an FwSizeType are the same + static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), + "String size type must fit into FwSizeType"); + return Fw::stringFormat(us, static_cast(cap), formatString, args); } bool StringBase::operator!=(const StringBase& other) const { diff --git a/Fw/Types/StringBase.hpp b/Fw/Types/StringBase.hpp index 82df7def28..6290386afe 100644 --- a/Fw/Types/StringBase.hpp +++ b/Fw/Types/StringBase.hpp @@ -12,7 +12,7 @@ #ifndef FW_STRING_BASE_HPP #define FW_STRING_BASE_HPP - +#include #include #include #include @@ -22,14 +22,6 @@ namespace Fw { -//! \brief status of format -enum class FormatStatus { - SUCCESS, //!< Format worked - OVERFLOWED, //!< Format overflowed - INVALID_FORMAT_STRING, //!< Format provided invalid format string - OTHER_ERROR //!< An error was returned from an underlying call -}; - class StringBase : public Serializable { public: using SizeType = NATIVE_UINT_TYPE; diff --git a/Fw/Types/format.hpp b/Fw/Types/format.hpp new file mode 100644 index 0000000000..407227087e --- /dev/null +++ b/Fw/Types/format.hpp @@ -0,0 +1,46 @@ +// ====================================================================== +// \title format.hpp +// \author mstarch +// \brief hpp file for c-string format function +// +// \copyright +// Copyright (C) 2025 California Institute of Technology. +// ALL RIGHTS RESERVED. United States Government Sponsorship +// acknowledged. +// ====================================================================== +#ifndef FW_TYPES_FORMAT_HPP_ +#define FW_TYPES_FORMAT_HPP_ +#include +#include +namespace Fw { + +//! \brief status of string format calls +enum class FormatStatus { + SUCCESS, //!< Format worked + OVERFLOWED, //!< Format overflowed + INVALID_FORMAT_STRING, //!< Format provided invalid format string + SIZE_OVERFLOW, //!< FwSizeType overflowed the range of size_t + OTHER_ERROR //!< An error was returned from an underlying call +}; + +//! \brief format a c-string +//! +//! Format a string using printf family formatting semantics. Destination will be filled with the formatted string up to +//! maximumSize - 1. This function will always terminate the string with a \0. +//! +//! This function can return several error codes: +//! OVERFLOWED: the complete string did not fit in the buffer with an appended null-terminator +//! INVALID_FORMAT_STRING: the format string was null +//! OTHER_ERROR: another error occurred in an underlying function call +//! Otherwise SUCCESS is returned. destination may be modified even in the case of an error. +//! +//! \param destination: destination to fill with the formatted string. +//! \param maximumSize: size of the buffer represented by destination +//! \param formatString: format string to fill +//! \param args: variable arguments. +//! \return: SUCCESS on successful formatting, OVERFLOWED on overflow, and something else on any error +FormatStatus stringFormat(char* destination, const FwSizeType maximumSize, const char* formatString, va_list args); +} +#endif // FW_TYPES_FORMAT_HPP_ + + diff --git a/Fw/Types/snprintf_format.cpp b/Fw/Types/snprintf_format.cpp new file mode 100644 index 0000000000..8681bce39c --- /dev/null +++ b/Fw/Types/snprintf_format.cpp @@ -0,0 +1,34 @@ +// ====================================================================== +// \title format.cpp +// \author mstarch +// \brief cpp file for c-string format function as a implementation using snprintf +// +// \copyright +// Copyright (C) 2025 California Institute of Technology. +// ALL RIGHTS RESERVED. United States Government Sponsorship +// acknowledged. +// ====================================================================== +#include +#include +#include + +Fw::FormatStatus Fw::stringFormat(char* destination, const FwSizeType maximumSize, const char* formatString, va_list args) { + Fw::FormatStatus formatStatus = Fw::FormatStatus::SUCCESS; + // Check format string + if (formatString == nullptr) { + formatStatus = Fw::FormatStatus::INVALID_FORMAT_STRING; + } + // Must allow the compiler to choose the correct type for comparison + else if (maximumSize > std::numeric_limits::max()) { + formatStatus = Fw::FormatStatus::SIZE_OVERFLOW; + } else { + PlatformIntType needed_size = vsnprintf(destination, static_cast(maximumSize), formatString, args); + destination[maximumSize - 1] = 0; // Force null-termination + if (needed_size < 0) { + formatStatus = Fw::FormatStatus::OTHER_ERROR; + } else if (static_cast(needed_size) >= maximumSize) { + formatStatus = Fw::FormatStatus::OVERFLOWED; + } + } + return formatStatus; +} \ No newline at end of file From 5aa6308704d280d40e47f058d07555507dc5a710 Mon Sep 17 00:00:00 2001 From: Michael D Starch Date: Wed, 29 Jan 2025 18:24:22 -0800 Subject: [PATCH 2/5] Removing printf from Fw and cleaning-up toString methods --- Fw/Buffer/Buffer.hpp | 1 - Fw/Comp/ActiveComponentBase.cpp | 16 ++++--------- Fw/Comp/ActiveComponentBase.hpp | 2 +- Fw/Comp/PassiveComponentBase.cpp | 19 +++++++++++---- Fw/Comp/PassiveComponentBase.hpp | 5 +++- Fw/Comp/QueuedComponentBase.cpp | 15 ++++-------- Fw/Comp/QueuedComponentBase.hpp | 2 +- Fw/Obj/ObjBase.cpp | 7 +++--- Fw/Port/InputPortBase.cpp | 14 ++--------- Fw/Port/InputPortBase.hpp | 4 ++-- Fw/Port/InputSerializePort.cpp | 12 ++-------- Fw/Port/InputSerializePort.hpp | 6 ++--- Fw/Port/OutputPortBase.cpp | 13 ++-------- Fw/Port/OutputPortBase.hpp | 4 ++-- Fw/Port/OutputSerializePort.cpp | 12 ++-------- Fw/Port/OutputSerializePort.hpp | 6 ++--- Fw/Port/PortBase.cpp | 35 +++++++++++++++++++++++---- Fw/Port/PortBase.hpp | 4 +++- Fw/Types/Assert.cpp | 23 +++++++++--------- Fw/Types/PolyType.cpp | 41 +++++++++++++++----------------- 20 files changed, 113 insertions(+), 128 deletions(-) diff --git a/Fw/Buffer/Buffer.hpp b/Fw/Buffer/Buffer.hpp index f24e7971a5..82c92357d5 100644 --- a/Fw/Buffer/Buffer.hpp +++ b/Fw/Buffer/Buffer.hpp @@ -16,7 +16,6 @@ #include #if FW_SERIALIZABLE_TO_STRING #include - #include // snprintf #ifdef BUILD_UT #include #include diff --git a/Fw/Comp/ActiveComponentBase.cpp b/Fw/Comp/ActiveComponentBase.cpp index d5bbd8c7a4..e0cb49f519 100644 --- a/Fw/Comp/ActiveComponentBase.cpp +++ b/Fw/Comp/ActiveComponentBase.cpp @@ -2,7 +2,6 @@ #include #include #include -#include namespace Fw { @@ -38,14 +37,9 @@ namespace Fw { QueuedComponentBase::init(instance); } -#if FW_OBJECT_TO_STRING == 1 && FW_OBJECT_NAMES == 1 - void ActiveComponentBase::toString(char* buffer, NATIVE_INT_TYPE size) { - FW_ASSERT(size > 0); - FW_ASSERT(buffer != nullptr); - PlatformIntType status = snprintf(buffer, static_cast(size), "ActComp: %s", this->m_objName.toChar()); - if (status < 0) { - buffer[0] = 0; - } +#if FW_OBJECT_TO_STRING == 1 + const char* ActiveComponentBase::getToStringFormatString() { + return "ActComp: %s"; } #endif @@ -55,9 +49,7 @@ namespace Fw { #if FW_OBJECT_NAMES == 1 taskName = this->getObjName(); #else - char taskNameChar[FW_TASK_NAME_BUFFER_SIZE]; - (void)snprintf(taskNameChar,sizeof(taskNameChar),"ActComp_%" PRI_FwSizeType,Os::Task::getNumTasks()); - taskName = taskNameChar; + (void) taskName.format("ActComp_%" PRI_FwSizeType, Os::Task::getNumTasks()); #endif // Cooperative threads tasks externalize the task loop, and as such use the state machine as their task function // Standard multithreading tasks use the task loop to respectively call the state machine diff --git a/Fw/Comp/ActiveComponentBase.hpp b/Fw/Comp/ActiveComponentBase.hpp index d9ee8d3ccf..feed74ec8a 100644 --- a/Fw/Comp/ActiveComponentBase.hpp +++ b/Fw/Comp/ActiveComponentBase.hpp @@ -50,7 +50,7 @@ class ActiveComponentBase : public QueuedComponentBase { Os::Task m_task; //!< task object for active component #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); //!< create string description of component + virtual const char* getToStringFormatString(); //!< Format string for toString function #endif PRIVATE: Lifecycle m_stage; //!< Lifecycle stage of the component diff --git a/Fw/Comp/PassiveComponentBase.cpp b/Fw/Comp/PassiveComponentBase.cpp index 1e3b504c67..a73e9f23e2 100644 --- a/Fw/Comp/PassiveComponentBase.cpp +++ b/Fw/Comp/PassiveComponentBase.cpp @@ -2,19 +2,30 @@ #include #include -#include +#include namespace Fw { PassiveComponentBase::PassiveComponentBase(const char* name) : Fw::ObjBase(name), m_idBase(0), m_instance(0) { } -#if FW_OBJECT_TO_STRING == 1 && FW_OBJECT_NAMES == 1 +#if FW_OBJECT_TO_STRING == 1 + const char* getToStringFormatString() { + return "Comp: %s"; + } + void PassiveComponentBase::toString(char* buffer, NATIVE_INT_TYPE size) { FW_ASSERT(size > 0); FW_ASSERT(buffer != nullptr); - PlatformIntType status = snprintf(buffer, static_cast(size), "Comp: %s", this->m_objName.toChar()); - if (status < 0) { + Fw::FormatStatus status = Fw::ExternalString(buffer, static_cast(size)).format( + this->getToStringFormatString(), +#if FW_OBJECT_NAMES == 1 + this->m_objName.toChar() +#else + "UNKNOWN" +#endif + ); + if (status != Fw::FormatStatus::SUCCESS) { buffer[0] = 0; } } diff --git a/Fw/Comp/PassiveComponentBase.hpp b/Fw/Comp/PassiveComponentBase.hpp index ddf1be3ca3..ff56a799cd 100644 --- a/Fw/Comp/PassiveComponentBase.hpp +++ b/Fw/Comp/PassiveComponentBase.hpp @@ -22,8 +22,11 @@ namespace Fw { virtual ~PassiveComponentBase(); //!< Destructor void init(NATIVE_INT_TYPE instance); //!< Initialization function NATIVE_INT_TYPE getInstance() const; + + #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); //!< returns string description of component + virtual const char* getToStringFormatString(); //!< Return the format for a generic component toString + void toString(char* str, NATIVE_INT_TYPE size) override; //!< returns string description of component #endif PRIVATE: U32 m_idBase; //!< ID base for opcodes etc. diff --git a/Fw/Comp/QueuedComponentBase.cpp b/Fw/Comp/QueuedComponentBase.cpp index b649093ff2..7ba871fc0f 100644 --- a/Fw/Comp/QueuedComponentBase.cpp +++ b/Fw/Comp/QueuedComponentBase.cpp @@ -19,14 +19,9 @@ namespace Fw { PassiveComponentBase::init(instance); } -#if FW_OBJECT_TO_STRING == 1 && FW_OBJECT_NAMES == 1 - void QueuedComponentBase::toString(char* buffer, NATIVE_INT_TYPE size) { - FW_ASSERT(size > 0); - FW_ASSERT(buffer != nullptr); - PlatformIntType status = snprintf(buffer, static_cast(size), "QueueComp: %s", this->m_objName.toChar()); - if (status < 0) { - buffer[0] = 0; - } +#if FW_OBJECT_TO_STRING == 1 + const char* QueuedComponentBase::getToStringFormatString() { + return "QueueComp: %s", this->m_objName.toChar()); } #endif @@ -36,9 +31,7 @@ namespace Fw { #if FW_OBJECT_NAMES == 1 queueName = this->m_objName; #else - char queueNameChar[FW_QUEUE_NAME_BUFFER_SIZE]; - (void)snprintf(queueNameChar,sizeof(queueNameChar),"CompQ_%" PRI_FwSizeType,Os::Queue::getNumQueues()); - queueName = queueNameChar; + queueName.format("CompQ_%" PRI_FwSizeType,Os::Queue::getNumQueues()); #endif return this->m_queue.create(queueName, depth, msgSize); } diff --git a/Fw/Comp/QueuedComponentBase.hpp b/Fw/Comp/QueuedComponentBase.hpp index 79833e1284..d78f69d393 100644 --- a/Fw/Comp/QueuedComponentBase.hpp +++ b/Fw/Comp/QueuedComponentBase.hpp @@ -37,7 +37,7 @@ namespace Fw { Os::Queue::Status createQueue(FwSizeType depth, FwSizeType msgSize); virtual MsgDispatchStatus doDispatch()=0; //!< method to dispatch a single message in the queue. #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); //!< dump string representation of component + virtual const char* getToStringFormatString(); //!< Format string for toString function #endif NATIVE_INT_TYPE getNumMsgsDropped(); //!< return number of messages dropped void incNumMsgDropped(); //!< increment the number of messages dropped diff --git a/Fw/Obj/ObjBase.cpp b/Fw/Obj/ObjBase.cpp index 161e047129..2d86ebac2a 100644 --- a/Fw/Obj/ObjBase.cpp +++ b/Fw/Obj/ObjBase.cpp @@ -1,8 +1,7 @@ #include #include -#include -#include #include +#include namespace Fw { @@ -48,8 +47,8 @@ namespace Fw { void ObjBase::toString(char* str, NATIVE_INT_TYPE size) { FW_ASSERT(size > 0); FW_ASSERT(str != nullptr); - PlatformIntType status = snprintf(str, static_cast(size), "Obj: %s", this->m_objName.toChar()); - if (status < 0) { + Fw::FormatStatus formatStatus = Fw::ExternalString(str, static_cast(size)).format("Obj: %s", this->m_objName.toChar()); + if (formatStatus != Fw::FormatStatus::SUCCESS) { str[0] = 0; } } diff --git a/Fw/Port/InputPortBase.cpp b/Fw/Port/InputPortBase.cpp index f60af31df6..5f3f88e501 100644 --- a/Fw/Port/InputPortBase.cpp +++ b/Fw/Port/InputPortBase.cpp @@ -26,18 +26,8 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - void InputPortBase::toString(char* buffer, NATIVE_INT_TYPE size) { -#if FW_OBJECT_NAMES == 1 - FW_ASSERT(size > 0); - FW_ASSERT(buffer != nullptr); - PlatformIntType status = snprintf(buffer, static_cast(size), "InputPort: %s->%s", this->m_objName.toChar(), - this->isConnected() ? this->m_connObj->getObjName() : "None"); - if (status < 0) { - buffer[0] = 0; - } -#else - (void)snprintf(buffer,size,"%s","Unnamed Input port"); -#endif + const char* getToStringFormatString() { + return "Input Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/InputPortBase.hpp b/Fw/Port/InputPortBase.hpp index 5499c7c610..f6fe3f71c2 100644 --- a/Fw/Port/InputPortBase.hpp +++ b/Fw/Port/InputPortBase.hpp @@ -21,12 +21,12 @@ namespace Fw { InputPortBase(); // Constructor virtual ~InputPortBase(); // Destructor - virtual void init(); + void init() override; PassiveComponentBase* m_comp; // !< pointer to containing component NATIVE_INT_TYPE m_portNum; // !< port number in containing object #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); + const char* getToStringFormatString() override; //!< Get format string for toString call #endif private: diff --git a/Fw/Port/InputSerializePort.cpp b/Fw/Port/InputSerializePort.cpp index 2bb7c1a61a..7fb150c23c 100644 --- a/Fw/Port/InputSerializePort.cpp +++ b/Fw/Port/InputSerializePort.cpp @@ -37,16 +37,8 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - void InputSerializePort::toString(char* buffer, NATIVE_INT_TYPE size) { -#if FW_OBJECT_NAMES == 1 - FW_ASSERT(size > 0); - if (snprintf(buffer, static_cast(size), "Input Serial Port: %s %s->(%s)", this->m_objName.toChar(), this->isConnected() ? "C" : "NC", - this->isConnected() ? this->m_connObj->getObjName() : "None") < 0) { - buffer[0] = 0; - } -#else - (void)snprintf(buffer,size,"%s","InputSerializePort"); -#endif + const char* getToStringFormatString() { + return "Input Serial Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/InputSerializePort.hpp b/Fw/Port/InputSerializePort.hpp index de5096a532..887dbd77cd 100644 --- a/Fw/Port/InputSerializePort.hpp +++ b/Fw/Port/InputSerializePort.hpp @@ -14,9 +14,9 @@ namespace Fw { InputSerializePort(); virtual ~InputSerializePort(); - void init(); + void init() override; - SerializeStatus invokeSerial(SerializeBufferBase &buffer); // !< invoke the port with a serialized version of the call + SerializeStatus invokeSerial(SerializeBufferBase &buffer) override; // !< invoke the port with a serialized version of the call typedef void (*CompFuncPtr)(Fw::PassiveComponentBase* callComp, NATIVE_INT_TYPE portNum, SerializeBufferBase &arg); //!< port callback definition void addCallComp(Fw::PassiveComponentBase* callComp, CompFuncPtr funcPtr); //!< call to register a component @@ -24,7 +24,7 @@ namespace Fw { protected: #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); + const char* getToStringFormatString() override; //!< Get format string for toString call #endif private: diff --git a/Fw/Port/OutputPortBase.cpp b/Fw/Port/OutputPortBase.cpp index 009a51c6b4..4c110b333b 100644 --- a/Fw/Port/OutputPortBase.cpp +++ b/Fw/Port/OutputPortBase.cpp @@ -35,17 +35,8 @@ namespace Fw { #endif #if FW_OBJECT_TO_STRING == 1 - void OutputPortBase::toString(char* buffer, NATIVE_INT_TYPE size) { -#if FW_OBJECT_NAMES == 1 - FW_ASSERT(size > 0); - if (snprintf(buffer, static_cast(size), "OutputPort: %s %s->(%s)", this->m_objName.toChar(), this->isConnected() ? "C" : "NC", - this->isConnected() ? this->m_connObj->getObjName() : "None") < 0) { - buffer[0] = 0; - } -#else - (void)snprintf(buffer,size,"%s","OutputPort"); -#endif - + const char* getToStringFormatString() { + return "Output Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/OutputPortBase.hpp b/Fw/Port/OutputPortBase.hpp index c64e11fc14..108f5dcfa4 100644 --- a/Fw/Port/OutputPortBase.hpp +++ b/Fw/Port/OutputPortBase.hpp @@ -19,10 +19,10 @@ namespace Fw { OutputPortBase(); // constructor virtual ~OutputPortBase(); // destructor - virtual void init(); + void init() override; #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); + const char* getToStringFormatString() override; //!< Get format string for toString call #endif #if FW_PORT_SERIALIZATION == 1 diff --git a/Fw/Port/OutputSerializePort.cpp b/Fw/Port/OutputSerializePort.cpp index a6c61b54df..9eac77d781 100644 --- a/Fw/Port/OutputSerializePort.cpp +++ b/Fw/Port/OutputSerializePort.cpp @@ -19,16 +19,8 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - void OutputSerializePort::toString(char* buffer, NATIVE_INT_TYPE size) { -#if FW_OBJECT_NAMES == 1 - FW_ASSERT(size > 0); - if (snprintf(buffer, static_cast(size), "Output Serial Port: %s %s->(%s)", this->m_objName.toChar(), this->isConnected() ? "C" : "NC", - this->isConnected() ? this->m_connObj->getObjName() : "None") < 0) { - buffer[0] = 0; - } -#else - (void)snprintf(buffer,size,"%s","OutputSerializePort"); -#endif + const char* getToStringFormatString() { + return "Output Serial Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/OutputSerializePort.hpp b/Fw/Port/OutputSerializePort.hpp index 5734cb7d65..f5b705980a 100644 --- a/Fw/Port/OutputSerializePort.hpp +++ b/Fw/Port/OutputSerializePort.hpp @@ -13,13 +13,11 @@ namespace Fw { public: OutputSerializePort(); virtual ~OutputSerializePort(); - virtual void init(); + void init() override; protected: - - #if FW_OBJECT_TO_STRING == 1 - virtual void toString(char* str, NATIVE_INT_TYPE size); + const char* getToStringFormatString() override; //!< Get format string for toString call #endif private: diff --git a/Fw/Port/PortBase.cpp b/Fw/Port/PortBase.cpp index 75e97704e0..115ac5a0f5 100644 --- a/Fw/Port/PortBase.cpp +++ b/Fw/Port/PortBase.cpp @@ -3,6 +3,7 @@ #include #include #include "Fw/Types/Assert.hpp" +#include "Fw/Types/ExternalString.hpp" #if FW_PORT_TRACING void setConnTrace(bool trace) { @@ -75,17 +76,43 @@ namespace Fw { #endif // FW_PORT_TRACING -#if FW_OBJECT_NAMES == 1 #if FW_OBJECT_TO_STRING == 1 + const char* getToStringFormatString() { + return "Port: %s %s->(%s)"; + } + void PortBase::toString(char* buffer, NATIVE_INT_TYPE size) { FW_ASSERT(size > 0); - if (snprintf(buffer, static_cast(size), "Port: %s %s->(%s)", this->m_objName.toChar(), this->m_connObj ? "C" : "NC", - this->m_connObj ? this->m_connObj->getObjName() : "None") < 0) { + // Get the port-custom format string + const char* formatString = this->getToStringFormatString(); + // Determine this port object name (or use "UNKOWN") + const char* object_name = +#if FW_OBJECT_NAMES == 1 + this->m_objName.toChar(); +#else + "UNKNOWN"; +#endif + // Get the C/NC for connected or not + const char* this_is_connected = this->isConnected() ? "C" : "NC"; + + // Get the name of the connectioned object, "UNKNNOWN" or "NONE" + const char* connected_to = this->isConnected() ? +#if FW_OBJECT_NAMES == 1 + this->m_connObj->getObjName() +#else + "UNKNOWN" +#endif + : "None"; + // Format the external string or use "" on error + if (Fw::ExternalString(buffer, static_cast(size)).format( + formatString, + object_name, + this_is_connected, + connected_to) != Fw::FormatStatus::SUCCESS) { buffer[0] = 0; } } #endif // FW_OBJECT_TO_STRING -#endif // FW_OBJECT_NAMES } diff --git a/Fw/Port/PortBase.hpp b/Fw/Port/PortBase.hpp index 0e81ddd56d..c9b8c09458 100644 --- a/Fw/Port/PortBase.hpp +++ b/Fw/Port/PortBase.hpp @@ -33,7 +33,9 @@ namespace Fw { Fw::ObjBase* m_connObj; // !< object port is connected to #if FW_OBJECT_TO_STRING - virtual void toString(char* str, NATIVE_INT_TYPE size); + virtual const char* getToStringFormatString(); //!< Get format string for toString call + + void toString(char* str, NATIVE_INT_TYPE size) override; //!< Unified port toString method #endif diff --git a/Fw/Types/Assert.cpp b/Fw/Types/Assert.cpp index b3565f6428..6a014cb877 100644 --- a/Fw/Types/Assert.cpp +++ b/Fw/Types/Assert.cpp @@ -1,7 +1,8 @@ #include #include +#include +#include #include -#include #if FW_ASSERT_LEVEL == FW_FILEID_ASSERT #define fileIdFs "Assert: 0x%08" PRIx32 ":%" PRI_PlatformUIntType @@ -12,7 +13,7 @@ namespace Fw { void defaultPrintAssert(const CHAR* msg) { - (void)fprintf(stderr, "%s\n", msg); + Fw::Logger::log("%s", msg); } void defaultReportAssert(FILE_NAME_ARG file, @@ -26,36 +27,37 @@ void defaultReportAssert(FILE_NAME_ARG file, FwAssertArgType arg6, CHAR* destBuffer, NATIVE_INT_TYPE buffSize) { + Fw::ExternalString external(destBuffer, static_cast(buffSize)); switch (numArgs) { case 0: - (void)snprintf(destBuffer, static_cast(buffSize), fileIdFs, file, lineNo); + (void)external.format(fileIdFs, file, lineNo); break; case 1: - (void)snprintf(destBuffer, static_cast(buffSize), fileIdFs " %" PRI_FwAssertArgType, file, lineNo, arg1); + (void)external.format(fileIdFs " %" PRI_FwAssertArgType, file, lineNo, arg1); break; case 2: - (void)snprintf(destBuffer, static_cast(buffSize), fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, + (void)external.format(fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, lineNo, arg1, arg2); break; case 3: - (void)snprintf(destBuffer, static_cast(buffSize), + (void)external.format( fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, lineNo, arg1, arg2, arg3); break; case 4: - (void)snprintf(destBuffer, static_cast(buffSize), + (void)external.format( fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, lineNo, arg1, arg2, arg3, arg4); break; case 5: - (void)snprintf(destBuffer, static_cast(buffSize), + (void)external.format( fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, lineNo, arg1, arg2, arg3, arg4, arg5); break; case 6: - (void)snprintf(destBuffer, static_cast(buffSize), + (void)external.format( fileIdFs " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType " %" PRI_FwAssertArgType, file, lineNo, arg1, arg2, arg3, arg4, arg5, arg6); @@ -63,9 +65,6 @@ void defaultReportAssert(FILE_NAME_ARG file, default: // in an assert already, what can we do? break; } - - // null terminate - destBuffer[buffSize - 1] = 0; } void AssertHook::printAssert(const CHAR* msg) { diff --git a/Fw/Types/PolyType.cpp b/Fw/Types/PolyType.cpp index 30c04196bd..66d4e24fcf 100644 --- a/Fw/Types/PolyType.cpp +++ b/Fw/Types/PolyType.cpp @@ -1,7 +1,6 @@ #include #include -#include -#define __STDC_FORMAT_MACROS +#include namespace Fw { @@ -605,68 +604,66 @@ void PolyType::toString(StringBase& dest) const { } void PolyType::toString(StringBase& dest, bool append) const { - char valString[80]; + char format[21]; // U64 max fits into 20 decimal digits + 1 null terminator + Fw::ExternalString external(format, sizeof format); switch (this->m_dataType) { case TYPE_U8: - (void)snprintf(valString, sizeof(valString), "%" PRIu8 " ", this->m_val.u8Val); + (void)external.format("%" PRIu8 " ", this->m_val.u8Val); break; case TYPE_I8: - (void)snprintf(valString, sizeof(valString), "%" PRId8 " ", this->m_val.i8Val); + (void)external.format("%" PRId8 " ", this->m_val.i8Val); break; #if FW_HAS_16_BIT case TYPE_U16: - (void)snprintf(valString, sizeof(valString), "%" PRIu16 " ", this->m_val.u16Val); + (void)external.format("%" PRIu16 " ", this->m_val.u16Val); break; case TYPE_I16: - (void)snprintf(valString, sizeof(valString), "%" PRId16 " ", this->m_val.i16Val); + (void)external.format("%" PRId16 " ", this->m_val.i16Val); break; #endif #if FW_HAS_32_BIT case TYPE_U32: - (void)snprintf(valString, sizeof(valString), "%" PRIu32 " ", this->m_val.u32Val); + (void)external.format("%" PRIu32 " ", this->m_val.u32Val); break; case TYPE_I32: - (void)snprintf(valString, sizeof(valString), "%" PRId32 " ", this->m_val.i32Val); + (void)external.format("%" PRId32 " ", this->m_val.i32Val); break; #endif #if FW_HAS_64_BIT case TYPE_U64: - (void)snprintf(valString, sizeof(valString), "%" PRIu64 " ", this->m_val.u64Val); + (void)external.format("%" PRIu64 " ", this->m_val.u64Val); break; case TYPE_I64: - (void)snprintf(valString, sizeof(valString), "%" PRId64 " ", this->m_val.i64Val); + (void)external.format("%" PRId64 " ", this->m_val.i64Val); break; #endif #if FW_HAS_F64 case TYPE_F64: - (void)snprintf(valString, sizeof(valString), "%g ", this->m_val.f64Val); + (void)external.format("%g ", this->m_val.f64Val); break; case TYPE_F32: - (void)snprintf(valString, sizeof(valString), "%g ", static_cast(this->m_val.f32Val)); + (void)external.format("%g ", static_cast(this->m_val.f32Val)); break; #else case TYPE_F32: - (void)snprintf(valString, sizeof(valString), "%g ", this->m_val.f32Val); + (void)external.format("%g ", this->m_val.f32Val); break; #endif case TYPE_BOOL: - (void)snprintf(valString, sizeof(valString), "%s ", this->m_val.boolVal ? "T" : "F"); + (void)external.format("%s ", this->m_val.boolVal ? "T" : "F"); break; case TYPE_PTR: - (void)snprintf(valString, sizeof(valString), "%p ", this->m_val.ptrVal); + (void)external.format("%p ", this->m_val.ptrVal); break; default: - (void)snprintf(valString, sizeof(valString), "%s ", "NT"); + (void)external.format("%s ", "NT"); break; } - // NULL terminate - valString[sizeof(valString) - 1] = 0; - if (append) { - dest += valString; + dest += external; } else { - dest = valString; + dest = external; } } From 203fbc031c0571ced81730b54912845a5ea2ac81 Mon Sep 17 00:00:00 2001 From: Michael D Starch Date: Thu, 30 Jan 2025 13:15:07 -0800 Subject: [PATCH 3/5] Fixes to get UTs to compile --- Fw/Comp/PassiveComponentBase.cpp | 2 +- Fw/Comp/QueuedComponentBase.cpp | 2 +- Fw/Port/InputPortBase.cpp | 2 +- Fw/Port/InputSerializePort.cpp | 2 +- Fw/Port/OutputPortBase.cpp | 2 +- Fw/Port/OutputSerializePort.cpp | 2 +- Fw/Port/PortBase.cpp | 2 +- Fw/Types/Assert.cpp | 3 ++- Fw/Types/CMakeLists.txt | 1 - Os/Posix/CMakeLists.txt | 8 ++++++++ Os/Posix/DefaultErrorConsole.cpp | 16 ++++++++++++++++ Os/Stub/test/CMakeLists.txt | 2 ++ Os/Stub/test/ut/StubFileTests.cpp | 2 ++ Os/Stub/test/ut/StubQueueTests.cpp | 2 ++ Os/Stub/test/ut/StubTaskTests.cpp | 2 ++ cmake/API.cmake | 3 ++- cmake/FPrime.cmake | 1 + cmake/implementation.cmake | 8 +++++++- 18 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 Os/Posix/DefaultErrorConsole.cpp diff --git a/Fw/Comp/PassiveComponentBase.cpp b/Fw/Comp/PassiveComponentBase.cpp index a73e9f23e2..1a57bcd046 100644 --- a/Fw/Comp/PassiveComponentBase.cpp +++ b/Fw/Comp/PassiveComponentBase.cpp @@ -10,7 +10,7 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* PassiveComponentBase::getToStringFormatString() { return "Comp: %s"; } diff --git a/Fw/Comp/QueuedComponentBase.cpp b/Fw/Comp/QueuedComponentBase.cpp index 7ba871fc0f..6fa01d695d 100644 --- a/Fw/Comp/QueuedComponentBase.cpp +++ b/Fw/Comp/QueuedComponentBase.cpp @@ -21,7 +21,7 @@ namespace Fw { #if FW_OBJECT_TO_STRING == 1 const char* QueuedComponentBase::getToStringFormatString() { - return "QueueComp: %s", this->m_objName.toChar()); + return "QueueComp: %s"; } #endif diff --git a/Fw/Port/InputPortBase.cpp b/Fw/Port/InputPortBase.cpp index 5f3f88e501..47ae6b4ee3 100644 --- a/Fw/Port/InputPortBase.cpp +++ b/Fw/Port/InputPortBase.cpp @@ -26,7 +26,7 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* InputPortBase::getToStringFormatString() { return "Input Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/InputSerializePort.cpp b/Fw/Port/InputSerializePort.cpp index 7fb150c23c..e518b97706 100644 --- a/Fw/Port/InputSerializePort.cpp +++ b/Fw/Port/InputSerializePort.cpp @@ -37,7 +37,7 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* InputSerializePort::getToStringFormatString() { return "Input Serial Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/OutputPortBase.cpp b/Fw/Port/OutputPortBase.cpp index 4c110b333b..89d2789b00 100644 --- a/Fw/Port/OutputPortBase.cpp +++ b/Fw/Port/OutputPortBase.cpp @@ -35,7 +35,7 @@ namespace Fw { #endif #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* OutputPortBase::getToStringFormatString() { return "Output Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/OutputSerializePort.cpp b/Fw/Port/OutputSerializePort.cpp index 9eac77d781..ab2d6801b7 100644 --- a/Fw/Port/OutputSerializePort.cpp +++ b/Fw/Port/OutputSerializePort.cpp @@ -19,7 +19,7 @@ namespace Fw { } #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* OutputSerializePort::getToStringFormatString() { return "Output Serial Port: %s %s->(%s)"; } #endif diff --git a/Fw/Port/PortBase.cpp b/Fw/Port/PortBase.cpp index 115ac5a0f5..25da27c715 100644 --- a/Fw/Port/PortBase.cpp +++ b/Fw/Port/PortBase.cpp @@ -77,7 +77,7 @@ namespace Fw { #endif // FW_PORT_TRACING #if FW_OBJECT_TO_STRING == 1 - const char* getToStringFormatString() { + const char* PortBase::getToStringFormatString() { return "Port: %s %s->(%s)"; } diff --git a/Fw/Types/Assert.cpp b/Fw/Types/Assert.cpp index 6a014cb877..3d827882cb 100644 --- a/Fw/Types/Assert.cpp +++ b/Fw/Types/Assert.cpp @@ -13,7 +13,8 @@ namespace Fw { void defaultPrintAssert(const CHAR* msg) { - Fw::Logger::log("%s", msg); + //Fw::Logger::log("%s", msg); + fprintf(stderr, "%s", msg); } void defaultReportAssert(FILE_NAME_ARG file, diff --git a/Fw/Types/CMakeLists.txt b/Fw/Types/CMakeLists.txt index 87ad8a3917..27dce5ae95 100644 --- a/Fw/Types/CMakeLists.txt +++ b/Fw/Types/CMakeLists.txt @@ -40,4 +40,3 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/GTest") # Create an empty interface library and use it to register an implementation add_library(snprintf-format INTERFACE) register_fprime_implementation(Fw_StringFormat snprintf-format "${CMAKE_CURRENT_LIST_DIR}/snprintf_format.cpp") -choose_fprime_implementation(Fw_StringFormat snprintf-format "${FPRIME_PLATFORM}") # Default choice is snprintf diff --git a/Os/Posix/CMakeLists.txt b/Os/Posix/CMakeLists.txt index a385d92b4c..950cf4e7e2 100644 --- a/Os/Posix/CMakeLists.txt +++ b/Os/Posix/CMakeLists.txt @@ -24,6 +24,14 @@ register_fprime_module(Os_Posix_Shared) # Set up Posix implementations register_os_implementation("File;FileSystem;Directory" Posix Os_Posix_Shared) register_os_implementation("Console" Posix) + +# Special error console +set(MOD_DEPS "Os_Console_Common") +add_library("Os_Console_PosixError" INTERFACE) +add_dependencies("Os_Console_PosixError" "Os_Console_Common" "Os_Console_Posix") +target_link_libraries("Os_Console_PosixError" INTERFACE "Os_Console_Common" "Os_Console_Posix") +register_fprime_implementation("Os_Console" "Os_Console_PosixError" "${CMAKE_CURRENT_LIST_DIR}/DefaultErrorConsole.cpp") + register_os_implementation("Task" Posix Os_Posix_Shared Fw_Time) register_os_implementation("Mutex;ConditionVariable" Posix Os_Posix_Shared) register_os_implementation("RawTime" Posix Os_Posix_Shared) diff --git a/Os/Posix/DefaultErrorConsole.cpp b/Os/Posix/DefaultErrorConsole.cpp new file mode 100644 index 0000000000..317c06a09a --- /dev/null +++ b/Os/Posix/DefaultErrorConsole.cpp @@ -0,0 +1,16 @@ +// ====================================================================== +// \title Os/Posix/DefaultErrorConsole.cpp +// \brief sets default Os::Console to posix implementation via linker +// ====================================================================== +#include "Os/Console.hpp" +#include "Os/Posix/Console.hpp" +#include "Os/Delegate.hpp" + +namespace Os { +ConsoleInterface* ConsoleInterface::getDelegate(ConsoleHandleStorage& aligned_new_memory, const ConsoleInterface* to_copy) { + auto console = Os::Delegate::makeDelegate(aligned_new_memory, to_copy); + // Override the output file + reinterpret_cast(console->getHandle())->m_file_descriptor = stderr; + return console; +} +} diff --git a/Os/Stub/test/CMakeLists.txt b/Os/Stub/test/CMakeLists.txt index a160004ee7..ae5f64e5ec 100644 --- a/Os/Stub/test/CMakeLists.txt +++ b/Os/Stub/test/CMakeLists.txt @@ -19,6 +19,8 @@ register_os_implementation(Memory Test_Stub) register_os_implementation(Queue Test_Stub) register_os_implementation(RawTime Test_Stub) # add Fw_Buffer here? +# Use the error console for this +choose_fprime_implementation(Os_Console Os_Console_PosixError) #### File Stub Testing #### set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/ut/StubFileTests.cpp" diff --git a/Os/Stub/test/ut/StubFileTests.cpp b/Os/Stub/test/ut/StubFileTests.cpp index 5836f3a74e..fee608c145 100644 --- a/Os/Stub/test/ut/StubFileTests.cpp +++ b/Os/Stub/test/ut/StubFileTests.cpp @@ -3,6 +3,7 @@ // \brief tests using stub implementation for Os::File interface testing // ====================================================================== #include +#include "Os/Os.hpp" #include "Os/File.hpp" #include "Os/Stub/test/File.hpp" #include "Os/test/ut/file/CommonTests.hpp" @@ -191,6 +192,7 @@ TEST_F(Interface, Write) { } int main(int argc, char **argv) { + Os::init(); ::testing::InitGoogleTest(&argc, argv); STest::Random::seed(); return RUN_ALL_TESTS(); diff --git a/Os/Stub/test/ut/StubQueueTests.cpp b/Os/Stub/test/ut/StubQueueTests.cpp index 556c2294b7..63aa7b7dc2 100644 --- a/Os/Stub/test/ut/StubQueueTests.cpp +++ b/Os/Stub/test/ut/StubQueueTests.cpp @@ -7,6 +7,7 @@ #include "Os/Queue.hpp" #include "Os/Stub/test/Queue.hpp" #include "STest/Random/Random.hpp" +#include "Os/Os.hpp" void resetInjections() { @@ -235,6 +236,7 @@ TEST(Interface, QueueHandle) { } int main(int argc, char** argv) { + Os::init(); ::testing::InitGoogleTest(&argc, argv); STest::Random::seed(); return RUN_ALL_TESTS(); diff --git a/Os/Stub/test/ut/StubTaskTests.cpp b/Os/Stub/test/ut/StubTaskTests.cpp index 75affe6b4b..ecde3002a7 100644 --- a/Os/Stub/test/ut/StubTaskTests.cpp +++ b/Os/Stub/test/ut/StubTaskTests.cpp @@ -7,6 +7,7 @@ #include "Os/Stub/test/Task.hpp" #include "Os/test/ut/task/CommonTests.hpp" #include "Os/test/ut/task/RulesHeaders.hpp" +#include "Os/Os.hpp" using namespace Os::Stub::Task::Test; @@ -137,6 +138,7 @@ TEST_F(Interface, RegistryRemove) { } int main(int argc, char **argv) { + Os::init(); ::testing::InitGoogleTest(&argc, argv); STest::Random::seed(); return RUN_ALL_TESTS(); diff --git a/cmake/API.cmake b/cmake/API.cmake index 64a4f626cc..1bda4fdc03 100644 --- a/cmake/API.cmake +++ b/cmake/API.cmake @@ -668,7 +668,8 @@ endfunction() # # Designates that the given implementor is the selected implementor for the needed implementation. Platforms must call # this function once for each defined IMPLEMENTATION. An executable/deployment/unit-test may call this function to set -# a specific implementor for any needed implementation +# a specific implementor for any needed implementation. FRAMEWORK_DEFAULT may be supplied to indicate a default choice +# set by the framework, which can be overriden by the platform and module selections. # # **IMPLEMENTATION:** implementation module name that is implemented by IMPLEMENTOR # **IMPLEMENTOR:** implementor of IMPLEMENTATION diff --git a/cmake/FPrime.cmake b/cmake/FPrime.cmake index 8e09fcd27a..dc467f550c 100644 --- a/cmake/FPrime.cmake +++ b/cmake/FPrime.cmake @@ -170,6 +170,7 @@ endmacro(fprime_initialize_build_system) # registered. #### function(fprime_setup_included_code) + choose_fprime_implementation(Fw_StringFormat snprintf-format FRAMEWORK_DEFAULT) # Default choice is snprintf # Must be done before code is registered but after custom target registration setup_global_targets() # For BUILD_TESTING builds then set up libraries that support testing diff --git a/cmake/implementation.cmake b/cmake/implementation.cmake index bac00d0a77..4e0e93699e 100644 --- a/cmake/implementation.cmake +++ b/cmake/implementation.cmake @@ -80,11 +80,17 @@ endfunction() # MODULE: module to setup implementation choices for ##### function(setup_executable_implementation IMPLEMENTATION MODULE) - # Get the chosen implementor and fallback to the platform choice + # Get the chosen implementor for the module get_property(IMPLEMENTOR GLOBAL PROPERTY "${MODULE}_${IMPLEMENTATION}") + # Fallback to the platform in the case that the module does not specify if (NOT IMPLEMENTOR) get_property(IMPLEMENTOR GLOBAL PROPERTY "${FPRIME_PLATFORM}_${IMPLEMENTATION}") endif() + # Fallback to the FRAMEWORK_DEFAULT in the case that the platform does not specify + if (NOT IMPLEMENTOR) + get_property(IMPLEMENTOR GLOBAL PROPERTY "FRAMEWORK_DEFAULT_${IMPLEMENTATION}") + endif() + # Handle a failure to choose anything if (NOT IMPLEMENTOR) get_property(LOCAL_IMPLEMENTATIONS GLOBAL PROPERTY "${IMPLEMENTATION}_IMPLEMENTORS") From fa8a2eaeaf4f00cc94e0eafba2c56aafa38d65ee Mon Sep 17 00:00:00 2001 From: Michael D Starch Date: Thu, 30 Jan 2025 14:50:23 -0800 Subject: [PATCH 4/5] Reverting test change to assert --- Fw/Types/Assert.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Fw/Types/Assert.cpp b/Fw/Types/Assert.cpp index 3d827882cb..6a014cb877 100644 --- a/Fw/Types/Assert.cpp +++ b/Fw/Types/Assert.cpp @@ -13,8 +13,7 @@ namespace Fw { void defaultPrintAssert(const CHAR* msg) { - //Fw::Logger::log("%s", msg); - fprintf(stderr, "%s", msg); + Fw::Logger::log("%s", msg); } void defaultReportAssert(FILE_NAME_ARG file, From 7447c5dada68fc6ecd419d619f4acf8eee0e72c6 Mon Sep 17 00:00:00 2001 From: Michael D Starch Date: Thu, 6 Feb 2025 10:59:03 -0800 Subject: [PATCH 5/5] Removing error console and restoring assert functionality --- Fw/Port/PortBase.cpp | 4 ++-- Fw/Types/Assert.cpp | 5 +++-- Os/Posix/CMakeLists.txt | 7 ------- Os/Posix/DefaultErrorConsole.cpp | 16 ---------------- Os/Stub/test/CMakeLists.txt | 2 -- cmake/API.cmake | 2 +- 6 files changed, 6 insertions(+), 30 deletions(-) delete mode 100644 Os/Posix/DefaultErrorConsole.cpp diff --git a/Fw/Port/PortBase.cpp b/Fw/Port/PortBase.cpp index 25da27c715..10621269b9 100644 --- a/Fw/Port/PortBase.cpp +++ b/Fw/Port/PortBase.cpp @@ -85,7 +85,7 @@ namespace Fw { FW_ASSERT(size > 0); // Get the port-custom format string const char* formatString = this->getToStringFormatString(); - // Determine this port object name (or use "UNKOWN") + // Determine this port object name (or use "UNKNOWN") const char* object_name = #if FW_OBJECT_NAMES == 1 this->m_objName.toChar(); @@ -95,7 +95,7 @@ namespace Fw { // Get the C/NC for connected or not const char* this_is_connected = this->isConnected() ? "C" : "NC"; - // Get the name of the connectioned object, "UNKNNOWN" or "NONE" + // Get the name of the connection object, "UNKNOWN" or "NONE" const char* connected_to = this->isConnected() ? #if FW_OBJECT_NAMES == 1 this->m_connObj->getObjName() diff --git a/Fw/Types/Assert.cpp b/Fw/Types/Assert.cpp index 6a014cb877..a05280f274 100644 --- a/Fw/Types/Assert.cpp +++ b/Fw/Types/Assert.cpp @@ -1,8 +1,9 @@ #include #include #include -#include +#include #include +#include #if FW_ASSERT_LEVEL == FW_FILEID_ASSERT #define fileIdFs "Assert: 0x%08" PRIx32 ":%" PRI_PlatformUIntType @@ -13,7 +14,7 @@ namespace Fw { void defaultPrintAssert(const CHAR* msg) { - Fw::Logger::log("%s", msg); + (void) fwrite(msg, sizeof(CHAR), static_cast(Fw::StringUtils::string_length(msg, FW_ASSERT_TEXT_SIZE)), stderr); } void defaultReportAssert(FILE_NAME_ARG file, diff --git a/Os/Posix/CMakeLists.txt b/Os/Posix/CMakeLists.txt index 950cf4e7e2..9d6e594310 100644 --- a/Os/Posix/CMakeLists.txt +++ b/Os/Posix/CMakeLists.txt @@ -25,13 +25,6 @@ register_fprime_module(Os_Posix_Shared) register_os_implementation("File;FileSystem;Directory" Posix Os_Posix_Shared) register_os_implementation("Console" Posix) -# Special error console -set(MOD_DEPS "Os_Console_Common") -add_library("Os_Console_PosixError" INTERFACE) -add_dependencies("Os_Console_PosixError" "Os_Console_Common" "Os_Console_Posix") -target_link_libraries("Os_Console_PosixError" INTERFACE "Os_Console_Common" "Os_Console_Posix") -register_fprime_implementation("Os_Console" "Os_Console_PosixError" "${CMAKE_CURRENT_LIST_DIR}/DefaultErrorConsole.cpp") - register_os_implementation("Task" Posix Os_Posix_Shared Fw_Time) register_os_implementation("Mutex;ConditionVariable" Posix Os_Posix_Shared) register_os_implementation("RawTime" Posix Os_Posix_Shared) diff --git a/Os/Posix/DefaultErrorConsole.cpp b/Os/Posix/DefaultErrorConsole.cpp deleted file mode 100644 index 317c06a09a..0000000000 --- a/Os/Posix/DefaultErrorConsole.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// ====================================================================== -// \title Os/Posix/DefaultErrorConsole.cpp -// \brief sets default Os::Console to posix implementation via linker -// ====================================================================== -#include "Os/Console.hpp" -#include "Os/Posix/Console.hpp" -#include "Os/Delegate.hpp" - -namespace Os { -ConsoleInterface* ConsoleInterface::getDelegate(ConsoleHandleStorage& aligned_new_memory, const ConsoleInterface* to_copy) { - auto console = Os::Delegate::makeDelegate(aligned_new_memory, to_copy); - // Override the output file - reinterpret_cast(console->getHandle())->m_file_descriptor = stderr; - return console; -} -} diff --git a/Os/Stub/test/CMakeLists.txt b/Os/Stub/test/CMakeLists.txt index ae5f64e5ec..a160004ee7 100644 --- a/Os/Stub/test/CMakeLists.txt +++ b/Os/Stub/test/CMakeLists.txt @@ -19,8 +19,6 @@ register_os_implementation(Memory Test_Stub) register_os_implementation(Queue Test_Stub) register_os_implementation(RawTime Test_Stub) # add Fw_Buffer here? -# Use the error console for this -choose_fprime_implementation(Os_Console Os_Console_PosixError) #### File Stub Testing #### set(UT_SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/ut/StubFileTests.cpp" diff --git a/cmake/API.cmake b/cmake/API.cmake index 1bda4fdc03..b090c1fbca 100644 --- a/cmake/API.cmake +++ b/cmake/API.cmake @@ -669,7 +669,7 @@ endfunction() # Designates that the given implementor is the selected implementor for the needed implementation. Platforms must call # this function once for each defined IMPLEMENTATION. An executable/deployment/unit-test may call this function to set # a specific implementor for any needed implementation. FRAMEWORK_DEFAULT may be supplied to indicate a default choice -# set by the framework, which can be overriden by the platform and module selections. +# set by the framework, which can be overridden by the platform and module selections. # # **IMPLEMENTATION:** implementation module name that is implemented by IMPLEMENTOR # **IMPLEMENTOR:** implementor of IMPLEMENTATION