opt-file.mk revision 1.10 1 # $NetBSD: opt-file.mk,v 1.10 2020/12/22 08:51:30 rillig Exp $
2 #
3 # Tests for the -f command line option.
4
5 # TODO: Implementation
6
7 all: .PHONY
8 all: file-ending-in-backslash
9 all: file-ending-in-backslash-mmap
10 all: line-with-trailing-whitespace
11 all: file-containing-null-byte
12
13 # Passing '-' as the filename reads from stdin. This is unusual but possible.
14 #
15 # In the unlikely case where a file ends in a backslash instead of a newline,
16 # that backslash is trimmed. See ParseGetLine.
17 #
18 # make-2014.01.01.00.00.00 invoked undefined behavior, reading text from
19 # outside of the file buffer.
20 #
21 # printf '%s' 'VAR=value\' \
22 # | MALLOC_OPTIONS=JA make-2014.01.01.00.00.00 -r -f - -V VAR -dA 2>&1 \
23 # | less
24 #
25 # The debug output shows how make happily uses freshly allocated memory (the
26 # <A5>) and already freed memory ('Z').
27 #
28 # ParseReadLine (1): 'VAR=value\<A5><A5><A5><A5><A5><A5>'
29 # Global:VAR = value\<A5><A5><A5><A5><A5><A5>value\<A5><A5><A5><A5><A5><A5>
30 # ParseReadLine (2): 'alue\<A5><A5><A5><A5><A5><A5>'
31 # ParseDoDependency(alue\<A5><A5><A5><A5><A5><A5>)
32 # make-2014.01.01.00.00.00: "(stdin)" line 2: Need an operator
33 # ParseReadLine (3): '<A5><A5><A5>ZZZZZZZZZZZZZZZZ'
34 # ParseDoDependency(<A5><A5><A5>ZZZZZZZZZZZZZZZZ)
35 #
36 file-ending-in-backslash: .PHONY
37 @printf '%s' 'VAR=value\' \
38 | ${MAKE} -r -f - -V VAR
39
40 # Between parse.c 1.170 from 2010-12-25 and parse.c 1.511 from 2020-12-22,
41 # there was an out-of-bounds write in ParseGetLine, where line_end pointed at
42 # the end of the allocated buffer, in the special case where loadedfile_mmap
43 # had not added the final newline character.
44 file-ending-in-backslash-mmap: .PHONY
45 @printf '%s' 'VAR=value\' > opt-file-backslash
46 @${MAKE} -r -f opt-file-backslash -V VAR
47 @rm opt-file-backslash
48
49 # Since parse.c 1.511 from 2020-12-22, an assertion in ParseGetLine failed
50 # for lines that contained trailing whitespace. Worked around in parse.c
51 # 1.513, properly fixed in parse.c 1.514.
52 line-with-trailing-whitespace: .PHONY
53 @printf '%s' 'VAR=$@ ' > opt-file-trailing-whitespace
54 @${MAKE} -r -f opt-file-trailing-whitespace -V VAR
55 @rm opt-file-trailing-whitespace
56
57 # If a file contains null bytes, the rest of the line is skipped, and parsing
58 # continues in the next line. Throughout the history of make, the behavior
59 # has changed several times, sometimes knowingly, sometimes by accident.
60 #
61 # echo 'VAR=value' | tr 'l' '\0' > zero-byte.in
62 # printf '%s\n' 'all:' ': VAR=${VAR:Q}' >> zero-byte.in
63 #
64 # for year in $(seq 2003 2020); do
65 # echo $year:
66 # make-$year.01.01.00.00.00 -r -f zero-byte.in
67 # echo "exit status $?"
68 # echo
69 # done 2>&1 \
70 # | sed "s,$PWD/,.,"
71 #
72 # This program generated the following output:
73 #
74 # 2003 to 2007:
75 # exit status 0
76 #
77 # 2008 to 2010:
78 # make: "zero-byte.in" line 1: Zero byte read from file
79 # make: Fatal errors encountered -- cannot continue
80 #
81 # make: stopped in .
82 # exit status 1
83 #
84 # 2011 to 2013:
85 # make: no target to make.
86 #
87 # make: stopped in .
88 # exit status 2
89 #
90 # 2014 to 2020-12-06:
91 # make: "zero-byte.in" line 1: warning: Zero byte read from file, skipping rest of line.
92 # exit status 0
93 #
94 # Since 2020-12-07:
95 # make: "zero-byte.in" line 1: Zero byte read from file
96 # make: Fatal errors encountered -- cannot continue
97 # make: stopped in .
98 # exit status 1
99 file-containing-null-byte: .PHONY
100 @printf '%s\n' 'VAR=value' 'VAR2=VALUE2' \
101 | tr 'l' '\0' \
102 | ${MAKE} -r -f - -V VAR -V VAR2
103
104 all:
105 : Making ${.TARGET}
106