kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 4528ed88ea666e52a2e2a81bffe57011a50c1995
parent ed999ee8e1b053dc5cf1e7fba06cd1ea4d9fe9f2
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Wed, 15 Jul 2026 20:46:16 -0700

driver: standardize command help behavior

Diffstat:
Mdriver/cmd/addr2line.c | 2+-
Mdriver/cmd/build_coord.c | 2+-
Mdriver/cmd/cas.c | 14+++++++++++++-
Mdriver/cmd/cc.c | 11++++++++---
Mdriver/cmd/cmp.c | 2+-
Mdriver/cmd/cpio.c | 2+-
Mdriver/cmd/dbg.c | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mdriver/cmd/install.c | 2+-
Mdriver/cmd/nm.c | 2+-
Mdriver/cmd/objcopy.c | 11++++++++---
Mdriver/cmd/pkg.c | 18+++++++++++++++++-
Mdriver/cmd/size.c | 2+-
Mdriver/cmd/strip.c | 11++++++++---
Mdriver/cmd/symbolize.c | 12++++++------
Mdriver/main.c | 4++--
Mmk/test.mk | 6+++++-
Mtest/TESTMAP.md | 2+-
Mtest/audit/release/modules/help.sh | 4++--
Atest/driver/help_uniform.sh | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
19 files changed, 265 insertions(+), 41 deletions(-)

