summaryrefslogtreecommitdiff
path: root/tests/t0043-include-next.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tests/t0043-include-next.sh')
-rwxr-xr-xtests/t0043-include-next.sh87
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/t0043-include-next.sh b/tests/t0043-include-next.sh
new file mode 100755
index 0000000..a2d86c3
--- /dev/null
+++ b/tests/t0043-include-next.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+set -eu
+base="${TMPDIR-/tmp}/mcpu-cpp-include-next-$$"
+mkdir -p "$base/wrapper" "$base/system" "$base/after" "$base/local"
+trap 'rm -rf "$base"' EXIT HUP INT TERM
+
+cat > "$base/config" <<EOT
+MCPU_CPP_SYSTEM_INCLUDE_PATH = $base/system;
+EOT
+
+cat > "$base/main.c" <<'EOT'
+#include <wrapped.h>
+#include "local/local.h"
+#if 0
+#include_next <never.h>
+#endif
+EOT
+
+cat > "$base/wrapper/wrapped.h" <<'EOT'
+wrapper_begin
+#line 500 "virtual/wrapped.h"
+#define NEXT_WRAPPED <wrapped.h>
+#include_next NEXT_WRAPPED
+wrapper_end
+EOT
+
+cat > "$base/system/wrapped.h" <<'EOT'
+system_begin
+#include_next "wrapped.h"
+system_end
+EOT
+
+cat > "$base/after/wrapped.h" <<'EOT'
+after_header
+EOT
+
+cat > "$base/local/local.h" <<'EOT'
+local_header
+#include_next <from_chain.h>
+EOT
+
+cat > "$base/wrapper/from_chain.h" <<'EOT'
+from_chain_wrapper
+EOT
+
+"$MCPU_CPP" --config-file "$base/config" \
+ -isystem "$base/wrapper" -idirafter "$base/after" \
+ "$base/main.c" -o "$base/out"
+
+# The wrapper header found through -isystem continues into the configured
+# system include root, then that header continues into -idirafter. The quote
+# form of #include_next must not re-search the current source directory.
+awk '
+ /wrapper_begin/ { a = NR }
+ /system_begin/ { b = NR }
+ /after_header/ { c = NR }
+ /system_end/ { d = NR }
+ /wrapper_end/ { e = NR }
+ END { exit !(a && a < b && b < c && c < d && d < e) }
+' "$base/out"
+
+# A header found by ordinary quoted-source-directory lookup has no configured
+# search entry to skip, so include_next begins with the configured chain.
+grep '^local_header$' "$base/out" >/dev/null
+grep '^from_chain_wrapper$' "$base/out" >/dev/null
+
+# Macro-expanded include_next operands use the same include operand parser.
+grep '^system_begin$' "$base/out" >/dev/null
+
+# Inactive conditional branches must not execute include_next.
+! grep 'never.h' "$base/out" >/dev/null
+
+# If no later search entry contains the file, include_next is an error rather
+# than falling back to the directory that supplied the current header.
+cat > "$base/wrapper/last.h" <<'EOT'
+#include_next <last.h>
+EOT
+cat > "$base/last-main.c" <<'EOT'
+#include <last.h>
+EOT
+if "$MCPU_CPP" --config-file "$base/config" \
+ -isystem "$base/wrapper" "$base/last-main.c" \
+ -o "$base/last.out" 2>"$base/last.err"; then
+ echo '#include_next unexpectedly found the current header again' >&2
+ exit 1
+fi
+grep "cannot find include_next file 'last.h'" "$base/last.err" >/dev/null