Skip to content

Commit 979b34c

Browse files
init: convert ArgParse/MachoCache/PdbCache to compound-literal macros
These three were the only non-I/O inits still doing function-shaped construction. Their bodies were trivial -- field assigns plus a nested VecInit -- so they fit the same compound-literal pattern the rest of the codebase uses (StrInit / VecInit / MapInit / HttpRequestInit). `ArgParseInit` keeps the `(name, about[, alloc])` shape and now expands to `((ArgParse){.alloc = ALLOCATOR_OF(...), .name = ..., .about = ..., .specs = VecInit_1(...)})`. The macro parameters are renamed `prog_name` / `prog_about` so they don't shadow the `.name` / `.about` field designators when the preprocessor substitutes the args inside the compound literal -- a portability requirement, not a stylistic one. The NULL-`name` runtime guard is dropped: `ALLOCATOR_OF` already enforces a typed allocator at compile time and callers pass string literals for `name`. `MachoCacheInit` / `PdbCacheInit` shift from `bool fn(T *out, Allocator *)` to return-by-value compound literal. The two Backtrace callsites are rewritten to gate on `alloc` first (`bool ok = alloc != NULL; T c = ok ? Init(alloc) : (T){0};`) and the test callers drop the `&out` argument. The bool return was already effectively redundant: the only failure path was a NULL out-pointer that never occurred in any caller. Linux 104/104 + Mac 99/99 green.
1 parent b21a6b9 commit 979b34c

9 files changed

Lines changed: 48 additions & 76 deletions

File tree

Include/Misra/Std/ArgParse.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,23 +137,28 @@ extern "C" {
137137
} ArgParse;
138138

139139
///
140-
/// Create a parser. Registers `-h` / `--help` automatically. The
141-
/// `name` and `about` pointers are borrowed -- they must outlive
142-
/// the parser (string literals are the typical case).
140+
/// Create a parser. The `name` and `about` pointers are borrowed --
141+
/// they must outlive the parser (string literals are the typical
142+
/// case). The `-h` / `--help` flag is registered lazily on the
143+
/// first `ArgParseRun` / `ArgParseHelp` call.
143144
///
144145
/// Two call shapes, like `StrInit` / `VecInitT`:
145146
/// `ArgParseInit(name, about)` -- uses the surrounding
146147
/// `Scope`'s allocator.
147148
/// `ArgParseInit(name, about, alloc)` -- explicit allocator.
148149
///
149-
/// SUCCESS: Returns an initialized parser.
150-
/// FAILURE: Aborts via `LOG_FATAL` on allocator OOM.
151-
///
152-
ArgParse arg_parse_init(Zstr name, Zstr about, Allocator *alloc);
153-
154-
#define ArgParseInit(...) MISRA_OVERLOAD(ArgParseInit, __VA_ARGS__)
155-
#define ArgParseInit_2(name, about) arg_parse_init((name), (about), MisraScope)
156-
#define ArgParseInit_3(name, about, alloc_ptr) arg_parse_init((name), (about), ALLOCATOR_OF(alloc_ptr))
150+
/// SUCCESS: Yields an initialized parser. The `specs` Vec is empty;
151+
/// add specs with `ArgParseAddPositional` / etc.
152+
/// FAILURE: Cannot fail at construction; first allocator OOM
153+
/// surfaces from later spec-Vec growth.
154+
///
155+
#define ArgParseInit(...) MISRA_OVERLOAD(ArgParseInit, __VA_ARGS__)
156+
#define ArgParseInit_2(prog_name, prog_about) ArgParseInit_3((prog_name), (prog_about), MisraScope)
157+
#define ArgParseInit_3(prog_name, prog_about, alloc_ptr) \
158+
((ArgParse) {.alloc = ALLOCATOR_OF(alloc_ptr), \
159+
.name = (prog_name), \
160+
.about = (prog_about), \
161+
.specs = VecInit_1(alloc_ptr)})
157162

158163
///
159164
/// Release the spec Vec. Safe on a fully-initialised parser; not

Include/Misra/Sys/MachoCache.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,21 @@ typedef struct MachoCache {
4848
} MachoCache;
4949

