Fri Mar 20 16:39:03 2020 UTC ()
show-all: fix output for list variables containing dollar characters

Before, variables containing dollar characters displayed so wrong that it
was hard to explain.

To fix the problem, I typed almost random characters into the code until
the output was exactly as expected. I still do not understand:

* why the list variables need 8 dollars to survive the @x@ loop,
* why the code only works if the dollars come from an external variable
  instead of being written inline,
* why the backslash in the :C modifier needs to be doubled.

Anyway, the output of "bmake show-all-extract" now contains the shell
variable $${extract_file}, just as it should. The dollars are now doubled
in the output and thereby match the source code from the Makefile
exactly.


(rillig)
diff -r1.18 -r1.19 pkgsrc/mk/misc/show.mk
diff -r1.4 -r1.5 pkgsrc/regress/show-all/Makefile
diff -r1.3 -r1.4 pkgsrc/regress/show-all/spec

cvs diff -r1.18 -r1.19 pkgsrc/mk/misc/show.mk (expand / switch to unified diff)

--- pkgsrc/mk/misc/show.mk 2019/09/08 09:01:04 1.18
+++ pkgsrc/mk/misc/show.mk 2020/03/20 16:39:03 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: show.mk,v 1.18 2019/09/08 09:01:04 rillig Exp $ 1# $NetBSD: show.mk,v 1.19 2020/03/20 16:39:03 rillig Exp $
2# 2#
3# This file contains some targets that print information gathered from 3# This file contains some targets that print information gathered from
4# variables. They do not modify any variables. 4# variables. They do not modify any variables.
5# 5#
6 6
7# show-tools: 7# show-tools:
8# Emits a /bin/sh shell script that defines all known tools 8# Emits a /bin/sh shell script that defines all known tools
9# to the values they have in the pkgsrc infrastructure. 9# to the values they have in the pkgsrc infrastructure.
10# 10#
11show-tools: .PHONY 11show-tools: .PHONY
12.for t in ${_USE_TOOLS} 12.for t in ${_USE_TOOLS}
13. if defined(_TOOLS_VARNAME.${t}) 13. if defined(_TOOLS_VARNAME.${t})
14 @${ECHO} ${_TOOLS_VARNAME.${t}:Q}=${${_TOOLS_VARNAME.${t}}:Q:Q} 14 @${ECHO} ${_TOOLS_VARNAME.${t}:Q}=${${_TOOLS_VARNAME.${t}}:Q:Q}
@@ -155,67 +155,70 @@ _LABEL._DEF_VARS= def @@ -155,67 +155,70 @@ _LABEL._DEF_VARS= def
155show-all: .PHONY 155show-all: .PHONY
156.for g in ${_VARGROUPS:O:u} 156.for g in ${_VARGROUPS:O:u}
157 157
158show-all: show-all-${g} 158show-all: show-all-${g}
159 159
160# In the following code, the variables are evaluated as late as possible. 160# In the following code, the variables are evaluated as late as possible.
161# This is especially important for variables that use the :sh modifier, 161# This is especially important for variables that use the :sh modifier,
162# like SUBST_FILES.pkglocaledir from mk/configure/replace-localedir.mk. 162# like SUBST_FILES.pkglocaledir from mk/configure/replace-localedir.mk.
163# 163#
164# When finally showing the variables, it is unavoidable that variables 164# When finally showing the variables, it is unavoidable that variables
165# using the :sh modifier may show warnings, for example because ${WRKDIR} 165# using the :sh modifier may show warnings, for example because ${WRKDIR}
166# doesn't exist. 166# doesn't exist.
167 167
 168_SHOW_ALL.d4= $$$$ # see regress/show-all
 169_SHOW_ALL.d8= $$$$$$$$ # see regress/show-all
 170
