kit

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

run_include_next.sh (3177B)


      1 #!/usr/bin/env bash
      2 # test/pp/run_include_next.sh — regression for `#include_next` and
      3 # `__has_include_next` (clang/GCC preprocessor extensions).
      4 #
      5 # #include_next resumes the header search in the directories *after* the one the
      6 # current file was found in — the mechanism system-header wrappers use to pull in
      7 # the "real" header of the same name further down the search path. It cannot be
      8 # exercised by the single-`-I` golden corpus (test/pp/run.sh), so it gets its own
      9 # two-directory harness here.
     10 #
     11 # Layout: dirs a/ and b/ both hold widget.h. Compiling `#include <widget.h>` with
     12 # `-I a -I b` resolves to a/widget.h; its `#include_next <widget.h>` must then
     13 # reach b/widget.h (the next dir), not loop back on itself. __has_include_next
     14 # from a/ must see b/widget.h as present, and from b/ (the last dir) as absent.
     15 #
     16 # Host-target only: no sysroot needed (all headers are local).
     17 
     18 set -u
     19 
     20 ROOT=${KIT_TEST_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)}
     21 KIT=${KIT:-"$ROOT/build/kit"}
     22 export KIT
     23 
     24 KIT_KIT_DIR="$ROOT/test/lib"
     25 . "$ROOT/test/lib/kit_sh_kit.sh"
     26 kit_require_kit pp-include-next
     27 
     28 kit_report_init
     29 work=$(mktemp -d "${TMPDIR:-/tmp}/kit-pp-incnext.XXXXXX")
     30 trap 'rm -rf "$work"' EXIT
     31 cd "$work" || exit 2
     32 
     33 mkdir -p a b
     34 cat > a/widget.h <<'EOF'
     35 marker_a_before
     36 #if __has_include_next(<widget.h>)
     37 a_sees_next
     38 #else
     39 a_no_next
     40 #endif
     41 #include_next <widget.h>
     42 marker_a_after
     43 EOF
     44 cat > b/widget.h <<'EOF'
     45 marker_b
     46 #if __has_include_next(<widget.h>)
     47 b_sees_next
     48 #else
     49 b_no_next
     50 #endif
     51 EOF
     52 printf '#include <widget.h>\ndone\n' > main.c
     53 
     54 # emit_seq NAME : `kit cc -E -I a -I b main.c` must succeed and its output tokens
     55 # must appear in the exact relative order of the remaining args.
     56 emit_seq() {
     57     name=$1; shift
     58     if ! "$KIT" cc -E -I a -I b main.c -o "$work/$name.pp" \
     59             >"$work/$name.out" 2>"$work/$name.err"; then
     60         kit_fail "$name" "kit cc -E failed; see $work/$name.err"
     61         return
     62     fi
     63     # Collapse to one token per line, then check the needles appear in order.
     64     tr -s '[:space:]' '\n' < "$work/$name.pp" > "$work/$name.toks"
     65     local prev=0 line
     66     for tok in "$@"; do
     67         line=$(grep -nxF "$tok" "$work/$name.toks" | head -1 | cut -d: -f1)
     68         if [ -z "$line" ]; then
     69             kit_fail "$name" "missing token '$tok'"; return
     70         fi
     71         if [ "$line" -le "$prev" ]; then
     72             kit_fail "$name" "token '$tok' out of order (line $line <= $prev)"; return
     73         fi
     74         prev=$line
     75     done
     76     kit_pass "$name"
     77 }
     78 
     79 # include_next from a/ reaches b/ (and a/ continues after); __has_include_next
     80 # is true in a/ (b follows) and false in b/ (last dir).
     81 emit_seq include_next_order \
     82     marker_a_before a_sees_next marker_b b_no_next marker_a_after done
     83 
     84 # A token that must NOT appear: a/ must not loop back onto itself (a_no_next),
     85 # and b/ must not think another widget.h follows it (b_sees_next).
     86 if grep -qxF a_no_next "$work/include_next_order.toks" 2>/dev/null \
     87    || grep -qxF b_sees_next "$work/include_next_order.toks" 2>/dev/null; then
     88     kit_fail include_next_no_loop "unexpected a_no_next/b_sees_next token"
     89 else
     90     kit_pass include_next_no_loop
     91 fi
     92 
     93 kit_summary pp-include-next
     94 kit_exit