Merge branch 'es/chain-lint-more'
authorJunio C Hamano <gitster@pobox.com>
Tue, 4 Sep 2018 21:31:40 +0000 (14:31 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 4 Sep 2018 21:31:40 +0000 (14:31 -0700)
The test linter code has learned that the end of here-doc mark
"EOF" can be quoted in a double-quote pair, not just in a
single-quote pair.

* es/chain-lint-more:
  chainlint: match "quoted" here-doc tags

1  2 
t/chainlint.sed

diff --combined t/chainlint.sed
  
  # here-doc -- swallow it to avoid false hits within its body (but keep the
  # command to which it was attached)
- /<<[  ]*[-\\']*[A-Za-z0-9_]/ {
-       s/^\(.*\)<<[    ]*[-\\']*\([A-Za-z0-9_][A-Za-z0-9_]*\)'*/<\2>\1<</
+ /<<[  ]*[-\\'"]*[A-Za-z0-9_]/ {
+       s/^\(.*\)<<[    ]*[-\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</
        s/[     ]*<<//
 -      :hereslurp
 +      :hered
        N
        /^<\([^>]*\)>.*\n[      ]*\1[   ]*$/!{
                s/\n.*$//
 -              bhereslurp
 +              bhered
        }
        s/^<[^>]*>//
        s/\n.*$//
  b
  
  :subshell
 -# bare "(" line?
 +# bare "(" line? -- stash for later printing
  /^[   ]*([    ]*$/ {
 -      # stash for later printing
        h
        bnextline
  }
@@@ -149,7 -150,7 +149,7 @@@ s/.*\n/
  
  :slurp
  # incomplete line "...\"
 -/\\$/bincomplete
 +/\\$/bicmplte
  # multi-line quoted string "...\n..."?
  /"/bdqstring
  # multi-line quoted string '...\n...'? (but not contraction in string "it's")
  }
  :folded
  # here-doc -- swallow it
- /<<[  ]*[-\\']*[A-Za-z0-9_]/bheredoc
+ /<<[  ]*[-\\'"]*[A-Za-z0-9_]/bheredoc
  # comment or empty line -- discard since final non-comment, non-empty line
  # before closing ")", "done", "elsif", "else", or "fi" will need to be
  # re-visited to drop "suspect" marking since final line of those constructs
        /"[^"]*#[^"]*"/!s/[     ]#.*$//
  }
  # one-liner "case ... esac"
 -/^[   ]*case[         ]*..*esac/bcheckchain
 +/^[   ]*case[         ]*..*esac/bchkchn
  # multi-line "case ... esac"
  /^[   ]*case[         ]..*[   ]in/bcase
  # multi-line "for ... done" or "while ... done"
  /^[   ]*fi[   ]*[<>|]/bdone
  /^[   ]*fi[   ]*)/bdone
  # nested one-liner "(...) &&"
 -/^[   ]*(.*)[         ]*&&[   ]*$/bcheckchain
 +/^[   ]*(.*)[         ]*&&[   ]*$/bchkchn
  # nested one-liner "(...)"
 -/^[   ]*(.*)[         ]*$/bcheckchain
 +/^[   ]*(.*)[         ]*$/bchkchn
  # nested one-liner "(...) >x" (or "2>x" or "<x" or "|x")
 -/^[   ]*(.*)[         ]*[0-9]*[<>|]/bcheckchain
 +/^[   ]*(.*)[         ]*[0-9]*[<>|]/bchkchn
  # nested multi-line "(...\n...)"
  /^[   ]*(/bnest
  # multi-line "{...\n...}"
  /^[   ]*{/bblock
  # closing ")" on own line -- exit subshell
 -/^[   ]*)/bclosesolo
 +/^[   ]*)/bclssolo
  # "$((...))" -- arithmetic expansion; not closing ")"
 -/\$(([^)][^)]*))[^)]*$/bcheckchain
 +/\$(([^)][^)]*))[^)]*$/bchkchn
  # "$(...)" -- command substitution; not closing ")"
 -/\$([^)][^)]*)[^)]*$/bcheckchain
 +/\$([^)][^)]*)[^)]*$/bchkchn
  # multi-line "$(...\n...)" -- command substitution; treat as nested subshell
  /\$([^)]*$/bnest
  # "=(...)" -- Bash array assignment; not closing ")"
 -/=(/bcheckchain
 +/=(/bchkchn
  # closing "...) &&"
  /)[   ]*&&[   ]*$/bclose
  # closing "...)"
  /)[   ]*$/bclose
  # closing "...) >x" (or "2>x" or "<x" or "|x")
  /)[   ]*[<>|]/bclose
 -:checkchain
 +:chkchn
  # mark suspect if line uses ";" internally rather than "&&" (but not ";" in a
  # string and not ";;" in one-liner "case...esac")
  /;/{
  bslurp
  
  # found incomplete line "...\" -- slurp up next line
 -:incomplete
 +:icmplte
  N
  s/\\\n//
  bslurp
@@@ -280,13 -281,13 +280,13 @@@ bfolde
  # found here-doc -- swallow it to avoid false hits within its body (but keep
  # the command to which it was attached)
  :heredoc
- s/^\(.*\)<<[  ]*[-\\']*\([A-Za-z0-9_][A-Za-z0-9_]*\)'*/<\2>\1<</
+ s/^\(.*\)<<[  ]*[-\\'"]*\([A-Za-z0-9_][A-Za-z0-9_]*\)['"]*/<\2>\1<</
  s/[   ]*<<//
 -:hereslurpsub
 +:heredsub
  N
  /^<\([^>]*\)>.*\n[    ]*\1[   ]*$/!{
        s/\n.*$//
 -      bhereslurpsub
 +      bheredsub
  }
  s/^<[^>]*>//
  s/\n.*$//
  # is 'done' or 'fi' cuddled with ")" to close subshell?
  /done.*)/bclose
  /fi.*)/bclose
 -bcheckchain
 +bchkchn
  
  # found nested multi-line "(...\n...)" -- pass through untouched
  :nest
  x
 -:nestslurp
 +:nstslurp
  n
  # closing ")" on own line -- stop nested slurp
 -/^[   ]*)/bnestclose
 +/^[   ]*)/bnstclose
  # comment -- not closing ")" if in comment
 -/^[   ]*#/bnestcontinue
 +/^[   ]*#/bnstcnt
  # "$((...))" -- arithmetic expansion; not closing ")"
 -/\$(([^)][^)]*))[^)]*$/bnestcontinue
 +/\$(([^)][^)]*))[^)]*$/bnstcnt
  # "$(...)" -- command substitution; not closing ")"
 -/\$([^)][^)]*)[^)]*$/bnestcontinue
 +/\$([^)][^)]*)[^)]*$/bnstcnt
  # closing "...)" -- stop nested slurp
 -/)/bnestclose
 -:nestcontinue
 +/)/bnstclose
 +:nstcnt
  x
 -bnestslurp
 -:nestclose
 +bnstslurp
 +:nstclose
  s/^/>>/
  # is it "))" which closes nested and parent subshells?
  /)[   ]*)/bslurp
 -bcheckchain
 +bchkchn
  
  # found multi-line "{...\n...}" block -- pass through untouched
  :block
  x
  n
  # closing "}" -- stop block slurp
 -/}/bcheckchain
 +/}/bchkchn
  bblock
  
  # found closing ")" on own line -- drop "suspect" from final line of subshell
  # since that line legitimately lacks "&&" and exit subshell loop
 -:closesolo
 +:clssolo
  x
  s/?!AMP?!//
  p