168show-all-${g}: .PHONY 171show-all-${g}: .PHONY
169 @${RUN} printf '%s:\n' ${g:Q} 172 @${RUN} printf '%s:\n' ${g:Q}
170 173
171. for c in ${_SHOW_ALL_CATEGORIES} 174. for c in ${_SHOW_ALL_CATEGORIES}
172. for v in ${${c}.${g}} 175. for v in ${${c}.${g}}
173 176
174. if ${_SORTED_VARS.${g}:U:@pattern@ ${v:M${pattern}} @:M*} 177. if ${_SORTED_VARS.${g}:U:@pattern@ ${v:M${pattern}} @:M*}
175 178
176# multi-valued variables, values are sorted 179# multi-valued variables, values are sorted
177 ${RUN} \ 180 ${RUN} \
178 if ${!defined(${v}) :? true : false}; then \ 181 if ${!defined(${v}) :? true : false}; then \
179 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \ 182 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \
180 elif value=${${v}:U:M*:Q} && test "x$$value" = "x"; then \ 183 elif value=${${v}:U:M*:Q} && test "x$$value" = "x"; then \
181 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \ 184 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \
182 else \ 185 else \
183 printf ' %s\t%-23s \\\n' ${_LABEL.${c}} ${v:Q}=; \ 186 printf ' %s\t%-23s \\\n' ${_LABEL.${c}} ${v:Q}=; \
184 printf '\t\t\t\t%s \\\n' ${${v}:O:@x@${x:Q}@}; \ 187 printf '\t\t\t\t%s \\\n' ${${v}:O:C,\\$$,${_SHOW_ALL.d8},g:@x@${x:Q}@}; \
185 printf '\t\t\t\t# end of %s (sorted)\n' ${v:Q}; \ 188 printf '\t\t\t\t# end of %s (sorted)\n' ${v:Q}; \
186 fi 189 fi
187 190
188. elif ${_LISTED_VARS.${g}:U:@pattern@ ${v:M${pattern}} @:M*} 191. elif ${_LISTED_VARS.${g}:U:@pattern@ ${v:M${pattern}} @:M*}
189 192
190# multi-valued variables, preserving original order 193# multi-valued variables, preserving original order
191 ${RUN} \ 194 ${RUN} \
192 if ${!defined(${v}) :? true : false}; then \ 195 if ${!defined(${v}) :? true : false}; then \
193 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \ 196 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \
194 elif value=${${v}:U:M*:Q} && test "x$$value" = "x"; then \ 197 elif value=${${v}:U:M*:Q} && test "x$$value" = "x"; then \
195 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \ 198 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \
196 else \ 199 else \
197 printf ' %s\t%-23s \\\n' ${_LABEL.${c}} ${v:Q}=; \ 200 printf ' %s\t%-23s \\\n' ${_LABEL.${c}} ${v:Q}=; \
198 printf '\t\t\t\t%s \\\n' ${${v}:@x@${x:Q}@}; \ 201 printf '\t\t\t\t%s \\\n' ${${v}:C,\\$$,${_SHOW_ALL.d8},g:@x@${x:Q}@}; \
199 printf '\t\t\t\t# end of %s\n' ${v:Q}; \ 202 printf '\t\t\t\t# end of %s\n' ${v:Q}; \
200 fi 203 fi
201 204
202. else 205. else
203 206
204# single-valued variables 207# single-valued variables
205 ${RUN} \ 208 ${RUN} \
206 if ${!defined(${v}) :? true : false}; then \ 209 if ${!defined(${v}) :? true : false}; then \
207 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \ 210 printf ' %s\t%-23s # undefined\n' ${_LABEL.${c}} ${v:Q}; \
208 elif value=${${v}:U:Q} && test "x$$value" = "x"; then \ 211 elif value=${${v}:U:C,\\$$,${_SHOW_ALL.d4},gW:Q} && test "x$$value" = "x"; then \
209 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \ 212 printf ' %s\t%-23s # empty\n' ${_LABEL.${c}} ${v:Q}=; \
210 else \ 213 else \
211 case "$$value" in (*[\ \ ]) eol="# ends with space";; (*) eol=""; esac; \ 214 case "$$value" in (*[\ \ ]) eol="# ends with space";; (*) eol=""; esac; \
212 printf ' %s\t%-23s %s\n' ${_LABEL.${c}} ${v:Q}= "$$value$$eol"; \ 215 printf ' %s\t%-23s %s\n' ${_LABEL.${c}} ${v:Q}= "$$value$$eol"; \
213 fi 216 fi
214 217
215. endif 218. endif
216. endfor 219. endfor
217. endfor 220. endfor
218 ${RUN} printf '\n' 221 ${RUN} printf '\n'
219.endfor 222.endfor
220 223
221.PHONY: show-depends-options 224.PHONY: show-depends-options

cvs diff -r1.4 -r1.5 pkgsrc/regress/show-all/Attic/Makefile (expand / switch to unified diff)

