Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions Core/Interface/SolidSyslogStructuredData.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions Core/Interface/SolidSyslogStructuredDataDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion Core/Source/SolidSyslogMessageFormatter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
20 changes: 8 additions & 12 deletions Core/Source/SolidSyslogMetaSd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions Core/Source/SolidSyslogNullSd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

#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)
{
static struct SolidSyslogStructuredData instance = {.Format = NullSd_Format};
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;
}
22 changes: 9 additions & 13 deletions Core/Source/SolidSyslogOriginSd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions Core/Source/SolidSyslogStructuredData.c
Original file line number Diff line number Diff line change
@@ -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);
}
20 changes: 8 additions & 12 deletions Core/Source/SolidSyslogTimeQualitySd.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@

#include "SolidSyslogError.h"
#include "SolidSyslogNullSd.h"
#include "SolidSyslogSdElementPrivate.h"
#include "SolidSyslogSdElement.h"
#include "SolidSyslogSdValue.h"
#include "SolidSyslogStructuredDataDefinition.h"
#include "SolidSyslogTimeQualitySdErrors.h"
#include "SolidSyslogTimeQualitySdPrivate.h"

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);

Expand All @@ -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)
Expand Down
31 changes: 31 additions & 0 deletions DEVLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
7 changes: 5 additions & 2 deletions Tests/SolidSyslogMetaSdTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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
}
Expand Down
5 changes: 4 additions & 1 deletion Tests/SolidSyslogNullSdTest.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "CppUTest/TestHarness.h"
#include "SolidSyslogFormatter.h"
#include "SolidSyslogNullSd.h"
#include "SolidSyslogSdElementPrivate.h"
#include "SolidSyslogStructuredData.h"

// clang-format off
Expand All @@ -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));
}
7 changes: 5 additions & 2 deletions Tests/SolidSyslogOriginSdTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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()
Expand All @@ -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
}
Expand Down
16 changes: 8 additions & 8 deletions Tests/SolidSyslogTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 */)
{
}

Expand Down
Loading
Loading