chore: import upstream snapshot with attribution
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped

This commit is contained in:
wehub-resource-sync
2026-07-13 12:29:30 +08:00
commit e7738de6d2
1723 changed files with 216139 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,273 @@
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
#ifndef _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#endif
#ifndef _DARWIN_C_SOURCE
#define _DARWIN_C_SOURCE
#endif
#include "zero.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
void *z_checked_malloc(size_t size) {
void *ptr = malloc(size ? size : 1);
if (!ptr) abort();
return ptr;
}
void zbuf_init(ZBuf *buf) {
if (buf) *buf = (ZBuf){0};
}
void zbuf_append(ZBuf *buf, const char *text) {
(void)buf;
(void)text;
}
void zbuf_append_char(ZBuf *buf, char ch) {
(void)buf;
(void)ch;
}
void zbuf_appendf(ZBuf *buf, const char *fmt, ...) {
(void)buf;
(void)fmt;
}
void zbuf_free(ZBuf *buf) {
if (!buf) return;
free(buf->data);
*buf = (ZBuf){0};
}
bool z_write_file(const char *path, const char *text, ZDiag *diag) {
(void)path;
(void)text;
(void)diag;
return false;
}
bool z_http_listen_temp_path(const char *temp_dir, const char *leaf, char *out, size_t out_cap, ZDiag *diag) {
(void)temp_dir;
(void)leaf;
(void)out;
(void)out_cap;
(void)diag;
return false;
}
bool z_http_listen_create_temp_dir(char *out, size_t out_cap, ZDiag *diag) {
(void)out;
(void)out_cap;
(void)diag;
return false;
}
void z_http_listen_cleanup_temp_dir(const char *temp_dir) {
(void)temp_dir;
}
#include "../src/http_listen_runner.c"
static int fail(const char *message) {
fprintf(stderr, "http_listen_runner_smoke: %s\n", message);
return 1;
}
static int expect_true(bool condition, const char *message) {
return condition ? 0 : fail(message);
}
static int make_pair(int fds[2]) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) return fail("socketpair failed");
return 0;
}
static int read_peer_text(int fd, char *out, size_t out_cap, size_t *out_len) {
if (!out || out_cap == 0 || !out_len) return fail("invalid read buffer");
*out_len = 0;
while (*out_len + 1 < out_cap) {
ssize_t n = recv(fd, out + *out_len, out_cap - *out_len - 1, 0);
if (n < 0) {
if (errno == EINTR) continue;
return fail("recv failed");
}
if (n == 0) break;
*out_len += (size_t)n;
}
out[*out_len] = '\0';
return 0;
}
static int smoke_send_all(void) {
int fds[2];
if (make_pair(fds) != 0) return 1;
const char payload[] = "abc123";
int status = expect_true(send_all(fds[0], payload, sizeof(payload) - 1), "send_all should send full payload");
char got[16];
ssize_t n = recv(fds[1], got, sizeof(got), 0);
if (n < 0) status |= fail("send_all peer recv failed");
else status |= expect_true((size_t)n == sizeof(payload) - 1 && memcmp(got, payload, sizeof(payload) - 1) == 0, "send_all peer payload mismatch");
close(fds[0]);
close(fds[1]);
return status;
}
static int smoke_json_error(void) {
int fds[2];
if (make_pair(fds) != 0) return 1;
int status = expect_true(send_json_error(fds[0], 413, "Payload Too Large", "{\"error\":\"payload_too_large\"}"), "send_json_error should send response");
shutdown(fds[0], SHUT_WR);
char got[512];
size_t len = 0;
status |= read_peer_text(fds[1], got, sizeof(got), &len);
status |= expect_true(strstr(got, "HTTP/1.1 413 Payload Too Large\r\n") == got, "json error status line");
status |= expect_true(strstr(got, "connection: close\r\n") != NULL, "json error connection close");
status |= expect_true(strstr(got, "{\"error\":\"payload_too_large\"}") != NULL, "json error body");
close(fds[0]);
close(fds[1]);
return status;
}
static int smoke_read_request_complete(void) {
int fds[2];
if (make_pair(fds) != 0) return 1;
const char request[] = "POST /echo\r\ncontent-length: 4\r\n\r\npong";
send_all(fds[0], request, sizeof(request) - 1);
shutdown(fds[0], SHUT_WR);
char buffer[Z_HTTP_LISTEN_REQUEST_CAP];
size_t len = 0;
unsigned status = 0;
int result = read_http_request(fds[1], buffer, sizeof(buffer), &len, &status);
int smoke = expect_true(result && len == sizeof(request) - 1 && memcmp(buffer, request, len) == 0, "complete request should parse");
close(fds[0]);
close(fds[1]);
return smoke;
}
static int smoke_read_request_rejections(void) {
int malformed[2];
if (make_pair(malformed) != 0) return 1;
const char bad_length[] = "POST /echo\r\ncontent-length: nope\r\n\r\nx";
send_all(malformed[0], bad_length, sizeof(bad_length) - 1);
shutdown(malformed[0], SHUT_WR);
char buffer[Z_HTTP_LISTEN_REQUEST_CAP];
size_t len = 0;
unsigned status = 0;
int ok = read_http_request(malformed[1], buffer, sizeof(buffer), &len, &status);
int smoke = expect_true(!ok && status == 400, "malformed content-length should be bad request");
close(malformed[0]);
close(malformed[1]);
int oversized[2];
if (make_pair(oversized) != 0) return 1;
const char too_large[] = "POST /echo\r\ncontent-length: 999999\r\n\r\n";
send_all(oversized[0], too_large, sizeof(too_large) - 1);
shutdown(oversized[0], SHUT_WR);
status = 0;
len = 0;
ok = read_http_request(oversized[1], buffer, sizeof(buffer), &len, &status);
smoke |= expect_true(!ok && status == 413, "oversized content-length should be payload too large");
close(oversized[0]);
close(oversized[1]);
return smoke;
}
static int write_literal_file(const char *path, const char *text, mode_t mode) {
int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
if (fd < 0) return fail("open fixture file failed");
size_t len = strlen(text);
size_t written = 0;
while (written < len) {
ssize_t n = write(fd, text + written, len - written);
if (n < 0) {
if (errno == EINTR) continue;
close(fd);
return fail("write fixture file failed");
}
if (n == 0) {
close(fd);
return fail("short fixture write");
}
written += (size_t)n;
}
if (close(fd) != 0) return fail("close fixture file failed");
return 0;
}
static int smoke_write_request_file(void) {
char dir[] = "/tmp/zero-listen-runner-smoke-XXXXXX";
if (!mkdtemp(dir)) return fail("mkdtemp failed");
char path[256];
snprintf(path, sizeof(path), "%s/request.http", dir);
const char request[] = "GET /ping\r\n\r\n";
int status = expect_true(write_request_file(path, request, sizeof(request) - 1), "write_request_file should create request");
status |= expect_true(!write_request_file(path, request, sizeof(request) - 1), "write_request_file should be exclusive");
char got[64] = {0};
int fd = open(path, O_RDONLY);
if (fd < 0) status |= fail("open written request failed");
else {
ssize_t n = read(fd, got, sizeof(got));
status |= expect_true(n == (ssize_t)(sizeof(request) - 1) && memcmp(got, request, sizeof(request) - 1) == 0, "request file content mismatch");
close(fd);
}
unlink(path);
rmdir(dir);
return status;
}
static int smoke_handler_capture(void) {
char dir[] = "/tmp/zero-listen-handler-smoke-XXXXXX";
if (!mkdtemp(dir)) return fail("mkdtemp handler failed");
char request_path[256];
char ok_handler[256];
char bad_handler[256];
snprintf(request_path, sizeof(request_path), "%s/request.http", dir);
snprintf(ok_handler, sizeof(ok_handler), "%s/ok-handler", dir);
snprintf(bad_handler, sizeof(bad_handler), "%s/bad-handler", dir);
int status = 0;
status |= write_literal_file(request_path, "GET /ping\r\n\r\n", 0600);
status |= write_literal_file(ok_handler, "#!/bin/sh\nprintf 'HTTP/1.1 200 OK\\r\\ncontent-length: 2\\r\\n\\r\\nok'\n", 0700);
status |= write_literal_file(bad_handler, "#!/bin/sh\nprintf 'not http'\n", 0700);
chmod(ok_handler, 0700);
chmod(bad_handler, 0700);
char *response = NULL;
size_t response_len = 0;
status |= expect_true(run_handler_capture(ok_handler, request_path, &response, &response_len), "handler capture should accept HTTP response");
status |= expect_true(response && response_len >= 17 && memcmp(response, "HTTP/1.1 200 OK", 15) == 0, "handler capture response mismatch");
free(response);
response = NULL;
response_len = 0;
status |= expect_true(!run_handler_capture(bad_handler, request_path, &response, &response_len), "handler capture should reject non-HTTP response");
status |= expect_true(response == NULL && response_len == 0, "rejected handler should not return response");
unlink(request_path);
unlink(ok_handler);
unlink(bad_handler);
rmdir(dir);
return status;
}
int main(void) {
int status = 0;
status |= smoke_send_all();
status |= smoke_json_error();
status |= smoke_read_request_complete();
status |= smoke_read_request_rejections();
status |= smoke_write_request_file();
status |= smoke_handler_capture();
return status;
}
File diff suppressed because it is too large Load Diff
+291
View File
@@ -0,0 +1,291 @@
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
#include "../include/zero.h"
#include "../src/process_exec.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#if defined(_WIN32)
#include <process.h>
#else
#include <unistd.h>
#endif
static void fail(const char *message) {
fprintf(stderr, "process_exec_smoke: %s\n", message);
exit(1);
}
static void expect_true(bool value, const char *message) {
if (!value) fail(message);
}
static void expect_false(bool value, const char *message) {
if (value) fail(message);
}
static void expect_text(const char *actual, const char *expected, const char *message) {
if (strcmp(actual ? actual : "", expected ? expected : "") != 0) {
fprintf(stderr, "process_exec_smoke: %s\nactual: %s\nexpected: %s\n", message, actual ? actual : "", expected ? expected : "");
exit(1);
}
}
void *z_checked_reallocarray(void *ptr, size_t count, size_t item_size) {
if (item_size != 0 && count > ((size_t)-1) / item_size) fail("allocation overflow");
size_t size = count * item_size;
void *next = realloc(ptr, size == 0 ? 1 : size);
if (!next) fail("out of memory");
return next;
}
size_t z_grow_capacity(size_t current, size_t required, size_t initial) {
size_t next = current == 0 ? (initial == 0 ? 1 : initial) : current;
while (next < required) {
if (next > ((size_t)-1) / 2) return required;
next *= 2;
}
return next;
}
char *z_strndup(const char *text, size_t len) {
char *copy = malloc(len + 1);
if (!copy) fail("out of memory");
memcpy(copy, text, len);
copy[len] = 0;
return copy;
}
char *z_strdup(const char *text) {
return z_strndup(text ? text : "", strlen(text ? text : ""));
}
void zbuf_init(ZBuf *buf) {
buf->data = NULL;
buf->len = 0;
buf->cap = 0;
}
void zbuf_append_char(ZBuf *buf, char ch) {
size_t required = buf->len + 2;
if (required > buf->cap) {
size_t next = z_grow_capacity(buf->cap, required, 16);
buf->data = z_checked_reallocarray(buf->data, next, sizeof(char));
buf->cap = next;
}
buf->data[buf->len++] = ch;
buf->data[buf->len] = 0;
}
void zbuf_append(ZBuf *buf, const char *text) {
for (const char *cursor = text ? text : ""; *cursor; cursor++) zbuf_append_char(buf, *cursor);
}
void zbuf_free(ZBuf *buf) {
free(buf->data);
buf->data = NULL;
buf->len = 0;
buf->cap = 0;
}
static void test_argv_builder(void) {
ZProcessArgv argv;
z_process_argv_init(&argv);
expect_false(z_process_argv_push(NULL, "cc"), "push rejects null argv");
expect_false(z_process_argv_push(&argv, ""), "push rejects empty value");
expect_true(z_process_argv_push(&argv, "cc"), "push accepts command");
expect_true(argv.len == 1 && argv.items && argv.items[1] == NULL, "push keeps argv null-terminated");
z_process_argv_free(&argv);
expect_true(argv.items == NULL && argv.len == 0 && argv.cap == 0, "free resets argv");
}
static void test_flag_parser(void) {
ZProcessArgv argv;
z_process_argv_init(&argv);
bool suppress_stderr = false;
expect_true(z_process_argv_append_flag_text(&argv, "-O2 -DNAME='two words' escaped\\ space 2>/dev/null", &suppress_stderr), "flag parser accepts quoted flags");
expect_true(suppress_stderr, "flag parser recognizes stderr suppression");
expect_true(argv.len == 3, "flag parser appends expected token count");
expect_text(argv.items[0], "-O2", "flag parser keeps first flag");
expect_text(argv.items[1], "-DNAME=two words", "flag parser preserves quoted spaces inside token");
expect_text(argv.items[2], "escaped space", "flag parser handles escaped spaces");
z_process_argv_free(&argv);
ZProcessArgv malformed;
z_process_argv_init(&malformed);
suppress_stderr = false;
expect_false(z_process_argv_append_flag_text(&malformed, "-O2 -DNAME='unterminated", &suppress_stderr), "flag parser rejects unterminated quotes");
z_process_argv_free(&malformed);
}
static void test_ensure_dir(void) {
char dir_path[256];
char file_path[256];
snprintf(dir_path, sizeof(dir_path), "/tmp/zero-process-exec-smoke-dir-%ld", (long)getpid());
snprintf(file_path, sizeof(file_path), "/tmp/zero-process-exec-smoke-file-%ld", (long)getpid());
remove(dir_path);
remove(file_path);
expect_true(z_process_ensure_dir(dir_path), "ensure_dir creates missing directory");
expect_true(z_process_ensure_dir(dir_path), "ensure_dir accepts existing directory");
FILE *file = fopen(file_path, "wb");
expect_true(file != NULL, "created regular file for ensure_dir check");
fputs("not a directory", file);
fclose(file);
expect_false(z_process_ensure_dir(file_path), "ensure_dir rejects existing regular file");
remove(file_path);
rmdir(dir_path);
}
static void write_text_file(const char *path, const char *text) {
FILE *file = fopen(path, "wb");
expect_true(file != NULL, "created fixture file");
fputs(text ? text : "", file);
fclose(file);
}
static void test_output_file_contract(void) {
expect_false(z_process_prepare_output_file(NULL), "output preparation rejects null path");
expect_false(z_process_prepare_output_file(""), "output preparation rejects empty path");
expect_false(z_process_output_file_ready(NULL), "output ready rejects null path");
expect_false(z_process_output_file_ready(""), "output ready rejects empty path");
char root[256];
snprintf(root, sizeof(root), "/tmp/zero-process-output-smoke-%ld", (long)getpid());
rmdir(root);
expect_true(mkdir(root, 0700) == 0, "created output contract temp dir");
char missing_path[256];
char file_path[256];
char empty_path[256];
char dir_path[256];
char missing_parent_path[256];
char cleanup_path[256];
char cleanup_missing_path[256];
snprintf(missing_path, sizeof(missing_path), "%s/missing.out", root);
snprintf(file_path, sizeof(file_path), "%s/file.out", root);
snprintf(empty_path, sizeof(empty_path), "%s/empty.out", root);
snprintf(dir_path, sizeof(dir_path), "%s/dir.out", root);
snprintf(missing_parent_path, sizeof(missing_parent_path), "%s/nope/out", root);
snprintf(cleanup_path, sizeof(cleanup_path), "%s/cleanup.out", root);
snprintf(cleanup_missing_path, sizeof(cleanup_missing_path), "%s/already-gone.out", root);
expect_true(z_process_prepare_output_file(missing_path), "missing output is ready for creation");
expect_false(z_process_output_file_ready(missing_path), "missing output is not ready after tool run");
expect_false(z_process_executable_file_ready(missing_path), "executable ready rejects missing output");
expect_false(z_process_mark_executable(missing_path), "mark executable rejects missing output");
expect_true(z_process_remove_regular_file(cleanup_missing_path), "cleanup accepts missing regular output");
expect_false(z_process_prepare_output_file(missing_parent_path), "output preparation rejects missing parent directory");
write_text_file(file_path, "artifact");
expect_true(z_process_output_file_ready(file_path), "non-empty regular output is ready");
#if !defined(_WIN32)
expect_false(z_process_executable_file_ready(file_path), "plain output is not executable before finalization");
#endif
expect_true(z_process_mark_executable(file_path), "mark executable accepts regular non-empty output");
expect_true(z_process_executable_file_ready(file_path), "executable ready accepts finalized artifact");
#if !defined(_WIN32)
expect_true(access(file_path, X_OK) == 0, "mark executable sets execute bit");
#endif
expect_true(z_process_prepare_output_file(file_path), "stale regular output can be removed");
expect_false(z_process_output_file_ready(file_path), "removed stale output is no longer ready");
write_text_file(empty_path, "");
expect_false(z_process_output_file_ready(empty_path), "empty output is not ready");
expect_false(z_process_executable_file_ready(empty_path), "executable ready rejects empty output");
expect_false(z_process_mark_executable(empty_path), "mark executable rejects empty output");
expect_true(z_process_prepare_output_file(empty_path), "empty regular output can be removed before rebuild");
write_text_file(cleanup_path, "temporary");
expect_true(z_process_remove_regular_file(cleanup_path), "cleanup removes regular output");
expect_false(z_process_output_file_ready(cleanup_path), "cleanup removed regular output");
expect_true(mkdir(dir_path, 0700) == 0, "created directory output fixture");
expect_false(z_process_prepare_output_file(dir_path), "output preparation rejects directories");
expect_false(z_process_output_file_ready(dir_path), "output ready rejects directories");
expect_false(z_process_executable_file_ready(dir_path), "executable ready rejects directories");
expect_false(z_process_mark_executable(dir_path), "mark executable rejects directories");
expect_false(z_process_remove_regular_file(dir_path), "cleanup rejects directories");
rmdir(dir_path);
#if !defined(_WIN32)
char target_path[256];
char symlink_path[256];
snprintf(target_path, sizeof(target_path), "%s/target.out", root);
snprintf(symlink_path, sizeof(symlink_path), "%s/link.out", root);
write_text_file(target_path, "target");
expect_true(symlink(target_path, symlink_path) == 0, "created symlink output fixture");
expect_false(z_process_prepare_output_file(symlink_path), "output preparation rejects symlinks");
expect_false(z_process_output_file_ready(symlink_path), "output ready rejects symlinks");
expect_false(z_process_executable_file_ready(symlink_path), "executable ready rejects symlinks");
expect_false(z_process_mark_executable(symlink_path), "mark executable rejects symlinks");
expect_false(z_process_remove_regular_file(symlink_path), "cleanup rejects symlinks");
unlink(symlink_path);
unlink(target_path);
#endif
rmdir(root);
}
static void test_command_lookup(void) {
expect_false(z_process_command_available("sh;rm"), "command lookup rejects shell syntax");
expect_false(z_process_command_available("../sh"), "command lookup rejects unresolved relative path");
#if !defined(_WIN32)
expect_true(z_process_command_available("/bin/sh"), "command lookup accepts executable absolute path");
#endif
}
static void test_run_argv(void) {
#if !defined(_WIN32)
const char *ok_argv[] = {"/bin/sh", "-c", "exit 0", NULL};
const char *bad_argv[] = {"/bin/sh", "-c", "exit 7", NULL};
ZProcessArgv ok;
z_process_argv_init(&ok);
expect_true(z_process_argv_push(&ok, ok_argv[0]), "run argv command push");
expect_true(z_process_argv_push(&ok, ok_argv[1]), "run argv flag push");
expect_true(z_process_argv_push(&ok, ok_argv[2]), "run argv script push");
expect_true(z_process_run_argv(&ok, true, true, false), "run argv reports successful child");
z_process_argv_free(&ok);
ZProcessArgv bad;
z_process_argv_init(&bad);
expect_true(z_process_argv_push(&bad, bad_argv[0]), "bad argv command push");
expect_true(z_process_argv_push(&bad, bad_argv[1]), "bad argv flag push");
expect_true(z_process_argv_push(&bad, bad_argv[2]), "bad argv script push");
expect_false(z_process_run_argv(&bad, true, true, false), "run argv reports failed child");
z_process_argv_free(&bad);
#endif
}
static void test_first_stdout_line(void) {
#if !defined(_WIN32)
const char *first_line[] = {"/bin/sh", "-c", "printf 'alpha\\nbeta\\n'", NULL};
char *line = z_process_first_stdout_line(first_line, true);
expect_text(line, "alpha", "first stdout line captures only first line");
free(line);
const char *failed_after_output[] = {"/bin/sh", "-c", "printf stale; exit 9", NULL};
line = z_process_first_stdout_line(failed_after_output, true);
expect_text(line, "", "first stdout line ignores failed child output");
free(line);
const char *missing[] = {"/tmp/zero-process-exec-smoke-missing-command", NULL};
line = z_process_first_stdout_line(missing, true);
expect_text(line, "", "first stdout line handles missing command");
free(line);
#endif
}
int main(void) {
test_argv_builder();
test_flag_parser();
test_ensure_dir();
test_output_file_contract();
test_command_lookup();
test_run_argv();
test_first_stdout_line();
return 0;
}
+780
View File
@@ -0,0 +1,780 @@
#include "program_graph_format.h"
#include "program_graph_lower.h"
#include "program_graph_projection.h"
#include "program_graph_store_binary.h"
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void expect(int ok, const char *message);
void *z_checked_malloc(size_t size) {
void *ptr = malloc(size ? size : 1);
if (ptr) return ptr;
fprintf(stderr, "out of memory\n");
exit(1);
}
void *z_checked_calloc(size_t count, size_t item_size) {
void *ptr = calloc(count ? count : 1, item_size ? item_size : 1);
if (ptr) return ptr;
fprintf(stderr, "out of memory\n");
exit(1);
}
void *z_checked_reallocarray(void *ptr, size_t count, size_t item_size) {
void *next = realloc(ptr, (count ? count : 1) * (item_size ? item_size : 1));
if (next) return next;
fprintf(stderr, "out of memory\n");
exit(1);
}
size_t z_grow_capacity(size_t current, size_t required, size_t initial) {
size_t next = current ? current : initial;
while (next < required) next *= 2;
return next;
}
char *z_strdup(const char *text) {
size_t len = strlen(text ? text : "");
return z_strndup(text ? text : "", len);
}
char *z_strndup(const char *text, size_t len) {
char *copy = z_checked_malloc(len + 1);
memcpy(copy, text ? text : "", len + 1);
copy[len] = 0;
return copy;
}
bool z_write_file(const char *path, const char *text, ZDiag *diag) {
FILE *file = fopen(path, "wb");
if (!file) {
if (diag) snprintf(diag->message, sizeof(diag->message), "failed to write test graph");
return false;
}
fputs(text ? text : "", file);
fclose(file);
return true;
}
void zbuf_init(ZBuf *buf) { *buf = (ZBuf){0}; }
void zbuf_free(ZBuf *buf) {
free(buf->data);
*buf = (ZBuf){0};
}
void zbuf_append_char(ZBuf *buf, char ch) {
if (buf->len + 1 >= buf->cap) {
buf->cap = z_grow_capacity(buf->cap, buf->len + 2, 64);
buf->data = z_checked_reallocarray(buf->data, buf->cap, 1);
}
buf->data[buf->len++] = ch;
buf->data[buf->len] = 0;
}
void zbuf_append(ZBuf *buf, const char *text) {
for (const char *p = text ? text : ""; *p; p++) zbuf_append_char(buf, *p);
}
void zbuf_appendf(ZBuf *buf, const char *fmt, ...) {
char stack[256];
va_list args;
va_start(args, fmt);
int len = vsnprintf(stack, sizeof(stack), fmt, args);
va_end(args);
expect(len >= 0 && (size_t)len < sizeof(stack), "formatted test buffer overflow");
zbuf_append(buf, stack);
}
static void expect(int ok, const char *message) {
if (ok) return;
fprintf(stderr, "%s\n", message);
exit(1);
}
static uint64_t read_le_u64(const unsigned char *bytes, size_t offset, size_t len) {
expect(bytes != NULL && offset <= len && len - offset >= 8, "binary fixture read out of range");
uint64_t value = 0;
for (unsigned i = 0; i < 8; i++) value |= (uint64_t)bytes[offset + i] << (i * 8);
return value;
}
static void write_le_u64(unsigned char *bytes, size_t offset, size_t len, uint64_t value) {
expect(bytes != NULL && offset <= len && len - offset >= 8, "binary fixture write out of range");
for (unsigned i = 0; i < 8; i++) bytes[offset + i] = (unsigned char)((value >> (i * 8)) & 0xffu);
}
static unsigned char *copy_binary_fixture(const ZBuf *binary) {
unsigned char *copy = z_checked_malloc(binary->len);
memcpy(copy, binary->data, binary->len);
return copy;
}
static void expect_binary_store_rejected(const unsigned char *bytes, size_t len, const char *message) {
ZProgramGraphStore parsed;
ZDiag diag = {0};
expect(!z_program_graph_store_parse_binary("corrupt-zero.graph", bytes, len, &parsed, &diag), message);
expect(strstr(diag.message, "invalid") != NULL || strstr(diag.message, "failed") != NULL, "binary rejection reported wrong diagnostic");
}
enum {
BINARY_SOURCE_COUNT_OFFSET = 24,
BINARY_PROJECTION_COUNT_OFFSET = 32,
BINARY_NODE_COUNT_OFFSET = 40,
BINARY_EDGE_COUNT_OFFSET = 48,
BINARY_STRING_BYTES_OFFSET = 64,
BINARY_MODULE_IDENTITY_REF_OFFSET = 72,
};
static void set_node(ZProgramGraphNode *node, const char *id, ZProgramGraphNodeKind kind, const char *name, const char *type) {
node->id = z_strdup(id);
node->kind = kind;
node->name = name ? z_strdup(name) : NULL;
node->type = type ? z_strdup(type) : NULL;
node->path = z_strdup("program-graph-smoke.0");
node->line = 1;
node->column = 1;
}
static void set_edge(ZProgramGraphEdge *edge, const char *from, const char *to, const char *kind, ZProgramGraphEdgeTarget target, size_t order) {
edge->from = z_strdup(from);
edge->to = z_strdup(to);
edge->kind = z_strdup(kind);
edge->target = target;
edge->order = order;
}
static void expect_binary_store_corruption_rejected(const ZProgramGraph *graph) {
ZProgramGraphStore projections;
z_program_graph_store_init(&projections);
projections.projection_paths = z_checked_calloc(1, sizeof(char *));
projections.projection_texts = z_checked_calloc(1, sizeof(char *));
projections.projection_cap = 1;
projections.projection_len = 1;
projections.projection_paths[0] = z_strdup("program-graph-smoke.0");
projections.projection_texts[0] = z_strdup("pub fn main(world: World) -> Void raises {\n}\n");
ZBuf binary;
zbuf_init(&binary);
z_program_graph_store_append_binary(&binary, graph, &projections);
expect(z_program_graph_store_bytes_are_binary((const unsigned char *)binary.data, binary.len), "binary store fixture did not use binary magic");
ZProgramGraphStore parsed;
ZDiag valid_diag = {0};
expect(z_program_graph_store_parse_binary("valid-zero.graph", (const unsigned char *)binary.data, binary.len, &parsed, &valid_diag), valid_diag.message);
z_program_graph_store_free(&parsed);
uint64_t string_bytes = read_le_u64((const unsigned char *)binary.data, BINARY_STRING_BYTES_OFFSET, binary.len);
uint64_t module_identity_offset = read_le_u64((const unsigned char *)binary.data, BINARY_MODULE_IDENTITY_REF_OFFSET, binary.len);
uint64_t module_identity_len = read_le_u64((const unsigned char *)binary.data, BINARY_MODULE_IDENTITY_REF_OFFSET + 8, binary.len);
expect(string_bytes <= (uint64_t)binary.len, "binary fixture has invalid string table size");
expect(module_identity_len > 2, "binary fixture module identity too small to corrupt");
size_t strings_offset = binary.len - (size_t)string_bytes;
expect(module_identity_offset + 1 < string_bytes, "binary fixture module identity offset out of range");
unsigned char *embedded_nul = copy_binary_fixture(&binary);
embedded_nul[strings_offset + (size_t)module_identity_offset + 1] = 0;
expect_binary_store_rejected(embedded_nul, binary.len, "binary store with embedded NUL parsed");
free(embedded_nul);
unsigned char *too_many_sources = copy_binary_fixture(&binary);
write_le_u64(too_many_sources, BINARY_SOURCE_COUNT_OFFSET, binary.len, 100001u);
expect_binary_store_rejected(too_many_sources, binary.len, "binary store with oversized source count parsed");
free(too_many_sources);
unsigned char *too_many_projections = copy_binary_fixture(&binary);
write_le_u64(too_many_projections, BINARY_PROJECTION_COUNT_OFFSET, binary.len, 100001u);
expect_binary_store_rejected(too_many_projections, binary.len, "binary store with oversized projection count parsed");
free(too_many_projections);
unsigned char *too_many_nodes = copy_binary_fixture(&binary);
write_le_u64(too_many_nodes, BINARY_NODE_COUNT_OFFSET, binary.len, 1000001u);
expect_binary_store_rejected(too_many_nodes, binary.len, "binary store with oversized node count parsed");
free(too_many_nodes);
unsigned char *too_many_edges = copy_binary_fixture(&binary);
write_le_u64(too_many_edges, BINARY_EDGE_COUNT_OFFSET, binary.len, 4000001u);
expect_binary_store_rejected(too_many_edges, binary.len, "binary store with oversized edge count parsed");
free(too_many_edges);
unsigned char *too_many_string_bytes = copy_binary_fixture(&binary);
write_le_u64(too_many_string_bytes, BINARY_STRING_BYTES_OFFSET, binary.len, 256u * 1024u * 1024u + 1u);
expect_binary_store_rejected(too_many_string_bytes, binary.len, "binary store with oversized string table parsed");
free(too_many_string_bytes);
zbuf_free(&binary);
z_program_graph_store_free(&projections);
}
static void expect_binary_store_rejects_user_std_basename_without_projection(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(1, sizeof(ZProgramGraphNode));
graph.node_len = 1;
graph.node_cap = 1;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "term", NULL);
free(graph.nodes[0].path);
graph.nodes[0].path = z_strdup("src/term.0");
z_program_graph_finalize_identities(&graph);
ZBuf binary;
zbuf_init(&binary);
z_program_graph_store_append_binary(&binary, &graph, NULL);
ZProgramGraphStore parsed;
ZDiag diag = {0};
expect(!z_program_graph_store_parse_binary("user-std-basename.graph", (const unsigned char *)binary.data, binary.len, &parsed, &diag),
"binary store accepted user source path matching std basename without projection");
expect(strstr(diag.message, "projection table") != NULL || strstr(diag.message, "source table") != NULL,
"binary store basename collision reported wrong diagnostic");
zbuf_free(&binary);
z_program_graph_free(&graph);
}
static void expect_binary_fast_sync_rejects_empty_projection_table(const ZProgramGraph *graph) {
ZBuf binary;
zbuf_init(&binary);
z_program_graph_store_append_binary(&binary, graph, NULL);
char storage_path[128];
snprintf(storage_path, sizeof(storage_path), "/tmp/zero-program-graph-empty-projection-%p.graph", (void *)graph);
ZDiag write_diag = {0};
expect(z_write_binary_file(storage_path, (const unsigned char *)binary.data, binary.len, &write_diag), write_diag.message);
ZProgramGraphProjectionSourceSync sync = Z_PROGRAM_GRAPH_PROJECTION_SYNC_DIVERGED;
expect(!z_program_graph_projection_source_sync_state_binary_fast(storage_path, ".", &sync),
"binary fast sync accepted store with empty projection table");
remove(storage_path);
zbuf_free(&binary);
}
static void expect_lowered_program(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
graph.nodes[1].is_public = true;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "lowerable graph failed validation");
Program program = {0};
ZDiag diag = {0};
expect(z_program_graph_lower_to_program(&graph, &program, &diag), diag.message);
expect(program.functions.len == 1, "lowered graph reported wrong function count");
expect(strcmp(program.functions.items[0].name, "main") == 0, "lowered function kept wrong name");
expect(strcmp(program.functions.items[0].return_type, "Void") == 0, "lowered function kept wrong return type");
expect(program.functions.items[0].is_public, "lowered function lost public flag");
expect(program.functions.items[0].body.len == 0, "lowered empty body gained statements");
z_free_program(&program);
z_program_graph_free(&graph);
}
static void expect_import_lowering_failure(const char *module, const char *alias, const char *message) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(4, sizeof(ZProgramGraphNode));
graph.node_len = 4;
graph.node_cap = 4;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_IMPORT, module, NULL);
graph.nodes[1].value = alias ? z_strdup(alias) : NULL;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
graph.nodes[2].is_public = true;
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(3, sizeof(ZProgramGraphEdge));
graph.edge_len = 3;
graph.edge_cap = 3;
set_edge(&graph.edges[0], "#000001", "#000002", "import", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000001", "#000003", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "invalid import test graph should remain shape-valid");
Program program = {0};
ZDiag diag = {0};
expect(!z_program_graph_lower_to_program(&graph, &program, &diag), "invalid import graph lowered successfully");
expect(strstr(diag.message, message) != NULL, "invalid import graph reported wrong diagnostic");
z_program_graph_free(&graph);
}
static void expect_lower_rejects_bad_imports(void) {
expect_import_lowering_failure("+", NULL, "import module");
expect_import_lowering_failure("pub", NULL, "import module");
expect_import_lowering_failure("missing", NULL, "target module is missing");
expect_import_lowering_failure("std.mem", "+", "import alias");
expect_import_lowering_failure("std.mem", "pub", "import alias");
}
static void expect_lower_rejects_reserved_function_name(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "pub", "Void");
graph.nodes[1].is_public = true;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "reserved function name graph should remain shape-valid");
Program program = {0};
ZDiag diag = {0};
expect(!z_program_graph_lower_to_program(&graph, &program, &diag), "reserved function name lowered successfully");
expect(strstr(diag.message, "function name") != NULL, "reserved function name reported wrong diagnostic");
z_program_graph_free(&graph);
}
static void expect_lower_rejects_internal_function_name(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "__zero_bad", "Void");
graph.nodes[1].is_public = true;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "internal function name graph should remain shape-valid");
Program program = {0};
ZDiag diag = {0};
expect(!z_program_graph_lower_to_program(&graph, &program, &diag), "internal function name lowered successfully");
expect(strstr(diag.message, "reserved compiler-internal") != NULL, "internal function name reported wrong diagnostic");
z_program_graph_free(&graph);
}
static void expect_lower_allows_embedded_std_internal_function_name(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "std.math", NULL);
free(graph.nodes[0].path);
graph.nodes[0].path = z_strdup("std/math.0");
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "__zero_std_math_local", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "embedded std internal function graph should remain shape-valid");
Program program = {0};
ZDiag diag = {0};
expect(z_program_graph_lower_to_program(&graph, &program, &diag), diag.message);
expect(program.functions.len == 1, "embedded std internal function was not lowered");
expect(strcmp(program.functions.items[0].name, "__zero_std_math_local") == 0, "embedded std internal function name changed");
z_free_program(&program);
z_program_graph_free(&graph);
}
static void expect_lower_rejects_reserved_call_name(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(5, sizeof(ZProgramGraphNode));
graph.node_len = 5;
graph.node_cap = 5;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
graph.nodes[1].is_public = true;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_EXPRESSION_STATEMENT, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_CALL, "pub", NULL);
graph.edges = z_checked_calloc(4, sizeof(ZProgramGraphEdge));
graph.edge_len = 4;
graph.edge_cap = 4;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "expr", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "reserved call name graph should remain shape-valid");
Program program = {0};
ZDiag diag = {0};
expect(!z_program_graph_lower_to_program(&graph, &program, &diag), "reserved call name lowered successfully");
expect(strstr(diag.message, "call callee") != NULL, "reserved call name reported wrong diagnostic");
z_program_graph_free(&graph);
}
static void expect_validation_code(ZProgramGraph *graph, const char *code, const char *message) {
z_program_graph_finalize_identities(graph);
ZProgramGraphValidation validation = {0};
expect(!z_program_graph_validate(graph, &validation), message);
expect(strcmp(validation.code, code) == 0, "validation reported wrong code");
}
static void expect_validation_allows_unconstrained_type_params(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(5, sizeof(ZProgramGraphNode));
graph.node_len = 5;
graph.node_cap = 5;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_SHAPE, "Box", NULL);
graph.nodes[1].value = z_strdup("auto");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_PARAM, "T", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_FIELD, "value", "T");
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_TYPE_REF, NULL, "T");
graph.edges = z_checked_calloc(4, sizeof(ZProgramGraphEdge));
graph.edge_len = 4;
graph.edge_cap = 4;
set_edge(&graph.edges[0], "#000001", "#000002", "shape", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "typeParam", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000002", "#000004", "field", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "type", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(z_program_graph_validate(&graph, &validation), "unconstrained type param failed validation");
z_program_graph_free(&graph);
}
static void expect_validation_rejects_malformed_graphs(void) {
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(4, sizeof(ZProgramGraphNode));
graph.node_len = 4;
graph.node_cap = 4;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
graph.nodes[1].is_public = true;
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_CHECK, NULL, NULL);
graph.edges = z_checked_calloc(4, sizeof(ZProgramGraphEdge));
graph.edge_len = 4;
graph.edge_cap = 4;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 2);
expect_validation_code(&graph, "GRF013", "sparse ordered statement edges validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "#000002", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF012", "invalid module child edge validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(2, sizeof(ZProgramGraphNode));
graph.node_len = 2;
graph.node_cap = 2;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
graph.edges = z_checked_calloc(1, sizeof(ZProgramGraphEdge));
graph.edge_len = 1;
graph.edge_cap = 1;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF016", "function without body validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(4, sizeof(ZProgramGraphNode));
graph.node_len = 4;
graph.node_cap = 4;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_PARAM, "world", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(3, sizeof(ZProgramGraphEdge));
graph.edge_len = 3;
graph.edge_cap = 3;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "param", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000002", "#000004", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF014", "value param without type validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(1, sizeof(ZProgramGraphNode));
graph.node_len = 1;
graph.node_cap = 1;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_LITERAL, NULL, NULL);
expect_validation_code(&graph, "GRF014", "literal without value validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(5, sizeof(ZProgramGraphNode));
graph.node_len = 5;
graph.node_cap = 5;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_CHECK, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_LITERAL, NULL, NULL);
graph.nodes[4].value = z_strdup("true");
graph.edges = z_checked_calloc(4, sizeof(ZProgramGraphEdge));
graph.edge_len = 4;
graph.edge_cap = 4;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "left", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF016", "statement check with left edge validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(6, sizeof(ZProgramGraphNode));
graph.node_len = 6;
graph.node_cap = 6;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_LET, "value", NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_CHECK, NULL, NULL);
set_node(&graph.nodes[5], "#000006", Z_PROGRAM_GRAPH_NODE_LITERAL, NULL, NULL);
graph.nodes[5].value = z_strdup("true");
graph.edges = z_checked_calloc(5, sizeof(ZProgramGraphEdge));
graph.edge_len = 5;
graph.edge_cap = 5;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "expr", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[4], "#000005", "#000006", "expr", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF016", "expression check with expr edge validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(7, sizeof(ZProgramGraphNode));
graph.node_len = 7;
graph.node_cap = 7;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_CHECK, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_INDEX_ACCESS, NULL, NULL);
set_node(&graph.nodes[5], "#000006", Z_PROGRAM_GRAPH_NODE_IDENTIFIER, "world", NULL);
set_node(&graph.nodes[6], "#000007", Z_PROGRAM_GRAPH_NODE_LITERAL, NULL, NULL);
graph.nodes[6].value = z_strdup("0");
graph.edges = z_checked_calloc(6, sizeof(ZProgramGraphEdge));
graph.edge_len = 6;
graph.edge_cap = 6;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "expr", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[4], "#000005", "#000006", "left", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[5], "#000005", "#000007", "right", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF016", "right edge at order zero validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(5, sizeof(ZProgramGraphNode));
graph.node_len = 5;
graph.node_cap = 5;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "u8");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_RETURN, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_RESCUE, NULL, "u8");
graph.edges = z_checked_calloc(3, sizeof(ZProgramGraphEdge));
graph.edge_len = 3;
graph.edge_cap = 3;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF014", "rescue without binding name validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(5, sizeof(ZProgramGraphNode));
graph.node_len = 5;
graph.node_cap = 5;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "u8");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_RETURN, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_CAST, NULL, NULL);
graph.edges = z_checked_calloc(3, sizeof(ZProgramGraphEdge));
graph.edge_len = 3;
graph.edge_cap = 3;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
expect_validation_code(&graph, "GRF014", "cast without target type validated");
z_program_graph_free(&graph);
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(7, sizeof(ZProgramGraphNode));
graph.node_len = 7;
graph.node_cap = 7;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
set_node(&graph.nodes[3], "#000004", Z_PROGRAM_GRAPH_NODE_RETURN, NULL, NULL);
set_node(&graph.nodes[4], "#000005", Z_PROGRAM_GRAPH_NODE_SLICE, NULL, NULL);
set_node(&graph.nodes[5], "#000006", Z_PROGRAM_GRAPH_NODE_IDENTIFIER, "bytes", NULL);
set_node(&graph.nodes[6], "#000007", Z_PROGRAM_GRAPH_NODE_LITERAL, NULL, NULL);
graph.nodes[6].value = z_strdup("1");
graph.edges = z_checked_calloc(6, sizeof(ZProgramGraphEdge));
graph.edge_len = 6;
graph.edge_cap = 6;
set_edge(&graph.edges[0], "#000001", "#000002", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[2], "#000003", "#000004", "statement", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[3], "#000004", "#000005", "expr", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[4], "#000005", "#000006", "left", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
set_edge(&graph.edges[5], "#000005", "#000007", "arg", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 2);
expect_validation_code(&graph, "GRF016", "slice arg outside supported order range validated");
z_program_graph_free(&graph);
}
int main(void) {
expect_lowered_program();
expect_lower_rejects_bad_imports();
expect_lower_rejects_reserved_function_name();
expect_lower_rejects_internal_function_name();
expect_lower_allows_embedded_std_internal_function_name();
expect_lower_rejects_reserved_call_name();
expect_validation_allows_unconstrained_type_params();
expect_validation_rejects_malformed_graphs();
ZProgramGraph graph;
z_program_graph_init(&graph);
graph.nodes = z_checked_calloc(3, sizeof(ZProgramGraphNode));
graph.node_len = 3;
graph.node_cap = 3;
set_node(&graph.nodes[0], "#000001", Z_PROGRAM_GRAPH_NODE_MODULE, "smoke", NULL);
set_node(&graph.nodes[1], "#000002", Z_PROGRAM_GRAPH_NODE_FUNCTION, "main", "Void");
set_node(&graph.nodes[2], "#000003", Z_PROGRAM_GRAPH_NODE_BLOCK, "body", NULL);
graph.edges = z_checked_calloc(2, sizeof(ZProgramGraphEdge));
graph.edge_len = 2;
graph.edge_cap = 2;
set_edge(&graph.edges[0], "#000001", "symbol:missing", "function", Z_PROGRAM_GRAPH_EDGE_TARGET_SYMBOL, 0);
set_edge(&graph.edges[1], "#000002", "#000003", "body", Z_PROGRAM_GRAPH_EDGE_TARGET_NODE, 0);
z_program_graph_finalize_identities(&graph);
ZProgramGraphValidation validation = {0};
expect(!z_program_graph_validate(&graph, &validation), "missing symbol target validated");
expect(strcmp(validation.code, "GRF005") == 0, "missing symbol target reported wrong code");
expect(strcmp(validation.edge_target, "symbol") == 0, "missing symbol target reported wrong domain");
free(graph.edges[0].to);
graph.edges[0].to = z_strdup(graph.nodes[1].symbol_id);
z_program_graph_finalize_identities(&graph);
expect(z_program_graph_validate(&graph, &validation), "valid symbol target failed validation");
expect(validation.state == Z_PROGRAM_GRAPH_VALIDATION_SHAPE_VALID, "valid graph reported wrong state");
expect_binary_store_corruption_rejected(&graph);
expect_binary_store_rejects_user_std_basename_without_projection();
expect_binary_fast_sync_rejects_empty_projection_table(&graph);
ZBuf dump;
zbuf_init(&dump);
z_program_graph_append_dump(&dump, &graph, &validation);
ZProgramGraph parsed;
ZDiag diag = {0};
expect(z_program_graph_parse_dump(dump.data, &parsed, &diag), diag.message);
ZProgramGraphValidation parsed_validation = {0};
expect(z_program_graph_validate(&parsed, &parsed_validation), "parsed graph failed validation");
ZBuf redump;
zbuf_init(&redump);
z_program_graph_append_dump(&redump, &parsed, &parsed_validation);
expect(strcmp(dump.data, redump.data) == 0, "parsed graph dump was not byte-stable");
char storage_path[128];
snprintf(storage_path, sizeof(storage_path), "/tmp/zero-program-graph-smoke-%p.graph", (void *)&graph);
ZDiag storage_diag = {0};
expect(z_program_graph_save(storage_path, &graph, &storage_diag), storage_diag.message);
ZProgramGraph loaded;
expect(z_program_graph_load(storage_path, &loaded, &storage_diag), storage_diag.message);
ZProgramGraphValidation loaded_validation = {0};
expect(z_program_graph_validate(&loaded, &loaded_validation), "loaded graph failed validation");
ZBuf loaded_dump;
zbuf_init(&loaded_dump);
z_program_graph_append_dump(&loaded_dump, &loaded, &loaded_validation);
expect(strcmp(dump.data, loaded_dump.data) == 0, "loaded graph dump was not byte-stable");
zbuf_free(&loaded_dump);
z_program_graph_free(&loaded);
remove(storage_path);
char *corrupted = z_strdup(dump.data);
char *corrupt_name = strstr(corrupted, "name:\"main\"");
expect(corrupt_name != NULL, "expected main function name in graph dump");
memcpy(corrupt_name, "name:\"fail\"", strlen("name:\"fail\""));
ZProgramGraph rejected;
ZDiag rejected_diag = {0};
expect(!z_program_graph_parse_dump(corrupted, &rejected, &rejected_diag), "corrupt graph content parsed");
expect(strstr(rejected_diag.message, "identities") != NULL, "corrupt graph content reported wrong diagnostic");
free(corrupted);
ZProgramGraph wrong_schema;
ZDiag wrong_schema_diag = {0};
expect(!z_program_graph_parse_dump("zero-graph v2\n", &wrong_schema, &wrong_schema_diag), "unknown schema parsed");
expect(strstr(wrong_schema_diag.message, "schema") != NULL, "unknown schema reported wrong diagnostic");
const char *failed_dump =
"zero-graph v1\n"
"origin source-text\n"
"module \"main\"\n"
"hash \"\"\n"
"validation \"decoded\" failed\n"
"diagnostic code:\"GRF001\" message:\"program graph construction failed\"\n";
ZProgramGraph failed_artifact;
ZDiag failed_artifact_diag = {0};
expect(!z_program_graph_parse_dump(failed_dump, &failed_artifact, &failed_artifact_diag), "failed validation artifact parsed");
expect(strstr(failed_artifact_diag.message, "failed validation") != NULL, "failed validation artifact reported wrong diagnostic");
ZBuf trailing_extra;
zbuf_init(&trailing_extra);
zbuf_append(&trailing_extra, dump.data);
zbuf_append(&trailing_extra, "\nextra\n");
ZProgramGraph trailing_artifact;
ZDiag trailing_artifact_diag = {0};
expect(!z_program_graph_parse_dump(trailing_extra.data, &trailing_artifact, &trailing_artifact_diag), "trailing content parsed");
expect(strstr(trailing_artifact_diag.message, "unexpected content") != NULL, "trailing content reported wrong diagnostic");
zbuf_free(&trailing_extra);
zbuf_free(&redump);
z_program_graph_free(&parsed);
zbuf_free(&dump);
z_program_graph_free(&graph);
puts("program graph smoke ok");
return 0;
}
@@ -0,0 +1,54 @@
#include "zero.h"
#include <stdio.h>
#include <stdlib.h>
void z_backend_blocker_set(ZBackendBlocker *blocker,
const char *target,
const char *object_format,
const char *backend,
const char *stage,
const char *unsupported_feature) {
if (!blocker) return;
*blocker = (ZBackendBlocker){0};
blocker->present = true;
snprintf(blocker->target, sizeof(blocker->target), "%s", target ? target : "");
snprintf(blocker->object_format, sizeof(blocker->object_format), "%s", object_format ? object_format : "");
snprintf(blocker->backend, sizeof(blocker->backend), "%s", backend ? backend : "");
snprintf(blocker->stage, sizeof(blocker->stage), "%s", stage ? stage : "");
snprintf(blocker->unsupported_feature, sizeof(blocker->unsupported_feature), "%s", unsupported_feature ? unsupported_feature : "");
}
bool z_write_binary_file(const char *path, const unsigned char *data, size_t len, ZDiag *diag) {
FILE *file = fopen(path, "wb");
if (!file) {
if (diag) snprintf(diag->message, sizeof(diag->message), "failed to write binary test file");
return false;
}
size_t wrote = fwrite(data ? data : (const unsigned char *)"", 1, len, file);
fclose(file);
return wrote == len;
}
void z_free_source(SourceInput *input) {
if (!input) return;
free(input->source_file);
free(input->source);
for (size_t i = 0; i < input->source_file_count; i++) free(input->source_files[i]);
free(input->source_files);
for (size_t i = 0; i < input->module_count; i++) {
free(input->module_names[i]);
free(input->module_paths[i]);
}
free(input->module_names);
free(input->module_paths);
for (size_t i = 0; i < input->symbol_count; i++) {
free(input->symbol_modules[i]);
free(input->symbol_kinds[i]);
free(input->symbol_names[i]);
}
free(input->symbol_modules);
free(input->symbol_kinds);
free(input->symbol_names);
*input = (SourceInput){0};
}