--- pkgsrc/regress/show-all/Attic/Makefile 2020/03/20 15:45:12 1.4
+++ pkgsrc/regress/show-all/Attic/Makefile 2020/03/20 16:39:03 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: Makefile,v 1.4 2020/03/20 15:45:12 rillig Exp $ 1# $NetBSD: Makefile,v 1.5 2020/03/20 16:39:03 rillig Exp $
2 2
3DISTNAME= show-all-1.0 3DISTNAME= show-all-1.0
4CATEGORIES= regress 4CATEGORIES= regress
5MASTER_SITES= # none 5MASTER_SITES= # none
6DISTFILES= # none 6DISTFILES= # none
7 7
8MAINTAINER= pkgsrc-users@NetBSD.org 8MAINTAINER= pkgsrc-users@NetBSD.org
9COMMENT= Demonstrates the show-all target 9COMMENT= Demonstrates the show-all target
10LICENSE= 2-clause-bsd 10LICENSE= 2-clause-bsd
11 11
12REGRESS.empty= # empty 12REGRESS.empty= # empty
13REGRESS.space= ${:U } # a single space 13REGRESS.space= ${:U } # a single space
14REGRESS.value= All * kinds of `strange' \escape $$characters 14REGRESS.value= All * kinds of `strange' \escape $$characters
@@ -23,23 +23,23 @@ REGRESS_ARGS.value= VAR1=value1 VAR2=`co @@ -23,23 +23,23 @@ REGRESS_ARGS.value= VAR1=value1 VAR2=`co
23 23
24# Variable names may also contain special characters that must be escaped. 24# Variable names may also contain special characters that must be escaped.
25*= bmake built-in 25*= bmake built-in
26**= asterisk 26**= asterisk
27 27
28_VARGROUPS+= regress 28_VARGROUPS+= regress
29_PKG_VARS.regress+= REGRESS_ENV.undefined REGRESS_ENV.empty REGRESS_ENV.space REGRESS_ENV.value 29_PKG_VARS.regress+= REGRESS_ENV.undefined REGRESS_ENV.empty REGRESS_ENV.space REGRESS_ENV.value
30_PKG_VARS.regress+= REGRESS_ARGS.undefined REGRESS_ARGS.empty REGRESS_ARGS.space REGRESS_ARGS.value 30_PKG_VARS.regress+= REGRESS_ARGS.undefined REGRESS_ARGS.empty REGRESS_ARGS.space REGRESS_ARGS.value
31_PKG_VARS.regress+= REGRESS.undefined REGRESS.empty REGRESS.space REGRESS.value 31_PKG_VARS.regress+= REGRESS.undefined REGRESS.empty REGRESS.space REGRESS.value
32_PKG_VARS.regress+= * ** 32_PKG_VARS.regress+= * **
33_SORTED_VARS.regress= *_ENV.* 33_SORTED_VARS.regress= *_ENV.*
34_LISTED_VARS.regress= *_ARGS.* 34_LISTED_VARS.regress= *_ARGS.*
35 35
36SHELLVAR_PLAIN= "$$var $${var} $$other" 36SHELLVAR_PLAIN= "$$var $${var} $$other $$$$"
37SHELLVAR_ENV= "$$var $${var} $$other" 37SHELLVAR_ENV= "$$var $${var} $$other $$$$"
38SHELLVAR_ARGS= "$$var $${var} $$other" 38SHELLVAR_ARGS= "$$var $${var} $$other $$$$"
39 39
40_VARGROUPS+= shellvar 40_VARGROUPS+= shellvar
41_PKG_VARS.shellvar= SHELLVAR_PLAIN SHELLVAR_ENV SHELLVAR_ARGS 41_PKG_VARS.shellvar= SHELLVAR_PLAIN SHELLVAR_ENV SHELLVAR_ARGS
42_SORTED_VARS.shellvar= *_ENV 42_SORTED_VARS.shellvar= *_ENV
43_LISTED_VARS.shellvar= *_ARGS 43_LISTED_VARS.shellvar= *_ARGS
44 44
45.include "../../mk/bsd.pkg.mk" 45.include "../../mk/bsd.pkg.mk"

cvs diff -r1.3 -r1.4 pkgsrc/regress/show-all/Attic/spec (expand / switch to unified diff)