5050
///
51-
/// Initialise an empty Mach-O symbol cache.
51+
/// Initialise an empty Mach-O symbol cache. The allocator argument
52+
/// is optional inside a `Scope` block (defaults to `MisraScope`) and
53+
/// backs both the entries Vec and every Mach-O / DWARF table the
54+
/// cache grows lazily.
5255
///
53-
/// out[out] : Cache to initialise.
54-
/// alloc[in] : Allocator used for the entries vector and for
55-
/// every Mach-O / DWARF table the cache grows lazily.
56+
/// SUCCESS : Yields a `MachoCache` whose `entries` Vec is empty and
57+
/// ready for use.
58+
/// FAILURE : Cannot fail at construction; first allocator OOM
59+
/// surfaces from later `entries` growth.
5660
///
57-
/// SUCCESS : Returns true. `out` is a usable empty cache.
58-
/// FAILURE : Returns false on allocator OOM. `out` is left zeroed.
61+
/// TAGS: Sys, MachO, Cache, Init, Lifecycle
5962
///
60-
bool macho_cache_init(MachoCache *out, Allocator *alloc);
61-
#define MachoCacheInit(...) MISRA_OVERLOAD(MachoCacheInit, __VA_ARGS__)
62-
#define MachoCacheInit_1(out) macho_cache_init((out), MisraScope)
63-
#define MachoCacheInit_2(out, alloc) macho_cache_init((out), ALLOCATOR_OF(alloc))
63+
#define MachoCacheInit(...) MISRA_OVERLOAD(MachoCacheInit, __VA_ARGS__)
64+
#define MachoCacheInit_0() MachoCacheInit_1(MisraScope)
65+
#define MachoCacheInit_1(alloc_ptr) ((MachoCache) {.allocator = ALLOCATOR_OF(alloc_ptr), .entries = VecInit_1(alloc_ptr)})
6466

6567
///
6668
/// Release every cached Mach-O / DWARF table and the entries vector.

Include/Misra/Sys/PdbCache.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,19 @@ typedef struct PdbCache {
4747
} PdbCache;
4848

4949
///
50-
/// Initialize an empty cache.
50+
/// Initialize an empty cache. The allocator argument is optional
51+
/// inside a `Scope` block (defaults to `MisraScope`).
5152
///
52-
/// SUCCESS : Returns true; `out` is zeroed and ready for `Resolve`.
53-
/// FAILURE : Returns false on NULL arg.
53+
/// SUCCESS : Yields a `PdbCache` whose `entries` Vec is empty and
54+
/// ready for `Resolve`.
55+
/// FAILURE : Cannot fail at construction; first allocator OOM
56+
/// surfaces from later `entries` growth.
5457
///
55-
bool pdb_cache_init(PdbCache *out, Allocator *alloc);
56-
#define PdbCacheInit(...) MISRA_OVERLOAD(PdbCacheInit, __VA_ARGS__)
57-
#define PdbCacheInit_1(out) pdb_cache_init((out), MisraScope)
58-
#define PdbCacheInit_2(out, alloc) pdb_cache_init((out), ALLOCATOR_OF(alloc))
58+
/// TAGS: Sys, PDB, Cache, Init, Lifecycle
59+
///
60+
#define PdbCacheInit(...) MISRA_OVERLOAD(PdbCacheInit, __VA_ARGS__)
61+
#define PdbCacheInit_0() PdbCacheInit_1(MisraScope)
62+
#define PdbCacheInit_1(alloc_ptr) ((PdbCache) {.allocator = ALLOCATOR_OF(alloc_ptr), .entries = VecInit_1(alloc_ptr)})
5963

6064
///
6165
/// Tear down the cache, releasing every cached `Pe` and `Pdb`.

