xref: /freebsd/contrib/bmake/unit-tests/escape.mk (revision 78ae60b4)
1# $NetBSD: escape.mk,v 1.15 2023/10/19 18:24:33 rillig Exp $
2#
3# Test backslash escaping.
4
5# Extracts from the POSIX 2008 specification
6# <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html>:
7#
8#     Comments start with a <number-sign> ( '#' ) and continue until an
9#     unescaped <newline> is reached.
10#
11#     When an escaped <newline> (one preceded by a <backslash>) is found
12#     anywhere in the makefile except in a command line, an include
13#     line, or a line immediately preceding an include line, it shall
14#     be replaced, along with any leading white space on the following
15#     line, with a single <space>.
16#
17#     When an escaped <newline> is found in a command line in a
18#     makefile, the command line shall contain the <backslash>, the
19#     <newline>, and the next line, except that the first character of
20#     the next line shall not be included if it is a <tab>.
21#
22#     When an escaped <newline> is found in an include line or in a
23#     line immediately preceding an include line, the behavior is
24#     unspecified.
25#
26# Notice that the behaviour of <backslash><backslash> or
27# <backslash><anything other than newline> is not mentioned.  I think
28# this implies that <backslash> should be taken literally everywhere
29# except before <newline>.
30#
31# Our practice, despite what POSIX might say, is that "\#"
32# in a variable assignment stores "#" as part of the value.
33# The "\" is not taken literally, and the "#" does not begin a comment.
34#
35# Also, our practice is that an even number of backslashes before a
36# newline in a variable assignment simply stores the backslashes as part
37# of the value, and treats the newline as though it was not escaped.
38# Similarly, an even number of backslashes before a newline in a
39# command simply uses the backslashes as part of the command, but
40# does not escape the newline.  This is compatible with GNU make.
41
42all: .PHONY
43# We will add dependencies like "all: yet-another-test" later.
44
45# Some variables to be expanded in tests
46#
47a=	aaa
48A=	${a}
49
50# Backslash at end of line in a comment\
51should continue the comment. \
52# This is also tested in comment.mk.
53
54__printvars: .USE .MADE
55	@echo ${.TARGET}
56	@${.ALLSRC:@v@ printf "%s=:%s:\n" ${v:Q} ${${v}:Q}; @}
57
58# Embedded backslash in variable should be taken literally.
59#
60VAR1BS=		111\111
61VAR1BSa=	111\${a}
62VAR1BSA=	111\${A}
63VAR1BSda=	111\$${a}
64VAR1BSdA=	111\$${A}
65VAR1BSc=	111\# backslash escapes comment char, so this is part of the value
66VAR1BSsc=	111\ # This is a comment.  Value ends with <backslash><space>
67
68all: var-1bs
69var-1bs: .PHONY __printvars VAR1BS VAR1BSa VAR1BSA VAR1BSda VAR1BSdA \
70	VAR1BSc VAR1BSsc
71
72# Double backslash in variable should be taken as two literal backslashes.
73#
74VAR2BS=		222\\222
75VAR2BSa=	222\\${a}
76VAR2BSA=	222\\${A}
77VAR2BSda=	222\\$${a}
78VAR2BSdA=	222\\$${A}
79VAR2BSc=	222\\# backslash does not escape comment char, so this is a comment
80VAR2BSsc=	222\\ # This is a comment.  Value ends with <backslash><backslash>
81
82all: var-2bs
83var-2bs: .PHONY __printvars VAR2BS VAR2BSa VAR2BSA VAR2BSda VAR2BSdA \
84	VAR2BSc VAR2BSsc
85
86# In a variable assignment, when the sequence <backslash><newline> occurs at
87# the end of a physical line, it is replaced with a single space.
88#
89VAR1BSNL=	111\
90111
91VAR1BSNLa=	111\
92${a}
93VAR1BSNLA=	111\
94${A}
95VAR1BSNLda=	111\
96$${a}
97VAR1BSNLdA=	111\
98$${A}
99VAR1BSNLc=	111\
100# this should be processed as a comment
101VAR1BSNLsc=	111\
102 # this should be processed as a comment
103
104all: var-1bsnl
105var-1bsnl:	.PHONY
106var-1bsnl: .PHONY __printvars \
107	VAR1BSNL VAR1BSNLa VAR1BSNLA VAR1BSNLda VAR1BSNLdA \
108	VAR1BSNLc VAR1BSNLsc
109
110# Double-backslash-newline in a variable setting.
111# Both backslashes should be taken literally, and the newline is NOT escaped.
112#
113# The second lines below each end with '=' so that they will not
114# generate syntax errors regardless of whether or not they are
115# treated as part of the value.
116#
117VAR2BSNL=	222\\
118222=
119VAR2BSNLa=	222\\
120${a}=
121VAR2BSNLA=	222\\
122${A}=
123VAR2BSNLda=	222\\
124$${a}=
125VAR2BSNLdA=	222\\
126$${A}=
127VAR2BSNLc=	222\\
128# this should be processed as a comment
129VAR2BSNLsc=	222\\
130 # this should be processed as a comment
131
132all: var-2bsnl
133var-2bsnl: .PHONY __printvars \
134	VAR2BSNL VAR2BSNLa VAR2BSNLA VAR2BSNLda VAR2BSNLdA \
135	VAR2BSNLc VAR2BSNLsc
136
137# Triple-backslash-newline in a variable setting.
138# First two should be taken literally, and last should escape the newline.
139#
140# The second lines below each end with '=' so that they will not
141# generate syntax errors regardless of whether or not they are
142# treated as part of the value.
143#
144VAR3BSNL=	333\\\
145333=
146VAR3BSNLa=	333\\\
147${a}=
148VAR3BSNLA=	333\\\
149${A}=
150VAR3BSNLda=	333\\\
151$${a}=
152VAR3BSNLdA=	333\\\
153$${A}=
154VAR3BSNLc=	333\\\
155# this should be processed as a comment
156VAR3BSNLsc=	333\\\
157 # this should be processed as a comment
158
159all: var-3bsnl
160var-3bsnl: .PHONY __printvars \
161	VAR3BSNL VAR3BSNLa VAR3BSNLA VAR3BSNLda VAR3BSNLdA \
162	VAR3BSNLc VAR3BSNLsc
163
164# Backslash-newline in a variable setting, plus any amount of white space
165# on the next line, is replaced by a single space.
166#
167VAR1BSNL00=	first line\
168
169# above line is entirely empty, and this is a comment
170VAR1BSNL0=	first line\
171no space on second line
172VAR1BSNLs=	first line\
173 one space on second line
174VAR1BSNLss=	first line\
175  two spaces on second line
176VAR1BSNLt=	first line\
177	one tab on second line
178VAR1BSNLtt=	first line\
179		two tabs on second line
180VAR1BSNLxx=	first line\
181  	 	 	 many spaces and tabs [  	 ] on second line
182
183all: var-1bsnl-space
184var-1bsnl-space: .PHONY __printvars \
185	VAR1BSNL00 VAR1BSNL0 VAR1BSNLs VAR1BSNLss VAR1BSNLt VAR1BSNLtt \
186	VAR1BSNLxx
187
188# Backslash-newline in a command is retained.
189#
190# The "#" in "# second line without space" makes it a comment instead
191# of a syntax error if the preceding line is parsed incorrectly.
192# The ":" in "third line':" makes it look like the start of a
193# target instead of a syntax error if the first line is parsed incorrectly.
194#
195all: cmd-1bsnl
196cmd-1bsnl: .PHONY
197	@echo ${.TARGET}
198	echo :'first line\
199#second line without space\
200third line':
201	echo :'first line\
202     second line spaces should be retained':
203	echo :'first line\
204	second line tab should be elided':
205	echo :'first line\
206		only one tab should be elided, second tab remains'
207
208# When backslash-newline appears at the end of a command script,
209# both the backslash and the newline should be passed to the shell.
210# The shell should elide the backslash-newline.
211#
212all: cmd-1bsnl-eof
213cmd-1bsnl-eof:
214	@echo ${.TARGET}
215	echo :'command ending with backslash-newline'; \
216
217# above line must be blank
218
219# Double-backslash-newline in a command.
220# Both backslashes are retained, but the newline is not escaped.
221# XXX: This may differ from POSIX, but matches gmake.
222#
223# When make passes two backslashes to the shell, the shell will pass one
224# backslash to the echo command.
225#
226all: cmd-2bsnl
227cmd-2bsnl: .PHONY
228	@echo ${.TARGET}
229	echo take one\\
230# this should be a comment
231	echo take two\\
232	echo take three\\
233
234# Triple-backslash-newline in a command is retained.
235#
236all: cmd-3bsnl
237cmd-3bsnl: .PHONY
238	@echo ${.TARGET}
239	echo :'first line\\\
240#second line without space\\\
241third line':
242	echo :'first line\\\
243     second line spaces should be retained':
244	echo :'first line\\\
245	second line tab should be elided':
246	echo :'first line\\\
247		only one tab should be elided, second tab remains'
248