blob: e40b1ee515ac0a651d5daeb6c6baf94a4f7506d1 (
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
|
#!/bin/sh
set -eu
base="${TMPDIR-/tmp}/mcpu-cpp-output-line-compaction-$$"
mkdir -p "$base"
trap 'rm -rf "$base"' EXIT HUP INT TERM
# Seven invisible lines stay as seven ordinary newlines. The next visible
# source line is line 9, and no corrective marker is needed.
cat > "$base/gap7.c" <<'EOT'
int a;
// one
#define A 1
#if 0
hidden
#endif
/* six */
int b;
EOT
"$MCPU_CPP" --no-config "$base/gap7.c" -o "$base/gap7.out"
if grep -F "# 9 \"$base/gap7.c\"" "$base/gap7.out" >/dev/null; then
echo "unexpected line marker for seven-line invisible gap" >&2
exit 1
fi
gap7_count=`awk '
$0 == "int a;" { inside = 1; next }
$0 == "int b;" { print count; exit }
inside { ++count }
' "$base/gap7.out"`
test "$gap7_count" -eq 7
# Eight invisible lines cross the GNU CPP threshold. They disappear from the
# byte stream and are represented by a line marker for the next visible line.
cat > "$base/gap8.c" <<'EOT'
int a;
// one
#define A 1
#if 0
hidden
#endif
/* six */
// seven
int b;
EOT
"$MCPU_CPP" --no-config "$base/gap8.c" -o "$base/gap8.out"
grep -F "# 10 \"$base/gap8.c\"" "$base/gap8.out" >/dev/null
awk '
/^# 10 "/ { getline; if( $0 == "int b;" ) ok = 1 }
END { exit ok ? 0 : 1 }
' "$base/gap8.out"
# A completely invisible header has no synthetic end-of-header marker. Only
# the structural enter/return markers survive. A long invisible gap in the
# parent is then represented by the parent's next visible source position.
cat > "$base/silent.h" <<'EOT'
#ifndef SILENT_H
#define SILENT_H 1
#define H1 1
#define H2 2
#define H3 3
#define H4 4
#define H5 5
#define H6 6
#define H7 7
#define H8 8
#define H9 9
#endif
EOT
cat > "$base/include.c" <<'EOT'
// leading comment
#include "silent.h"
// one
#define P1 1
#if 0
hidden
#endif
// six
// seven
int visible;
EOT
"$MCPU_CPP" --no-config -I"$base" "$base/include.c" -o "$base/include.out"
grep -F "# 1 \"$base/silent.h\" 1" "$base/include.out" >/dev/null
grep -F "# 3 \"$base/include.c\" 2" "$base/include.out" >/dev/null
grep -F "# 11 \"$base/include.c\"" "$base/include.out" >/dev/null
if grep -E "^# (2|3|4|5|6|7|8|9|10|11|12) \"$base/silent.h\"" "$base/include.out" >/dev/null; then
echo "silent header acquired a synthetic progress marker" >&2
exit 1
fi
awk '
/\/silent\.h" 1$/ { getline; if( $0 ~ /\/include\.c" 2$/ ) adjacent = 1 }
/^# 11 "/ { getline; if( $0 == "int visible;" ) visible = 1 }
END { exit adjacent && visible ? 0 : 1 }
' "$base/include.out"
# The threshold is based on source position, not on why the lines are
# invisible. A long run of comments alone is compacted in exactly the same
# way as directives or inactive conditional text.
cat > "$base/comments.c" <<'EOT'
int before;
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
int after;
EOT
"$MCPU_CPP" --no-config "$base/comments.c" -o "$base/comments.out"
grep -F "# 10 \"$base/comments.c\"" "$base/comments.out" >/dev/null
# __LINE__ observes source coordinates, not the compacted output layout.
cat > "$base/line.c" <<'EOT'
int a = __LINE__;
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
int b = __LINE__;
EOT
"$MCPU_CPP" --no-config "$base/line.c" -o "$base/line.out"
grep -Fx 'int a = 1;' "$base/line.out" >/dev/null
grep -Fx 'int b = 10;' "$base/line.out" >/dev/null
grep -F "# 10 \"$base/line.c\"" "$base/line.out" >/dev/null
|