run_file_escape.sh (2745B)
1 #!/usr/bin/env bash 2 # test/pp/run_file_escape.sh — regression for __FILE__ string-literal escaping. 3 # 4 # __FILE__ expands to a string literal of the source path. On POSIX paths use 5 # '/', so wrapping the raw name in quotes happens to be a valid string literal; 6 # on Windows the path holds backslashes (C:\Users\...), and emitting them raw 7 # turns '\U'/'\u'/'\x' into bogus escape sequences — '\Users' was diagnosed as a 8 # "malformed UCN" and other components (e.g. '\r') silently corrupted the value. 9 # The preprocessor must escape '\' and '"' when building the __FILE__ literal. 10 # 11 # This reproduces the OS-path case faithfully (a backslash IS a legal filename 12 # byte on POSIX): we create files whose *names* contain backslashes/quotes and 13 # compile them, rather than a #line override (whose escapes are already in the 14 # token spelling, so it cannot reproduce the raw-path bug). A #line case is 15 # included too, to guard the symmetric destringize-then-re-escape path. 16 # 17 # Host-target only: each input is a self-contained TU (no includes), so no 18 # sysroot is needed and the test runs anywhere build/kit exists. 19 20 set -u 21 22 ROOT=${KIT_TEST_ROOT:-$(cd "$(dirname "$0")/../.." && pwd)} 23 KIT=${KIT:-"$ROOT/build/kit"} 24 export KIT 25 26 KIT_KIT_DIR="$ROOT/test/lib" 27 . "$ROOT/test/lib/kit_sh_kit.sh" 28 kit_require_kit pp-file-escape 29 30 kit_report_init 31 work=$(mktemp -d "${TMPDIR:-/tmp}/kit-pp-fesc.XXXXXX") 32 trap 'rm -rf "$work"' EXIT 33 cd "$work" || exit 2 34 35 # emit_has NAME SRCFILE NEEDLE : `kit cc -E SRCFILE` must succeed and its output 36 # must contain NEEDLE (the correctly-escaped spelling). 37 emit_has() { 38 name=$1; src=$2; needle=$3 39 if "$KIT" cc -E "$src" -o "$name.pp" >"$work/$name.out" 2>"$work/$name.err"; then 40 contains "$name" "$name.pp" "$needle" 41 else 42 not_ok "$name" "$work/$name.err" 43 fi 44 } 45 46 # --- raw OS path: '\U' was the hard "malformed UCN" error ------------------- 47 printf 'const char *f = __FILE__;\n' > 'seg\Uone.c' 48 emit_has emit_escape_U 'seg\Uone.c' 'seg\\Uone.c' 49 run_ok compile_backslash_U "$KIT" cc -c 'seg\Uone.c' -o "$work/u.o" 50 51 # --- raw OS path: '\r' silently injected a carriage return (no error) ------- 52 printf 'const char *f = __FILE__;\n' > 'seg\rtwo.c' 53 emit_has emit_escape_r 'seg\rtwo.c' 'seg\\rtwo.c' 54 55 # --- embedded double-quote in the name must escape too ---------------------- 56 printf 'const char *f = __FILE__;\n' > 'q"three.c' 57 emit_has emit_escape_quote 'q"three.c' 'q\"three.c' 58 59 # --- #line override: destringize-then-re-escape must stay correct ----------- 60 printf '#line 7 "a\\\\Users\\\\z.c"\nconst char *f = __FILE__;\n' > 'lineov.c' 61 emit_has emit_line_override 'lineov.c' '"a\\Users\\z.c"' 62 run_ok compile_line_override "$KIT" cc -c 'lineov.c' -o "$work/l.o" 63 64 kit_summary pp-file-escape 65 kit_exit