summaryrefslogtreecommitdiff
path: root/tests/t0046-pragma-once.sh
blob: 9429dd7cd3ec0100b42e6d7248a050c267325dda (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
#!/bin/sh
set -eu
base="${TMPDIR-/tmp}/mcpu-cpp-pragma-once-$$"
mkdir -p "$base"
trap 'rm -rf "$base"' EXIT HUP INT TERM

cat > "$base/once.h" <<'EOT'
#pragma once
ONCE_BODY
EOT
ln -s once.h "$base/once-link.h"
ln "$base/once.h" "$base/once-hard.h"

cat > "$base/self.h" <<'EOT'
#pragma once
SELF_BEGIN
#include "self.h"
SELF_END
EOT

cat > "$base/inactive.h" <<'EOT'
#if 0
#pragma once
#endif
INACTIVE_BODY
EOT

cat > "$base/main.c" <<'EOT'
#include "once.h"
#include "once.h"
#include "once-link.h"
#include "once-hard.h"
#include "self.h"
#include "inactive.h"
#include "inactive.h"
#pragma pack(push, 1)
EOT

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

# The same physical file is processed only once, even through a symbolic link
# and a hard link.  #pragma once itself is consumed by the preprocessor.
test "$(grep -c '^ONCE_BODY$' "$base/out")" -eq 1
! grep '^#pragma once$' "$base/out" >/dev/null

# Marking happens as soon as the active directive is seen, so a file may safely
# include itself after #pragma once without recursive inclusion.
test "$(grep -c '^SELF_BEGIN$' "$base/out")" -eq 1
test "$(grep -c '^SELF_END$' "$base/out")" -eq 1

# An inactive #pragma once has no effect.
test "$(grep -c '^INACTIVE_BODY$' "$base/out")" -eq 2

# Other pragmas are not consumed; they remain available to the later compiler.
grep '^#pragma pack(push, 1)$' "$base/out" >/dev/null

# -dD does not make #pragma once reappear; unrelated pragmas are still kept.
"$MCPU_CPP" --no-config -dD "$base/main.c" -o "$base/dd.out"
! grep '^#pragma once$' "$base/dd.out" >/dev/null
grep '^#pragma pack(push, 1)$' "$base/dd.out" >/dev/null

# A non-file input stream has no physical identity.  The directive is simply
# consumed and must not turn stdin preprocessing into an error.
printf '#pragma once\nSTDIN_BODY\n' | \
  "$MCPU_CPP" --no-config > "$base/stdin.out"
grep '^STDIN_BODY$' "$base/stdin.out" >/dev/null
! grep '^#pragma once$' "$base/stdin.out" >/dev/null