chainlint.sed: stop throwing away here-doc tags

The purpose of chainlint is to highlight problems it finds in test code by inserting annotations at the location of each problem. Arbitrarily eliding bits of the code it is checking is not helpful, yet this is exactly what chainlint.sed does by cavalierly and unnecessarily dropping the here-doc operator and tag; i.e. `cat <<TAG` becomes simply `cat` in the output. This behavior can make it more difficult for the test writer to align the annotated output of chainlint.sed with the original test code. Address this by retaining here-doc tags. Signed-off-by: Eric Sunshine <sunshine@sunshineco.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Eric Sunshine committed Dec 13, 2021 at 01:30 UTC 34ba05c2966f9e96b74ea984251e3bda802d6a7a
11 files changed +35 -29
t/chainlint.sed
+15 -9
@@ -62,20 +62,20 @@
62 # receives similar treatment.
63 #
64 # Swallowing here-docs with arbitrary tags requires a bit of finesse. When a
65 -# line such as "cat <<EOF >out" is seen, the here-doc tag is moved to the front
66 -# of the line enclosed in angle brackets as a sentinel, giving "<EOF>cat >out".
65 +# line such as "cat <<EOF" is seen, the here-doc tag is copied to the front of
66 +# the line enclosed in angle brackets as a sentinel, giving "<EOF>cat <<EOF".
67 # As each subsequent line is read, it is appended to the target line and a
68 # (whitespace-loose) back-reference match /^<(.*)>\n\1$/ is attempted to see if
69 # the content inside "<...>" matches the entirety of the newly-read line. For
70 # instance, if the next line read is "some data", when concatenated with the
71 -# target line, it becomes "<EOF>cat >out\nsome data", and a match is attempted
71 +# target line, it becomes "<EOF>cat <<EOF\nsome data", and a match is attempted
72 # to see if "EOF" matches "some data". Since it doesn't, the next line is
73 # attempted. When a line consisting of only "EOF" (and possible whitespace) is
74 -# encountered, it is appended to the target line giving "<EOF>cat >out\nEOF",
74 +# encountered, it is appended to the target line giving "<EOF>cat <<EOF\nEOF",
75 # in which case the "EOF" inside "<...>" does match the text following the
76 # newline, thus the closing here-doc tag has been found. The closing tag line
77 # and the "<...>" prefix on the target line are then discarded, leaving just
78 -# the target line "cat >out".
78 +# the target line "cat <<EOF".
79 #------------------------------------------------------------------------------
80
81 # incomplete line -- slurp up next line
@@ -90,8 +90,7 @@
90 # command to which it was attached)
91 /<<-*[ ]*[\\'"]*[A-Za-z0-9_]/ {
92 /"[^"]*<<[^"]*"/bnotdoc
93 - s/^\(.*\)<<-*[ ]*[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</
94 - s/[ ]*<<//
93 + s/^\(.*<<-*[ ]*\)[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1\2/
94 :hered
95 N
96 /^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
@@ -238,6 +237,7 @@ s/.*\n//
237 :cont
238 # retrieve and print previous line
239 x
240 +s/?!HERE?!/<</g
241 n
242 bslurp
243
@@ -278,8 +278,7 @@ bfolded
278 # found here-doc -- swallow it to avoid false hits within its body (but keep
279 # the command to which it was attached)
280 :heredoc
281 -s/^\(.*\)<<-*[ ]*[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</
282 -s/[ ]*<<//
281 +s/^\(.*\)<<\(-*[ ]*\)[\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\3>\1?!HERE?!\2\3/
282 :hdocsub
283 N
284 /^<\([^>]*\)>.*\n[ ]*\1[ ]*$/!{
@@ -293,6 +292,7 @@ bfolded
292 # found "case ... in" -- pass through untouched
293 :case
294 x
295 +s/?!HERE?!/<</g
296 n
297 /^[ ]*esac/bslurp
298 bcase
@@ -320,6 +320,7 @@ bchkchn
320 :nest
321 x
322 :nstslrp
323 +s/?!HERE?!/<</g
324 n
325 # closing ")" on own line -- stop nested slurp
326 /^[ ]*)/bnstcl
@@ -342,6 +343,7 @@ bchkchn
343 # found multi-line "{...\n...}" block -- pass through untouched
344 :block
345 x
346 +s/?!HERE?!/<</g
347 n
348 # closing "}" -- stop block slurp
349 /}/bchkchn
@@ -352,13 +354,17 @@ bblock
354 :clssolo
355 x
356 s/\( ?!AMP?!\)* ?!AMP?!$//
357 +s/?!HERE?!/<</g
358 p
359 x
360 +s/?!HERE?!/<</g
361 b
362
363 # found closing "...)" -- exit subshell loop
364 :close
365 x
366 +s/?!HERE?!/<</g
367 p
368 x
369 +s/?!HERE?!/<</g
370 b
t/chainlint/for-loop.expect
+1 -1
@@ -2,7 +2,7 @@
2 for i in a b c
3 do
4 echo $i ?!AMP?!
5 - cat
5 + cat <<-EOF
6 done ?!AMP?!
7 for i in a b c; do
8 echo $i &&
t/chainlint/here-doc-close-subshell.expect
+1 -1
@@ -1,2 +1,2 @@
1 (
2 - cat)
2 + cat <<-INPUT)
t/chainlint/here-doc-multi-line-command-subst.expect
+1 -1
@@ -1,5 +1,5 @@
1 (
2 - x=$(bobble &&
2 + x=$(bobble <<-END &&
3 wiffle) ?!AMP?!
4 echo $x
5 )
t/chainlint/here-doc-multi-line-string.expect
+1 -1
@@ -1,4 +1,4 @@
1 (
2 - cat && echo "multi-line string" ?!AMP?!
2 + cat <<-TXT && echo "multi-line string" ?!AMP?!
3 bap
4 )
t/chainlint/here-doc.expect
+4 -4
@@ -1,7 +1,7 @@
1 -boodle wobba gorgo snoot wafta snurb &&
1 +boodle wobba gorgo snoot wafta snurb <<EOF &&
2
3 -cat >foo &&
3 +cat <<-Arbitrary_Tag_42 >foo &&
4
5 -cat >boo &&
5 +cat <<zump >boo &&
6
7 -horticulture
7 +horticulture <<EOF
t/chainlint/if-then-else.expect
+1 -1
@@ -8,7 +8,7 @@
8 echo foo
9 else
10 echo foo &&
11 - cat
11 + cat <<-EOF
12 fi ?!AMP?!
13 echo poodle
14 ) &&
t/chainlint/nested-here-doc.expect
+3 -3
@@ -1,7 +1,7 @@
1 -cat >foop &&
1 +cat <<ARBITRARY >foop &&
2
3 (
4 - cat &&
5 - cat ?!AMP?!
4 + cat <<-INPUT_END &&
5 + cat <<-EOT ?!AMP?!
6 foobar
7 )
t/chainlint/subshell-here-doc.expect
+5 -5
@@ -1,10 +1,10 @@
1 (
2 - echo wobba gorgo snoot wafta snurb &&
3 - cat >bip ?!AMP?!
4 - echo >bop
2 + echo wobba gorgo snoot wafta snurb <<-EOF &&
3 + cat <<EOF >bip ?!AMP?!
4 + echo <<-EOF >bop
5 ) &&
6 (
7 - cat >bup &&
8 - cat >bup3 &&
7 + cat <<-ARBITRARY >bup &&
8 + cat <<-ARBITRARY3 >bup3 &&
9 meep
10 )
t/chainlint/t7900-subtree.expect
+2 -2
@@ -1,9 +1,9 @@
1 (
2 chks="sub1sub2sub3sub4" &&
3 - chks_sub=$(cat | sed "s,^,sub dir/,"
3 + chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
4 ) &&
5 chkms="main-sub1main-sub2main-sub3main-sub4" &&
6 - chkms_sub=$(cat | sed "s,^,sub dir/,"
6 + chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
7 ) &&
8 subfiles=$(git ls-files) &&
9 check_equal "$subfiles" "$chkms$chks"
t/chainlint/while-loop.expect
+1 -1
@@ -2,7 +2,7 @@
2 while true
3 do
4 echo foo ?!AMP?!
5 - cat
5 + cat <<-EOF
6 done ?!AMP?!
7 while true; do
8 echo foo &&