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
3 changes: 1 addition & 2 deletions Core/Source/SolidSyslogNullAtomicCounter.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

static uint32_t NullAtomicCounter_Increment(struct SolidSyslogAtomicCounter* base);

static struct SolidSyslogAtomicCounter instance = {.Increment = NullAtomicCounter_Increment};

struct SolidSyslogAtomicCounter* SolidSyslogNullAtomicCounter_Get(void)
{
static struct SolidSyslogAtomicCounter instance = {.Increment = NullAtomicCounter_Increment};
return &instance;
}

Expand Down
19 changes: 9 additions & 10 deletions Core/Source/SolidSyslogNullBlockDevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,17 @@ static bool NullBlockDevice_Append(
);
static size_t NullBlockDevice_Size(struct SolidSyslogBlockDevice* base, size_t blockIndex);

static struct SolidSyslogBlockDevice instance = {
.Acquire = NullBlockDevice_Acquire,
.Dispose = NullBlockDevice_Dispose,
.Exists = NullBlockDevice_Exists,
.Read = NullBlockDevice_Read,
.Append = NullBlockDevice_Append,
.WriteAt = NullBlockDevice_WriteAt,
.Size = NullBlockDevice_Size,
};

struct SolidSyslogBlockDevice* SolidSyslogNullBlockDevice_Get(void)
{
static struct SolidSyslogBlockDevice instance = {
.Acquire = NullBlockDevice_Acquire,
.Dispose = NullBlockDevice_Dispose,
.Exists = NullBlockDevice_Exists,
.Read = NullBlockDevice_Read,
.Append = NullBlockDevice_Append,
.WriteAt = NullBlockDevice_WriteAt,
.Size = NullBlockDevice_Size,
};
return &instance;
}

Expand Down
3 changes: 1 addition & 2 deletions Core/Source/SolidSyslogNullBuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
static bool NullBuffer_Read(struct SolidSyslogBuffer* base, void* data, size_t maxSize, size_t* bytesRead);
static void NullBuffer_Write(struct SolidSyslogBuffer* base, const void* data, size_t size);

static struct SolidSyslogBuffer instance = {.Write = NullBuffer_Write, .Read = NullBuffer_Read};

struct SolidSyslogBuffer* SolidSyslogNullBuffer_Get(void)
{
static struct SolidSyslogBuffer instance = {.Write = NullBuffer_Write, .Read = NullBuffer_Read};
return &instance;
}

Expand Down
13 changes: 6 additions & 7 deletions Core/Source/SolidSyslogNullDatagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ static enum SolidSyslogDatagramSendResult NullDatagram_SendTo(
static size_t NullDatagram_MaxPayload(struct SolidSyslogDatagram* base);
static void NullDatagram_Close(struct SolidSyslogDatagram* base);

static struct SolidSyslogDatagram instance = {
.Open = NullDatagram_Open,
.SendTo = NullDatagram_SendTo,
.MaxPayload = NullDatagram_MaxPayload,
.Close = NullDatagram_Close,
};

struct SolidSyslogDatagram* SolidSyslogNullDatagram_Get(void)
{
static struct SolidSyslogDatagram instance = {
.Open = NullDatagram_Open,
.SendTo = NullDatagram_SendTo,
.MaxPayload = NullDatagram_MaxPayload,
.Close = NullDatagram_Close,
};
return &instance;
}

Expand Down
25 changes: 12 additions & 13 deletions Core/Source/SolidSyslogNullFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,20 @@ static void NullFile_Truncate(struct SolidSyslogFile* base);
static bool NullFile_Exists(struct SolidSyslogFile* base, const char* path);
static bool NullFile_Delete(struct SolidSyslogFile* base, const char* path);

static struct SolidSyslogFile instance = {
.Open = NullFile_Open,
.Close = NullFile_Close,
.IsOpen = NullFile_IsOpen,
.Read = NullFile_Read,
.Write = NullFile_Write,
.SeekTo = NullFile_SeekTo,
.Size = NullFile_Size,
.Truncate = NullFile_Truncate,
.Exists = NullFile_Exists,
.Delete = NullFile_Delete,
};

struct SolidSyslogFile* SolidSyslogNullFile_Get(void)
{
static struct SolidSyslogFile instance = {
.Open = NullFile_Open,
.Close = NullFile_Close,
.IsOpen = NullFile_IsOpen,
.Read = NullFile_Read,
.Write = NullFile_Write,
.SeekTo = NullFile_SeekTo,
.Size = NullFile_Size,
.Truncate = NullFile_Truncate,
.Exists = NullFile_Exists,
.Delete = NullFile_Delete,
};
return &instance;
}

Expand Down
9 changes: 4 additions & 5 deletions Core/Source/SolidSyslogNullMutex.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
static void NullMutex_Lock(struct SolidSyslogMutex* base);
static void NullMutex_Unlock(struct SolidSyslogMutex* base);

static struct SolidSyslogMutex instance = {
.Lock = NullMutex_Lock,
.Unlock = NullMutex_Unlock,
};

struct SolidSyslogMutex* SolidSyslogNullMutex_Get(void)
{
static struct SolidSyslogMutex instance = {
.Lock = NullMutex_Lock,
.Unlock = NullMutex_Unlock,
};
return &instance;
}

Expand Down
3 changes: 1 addition & 2 deletions Core/Source/SolidSyslogNullResolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ static bool NullResolver_Resolve(
struct SolidSyslogAddress* result
);

static struct SolidSyslogResolver instance = {.Resolve = NullResolver_Resolve};

struct SolidSyslogResolver* SolidSyslogNullResolver_Get(void)
{
static struct SolidSyslogResolver instance = {.Resolve = NullResolver_Resolve};
return &instance;
}

Expand Down
3 changes: 1 addition & 2 deletions Core/Source/SolidSyslogNullSd.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ struct SolidSyslogFormatter;

static void NullSd_Format(struct SolidSyslogStructuredData* base, struct SolidSyslogFormatter* formatter);

static struct SolidSyslogStructuredData instance = {.Format = NullSd_Format};

struct SolidSyslogStructuredData* SolidSyslogNullSd_Get(void)
{
static struct SolidSyslogStructuredData instance = {.Format = NullSd_Format};
return &instance;
}

Expand Down
11 changes: 5 additions & 6 deletions Core/Source/SolidSyslogNullSecurityPolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ static bool NullSecurityPolicy_NullVerifyIntegrity(const uint8_t* data, uint16_t
return true;
}

static struct SolidSyslogSecurityPolicy instance = {
0,
NullSecurityPolicy_NullComputeIntegrity,
NullSecurityPolicy_NullVerifyIntegrity,
};

struct SolidSyslogSecurityPolicy* SolidSyslogNullSecurityPolicy_Get(void)
{
static struct SolidSyslogSecurityPolicy instance = {
0,
NullSecurityPolicy_NullComputeIntegrity,
NullSecurityPolicy_NullVerifyIntegrity,
};
return &instance;
}
3 changes: 1 addition & 2 deletions Core/Source/SolidSyslogNullSender.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
static bool NullSender_Send(struct SolidSyslogSender* base, const void* buffer, size_t size);
static void NullSender_Disconnect(struct SolidSyslogSender* base);

static struct SolidSyslogSender instance = {.Send = NullSender_Send, .Disconnect = NullSender_Disconnect};

struct SolidSyslogSender* SolidSyslogNullSender_Get(void)
{
static struct SolidSyslogSender instance = {.Send = NullSender_Send, .Disconnect = NullSender_Disconnect};
return &instance;
}

Expand Down
21 changes: 10 additions & 11 deletions Core/Source/SolidSyslogNullStore.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@ static size_t NullStore_GetTotalBytes(struct SolidSyslogStore* base);
static size_t NullStore_GetUsedBytes(struct SolidSyslogStore* base);
static bool NullStore_IsTransient(struct SolidSyslogStore* base);

static struct SolidSyslogStore instance = {
.Write = NullStore_Write,
.ReadNextUnsent = NullStore_ReadNextUnsent,
.MarkSent = NullStore_MarkSent,
.HasUnsent = NullStore_HasUnsent,
.IsHalted = NullStore_IsHalted,
.GetTotalBytes = NullStore_GetTotalBytes,
.GetUsedBytes = NullStore_GetUsedBytes,
.IsTransient = NullStore_IsTransient
};

struct SolidSyslogStore* SolidSyslogNullStore_Get(void)
{
static struct SolidSyslogStore instance = {
.Write = NullStore_Write,
.ReadNextUnsent = NullStore_ReadNextUnsent,
.MarkSent = NullStore_MarkSent,
.HasUnsent = NullStore_HasUnsent,
.IsHalted = NullStore_IsHalted,
.GetTotalBytes = NullStore_GetTotalBytes,
.GetUsedBytes = NullStore_GetUsedBytes,
.IsTransient = NullStore_IsTransient
};
return &instance;
}

Expand Down
13 changes: 6 additions & 7 deletions Core/Source/SolidSyslogNullStream.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ static bool NullStream_Send(struct SolidSyslogStream* base, const void* buffer,
static SolidSyslogSsize NullStream_Read(struct SolidSyslogStream* base, void* buffer, size_t size);
static void NullStream_Close(struct SolidSyslogStream* base);

static struct SolidSyslogStream instance = {
.Open = NullStream_Open,
.Send = NullStream_Send,
.Read = NullStream_Read,
.Close = NullStream_Close,
};

struct SolidSyslogStream* SolidSyslogNullStream_Get(void)
{
static struct SolidSyslogStream instance = {
.Open = NullStream_Open,
.Send = NullStream_Send,
.Read = NullStream_Read,
.Close = NullStream_Close,
};
return &instance;
}

Expand Down
11 changes: 6 additions & 5 deletions Core/Source/SolidSyslogUdpPayload.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ size_t SolidSyslogUdpPayload_FromMtu(size_t mtu, bool isIpv6)

size_t SolidSyslogUdpPayload_TrimToCodepointBoundary(const uint8_t* buffer, size_t length)
{
if (length > 0U)
size_t trimmed = length;
if (trimmed > 0U)
{
size_t lastCodepointStart = UdpPayload_FindLastCodepointStart(buffer, length);
if (UdpPayload_LastCodepointExtendsPastCut(buffer, length, lastCodepointStart))
size_t lastCodepointStart = UdpPayload_FindLastCodepointStart(buffer, trimmed);
if (UdpPayload_LastCodepointExtendsPastCut(buffer, trimmed, lastCodepointStart))
{
length = lastCodepointStart;
trimmed = lastCodepointStart;
}
}
return length;
return trimmed;
}

static inline size_t UdpPayload_FindLastCodepointStart(const uint8_t* buffer, size_t length)
Expand Down
93 changes: 93 additions & 0 deletions DEVLOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,98 @@
# Dev Log

## 2026-05-22 — S10.16 Senders conformance

Closes S10.16 (#389). Fifth per-group conformance story in E10,
applying the S10.12 pilot recipe to the Senders cluster
(`Sender`, `NullSender`, `UdpSender`, `StreamSender`, `SwitchingSender`,
`UdpPayload` plus the E11 three-TU split files for the three pool-backed
senders). Started from the CI cppcheck-misra report against `main@ddbc81f`
— `analyze-tidy` was already clean against the cluster, so the work was
entirely on the cppcheck-misra side.

### Findings landscape

Six unsuppressed findings against scope in the starting CI report:

- Four were one-line **anchor drift** in `misra_suppressions.txt`. The
11.3 / 11.5 vtable-cast lines were anchored at the closing `}` of
the inline `SelfFromBase` (or the comment line for 11.5); cppcheck
actually reports at the cast-expression line one above. The 5.7
anchor on the StreamSender anonymous enum was at the first constant
rather than the `{`. `SwitchingSender:59` matched by coincidence
(cast and brace on the same line).
- One **genuine fix** at `UdpPayload.c:37` — function parameter
`length` mutated in-place (rule 17.8). Introduced a local `trimmed`
copy. The audit anticipated this site; the three sibling 17.8 sites
in `SolidSyslogFormatter.c` belong to S10.19.
- One **family-wide pattern fix** at `NullSender.c:11` (rule 8.9).
The file-scope `static struct SolidSyslogSender instance = {...}`
is only used by the `_Get()` accessor — moving it inside the
accessor as a function-scope `static` narrows the identifier scope
per MISRA 8.9 with identical semantics (program-duration storage,
stable address).

### Decisions taken at the bend

- **8.9 — sweep all twelve sister null-objects, not just NullSender.**
The 8.9 finding fires on every `Null*.c` file (NullAtomicCounter,
NullBlockDevice, NullBuffer, NullDatagram, NullFile, NullMutex,
NullResolver, NullSd, NullSecurityPolicy, NullSender, NullStore,
NullStream). None were previously suppressed, so the cluster has
always been pending decision. The sender-only fix would have left
the family inconsistent for the duration of S10.17–S10.19, and the
diff per file is tiny. David's call: fix-when-we-see-it across
the family. No new deviation.
- **D.009 widened to cover rule 5.7 in addition to 2.4.** cppcheck
fires both rules on the same anonymous-enum named-constant idiom,
for the same syntactic shape. Splitting them across D.003 (which
is strictly about struct-tag repetition) and D.009 added noise to
no benefit. D.009's title and rule statement now name both rules;
the three Senders-scope 5.7-on-anonymous-enum suppressions
(`UdpPayload.h:15`, `StreamSender.c:19`, `UdpPayload.c:5`)
moved from the D.003 block to the D.009 block. Other historical
5.7-on-anonymous-enum suppressions stay in the D.003 block until
S10.17 / S10.18 / S10.19 review their clusters — the deviation
that authorises each line is determined by the identifier kind,
not by the physical block.

### Cppcheck dedup surfaced a second drift

Re-running cppcheck after the 5.7 anchor fix surfaced rule 2.4 at
`SolidSyslogStreamSender.c:19` — the existing 2.4 suppression at
line 20 had been shadowed by the matching (mis-anchored) 5.7 at the
same site. With 5.7 correctly at line 19, the 2.4 finding emerged.
Sister anonymous-enum 2.4 suppressions (`BlockSequence.c:13`,
`RecordStore.c:14`, `Transport.h:5`) already anchor at the `{`
line. One more line bump, no new behaviour. Worth noting for
future per-group stories: removing one suppression can unmask
another on the same source line.

### Acceptance

- Zero in-scope `analyze-tidy` warnings (unchanged from starting state).
- Zero in-scope `cppcheck-misra` findings after the fixes (verified
against the same `ghcr.io/davidcozens/cpputest:sha-18f19e1` image
the CI uses).
- 1290/1290 tests pass on `debug` and `sanitize`.
- Tree-wide coverage 99.9% (2921/2925 lines, 602/602 functions);
uncovered lines sit in `BlockStoreStatic.c` and `PosixMutex.c` and
are pre-existing — none of the changed files lost coverage.
- clang-format clean tree-wide.
- No new deviations; no new inline suppressions; one count-bump on
D.009 (three 5.7-on-anonymous-enum lines migrated in).

### Scope clean-up noted for the issue body

`UdpSender` is already three-TU-split under E11
(`SolidSyslogUdpSenderPrivate.h`, `SolidSyslogUdpSenderStatic.c`) but
the original issue body listed only `SolidSyslogUdpSender.c`. The
`SolidSyslogNullSender.{c,h}` files were also added by E11 and missing
from the original scope list. Both are folded into S10.16 — issue body
updated to reflect.

---

## 2026-05-22 — S24.08 top-down function ordering sweep

Closes S24.08 (#423). Pure refactoring pass: re-applied the documented
Expand Down
Loading
Loading