syntax/sh: Improve `heredoc` detection
- allow spaces between optional '-' and delimiter
- allow additional characters as delimiter
Fixes #3927
@Andriamanitra: I kindly request your review too. :)
We should probably handle quotes. GNU Bash reference manual says:
If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded.
I've gathered some examples of heredocs below. This PR has some issues when heredoc is in the middle of a command, and when there are \t characters before the delimiter:
# common usage
cat << EOF
hello ' " world
EOF
cat << 'EOF'
hello ' " world
EOF
cat <<-"EOF"
hello ' " world
EOF
# from https://github.com/openwrt/openwrt
cat <<-EOT | "${CC:-false}" $CFLAGS -o /dev/null -x c - 2>/dev/null
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello, world!\n");
return 0;
}
EOT
# from https://github.com/goToMain/libosdp/blob/e586d3f700215d16b0e79513880d1c1ade815ba0/configure.sh#L9-L32
cat >&2<<----
LibOSDP build configure script
OPTIONS:
--packet-trace Enable raw packet trace for diagnostics
--data-trace Enable command/reply data buffer tracing
--skip-mark Don't send the leading mark byte (0xFF)
--crypto LIB Use methods from LIB (openssl/mbedtls/*tinyaes)
---
# from https://github.com/mingw-w64/mingw-w64/blob/c2167bc6da600f7fdbd131734767a67ffb9e970e/mingw-w64-headers/configure#L1281
cat <<_ACEOF
'configure' configures mingw-w64-headers 4.0b to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print 'checking ...' messages
_ACEOF
# from https://github.com/mingw-w64/mingw-w64/blob/c2167bc6da600f7fdbd131734767a67ffb9e970e/mingw-w64-tools/genpeimg/build-aux/compile#L240
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
EOF
You're right.
But especially the \t(or \s) in front of the closing delimiter is a problem, because this indeed will lead to a false positive delimiter. I still have no good idea how this should be solved. :thinking: