// staticDemo.c -- a self-contained calog application, built as a fully static binary. // // It embeds the Lua engine, the DB library (SQLite backend), and the network library, then // runs one script that sums 1..10 through an in-memory database and opens/closes a UDP // socket -- proving the engine, DB, and network stacks all work in a `-static` executable // with no shared-library dependencies at runtime. Build it with `make static`. // // Static-glibc caveat: name resolution (getaddrinfo) and dlopen-based Lua C modules do not // work in a fully static glibc binary -- connect by IP and avoid `require` of C modules, or // link musl. This demo uses neither, so it is fully self-contained. #define _POSIX_C_SOURCE 200809L #include "calog.h" #include "calogDb.h" #include "calogNet.h" #include #include #include static _Atomic int64_t reportedTotal = -1; static _Atomic bool scriptDone = false; static _Atomic int32_t errorCount = 0; static int32_t nativeDone(CalogValueT *args, int32_t argCount, CalogValueT *result, void *userData) { (void)args; (void)argCount; (void)userData; atomic_store(&scriptDone, true); calogValueNil(result); return calogOkE; } static int32_t nativeReport(CalogValueT *args, int32_t argCount, CalogValueT *result, void *userData) { (void)userData; calogValueNil(result); if (argCount != 1 || args[0].type != calogIntE) { return calogFail(result, calogErrArgE, "report expects one integer"); } atomic_store(&reportedTotal, args[0].as.i); return calogOkE; } static void onError(uint64_t contextId, const char *message, void *userData) { (void)contextId; (void)userData; fprintf(stderr, "script error: %s\n", (message != NULL) ? message : "(null)"); atomic_fetch_add(&errorCount, 1); } int main(void) { CalogT *calog; CalogContextT *ctx; struct timespec tick = { 0, 1000000 }; int i; calog = calogCreate(); if (calog == NULL) { printf("calog create failed\n"); return 1; } calogSetErrorHandler(calog, onError, NULL); calogRegister(calog, "report", nativeReport, NULL); calogRegister(calog, "done", nativeDone, NULL); if (calogDbRegister(calog) != calogOkE || calogNetRegister(calog) != calogOkE) { printf("library registration failed\n"); return 1; } ctx = calogContextOpen(calog, &calogLuaEngine); if (ctx == NULL) { printf("context open failed\n"); calogDestroy(calog); calogDbShutdown(); calogNetShutdown(); return 1; } calogContextEval(ctx, "local db = dbOpen('sqlite', ':memory:')\n" "dbExec(db, 'create table n (v integer)')\n" "for i = 1, 10 do dbExec(db, 'insert into n values (?)', i) end\n" "local rows = dbQuery(db, 'select sum(v) as total from n')\n" "local total = rows[1].total\n" "dbClose(db)\n" "local s = udpOpen(0)\n" "udpClose(s)\n" "report(total)\n" "done()"); for (i = 0; i < 2000 && !atomic_load(&scriptDone) && atomic_load(&errorCount) == 0; i++) { calogPump(calog); nanosleep(&tick, NULL); } calogPump(calog); calogContextClose(ctx); calogDestroy(calog); calogDbShutdown(); calogNetShutdown(); if (atomic_load(&reportedTotal) != 55) { printf("FAILED: expected 55, got %lld\n", (long long)atomic_load(&reportedTotal)); return 1; } printf("static calog app OK: SQLite summed 1..10 = %lld, UDP socket opened + closed\n", (long long)atomic_load(&reportedTotal)); return 0; }