#!/bin/sh set -eu base="${TMPDIR-/tmp}/mcpu-cpp-macro-whitespace-$$" mkdir -p "$base" trap 'rm -rf "$base"' EXIT HUP INT TERM cat > "$base/main.c" <<'EOT' #define MULTI(fmt, ...) \ do \ { \ output(fmt __VA_OPT__(,) __VA_ARGS__); \ done(); \ } \ while( 0 ) #define TEXT "left right" #define OPS + + - > < < #define ID(x) x #define V(...) __VA_OPT__(__VA_ARGS__) void f( int x ) { MULTI("x=%d", x); MULTI("hello"); ID(alpha + beta); V(gamma + delta); const char *s = TEXT; OPS } EOT "$MCPU_CPP" --no-config "$base/main.c" -o "$base/out" sed '/^#/d; /^[[:space:]]*$/d' "$base/out" > "$base/norm" cat > "$base/expected" <<'EOT' void f( int x ) { do { output("x=%d" , x); done(); } while( 0 ); do { output("hello" ); done(); } while( 0 ); alpha + beta; gamma + delta; const char *s = "left right"; + + - > < < } EOT diff -u "$base/expected" "$base/norm" # Macro dumps use the same normalized replacement-list whitespace. "$MCPU_CPP" --no-config -dM "$base/main.c" > "$base/dump" grep -Fx '#define MULTI(fmt,...) do { output(fmt __VA_OPT__(,) __VA_ARGS__); done(); } while( 0 )' "$base/dump" >/dev/null grep -Fx '#define TEXT "left right"' "$base/dump" >/dev/null grep -Fx '#define OPS + + - > < <' "$base/dump" >/dev/null grep -Fx '#define ID(x) x' "$base/dump" >/dev/null grep -Fx '#define V(...) __VA_OPT__(__VA_ARGS__)' "$base/dump" >/dev/null # Ordinary source text that is not replacement-list formatting stays untouched. cat > "$base/plain.c" <<'EOT' int plain = 1; #define ID(x) x #define V(...) __VA_OPT__(__VA_ARGS__) ID(a + b) EOT "$MCPU_CPP" --no-config "$base/plain.c" -o "$base/plain.out" sed '/^#/d; /^[[:space:]]*$/d' "$base/plain.out" > "$base/plain.norm" cat > "$base/plain.expected" <<'EOT' int plain = 1; a + b EOT diff -u "$base/plain.expected" "$base/plain.norm"