Sat May 16 19:02:32 2020 UTC ()
mk/subst.mk: change default value for SUBST_NOOP_OK from yes to no

This makes the SUBST blocks stricter than before, to detect outdated or
unnecessary definitions.

Filename patterns that are not affected by any of the SUBST_SED
expressions make the build fail.  It is still ok if only some of the
files from a pattern are affected and some aren't.

The latest bulk build shows that most of the build failures are fixed.
The packages that fail in that build are mostly due to other failures,
like missing C headers, wrong PLIST files, unresolved references at link
time.  There may be a few packages that still fail because of this, but
these are near the leaves of the dependency tree.

https://mail-index.netbsd.org/pkgsrc-bulk/2020/05/14/msg018919.html


(rillig)
diff -r1.92 -r1.93 pkgsrc/mk/subst.mk
diff -r1.41 -r1.42 pkgsrc/regress/infra-unittests/subst.sh

cvs diff -r1.92 -r1.93 pkgsrc/mk/subst.mk (switch to unified diff)

--- pkgsrc/mk/subst.mk 2020/05/02 05:52:09 1.92
+++ pkgsrc/mk/subst.mk 2020/05/16 19:02:32 1.93
@@ -1,233 +1,236 @@ @@ -1,233 +1,236 @@
1# $NetBSD: subst.mk,v 1.92 2020/05/02 05:52:09 rillig Exp $ 1# $NetBSD: subst.mk,v 1.93 2020/05/16 19:02:32 rillig Exp $
2# 2#
3# The subst framework replaces text in one or more files in the WRKSRC 3# The subst framework replaces text in one or more files in the WRKSRC
4# directory. Packages can define several ``classes'' of replacements. 4# directory. Packages can define several ``classes'' of replacements.
5# Each such class defines: 5# Each such class defines:
6# 6#
7# - in which stage of the build process the replacement happens 7# - in which stage of the build process the replacement happens
8# - which files are affected by the replacement 8# - which files are affected by the replacement
9# - which text or pattern is replaced by which replacement text 9# - which text or pattern is replaced by which replacement text
10# 10#
11# A typical example is: 11# A typical example is:
12# 12#
13# SUBST_CLASSES+= prefix 13# SUBST_CLASSES+= prefix
14# SUBST_STAGE.prefix= pre-configure 14# SUBST_STAGE.prefix= pre-configure
15# SUBST_FILES.prefix= ./configure doc/*.html 15# SUBST_FILES.prefix= ./configure doc/*.html
16# SUBST_SED.prefix= -e 's,/usr/local,${PREFIX},g' 16# SUBST_SED.prefix= -e 's,/usr/local,${PREFIX},g'
17# 17#
18# User-settable variables: 18# User-settable variables:
19# 19#
20# SUBST_SHOW_DIFF 20# SUBST_SHOW_DIFF
21# Whether to log each changed file as a unified diff, for all 21# Whether to log each changed file as a unified diff, for all
22# SUBST classes. Defaults to "no". 22# SUBST classes. Defaults to "no".
23# 23#
24# SUBST_NOOP_OK 24# SUBST_NOOP_OK
25# Whether it is ok to list files in SUBST_FILES that don't contain 25# Whether it is ok to have patterns in SUBST_FILES that don't
26# any of the patterns from SUBST_SED or SUBST_VARS. Such a 26# contain any of the patterns from SUBST_SED or SUBST_VARS and
27# situation often arises when a package is updated to a newer 27# thus are not modified at all.
28# version, and the build instructions of the package have been 28#
29# made more portable or flexible. 29# This setting only detects redundant filename patterns. It does
30# 30# not detect redundant patterns in SUBST_SED.
31# This setting only affects the filename patterns in SUBST_FILES. 31#
32# It does not (yet) affect the regular expressions in SUBST_SED. 32# Identity substitutions like s|man|man| do not count as no-ops
33# 33# since their replacement part usually comes from a variable, such
34# From the viewpoint of sed(1), a pattern like s|man|man| may look 34# as PKGMANDIR.
35# redundant but it really isn't, because the second "man" probably 
36# comes from ${PKGMANDIR}, which may be configured to a different 
37# directory. Patterns like these are therefore allowed, even if 
38# they are no-ops in the current configuration. 
39# 35#
40# For backwards compatibility this defaults to "yes", but it 36# Defaults to no. Will be removed after 2020Q3.
41# should rather be set to "no". 
42# 37#
43# Package-settable variables: 38# Package-settable variables:
44# 39#
45# SUBST_CLASSES 40# SUBST_CLASSES
46# A list of class names. When adding new classes to this list, be 41# A list of class names. When adding new classes to this list, be
47# sure to append them (+=) instead of overriding them (=). 42# sure to append them (+=) instead of overriding them (=).
48# 43#
49# SUBST_STAGE.<class> 44# SUBST_STAGE.<class>
50# "stage" at which we do the text replacement. Should be one of 45# "stage" at which we do the text replacement. Should be one of
51# {pre,do,post}-{extract,configure,build,install}. 46# {pre,do,post}-{extract,configure,build,install}.
52# 47#
53# SUBST_MESSAGE.<class> 48# SUBST_MESSAGE.<class>
54# The message to display before doing the substitution. 49# The message to display before doing the substitution.
55# 50#
56# SUBST_FILES.<class> 51# SUBST_FILES.<class>
57# A list of file patterns on which to run the substitution; 52# A list of file patterns on which to run the substitution;
58# the filenames are either absolute or relative to ${WRKSRC}. 53# the filenames are either absolute or relative to ${WRKSRC}.
59# 54#
60# Starting with 2020Q1, it is an error if any of these patterns 55# Starting with 2020Q1, it is an error if any of these patterns
61# has no effect at all, to catch typos and outdated definitions. 56# has no effect at all, to catch typos and outdated definitions.
62# To prevent this, see SUBST_NOOP_OK.<class> below. 57# To prevent this, see SUBST_NOOP_OK.<class> below.
63# 58#
64# In most cases the filename patterns are given directly. 59# In most cases the filename patterns are given directly.
65# If that is not flexible enough, use the :sh variable modifier. 60# If that is not flexible enough, use the :sh variable modifier.
66# See mk/configure/replace-localedir.mk for an example. 61# See mk/configure/replace-localedir.mk for an example.
67# 62#
68# SUBST_SED.<class> 63# SUBST_SED.<class>
69# List of sed(1) arguments to run on the specified files. 64# List of sed(1) arguments to run on the specified files.
70# Multiple commands can be specified using the -e option of sed. 65# Multiple commands can be specified using the -e option of sed.
71# Do not use non-standard sed options (e.g. -E). 66# Do not use non-standard sed options (e.g. -E).
72# 67#
73# SUBST_VARS.<class> 68# SUBST_VARS.<class>
74# List of variables that are substituted whenever they appear in 69# List of variables that are substituted whenever they appear in
75# the form @VARNAME@. This is basically a shortcut for 70# the form @VARNAME@. This is basically a shortcut for
76# 71#
77# -e 's,@VARNAME@,${VARNAME},g' 72# -e 's,@VARNAME@,${VARNAME},g'
78# 73#
79# that even works when ${VARNAME} contains arbitrary characters. 74# that even works when ${VARNAME} contains arbitrary characters.
80# SUBST_SED and SUBST_VARS can be combined freely. 75# SUBST_SED and SUBST_VARS can be combined freely.
81# 76#
82# SUBST_FILTER_CMD.<class> 77# SUBST_FILTER_CMD.<class>
83# Filter used to perform the actual substitution on the specified 78# Filter used to perform the actual substitution on the specified
84# files. Defaults to ${SED} ${SUBST_SED.<class>}. 79# files. Defaults to ${SED} ${SUBST_SED.<class>}.
85# 80#
86# SUBST_SKIP_TEXT_CHECK.<class> 81# SUBST_SKIP_TEXT_CHECK.<class>
87# By default, each file is checked whether it really is a text file 82# By default, each file is checked whether it really is a text file
88# before any substitutions are done to it. Since that test is not 83# before any substitutions are done to it. Since that test is not
89# perfect, it can be disabled by setting this variable to "yes". 84# perfect, it can be disabled by setting this variable to "yes".
90# 85#
91# SUBST_SHOW_DIFF.<class> 86# SUBST_SHOW_DIFF.<class>
92# During development of a package, this can be set to "yes" to see 87# During development of a package, this can be set to "yes" to see
93# the actual changes as a unified diff. 88# the actual changes as a unified diff.
94# 89#
95# SUBST_NOOP_OK.<class> 90# SUBST_NOOP_OK.<class>
96# Whether to fail when a SUBST_FILES pattern has no effect. 91# Whether to allow filename patterns in SUBST_FILES that don't
97# In most cases, "yes" is appropriate, to catch typos and outdated 92# contain any of the patterns from SUBST_SED.
98# definitions. 
99# 93#
100# Default: no (up to 2019Q4), yes (starting with 2020Q1) 94# Defaults to no, since May 2020.
 95#
 96# Typical reasons to change this to yes are:
 97#
 98# 1. SUBST_FILES is generated dynamically and may include
 99# unaffected files.
 100#
 101# 2. There are multiple SUBST_SED patterns, and some of these
 102# do not count as identity substitution since they contain
 103# ".*" or similar parts.