Source/Misra/Std/ArgParse.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -461,19 +461,6 @@ void arg_register(
461461
/* Lifecycle + run */
462462
/* ------------------------------------------------------------------ */
463463

464-
ArgParse arg_parse_init(Zstr name, Zstr about, Allocator *alloc) {
465-
if (!name)
466-
LOG_FATAL("ArgParseInit: name is required");
467-
if (!alloc)
468-
LOG_FATAL("ArgParseInit: allocator is required");
469-
ArgParse p = {0};
470-
p.alloc = alloc;
471-
p.name = name;
472-
p.about = about;
473-
p.specs = VecInitT(p.specs, alloc);
474-
return p;
475-
}
476-
477464
void ArgParseDeinit(ArgParse *self) {
478465
if (!self)
479466
return;

Source/Misra/Sys/Backtrace.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ static void format_walk_win(Str *out, const StackFrame *frames, size count, Allo
177177
line.SizeOfStruct = sizeof(line);
178178

179179
# if FEATURE_PARSER_PDB
180-
PdbCache pdb_cache;
181-
bool pdb_cache_ok = alloc && PdbCacheInit(&pdb_cache, alloc);
180+
bool pdb_cache_ok = (alloc != NULL);
181+
PdbCache pdb_cache = pdb_cache_ok ? PdbCacheInit(alloc) : (PdbCache) {0};
182182
# else
183183
(void)alloc;
184184
# endif
@@ -389,8 +389,8 @@ static bool dyld_image_for_ip(void *ip, Zstr *out_path, u64 *out_slide) {
389389

390390
static void format_walk_mac(Str *out, const StackFrame *frames, size count, Allocator *alloc) {
391391
# if FEATURE_PARSER_MACHO
392-
MachoCache cache;
393-
bool cache_ok = alloc && MachoCacheInit(&cache, alloc);
392+
bool cache_ok = (alloc != NULL);
393+
MachoCache cache = cache_ok ? MachoCacheInit(alloc) : (MachoCache) {0};
394394
# else
395395
(void)alloc;
396396
# endif

Source/Misra/Sys/MachoCache.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,6 @@ static bool entry_build_dwarf(MachoCacheEntry *e, Allocator *alloc) {
149149
// Public API
150150
// ---------------------------------------------------------------------------
151151

152-
bool macho_cache_init(MachoCache *out, Allocator *alloc) {
153-
if (!out || !alloc)
154-
return false;
155-
MemSet(out, 0, sizeof(*out));
156-
out->allocator = alloc;
157-
out->entries = VecInitT(out->entries, alloc);
158-
return true;
159-
}
160-
161152
void MachoCacheDeinit(MachoCache *self) {
162153
if (!self)
163154
return;

Source/Misra/Sys/PdbCache.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,6 @@ static PdbCacheEntry *cache_find_or_open(PdbCache *self, Zstr module_path) {
152152
// Public API
153153
// ---------------------------------------------------------------------------
154154

155-
bool pdb_cache_init(PdbCache *out, Allocator *alloc) {
156-
if (!out || !alloc)
157-
return false;
158-
MemSet(out, 0, sizeof(*out));
159-
out->allocator = alloc;
160-
out->entries = VecInitT(out->entries, alloc);
161-
return true;
162-
}
163-
164155
void PdbCacheDeinit(PdbCache *self) {
165156
if (!self)
166157
return;

Tests/Std/MachoCache.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ bool test_macho_cache_resolves_via_main_symtab(void) {
185185
return false;
186186
}
187187

188-
MachoCache cache;
189-
MachoCacheInit(&cache, base);
188+
MachoCache cache = MachoCacheInit(base);
190189

191190
// slide chosen so runtime_ip - slide = 0x100000110 (10 bytes past
192191
// function start)
@@ -225,8 +224,7 @@ bool test_macho_cache_falls_through_to_dsym(void) {
225224
return false;
226225
}
227226

228-
MachoCache cache;
229-
MachoCacheInit(&cache, base);
227+
MachoCache cache = MachoCacheInit(base);
230228

231229
const u64 slide = 0;
232230
const u64 runtime_ip = 0x100000208ull; // 8 bytes into dsym_only_fn
@@ -264,8 +262,7 @@ bool test_macho_cache_rejects_uuid_mismatch(void) {
264262
write_file(bin_path, bin_buf, bin_size);
265263
write_file(dsym_path, dsym_buf, dsym_size);
266264

267-
MachoCache cache;
268-
MachoCacheInit(&cache, base);
265+
MachoCache cache = MachoCacheInit(base);
269266

270267
Zstr name = NULL;
271268
bool ok = !MachoCacheResolve(&cache, bin_path, 0, 0x100000208ull, &name, NULL);

Tests/Std/PdbCache.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,7 @@ bool test_pdb_cache_resolves_via_codeview(void) {
285285
return false;
286286
}
287287

288-
PdbCache cache;
289-
if (!PdbCacheInit(&cache, base)) {
290-
DefaultAllocatorDeinit(&alloc);
291-
return false;
292-
}
288+
PdbCache cache = PdbCacheInit(base);
293289

294290
// module_base = 0x140000000 -> RVA = (ip - base). For func at
295291
// RVA 0x1100, ip = module_base + 0x1100.
@@ -323,8 +319,7 @@ bool test_pdb_cache_rejects_unknown_module(void) {
323319
char missing[1024];
324320
tmp_path_join(missing, sizeof(missing), "misra_pdbcache_missing_xyz.exe");
325321

326-
PdbCache cache;
327-
PdbCacheInit(&cache, base);
322+
PdbCache cache = PdbCacheInit(base);
328323
Zstr name = NULL;
329324
bool ok = !PdbCacheResolve(&cache, (Zstr)missing, 0, 0x1000, &name, NULL);
330325
PdbCacheDeinit(&cache);

0 commit comments

Comments
 (0)