summaryrefslogtreecommitdiff
path: root/tests/t0034-conditionals.sh
blob: 85f3d669559de8c3031592bfa2c9e3eda60c1e8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/sh
set -eu
base="${TMPDIR-/tmp}/mcpu-cpp-conditionals-$$"
mkdir -p "$base/inc"
trap 'rm -rf "$base"' EXIT HUP INT TERM

cat > "$base/inc/guard.h" <<'EOT'
#ifndef MCPP_TEST_GUARD_H
#define MCPP_TEST_GUARD_H 1
#define HEADER_VALUE 17
header_line
#endif
EOT

cat > "$base/main.c" <<'EOT'
#define A 1
#define B 2
#define F(x) ((x) + 1)

#include <guard.h>
#include <guard.h>

#if A + B * 3 == 7 && defined(A) && !defined(NO_SUCH_MACRO)
if_line
#else
bad_if
#endif

#if 0
#define BAD_SKIPPED 1
bad_elif_0
#elif F(B) == 3
elif_line
#else
bad_elif_else
#endif

#ifdef A
ifdef_line
#else
bad_ifdef
#endif

#ifndef NO_SUCH_MACRO
ifndef_line
#endif

#if 0
# if 1 / 0
bad_nested
# endif
#else
nested_skip_line
#endif

#if 0 && (1 / 0)
bad_short_and
#endif

#if 1 || (1 / 0)
short_or_line
#endif

#if 1 ? 2 : 1 / 0
ternary_true_line
#endif

#if 0 ? 1 / 0 : 3
ternary_false_line
#endif

#if UNKNOWN_IDENTIFIER
bad_unknown
#else
unknown_zero_line
#endif
EOT

"$MCPU_CPP" --no-config -I"$base/inc" -dD "$base/main.c" -o "$base/out"

for word in \
  header_line if_line elif_line ifdef_line ifndef_line nested_skip_line \
  short_or_line ternary_true_line ternary_false_line unknown_zero_line; do
  test "`grep -c "^${word}$" "$base/out"`" -eq 1
done

for word in \
  bad_if bad_elif_0 bad_elif_else bad_ifdef bad_nested bad_short_and bad_unknown; do
  if grep "^${word}$" "$base/out" >/dev/null; then exit 1; fi
done

# Conditional-control directives are consumed by the preprocessor and never
# survive in the normal output, including -dD output.
if grep '^[[:blank:]]*#[[:blank:]]*\(if\|ifdef\|ifndef\|elif\|else\|endif\)\>' "$base/out" >/dev/null; then
  exit 1
fi

# Active definitions are retained by -dD, skipped ones are not.
grep '^#define A 1$' "$base/out" >/dev/null
grep '^#define HEADER_VALUE 17$' "$base/out" >/dev/null
if grep '^#define BAD_' "$base/out" >/dev/null; then exit 1; fi

cat > "$base/bad-endif.c" <<'EOT'
#endif
EOT
if "$MCPU_CPP" --no-config "$base/bad-endif.c" -o "$base/bad-out" 2>/dev/null; then
  exit 1
fi

cat > "$base/bad-else.c" <<'EOT'
#if 1
#else
#else
#endif
EOT
if "$MCPU_CPP" --no-config "$base/bad-else.c" -o "$base/bad-out" 2>/dev/null; then
  exit 1
fi

cat > "$base/bad-elif.c" <<'EOT'
#if 0
#else
#elif 1
#endif
EOT
if "$MCPU_CPP" --no-config "$base/bad-elif.c" -o "$base/bad-out" 2>/dev/null; then
  exit 1
fi

cat > "$base/unterminated.c" <<'EOT'
#if 1
unterminated
EOT
if "$MCPU_CPP" --no-config "$base/unterminated.c" -o "$base/bad-out" 2>/dev/null; then
  exit 1
fi