101# 104#
102# See also: 105# See also:
103# PLIST_SUBST 106# PLIST_SUBST
104# 107#
105# Keywords: subst 108# Keywords: subst
106# 109#
107 110
108SUBST_SHOW_DIFF?= no 111SUBST_SHOW_DIFF?= no
109SUBST_NOOP_OK?= yes # only for backwards compatibility 112SUBST_NOOP_OK?= no # since May 2020
110 113
111_VARGROUPS+= subst 114_VARGROUPS+= subst
112_USER_VARS.subst= SUBST_SHOW_DIFF SUBST_NOOP_OK 115_USER_VARS.subst= SUBST_SHOW_DIFF SUBST_NOOP_OK
113_PKG_VARS.subst= SUBST_CLASSES 116_PKG_VARS.subst= SUBST_CLASSES
114.for c in ${SUBST_CLASSES} 117.for c in ${SUBST_CLASSES}
115. for pv in SUBST_STAGE SUBST_MESSAGE SUBST_FILES SUBST_SED SUBST_VARS \ 118. for pv in SUBST_STAGE SUBST_MESSAGE SUBST_FILES SUBST_SED SUBST_VARS \
116 SUBST_FILTER_CMD SUBST_SKIP_TEXT_CHECK SUBST_NOOP_OK 119 SUBST_FILTER_CMD SUBST_SKIP_TEXT_CHECK SUBST_NOOP_OK
117_PKG_VARS.subst+= ${pv}.${c} 120_PKG_VARS.subst+= ${pv}.${c}
118. endfor 121. endfor
119.endfor 122.endfor
120_DEF_VARS.subst= ECHO_SUBST_MSG 123_DEF_VARS.subst= ECHO_SUBST_MSG
121_USE_VARS.subst= WRKDIR WRKSRC 124_USE_VARS.subst= WRKDIR WRKSRC
122_IGN_VARS.subst= _SUBST_IS_TEXT_FILE_CMD 125_IGN_VARS.subst= _SUBST_IS_TEXT_FILE_CMD
123_SORTED_VARS.subst= SUBST_CLASSES SUBST_FILES.* SUBST_VARS.* 126_SORTED_VARS.subst= SUBST_CLASSES SUBST_FILES.* SUBST_VARS.*
124_LISTED_VARS.subst= SUBST_SED.* SUBST_FILTER_CMD.* 127_LISTED_VARS.subst= SUBST_SED.* SUBST_FILTER_CMD.*
125 128
126ECHO_SUBST_MSG?= ${STEP_MSG} 129ECHO_SUBST_MSG?= ${STEP_MSG}
127 130
128# _SUBST_IS_TEXT_FILE_CMD exits successfully if $$file is a text file. 131# _SUBST_IS_TEXT_FILE_CMD exits successfully if $$file is a text file.
129_SUBST_IS_TEXT_FILE_CMD= \ 132_SUBST_IS_TEXT_FILE_CMD= \
130 [ -z "`LC_ALL=C ${TR} -cd '\\0' < \"$$file\" | ${TR} '\\0' 'x'`" ] 133 [ -z "`LC_ALL=C ${TR} -cd '\\0' < \"$$file\" | ${TR} '\\0' 'x'`" ]
131 134
132.if ${SUBST_CLASSES:U:O} != ${SUBST_CLASSES:U:O:u} 135.if ${SUBST_CLASSES:U:O} != ${SUBST_CLASSES:U:O:u}
133PKG_FAIL_REASON+= "[subst.mk] duplicate SUBST class in: ${SUBST_CLASSES:O}" 136PKG_FAIL_REASON+= "[subst.mk] duplicate SUBST class in: ${SUBST_CLASSES:O}"
134.endif 137.endif
135 138
136.for class in ${SUBST_CLASSES:O:u} 139.for class in ${SUBST_CLASSES:O:u}
137_SUBST_COOKIE.${class}= ${WRKDIR}/.subst_${class}_done 140_SUBST_COOKIE.${class}= ${WRKDIR}/.subst_${class}_done
138 141
139.if defined(SUBST_FILTER_CMD.${class}) && (defined(SUBST_SED.${class}) || defined(SUBST_VARS.${class})) 142.if defined(SUBST_FILTER_CMD.${class}) && (defined(SUBST_SED.${class}) || defined(SUBST_VARS.${class}))
140PKG_FAIL_REASON+= "[subst.mk:${class}] SUBST_FILTER_CMD and SUBST_SED/SUBST_VARS cannot be combined." 143PKG_FAIL_REASON+= "[subst.mk:${class}] SUBST_FILTER_CMD and SUBST_SED/SUBST_VARS cannot be combined."
141.endif 144.endif
142 145
143SUBST_FILTER_CMD.${class}?= LC_ALL=C ${SED} ${SUBST_SED.${class}} 146SUBST_FILTER_CMD.${class}?= LC_ALL=C ${SED} ${SUBST_SED.${class}}
144SUBST_VARS.${class}?= # none 147SUBST_VARS.${class}?= # none
145SUBST_MESSAGE.${class}?= Substituting "${class}" in ${SUBST_FILES.${class}} 148SUBST_MESSAGE.${class}?= Substituting "${class}" in ${SUBST_FILES.${class}}
146. for v in ${SUBST_VARS.${class}} 149. for v in ${SUBST_VARS.${class}}
147SUBST_FILTER_CMD.${class}+= -e s,@${v:C|[.[\\*^]|\\\\&|gW:Q}@,${${v}:S|\\|\\\\|gW:S|,|\\,|gW:S|&|\\\&|gW:S|${.newline}|\\${.newline}|gW:Q},g 150SUBST_FILTER_CMD.${class}+= -e s,@${v:C|[.[\\*^]|\\\\&|gW:Q}@,${${v}:S|\\|\\\\|gW:S|,|\\,|gW:S|&|\\\&|gW:S|${.newline}|\\${.newline}|gW:Q},g
148. endfor 151. endfor
149. if ${SUBST_SHOW_DIFF.${class}:U${SUBST_SHOW_DIFF}:tl} == yes 152. if ${SUBST_SHOW_DIFF.${class}:U${SUBST_SHOW_DIFF}:tl} == yes
150_SUBST_KEEP.${class}?= LC_ALL=C ${DIFF} -u "$$file" "$$tmpfile" || true 153_SUBST_KEEP.${class}?= LC_ALL=C ${DIFF} -u "$$file" "$$tmpfile" || true
151. endif 154. endif
152_SUBST_KEEP.${class}?= ${DO_NADA} 155_SUBST_KEEP.${class}?= ${DO_NADA}
153SUBST_SKIP_TEXT_CHECK.${class}?= \ 156SUBST_SKIP_TEXT_CHECK.${class}?= \
154 no 157 no
155SUBST_NOOP_OK.${class}?= ${SUBST_NOOP_OK} 158SUBST_NOOP_OK.${class}?= ${SUBST_NOOP_OK}
156_SUBST_WARN.${class}= ${${SUBST_NOOP_OK.${class}:tl} == yes:?${INFO_MSG}:${WARNING_MSG}} "[subst.mk:${class}]" 159_SUBST_WARN.${class}= ${${SUBST_NOOP_OK.${class}:tl} == yes:?${INFO_MSG}:${WARNING_MSG}} "[subst.mk:${class}]"
157 160
158. if !empty(SUBST_SKIP_TEXT_CHECK.${class}:M[Yy][Ee][Ss]) 161. if !empty(SUBST_SKIP_TEXT_CHECK.${class}:M[Yy][Ee][Ss])
159_SUBST_IS_TEXT_FILE_CMD.${class}= ${TRUE} 162_SUBST_IS_TEXT_FILE_CMD.${class}= ${TRUE}
160. else 163. else
161_SUBST_IS_TEXT_FILE_CMD.${class}= ${_SUBST_IS_TEXT_FILE_CMD} 164_SUBST_IS_TEXT_FILE_CMD.${class}= ${_SUBST_IS_TEXT_FILE_CMD}
162. endif 165. endif
163 166
164. if defined(SUBST_STAGE.${class}) 167. if defined(SUBST_STAGE.${class})
165${SUBST_STAGE.${class}}: subst-${class} 168${SUBST_STAGE.${class}}: subst-${class}
166. else 169. else
167# SUBST_STAGE.* does not need to be defined. 170# SUBST_STAGE.* does not need to be defined.
168#PKG_FAIL_REASON+= "SUBST_STAGE missing for ${class}." 171#PKG_FAIL_REASON+= "SUBST_STAGE missing for ${class}."
169. endif 172. endif
170 173
171.PHONY: subst-${class} 174.PHONY: subst-${class}
172subst-${class}: ${_SUBST_COOKIE.${class}} 175subst-${class}: ${_SUBST_COOKIE.${class}}
173 176
174${_SUBST_COOKIE.${class}}: 177${_SUBST_COOKIE.${class}}:
175 ${RUN} set -u; \ 178 ${RUN} set -u; \
176 message=${SUBST_MESSAGE.${class}:Q}; \ 179 message=${SUBST_MESSAGE.${class}:Q}; \
177 [ "$$message" ] && ${ECHO_SUBST_MSG} "$$message"; \ 180 [ "$$message" ] && ${ECHO_SUBST_MSG} "$$message"; \
178 \ 181 \
179 cd ${WRKSRC}; \ 182 cd ${WRKSRC}; \
180 patterns=${SUBST_FILES.${class}:Q}; \ 183 patterns=${SUBST_FILES.${class}:Q}; \
181 set -f; \ 184 set -f; \
182 noop_count=''; \ 185 noop_count=''; \
183 noop_patterns=''; \ 186 noop_patterns=''; \
184 noop_sep=''; \ 187 noop_sep=''; \
185 for pattern in $$patterns; do \ 188 for pattern in $$patterns; do \
186 set +f; \ 189 set +f; \
187 changed=no; \ 190 changed=no; \
188 for file in $$pattern; do \ 191 for file in $$pattern; do \
189 case $$file in ([!A-Za-z0-9/]*) file="./$$file";; esac; \ 192 case $$file in ([!A-Za-z0-9/]*) file="./$$file";; esac; \
190 tmpfile="$$file.subst.sav"; \ 193 tmpfile="$$file.subst.sav"; \
191 [ -d "$$file" ] && continue; \ 194 [ -d "$$file" ] && continue; \
192 [ -f "$$file" ] || { \ 195 [ -f "$$file" ] || { \
193 ${_SUBST_WARN.${class}} "Ignoring nonexistent file \"$$file\"."; \ 196 ${_SUBST_WARN.${class}} "Ignoring nonexistent file \"$$file\"."; \
194 continue; \ 197 continue; \
195 }; \ 198 }; \
196 ${_SUBST_IS_TEXT_FILE_CMD.${class}} || { \ 199 ${_SUBST_IS_TEXT_FILE_CMD.${class}} || { \
197 ${_SUBST_WARN.${class}} "Ignoring non-text file \"$$file\"."; \ 200 ${_SUBST_WARN.${class}} "Ignoring non-text file \"$$file\"."; \
198 continue; \ 201 continue; \
199 }; \ 202 }; \
200 ${SUBST_FILTER_CMD.${class}} < "$$file" > "$$tmpfile"; \ 203 ${SUBST_FILTER_CMD.${class}} < "$$file" > "$$tmpfile"; \
201 ${CMP} -s "$$tmpfile" "$$file" && { \ 204 ${CMP} -s "$$tmpfile" "$$file" && { \
202 ${AWK} -f ${PKGSRCDIR}/mk/scripts/subst-identity.awk -- ${SUBST_SED.${class}} \ 205 ${AWK} -f ${PKGSRCDIR}/mk/scripts/subst-identity.awk -- ${SUBST_SED.${class}} \
203 && found=$$(LC_ALL=C ${SED} -n ${SUBST_SED.${class}:C,^['"]?s.*,&p,} "$$file") \ 206 && found=$$(LC_ALL=C ${SED} -n ${SUBST_SED.${class}:C,^['"]?s.*,&p,} "$$file") \
204 && [ -n "$$found" ] && { \ 207 && [ -n "$$found" ] && { \
205 changed=yes; \ 208 changed=yes; \
206 continue; \ 209 continue; \
207 }; \ 210 }; \
208 ${_SUBST_WARN.${class}} "Nothing changed in \"$$file\"."; \ 211 ${_SUBST_WARN.${class}} "Nothing changed in \"$$file\"."; \
209 ${RM} -f "$$tmpfile"; \ 212 ${RM} -f "$$tmpfile"; \
210 continue; \ 213 continue; \
211 }; \ 214 }; \
212 [ -x "$$file" ] && ${CHMOD} +x "$$tmpfile"; \ 215 [ -x "$$file" ] && ${CHMOD} +x "$$tmpfile"; \
213 changed=yes; \ 216 changed=yes; \
214 ${_SUBST_KEEP.${class}}; \ 217 ${_SUBST_KEEP.${class}}; \
215 ${MV} -f "$$tmpfile" "$$file"; \ 218 ${MV} -f "$$tmpfile" "$$file"; \
216 ${ECHO} "$$file" >> ${.TARGET}.tmp; \ 219 ${ECHO} "$$file" >> ${.TARGET}.tmp; \
217 done; \ 220 done; \
218 \ 221 \
219 [ "$$changed,${SUBST_NOOP_OK.${class}:tl}" = no,no ] && { \ 222 [ "$$changed,${SUBST_NOOP_OK.${class}:tl}" = no,no ] && { \
220 noop_count="$$noop_count+"; \ 223 noop_count="$$noop_count+"; \
221 noop_patterns="$$noop_patterns$$noop_sep$$pattern"; \ 224 noop_patterns="$$noop_patterns$$noop_sep$$pattern"; \
222 noop_sep=" "; \ 225 noop_sep=" "; \
223 }; \ 226 }; \
224 done; \ 227 done; \
225 \ 228 \
226 case $$noop_count in \ 229 case $$noop_count in \
227 ('') ;; \ 230 ('') ;; \
228 (+) ${FAIL_MSG} "[subst.mk:${class}] The filename pattern \"$$noop_patterns\" has no effect.";; \ 231 (+) ${FAIL_MSG} "[subst.mk:${class}] The filename pattern \"$$noop_patterns\" has no effect.";; \
229 (*) ${FAIL_MSG} "[subst.mk:${class}] The filename patterns \"$$noop_patterns\" have no effect.";; \ 232 (*) ${FAIL_MSG} "[subst.mk:${class}] The filename patterns \"$$noop_patterns\" have no effect.";; \
230 esac; \ 233 esac; \
231 ${TOUCH} ${TOUCH_FLAGS} ${.TARGET}.tmp; \ 234 ${TOUCH} ${TOUCH_FLAGS} ${.TARGET}.tmp; \
232 ${MV} ${.TARGET}.tmp ${.TARGET} 235 ${MV} ${.TARGET}.tmp ${.TARGET}
233.endfor 236.endfor

cvs diff -r1.41 -r1.42 pkgsrc/regress/infra-unittests/subst.sh (switch to unified diff)

--- pkgsrc/regress/infra-unittests/subst.sh 2020/05/16 12:43:10 1.41
+++ pkgsrc/regress/infra-unittests/subst.sh 2020/05/16 19:02:32 1.42
@@ -1,1491 +1,1636 @@ @@ -1,1491 +1,1636 @@
1#! /bin/sh 1#! /bin/sh
2# $NetBSD: subst.sh,v 1.41 2020/05/16 12:43:10 rillig Exp $ 2# $NetBSD: subst.sh,v 1.42 2020/05/16 19:02:32 rillig Exp $
3# 3#
4# Tests for mk/subst.mk. 4# Tests for mk/subst.mk.
5# 5#
6 6
7set -eu 7set -eu
8 8
9. './test.subr' 9. './test.subr'
10 10
11test_case_set_up() { 11test_case_set_up() {
12 wrkdir="$tmpdir/wrkdir" 12 wrkdir="$tmpdir/wrkdir"
13 mkdir "$wrkdir" 13 mkdir "$wrkdir"
14 14
15 create_file 'prepare-subst.mk' <<-EOF 15 create_file 'prepare-subst.mk' <<-EOF
16 # The tools that are used by subst.mk 16 # The tools that are used by subst.mk
17 AWK= awk 17 AWK= awk
18 CHMOD= chmod 18 CHMOD= chmod
19 CMP= cmp 19 CMP= cmp
20 DIFF= diff 20 DIFF= diff
21 ECHO= echo 21 ECHO= echo
22 MKDIR= mkdir -p 22 MKDIR= mkdir -p
23 MV= mv 23 MV= mv
24 RM= rm 24 RM= rm
25 RMDIR= rmdir 25 RMDIR= rmdir
26 SED= sed 26 SED= sed
27 TEST= test 27 TEST= test
28 TOUCH= touch 28 TOUCH= touch
29 TOUCH_FLAGS= # none 29 TOUCH_FLAGS= # none
30 TR= tr 30 TR= tr
31 TRUE= true 31 TRUE= true
32 32
33 # Commands that are specific to pkgsrc 33 # Commands that are specific to pkgsrc
34 RUN= @set -e; 34 RUN= @set -e;
35 STEP_MSG= echo '=>' 35 STEP_MSG= echo '=>'
36 DO_NADA= : do-nada 36 DO_NADA= : do-nada
37 INFO_MSG= echo 'info:' 37 INFO_MSG= echo 'info:'
38 WARNING_MSG= echo 'warning:' 38 WARNING_MSG= echo 'warning:'
39 FAIL_MSG= sh $pkgsrcdir/mk/scripts/fail echo 'fail:' 1>&2 39 FAIL_MSG= sh $pkgsrcdir/mk/scripts/fail echo 'fail:' 1>&2
40 40
41 WRKDIR= $tmpdir/wrkdir 41 WRKDIR= $tmpdir/wrkdir
42 WRKSRC= . 42 WRKSRC= .
43 EOF 43 EOF
44} 44}
45 45
46test_case_tear_down() { 46test_case_tear_down() {
47 # Clean up the .subst_*_done cookie files. 47 # Clean up the .subst_*_done cookie files.
48 rm -r "$wrkdir" 48 rm -r "$wrkdir"
49} 49}
50 50
51 51
52if test_case_begin 'single file'; then 52if test_case_begin 'single file'; then
53 53
54 # A single file is patched successfully. 54 # A single file is patched successfully.
55 55
56 create_file 'testcase.mk' <<-EOF 56 create_file 'testcase.mk' <<-EOF
57 SUBST_CLASSES+= class 57 SUBST_CLASSES+= class
58 SUBST_STAGE.class= pre-configure 58 SUBST_STAGE.class= pre-configure
59 SUBST_FILES.class= subst-single.txt 59 SUBST_FILES.class= subst-single.txt
60 SUBST_SED.class= -e 's,before,after,' 60 SUBST_SED.class= -e 's,before,after,'
61 61
62 .include "prepare-subst.mk" 62 .include "prepare-subst.mk"
63 .include "mk/subst.mk" 63 .include "mk/subst.mk"
64 EOF 64 EOF
65 65
66 create_file_lines 'subst-single.txt' \ 66 create_file_lines 'subst-single.txt' \
67 'before' 67 'before'
68 68
69 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 69 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
70 && exitcode=0 || exitcode=$? 70 && exitcode=0 || exitcode=$?
71 71
72 assert_that "$tmpdir/output" --file-is-lines \ 72 assert_that "$tmpdir/output" --file-is-lines \
73 '=> Substituting "class" in subst-single.txt' 73 '=> Substituting "class" in subst-single.txt'
74 assert_that 'subst-single.txt' --file-is-lines \ 74 assert_that 'subst-single.txt' --file-is-lines \
75 'after' 75 'after'
76 76
77 test_case_end 77 test_case_end
78fi 78fi
79 79
80 80
81if test_case_begin 'several individual files'; then 81if test_case_begin 'several individual files'; then
82 82
83 # Several individual files are patched successfully. 83 # Several individual files are patched successfully.
84 84
85 create_file 'testcase.mk' <<-EOF 85 create_file 'testcase.mk' <<-EOF
86 SUBST_CLASSES+= class 86 SUBST_CLASSES+= class
87 SUBST_STAGE.class= pre-configure 87 SUBST_STAGE.class= pre-configure
88 SUBST_FILES.class= first second third 88 SUBST_FILES.class= first second third
89 SUBST_SED.class= -e 's,file,example,' 89 SUBST_SED.class= -e 's,file,example,'
90 90
91 .include "prepare-subst.mk" 91 .include "prepare-subst.mk"
92 .include "mk/subst.mk" 92 .include "mk/subst.mk"
93 EOF 93 EOF
94 94
95 create_file_lines 'first' 'the first file' 95 create_file_lines 'first' 'the first file'
96 create_file_lines 'second' 'the second file' 96 create_file_lines 'second' 'the second file'
97 create_file_lines 'third' 'the third file' 97 create_file_lines 'third' 'the third file'
98 98
99 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 99 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
100 && exitcode=0 || exitcode=$? 100 && exitcode=0 || exitcode=$?
101 101
102 assert_that "$tmpdir/output" --file-is-lines \ 102 assert_that "$tmpdir/output" --file-is-lines \
103 '=> Substituting "class" in first second third' 103 '=> Substituting "class" in first second third'
104 assert_that 'first' --file-is-lines 'the first example' 104 assert_that 'first' --file-is-lines 'the first example'
105 assert_that 'second' --file-is-lines 'the second example' 105 assert_that 'second' --file-is-lines 'the second example'
106 assert_that 'third' --file-is-lines 'the third example' 106 assert_that 'third' --file-is-lines 'the third example'
107 107
108 test_case_end 108 test_case_end
109fi 109fi
110 110
111 111
112if test_case_begin 'several files by pattern'; then 112if test_case_begin 'several files by pattern'; then
113 113
114 # Several files are patched successfully. 114 # Several files are patched successfully.
115 # The filenames are given by a pattern. 115 # The filenames are given by a pattern.
116 116
117 create_file 'testcase.mk' <<-EOF 117 create_file 'testcase.mk' <<-EOF
118 SUBST_CLASSES+= class 118 SUBST_CLASSES+= class
119 SUBST_STAGE.class= pre-configure 119 SUBST_STAGE.class= pre-configure
120 SUBST_FILES.class= pattern-* 120 SUBST_FILES.class= pattern-*
121 SUBST_SED.class= -e 's,file,example,' 121 SUBST_SED.class= -e 's,file,example,'
122 122
123 .include "prepare-subst.mk" 123 .include "prepare-subst.mk"
124 .include "mk/subst.mk" 124 .include "mk/subst.mk"
125 EOF 125 EOF
126 126
127 create_file_lines 'pattern-first' 'the first file' 127 create_file_lines 'pattern-first' 'the first file'
128 create_file_lines 'pattern-second' 'the second file' 128 create_file_lines 'pattern-second' 'the second file'
129 create_file_lines 'pattern-third' 'the third file' 129 create_file_lines 'pattern-third' 'the third file'
130 130
131 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 131 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
132 && exitcode=0 || exitcode=$? 132 && exitcode=0 || exitcode=$?
133 133
134 assert_that "$tmpdir/output" --file-is-lines \ 134 assert_that "$tmpdir/output" --file-is-lines \
135 '=> Substituting "class" in pattern-*' 135 '=> Substituting "class" in pattern-*'
136 assert_that 'pattern-first' --file-is-lines 'the first example' 136 assert_that 'pattern-first' --file-is-lines 'the first example'
137 assert_that 'pattern-second' --file-is-lines 'the second example' 137 assert_that 'pattern-second' --file-is-lines 'the second example'
138 assert_that 'pattern-third' --file-is-lines 'the third example' 138 assert_that 'pattern-third' --file-is-lines 'the third example'
139 139
140 test_case_end 140 test_case_end
141fi 141fi
142 142
143 143
144if test_case_begin 'pattern with 1 noop'; then 144if test_case_begin 'pattern with 1 noop, no-op ok'; then
145 145
146 # Several files are given via a pattern. 146 # Several files are given via a pattern.
147 # Most of the files are patched, but one stays the same. 147 # Most of the files are patched, but one stays the same.
148 # Since it is easier to give a too broad pattern like *.py 148 # Since it is easier to give a too broad pattern like *.py
149 # than to exclude a few files from such a pattern, 149 # than to exclude a few files from such a pattern,
150 # only an info is logged. 150 # only an info is logged.
151 # This is not an error. 151 # This is not an error.
152 152
153 create_file 'testcase.mk' <<-EOF 153 create_file 'testcase.mk' <<-EOF
154 SUBST_CLASSES+= class 154 SUBST_CLASSES+= class
155 SUBST_STAGE.class= pre-configure 155 SUBST_STAGE.class= pre-configure
156 SUBST_FILES.class= pattern-* 156 SUBST_FILES.class= pattern-*
157 SUBST_SED.class= -e 's,file,example,' 157 SUBST_SED.class= -e 's,file,example,'
 158 SUBST_NOOP_OK.class= yes
158 159
159 .include "prepare-subst.mk" 160 .include "prepare-subst.mk"
160 .include "mk/subst.mk" 161 .include "mk/subst.mk"
161 162
162 all: subst-class 163 all: subst-class
163 EOF 164 EOF
164 165
165 create_file_lines 'pattern-first' 'the first file' 166 create_file_lines 'pattern-first' 'the first file'
166 create_file_lines 'pattern-second' 'the second is already an example' 167 create_file_lines 'pattern-second' 'the second is already an example'
167 create_file_lines 'pattern-third' 'the third file' 168 create_file_lines 'pattern-third' 'the third file'
168 169
169 run_bmake 'testcase.mk' 1> "$tmpdir/output" \ 170 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
170 && exitcode=0 || exitcode=$? 171 && exitcode=0 || exitcode=$?
171 172
172 assert_that "$tmpdir/output" --file-is-lines \ 173 assert_that "$tmpdir/output" --file-is-lines \
173 '=> Substituting "class" in pattern-*' \ 174 '=> Substituting "class" in pattern-*' \
174 'info: [subst.mk:class] Nothing changed in "pattern-second".' 175 'info: [subst.mk:class] Nothing changed in "pattern-second".'
175 assert_that 'pattern-first' --file-is-lines 'the first example' 176 assert_that 'pattern-first' --file-is-lines 'the first example'
176 assert_that 'pattern-second' --file-is-lines 'the second is already an example' 177 assert_that 'pattern-second' --file-is-lines 'the second is already an example'
177 assert_that 'pattern-third' --file-is-lines 'the third example' 178 assert_that 'pattern-third' --file-is-lines 'the third example'
178 179
179 test_case_end 180 test_case_end
180fi 181fi
181 182
182 183
 184if test_case_begin 'pattern with 1 noop, no-op not ok'; then
 185
 186 # Several files are given via a pattern.
 187 # Most of the files are patched, but one stays the same.
 188 # Since it is easier to give a too broad pattern like *.py
 189 # than to exclude a few files from such a pattern,
 190 # only a warning is logged.
 191 # This is not an error.
 192
 193 create_file 'testcase.mk' <<-EOF
 194 SUBST_CLASSES+= class
 195 SUBST_STAGE.class= pre-configure
 196 SUBST_FILES.class= pattern-*
 197 SUBST_SED.class= -e 's,file,example,'
 198 SUBST_NOOP_OK.class= no
 199
 200 .include "prepare-subst.mk"
 201 .include "mk/subst.mk"
 202
 203 all: subst-class
 204 EOF
 205
 206 create_file_lines 'pattern-first' 'the first file'
 207 create_file_lines 'pattern-second' 'the second is already an example'
 208 create_file_lines 'pattern-third' 'the third file'
 209
 210 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
 211 && exitcode=0 || exitcode=$?
 212
 213 assert_that "$tmpdir/output" --file-is-lines \
 214 '=> Substituting "class" in pattern-*' \
 215 'warning: [subst.mk:class] Nothing changed in "pattern-second".'
 216 assert_that 'pattern-first' --file-is-lines 'the first example'
 217 assert_that 'pattern-second' --file-is-lines 'the second is already an example'
 218 assert_that 'pattern-third' --file-is-lines 'the third example'
 219
 220 test_case_end
 221fi
 222
 223
183if test_case_begin 'single file noop, noop_ok=yes'; then 224if test_case_begin 'single file noop, noop_ok=yes'; then
184 225
185 create_file 'testcase.mk' <<-EOF 226 create_file 'testcase.mk' <<-EOF
186 SUBST_CLASSES+= class 227 SUBST_CLASSES+= class
187 SUBST_STAGE.class= pre-configure 228 SUBST_STAGE.class= pre-configure
188 SUBST_FILES.class= single 229 SUBST_FILES.class= single
189 SUBST_SED.class= -e 's,file,example,' 230 SUBST_SED.class= -e 's,file,example,'
190 SUBST_NOOP_OK.class= yes 231 SUBST_NOOP_OK.class= yes
191 232
192 .include "prepare-subst.mk" 233 .include "prepare-subst.mk"
193 .include "mk/subst.mk" 234 .include "mk/subst.mk"
194 EOF 235 EOF
195 236
196 create_file_lines 'single' 'already an example' 237 create_file_lines 'single' 'already an example'
197 238
198 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 239 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
199 && exitcode=0 || exitcode=$? 240 && exitcode=0 || exitcode=$?
200 241
201 assert_that "$tmpdir/output" --file-is-lines \ 242 assert_that "$tmpdir/output" --file-is-lines \
202 '=> Substituting "class" in single' \ 243 '=> Substituting "class" in single' \
203 'info: [subst.mk:class] Nothing changed in "single".' 244 'info: [subst.mk:class] Nothing changed in "single".'
204 assert_that 'single' --file-is-lines 'already an example' 245 assert_that 'single' --file-is-lines 'already an example'
205 246
206 test_case_end 247 test_case_end
207fi 248fi
208 249
209 250
210if test_case_begin 'single file noop, noop_ok=no'; then 251if test_case_begin 'single file noop, noop_ok=no'; then
211 252
212 create_file 'testcase.mk' <<-EOF 253 create_file 'testcase.mk' <<-EOF
213 SUBST_CLASSES+= class 254 SUBST_CLASSES+= class
214 SUBST_STAGE.class= pre-configure 255 SUBST_STAGE.class= pre-configure
215 SUBST_FILES.class= single 256 SUBST_FILES.class= single
216 SUBST_SED.class= -e 's,file,example,' 257 SUBST_SED.class= -e 's,file,example,'
217 SUBST_NOOP_OK.class= no 258 SUBST_NOOP_OK.class= no
218 259
219 .include "prepare-subst.mk" 260 .include "prepare-subst.mk"
220 .include "mk/subst.mk" 261 .include "mk/subst.mk"
221 EOF 262 EOF
222 263
223 create_file_lines 'single' 'already an example' 264 create_file_lines 'single' 'already an example'
224 265
225 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 266 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
226 && exitcode=0 || exitcode=$? 267 && exitcode=0 || exitcode=$?
227 268
228 assert_that "$tmpdir/output" --file-is-lines \ 269 assert_that "$tmpdir/output" --file-is-lines \
229 '=> Substituting "class" in single' \ 270 '=> Substituting "class" in single' \
230 'warning: [subst.mk:class] Nothing changed in "single".' \ 271 'warning: [subst.mk:class] Nothing changed in "single".' \
231 'fail: [subst.mk:class] The filename pattern "single" has no effect.' \ 272 'fail: [subst.mk:class] The filename pattern "single" has no effect.' \
232 '*** Error code 1' \ 273 '*** Error code 1' \
233 '' \ 274 '' \
234 'Stop.' \ 275 'Stop.' \
235 "$make: stopped in $PWD" 276 "$make: stopped in $PWD"
236 assert_that 'single' --file-is-lines 'already an example' 277 assert_that 'single' --file-is-lines 'already an example'
237 assert_that "$exitcode" --equals '1' 278 assert_that "$exitcode" --equals '1'
238 279
239 test_case_end 280 test_case_end
240fi 281fi
241 282
242 283
243if test_case_begin 'single file nonexistent'; then 284if test_case_begin 'single file nonexistent'; then
244 285
245 create_file 'testcase.mk' <<-EOF 286 create_file 'testcase.mk' <<-EOF
246 SUBST_CLASSES+= class 287 SUBST_CLASSES+= class
247 SUBST_STAGE.class= pre-configure 288 SUBST_STAGE.class= pre-configure
248 SUBST_FILES.class= nonexistent 289 SUBST_FILES.class= nonexistent
249 SUBST_SED.class= -e 's,file,example,' 290 SUBST_SED.class= -e 's,file,example,'
250 SUBST_NOOP_OK.class= no 291 SUBST_NOOP_OK.class= no
251 292
252 .include "prepare-subst.mk" 293 .include "prepare-subst.mk"
253 .include "mk/subst.mk" 294 .include "mk/subst.mk"
254 EOF 295 EOF
255 296
256 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 297 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
257 && exitcode=0 || exitcode=$? 298 && exitcode=0 || exitcode=$?
258 299
259 assert_that "$tmpdir/output" --file-is-lines \ 300 assert_that "$tmpdir/output" --file-is-lines \
260 '=> Substituting "class" in nonexistent' \ 301 '=> Substituting "class" in nonexistent' \
261 'warning: [subst.mk:class] Ignoring nonexistent file "nonexistent".' \ 302 'warning: [subst.mk:class] Ignoring nonexistent file "nonexistent".' \
262 'fail: [subst.mk:class] The filename pattern "nonexistent" has no effect.' \ 303 'fail: [subst.mk:class] The filename pattern "nonexistent" has no effect.' \
263 '*** Error code 1' \ 304 '*** Error code 1' \
264 '' \ 305 '' \
265 'Stop.' \ 306 'Stop.' \
266 "$make: stopped in $PWD" 307 "$make: stopped in $PWD"
267 assert_that "$exitcode" --equals '1' 308 assert_that "$exitcode" --equals '1'
268 309
269 test_case_end 310 test_case_end
270fi 311fi
271 312
272 313
273if test_case_begin 'single file nonexistent ok'; then 314if test_case_begin 'single file nonexistent ok'; then
274 315
275 create_file 'testcase.mk' <<-EOF 316 create_file 'testcase.mk' <<-EOF
276 SUBST_CLASSES+= class 317 SUBST_CLASSES+= class
277 SUBST_STAGE.class= pre-configure 318 SUBST_STAGE.class= pre-configure
278 SUBST_FILES.class= nonexistent 319 SUBST_FILES.class= nonexistent
279 SUBST_SED.class= -e 's,file,example,' 320 SUBST_SED.class= -e 's,file,example,'
280 SUBST_NOOP_OK.class= yes 321 SUBST_NOOP_OK.class= yes
281 322
282 .include "prepare-subst.mk" 323 .include "prepare-subst.mk"
283 .include "mk/subst.mk" 324 .include "mk/subst.mk"
284 EOF 325 EOF
285 326
286 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 327 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
287 && exitcode=0 || exitcode=$? 328 && exitcode=0 || exitcode=$?
288 329
289 assert_that "$tmpdir/output" --file-is-lines \ 330 assert_that "$tmpdir/output" --file-is-lines \
290 '=> Substituting "class" in nonexistent' \ 331 '=> Substituting "class" in nonexistent' \
291 'info: [subst.mk:class] Ignoring nonexistent file "nonexistent".' 332 'info: [subst.mk:class] Ignoring nonexistent file "nonexistent".'
292 assert_that "$exitcode" --equals '0' 333 assert_that "$exitcode" --equals '0'
293 334
294 test_case_end 335 test_case_end
295fi 336fi
296 337
297 338
298if test_case_begin 'several patterns, 1 nonexistent'; then 339if test_case_begin 'several filename patterns, 1 nonexistent, no-op ok'; then
299 340
300 create_file 'testcase.mk' <<-EOF 341 create_file 'testcase.mk' <<-EOF
301 SUBST_CLASSES+= class 342 SUBST_CLASSES+= class
302 SUBST_STAGE.class= pre-configure 343 SUBST_STAGE.class= pre-configure
303 SUBST_FILES.class= *exist* *not-found* 344 SUBST_FILES.class= *exist* *not-found*
304 SUBST_SED.class= -e 's,file,example,' 345 SUBST_SED.class= -e 's,file,example,'
 346 SUBST_NOOP_OK.class= yes
305 347
306 .include "prepare-subst.mk" 348 .include "prepare-subst.mk"
307 .include "mk/subst.mk" 349 .include "mk/subst.mk"
308 EOF 350 EOF
309 351
310 create_file_lines 'exists' 'this file exists' 352 create_file_lines 'exists' 'this file exists'
311 353
312 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 354 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
313 && exitcode=0 || exitcode=$? 355 && exitcode=0 || exitcode=$?
314 356
315 assert_that "$tmpdir/output" --file-is-lines \ 357 assert_that "$tmpdir/output" --file-is-lines \
316 '=> Substituting "class" in *exist* *not-found*' \ 358 '=> Substituting "class" in *exist* *not-found*' \
317 'info: [subst.mk:class] Ignoring nonexistent file "./*not-found*".' 359 'info: [subst.mk:class] Ignoring nonexistent file "./*not-found*".'
318 assert_that 'exists' --file-is-lines 'this example exists' 360 assert_that 'exists' --file-is-lines 'this example exists'
319 assert_that "$exitcode" --equals '0' 361 assert_that "$exitcode" --equals '0'
320 362
321 test_case_end 363 test_case_end
322fi 364fi
323 365
324 366
325if test_case_begin 'multiple missing files, all are reported at once'; then 367if test_case_begin 'several filename patterns, 1 nonexistent, no-op not ok'; then
 368
 369 create_file 'testcase.mk' <<-EOF
 370 SUBST_CLASSES+= class
 371 SUBST_STAGE.class= pre-configure
 372 SUBST_FILES.class= *exist* *not-found*
 373 SUBST_SED.class= -e 's,file,example,'
 374 SUBST_NOOP_OK.class= no
 375
 376 .include "prepare-subst.mk"
 377 .include "mk/subst.mk"
 378 EOF
 379
 380 create_file_lines 'exists' 'this file exists'
 381
 382 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
 383 && exitcode=0 || exitcode=$?
 384
 385 assert_that "$tmpdir/output" --file-is-lines \
 386 '=> Substituting "class" in *exist* *not-found*' \
 387 'warning: [subst.mk:class] Ignoring nonexistent file "./*not-found*".' \
 388 'fail: [subst.mk:class] The filename pattern "*not-found*" has no effect.' \
 389 '*** Error code 1' \
 390 '' \
 391 'Stop.' \
 392 "$make: stopped in $PWD"
 393 assert_that 'exists' --file-is-lines 'this example exists'
 394 assert_that "$exitcode" --equals '1'
 395
 396 test_case_end
 397fi
 398
 399
 400if test_case_begin 'multiple missing files, all are reported at once, no-op not ok'; then
 401
 402 create_file 'testcase.mk' <<-EOF
 403 SUBST_CLASSES+= class
 404 SUBST_STAGE.class= pre-configure
 405 SUBST_FILES.class= does not exist
 406 SUBST_SED.class= -e 'sahara'
 407 SUBST_NOOP_OK.class= no
 408
 409 .include "prepare-subst.mk"
 410 .include "mk/subst.mk"
 411 EOF
 412
 413 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
 414 && exitcode=0 || exitcode=$?
 415
 416 assert_that "$tmpdir/output" --file-is-lines \
 417 '=> Substituting "class" in does not exist' \
 418 'warning: [subst.mk:class] Ignoring nonexistent file "does".' \
 419 'warning: [subst.mk:class] Ignoring nonexistent file "not".' \
 420 'warning: [subst.mk:class] Ignoring nonexistent file "exist".' \
 421 'fail: [subst.mk:class] The filename patterns "does not exist" have no effect.' \
 422 '*** Error code 1' \
 423 '' \
 424 'Stop.' \
 425 "$make: stopped in $PWD"
 426 assert_that "$exitcode" --equals '1'
 427
 428 test_case_end
 429fi
 430
 431
 432if test_case_begin 'multiple missing files, all are reported at once, no-op ok'; then
326 433
327 create_file 'testcase.mk' <<-EOF 434 create_file 'testcase.mk' <<-EOF
328 SUBST_CLASSES+= class 435 SUBST_CLASSES+= class
329 SUBST_STAGE.class= pre-configure 436 SUBST_STAGE.class= pre-configure
330 SUBST_FILES.class= does not exist 437 SUBST_FILES.class= does not exist
331 SUBST_SED.class= -e 'sahara' 438 SUBST_SED.class= -e 'sahara'
 439 SUBST_NOOP_OK.class= yes
332 440
333 .include "prepare-subst.mk" 441 .include "prepare-subst.mk"
334 .include "mk/subst.mk" 442 .include "mk/subst.mk"
335 EOF 443 EOF
336 444
337 run_bmake 'testcase.mk' > "$tmpdir/output" \ 445 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
338 && exitcode=0 || exitcode=$? 446 && exitcode=0 || exitcode=$?
339 447
340 assert_that "$tmpdir/output" --file-is-lines \ 448 assert_that "$tmpdir/output" --file-is-lines \
341 '=> Substituting "class" in does not exist' \ 449 '=> Substituting "class" in does not exist' \
342 'info: [subst.mk:class] Ignoring nonexistent file "does".' \ 450 'info: [subst.mk:class] Ignoring nonexistent file "does".' \
343 'info: [subst.mk:class] Ignoring nonexistent file "not".' \ 451 'info: [subst.mk:class] Ignoring nonexistent file "not".' \
344 'info: [subst.mk:class] Ignoring nonexistent file "exist".' 452 'info: [subst.mk:class] Ignoring nonexistent file "exist".'
345 assert_that "$exitcode" --equals '0' 453 assert_that "$exitcode" --equals '0'
346 454
347 test_case_end 455 test_case_end
348fi 456fi
349 457
350 458
351if test_case_begin 'multiple no-op files, all are reported at once'; then 459if test_case_begin 'multiple no-op files, all are reported at once, no-op not ok'; then
352 460
353 create_file 'testcase.mk' <<-EOF 461 create_file 'testcase.mk' <<-EOF
354 SUBST_CLASSES+= class 462 SUBST_CLASSES+= class
355 SUBST_STAGE.class= pre-configure 463 SUBST_STAGE.class= pre-configure
356 SUBST_FILES.class= first second third 464 SUBST_FILES.class= first second third
357 SUBST_SED.class= -e 's,from,to,' 465 SUBST_SED.class= -e 's,from,to,'
 466 SUBST_NOOP_OK.class= no
 467
 468 .include "prepare-subst.mk"
 469 .include "mk/subst.mk"
 470 EOF
 471 create_file_lines 'first' 'text'
 472 create_file_lines 'second' 'second'
 473 create_file_lines 'third' 'third'
 474
 475 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
 476 && exitcode=0 || exitcode=$?
 477
 478 assert_that "$tmpdir/output" --file-is-lines \
 479 '=> Substituting "class" in first second third' \
 480 'warning: [subst.mk:class] Nothing changed in "first".' \
 481 'warning: [subst.mk:class] Nothing changed in "second".' \
 482 'warning: [subst.mk:class] Nothing changed in "third".' \
 483 'fail: [subst.mk:class] The filename patterns "first second third" have no effect.' \
 484 '*** Error code 1' \
 485 '' \
 486 'Stop.' \
 487 "$make: stopped in $PWD"
 488 assert_that "$exitcode" --equals '1'
 489
 490 test_case_end
 491fi
 492
 493
 494if test_case_begin 'multiple no-op files, all are reported at once, no-op ok'; then
 495
 496 create_file 'testcase.mk' <<-EOF
 497 SUBST_CLASSES+= class
 498 SUBST_STAGE.class= pre-configure
 499 SUBST_FILES.class= first second third
 500 SUBST_SED.class= -e 's,from,to,'
 501 SUBST_NOOP_OK.class= yes
358 502
359 .include "prepare-subst.mk" 503 .include "prepare-subst.mk"
360 .include "mk/subst.mk" 504 .include "mk/subst.mk"
361 EOF 505 EOF
362 create_file_lines 'first' 'text' 506 create_file_lines 'first' 'text'
363 create_file_lines 'second' 'second' 507 create_file_lines 'second' 'second'
364 create_file_lines 'third' 'third' 508 create_file_lines 'third' 'third'
365 509
366 run_bmake 'testcase.mk' > "$tmpdir/output" \ 510 run_bmake 'testcase.mk' 1> "$tmpdir/output" 2>&1 \
367 && exitcode=0 || exitcode=$? 511 && exitcode=0 || exitcode=$?
368 512
369 assert_that "$tmpdir/output" --file-is-lines \ 513 assert_that "$tmpdir/output" --file-is-lines \
370 '=> Substituting "class" in first second third' \ 514 '=> Substituting "class" in first second third' \
371 'info: [subst.mk:class] Nothing changed in "first".' \ 515 'info: [subst.mk:class] Nothing changed in "first".' \
372 'info: [subst.mk:class] Nothing changed in "second".' \ 516 'info: [subst.mk:class] Nothing changed in "second".' \
373 'info: [subst.mk:class] Nothing changed in "third".' 517 'info: [subst.mk:class] Nothing changed in "third".'
374 assert_that "$exitcode" --equals '0' 518 assert_that "$exitcode" --equals '0'
375 519
376 test_case_end 520 test_case_end
377fi 521fi
378 522
379 523
380if test_case_begin 'late evaluation of SUBST_FILES'; then 524if test_case_begin 'late evaluation of SUBST_FILES'; then
381 525
382 # Ensure that SUBST_FILES is evaluated as late as possible. 526 # Ensure that SUBST_FILES is evaluated as late as possible.
383 # Evaluating it early breaks cases like pkglocaledir where the 527 # Evaluating it early breaks cases like pkglocaledir where the
384 # list of files is generated by a shell command. 528 # list of files is generated by a shell command.
385 # See mk/configure/replace-localedir.mk. 529 # See mk/configure/replace-localedir.mk.
386 530
387 create_file 'testcase.mk' <<EOF 531 create_file 'testcase.mk' <<EOF
388REPLACE_FILES_CMD.class= \ 532REPLACE_FILES_CMD.class= \
389 cd \${WRKSRC} && echo *r* 533 cd \${WRKSRC} && echo *r*
390 534
391SUBST_CLASSES+= class 535SUBST_CLASSES+= class
392SUBST_STAGE.class= pre-configure 536SUBST_STAGE.class= pre-configure
393SUBST_FILES.class= first third # \${REPLACE_FILES_CMD.class:sh} 537SUBST_FILES.class= first third # \${REPLACE_FILES_CMD.class:sh}
394SUBST_SED.class= -e 's,from,to,' 538SUBST_SED.class= -e 's,from,to,'
395 539
396.include "prepare-subst.mk" 540.include "prepare-subst.mk"
397RUN= @set -e; 541RUN= @set -e;
398WRKSRC= \${WRKDIR}/package-1.0 542WRKSRC= \${WRKDIR}/package-1.0
399.include "mk/subst.mk" 543.include "mk/subst.mk"
400 544
401# It is tricky that the dependency must use an internal implementation 545# It is tricky that the dependency must use an internal implementation
402# detail, but that's the only way to guarantee the correct ordering. 546# detail, but that's the only way to guarantee the correct ordering.
403\${_SUBST_COOKIE.class}: prepare-subst-class 547\${_SUBST_COOKIE.class}: prepare-subst-class
404prepare-subst-class: 548prepare-subst-class:
405 \${RUN} \${MKDIR} \${WRKSRC} 549 \${RUN} \${MKDIR} \${WRKSRC}
406 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/first' 550 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/first'
407 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/second' 551 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/second'
408 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/third' 552 \${RUN} \${ECHO} 'from' > '\${WRKSRC}/third'
409EOF 553EOF
410 554
411 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 555 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
412 && exitcode=0 || exitcode=$? 556 && exitcode=0 || exitcode=$?
413 557
414 assert_that "$tmpdir/output" --file-is-lines \ 558 assert_that "$tmpdir/output" --file-is-lines \
415 '=> Substituting "class" in first third' 559 '=> Substituting "class" in first third'
416 assert_that "$wrkdir/package-1.0/first" --file-is-lines 'to' 560 assert_that "$wrkdir/package-1.0/first" --file-is-lines 'to'
417 assert_that "$wrkdir/package-1.0/second" --file-is-lines 'from' 561 assert_that "$wrkdir/package-1.0/second" --file-is-lines 'from'
418 assert_that "$wrkdir/package-1.0/third" --file-is-lines 'to' 562 assert_that "$wrkdir/package-1.0/third" --file-is-lines 'to'
419 assert_that "$exitcode" --equals '0' 563 assert_that "$exitcode" --equals '0'
420 564
421 test_case_end 565 test_case_end
422fi 566fi
423 567
424 568
425if test_case_begin 'special characters in filenames'; then 569if test_case_begin 'special characters in filenames'; then
426 570
427 create_file 'testcase.mk' <<-EOF 571 create_file 'testcase.mk' <<-EOF
428 SUBST_CLASSES+= class 572 SUBST_CLASSES+= class
429 SUBST_STAGE.class= pre-configure 573 SUBST_STAGE.class= pre-configure
430 SUBST_FILES.class= * 574 SUBST_FILES.class= *
431 SUBST_SED.class= -e s,before,after, 575 SUBST_SED.class= -e s,before,after,
432 SUBST_NOOP_OK.class= yes 576 SUBST_NOOP_OK.class= yes
433 577
434 .include "prepare-subst.mk" 578 .include "prepare-subst.mk"
435 .include "mk/subst.mk" 579 .include "mk/subst.mk"
436 EOF 580 EOF
437 581
438 create_file_lines ' !"#$%&'\''()*+,-.' 'before' 582 create_file_lines ' !"#$%&'\''()*+,-.' 'before'
439 create_file_lines '0123456789:;<=>?' 'before' 583 create_file_lines '0123456789:;<=>?' 'before'
440 create_file_lines '@ABCDEFGHIJKLMNO' 'before' 584 create_file_lines '@ABCDEFGHIJKLMNO' 'before'
441 create_file_lines 'PQRSTUVWXYZ[\]^_' 'before' 585 create_file_lines 'PQRSTUVWXYZ[\]^_' 'before'
442 create_file_lines '`abcdefghijklmno' 'before' 586 create_file_lines '`abcdefghijklmno' 'before'
443 create_file_lines 'pqrstuvwxyz{|}~' 'before' 587 create_file_lines 'pqrstuvwxyz{|}~' 'before'
444 create_file_lines '--no-option' 'before' 588 create_file_lines '--no-option' 'before'
445 create_file_lines '.hidden' 'before' 589 create_file_lines '.hidden' 'before'
446 590
447 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 591 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
448 && exitcode=0 || exitcode=$? 592 && exitcode=0 || exitcode=$?
449 593
450 assert_that "$tmpdir/output" --file-is-lines \ 594 assert_that "$tmpdir/output" --file-is-lines \
451 '=> Substituting "class" in *' \ 595 '=> Substituting "class" in *' \
452 'info: [subst.mk:class] Nothing changed in "prepare-subst.mk".' 596 'info: [subst.mk:class] Nothing changed in "prepare-subst.mk".'
453 597
454 assert_that ' !"#$%&'\''()*+,-.' --file-is-lines 'after' 598 assert_that ' !"#$%&'\''()*+,-.' --file-is-lines 'after'
455 assert_that '0123456789:;<=>?' --file-is-lines 'after' 599 assert_that '0123456789:;<=>?' --file-is-lines 'after'
456 assert_that '@ABCDEFGHIJKLMNO' --file-is-lines 'after' 600 assert_that '@ABCDEFGHIJKLMNO' --file-is-lines 'after'
457 assert_that 'PQRSTUVWXYZ[\]^_' --file-is-lines 'after' 601 assert_that 'PQRSTUVWXYZ[\]^_' --file-is-lines 'after'
458 assert_that '`abcdefghijklmno' --file-is-lines 'after' 602 assert_that '`abcdefghijklmno' --file-is-lines 'after'
459 assert_that 'pqrstuvwxyz{|}~' --file-is-lines 'after' 603 assert_that 'pqrstuvwxyz{|}~' --file-is-lines 'after'
460 assert_that '--no-option' --file-is-lines 'after' 604 assert_that '--no-option' --file-is-lines 'after'
461 assert_that '.hidden' --file-is-lines 'before' 605 assert_that '.hidden' --file-is-lines 'before'
462 606
463 test_case_end 607 test_case_end
464fi 608fi
465 609
466if test_case_begin 'brackets in filename patterns'; then 610if test_case_begin 'brackets in filename patterns'; then
467 611
468 create_file 'testcase.mk' <<-EOF 612 create_file 'testcase.mk' <<-EOF
469 SUBST_CLASSES+= class 613 SUBST_CLASSES+= class
470 SUBST_STAGE.class= pre-configure 614 SUBST_STAGE.class= pre-configure
471 SUBST_FILES.class= [*] 615 SUBST_FILES.class= [*]
472 SUBST_SED.class= -e s,before,after, 616 SUBST_SED.class= -e s,before,after,
473 SUBST_NOOP_OK.class= yes 617 SUBST_NOOP_OK.class= yes
474 618
475 .include "prepare-subst.mk" 619 .include "prepare-subst.mk"
476 .include "mk/subst.mk" 620 .include "mk/subst.mk"
477 EOF 621 EOF
478 622
479 create_file_lines 'any' 'before' 623 create_file_lines 'any' 'before'
480 create_file_lines 'x' 'before' 624 create_file_lines 'x' 'before'
481 create_file_lines '*' 'before' 625 create_file_lines '*' 'before'
482 create_file_lines '[*]' 'before' 626 create_file_lines '[*]' 'before'
483 627
484 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \ 628 run_bmake 'testcase.mk' 'subst-class' 1> "$tmpdir/output" 2>&1 \
485 && exitcode=0 || exitcode=$? 629 && exitcode=0 || exitcode=$?
486 630
487 assert_that "$tmpdir/output" --file-is-lines \ 631 assert_that "$tmpdir/output" --file-is-lines \
488 '=> Substituting "class" in [*]' 632 '=> Substituting "class" in [*]'
489 assert_that "$exitcode" --equals '0' 633 assert_that "$exitcode" --equals '0'
490 634
491 assert_that 'any' --file-is-lines 'before' 635 assert_that 'any' --file-is-lines 'before'
492 assert_that 'x' --file-is-lines 'before' 636 assert_that 'x' --file-is-lines 'before'
493 assert_that '*' --file-is-lines 'after' 637 assert_that '*' --file-is-lines 'after'
494 assert_that '[*]' --file-is-lines 'before' 638 assert_that '[*]' --file-is-lines 'before'
495 639
496 test_case_end 640 test_case_end
497fi 641fi
498 642
499 643
500if test_case_begin 'duplicate SUBST class'; then 644if test_case_begin 'duplicate SUBST class'; then
501 645
502 create_file 'testcase.mk' <<EOF 646 create_file 'testcase.mk' <<EOF
503SUBST_CLASSES+= one 647SUBST_CLASSES+= one
504SUBST_CLASSES+= two 648SUBST_CLASSES+= two
505SUBST_CLASSES+= one 649SUBST_CLASSES+= one
506 650
507all: 651all:
508 @printf 'fail reason: %s\n' \${PKG_FAIL_REASON} 1>&2 652 @printf 'fail reason: %s\n' \${PKG_FAIL_REASON} 1>&2
509 653
510.include "prepare-subst.mk" 654.include "prepare-subst.mk"
511.include "mk/subst.mk" 655.include "mk/subst.mk"
512EOF 656EOF
513 657
514 run_bmake 'testcase.mk' 'all' \ 658 run_bmake 'testcase.mk' 'all' \
515 1> "$tmpdir/stdout" \ 659 1> "$tmpdir/stdout" \
516 2> "$tmpdir/stderr" \ 660 2> "$tmpdir/stderr" \
517 && exitcode=0 || exitcode=$? 661 && exitcode=0 || exitcode=$?
518 662
519 assert_that "$tmpdir/stdout" --file-is-empty 663 assert_that "$tmpdir/stdout" --file-is-empty
520 assert_that "$tmpdir/stderr" --file-is-lines \ 664 assert_that "$tmpdir/stderr" --file-is-lines \
521 'fail reason: [subst.mk] duplicate SUBST class in: one one two' 665 'fail reason: [subst.mk] duplicate SUBST class in: one one two'
522 assert_that "$exitcode" --equals '0' 666 assert_that "$exitcode" --equals '0'
523 667
524 test_case_end 668 test_case_end
525fi 669fi
526 670
527 671
528if test_case_begin 'several SUBST classes'; then 672if test_case_begin 'several SUBST classes'; then
529 673
530 # It's ok to have several SUBST classes that apply to the same file. 674 # It's ok to have several SUBST classes that apply to the same file.
531 # The order of execution is not guaranteed though. 675 # The order of execution is not guaranteed though.
532 676
533 create_file_lines 'file' 'zero one two three four' 677 create_file_lines 'file' 'zero one two three four'
534 678
535 create_file 'testcase.mk' <<-EOF 679 create_file 'testcase.mk' <<-EOF
536 SUBST_CLASSES+= one 680 SUBST_CLASSES+= one
537 SUBST_STAGE.one= pre-configure 681 SUBST_STAGE.one= pre-configure
538 SUBST_FILES.one= file 682 SUBST_FILES.one= file
539 SUBST_SED.one= -e 's,one,I,' 683 SUBST_SED.one= -e 's,one,I,'
540 684
541 SUBST_CLASSES+= two 685 SUBST_CLASSES+= two
542 SUBST_STAGE.two= pre-configure 686 SUBST_STAGE.two= pre-configure
543 SUBST_FILES.two= file 687 SUBST_FILES.two= file
544 SUBST_SED.two= -e 's,two,II,' 688 SUBST_SED.two= -e 's,two,II,'
545 689
546 SUBST_CLASSES+= three 690 SUBST_CLASSES+= three
547 SUBST_STAGE.three= pre-configure 691 SUBST_STAGE.three= pre-configure
548 SUBST_FILES.three= file 692 SUBST_FILES.three= file
549 SUBST_SED.three= -e 's,three,III,' 693 SUBST_SED.three= -e 's,three,III,'
550 694
551 .include "prepare-subst.mk" 695 .include "prepare-subst.mk"
552 .include "mk/subst.mk" 696 .include "mk/subst.mk"
553 EOF 697 EOF
554 698
555 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 699 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
556 && exitcode=0 || exitcode=$? 700 && exitcode=0 || exitcode=$?
557 701
558 # The order of the above output is not guaranteed. 702 # The order of the above output is not guaranteed.
559 LC_ALL=C sort < "$tmpdir/output" > "$tmpdir/output-sorted" 703 LC_ALL=C sort < "$tmpdir/output" > "$tmpdir/output-sorted"
560 704
561 assert_that 'file' --file-is-lines 'zero I II III four' 705 assert_that 'file' --file-is-lines 'zero I II III four'
562 assert_that "$tmpdir/output-sorted" --file-is-lines \ 706 assert_that "$tmpdir/output-sorted" --file-is-lines \
563 '=> Substituting "one" in file' \ 707 '=> Substituting "one" in file' \
564 '=> Substituting "three" in file' \ 708 '=> Substituting "three" in file' \
565 '=> Substituting "two" in file' 709 '=> Substituting "two" in file'
566 710
567 test_case_end 711 test_case_end
568fi 712fi
569 713
570 714
571if test_case_begin 'show diff'; then 715if test_case_begin 'show diff'; then
572 716
573 create_file_lines 'file' 'one' 'two' 'three' 717 create_file_lines 'file' 'one' 'two' 'three'
574 718
575 create_file 'testcase.mk' <<-EOF 719 create_file 'testcase.mk' <<-EOF
576 SUBST_CLASSES+= two 720 SUBST_CLASSES+= two
577 SUBST_STAGE.two= pre-configure 721 SUBST_STAGE.two= pre-configure
578 SUBST_FILES.two= file 722 SUBST_FILES.two= file
579 SUBST_SED.two= -e 's,two,II,' 723 SUBST_SED.two= -e 's,two,II,'
580 SUBST_SHOW_DIFF.two= yes 724 SUBST_SHOW_DIFF.two= yes
581 725
582 .include "prepare-subst.mk" 726 .include "prepare-subst.mk"
583 .include "mk/subst.mk" 727 .include "mk/subst.mk"
584 EOF 728 EOF
585 729
586 LC_ALL=C \ 730 LC_ALL=C \
587 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 731 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
588 && exitcode=0 || exitcode=$? 732 && exitcode=0 || exitcode=$?
589 733
590 awk '{ if (/^(---|\+\+\+) /) { print $1 " " $2 " (filtered timestamp)" } else { print $0 } }' \ 734 awk '{ if (/^(---|\+\+\+) /) { print $1 " " $2 " (filtered timestamp)" } else { print $0 } }' \
591 < "$tmpdir/output" > "$tmpdir/output-filtered" 735 < "$tmpdir/output" > "$tmpdir/output-filtered"
592 736
593 assert_that 'file' --file-is-lines 'one' 'II' 'three' 737 assert_that 'file' --file-is-lines 'one' 'II' 'three'
594 assert_that "$tmpdir/output-filtered" --file-is-lines \ 738 assert_that "$tmpdir/output-filtered" --file-is-lines \
595 '=> Substituting "two" in file' \ 739 '=> Substituting "two" in file' \
596 '--- file (filtered timestamp)' \ 740 '--- file (filtered timestamp)' \
597 '+++ file.subst.sav (filtered timestamp)' \ 741 '+++ file.subst.sav (filtered timestamp)' \
598 '@@ -1,3 +1,3 @@' \ 742 '@@ -1,3 +1,3 @@' \
599 ' one' \ 743 ' one' \
600 '-two' \ 744 '-two' \
601 '+II' \ 745 '+II' \
602 ' three' 746 ' three'
603 747
604 test_case_end 748 test_case_end
605fi 749fi
606 750
607 751
608if test_case_begin 'global show diff'; then 752if test_case_begin 'global show diff'; then
609 753
610 create_file_lines 'file' \ 754 create_file_lines 'file' \
611 'one' \ 755 'one' \
612 'two' \ 756 'two' \
613 'three' 757 'three'
614 758
615 create_file 'testcase.mk' <<-EOF 759 create_file 'testcase.mk' <<-EOF
616 SUBST_CLASSES+= two 760 SUBST_CLASSES+= two
617 SUBST_STAGE.two= pre-configure 761 SUBST_STAGE.two= pre-configure
618 SUBST_FILES.two= file 762 SUBST_FILES.two= file
619 SUBST_SED.two= -e 's,two,II,' 763 SUBST_SED.two= -e 's,two,II,'
620 SUBST_SHOW_DIFF= yes 764 SUBST_SHOW_DIFF= yes
621 765
622 .include "prepare-subst.mk" 766 .include "prepare-subst.mk"
623 .include "mk/subst.mk" 767 .include "mk/subst.mk"
624 EOF 768 EOF
625 769
626 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 770 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
627 && exitcode=0 || exitcode=$? 771 && exitcode=0 || exitcode=$?
628 772
629 awk '{ if (/^(---|\+\+\+) /) { print $1 " " $2 " (filtered timestamp)" } else { print $0 } }' \ 773 awk '{ if (/^(---|\+\+\+) /) { print $1 " " $2 " (filtered timestamp)" } else { print $0 } }' \
630 < "$tmpdir/output" > "$tmpdir/output-filtered" 774 < "$tmpdir/output" > "$tmpdir/output-filtered"
631 775
632 assert_that 'file' --file-is-lines \ 776 assert_that 'file' --file-is-lines \
633 'one' \ 777 'one' \
634 'II' \ 778 'II' \
635 'three' 779 'three'
636 assert_that "$tmpdir/output-filtered" --file-is-lines \ 780 assert_that "$tmpdir/output-filtered" --file-is-lines \
637 '=> Substituting "two" in file' \ 781 '=> Substituting "two" in file' \
638 '--- file (filtered timestamp)' \ 782 '--- file (filtered timestamp)' \
639 '+++ file.subst.sav (filtered timestamp)' \ 783 '+++ file.subst.sav (filtered timestamp)' \
640 '@@ -1,3 +1,3 @@' \ 784 '@@ -1,3 +1,3 @@' \
641 ' one' \ 785 ' one' \
642 '-two' \ 786 '-two' \
643 '+II' \ 787 '+II' \
644 ' three' 788 ' three'
645 789
646 test_case_end 790 test_case_end
647fi 791fi
648 792
649 793
650if test_case_begin 'SUBST_VARS'; then 794if test_case_begin 'SUBST_VARS'; then
651 795
652 create_file_lines 'testcase.mk' \ 796 create_file_lines 'testcase.mk' \
653 'SUBST_CLASSES+= vars' \ 797 'SUBST_CLASSES+= vars' \
654 'SUBST_STAGE.vars= pre-configure' \ 798 'SUBST_STAGE.vars= pre-configure' \
655 'SUBST_FILES.vars= vars.txt' \ 799 'SUBST_FILES.vars= vars.txt' \
656 'SUBST_VARS.vars= PLAIN DQUOT SQUOT DELIM PRINTABLE' \ 800 'SUBST_VARS.vars= PLAIN DQUOT SQUOT DELIM PRINTABLE' \
657 'SUBST_VARS.vars+= UNDEFINED' \ 801 'SUBST_VARS.vars+= UNDEFINED' \
658 '' \ 802 '' \
659 'PLAIN= plain' \ 803 'PLAIN= plain' \
660 'DQUOT= "double quoted"' \ 804 'DQUOT= "double quoted"' \
661 'SQUOT= '\''single quoted'\''' \ 805 'SQUOT= '\''single quoted'\''' \
662 'DELIM= hello, world' \ 806 'DELIM= hello, world' \
663 'PRINTABLE= !"\#$$%&'\''()*+,-./09:;<=>?@AZ[\]^_`az{|}' \ 807 'PRINTABLE= !"\#$$%&'\''()*+,-./09:;<=>?@AZ[\]^_`az{|}' \
664 '#UNDEFINED= # undefined' \ 808 '#UNDEFINED= # undefined' \
665 '' \ 809 '' \
666 '.include "prepare-subst.mk"' \ 810 '.include "prepare-subst.mk"' \
667 '.include "mk/subst.mk"' 811 '.include "mk/subst.mk"'
668 create_file_lines 'vars.txt' \ 812 create_file_lines 'vars.txt' \
669 '@PLAIN@' \ 813 '@PLAIN@' \
670 '@DQUOT@' \ 814 '@DQUOT@' \
671 '@SQUOT@' \ 815 '@SQUOT@' \
672 '@DELIM@' \ 816 '@DELIM@' \
673 '@PRINTABLE@' \ 817 '@PRINTABLE@' \
674 '@UNDEFINED@' 818 '@UNDEFINED@'
675 819
676 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 820 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
677 && exitcode=0 || exitcode=$? 821 && exitcode=0 || exitcode=$?
678 822
679 # The double quotes and single quotes are kept since the variables 823 # The double quotes and single quotes are kept since the variables
680 # are treated as simple string variables, not as lists of shell 824 # are treated as simple string variables, not as lists of shell
681 # words. In these string variables, the quotes are part of the value. 825 # words. In these string variables, the quotes are part of the value.
682 assert_that 'vars.txt' --file-is-lines \ 826 assert_that 'vars.txt' --file-is-lines \
683 'plain' \ 827 'plain' \
684 '"double quoted"' \ 828 '"double quoted"' \
685 "'single quoted'" \ 829 "'single quoted'" \
686 'hello, world' \ 830 'hello, world' \
687 '!"#$%&'\''()*+,-./09:;<=>?@AZ[\]^_`az{|}' \ 831 '!"#$%&'\''()*+,-./09:;<=>?@AZ[\]^_`az{|}' \
688 '' 832 ''
689 assert_that "$tmpdir/output" --file-is-lines \ 833 assert_that "$tmpdir/output" --file-is-lines \
690 '=> Substituting "vars" in vars.txt' 834 '=> Substituting "vars" in vars.txt'
691 835
692 test_case_end 836 test_case_end
693fi 837fi
694 838
695if test_case_begin 'SUBST_VARS with surrounding whitespace'; then 839if test_case_begin 'SUBST_VARS with surrounding whitespace'; then
696 840
697 # Ensure that leading and trailing whitespace is preserved 841 # Ensure that leading and trailing whitespace is preserved
698 # in the variable values. 842 # in the variable values.
699 843
700 create_file_lines 'testcase.mk' \ 844 create_file_lines 'testcase.mk' \
701 'SUBST_CLASSES+= vars' \ 845 'SUBST_CLASSES+= vars' \
702 'SUBST_STAGE.vars= pre-configure' \ 846 'SUBST_STAGE.vars= pre-configure' \
703 'SUBST_FILES.vars= vars.txt' \ 847 'SUBST_FILES.vars= vars.txt' \
704 'SUBST_VARS.vars= SPACE TAB NEWLINE' \ 848 'SUBST_VARS.vars= SPACE TAB NEWLINE' \
705 '' \ 849 '' \
706 'SPACE= ${:U }between spaces${:U }' \ 850 'SPACE= ${:U }between spaces${:U }' \
707 'TAB= ${:U }between tabs${:U }' \ 851 'TAB= ${:U }between tabs${:U }' \
708 'NEWLINE= ${.newline}between newlines${.newline}' \ 852 'NEWLINE= ${.newline}between newlines${.newline}' \
709 '' \ 853 '' \
710 '.include "prepare-subst.mk"' \ 854 '.include "prepare-subst.mk"' \
711 '.include "mk/subst.mk"' 855 '.include "mk/subst.mk"'
712 create_file_lines 'vars.txt' \ 856 create_file_lines 'vars.txt' \
713 '@SPACE@' \ 857 '@SPACE@' \
714 '@TAB@' \ 858 '@TAB@' \
715 '@NEWLINE@' 859 '@NEWLINE@'
716 860
717 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 861 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
718 && exitcode=0 || exitcode=$? 862 && exitcode=0 || exitcode=$?
719 863
720 space=' ' 864 space=' '
721 tab=' ' 865 tab=' '
722 newline=' 866 newline='
723' 867'
724 assert_that 'vars.txt' --file-is-lines \ 868 assert_that 'vars.txt' --file-is-lines \
725 "$space"'between spaces'"$space" \ 869 "$space"'between spaces'"$space" \
726 "$tab"'between tabs'"$tab" \ 870 "$tab"'between tabs'"$tab" \
727 "$newline"'between newlines'"$newline" 871 "$newline"'between newlines'"$newline"
728 assert_that "$tmpdir/output" --file-is-lines \ 872 assert_that "$tmpdir/output" --file-is-lines \
729 '=> Substituting "vars" in vars.txt' 873 '=> Substituting "vars" in vars.txt'
730 874
731 test_case_end 875 test_case_end
732fi 876fi
733 877
734 878
735if test_case_begin 'SUBST_VARS with backslashes'; then 879if test_case_begin 'SUBST_VARS with backslashes'; then
736 880
737 create_file_lines 'testcase.mk' \ 881 create_file_lines 'testcase.mk' \
738 'SUBST_CLASSES+= bs' \ 882 'SUBST_CLASSES+= bs' \
739 'SUBST_STAGE.bs= pre-configure' \ 883 'SUBST_STAGE.bs= pre-configure' \
740 'SUBST_FILES.bs= backslash.txt' \ 884 'SUBST_FILES.bs= backslash.txt' \
741 'SUBST_VARS.bs= BACKSLASHES' \ 885 'SUBST_VARS.bs= BACKSLASHES' \
742 '' \ 886 '' \
743 'BACKSLASHES= \" \, \\, \" \'\'' \0\000 \x40 \089 \a \$$' \ 887 'BACKSLASHES= \" \, \\, \" \'\'' \0\000 \x40 \089 \a \$$' \
744 '' \ 888 '' \
745 '.include "prepare-subst.mk"' \ 889 '.include "prepare-subst.mk"' \
746 '.include "mk/subst.mk"' 890 '.include "mk/subst.mk"'
747 create_file_lines 'backslash.txt' '@BACKSLASHES@' 891 create_file_lines 'backslash.txt' '@BACKSLASHES@'
748 892
749 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 893 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
750 && exitcode=0 || exitcode=$? 894 && exitcode=0 || exitcode=$?
751 895
752 assert_that 'backslash.txt' --file-is-lines \ 896 assert_that 'backslash.txt' --file-is-lines \
753 '\" \, \\, \" \'\'' \0\000 \x40 \089 \a \$' 897 '\" \, \\, \" \'\'' \0\000 \x40 \089 \a \$'
754 assert_that "$tmpdir/output" --file-is-lines \ 898 assert_that "$tmpdir/output" --file-is-lines \
755 '=> Substituting "bs" in backslash.txt' 899 '=> Substituting "bs" in backslash.txt'
756 900
757 test_case_end 901 test_case_end
758fi 902fi
759 903
760 904
761if test_case_begin 'SUBST_VARS for variables with regex characters'; then 905if test_case_begin 'SUBST_VARS for variables with regex characters'; then
762 906
763 # Ensure that special regex characters like dots and parentheses 907 # Ensure that special regex characters like dots and parentheses
764 # may appear in variable names and are properly escaped. 908 # may appear in variable names and are properly escaped.
765 909
766 # Variable names containing a dollar are not supported. 910 # Variable names containing a dollar are not supported.
767 # Bmake behaves very surprisingly when a $ is expanded inside a :C 911 # Bmake behaves very surprisingly when a $ is expanded inside a :C
768 # modifier. Nobody needs this feature anyway, it was just an 912 # modifier. Nobody needs this feature anyway, it was just an
769 # experiment to see whether this would be theoretically possible. 913 # experiment to see whether this would be theoretically possible.
770 914
771 # Variable names ending with a backslash are not supported. 915 # Variable names ending with a backslash are not supported.
772 # The backslash may only occur in the middle of the variable name. 916 # The backslash may only occur in the middle of the variable name.
773 917
774 create_file_lines 'testcase.mk' \ 918 create_file_lines 'testcase.mk' \
775 'SUBST_CLASSES+= vars' \ 919 'SUBST_CLASSES+= vars' \
776 'SUBST_STAGE.vars= pre-configure' \ 920 'SUBST_STAGE.vars= pre-configure' \
777 'SUBST_FILES.vars= vars.txt' \ 921 'SUBST_FILES.vars= vars.txt' \
778 'SUBST_VARS.vars= VAR...... VAR.abcde' \ 922 'SUBST_VARS.vars= VAR...... VAR.abcde' \
779 'SUBST_VARS.vars+= VAR.() VAR.<> VAR.[]' \ 923 'SUBST_VARS.vars+= VAR.() VAR.<> VAR.[]' \
780 'SUBST_VARS.vars+= VAR.$$x VAR.^ VAR.\x' \ 924 'SUBST_VARS.vars+= VAR.$$x VAR.^ VAR.\x' \
781 '' \ 925 '' \
782 'VAR......= dots' \ 926 'VAR......= dots' \
783 'VAR.abcde= letters' \ 927 'VAR.abcde= letters' \
784 'VAR.()= parentheses' \ 928 'VAR.()= parentheses' \
785 'VAR.<>= angle brackets' \ 929 'VAR.<>= angle brackets' \
786 'VAR.[]= square brackets' \ 930 'VAR.[]= square brackets' \
787 'VAR.$$x= dollar' \ 931 'VAR.$$x= dollar' \
788 'VAR.^= circumflex' \ 932 'VAR.^= circumflex' \
789 'VAR.\x= backslash' \ 933 'VAR.\x= backslash' \
790 '' \ 934 '' \
791 '.include "prepare-subst.mk"' \ 935 '.include "prepare-subst.mk"' \
792 '.include "mk/subst.mk"' 936 '.include "mk/subst.mk"'
793 create_file_lines 'vars.txt' \ 937 create_file_lines 'vars.txt' \
794 '@VAR......@' \ 938 '@VAR......@' \
795 '@VAR.abcde@' \ 939 '@VAR.abcde@' \
796 '@VAR.()@' \ 940 '@VAR.()@' \
797 '@VAR.<>@' \ 941 '@VAR.<>@' \
798 '@VAR.[]@' \ 942 '@VAR.[]@' \
799 '@VAR.$x@' \ 943 '@VAR.$x@' \
800 '@VAR.^@' \ 944 '@VAR.^@' \
801 '@VAR.\x@' 945 '@VAR.\x@'
802 946
803 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 947 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
804 && exitcode=0 || exitcode=$? 948 && exitcode=0 || exitcode=$?
805 949
806 assert_that 'vars.txt' --file-is-lines \ 950 assert_that 'vars.txt' --file-is-lines \
807 'dots' \ 951 'dots' \
808 'letters' \ 952 'letters' \
809 'parentheses' \ 953 'parentheses' \
810 'angle brackets' \ 954 'angle brackets' \
811 'square brackets' \ 955 'square brackets' \
812 '@VAR.$x@' \ 956 '@VAR.$x@' \
813 'circumflex' \ 957 'circumflex' \
814 'backslash' 958 'backslash'
815 assert_that "$tmpdir/output" --file-is-lines \ 959 assert_that "$tmpdir/output" --file-is-lines \
816 '=> Substituting "vars" in vars.txt' 960 '=> Substituting "vars" in vars.txt'
817 961
818 test_case_end 962 test_case_end
819fi 963fi
820 964
821if test_case_begin 'pattern matches directory'; then 965if test_case_begin 'pattern matches directory'; then
822 966
823 # When a pattern matches a directory, that directory is silently 967 # When a pattern matches a directory, that directory is silently
824 # skipped. 968 # skipped.
825 # 969 #
826 # In this test case, the pattern also matches a regular file that 970 # In this test case, the pattern also matches a regular file that
827 # is actually modified. Therefore the pattern has an effect, and 971 # is actually modified. Therefore the pattern has an effect, and
828 # there is no error message. 972 # there is no error message.
829 973
830 create_file_lines 'testcase.mk' \ 974 create_file_lines 'testcase.mk' \
831 'SUBST_CLASSES+= dir' \ 975 'SUBST_CLASSES+= dir' \
832 'SUBST_STAGE.dir= pre-configure' \ 976 'SUBST_STAGE.dir= pre-configure' \
833 'SUBST_FILES.dir= sub*' \ 977 'SUBST_FILES.dir= sub*' \
834 'SUBST_VARS.dir= VAR' \ 978 'SUBST_VARS.dir= VAR' \
835 'SUBST_NOOP_OK.dir= no' \ 979 'SUBST_NOOP_OK.dir= no' \
836 '' \ 980 '' \
837 'VAR= value' \ 981 'VAR= value' \
838 '' \ 982 '' \
839 '.include "prepare-subst.mk"' \ 983 '.include "prepare-subst.mk"' \
840 '.include "mk/subst.mk"' 984 '.include "mk/subst.mk"'
841 create_file_lines 'subdir/subfile' \ 985 create_file_lines 'subdir/subfile' \
842 '@VAR@' 986 '@VAR@'
843 create_file_lines 'subst-file' \ 987 create_file_lines 'subst-file' \
844 '@VAR@' 988 '@VAR@'
845 989
846 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 990 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
847 && exitcode=0 || exitcode=$? 991 && exitcode=0 || exitcode=$?
848 992
849 assert_that 'subst-file' --file-is-lines 'value' 993 assert_that 'subst-file' --file-is-lines 'value'
850 assert_that 'subdir/subfile' --file-is-lines '@VAR@' # unchanged 994 assert_that 'subdir/subfile' --file-is-lines '@VAR@' # unchanged
851 assert_that "$tmpdir/output" --file-is-lines \ 995 assert_that "$tmpdir/output" --file-is-lines \
852 '=> Substituting "dir" in sub*' 996 '=> Substituting "dir" in sub*'
853 997
854 test_case_end 998 test_case_end
855fi 999fi
856 1000
857 1001
858if test_case_begin 'pattern matches only directory'; then 1002if test_case_begin 'pattern matches only directory'; then
859 1003
860 # When a pattern matches a directory, that directory is silently 1004 # When a pattern matches a directory, that directory is silently
861 # skipped. 1005 # skipped.
862 1006
863 create_file_lines 'testcase.mk' \ 1007 create_file_lines 'testcase.mk' \
864 'SUBST_CLASSES+= dir' \ 1008 'SUBST_CLASSES+= dir' \
865 'SUBST_STAGE.dir= pre-configure' \ 1009 'SUBST_STAGE.dir= pre-configure' \
866 'SUBST_FILES.dir= sub*' \ 1010 'SUBST_FILES.dir= sub*' \
867 'SUBST_VARS.dir= VAR' \ 1011 'SUBST_VARS.dir= VAR' \
868 'SUBST_NOOP_OK.dir= no' \ 1012 'SUBST_NOOP_OK.dir= no' \
869 '' \ 1013 '' \
870 'VAR= value' \ 1014 'VAR= value' \
871 '' \ 1015 '' \
872 '.include "prepare-subst.mk"' \ 1016 '.include "prepare-subst.mk"' \
873 '.include "mk/subst.mk"' 1017 '.include "mk/subst.mk"'
874 create_file_lines 'subdir/subfile' \ 1018 create_file_lines 'subdir/subfile' \
875 '@VAR@' 1019 '@VAR@'
876 1020
877 run_bmake 'testcase.mk' 'pre-configure' \ 1021 run_bmake 'testcase.mk' 'pre-configure' \
878 1> "$tmpdir/stdout" \ 1022 1> "$tmpdir/stdout" \
879 2> "$tmpdir/stderr" \ 1023 2> "$tmpdir/stderr" \
880 && exitcode=0 || exitcode=$? 1024 && exitcode=0 || exitcode=$?
881 1025
882 assert_that 'subdir/subfile' --file-is-lines '@VAR@' # unchanged 1026 assert_that 'subdir/subfile' --file-is-lines '@VAR@' # unchanged
883 assert_that "$tmpdir/stdout" --file-is-lines \ 1027 assert_that "$tmpdir/stdout" --file-is-lines \
884 '=> Substituting "dir" in sub*' \ 1028 '=> Substituting "dir" in sub*' \
885 '*** Error code 1' \ 1029 '*** Error code 1' \
886 '' \ 1030 '' \
887 'Stop.' \ 1031 'Stop.' \
888 "$make: stopped in $PWD" 1032 "$make: stopped in $PWD"
889 assert_that "$tmpdir/stderr" --file-is-lines \ 1033 assert_that "$tmpdir/stderr" --file-is-lines \
890 'fail: [subst.mk:dir] The filename pattern "sub*" has no effect.' 1034 'fail: [subst.mk:dir] The filename pattern "sub*" has no effect.'
891 assert_that "$exitcode" --equals 1 1035 assert_that "$exitcode" --equals 1
892 test_case_end 1036 test_case_end
893fi 1037fi
894 1038
895 1039
896if test_case_begin 'two filename patterns have no effect'; then 1040if test_case_begin 'two filename patterns have no effect'; then
897 1041
898 # All patterns of SUBST_FILES should be applied before erroring out, 1042 # All patterns of SUBST_FILES should be applied before erroring out,
899 # to give a complete picture of the situation. 1043 # to give a complete picture of the situation.
900 1044
901 create_file_lines 'testcase.mk' \ 1045 create_file_lines 'testcase.mk' \
902 'SUBST_CLASSES+= id' \ 1046 'SUBST_CLASSES+= id' \
903 'SUBST_STAGE.id= pre-configure' \ 1047 'SUBST_STAGE.id= pre-configure' \
904 'SUBST_FILES.id= file1 file2' \ 1048 'SUBST_FILES.id= file1 file2' \
905 'SUBST_VARS.id= A B' \ 1049 'SUBST_VARS.id= A B' \
906 'SUBST_NOOP_OK.id= no' \ 1050 'SUBST_NOOP_OK.id= no' \
907 'A= a-value' \ 1051 'A= a-value' \
908 'B= b-value' \ 1052 'B= b-value' \
909 '' \ 1053 '' \
910 '.include "prepare-subst.mk"' \ 1054 '.include "prepare-subst.mk"' \
911 '.include "mk/subst.mk"' 1055 '.include "mk/subst.mk"'
912 create_file_lines 'file1' 'nothing to replace' 1056 create_file_lines 'file1' 'nothing to replace'
913 create_file_lines 'file2' 'nothing to replace' 1057 create_file_lines 'file2' 'nothing to replace'
914 1058
915 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 1059 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
916 && exitcode=0 || exitcode=$? 1060 && exitcode=0 || exitcode=$?
917 1061
918 assert_that "$tmpdir/output" --file-is-lines \ 1062 assert_that "$tmpdir/output" --file-is-lines \
919 '=> Substituting "id" in file1 file2' \ 1063 '=> Substituting "id" in file1 file2' \
920 'warning: [subst.mk:id] Nothing changed in "file1".' \ 1064 'warning: [subst.mk:id] Nothing changed in "file1".' \
921 'warning: [subst.mk:id] Nothing changed in "file2".' \ 1065 'warning: [subst.mk:id] Nothing changed in "file2".' \
922 'fail: [subst.mk:id] The filename patterns "file1 file2" have no effect.' \ 1066 'fail: [subst.mk:id] The filename patterns "file1 file2" have no effect.' \
923 '*** Error code 1' \ 1067 '*** Error code 1' \
924 '' \ 1068 '' \
925 'Stop.' \ 1069 'Stop.' \
926 "$make: stopped in $PWD" 1070 "$make: stopped in $PWD"
927 1071
928 test_case_end 1072 test_case_end
929fi 1073fi
930 1074
931 1075
932if test_case_begin 'empty SUBST_FILES'; then 1076if test_case_begin 'empty SUBST_FILES'; then
933 1077
934 # An empty SUBST_FILES section is ok. 1078 # An empty SUBST_FILES section is ok.
935 # It may have been produced by a shell command like find(1). 1079 # It may have been produced by a shell command like find(1).
936 1080
937 create_file_lines 'testcase.mk' \ 1081 create_file_lines 'testcase.mk' \
938 'SUBST_CLASSES+= id' \ 1082 'SUBST_CLASSES+= id' \
939 'SUBST_STAGE.id= pre-configure' \ 1083 'SUBST_STAGE.id= pre-configure' \
940 'SUBST_FILES.id= # none' \ 1084 'SUBST_FILES.id= # none' \
941 'SUBST_SED.id= -e s,from,to,' \ 1085 'SUBST_SED.id= -e s,from,to,' \
942 'SUBST_NOOP_OK.id= no' \ 1086 'SUBST_NOOP_OK.id= no' \
943 '' \ 1087 '' \
944 'all:' \ 1088 'all:' \
945 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \ 1089 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \
946 '' \ 1090 '' \
947 '.include "prepare-subst.mk"' \ 1091 '.include "prepare-subst.mk"' \
948 '.include "mk/subst.mk"' 1092 '.include "mk/subst.mk"'
949 1093
950 run_bmake 'testcase.mk' 'pre-configure' 'all' 1> "$tmpdir/output" 2>&1 \ 1094 run_bmake 'testcase.mk' 'pre-configure' 'all' 1> "$tmpdir/output" 2>&1 \
951 && exitcode=0 || exitcode=$? 1095 && exitcode=0 || exitcode=$?
952 1096
953 assert_that "$tmpdir/output" --file-is-lines \ 1097 assert_that "$tmpdir/output" --file-is-lines \
954 '=> Substituting "id" in ' \ 1098 '=> Substituting "id" in ' \
955 'ok' 1099 'ok'
956 1100
957 test_case_end 1101 test_case_end
958fi 1102fi
959 1103
960 1104
961if test_case_begin 'empty SUBST_SED'; then 1105if test_case_begin 'empty SUBST_SED'; then
962 1106
963 create_file_lines 'testcase.mk' \ 1107 create_file_lines 'testcase.mk' \
964 'SUBST_CLASSES+= id' \ 1108 'SUBST_CLASSES+= id' \
965 'SUBST_STAGE.id= pre-configure' \ 1109 'SUBST_STAGE.id= pre-configure' \
966 'SUBST_FILES.id= file' \ 1110 'SUBST_FILES.id= file' \
967 'SUBST_SED.id= # none' \ 1111 'SUBST_SED.id= # none' \
968 'SUBST_NOOP_OK.id= no' \ 1112 'SUBST_NOOP_OK.id= no' \
969 '' \ 1113 '' \
970 'all:' \ 1114 'all:' \
971 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \ 1115 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \
972 '' \ 1116 '' \
973 '.include "prepare-subst.mk"' \ 1117 '.include "prepare-subst.mk"' \
974 '.include "mk/subst.mk"' 1118 '.include "mk/subst.mk"'
975 1119
976 run_bmake 'testcase.mk' 'subst-id' 'all' 1> "$tmpdir/output" 2>&1 \ 1120 run_bmake 'testcase.mk' 'subst-id' 'all' 1> "$tmpdir/output" 2>&1 \
977 && exitcode=0 || exitcode=$? 1121 && exitcode=0 || exitcode=$?
978 1122
979 assert_that "$tmpdir/output" --file-is-lines \ 1123 assert_that "$tmpdir/output" --file-is-lines \
980 '=> Substituting "id" in file' \ 1124 '=> Substituting "id" in file' \
981 'warning: [subst.mk:id] Ignoring nonexistent file "file".' \ 1125 'warning: [subst.mk:id] Ignoring nonexistent file "file".' \
982 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1126 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
983 '*** Error code 1' \ 1127 '*** Error code 1' \
984 '' \ 1128 '' \
985 'Stop.' \ 1129 'Stop.' \
986 "$make: stopped in $PWD" 1130 "$make: stopped in $PWD"
987 1131
988 test_case_end 1132 test_case_end
989fi 1133fi
990 1134
991 1135
992if test_case_begin 'typo in SUBST_CLASSES'; then 1136if test_case_begin 'typo in SUBST_CLASSES'; then
993 1137
994 # Look closely. The SUBST_CLASSES line contains a typo. 1138 # Look closely. The SUBST_CLASSES line contains a typo.
995 # subst.mk does not catch this, but pkglint does. 1139 # subst.mk does not catch this, but pkglint does.
996 1140
997 create_file_lines 'testcase.mk' \ 1141 create_file_lines 'testcase.mk' \
998 'SUBST_CLASSES=+ id' \ 1142 'SUBST_CLASSES=+ id' \
999 'SUBST_STAGE.id= pre-configure' \ 1143 'SUBST_STAGE.id= pre-configure' \
1000 'SUBST_FILES.id= file' \ 1144 'SUBST_FILES.id= file' \
1001 'SUBST_SED.id= # none' \ 1145 'SUBST_SED.id= # none' \
1002 'SUBST_NOOP_OK.id= no' \ 1146 'SUBST_NOOP_OK.id= no' \
1003 '' \ 1147 '' \
1004 'all:' \ 1148 'all:' \
1005 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \ 1149 ' @printf "%s\n" ${PKG_FAIL_REASON:Uok}' \
1006 '' \ 1150 '' \
1007 '.include "prepare-subst.mk"' \ 1151 '.include "prepare-subst.mk"' \
1008 '.include "mk/subst.mk"' 1152 '.include "mk/subst.mk"'
1009 1153
1010 run_bmake 'testcase.mk' 'pre-configure' 'all' 1> "$tmpdir/output" 2>&1 \ 1154 run_bmake 'testcase.mk' 'pre-configure' 'all' 1> "$tmpdir/output" 2>&1 \
1011 && exitcode=0 || exitcode=$? 1155 && exitcode=0 || exitcode=$?
1012 1156
1013 assert_that "$tmpdir/output" --file-is-lines \ 1157 assert_that "$tmpdir/output" --file-is-lines \
1014 '=> Substituting "id" in file' \ 1158 '=> Substituting "id" in file' \
1015 'warning: [subst.mk:id] Ignoring nonexistent file "file".' \ 1159 'warning: [subst.mk:id] Ignoring nonexistent file "file".' \
1016 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1160 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
1017 '*** Error code 1' \ 1161 '*** Error code 1' \
1018 '' \ 1162 '' \
1019 'Stop.' \ 1163 'Stop.' \
1020 "$make: stopped in $PWD" 1164 "$make: stopped in $PWD"
1021 1165
1022 test_case_end 1166 test_case_end
1023fi 1167fi
1024 1168
1025 1169
1026if test_case_begin 'executable bit is preserved'; then 1170if test_case_begin 'executable bit is preserved'; then
1027 1171
1028 create_file_lines 'testcase.mk' \ 1172 create_file_lines 'testcase.mk' \
1029 'SUBST_CLASSES+= id' \ 1173 'SUBST_CLASSES+= id' \
1030 'SUBST_STAGE.id= pre-configure' \ 1174 'SUBST_STAGE.id= pre-configure' \
1031 'SUBST_FILES.id= cmd data' \ 1175 'SUBST_FILES.id= cmd data' \
1032 'SUBST_VARS.id= VAR' \ 1176 'SUBST_VARS.id= VAR' \
1033 'VAR= replaced' \ 1177 'VAR= replaced' \
1034 '' \ 1178 '' \
1035 '.include "prepare-subst.mk"' \ 1179 '.include "prepare-subst.mk"' \
1036 '.include "mk/subst.mk"' 1180 '.include "mk/subst.mk"'
1037 create_file_lines 'cmd' \ 1181 create_file_lines 'cmd' \
1038 '@VAR@' 1182 '@VAR@'
1039 create_file_lines 'data' \ 1183 create_file_lines 'data' \
1040 '@VAR@' 1184 '@VAR@'
1041 chmod +x 'cmd' 1185 chmod +x 'cmd'
1042 1186
1043 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 1187 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
1044 && exitcode=0 || exitcode=$? 1188 && exitcode=0 || exitcode=$?
1045 1189
1046 assert_that "$tmpdir/output" --file-is-lines \ 1190 assert_that "$tmpdir/output" --file-is-lines \
1047 '=> Substituting "id" in cmd data' 1191 '=> Substituting "id" in cmd data'
1048 assert_that 'cmd' --file-is-lines 'replaced' 1192 assert_that 'cmd' --file-is-lines 'replaced'
1049 assert_that 'data' --file-is-lines 'replaced' 1193 assert_that 'data' --file-is-lines 'replaced'
1050 [ -x 'cmd' ] \ 1194 [ -x 'cmd' ] \
1051 || assert_fail 'cmd must still be executable\n' 1195 || assert_fail 'cmd must still be executable\n'
1052 [ -x 'data' ] \ 1196 [ -x 'data' ] \
1053 && assert_fail 'data must not be executable\n' 1197 && assert_fail 'data must not be executable\n'
1054 1198
1055 test_case_end 1199 test_case_end
1056fi 1200fi
1057 1201
1058 1202
1059if test_case_begin 'unreadable file'; then 1203if test_case_begin 'unreadable file'; then
1060 1204
1061 create_file_lines 'testcase.mk' \ 1205 create_file_lines 'testcase.mk' \
1062 'SUBST_CLASSES+= id' \ 1206 'SUBST_CLASSES+= id' \
1063 'SUBST_STAGE.id= pre-configure' \ 1207 'SUBST_STAGE.id= pre-configure' \
1064 'SUBST_FILES.id= unreadable-file' \ 1208 'SUBST_FILES.id= unreadable-file' \
1065 'SUBST_SED.id= -e s,before,after,' \ 1209 'SUBST_SED.id= -e s,before,after,' \
1066 '' \ 1210 '' \
1067 '.include "prepare-subst.mk"' \ 1211 '.include "prepare-subst.mk"' \
1068 '.include "mk/subst.mk"' 1212 '.include "mk/subst.mk"'
1069 create_file_lines 'unreadable-file' \ 1213 create_file_lines 'unreadable-file' \
1070 'before' 1214 'before'
1071 chmod 0000 'unreadable-file' 1215 chmod 0000 'unreadable-file'
1072 1216
1073 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \ 1217 run_bmake 'testcase.mk' 'pre-configure' 1> "$tmpdir/output" 2>&1 \
1074 && exitcode=0 || exitcode=$? 1218 && exitcode=0 || exitcode=$?
1075 1219
1076 assert_that "$tmpdir/output" --file-is-lines \ 1220 assert_that "$tmpdir/output" --file-is-lines \
1077 '=> Substituting "id" in unreadable-file' \ 1221 '=> Substituting "id" in unreadable-file' \
1078 'sh: cannot open unreadable-file: permission denied' \ 1222 'sh: cannot open unreadable-file: permission denied' \
1079 'sh: cannot open unreadable-file: permission denied' \ 1223 'sh: cannot open unreadable-file: permission denied' \
1080 '*** Error code 1' \ 1224 '*** Error code 1' \
1081 '' \ 1225 '' \
1082 'Stop.' \ 1226 'Stop.' \
1083 "$make: stopped in $PWD" 1227 "$make: stopped in $PWD"
1084 1228
1085 test_case_end 1229 test_case_end
1086fi 1230fi
1087 1231
1088 1232
1089if test_case_begin 'identity substitution implementation'; then 1233if test_case_begin 'identity substitution implementation'; then
1090 1234
1091 assert_identity() { 1235 assert_identity() {
1092 _ai_expected="$1"; shift 1236 _ai_expected="$1"; shift
1093 awk -f "$pkgsrcdir/mk/scripts/subst-identity.awk" -- ${1+"$@"} \ 1237 awk -f "$pkgsrcdir/mk/scripts/subst-identity.awk" -- ${1+"$@"} \
1094 && _ai_actual='yes' || _ai_actual='no' 1238 && _ai_actual='yes' || _ai_actual='no'
1095 1239
1096 [ "$_ai_actual" = "$_ai_expected" ] \ 1240 [ "$_ai_actual" = "$_ai_expected" ] \
1097 || assert_fail 'expected "%s", got "%s" for %s\n' "$_ai_expected" "$_ai_actual" "$*" 1241 || assert_fail 'expected "%s", got "%s" for %s\n' "$_ai_expected" "$_ai_actual" "$*"
1098 } 1242 }
1099 1243
1100 # If there is no SUBST_SED at all, this is not the situation 1244 # If there is no SUBST_SED at all, this is not the situation
1101 # that is targeted by this test for identity substitution. 1245 # that is targeted by this test for identity substitution.
1102 assert_identity 'no' # no substitutions at all 1246 assert_identity 'no' # no substitutions at all
1103 1247
1104 # Even though this is an identity substitution, it is missing 1248 # Even though this is an identity substitution, it is missing
1105 # the -e option and thus does not follow the usual format. 1249 # the -e option and thus does not follow the usual format.
1106 # Therefore it is considered just a normal substitution. 1250 # Therefore it is considered just a normal substitution.
1107 assert_identity 'no' 's,from,from,' 1251 assert_identity 'no' 's,from,from,'
1108 1252
1109 # The following are typical identity substitutions. 1253 # The following are typical identity substitutions.
1110 # It does not matter whether the g modifier is there or not. 1254 # It does not matter whether the g modifier is there or not.
1111 # Unknown modifiers are not allowed though. 1255 # Unknown modifiers are not allowed though.
1112 assert_identity 'yes' -e 's,from,from,' 1256 assert_identity 'yes' -e 's,from,from,'
1113 assert_identity 'yes' -e 's;from;from;' 1257 assert_identity 'yes' -e 's;from;from;'
1114 assert_identity 'yes' -e 's,from,from,g' 1258 assert_identity 'yes' -e 's,from,from,g'
1115 assert_identity 'no' -e 's,from,from,gunknown' 1259 assert_identity 'no' -e 's,from,from,gunknown'
1116 1260
1117 # The identity substitution may include characters other than 1261 # The identity substitution may include characters other than
1118 # A-Za-z0-9, but no characters that have a special meaning in 1262 # A-Za-z0-9, but no characters that have a special meaning in
1119 # basic regular expressions. 1263 # basic regular expressions.
1120 assert_identity 'yes' -e 's,/dev/audio,/dev/audio,' 1264 assert_identity 'yes' -e 's,/dev/audio,/dev/audio,'
1121 assert_identity 'yes' -e 's!/dev/audio!/dev/audio!' 1265 assert_identity 'yes' -e 's!/dev/audio!/dev/audio!'
1122 1266
1123 # There may be several identity substitutions in the same 1267 # There may be several identity substitutions in the same
1124 # SUBST_SED. As long as all these substitutions are identity 1268 # SUBST_SED. As long as all these substitutions are identity
1125 # substitutions, they may be skipped. As soon as there is one 1269 # substitutions, they may be skipped. As soon as there is one
1126 # other substitution, the whole SUBST_SED is treated as usual. 1270 # other substitution, the whole SUBST_SED is treated as usual.
1127 assert_identity 'yes' -e 's;from;from;' -e 's!second!second!' 1271 assert_identity 'yes' -e 's;from;from;' -e 's!second!second!'
1128 assert_identity 'no' -e 's,changing,x,' -e 's,id,id,' 1272 assert_identity 'no' -e 's,changing,x,' -e 's,id,id,'
1129 assert_identity 'no' -e 's,id,id,' -e 's,changing,x,' 1273 assert_identity 'no' -e 's,id,id,' -e 's,changing,x,'
1130 1274
1131 # A demonstration of all ASCII characters that may appear in an 1275 # A demonstration of all ASCII characters that may appear in an
1132 # identity substitution. 1276 # identity substitution.
1133 # 1277 #
1134 # The # and $ are excluded since they are interpreted specially 1278 # The # and $ are excluded since they are interpreted specially
1135 # in Makefiles and would thus be confusing to the human reader. 1279 # in Makefiles and would thus be confusing to the human reader.
1136 # 1280 #
1137 # The characters *.?[\]^ have a special meaning in the pattern of the 1281 # The characters *.?[\]^ have a special meaning in the pattern of the
1138 # substitution. 1282 # substitution.
1139 # The & has a special meaning in the replacement of the 1283 # The & has a special meaning in the replacement of the
1140 # substitution. 1284 # substitution.
1141 specials='!"%'\''()+,-/:;<=>@_`{|}~' 1285 specials='!"%'\''()+,-/:;<=>@_`{|}~'
1142 assert_identity 'yes' -e "sX${specials}X${specials}X" 1286 assert_identity 'yes' -e "sX${specials}X${specials}X"
1143 1287
1144 # Regular expression meta-characters may be escaped using a 1288 # Regular expression meta-characters may be escaped using a
1145 # backslash or be enclosed in square brackets. 1289 # backslash or be enclosed in square brackets.
1146 assert_identity 'yes' -e 's,library\.so,library.so,g' 1290 assert_identity 'yes' -e 's,library\.so,library.so,g'
1147 assert_identity 'yes' -e 's,library[.]so,library.so,g' 1291 assert_identity 'yes' -e 's,library[.]so,library.so,g'
1148 assert_identity 'yes' -e 's,[*],*,' 1292 assert_identity 'yes' -e 's,[*],*,'
1149 assert_identity 'yes' -e 's,[$],$,' 1293 assert_identity 'yes' -e 's,[$],$,'
1150 1294
1151 # When this happens, it is probably a mistake. 1295 # When this happens, it is probably a mistake.
1152 assert_identity 'no' -e 's,,,' 1296 assert_identity 'no' -e 's,,,'
1153 1297
1154 # Backslashes are not considered identity substitutions since 1298 # Backslashes are not considered identity substitutions since
1155 # there might be tricky corner cases. 1299 # there might be tricky corner cases.
1156 assert_identity 'no' -e 's,\\,\\,' 1300 assert_identity 'no' -e 's,\\,\\,'
1157 1301
1158 # Back-references are not considered identity substitutions. 1302 # Back-references are not considered identity substitutions.
1159 assert_identity 'no' -e 's,\1,\1,' 1303 assert_identity 'no' -e 's,\1,\1,'
1160 1304
1161 # The & is interpreted specially in the replacement string. 1305 # The & is interpreted specially in the replacement string.
1162 assert_identity 'no' -e 's,&&&,&&&,' 1306 assert_identity 'no' -e 's,&&&,&&&,'
1163 assert_identity 'no' -e 's,\&,&,' 1307 assert_identity 'no' -e 's,\&,&,'
1164 assert_identity 'no' -e 's,[&],&,' 1308 assert_identity 'no' -e 's,[&],&,'
1165 assert_identity 'no' -e 's,&,\&,' # this would be an identity 1309 assert_identity 'no' -e 's,&,\&,' # this would be an identity
1166 1310
1167 # References to Makefile variables can be identical too. 1311 # References to Makefile variables can be identical too.
1168 # See converters/help2man for an example. 1312 # See converters/help2man for an example.
1169 assert_identity 'yes' -e 's,\$(var),$(var),' 1313 assert_identity 'yes' -e 's,\$(var),$(var),'
1170 1314
1171 # POSIX 2004 and 2018 both define in section "9.3.8 BRE Expression 1315 # POSIX 2004 and 2018 both define in section "9.3.8 BRE Expression
1172 # Anchoring" that a dollar-sign at the end of the string means 1316 # Anchoring" that a dollar-sign at the end of the string means
1173 # end-of-string. 1317 # end-of-string.
1174 # 1318 #
1175 # A dollar-sign followed by \) may or may not be an anchor. 1319 # A dollar-sign followed by \) may or may not be an anchor.
1176 # In all other cases the dollar is an ordinary character. 1320 # In all other cases the dollar is an ordinary character.
1177 assert_identity 'yes' -e 's,$(var),$(var),' 1321 assert_identity 'yes' -e 's,$(var),$(var),'
1178 1322
1179 # Since this dollar-sign may or may not be an anchor, treat the 1323 # Since this dollar-sign may or may not be an anchor, treat the
1180 # whole regular expression as not-an-identity. 1324 # whole regular expression as not-an-identity.
1181 # 1325 #
1182 # Since a regular expression with a subexpression must contain 1326 # Since a regular expression with a subexpression must contain
1183 # \( and \), it does not count as an identity substitution anyway, 1327 # \( and \), it does not count as an identity substitution anyway,
1184 # which makes the implementation simple. 1328 # which makes the implementation simple.
1185 assert_identity 'no' -e 's,aaa\(aaa$\),aaa\(aaa$\),' 1329 assert_identity 'no' -e 's,aaa\(aaa$\),aaa\(aaa$\),'
1186 1330
1187 assert_identity 'yes' -e 's,$a,$a,' 1331 assert_identity 'yes' -e 's,$a,$a,'
1188 assert_identity 'no' -e 's,a$,a$,' 1332 assert_identity 'no' -e 's,a$,a$,'
1189 1333
1190 # Same for the circumflex. 1334 # Same for the circumflex.
1191 assert_identity 'yes' -e 's,a^,a^,' 1335 assert_identity 'yes' -e 's,a^,a^,'
1192 assert_identity 'no' -e 's,^a,^a,' 1336 assert_identity 'no' -e 's,^a,^a,'
1193 assert_identity 'no' -e 's,\(^aaa\)aaa,\(^aaa\)aaa,' 1337 assert_identity 'no' -e 's,\(^aaa\)aaa,\(^aaa\)aaa,'
1194 1338
1195 # Seen in games/bastet before 2020-05-16. 1339 # Seen in games/bastet before 2020-05-16.
1196 assert_identity 'yes' -e 's,a,a,1' 1340 assert_identity 'yes' -e 's,a,a,1'
1197 1341
1198 test_case_end 1342 test_case_end
1199fi 1343fi
1200 1344
1201 1345
1202if test_case_begin 'identity substitution, found in file'; then 1346if test_case_begin 'identity substitution, found in file'; then
1203 1347
1204 # There are many situations in which a fixed text is replaced 1348 # There are many situations in which a fixed text is replaced
1205 # with a dynamic value that may or may not be equal to the 1349 # with a dynamic value that may or may not be equal to the
1206 # original text. 1350 # original text.
1207 # 1351 #
1208 # Typical examples are s|man|${PKGMANDIR}|, s|/usr/pkg|${PREFIX}|, 1352 # Typical examples are s|man|${PKGMANDIR}|, s|/usr/pkg|${PREFIX}|,
1209 # s|/dev/audio|${DEVOSSAUDIO}|. 1353 # s|/dev/audio|${DEVOSSAUDIO}|.
1210 # 1354 #
1211 # It is not an error if these substitutions result in a no-op, 1355 # It is not an error if these substitutions result in a no-op,
1212 # provided that the text is actually found in the file. 1356 # provided that the text is actually found in the file.
1213 # 1357 #
1214 # Alternatives for this special exception would be: 1358 # Alternatives for this special exception would be:
1215 # 1359 #
1216 # 1. Mark these blocks as SUBST_NOOP_OK. This would not detect 1360 # 1. Mark these blocks as SUBST_NOOP_OK. This would not detect
1217 # outdated definitions. Since this detection is the main goal 1361 # outdated definitions. Since this detection is the main goal
1218 # of SUBST_NOOP_OK, this is out of the question. 1362 # of SUBST_NOOP_OK, this is out of the question.
1219 # 1363 #
1220 # 2. Surround these blocks with a condition like ".if ${VAR} != 1364 # 2. Surround these blocks with a condition like ".if ${VAR} !=
1221 # fixed-value ... .endif". This pattern only works if VAR is 1365 # fixed-value ... .endif". This pattern only works if VAR is
1222 # definitely assigned, which often requires a corresponding 1366 # definitely assigned, which often requires a corresponding
1223 # .include line, leading to code bloat. It would also mean that 1367 # .include line, leading to code bloat. It would also mean that
1224 # variables defined in bsd.pkg.mk could not be used in SUBST 1368 # variables defined in bsd.pkg.mk could not be used in SUBST
1225 # blocks like these. 1369 # blocks like these.
1226 1370
1227 create_file_lines 'testcase.mk' \ 1371 create_file_lines 'testcase.mk' \
1228 'SUBST_CLASSES+= id' \ 1372 'SUBST_CLASSES+= id' \
1229 'SUBST_FILES.id= file' \ 1373 'SUBST_FILES.id= file' \
1230 'SUBST_SED.id= -e s,before,before,' \ 1374 'SUBST_SED.id= -e s,before,before,' \
1231 'SUBST_SED.id+= -e "s,before,before,"' \ 1375 'SUBST_SED.id+= -e "s,before,before,"' \
1232 "SUBST_SED.id+= -e 's,before,before,'" \ 1376 "SUBST_SED.id+= -e 's,before,before,'" \
1233 'SUBST_NOOP_OK.id= no' \ 1377 'SUBST_NOOP_OK.id= no' \
1234 '' \ 1378 '' \
1235 '.include "prepare-subst.mk"' \ 1379 '.include "prepare-subst.mk"' \
1236 '.include "mk/subst.mk"' 1380 '.include "mk/subst.mk"'
1237 create_file_lines 'file' \ 1381 create_file_lines 'file' \
1238 'before' 1382 'before'
1239 1383
1240 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1384 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1241 && exitcode=0 || exitcode=$? 1385 && exitcode=0 || exitcode=$?
1242 1386
1243 assert_that "$tmpdir/output" --file-is-lines \ 1387 assert_that "$tmpdir/output" --file-is-lines \
1244 '=> Substituting "id" in file' 1388 '=> Substituting "id" in file'
1245 1389
1246 test_case_end 1390 test_case_end
1247fi 1391fi
1248 1392
1249 1393
1250if test_case_begin 'identity substitution, not found in file'; then 1394if test_case_begin 'identity substitution, not found in file'; then
1251 1395
1252 create_file_lines 'testcase.mk' \ 1396 create_file_lines 'testcase.mk' \
1253 'SUBST_CLASSES+= id' \ 1397 'SUBST_CLASSES+= id' \
1254 'SUBST_FILES.id= file' \ 1398 'SUBST_FILES.id= file' \
1255 'SUBST_SED.id= s,before,before,' \ 1399 'SUBST_SED.id= s,before,before,' \
1256 'SUBST_NOOP_OK.id= no' \ 1400 'SUBST_NOOP_OK.id= no' \
1257 '' \ 1401 '' \
1258 '.include "prepare-subst.mk"' \ 1402 '.include "prepare-subst.mk"' \
1259 '.include "mk/subst.mk"' 1403 '.include "mk/subst.mk"'
1260 create_file_lines 'file' \ 1404 create_file_lines 'file' \
1261 'other' 1405 'other'
1262 1406
1263 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1407 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1264 && exitcode=0 || exitcode=$? 1408 && exitcode=0 || exitcode=$?
1265 1409
1266 assert_that "$tmpdir/output" --file-is-lines \ 1410 assert_that "$tmpdir/output" --file-is-lines \
1267 '=> Substituting "id" in file' \ 1411 '=> Substituting "id" in file' \
1268 'warning: [subst.mk:id] Nothing changed in "file".' \ 1412 'warning: [subst.mk:id] Nothing changed in "file".' \
1269 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1413 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
1270 '*** Error code 1' \ 1414 '*** Error code 1' \
1271 '' \ 1415 '' \
1272 'Stop.' \ 1416 'Stop.' \
1273 "$make: stopped in $PWD" 1417 "$make: stopped in $PWD"
1274 1418
1275 test_case_end 1419 test_case_end
1276fi 1420fi
1277 1421
1278 1422
1279if test_case_begin 'identity + effective substitution'; then 1423if test_case_begin 'identity + effective substitution'; then
1280 1424
1281 create_file_lines 'testcase.mk' \ 1425 create_file_lines 'testcase.mk' \
1282 'SUBST_CLASSES+= id' \ 1426 'SUBST_CLASSES+= id' \
1283 'SUBST_FILES.id= file' \ 1427 'SUBST_FILES.id= file' \
1284 'SUBST_SED.id= -e s,no-op,no-op,g' \ 1428 'SUBST_SED.id= -e s,no-op,no-op,g' \
1285 'SUBST_SED.id+= -e s,from,to,' \ 1429 'SUBST_SED.id+= -e s,from,to,' \
1286 'SUBST_NOOP_OK.id= no' \ 1430 'SUBST_NOOP_OK.id= no' \
1287 '' \ 1431 '' \
1288 '.include "prepare-subst.mk"' \ 1432 '.include "prepare-subst.mk"' \
1289 '.include "mk/subst.mk"' 1433 '.include "mk/subst.mk"'
1290 create_file_lines 'file' \ 1434 create_file_lines 'file' \
1291 'from' 1435 'from'
1292 1436
1293 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1437 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1294 && exitcode=0 || exitcode=$? 1438 && exitcode=0 || exitcode=$?
1295 1439
1296 assert_that "$tmpdir/output" --file-is-lines \ 1440 assert_that "$tmpdir/output" --file-is-lines \
1297 '=> Substituting "id" in file' 1441 '=> Substituting "id" in file'
1298 assert_that 'file' --file-is-lines \ 1442 assert_that 'file' --file-is-lines \
1299 'to' 1443 'to'
1300 1444
1301 test_case_end 1445 test_case_end
1302fi 1446fi
1303 1447
1304 1448
1305if test_case_begin 'identity + no-op substitution'; then 1449if test_case_begin 'identity + no-op substitution'; then
1306 1450
1307 # If there were only an identity substitution, it wouldn't be an 1451 # If there were only an identity substitution, it wouldn't be an
1308 # error. But since there is a regular substitution as well, 1452 # error. But since there is a regular substitution as well,
1309 # that substitution is an unexpected no-op and is therefore 1453 # that substitution is an unexpected no-op and is therefore
1310 # flagged as an error. 1454 # flagged as an error.
1311 1455
1312 create_file_lines 'testcase.mk' \ 1456 create_file_lines 'testcase.mk' \
1313 'SUBST_CLASSES+= id' \ 1457 'SUBST_CLASSES+= id' \
1314 'SUBST_FILES.id= file' \ 1458 'SUBST_FILES.id= file' \
1315 'SUBST_SED.id= -e s,no-op,no-op,g' \ 1459 'SUBST_SED.id= -e s,no-op,no-op,g' \
1316 'SUBST_SED.id+= -e s,from,to,' \ 1460 'SUBST_SED.id+= -e s,from,to,' \
1317 'SUBST_NOOP_OK.id= no' \ 1461 'SUBST_NOOP_OK.id= no' \
1318 '' \ 1462 '' \
1319 '.include "prepare-subst.mk"' \ 1463 '.include "prepare-subst.mk"' \
1320 '.include "mk/subst.mk"' 1464 '.include "mk/subst.mk"'
1321 create_file_lines 'file' \ 1465 create_file_lines 'file' \
1322 'other' 1466 'other'
1323 1467
1324 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1468 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1325 && exitcode=0 || exitcode=$? 1469 && exitcode=0 || exitcode=$?
1326 1470
1327 assert_that "$tmpdir/output" --file-is-lines \ 1471 assert_that "$tmpdir/output" --file-is-lines \
1328 '=> Substituting "id" in file' \ 1472 '=> Substituting "id" in file' \
1329 'warning: [subst.mk:id] Nothing changed in "file".' \ 1473 'warning: [subst.mk:id] Nothing changed in "file".' \
1330 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1474 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
1331 '*** Error code 1' \ 1475 '*** Error code 1' \
1332 '' \ 1476 '' \
1333 'Stop.' \ 1477 'Stop.' \
1334 "$make: stopped in $PWD" 1478 "$make: stopped in $PWD"
1335 assert_that 'file' --file-is-lines \ 1479 assert_that 'file' --file-is-lines \
1336 'other' 1480 'other'
1337 1481
1338 test_case_end 1482 test_case_end
1339fi 1483fi
1340 1484
1341 1485
1342if test_case_begin 'SUBST_FILTER_CMD + SUBST_SED in NOOP_OK=no mode'; then 1486if test_case_begin 'SUBST_FILTER_CMD + SUBST_SED in NOOP_OK=no mode'; then
1343 1487
1344 # If SUBST_FILTER_CMD is defined for a SUBST class, the 1488 # If SUBST_FILTER_CMD is defined for a SUBST class, the
1345 # corresponding SUBST_SED and SUBST_VARS are ignored. To avoid 1489 # corresponding SUBST_SED and SUBST_VARS are ignored. To avoid
1346 # redundant variable definitions, this case fails fast. 1490 # redundant variable definitions, this case fails fast.
1347 1491
1348 create_file_lines 'testcase.mk' \ 1492 create_file_lines 'testcase.mk' \
1349 'SUBST_CLASSES+= id' \ 1493 'SUBST_CLASSES+= id' \
1350 'SUBST_FILES.id= file' \ 1494 'SUBST_FILES.id= file' \
1351 'SUBST_FILTER_CMD.id= tr -d "0-9"' \ 1495 'SUBST_FILTER_CMD.id= tr -d "0-9"' \
1352 'SUBST_SED.id= -e s,x,x,' \ 1496 'SUBST_SED.id= -e s,x,x,' \
1353 'SUBST_NOOP_OK.id= no' \ 1497 'SUBST_NOOP_OK.id= no' \
1354 '' \ 1498 '' \
1355 '.include "prepare-subst.mk"' \ 1499 '.include "prepare-subst.mk"' \
1356 '.include "mk/subst.mk"' 1500 '.include "mk/subst.mk"'
1357 create_file_lines 'file' \ 1501 create_file_lines 'file' \
1358 'letters 123 letters' 1502 'letters 123 letters'
1359 create_file_lines "$tmpdir/main.mk" \ 1503 create_file_lines "$tmpdir/main.mk" \
1360 "PKGSRCDIR= $pkgsrcdir" \ 1504 "PKGSRCDIR= $pkgsrcdir" \
1361 ".PATH: $mocked_pkgsrcdir" \ 1505 ".PATH: $mocked_pkgsrcdir" \
1362 ".PATH: $pkgsrcdir" \ 1506 ".PATH: $pkgsrcdir" \
1363 '.include "testcase.mk"' \ 1507 '.include "testcase.mk"' \
1364 '' \ 1508 '' \
1365 'all: subst-id' \ 1509 'all: subst-id' \
1366 ' @printf '\''fail reason: %s\n'\'' ${PKG_FAIL_REASON} 1>&2' 1510 ' @printf '\''fail reason: %s\n'\'' ${PKG_FAIL_REASON} 1>&2'
1367 1511
1368 "$make" -f "$tmpdir/main.mk" 'all' 1> "$tmpdir/output" 2>&1 \ 1512 "$make" -f "$tmpdir/main.mk" 'all' 1> "$tmpdir/output" 2>&1 \
1369 && exitcode=0 || exitcode=$? 1513 && exitcode=0 || exitcode=$?
1370 1514
1371 assert_that "$tmpdir/output" --file-is-lines \ 1515 assert_that "$tmpdir/output" --file-is-lines \
1372 '=> Substituting "id" in file' \ 1516 '=> Substituting "id" in file' \
1373 'fail reason: [subst.mk:id] SUBST_FILTER_CMD and SUBST_SED/SUBST_VARS cannot be combined.' 1517 'fail reason: [subst.mk:id] SUBST_FILTER_CMD and SUBST_SED/SUBST_VARS cannot be combined.'
1374 assert_that 'file' --file-is-lines \ 1518 assert_that 'file' --file-is-lines \
1375 'letters letters' 1519 'letters letters'
1376 1520
1377 test_case_end 1521 test_case_end
1378fi 1522fi
1379 1523
1380 1524
1381if test_case_begin 'effective SUBST_FILTER_CMD in NOOP_OK=no mode'; then 1525if test_case_begin 'effective SUBST_FILTER_CMD in NOOP_OK=no mode'; then
1382 1526
1383 create_file_lines 'testcase.mk' \ 1527 create_file_lines 'testcase.mk' \
1384 'SUBST_CLASSES+= id' \ 1528 'SUBST_CLASSES+= id' \
1385 'SUBST_FILES.id= file' \ 1529 'SUBST_FILES.id= file' \
1386 'SUBST_FILTER_CMD.id= tr -d "0-9"' \ 1530 'SUBST_FILTER_CMD.id= tr -d "0-9"' \
1387 'SUBST_NOOP_OK.id= no' \ 1531 'SUBST_NOOP_OK.id= no' \
1388 '' \ 1532 '' \
1389 '.include "prepare-subst.mk"' \ 1533 '.include "prepare-subst.mk"' \
1390 '.include "mk/subst.mk"' 1534 '.include "mk/subst.mk"'
1391 create_file_lines 'file' \ 1535 create_file_lines 'file' \
1392 'letters 123 letters' 1536 'letters 123 letters'
1393 1537
1394 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1538 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1395 && exitcode=0 || exitcode=$? 1539 && exitcode=0 || exitcode=$?
1396 1540
1397 assert_that "$tmpdir/output" --file-is-lines \ 1541 assert_that "$tmpdir/output" --file-is-lines \
1398 '=> Substituting "id" in file' 1542 '=> Substituting "id" in file'
1399 assert_that 'file' --file-is-lines \ 1543 assert_that 'file' --file-is-lines \
1400 'letters letters' 1544 'letters letters'
1401 1545
1402 test_case_end 1546 test_case_end
1403fi 1547fi
1404 1548
1405 1549
1406if test_case_begin 'no-op SUBST_FILTER_CMD in NOOP_OK=no mode'; then 1550if test_case_begin 'no-op SUBST_FILTER_CMD in NOOP_OK=no mode'; then
1407 1551
1408 create_file_lines 'testcase.mk' \ 1552 create_file_lines 'testcase.mk' \
1409 'SUBST_CLASSES+= id' \ 1553 'SUBST_CLASSES+= id' \
1410 'SUBST_FILES.id= file' \ 1554 'SUBST_FILES.id= file' \
1411 'SUBST_FILTER_CMD.id= tr -d "0-9"' \ 1555 'SUBST_FILTER_CMD.id= tr -d "0-9"' \
1412 'SUBST_NOOP_OK.id= no' \ 1556 'SUBST_NOOP_OK.id= no' \
1413 '' \ 1557 '' \
1414 '.include "prepare-subst.mk"' \ 1558 '.include "prepare-subst.mk"' \
1415 '.include "mk/subst.mk"' 1559 '.include "mk/subst.mk"'
1416 create_file_lines 'file' \ 1560 create_file_lines 'file' \
1417 'only letters' 1561 'only letters'
1418 1562
1419 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1563 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1420 && exitcode=0 || exitcode=$? 1564 && exitcode=0 || exitcode=$?
1421 1565
1422 assert_that "$tmpdir/output" --file-is-lines \ 1566 assert_that "$tmpdir/output" --file-is-lines \
1423 '=> Substituting "id" in file' \ 1567 '=> Substituting "id" in file' \
1424 'warning: [subst.mk:id] Nothing changed in "file".' \ 1568 'warning: [subst.mk:id] Nothing changed in "file".' \
1425 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1569 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
1426 '*** Error code 1' \ 1570 '*** Error code 1' \
1427 '' \ 1571 '' \
1428 'Stop.' \ 1572 'Stop.' \
1429 "$make: stopped in $PWD" 1573 "$make: stopped in $PWD"
1430 1574
1431 assert_that 'file' --file-is-lines \ 1575 assert_that 'file' --file-is-lines \
1432 'only letters' 1576 'only letters'
1433 1577
1434 test_case_end 1578 test_case_end
1435fi 1579fi
1436 1580
1437 1581
1438if test_case_begin 'backtick in SUBST_SED'; then 1582if test_case_begin 'backtick in SUBST_SED'; then
1439 1583
1440 create_file_lines 'testcase.mk' \ 1584 create_file_lines 'testcase.mk' \
1441 'SUBST_CLASSES+= id' \ 1585 'SUBST_CLASSES+= id' \
1442 'SUBST_FILES.id= file' \ 1586 'SUBST_FILES.id= file' \
1443 "SUBST_SED.id= -e 's,\"\\\\\`,\"\\\\\`,'" \ 1587 "SUBST_SED.id= -e 's,\"\\\\\`,\"\\\\\`,'" \
 1588 'SUBST_NOOP_OK.id= yes' \
1444 '' \ 1589 '' \
1445 '.include "prepare-subst.mk"' \ 1590 '.include "prepare-subst.mk"' \
1446 '.include "mk/subst.mk"' 1591 '.include "mk/subst.mk"'
1447 create_file_lines 'file' \ 1592 create_file_lines 'file' \
1448 'from`' 1593 'from`'
1449 1594
1450 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1595 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1451 && exitcode=0 || exitcode=$? 1596 && exitcode=0 || exitcode=$?
1452 1597
1453 assert_that "$tmpdir/output" --file-is-lines \ 1598 assert_that "$tmpdir/output" --file-is-lines \
1454 '=> Substituting "id" in file' \ 1599 '=> Substituting "id" in file' \
1455 'info: [subst.mk:id] Nothing changed in "file".' 1600 'info: [subst.mk:id] Nothing changed in "file".'
1456 1601
1457 test_case_end 1602 test_case_end
1458fi 1603fi
1459 1604
1460 1605
1461if test_case_begin 'multiple sed commands with semicolon'; then 1606if test_case_begin 'multiple sed commands with semicolon'; then
1462 1607
1463 # From PR pkg/55226: 1608 # From PR pkg/55226:
1464 # ===> Configuring for perl-5.30.2 1609 # ===> Configuring for perl-5.30.2
1465 # sh: 1: Syntax error: Word "/d"p" unexpected (expecting ")") 1610 # sh: 1: Syntax error: Word "/d"p" unexpected (expecting ")")
1466 1611
1467 create_file_lines 'testcase.mk' \ 1612 create_file_lines 'testcase.mk' \
1468 'SUBST_CLASSES+= id' \ 1613 'SUBST_CLASSES+= id' \
1469 'SUBST_FILES.id= file' \ 1614 'SUBST_FILES.id= file' \
1470 'SUBST_SED.id= -e "s/755/755/g;/umask(/d"' \ 1615 'SUBST_SED.id= -e "s/755/755/g;/umask(/d"' \
1471 'SUBST_NOOP_OK.id= no' \ 1616 'SUBST_NOOP_OK.id= no' \
1472 '' \ 1617 '' \
1473 '.include "prepare-subst.mk"' \ 1618 '.include "prepare-subst.mk"' \
1474 '.include "mk/subst.mk"' 1619 '.include "mk/subst.mk"'
1475 create_file_lines 'file' \ 1620 create_file_lines 'file' \
1476 '$mode = 755;' 1621 '$mode = 755;'
1477 1622
1478 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \ 1623 run_bmake 'testcase.mk' 'subst-id' 1> "$tmpdir/output" 2>&1 \
1479 && exitcode=0 || exitcode=$? 1624 && exitcode=0 || exitcode=$?
1480 1625
1481 assert_that "$tmpdir/output" --file-is-lines \ 1626 assert_that "$tmpdir/output" --file-is-lines \
1482 '=> Substituting "id" in file' \ 1627 '=> Substituting "id" in file' \
1483 'warning: [subst.mk:id] Nothing changed in "file".' \ 1628 'warning: [subst.mk:id] Nothing changed in "file".' \
1484 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \ 1629 'fail: [subst.mk:id] The filename pattern "file" has no effect.' \
1485 '*** Error code 1' \ 1630 '*** Error code 1' \
1486 '' \ 1631 '' \
1487 'Stop.' \ 1632 'Stop.' \
1488 "$make: stopped in $PWD" 1633 "$make: stopped in $PWD"
1489 1634
1490 test_case_end 1635 test_case_end
1491fi 1636fi