From 0ac01d38d66eefaf272d86dfdec5c322cb37e9cd Mon Sep 17 00:00:00 2001 From: David Cozens Date: Sat, 6 Jun 2026 07:12:24 +0000 Subject: [PATCH 1/2] feat: S14.06 flip the SD vtable to SolidSyslogSdElement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change struct SolidSyslogStructuredData.Format (and the SolidSyslogStructuredData_Format dispatch wrapper) from receiving a raw struct SolidSyslogFormatter* to a struct SolidSyslogSdElement*. A custom-SD author's Format can no longer reach a raw formatter — the footgun is closed at the extension point itself. Move the SolidSyslogSdElement_FromFormatter wrap up into the SD-emission loop in SolidSyslogMessageFormatter: one element is built per message and passed to each configured SD in the existing order. The three SDs (MetaSd, OriginSd, TimeQualitySd) drop their now-redundant local wrap and emit straight onto the handed element; NullSd's no-op signature follows. Output is byte-for-byte identical (existing tests stand; SD test doubles' Format signatures updated, and the [spy]/[spy2] doubles now emit via _Begin/_End). Co-Authored-By: Claude Opus 4.8 (1M context) --- Core/Interface/SolidSyslogStructuredData.h | 7 ++---- .../SolidSyslogStructuredDataDefinition.h | 4 ++-- Core/Source/SolidSyslogMessageFormatter.c | 5 ++++- Core/Source/SolidSyslogMetaSd.c | 20 +++++++---------- Core/Source/SolidSyslogNullSd.c | 8 +++---- Core/Source/SolidSyslogOriginSd.c | 22 ++++++++----------- Core/Source/SolidSyslogStructuredData.c | 6 ++--- Core/Source/SolidSyslogTimeQualitySd.c | 20 +++++++---------- Tests/SolidSyslogMetaSdTest.cpp | 7 ++++-- Tests/SolidSyslogNullSdTest.cpp | 5 ++++- Tests/SolidSyslogOriginSdTest.cpp | 7 ++++-- Tests/SolidSyslogTest.cpp | 16 +++++++------- Tests/SolidSyslogTimeQualitySdTest.cpp | 7 ++++-- misra_suppressions.txt | 18 +++++++-------- 14 files changed, 76 insertions(+), 76 deletions(-) diff --git a/Core/Interface/SolidSyslogStructuredData.h b/Core/Interface/SolidSyslogStructuredData.h index 2d6b23a3..dbfaacd1 100644 --- a/Core/Interface/SolidSyslogStructuredData.h +++ b/Core/Interface/SolidSyslogStructuredData.h @@ -5,13 +5,10 @@ EXTERN_C_BEGIN - struct SolidSyslogFormatter; + struct SolidSyslogSdElement; struct SolidSyslogStructuredData; - void SolidSyslogStructuredData_Format( - struct SolidSyslogStructuredData * sd, - struct SolidSyslogFormatter * formatter - ); + void SolidSyslogStructuredData_Format(struct SolidSyslogStructuredData * sd, struct SolidSyslogSdElement * element); EXTERN_C_END diff --git a/Core/Interface/SolidSyslogStructuredDataDefinition.h b/Core/Interface/SolidSyslogStructuredDataDefinition.h index 1ce2cd41..1ce803a5 100644 --- a/Core/Interface/SolidSyslogStructuredDataDefinition.h +++ b/Core/Interface/SolidSyslogStructuredDataDefinition.h @@ -5,11 +5,11 @@ EXTERN_C_BEGIN - struct SolidSyslogFormatter; + struct SolidSyslogSdElement; struct SolidSyslogStructuredData { - void (*Format)(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); + void (*Format)(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element); }; EXTERN_C_END diff --git a/Core/Source/SolidSyslogMessageFormatter.c b/Core/Source/SolidSyslogMessageFormatter.c index d51af09a..a6bd67d3 100644 --- a/Core/Source/SolidSyslogMessageFormatter.c +++ b/Core/Source/SolidSyslogMessageFormatter.c @@ -7,6 +7,7 @@ #include "SolidSyslog.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogPrival.h" +#include "SolidSyslogSdElementPrivate.h" #include "SolidSyslogStringFunction.h" #include "SolidSyslogStructuredData.h" #include "SolidSyslogTimestamp.h" @@ -168,10 +169,12 @@ static inline void MessageFormatter_FormatStructuredData( ) { size_t lengthBefore = SolidSyslogFormatter_Length(f); + struct SolidSyslogSdElement element; + SolidSyslogSdElement_FromFormatter(&element, f); for (size_t i = 0; i < sdCount; i++) { - SolidSyslogStructuredData_Format(sd[i], f); + SolidSyslogStructuredData_Format(sd[i], &element); } if (SolidSyslogFormatter_Length(f) == lengthBefore) diff --git a/Core/Source/SolidSyslogMetaSd.c b/Core/Source/SolidSyslogMetaSd.c index 19651f80..a5d2032b 100644 --- a/Core/Source/SolidSyslogMetaSd.c +++ b/Core/Source/SolidSyslogMetaSd.c @@ -7,15 +7,13 @@ #include "SolidSyslogMetaSdErrors.h" #include "SolidSyslogMetaSdPrivate.h" #include "SolidSyslogNullSd.h" -#include "SolidSyslogSdElementPrivate.h" +#include "SolidSyslogSdElement.h" #include "SolidSyslogSdValue.h" #include "SolidSyslogStructuredDataDefinition.h" const struct SolidSyslogErrorSource MetaSdErrorSource = {"MetaSd"}; -struct SolidSyslogFormatter; - -static void MetaSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); +static void MetaSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element); static inline struct SolidSyslogMetaSd* MetaSd_SelfFromBase(struct SolidSyslogStructuredData* base); @@ -37,26 +35,24 @@ void MetaSd_Cleanup(struct SolidSyslogStructuredData* base) *base = *SolidSyslogNullSd_Get(); } -static void MetaSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter) +static void MetaSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element) { struct SolidSyslogMetaSd* self = MetaSd_SelfFromBase(base); - struct SolidSyslogSdElement element; - SolidSyslogSdElement_FromFormatter(&element, formatter); - SolidSyslogSdElement_Begin(&element, "meta", 0U); + SolidSyslogSdElement_Begin(element, "meta", 0U); SolidSyslogSdValue_Uint32( - SolidSyslogSdElement_Param(&element, "sequenceId"), + SolidSyslogSdElement_Param(element, "sequenceId"), SolidSyslogAtomicCounter_Increment(self->Counter) ); if (self->GetSysUpTime != NULL) { - SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(&element, "sysUpTime"), self->GetSysUpTime()); + SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(element, "sysUpTime"), self->GetSysUpTime()); } if (self->GetLanguage != NULL) { - self->GetLanguage(SolidSyslogSdElement_Param(&element, "language"), self->LanguageContext); + self->GetLanguage(SolidSyslogSdElement_Param(element, "language"), self->LanguageContext); } - SolidSyslogSdElement_End(&element); + SolidSyslogSdElement_End(element); } static inline struct SolidSyslogMetaSd* MetaSd_SelfFromBase(struct SolidSyslogStructuredData* base) diff --git a/Core/Source/SolidSyslogNullSd.c b/Core/Source/SolidSyslogNullSd.c index d3e47dcd..26d785ef 100644 --- a/Core/Source/SolidSyslogNullSd.c +++ b/Core/Source/SolidSyslogNullSd.c @@ -2,9 +2,9 @@ #include "SolidSyslogStructuredDataDefinition.h" -struct SolidSyslogFormatter; +struct SolidSyslogSdElement; -static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); +static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element); struct SolidSyslogStructuredData* SolidSyslogNullSd_Get(void) { @@ -12,8 +12,8 @@ struct SolidSyslogStructuredData* SolidSyslogNullSd_Get(void) return &instance; } -static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter) +static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element) { (void) base; - (void) formatter; + (void) element; } diff --git a/Core/Source/SolidSyslogOriginSd.c b/Core/Source/SolidSyslogOriginSd.c index ffd2442f..6c829e70 100644 --- a/Core/Source/SolidSyslogOriginSd.c +++ b/Core/Source/SolidSyslogOriginSd.c @@ -6,15 +6,13 @@ #include "SolidSyslogNullSd.h" #include "SolidSyslogOriginSdErrors.h" #include "SolidSyslogOriginSdPrivate.h" -#include "SolidSyslogSdElementPrivate.h" +#include "SolidSyslogSdElement.h" #include "SolidSyslogSdValue.h" #include "SolidSyslogStructuredDataDefinition.h" const struct SolidSyslogErrorSource OriginSdErrorSource = {"OriginSd"}; -struct SolidSyslogFormatter; - -static void OriginSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); +static void OriginSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element); static inline struct SolidSyslogOriginSd* OriginSd_SelfFromBase(struct SolidSyslogStructuredData* base); static inline void OriginSd_EmitSoftware(struct SolidSyslogSdElement* element, const char* software); @@ -42,18 +40,16 @@ void OriginSd_Cleanup(struct SolidSyslogStructuredData* base) *base = *SolidSyslogNullSd_Get(); } -static void OriginSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter) +static void OriginSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element) { struct SolidSyslogOriginSd* self = OriginSd_SelfFromBase(base); - struct SolidSyslogSdElement element; - SolidSyslogSdElement_FromFormatter(&element, formatter); - SolidSyslogSdElement_Begin(&element, "origin", 0U); - OriginSd_EmitSoftware(&element, self->Software); - OriginSd_EmitSwVersion(&element, self->SwVersion); - OriginSd_EmitEnterpriseId(&element, self->EnterpriseId); - OriginSd_EmitIps(&element, self); - SolidSyslogSdElement_End(&element); + SolidSyslogSdElement_Begin(element, "origin", 0U); + OriginSd_EmitSoftware(element, self->Software); + OriginSd_EmitSwVersion(element, self->SwVersion); + OriginSd_EmitEnterpriseId(element, self->EnterpriseId); + OriginSd_EmitIps(element, self); + SolidSyslogSdElement_End(element); } static inline struct SolidSyslogOriginSd* OriginSd_SelfFromBase(struct SolidSyslogStructuredData* base) diff --git a/Core/Source/SolidSyslogStructuredData.c b/Core/Source/SolidSyslogStructuredData.c index 40f03cfd..6a9eb947 100644 --- a/Core/Source/SolidSyslogStructuredData.c +++ b/Core/Source/SolidSyslogStructuredData.c @@ -1,9 +1,9 @@ #include "SolidSyslogStructuredDataDefinition.h" #include "SolidSyslogStructuredData.h" -struct SolidSyslogFormatter; +struct SolidSyslogSdElement; -void SolidSyslogStructuredData_Format(struct SolidSyslogStructuredData* sd, struct SolidSyslogFormatter* formatter) +void SolidSyslogStructuredData_Format(struct SolidSyslogStructuredData* sd, struct SolidSyslogSdElement* element) { - sd->Format(sd, formatter); + sd->Format(sd, element); } diff --git a/Core/Source/SolidSyslogTimeQualitySd.c b/Core/Source/SolidSyslogTimeQualitySd.c index 82bb81e2..b04e9a1b 100644 --- a/Core/Source/SolidSyslogTimeQualitySd.c +++ b/Core/Source/SolidSyslogTimeQualitySd.c @@ -5,7 +5,7 @@ #include "SolidSyslogError.h" #include "SolidSyslogNullSd.h" -#include "SolidSyslogSdElementPrivate.h" +#include "SolidSyslogSdElement.h" #include "SolidSyslogSdValue.h" #include "SolidSyslogStructuredDataDefinition.h" #include "SolidSyslogTimeQualitySdErrors.h" @@ -13,9 +13,7 @@ const struct SolidSyslogErrorSource TimeQualitySdErrorSource = {"TimeQualitySd"}; -struct SolidSyslogFormatter; - -static void TimeQualitySd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter); +static void TimeQualitySd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element); static inline struct SolidSyslogTimeQualitySd* TimeQualitySd_SelfFromBase(struct SolidSyslogStructuredData* base); @@ -34,23 +32,21 @@ void TimeQualitySd_Cleanup(struct SolidSyslogStructuredData* base) *base = *SolidSyslogNullSd_Get(); } -static void TimeQualitySd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter) +static void TimeQualitySd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogSdElement* element) { struct SolidSyslogTimeQualitySd* self = TimeQualitySd_SelfFromBase(base); struct SolidSyslogTimeQuality q = {0}; - struct SolidSyslogSdElement element; self->GetTimeQuality(&q); - SolidSyslogSdElement_FromFormatter(&element, formatter); - SolidSyslogSdElement_Begin(&element, "timeQuality", 0U); - SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(&element, "tzKnown"), q.TzKnown ? 1U : 0U); - SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(&element, "isSynced"), q.IsSynced ? 1U : 0U); + SolidSyslogSdElement_Begin(element, "timeQuality", 0U); + SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(element, "tzKnown"), q.TzKnown ? 1U : 0U); + SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(element, "isSynced"), q.IsSynced ? 1U : 0U); if (q.SyncAccuracyMicroseconds != SOLIDSYSLOG_SYNC_ACCURACY_OMIT) { - SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(&element, "syncAccuracy"), q.SyncAccuracyMicroseconds); + SolidSyslogSdValue_Uint32(SolidSyslogSdElement_Param(element, "syncAccuracy"), q.SyncAccuracyMicroseconds); } - SolidSyslogSdElement_End(&element); + SolidSyslogSdElement_End(element); } static inline struct SolidSyslogTimeQualitySd* TimeQualitySd_SelfFromBase(struct SolidSyslogStructuredData* base) diff --git a/Tests/SolidSyslogMetaSdTest.cpp b/Tests/SolidSyslogMetaSdTest.cpp index 3122fda2..49e2b195 100644 --- a/Tests/SolidSyslogMetaSdTest.cpp +++ b/Tests/SolidSyslogMetaSdTest.cpp @@ -9,6 +9,7 @@ #include "SolidSyslogMetaSd.h" #include "SolidSyslogMetaSdErrors.h" #include "SolidSyslogPrival.h" +#include "SolidSyslogSdElementPrivate.h" #include "SolidSyslogSdValue.h" #include "SolidSyslogStructuredData.h" #include "SolidSyslogTunables.h" @@ -120,7 +121,9 @@ TEST_GROUP(SolidSyslogMetaSd) void format() const { - SolidSyslogStructuredData_Format(sd, formatter); + struct SolidSyslogSdElement element{}; + SolidSyslogSdElement_FromFormatter(&element, formatter); + SolidSyslogStructuredData_Format(sd, &element); } void resetFormatter() @@ -178,7 +181,7 @@ TEST(SolidSyslogMetaSd, UseAfterDestroyIsCrashSafeViaNullSdVtable) * Format through the stale handle is a safe no-op rather than a NULL-fn-pointer * crash. NullSd.Format writes nothing into the Formatter. */ SolidSyslogMetaSd_Destroy(sd); - SolidSyslogStructuredData_Format(sd, formatter); + format(); LONGS_EQUAL(0, SolidSyslogFormatter_Length(formatter)); sd = SolidSyslogMetaSd_Create(&config); // for teardown } diff --git a/Tests/SolidSyslogNullSdTest.cpp b/Tests/SolidSyslogNullSdTest.cpp index a25e80cb..dd1ef87c 100644 --- a/Tests/SolidSyslogNullSdTest.cpp +++ b/Tests/SolidSyslogNullSdTest.cpp @@ -1,6 +1,7 @@ #include "CppUTest/TestHarness.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogNullSd.h" +#include "SolidSyslogSdElementPrivate.h" #include "SolidSyslogStructuredData.h" // clang-format off @@ -21,6 +22,8 @@ TEST_GROUP(SolidSyslogNullSd) TEST(SolidSyslogNullSd, FormatWritesNothing) { - SolidSyslogStructuredData_Format(sd, formatter); + struct SolidSyslogSdElement element{}; + SolidSyslogSdElement_FromFormatter(&element, formatter); + SolidSyslogStructuredData_Format(sd, &element); LONGS_EQUAL(0, SolidSyslogFormatter_Length(formatter)); } diff --git a/Tests/SolidSyslogOriginSdTest.cpp b/Tests/SolidSyslogOriginSdTest.cpp index 383d0d14..ace47cd3 100644 --- a/Tests/SolidSyslogOriginSdTest.cpp +++ b/Tests/SolidSyslogOriginSdTest.cpp @@ -9,6 +9,7 @@ #include "SolidSyslogOriginSd.h" #include "SolidSyslogOriginSdErrors.h" #include "SolidSyslogPrival.h" +#include "SolidSyslogSdElementPrivate.h" #include "SolidSyslogSdValue.h" #include "SolidSyslogStructuredData.h" #include "SolidSyslogTunables.h" @@ -139,7 +140,9 @@ TEST_GROUP(SolidSyslogOriginSd) void format() const { - SolidSyslogStructuredData_Format(sd, formatter); + struct SolidSyslogSdElement element{}; + SolidSyslogSdElement_FromFormatter(&element, formatter); + SolidSyslogStructuredData_Format(sd, &element); } void resetFormatter() @@ -161,7 +164,7 @@ TEST(SolidSyslogOriginSd, UseAfterDestroyIsCrashSafeViaNullSdVtable) * Format through the stale handle is a safe no-op rather than a NULL-fn-pointer * crash. NullSd.Format writes nothing into the Formatter. */ SolidSyslogOriginSd_Destroy(sd); - SolidSyslogStructuredData_Format(sd, formatter); + format(); LONGS_EQUAL(0, SolidSyslogFormatter_Length(formatter)); sd = SolidSyslogOriginSd_Create(&config); // for teardown } diff --git a/Tests/SolidSyslogTest.cpp b/Tests/SolidSyslogTest.cpp index abe7bcbe..b20533ed 100644 --- a/Tests/SolidSyslogTest.cpp +++ b/Tests/SolidSyslogTest.cpp @@ -19,6 +19,7 @@ #include "SolidSyslogNullStore.h" #include "SolidSyslogPassthroughBuffer.h" #include "SolidSyslogPrival.h" +#include "SolidSyslogSdElement.h" #include "SolidSyslogStore.h" #include "SolidSyslogStructuredDataDefinition.h" #include "SolidSyslogTimeQuality.h" @@ -58,24 +59,23 @@ static const char * const TEST_MSG = "hello world"; #define CHECK_PROCID(expected) STRCMP_EQUAL(expected, SyslogField(lastMessage(), SYSLOG_FIELD_PROCID).c_str()) -static const char SD_SPY_TEXT[] = "[spy]"; -static const char SD_SPY2_TEXT[] = "[spy2]"; - -static void SdSpyFormat(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogFormatter* formatter) +static void SdSpyFormat(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogSdElement* element) { - SolidSyslogFormatter_BoundedString(formatter, SD_SPY_TEXT, sizeof(SD_SPY_TEXT) - 1); + SolidSyslogSdElement_Begin(element, "spy", 0U); + SolidSyslogSdElement_End(element); } static struct SolidSyslogStructuredData sdSpy = {SdSpyFormat}; -static void SdSpyFormat2(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogFormatter* formatter) +static void SdSpyFormat2(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogSdElement* element) { - SolidSyslogFormatter_BoundedString(formatter, SD_SPY2_TEXT, sizeof(SD_SPY2_TEXT) - 1); + SolidSyslogSdElement_Begin(element, "spy2", 0U); + SolidSyslogSdElement_End(element); } static struct SolidSyslogStructuredData sdSpy2 = {SdSpyFormat2}; -static void SdFailFormat(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogFormatter* /* formatter */) +static void SdFailFormat(struct SolidSyslogStructuredData* /* self */, struct SolidSyslogSdElement* /* element */) { } diff --git a/Tests/SolidSyslogTimeQualitySdTest.cpp b/Tests/SolidSyslogTimeQualitySdTest.cpp index 822805a2..3e2ec11d 100644 --- a/Tests/SolidSyslogTimeQualitySdTest.cpp +++ b/Tests/SolidSyslogTimeQualitySdTest.cpp @@ -6,6 +6,7 @@ #include "SolidSyslogErrorCategory.h" #include "SolidSyslogFormatter.h" #include "SolidSyslogPrival.h" +#include "SolidSyslogSdElementPrivate.h" #include "SolidSyslogStructuredData.h" #include "SolidSyslogTimeQuality.h" #include "SolidSyslogTimeQualitySd.h" @@ -51,7 +52,9 @@ TEST_GROUP(SolidSyslogTimeQualitySd) void format() const { - SolidSyslogStructuredData_Format(sd, formatter); + struct SolidSyslogSdElement element{}; + SolidSyslogSdElement_FromFormatter(&element, formatter); + SolidSyslogStructuredData_Format(sd, &element); } void resetFormatter() @@ -135,7 +138,7 @@ TEST(SolidSyslogTimeQualitySd, UseAfterDestroyIsCrashSafeViaNullSdVtable) * Format through the stale handle is a safe no-op rather than a NULL-fn-pointer * crash. NullSd.Format writes nothing into the Formatter. */ SolidSyslogTimeQualitySd_Destroy(sd); - SolidSyslogStructuredData_Format(sd, formatter); + format(); LONGS_EQUAL(0, SolidSyslogFormatter_Length(formatter)); sd = SolidSyslogTimeQualitySd_Create(StubGetTimeQuality); // for teardown } diff --git a/misra_suppressions.txt b/misra_suppressions.txt index 6ee11e41..3a942a3a 100644 --- a/misra_suppressions.txt +++ b/misra_suppressions.txt @@ -28,12 +28,12 @@ misra-c2012-11.3:Core/Source/SolidSyslogBlockStore.c:73 misra-c2012-11.3:Core/Source/SolidSyslogCircularBuffer.c:91 misra-c2012-11.3:Core/Source/SolidSyslogFileBlockDevice.c:106 misra-c2012-11.3:Core/Source/SolidSyslogFormatter.c:79 -misra-c2012-11.3:Core/Source/SolidSyslogMetaSd.c:64 -misra-c2012-11.3:Core/Source/SolidSyslogOriginSd.c:61 +misra-c2012-11.3:Core/Source/SolidSyslogMetaSd.c:60 +misra-c2012-11.3:Core/Source/SolidSyslogOriginSd.c:57 misra-c2012-11.3:Core/Source/SolidSyslogPassthroughBuffer.c:53 misra-c2012-11.3:Core/Source/SolidSyslogStreamSender.c:166 misra-c2012-11.3:Core/Source/SolidSyslogSwitchingSender.c:63 -misra-c2012-11.3:Core/Source/SolidSyslogTimeQualitySd.c:58 +misra-c2012-11.3:Core/Source/SolidSyslogTimeQualitySd.c:54 misra-c2012-11.3:Core/Source/SolidSyslogUdpSender.c:120 misra-c2012-11.3:Platform/Atomics/Source/SolidSyslogStdAtomicCounter.c:29 misra-c2012-11.3:Platform/FatFs/Source/SolidSyslogFatFsFile.c:59 @@ -111,11 +111,11 @@ misra-c2012-11.8:Core/Source/SolidSyslog.c:57 misra-c2012-11.8:Core/Source/SolidSyslog.c:58 misra-c2012-11.8:Core/Source/SolidSyslog.c:59 misra-c2012-11.8:Core/Source/SolidSyslog.c:60 -misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:57 -misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:59 -misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:61 -misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:63 -misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:67 +misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:58 +misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:60 +misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:62 +misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:64 +misra-c2012-11.8:Core/Source/SolidSyslogMessageFormatter.c:68 misra-c2012-11.8:Core/Source/SolidSyslogBlockStoreStatic.c:46 misra-c2012-11.8:Core/Source/SolidSyslogBlockStoreStatic.c:117 misra-c2012-11.8:Core/Source/SolidSyslogBlockStoreStatic.c:143 @@ -171,7 +171,7 @@ misra-c2012-5.7:Core/Interface/SolidSyslogFormatter.h:14 misra-c2012-5.7:Core/Interface/SolidSyslogSecurityPolicyDefinition.h:13 misra-c2012-5.7:Core/Interface/SolidSyslogTimeQuality.h:12 misra-c2012-5.7:Core/Interface/SolidSyslogTransport.h:5 -misra-c2012-5.7:Core/Source/SolidSyslogMessageFormatter.c:19 +misra-c2012-5.7:Core/Source/SolidSyslogMessageFormatter.c:20 misra-c2012-5.7:Core/Source/SolidSyslogCircularBuffer.c:19 misra-c2012-5.7:Core/Source/SolidSyslogCrc16.c:12 misra-c2012-5.7:Core/Source/SolidSyslogCrc16Policy.c:10 From 455f012ec8a5ee84dd36d7759fbcff167d32ddfb Mon Sep 17 00:00:00 2001 From: David Cozens Date: Sat, 6 Jun 2026 07:12:38 +0000 Subject: [PATCH 2/2] docs: update DEVLOG for S14.06 SD vtable flip Co-Authored-By: Claude Opus 4.8 (1M context) --- DEVLOG.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/DEVLOG.md b/DEVLOG.md index 48e1a961..275ca80c 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -14520,3 +14520,34 @@ MISRA rule — different category, doesn't set precedent. ### Open questions - None outstanding. + +## 2026-06-06 — S14.06: flip the SD vtable to SolidSyslogSdElement + +### Decisions +- **Flipped the SD extension point.** `struct SolidSyslogStructuredData.Format` and the + `SolidSyslogStructuredData_Format` dispatch wrapper now take a + `struct SolidSyslogSdElement*` instead of a raw `struct SolidSyslogFormatter*`. A + custom-SD author's `Format` can no longer reach a formatter — the footgun is closed at + the vtable itself, the payoff of the S14.03–05 migrations. +- **One element per message.** Moved the `SolidSyslogSdElement_FromFormatter` wrap up into + `MessageFormatter_FormatStructuredData`: build the element once, pass it to each SD in + the existing order. `SolidSyslogSdElement_Begin` resets the element's per-SD state, so a + single instance hosts every configured SD sequentially (`[meta…][origin…]`). +- **SDs slimmed.** MetaSd / OriginSd / TimeQualitySd drop their local `element` + + `_FromFormatter` and emit straight onto the handed element; they now include the public + `SolidSyslogSdElement.h` rather than the private header. NullSd's no-op signature + follows. Byte-for-byte identical output (existing tests stand). SD test doubles' `Format` + signatures updated; the `[spy]`/`[spy2]` spies now emit via `_Begin`/`_End`; each SD + unit test's `format()` helper and `SolidSyslogNullSdTest` build the element from the + formatter via the private `_FromFormatter`. +- Checks: debug green (1459 tests), BddTargetTests 66/66; clang-format applied; + cppcheck-MISRA exit 0 (anchors moved: MetaSd 11.3 64→60, OriginSd 11.3 61→57, + TimeQualitySd 11.3 58→54, MessageFormatter 11.8 ×5 +1 and 5.7 19→20). + +### Deferred +- Header-field callbacks still take a formatter until S14.07; moving + `SolidSyslogFormatter.h` out of the public interface is S14.08 (along with the CLAUDE.md + header-table revision). + +### Open questions +- None outstanding.