On Sat, Jul 06, 2024 at 02:11:13AM -0400, Eric Sunshine wrote: > > > cat <<EOFA && x=$(cat <<EOFB && > > > A body > > > EOFA > > > B body > > > EOFB > [...] > In retrospect, I think my claim is bogus in the context of > ScriptParser::parse_cmd(). Specifically, ScriptParser::parse_cmd() > calls its parent ShellParser::parse_cmd() to latch one command. > ShellParser::parse_cmd() stops parsing as soon as it encounters a > command terminator (i.e. `;`, `&&`, `||`, `|`, '&', '\n') and returns > the command. Moreover, by definition, given the language > specification, the lexer only consumes the heredocs upon encountering > `\n`. Thus, if someone writes: > > test_expect_success title - <<\EOT && whatever && > ...test body... > EOT > > then ScriptParser::parse_cmd() will receive the command > `test_expect_success title -` from ShellParser::parse_cmd() but the > heredoc will not yet have been consumed by the lexer since it hasn't > yet encountered the newline[1]. > > So, the above example simply can't work correctly given the way > ScriptParser::parse_cmd() calls ScriptParser::check_test() as soon as > it encounters a `test_expect_success/failure` invocation since it > doesn't know if the heredocs have been latched at that point. Ah, yeah, I think you're right. I had parsed your example in my mind as: cat <<EOFA $(cat <<EOFB) without an intervening "&&" (taking the second here-doc as an argument to the original command). Which _does_ work with your patch. > To make it properly robust, rather than immediately calling > check_test(), it would have to continue consuming commands, and saving > the ones which match `test_expect_success/failure` invocation, until > it finally hits a `\n`, and only then call check_test() with each > command it saved. But that's probably overkill at this point > considering that we never write code like the above, so the submitted > patch[2] is probably good enough for now. Yep, I'd agree with all of that. -Peff