1281760Ssjg# $Id: escape.mk,v 1.1.1.2 2014/11/06 01:40:37 sjg Exp $
2281760Ssjg#
3281760Ssjg# Test backslash escaping.
4281760Ssjg
5281760Ssjg# Extracts from the POSIX 2008 specification
6281760Ssjg# <http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html>:
7281760Ssjg#
8281760Ssjg#     Comments start with a <number-sign> ( '#' ) and continue until an
9281760Ssjg#     unescaped <newline> is reached.
10281760Ssjg#
11281760Ssjg#     When an escaped <newline> (one preceded by a <backslash>) is found
12281760Ssjg#     anywhere in the makefile except in a command line, an include
13281760Ssjg#     line, or a line immediately preceding an include line, it shall
14281760Ssjg#     be replaced, along with any leading white space on the following
15281760Ssjg#     line, with a single <space>.
16281760Ssjg#
17281760Ssjg#     When an escaped <newline> is found in a command line in a
18281760Ssjg#     makefile, the command line shall contain the <backslash>, the
19281760Ssjg#     <newline>, and the next line, except that the first character of
20281760Ssjg#     the next line shall not be included if it is a <tab>.
21281760Ssjg#
22281760Ssjg#     When an escaped <newline> is found in an include line or in a
23281760Ssjg#     line immediately preceding an include line, the behavior is
24281760Ssjg#     unspecified.
25281760Ssjg#
26281760Ssjg# Notice that the behaviour of <backslash><backslash> or
27281760Ssjg# <backslash><anything other than newline> is not mentioned.  I think
28281760Ssjg# this implies that <backslash> should be taken literally everywhere
29281760Ssjg# except before <newline>.
30281760Ssjg#
31281760Ssjg# Our practice, despite what POSIX might say, is that "\#"
32281760Ssjg# in a variable assignment stores "#" as part of the value.
33281760Ssjg# The "\" is not taken literally, and the "#" does not begin a comment.
34281760Ssjg#
35281760Ssjg# Also, our practice is that an even number of backslashes before a
36281760Ssjg# newline in a variable assignment simply stores the backslashes as part
37281760Ssjg# of the value, and treats the newline as though it was not escaped.
38281760Ssjg# Similarly, ann even number of backslashes before a newline in a
39281760Ssjg# command simply uses the backslashes as part of the command test, but
40281760Ssjg# does not escape the newline.  This is compatible with GNU make.
41281760Ssjg
42281760Ssjgall: .PHONY
43281760Ssjg# We will add dependencies like "all: yet-another-test" later.
44281760Ssjg
45281760Ssjg# Some variables to be expanded in tests
46281760Ssjg#
47281760Ssjga = aaa
48281760SsjgA = ${a}
49281760Ssjg
50281760Ssjg# Backslash at end of line in a comment\
51281760Ssjgshould continue the comment. \
52281760Ssjg# This is also tested in comment.mk.
53281760Ssjg
54281760Ssjg__printvars: .USE .MADE
55281760Ssjg	@echo ${.TARGET}
56281760Ssjg	${.ALLSRC:@v@ printf "%s=:%s:\n" ${v:Q} ${${v}:Q}; @}
57281760Ssjg
58281760Ssjg# Embedded backslash in variable should be taken literally.
59281760Ssjg#
60281760SsjgVAR1BS = 111\111
61281760SsjgVAR1BSa = 111\${a}
62281760SsjgVAR1BSA = 111\${A}
63281760SsjgVAR1BSda = 111\$${a}
64281760SsjgVAR1BSdA = 111\$${A}
65281760SsjgVAR1BSc = 111\# backslash escapes comment char, so this is part of the value
66281760SsjgVAR1BSsc = 111\ # This is a comment.  Value ends with <backslash><space>
67281760Ssjg
68281760Ssjgall: var-1bs
69281760Ssjgvar-1bs: .PHONY __printvars VAR1BS VAR1BSa VAR1BSA VAR1BSda VAR1BSdA \
70281760Ssjg	VAR1BSc VAR1BSsc
71281760Ssjg
72281760Ssjg# Double backslash in variable should be taken as two literal backslashes.
73281760Ssjg#
74281760SsjgVAR2BS = 222\\222
75281760SsjgVAR2BSa = 222\\${a}
76281760SsjgVAR2BSA = 222\\${A}
77281760SsjgVAR2BSda = 222\\$${a}
78281760SsjgVAR2BSdA = 222\\$${A}
79281760SsjgVAR2BSc = 222\\# backslash does not escape comment char, so this is a comment
80281760SsjgVAR2BSsc = 222\\ # This is a comment.  Value ends with <backslash><backslash>
81281760Ssjg
82281760Ssjgall: var-2bs
83281760Ssjgvar-2bs: .PHONY __printvars VAR2BS VAR2BSa VAR2BSA VAR2BSda VAR2BSdA \
84281760Ssjg	VAR2BSc VAR2BSsc
85281760Ssjg
86281760Ssjg# Backslash-newline in a variable setting is replaced by a single space.
87281760Ssjg#
88281760SsjgVAR1BSNL = 111\
89281760Ssjg111
90281760SsjgVAR1BSNLa = 111\
91281760Ssjg${a}
92281760SsjgVAR1BSNLA = 111\
93281760Ssjg${A}
94281760SsjgVAR1BSNLda = 111\
95281760Ssjg$${a}
96281760SsjgVAR1BSNLdA = 111\
97281760Ssjg$${A}
98281760SsjgVAR1BSNLc = 111\
99281760Ssjg# this should be processed as a comment
100281760SsjgVAR1BSNLsc = 111\
101281760Ssjg # this should be processed as a comment
102281760Ssjg
103281760Ssjgall: var-1bsnl
104281760Ssjgvar-1bsnl:	.PHONY
105281760Ssjgvar-1bsnl: .PHONY __printvars \
106281760Ssjg	VAR1BSNL VAR1BSNLa VAR1BSNLA VAR1BSNLda VAR1BSNLdA \
107281760Ssjg	VAR1BSNLc VAR1BSNLsc
108281760Ssjg
109281760Ssjg# Double-backslash-newline in a variable setting.
110281760Ssjg# Both backslashes should be taken literally, and the newline is NOT escaped.
111281760Ssjg#
112281760Ssjg# The second lines below each end with '=' so that they will not
113281760Ssjg# generate syntax errors regardless of whether or not they are
114281760Ssjg# treated as part of the value.
115281760Ssjg#
116281760SsjgVAR2BSNL = 222\\
117281760Ssjg222=
118281760SsjgVAR2BSNLa = 222\\
119281760Ssjg${a}=
120281760SsjgVAR2BSNLA = 222\\
121281760Ssjg${A}=
122281760SsjgVAR2BSNLda = 222\\
123281760Ssjg$${a}=
124281760SsjgVAR2BSNLdA = 222\\
125281760Ssjg$${A}=
126281760SsjgVAR2BSNLc = 222\\
127281760Ssjg# this should be processed as a comment
128281760SsjgVAR2BSNLsc = 222\\
129281760Ssjg # this should be processed as a comment
130281760Ssjg
131281760Ssjgall: var-2bsnl
132281760Ssjgvar-2bsnl: .PHONY __printvars \
133281760Ssjg	VAR2BSNL VAR2BSNLa VAR2BSNLA VAR2BSNLda VAR2BSNLdA \
134281760Ssjg	VAR2BSNLc VAR2BSNLsc
135281760Ssjg
136281760Ssjg# Triple-backslash-newline in a variable setting.
137281760Ssjg# First two should be taken literally, and last should escape the newline.
138281760Ssjg#
139281760Ssjg# The second lines below each end with '=' so that they will not
140281760Ssjg# generate syntax errors regardless of whether or not they are
141281760Ssjg# treated as part of the value.
142281760Ssjg#
143281760SsjgVAR3BSNL = 333\\\
144281760Ssjg333=
145281760SsjgVAR3BSNLa = 333\\\
146281760Ssjg${a}=
147281760SsjgVAR3BSNLA = 333\\\
148281760Ssjg${A}=
149281760SsjgVAR3BSNLda = 333\\\
150281760Ssjg$${a}=
151281760SsjgVAR3BSNLdA = 333\\\
152281760Ssjg$${A}=
153281760SsjgVAR3BSNLc = 333\\\
154281760Ssjg# this should be processed as a comment
155281760SsjgVAR3BSNLsc = 333\\\
156281760Ssjg # this should be processed as a comment
157281760Ssjg
158281760Ssjgall: var-3bsnl
159281760Ssjgvar-3bsnl: .PHONY __printvars \
160281760Ssjg	VAR3BSNL VAR3BSNLa VAR3BSNLA VAR3BSNLda VAR3BSNLdA \
161281760Ssjg	VAR3BSNLc VAR3BSNLsc
162281760Ssjg
163281760Ssjg# Backslash-newline in a variable setting, plus any amount of white space
164281760Ssjg# on the next line, is replaced by a single space.
165281760Ssjg#
166281760SsjgVAR1BSNL00= first line\
167281760Ssjg
168281760Ssjg# above line is entirely empty, and this is a comment
169281760SsjgVAR1BSNL0= first line\
170281760Ssjgno space on second line
171281760SsjgVAR1BSNLs= first line\
172281760Ssjg one space on second line
173281760SsjgVAR1BSNLss= first line\
174281760Ssjg  two spaces on second line
175281760SsjgVAR1BSNLt= first line\
176281760Ssjg	one tab on second line
177281760SsjgVAR1BSNLtt= first line\
178281760Ssjg		two tabs on second line
179281760SsjgVAR1BSNLxx= first line\
180281760Ssjg  	 	 	 many spaces and tabs [  	 ] on second line
181281760Ssjg
182281760Ssjgall: var-1bsnl-space
183281760Ssjgvar-1bsnl-space: .PHONY __printvars \
184281760Ssjg	VAR1BSNL00 VAR1BSNL0 VAR1BSNLs VAR1BSNLss VAR1BSNLt VAR1BSNLtt \
185281760Ssjg	VAR1BSNLxx
186281760Ssjg
187281760Ssjg# Backslash-newline in a command is retained.
188281760Ssjg#
189281760Ssjg# The "#" in "# second line without space" makes it a comment instead
190281760Ssjg# of a syntax error if the preceding line is parsed incorretly.
191281760Ssjg# The ":" in "third line':" makes it look like the start of a
192281760Ssjg# target instead of a syntax error if the first line is parsed incorrectly.
193281760Ssjg#
194281760Ssjgall: cmd-1bsnl
195281760Ssjgcmd-1bsnl: .PHONY
196281760Ssjg	@echo ${.TARGET}
197281760Ssjg	echo :'first line\
198281760Ssjg#second line without space\
199281760Ssjgthird line':
200281760Ssjg	echo :'first line\
201281760Ssjg     second line spaces should be retained':
202281760Ssjg	echo :'first line\
203281760Ssjg	second line tab should be elided':
204281760Ssjg	echo :'first line\
205281760Ssjg		only one tab should be elided, second tab remains'
206281760Ssjg
207281760Ssjg# When backslash-newline appears at the end of a command script,
208281760Ssjg# both the backslash and the newline should be passed to the shell.
209281760Ssjg# The shell should elide the backslash-newline.
210281760Ssjg#
211281760Ssjgall: cmd-1bsnl-eof
212281760Ssjgcmd-1bsnl-eof:
213281760Ssjg	@echo ${.TARGET}
214281760Ssjg	echo :'command ending with backslash-newline'; \
215281760Ssjg
216281760Ssjg# above line must be blank
217281760Ssjg
218281760Ssjg# Double-backslash-newline in a command.
219281760Ssjg# Both backslashes are retained, but the newline is not escaped.
220281760Ssjg# XXX: This may differ from POSIX, but matches gmake.
221281760Ssjg#
222281760Ssjg# When make passes two backslashes to the shell, the shell will pass one
223281760Ssjg# backslash to the echo commant.
224281760Ssjg#
225281760Ssjgall: cmd-2bsnl
226281760Ssjgcmd-2bsnl: .PHONY
227281760Ssjg	@echo ${.TARGET}
228281760Ssjg	echo take one\\
229281760Ssjg# this should be a comment
230281760Ssjg	echo take two\\
231281760Ssjg	echo take three\\
232281760Ssjg
233281760Ssjg# Triple-backslash-newline in a command is retained.
234281760Ssjg#
235281760Ssjgall: cmd-3bsnl
236281760Ssjgcmd-3bsnl: .PHONY
237281760Ssjg	@echo ${.TARGET}
238281760Ssjg	echo :'first line\\\
239281760Ssjg#second line without space\\\
240281760Ssjgthird line':
241281760Ssjg	echo :'first line\\\
242281760Ssjg     second line spaces should be retained':
243281760Ssjg	echo :'first line\\\
244281760Ssjg	second line tab should be elided':
245281760Ssjg	echo :'first line\\\
246281760Ssjg		only one tab should be elided, second tab remains'
247