Repository navigation
refactor(foundation): port src/foundation from C to Zig - #164
Merged
Merged
Conversation
Replace 21 C files in src/foundation with Zig modules in libcbm_zig: arena, compat, compat_fs, compat_regex, compat_thread, diagnostics, dump_verify, file_lock, git_env, limits, log, mem, platform, profile, sha256, slab_alloc, str_intern, str_util, subprocess, system_info and yaml. The C headers stay the ABI: each Zig module exports the same symbols, and cbm_zig.zig checks every pub cbm_* export against its translated header declaration. OS-specific exports live in nested namespaces (compat.windows, compat_fs.impl, git_env.windows/posix, system_info.linux) that are checked the same way. The close-on-exec and posix_spawn code from #77 (compat_fs, subprocess, file_lock) is ported as written; the posix_child_* tests cover it. What stays C, and why: - src/foundation/c_shim.c (new, 127 lines): the two variadic functions, cbm_arena_sprintf and cbm_log. Zig cannot define a C-variadic function portably, so cbm_log walks its va_list in C and hands each key/value pair to the Zig formatter through log_internal.h. It also carries the _Static_assert that regex_t fits in cbm_regex_t, because glibc's regex_t is opaque to translate-c. - src/foundation/hash_table.c: a thin wrapper that instantiates the vendored Verstable macro template; there is nothing to port without rewriting the hash table itself. - Header-only code is unchanged: dyn_array.h macros, the static inline helpers in compat.h and platform.h, win_utf8.h, CBM_SNPRINTF_APPEND and the CBM_PROF_* macros. - vmem.c / vmem.h are in no build list (dead on main) and are untouched. Behavior differences from the C code: - cbm_mkdir_p (POSIX) with an empty path returns false after the failed mkdir; the C loop read one byte past the copied empty string. - cbm_sha256_backend_update with len 0 returns before touching data on Apple platforms. The C code passed the (possibly NULL) pointer to a loop that made no CommonCrypto call for len 0, so the digest is the same; the early return keeps the ReleaseSafe test build from trapping on the NULL pointer. - yaml: the leading-space count is bounded by the end of the line instead of relying on the terminating NUL. Same result for the NUL-terminated input every caller passes. - cbm_str_tolower lowers ASCII only; the C code called tolower(), which is the same thing in the "C" locale (nothing in the repo calls setlocale). Build and audit wiring: Makefile.cbm and build.zig drop the C sources (FOUNDATION_SRCS is now hash_table.c + c_shim.c) and list the Zig files and the foundation headers in CBM_ZIG_SRCS; cbm_zig_c.h gains the platform and foundation headers the ported code calls. The test-foundation make target is removed: it linked FOUNDATION_SRCS alone, which no longer contains the modules its tests exercise. security-allowlist.txt names compat_fs.zig and subprocess.zig in place of the C files (same six entries; the subprocess fork entry now names runPosix). security-audit.sh's fopen("w") known-safe list names diagnostics.zig and drops log.c, which had no fopen call. No audit count changes. Net change: 21 Zig modules, +4,821 lines (plus 53 in interop.zig), for 5,971 lines of C removed; 161 lines of C shim and internal header added. Signed-off-by: ata-sesli <atasesli@protonmail.com>
This was referenced Nov 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Ports
src/foundationfrom C to Zig, following the pattern of #163. 21 C files become Zig modules inlibcbm_zig: arena, compat, compat_fs, compat_regex, compat_thread, diagnostics, dump_verify, file_lock, git_env, limits, log, mem, platform, profile, sha256, slab_alloc, str_intern, str_util, subprocess, system_info and yaml.The C headers do not change. Each Zig module exports the same symbols, and
cbm_zig.zigchecks every exportedcbm_*function against its header declaration at compile time. OS-specific exports live in nested namespaces (compat.windows,compat_fs.impl,git_env.windows/posix,system_info.linux) that are checked the same way.The recent close-on-exec and
posix_spawncode (compat_fs, subprocess, file_lock; on main as ofa592846a) is ported as written. Theposix_child_*tests cover it.Net change: 5,971 lines of C removed; 4,821 lines of Zig in 21 modules plus 53 in
interop.zig; 161 lines of C shim and internal header added.What stays C, and why
src/foundation/c_shim.c(new, 127 lines) withlog_internal.h(34 lines): the two variadic functions,cbm_arena_sprintfandcbm_log. Zig cannot define a C-variadic function portably, socbm_logwalks itsva_listin C and hands each key/value pair to the Zig formatter. The shim also carries the_Static_assertthatregex_tfits incbm_regex_t, because glibc'sregex_tis opaque to translate-c.src/foundation/hash_table.c: a thin wrapper that instantiates the vendored Verstable macro template. There is nothing to port without rewriting the hash table itself.dyn_array.hmacros, thestatic inlinehelpers incompat.handplatform.h,win_utf8.h,CBM_SNPRINTF_APPENDand theCBM_PROF_*macros.vmem.c/vmem.hare in no build list on main (dead code) and are untouched.Behavior differences
cbm_mkdir_p(POSIX) with an empty path returns false after the failedmkdir. The C loop read one byte past the copied empty string.cbm_sha256_backend_updatewith length 0 returns before touching the data pointer on Apple platforms. The digest is the same; the early return keeps the ReleaseSafe test build from trapping on a NULL pointer.cbm_str_tolowerlowers ASCII only. The C code calledtolower(), which is the same in the "C" locale, and nothing in the repo callssetlocale.Build and audit wiring
Makefile.cbmandbuild.zigdrop the C sources (FOUNDATION_SRCSis nowhash_table.c+c_shim.c) and list the Zig files and foundation headers inCBM_ZIG_SRCS.cbm_zig_c.hadds the headers the ported code calls.test-foundationmake target is removed. It linkedFOUNDATION_SRCSalone, which no longer contains the modules its tests exercise.security-allowlist.txtnamescompat_fs.zigandsubprocess.zigin place of the C files (same six entries; the subprocess fork entry now namesrunPosix).security-audit.sh's fopen("w") known-safe list namesdiagnostics.zigand dropslog.c, which had nofopencall. No audit count changes.Verification
Run on macOS arm64 at this branch's commit, through
scripts/zova-run-tests.shwith the pinned Zova:a592846a) for arena 32, hash_table 28, dyn_array 26, str_intern 19, log 16, str_util 65, platform 14, subprocess 24, dump_verify 12, system_info 8, slab_alloc 14, mem 42, security 34, yaml 73, cli 132, zova 39, zova_operations 59, pipeline 276 (13 not run), mcp 176.libcbm_zig.abuilds for native, x86_64-linux-gnu, aarch64-linux-gnu, x86_64-windows-gnu and aarch64-macos, each with and without Zova.zig fmt --check,scripts/check-build-sources.shandscripts/security-audit.shpass.Not run:
make -f Makefile.cbm teston this branch alone. It was run on the stacked branch (see the follow-up PR): that target builds without Zova and fails 870 tests on main and on the port identically.lint-ciandsmoke-test.sh.Checklist
git commit -s)make -f Makefile.cbm test): not run on this branch; the suites listed above passmake -f Makefile.cbm lint-ci): not run