diff --git a/driver/cmd/addr2line.c b/driver/cmd/addr2line.c @@ -87,7 +87,7 @@ void driver_help_addr2line(void) { "USAGE\n" " kit addr2line [OPTIONS] -e FILE [ADDR...]\n" "\n" - "ADDRESS / OUTPUT\n" + "DESCRIPTION\n" " ADDR is hexadecimal, with or without a 0x prefix, and is a\n" " link-time address in FILE. With no ADDR operands, read one hex\n" " address token per line from stdin. The normal result is\n" diff --git a/driver/cmd/build_coord.c b/driver/cmd/build_coord.c @@ -1513,7 +1513,7 @@ int driver_build(int argc, char** argv) { char hex[2u * KIT_BUILD_HASH_LEN + 1u]; int rc; - if (driver_argv_wants_help(argc, argv, 1)) { + if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) { driver_help_build(); return 0; } diff --git a/driver/cmd/cas.c b/driver/cmd/cas.c @@ -23,11 +23,23 @@ void driver_help_cas(void) { " kit cas verify-tree --cas DIR TREE_ID\n" " kit cas materialize --cas DIR TREE_ID -C DIR\n" "\n" + "DESCRIPTION\n" + " Stores immutable blobs and canonical file trees by content ID, then\n" + " inspects, verifies, or materializes those trees. CAS objects are\n" + " content-verified but are not signed.\n" + "\n" + "OPTIONS\n" + " --cas DIR content-addressed store (required)\n" + " --root DIR recursively add a directory tree\n" + " --map FILE add a tree described by a mapping file\n" + " -C DIR materialization destination\n" + " -h, --help show this help and exit\n" + "\n" "STORE AND IDS\n" " --cas DIR is required; there is no implicit store. add-blob and\n" " add-tree print one lowercase 64-hex content ID to stdout. A tree ID\n" " names a canonical manifest of relative paths, modes, sizes, and blob\n" - " identities. CAS objects are content-verified, not signed.\n" + " identities.\n" "\n" "ADD TREE INPUTS\n" " --root DIR recursively store regular files from DIR.\n" diff --git a/driver/cmd/cc.c b/driver/cmd/cc.c @@ -179,7 +179,12 @@ void driver_help_cc(void) { " kit cc --emit=c|ir [options] INPUT.c emit C or IR\n" " kit cc -fsyntax-only [options] INPUT... check only\n" "\n" - "INPUTS AND OUTPUTS\n" + "DESCRIPTION\n" + " Compiles C and assembly sources, optionally linking compatible\n" + " objects, archives, and shared libraries into a program. It can\n" + " also stop after preprocessing, dependency generation, semantic\n" + " checks, assembly, object, portable C, or semantic IR output.\n" + "\n" " .c is C source; .S is preprocessed assembly; .s is assembly.\n" " Target-compatible .o, .a, and ELF .so files are accepted by the\n" " link stage. A single `-` input reads stdin; use `-x c -` when an\n" @@ -190,7 +195,7 @@ void driver_help_cc(void) { " <base>.o and <base>.s for one source. -E, -M, and -MM write stdout\n" " when -o is absent. Use -o for --emit=c/ir and combined outputs.\n" "\n" - "PREPROCESSING AND DEPENDENCIES\n" + "OPTIONS\n" " -I DIR, -isystem DIR Add user/system include directories\n" " -D NAME[=BODY], -U NAME Define or undefine a macro\n" " -E Preprocess without compiling\n" @@ -314,7 +319,7 @@ void driver_help_check(void) { " `kit cc -fsyntax-only`. It writes diagnostics only: no object,\n" " assembly, executable, or dependency output is produced.\n" "\n" - "OPTIONS AND INPUTS\n" + "OPTIONS\n" " Accepts the cc preprocessing, target, sysroot, diagnostic, and\n" " language options described by `kit cc --help`, including -I,\n" " -isystem, -D, -U, -std=c11, -Werror, -fmax-errors=N,\n" diff --git a/driver/cmd/cmp.c b/driver/cmd/cmp.c @@ -119,7 +119,7 @@ int driver_cmp(int argc, char** argv) { size_t sl1 = 0, sl2 = 0; int loaded1 = 0, loaded2 = 0; - if (driver_argv_wants_help(argc, argv, 1)) { + if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) { driver_help_cmp(); return 0; } diff --git a/driver/cmd/cpio.c b/driver/cmd/cpio.c @@ -1002,7 +1002,7 @@ int driver_cpio(int argc, char** argv) { size_t nops = 0; int i, rc = 2; - if (driver_argv_wants_help(argc, argv, 1)) { + if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) { driver_help_cpio(); return 0; } diff --git a/driver/cmd/dbg.c b/driver/cmd/dbg.c @@ -14,6 +14,7 @@ #include "backtrace.h" #include "cflags.h" #include "driver.h" +#include "hosted.h" #include "inputs.h" /* `kit dbg` — interactive JIT debugger. @@ -63,9 +64,12 @@ typedef struct DbgOpts { int opt_level; int debug_info; const char* entry; + const char* sysroot; + int wants_hosted_libc; KitLanguage default_lang; int has_default_lang; + DriverHostedPlan hosted; DriverCflags cf; DriverInputs inputs; @@ -88,13 +92,12 @@ void driver_help_dbg(void) { " kit dbg [options] [input.{c,s,wat,wasm} ...] [-- prog-arg ...]\n" "\n" "DESCRIPTION\n" - " Mirrors `kit run` for compile flags and argv shape, but " - "instead\n" - " of calling the entry directly drops into a REPL that drives the\n" - " JIT session: breakpoints, source-line stepping (into / over),\n" - " instruction stepping,\n" - " finish, backtrace, registers, locals/args, variable read/write,\n" - " and raw memory examine. -g is forced on so source lines and\n" + " Uses `kit run`'s preprocessing, hosted-SDK, and argv shape, but\n" + " instead of calling the entry directly drops into a REPL that\n" + " drives the JIT session: breakpoints, source-line stepping into or\n" + " over calls, instruction stepping, finish, backtrace, registers,\n" + " locals/args, variable read/write, and raw memory examine. -g is\n" + " forced on so source lines and\n" " variable locations are available at runtime.\n" " Current debugger support is limited to Darwin/Linux aarch64\n" " hosts.\n" @@ -109,9 +112,9 @@ void driver_help_dbg(void) { "(default -O0)\n" " -g Emit DWARF (forced on)\n" " -e SYMBOL Entry symbol (default `main`)\n" - " -target TRIPLE Host-compatible compile target\n" - " --sysroot DIR Hosted SDK/sysroot for headers with -lc\n" - " -lc Enable hosted libc headers/definitions\n" + " --sysroot DIR, -isysroot DIR\n" + " Hosted SDK/sysroot for headers with -lc\n" + " -lc, -l c Enable hosted libc headers/definitions\n" " -x LANG Default REPL language: c, asm, wasm/wat\n" " --language LANG Same as -x\n" " -I DIR Add quoted-include search path\n" @@ -222,13 +225,40 @@ static int dbg_alloc_arrays(DbgOpts* o, int argc) { } if (driver_inputs_init(&o->inputs, o->env, DBG_TOOL, argc) != 0) return 1; o->inputs.frontends = o->frontends; - if (driver_cflags_init(&o->cf, o->env, argc) != 0) { + if (driver_cflags_init( + &o->cf, o->env, + argc + DRIVER_HOSTED_MAX_INCLUDES + DRIVER_HOSTED_MAX_DEFINES) != 0) { driver_errf(DBG_TOOL, "out of memory"); return 1; } return 0; } +static int dbg_apply_hosted_profile(DbgOpts* o) { + DriverHostedRequest req; + uint32_t i; + if (!o->wants_hosted_libc) return 0; + { + DriverHostedRequest z = {0}; + req = z; + } + req.env = o->env; + req.tool = DBG_TOOL; + req.target = driver_host_target(); + req.sysroot = o->sysroot; + req.static_link = 0; + req.link_inputs = 0; + if (driver_hosted_resolve(&req, &o->hosted) != 0) return 1; + for (i = 0; i < o->hosted.nsystem_includes; ++i) { + o->cf.system_include_dirs[o->cf.nsystem_include_dirs++] = + o->hosted.system_includes[i]; + } + for (i = 0; i < o->hosted.ndefines; ++i) { + o->cf.defines[o->cf.ndefines++] = o->hosted.defines[i]; + } + return 0; +} + static int dbg_parse_language_name(DbgOpts* o, const char* name, KitLanguage* out) { KitLanguage lang; @@ -314,6 +344,46 @@ static int dbg_parse(int argc, char** argv, DbgOpts* o) { continue; } + if (driver_streq(a, "--sysroot") || driver_streq(a, "-isysroot")) { + if (++i >= argc) { + driver_errf(DBG_TOOL, "%.*s requires an argument", + KIT_SLICE_ARG(kit_slice_cstr(a))); + return 1; + } + o->sysroot = argv[i]; + continue; + } + if (driver_strneq(a, "--sysroot=", 10)) { + o->sysroot = a + 10; + continue; + } + if (driver_streq(a, "-lc")) { + o->wants_hosted_libc = 1; + continue; + } + if (driver_streq(a, "-l")) { + if (++i >= argc) { + driver_errf(DBG_TOOL, "-l requires an argument"); + return 1; + } + if (!driver_streq(argv[i], "c")) { + driver_errf(DBG_TOOL, "unsupported hosted library for JIT: -l%.*s", + KIT_SLICE_ARG(kit_slice_cstr(argv[i]))); + return 1; + } + o->wants_hosted_libc = 1; + continue; + } + if (driver_strneq(a, "-l", 2)) { + if (!driver_streq(a + 2, "c")) { + driver_errf(DBG_TOOL, "unsupported hosted library for JIT: %.*s", + KIT_SLICE_ARG(kit_slice_cstr(a))); + return 1; + } + o->wants_hosted_libc = 1; + continue; + } + if (driver_streq(a, "-e")) { if (++i >= argc) { driver_errf(DBG_TOOL, "-e requires an argument"); @@ -381,6 +451,7 @@ static int dbg_parse(int argc, char** argv, DbgOpts* o) { } } + if (dbg_apply_hosted_profile(o) != 0) return 1; if (!o->entry) o->entry = "main"; if (!o->debug_info) { /* Without -g there are no source lines or variable locations to @@ -394,6 +465,7 @@ static int dbg_parse(int argc, char** argv, DbgOpts* o) { static void dbg_options_release(DbgOpts* o) { size_t bound = o->argv_bound; + driver_hosted_plan_fini(o->env, &o->hosted); driver_inputs_release(&o->inputs); driver_cflags_fini(&o->cf, o->env); driver_free(o->env, o->prog_argv, bound * sizeof(*o->prog_argv)); diff --git a/driver/cmd/install.c b/driver/cmd/install.c @@ -86,7 +86,7 @@ int driver_install(int argc, char** argv) { unsigned done_count = 0, failures = 0; int i, rc = 2; - if (driver_argv_wants_help(argc, argv, 1)) { + if (argc < 2 || driver_argv_wants_help(argc, argv, 1)) { driver_help_install(); return 0; } diff --git a/driver/cmd/nm.c b/driver/cmd/nm.c @@ -252,7 +252,7 @@ void driver_help_nm(void) { "USAGE\n" " kit nm [OPTIONS] FILE...\n" "\n" - "INPUT / DEFAULT OUTPUT\n" + "DESCRIPTION\n" " Reads ELF, Mach-O, COFF/PE, and Wasm objects or linked images; a\n" " POSIX ar archive is opened member by member. The default static\n" " symbol table is sorted by symbol name and printed as ADDRESS,\n" diff --git a/driver/cmd/objcopy.c b/driver/cmd/objcopy.c @@ -41,6 +41,14 @@ void driver_help_objcopy(void) { "USAGE\n" " kit objcopy [OPTIONS] INPUT [OUTPUT]\n" "\n" + "DESCRIPTION\n" + " Copies an object while transforming its sections, symbols, strip\n" + " policy, or output format. If OUTPUT is omitted, INPUT is replaced\n" + " in place.\n" + "\n" + "OPTIONS\n" + " -h, --help Show this help and exit\n" + "\n" "OUTPUT\n" " With OUTPUT, write a separate file. If OUTPUT is omitted, INPUT\n" " is rewritten in place; name an OUTPUT while evaluating a\n" @@ -76,9 +84,6 @@ void driver_help_objcopy(void) { " linked executable, `kit image --format bin` provides explicit\n" " segment/section selection and layout validation.\n" "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit\n" - "\n" "EXAMPLES\n" " kit objcopy --strip-debug input.o output.o\n" " kit objcopy --add-section=.kitnote=note.txt input.o noted.o\n" diff --git a/driver/cmd/pkg.c b/driver/cmd/pkg.c @@ -35,6 +35,22 @@ void driver_help_pkg(void) { " kit pkg sign -s SECKEY [-o OUT] [--comment C] FILE\n" " kit pkg trust {path | list | add PUBKEY [label] | remove KEYID}\n" "\n" + "DESCRIPTION\n" + " Creates signed native or tar.gz packages, verifies package identity\n" + " and integrity, inspects manifests, manages trusted keys, and safely\n" + " unpacks authenticated contents.\n" + "\n" + "OPTIONS\n" + " -o OUT output path for keygen/create/sign\n" + " -s SECKEY secret signing key\n" + " -p PUBKEY explicit verification key\n" + " --tofu trust on first use\n" + " --format kpkg|tar.gz select or force the package format\n" + " --external DIR external CAS-shaped object store\n" + " -C DIR unpack destination\n" + " -h, --help show this help and exit\n"); + driver_printf( + "\n" "KEYS AND TRUST\n" " keygen -o BASE writes BASE.pub (public verification key) and BASE.key\n" " (passwordless secret signing key) using the host CSPRNG. Keep .key\n" @@ -759,7 +775,7 @@ int driver_pkg(int argc, char** argv) { int rc; if (driver_argv_wants_help(argc, argv, 1) || argc < 2) { driver_help_pkg(); - return argc < 2 ? 2 : 0; + return 0; } sub = argv[1]; driver_env_init(&env); diff --git a/driver/cmd/size.c b/driver/cmd/size.c @@ -171,7 +171,7 @@ void driver_help_size(void) { "USAGE\n" " kit size [OPTIONS] FILE...\n" "\n" - "INPUT / DEFAULT OUTPUT\n" + "DESCRIPTION\n" " Reads ELF, Mach-O, COFF/PE, and Wasm objects or linked images;\n" " POSIX ar archives are reported member by member. The default is\n" " Berkeley format in decimal: text, data, bss, total decimal/hex,\n" diff --git a/driver/cmd/strip.c b/driver/cmd/strip.c @@ -37,6 +37,14 @@ void driver_help_strip(void) { "USAGE\n" " kit strip [OPTIONS] FILE\n" "\n" + "DESCRIPTION\n" + " Copies a relocatable object or static archive while removing\n" + " selected debug sections and symbols. By default FILE is replaced\n" + " in place; use -o PATH to preserve the original.\n" + "\n" + "OPTIONS\n" + " -h, --help Show this help and exit\n" + "\n" "OPERATIONS (last one wins; default is --strip-all)\n" " --strip-debug remove debug-info sections\n" " --strip-unneeded remove debug + symbols not needed by " @@ -58,9 +66,6 @@ void driver_help_strip(void) { " small, non-executable, unusable output. Use -o for safe inputs so\n" " the original object/archive remains available for comparison.\n" "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit\n" - "\n" "EXAMPLES\n" " kit strip --strip-debug -o foo.stripped.o foo.o\n" " kit objdump -h foo.stripped.o\n" diff --git a/driver/cmd/symbolize.c b/driver/cmd/symbolize.c @@ -95,12 +95,7 @@ void driver_help_symbolize(void) { " <prog that prints a backtrace> | kit symbolize -e FILE\n" " kit symbolize -e FILE < backtrace.txt\n" "\n" - "OPTIONS\n" - " -e FILE object file with debug info (required)\n" - " --basenames strip directory from file paths\n" - " -h, --help show this help\n" - "\n" - "INPUT / OUTPUT\n" + "DESCRIPTION\n" " Reads raw `#N 0x<hex>` backtrace lines as text on stdin, resolves\n" " each address via FILE's debug info, and writes annotated text to\n" " stdout in the form\n" @@ -112,6 +107,11 @@ void driver_help_symbolize(void) { "no\n" "-e this release prints help and returns 0.\n" "\n" + "OPTIONS\n" + " -e FILE object file with debug info (required)\n" + " --basenames strip directory from file paths\n" + " -h, --help show this help\n" + "\n" "ADDRESS RESTRICTION\n" " Input addresses must be link-time addresses. Static/non-PIE\n" " runtime addresses already match. For PIE/ASLR, subtract the load\n" diff --git a/driver/main.c b/driver/main.c @@ -339,8 +339,8 @@ void driver_help_top(void) { " --version VER selects a release)\n" "\n" "NO-ARGUMENT BEHAVIOR\n" - " Compiler-like tools usually show help. Stream filters may read stdin,\n" - " dbg enters its REPL, and operand-required tools report bad usage.\n" + " Operand-oriented tools usually show help. Stream filters may read\n" + " stdin, dbg enters its REPL, and a few operational tools act directly.\n" " Each tool's page documents its stdin and output conventions.\n" "\n" "OUTPUT AND ENVIRONMENT\n" diff --git a/mk/test.mk b/mk/test.mk @@ -71,6 +71,7 @@ TEST_TARGETS = \ test-driver-cpio \ test-driver-cas \ test-driver-cc \ + test-driver-help \ test-driver-build \ test-driver-build-coord \ test-driver-lsan \ @@ -332,7 +333,10 @@ test-images: test-cf-corpus-selftest: @bash test/lib/kit_corpus_selftest.sh -test-driver: test-driver-cc test-driver-build test-driver-build-coord test-driver-ar test-driver-cpio test-driver-cas test-driver-strip test-driver-objcopy test-driver-objdump test-driver-pkg test-driver-strings test-driver-tools test-driver-wasm +test-driver: test-driver-help test-driver-cc test-driver-build test-driver-build-coord test-driver-ar test-driver-cpio test-driver-cas test-driver-strip test-driver-objcopy test-driver-objdump test-driver-pkg test-driver-strings test-driver-tools test-driver-wasm + +test-driver-help: bin + @KIT=$(abspath $(BIN)) sh test/driver/help_uniform.sh test-driver-cc: bin @KIT=$(abspath $(BIN)) sh test/driver/run.sh diff --git a/test/TESTMAP.md b/test/TESTMAP.md @@ -18,7 +18,7 @@ area you changed. | `src/debug/**`, `src/dbg/**` | `make test-t1-debug` | `make test-debug test-dwarf test-dbg` | | `src/emu/**`, `src/interp/**` | `make test-t1-emu-interp` | `make test-emu test-emu-unit test-interp` | | `lang/wasm/**`, `src/arch/wasm/**` | `make test-t1-wasm` | `make test-wasm test-wasm-target` | -| `driver/cmd/**`, byte utility tools | `make test-t1-tools` | matching `test-driver-*` target | +| `driver/cmd/**`, byte utility tools | `make test-t1-tools` | `make test-driver-help` plus the matching `test-driver-*` target | | `src/dist/**`, `src/api/cas.c`, `src/api/package.c` | `make test-t1-dist` | `make test-dist test-selfdist` | | `src/gram/**`, `driver/cmd/gram.c`, `test/gram/**` | `make test-t1-gram` | `make test-gram test-driver-gram` | | `test/lib/**`, `mk/test.mk` | `make test-t1-harness test-tier1` | affected suite | diff --git a/test/audit/release/modules/help.sh b/test/audit/release/modules/help.sh @@ -8,11 +8,11 @@ audit_help_safe_name() { audit_help_noargs_kind() { case "$1" in - build|install|cpio|cmp|gram) printf '%s\n' usage2 ;; + gram) printf '%s\n' usage2 ;; dbg) printf '%s\n' repl0 ;; strings|xxd|hash|sha256sum|b2sum|crc32|compress|gzip|lz4|lz4c) printf '%s\n' stdin0 ;; gunzip) printf '%s\n' stdin1 ;; - pkg|disas|mc) printf '%s\n' help2 ;; + disas|mc) printf '%s\n' help2 ;; update) printf '%s\n' operation ;; *) printf '%s\n' help0 ;; esac diff --git a/test/driver/help_uniform.sh b/test/driver/help_uniform.sh @@ -0,0 +1,105 @@ +#!/bin/sh +# Focused CLI help-shape and no-argument behavior checks. + +set -u + +script_dir=$(cd "$(dirname "$0")" && pwd) +repo_root=$(cd "$script_dir/../.." && pwd) + +KIT="${KIT:-$repo_root/build/kit}" + +if [ ! -x "$KIT" ]; then + echo "driver-help: kit binary not found at $KIT" >&2 + exit 2 +fi + +work=$(mktemp -d "${TMPDIR:-/tmp}/kit-driver-help-test.XXXXXX") +trap 'rm -rf "$work"' EXIT + +KIT_KIT_DIR="$repo_root/test/lib" +. "$repo_root/test/lib/kit_sh_kit.sh" +kit_report_init + +help_shape() { + tool=$1 + out="$work/$tool.help" + err="$work/$tool.help.err" + if ! "$KIT" "$tool" --help > "$out" 2> "$err"; then + not_ok "help-shape-$tool" "$err" + return + fi + usage=$(awk '$0 == "USAGE" { print NR; exit }' "$out") + desc=$(awk '$0 == "DESCRIPTION" { print NR; exit }' "$out") + opts=$(awk '$0 == "OPTIONS" { print NR; exit }' "$out") + exits=$(awk '$0 == "EXIT CODES" { print NR; exit }' "$out") + if [ -n "$usage" ] && [ -n "$desc" ] && [ -n "$opts" ] && + [ -n "$exits" ] && [ "$usage" -lt "$desc" ] && + [ "$desc" -lt "$opts" ] && [ "$opts" -lt "$exits" ] && + [ ! -s "$err" ]; then + ok "help-shape-$tool" + else + { + printf 'USAGE=%s DESCRIPTION=%s OPTIONS=%s EXIT_CODES=%s\n' \ + "$usage" "$desc" "$opts" "$exits" + sed 's/^/stdout: /' "$out" + sed 's/^/stderr: /' "$err" + } > "$work/$tool.help.diag" + not_ok "help-shape-$tool" "$work/$tool.help.diag" + fi +} + +for tool in cc check cas pkg build-exe build-lib nm size addr2line symbolize \ + strip objcopy; do + help_shape "$tool" +done + +for tool in build install cpio pkg cmp; do + noargs_out="$work/$tool.noargs.out" + noargs_err="$work/$tool.noargs.err" + help_out="$work/$tool.explicit-help.out" + help_err="$work/$tool.explicit-help.err" + if "$KIT" "$tool" > "$noargs_out" 2> "$noargs_err"; then + noargs_rc=0 + else + noargs_rc=$? + fi + if "$KIT" "$tool" --help > "$help_out" 2> "$help_err"; then + help_rc=0 + else + help_rc=$? + fi + if [ "$noargs_rc" -eq 0 ] && [ "$help_rc" -eq 0 ] && + cmp -s "$noargs_out" "$help_out" && [ ! -s "$noargs_err" ] && + [ ! -s "$help_err" ]; then + ok "noargs-help-$tool" + else + { + sed 's/^/noargs stdout: /' "$noargs_out" + sed 's/^/noargs stderr: /' "$noargs_err" + sed 's/^/help stdout: /' "$help_out" + sed 's/^/help stderr: /' "$help_err" + } > "$work/$tool.noargs.diag" + not_ok "noargs-help-$tool" "$work/$tool.noargs.diag" + fi +done + +# A minimal synthetic hosted SDK proves that dbg accepts the same -lc/sysroot +# workflow as run and actually adds the sysroot's system include directory. +mkdir -p "$work/sysroot/usr/include" "$work/sysroot/usr/lib" +printf '%s\n' '#define KIT_DBG_SYSROOT_VALUE 42' \ + > "$work/sysroot/usr/include/kit_dbg_sysroot_test.h" +: > "$work/sysroot/usr/lib/libc.so" +cat > "$work/dbg-sysroot.c" <<'SRC' +#include <kit_dbg_sysroot_test.h> +int main(void) { return KIT_DBG_SYSROOT_VALUE == 42 ? 0 : 1; } +SRC +if "$KIT" dbg -lc --sysroot "$work/sysroot" --batch --command q \ + "$work/dbg-sysroot.c" > "$work/dbg-sysroot.out" \ + 2> "$work/dbg-sysroot.err"; then + ok "dbg-sysroot-hosted-headers" +else + not_ok "dbg-sysroot-hosted-headers" "$work/dbg-sysroot.err" +fi + +kit_summary driver-help +kit_exit