@@ -99,25 +99,37 @@ of the codebase to see them in action.
9999 ` PdbCacheEntry.module_path ` are the canonical references.
100100- ** A ` (Zstr, length) ` API always ships with a ` Str ` overload.** If a
101101 function takes a Zstr together with an explicit length (i.e. it's
102- basically a Str minus the wrapper), provide a ` Str ` / ` const Str * `
103- variant alongside via ` _Generic ` or ` MISRA_OVERLOAD ` so callers
104- holding a Str don't have to reach inside for ` .length ` and ` .data ` .
105- The ` Cstr ` / ` Zstr ` / unsuffixed naming pattern in the codebase is
106- the canonical shape:
102+ basically a Str minus the wrapper), provide a ` Str ` overload
103+ alongside so callers holding a ` Str ` don't have to reach inside for
104+ ` .length ` and ` .data ` . The canonical shape is the ` Cstr ` / ` Zstr ` /
105+ unsuffixed-Str naming pattern as ** private snake_case backends in
106+ a ` Private.h ` ** (one file per namespace) plus a ** single public
107+ ` PascalCase ` macro** on top, dispatching via ` MISRA_OVERLOAD `
108+ (arg count for the Cstr variant) and ` _Generic ` (` Str * ` vs ` Zstr ` ):
107109
108110 ``` c
109- bool StrStartsWithCstr (const Str * s, Zstr prefix, size prefix_len);
110- bool StrStartsWithZstr(const Str * s, Zstr prefix);
111- bool StrStartsWith(const Str * s, const Str * prefix);
111+ // Private — Std/Container/Str/Private.h (one backend per shape).
112+ bool str_starts_with_str (const Str * s, const Str * prefix);
113+ bool str_starts_with_zstr (const Str * s, Zstr prefix);
114+ bool str_starts_with_cstr (const Str * s, Zstr prefix, size prefix_len);
115+
116+ // Public — Std/Container/Str/Ops.h (single unified entry point).
117+ #define StrStartsWith(...) MISRA_OVERLOAD(StrStartsWith, __ VA_ARGS__ )
118+ #define StrStartsWith_2(s, prefix) \
119+ _ Generic((prefix), \
120+ Str * : str_starts_with_str ((s), (const Str * )(prefix)), \
121+ Zstr: str_starts_with_zstr((s), (Zstr)(prefix)))
122+ #define StrStartsWith_3(s, prefix, prefix_len) \
123+ str_starts_with_cstr((s), (Zstr)(prefix), (prefix_len))
112124 ```
113125
114- All three exist so the caller can pass whichever shape they have on
115- hand without juggling fields . Same applies whenever a `Zstr`
116- parameter shows up — add a `Str` overload (by value or by pointer,
117- whichever fits the call shape) so user code that lives in `Str`-land
118- stays there. Adding the `Str` overload is also a chance to surface
119- cases where the function should really be Str-only: if no caller
120- ever wants the Zstr form, you don't need it .
126+ The user-facing surface is just `StrStartsWith` — callers never type
127+ `*Cstr` / `*Zstr` suffixes . Same applies whenever a `Zstr` parameter
128+ shows up: add the `Str` overload (or surface that the function
129+ should be `Str`-only — if no caller ever wants the `Zstr` form, you
130+ don't need it). The reference implementations are
131+ `Std/Container/ Str/Ops.h`'s `StrStartsWith`, `StrEndsWith`,
132+ `StrIndexOf`, `StrContains`, `StrReplace` families .
121133- **Accessor macros are read-only.** `VecLen`, `VecCapacity`,
122134 `StrCapacity`, `MapPairCount`, `ListHead`, `BitVecData`, etc. expose
123135 state for inspection; they don't mutate. Mutation always goes through
0 commit comments