chainlint: let here-doc and multi-line string commence on same line
authorEric Sunshine <sunshine@sunshineco.com>
Mon, 13 Aug 2018 08:47:37 +0000 (04:47 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 13 Aug 2018 19:22:12 +0000 (12:22 -0700)
After swallowing a here-doc, chainlint.sed assumes that no other
processing needs to be done on the line aside from checking for &&-chain
breakage; likewise, after folding a multi-line quoted string. However,
it's conceivable (even if unlikely in practice) that both a here-doc and
a multi-line quoted string might commence on the same line:

cat <<\EOF && echo "foo
bar"
data
EOF

Support this case by sending the line (after swallowing and folding)
through the normal processing sequence rather than jumping directly to
the check for broken &&-chain.

This change also allows other somewhat pathological cases to be handled,
such as closing a subshell on the same line starting a here-doc:

(
cat <<-\INPUT)
data
INPUT

or, for instance, opening a multi-line $(...) expression on the same
line starting a here-doc:

x=$(cat <<-\END &&
data
END
echo "x")

among others.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/chainlint.sed
t/chainlint/here-doc-close-subshell.expect [new file with mode: 0644]
t/chainlint/here-doc-close-subshell.test [new file with mode: 0644]
t/chainlint/here-doc-multi-line-command-subst.expect [new file with mode: 0644]
t/chainlint/here-doc-multi-line-command-subst.test [new file with mode: 0644]
t/chainlint/here-doc-multi-line-string.expect [new file with mode: 0644]
t/chainlint/here-doc-multi-line-string.test [new file with mode: 0644]
index afb2443a9cfba05b05d08a9b9a0f4c30c2a21149..6661e21f20059429acaadfd42b8e49b14f010f1f 100644 (file)
@@ -157,6 +157,7 @@ s/.*\n//
 /^[^']*'[^']*$/{
        /"[^'"]*'[^'"]*"/!bsqstring
 }
+:folded
 # here-doc -- swallow it
 /<<[   ]*[-\\']*[A-Za-z0-9_]/bheredoc
 # comment or empty line -- discard since final non-comment, non-empty line
@@ -255,7 +256,7 @@ s/"//g
 N
 s/\n//
 /"/!bdqstring
-bcheckchain
+bfolded
 
 # found multi-line single-quoted string '...\n...' -- slurp until end of string
 :sqstring
@@ -263,7 +264,7 @@ s/'//g
 N
 s/\n//
 /'/!bsqstring
-bcheckchain
+bfolded
 
 # found here-doc -- swallow it to avoid false hits within its body (but keep
 # the command to which it was attached)
@@ -278,7 +279,7 @@ N
 }
 s/^<[^>]*>//
 s/\n.*$//
-bcheckchain
+bfolded
 
 # found "case ... in" -- pass through untouched
 :case
diff --git a/t/chainlint/here-doc-close-subshell.expect b/t/chainlint/here-doc-close-subshell.expect
new file mode 100644 (file)
index 0000000..f011e33
--- /dev/null
@@ -0,0 +1,2 @@
+(
+>      cat)
diff --git a/t/chainlint/here-doc-close-subshell.test b/t/chainlint/here-doc-close-subshell.test
new file mode 100644 (file)
index 0000000..b857ff5
--- /dev/null
@@ -0,0 +1,5 @@
+(
+# LINT: line contains here-doc and closes nested subshell
+       cat <<-\INPUT)
+       fizz
+       INPUT
diff --git a/t/chainlint/here-doc-multi-line-command-subst.expect b/t/chainlint/here-doc-multi-line-command-subst.expect
new file mode 100644 (file)
index 0000000..e5fb752
--- /dev/null
@@ -0,0 +1,5 @@
+(
+       x=$(bobble &&
+?!AMP?!>>              wiffle)
+       echo $x
+>)
diff --git a/t/chainlint/here-doc-multi-line-command-subst.test b/t/chainlint/here-doc-multi-line-command-subst.test
new file mode 100644 (file)
index 0000000..899bc5d
--- /dev/null
@@ -0,0 +1,9 @@
+(
+# LINT: line contains here-doc and opens multi-line $(...)
+       x=$(bobble <<-\END &&
+               fossil
+               vegetable
+               END
+               wiffle)
+       echo $x
+)
diff --git a/t/chainlint/here-doc-multi-line-string.expect b/t/chainlint/here-doc-multi-line-string.expect
new file mode 100644 (file)
index 0000000..1e5b724
--- /dev/null
@@ -0,0 +1,4 @@
+(
+?!AMP?!        cat && echo multi-line  string"
+       bap
+>)
diff --git a/t/chainlint/here-doc-multi-line-string.test b/t/chainlint/here-doc-multi-line-string.test
new file mode 100644 (file)
index 0000000..a53edbc
--- /dev/null
@@ -0,0 +1,8 @@
+(
+# LINT: line contains here-doc and opens multi-line string
+       cat <<-\TXT && echo "multi-line
+       string"
+       fizzle
+       TXT
+       bap
+)