--- pkgsrc/regress/show-all/Attic/spec 2020/03/20 15:45:12 1.3
+++ pkgsrc/regress/show-all/Attic/spec 2020/03/20 16:39:03 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: spec,v 1.3 2020/03/20 15:45:12 rillig Exp $ 1# $NetBSD: spec,v 1.4 2020/03/20 16:39:03 rillig Exp $
2 2
3tmpdir=${TMPDIR:-/tmp}/pkgsrc-show-all 3tmpdir=${TMPDIR:-/tmp}/pkgsrc-show-all
4rm -rf "$tmpdir" 4rm -rf "$tmpdir"
5mkdir -p "$tmpdir" 5mkdir -p "$tmpdir"
6 6
7require_file() { 7require_file() {
8 if diff -u "$3" "$1" > /dev/null; then 8 if diff -u "$3" "$1" > /dev/null; then
9 : 9 :
10 else 10 else
11 regress_fail "Expected files to be equal." 11 regress_fail "Expected files to be equal."
12 diff -u "$3" "$1" || true 12 diff -u "$3" "$1" || true
13 fi 13 fi
14} 14}
@@ -39,52 +39,52 @@ regress: @@ -39,52 +39,52 @@ regress:
39 pkg REGRESS_ARGS.empty= # empty 39 pkg REGRESS_ARGS.empty= # empty
40 pkg REGRESS_ARGS.space= # empty 40 pkg REGRESS_ARGS.space= # empty
41 pkg REGRESS_ARGS.value= \ 41 pkg REGRESS_ARGS.value= \
42 VAR1=value1 \ 42 VAR1=value1 \
43 VAR2=`command \ 43 VAR2=`command \
44 execution \ 44 execution \
45 via \ 45 via \
46 backticks` \ 46 backticks` \
47 *=all \ 47 *=all \
48 # end of REGRESS_ARGS.value 48 # end of REGRESS_ARGS.value
49 pkg REGRESS.undefined # undefined 49 pkg REGRESS.undefined # undefined
50 pkg REGRESS.empty= # empty 50 pkg REGRESS.empty= # empty
51 pkg REGRESS.space= # ends with space 51 pkg REGRESS.space= # ends with space
52 pkg REGRESS.value= All * kinds of `strange' \escape $characters 52 pkg REGRESS.value= All * kinds of `strange' \escape $$characters
53 pkg *= show-all-regress 53 pkg *= show-all-regress
54 pkg **= asterisk 54 pkg **= asterisk
55 55
56EOF 56EOF
57 57
58 # The "*" variable is built-in into bmake and expands to the current 58 # The "*" variable is built-in into bmake and expands to the current
59 # make target, which in this case is "show-all-regress". 59 # make target, which in this case is "show-all-regress".
60 60
61 # The "**" variable ensures that show-all doesn't accidentally expand 61 # The "**" variable ensures that show-all doesn't accidentally expand
62 # filenames. 62 # filenames.
63 63
64 # It's a bit strange that bmake doesn't handle the backticks command 64 # It's a bit strange that bmake doesn't handle the backticks command
65 # as a single word. Luckily, this is a rare case. 65 # as a single word. Luckily, this is a rare case.
66 # 66 #
67 # On the other hand, if it did, bmake would also have to handle 67 # On the other hand, if it did, bmake would also have to handle
68 # variable expansion and all the other syntactic difficulties from 68 # variable expansion and all the other syntactic difficulties from
69 # parsing shell commands, and that would be just too much. 69 # parsing shell commands, and that would be just too much.
70 70
71 require_file "$tmpdir/show-all-regress.out" --equals "$tmpdir/expected" 71 require_file "$tmpdir/show-all-regress.out" --equals "$tmpdir/expected"
72 72
73 73
74 # TODO: What the heck is going on here? 74 # Up to 2020-03-20, the output of the ENV and ARGS variables differed
75 # The output of the ENV and ARGS cases should be the same as in PLAIN. 75 # a lot from the PLAIN variable.
76 # 76 #
77 cat <<'EOF' > "$tmpdir/expected" 77 cat <<'EOF' > "$tmpdir/expected"
78shellvar: 78shellvar:
79 pkg SHELLVAR_PLAIN= "$var ${var} $other" 79 pkg SHELLVAR_PLAIN= "$$var $${var} $$other $$$$"
80 pkg SHELLVAR_ENV= \ 80 pkg SHELLVAR_ENV= \
81 ".MAKE.LEVEL.ENVar ther" \ 81 "$$var $${var} $$other $$$$" \
82 # end of SHELLVAR_ENV (sorted) 82 # end of SHELLVAR_ENV (sorted)
83 pkg SHELLVAR_ARGS= \ 83 pkg SHELLVAR_ARGS= \
84 ".MAKE.LEVEL.ENVar ther" \ 84 "$$var $${var} $$other $$$$" \
85 # end of SHELLVAR_ARGS 85 # end of SHELLVAR_ARGS
86 86
87EOF 87EOF
88 88
89 require_file "$tmpdir/show-all-shellvar.out" --equals "$tmpdir/expected" 89 require_file "$tmpdir/show-all-shellvar.out" --equals "$tmpdir/expected"
90} 90}