From 4384435941b8c7658856b381d071aee2e0035e89 Mon Sep 17 00:00:00 2001 From: Berke Güzel Date: Mon, 12 Oct 2026 17:49:34 +0300 Subject: term: move the term core to subprojects/term The core now builds, tests, and benchmarks alone, as a Meson subproject with no dependency on the main tree. - include/term/ holds term.h and the header-only unicode/. src/ holds the core and its private headers. The main tree gets only include/term through term_dep, so it cannot reach a private header. - The term tests, the term benchmarks, the Kitty parser suite, and tools/amalgamate.py and tools/generate_unicode.py move with it. The tests run as term:. - The main build passes its -march (arch_flag) and b_ndebug to the subproject. A directory configured before this commit needs meson configure -Dterm:arch_flag=-march=... once. - The term tests compile with -UNDEBUG. They do work inside assert. - The subproject exports term_test_dep with term_api.h, for the main tree's render, thumbnail, color, and selection tests. - The Kitty bridge used struct vector2i and has not compiled since the public API redesign. It builds again. 2 of its 14 tests fail: REP after a tab, and a cursor report after a resize. - dirgraph.py drops the term and unicode layers. Its self-test uses pty. - The symbols test ignores the __odr_asan symbols that ASan adds. Co-Authored-By: Claude Opus 5.5 --- tests/symbols_test.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/symbols_test.sh (limited to 'tests/symbols_test.sh') diff --git a/tests/symbols_test.sh b/tests/symbols_test.sh new file mode 100644 index 0000000..4c7aee1 --- /dev/null +++ b/tests/symbols_test.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# Every global symbol of the term library starts with term_. A host links +# the library next to its own code, so a bare name such as palette_init can +# collide with a host symbol. Every function that term.h declares is also +# defined, so the library cannot leave one out. A shared build exports +# exactly the functions of term.h. +set -euo pipefail +lib=$1 +src=${2:-$(dirname "$0")/../include/term} + +syms=$(nm -g --defined-only -P "$lib") +# ASan adds an __odr_asan. symbol for each global variable. +defined=$(awk 'NF >= 2 && $2 ~ /^[A-Z]$/ && $2 != "U" { print $1 }' <<<"$syms" | + grep -v '^_*odr_asan\.' | sed 's/^_//' | sort -u) + +status=0 +bad=$(grep -v '^term_' <<<"$defined" || true) +if [[ -n $bad ]]; then + echo "$lib: global symbols without the term_ prefix:" >&2 + echo "$bad" >&2 + status=1 +fi + +declared=$("${CC:-cc}" -std=c11 -E -P -I"$src" "$src/term.h" | python3 -c ' +import re, sys +text = re.sub(r"\s+", " ", sys.stdin.read()) +depth, flat = 0, [] +for ch in text: + depth += ch == "{" + if depth == 0: + flat.append(ch) + depth -= ch == "}" + if ch == "}" and depth == 0: + flat.append(";") +for stmt in "".join(flat).split(";"): + if "static" in stmt or "typedef" in stmt: + continue + m = re.search(r"\b(term_\w+)\s*\(", stmt) + if m: + print(m.group(1)) +' | sort -u) +missing=$(comm -23 <(echo "$declared") <(echo "$defined")) +if [[ -n $missing ]]; then + echo "$lib: functions declared in term.h but not defined:" >&2 + echo "$missing" >&2 + status=1 +fi + +# The shared library exports term.h and nothing else. +shared=${3:-} +if [[ -n $shared ]]; then + exported=$(nm -D --defined-only -P "$shared" | awk '$2 ~ /^[TDBRVW]$/ { print $1 }' | + sed 's/^_//' | sort -u) + extra=$(comm -13 <(echo "$declared") <(echo "$exported")) + absent=$(comm -23 <(echo "$declared") <(echo "$exported")) + if [[ -n $extra || -n $absent ]]; then + echo "$shared: exports differ from term.h" >&2 + [[ -n $extra ]] && echo "not in term.h: $extra" >&2 + [[ -n $absent ]] && echo "not exported: $absent" >&2 + status=1 + fi +fi +exit $status -- cgit v1.2.3