np = stzalloc(sizeof(struct nfile));
if (c == '>') {
np->nfile.fd = 1;
- c = pgetc();
+ c = pgetc_eatbnl();
if (c == '>')
np->type = NAPPEND;
else if (c == '|')
#endif
else { /* c == '<' */
/*np->nfile.fd = 0; - stzalloc did it */
- c = pgetc();
+ c = pgetc_eatbnl();
switch (c) {
case '<':
if (sizeof(struct nfile) != sizeof(struct nhere)) {
np->type = NHERE;
heredoc = stzalloc(sizeof(struct heredoc));
heredoc->here = np;
- c = pgetc();
+ c = pgetc_eatbnl();
if (c == '-') {
heredoc->striptabs = 1;
} else {
int pc;
setprompt_if(needprompt, 2);
- pc = pgetc();
+ pc = pgetc_eatbnl();
switch (pc) {
case '`':
goto done;
case '\\':
- pc = pgetc();
- if (pc == '\n') {
- nlprompt();
- /*
- * If eating a newline, avoid putting
- * the newline into the new character
- * stream (via the STPUTC after the
- * switch).
- */
- continue;
- }
+ pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
if (pc != '\\' && pc != '`' && pc != '$'
&& (!dblquote || pc != '"')
) {
}
setprompt_if(needprompt, 2);
for (;;) { /* until token or start of word found */
- c = pgetc();
+ c = pgetc_eatbnl();
if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
continue;
continue;
pungetc();
} else if (c == '\\') {
- if (pgetc() != '\n') {
- pungetc();
- break; /* return readtoken1(...) */
- }
- nlprompt();
+ break; /* return readtoken1(...) */
} else {
const char *p;
}
setprompt_if(needprompt, 2);
for (;;) { /* until token or start of word found */
- c = pgetc();
+ c = pgetc_eatbnl();
switch (c) {
case ' ': case '\t':
IF_ASH_ALIAS(case PEOA:)
continue;
pungetc();
continue;
- case '\\':
- if (pgetc() == '\n') {
- nlprompt();
- continue;
- }
- pungetc();
- goto breakloop;
case '\n':
nlnoprompt();
RETURN(TNL);
case PEOF:
RETURN(TEOF);
case '&':
- if (pgetc() == '&')
+ if (pgetc_eatbnl() == '&')
RETURN(TAND);
pungetc();
RETURN(TBACKGND);
case '|':
- if (pgetc() == '|')
+ if (pgetc_eatbnl() == '|')
RETURN(TOR);
pungetc();
RETURN(TPIPE);
case ';':
- if (pgetc() == ';')
+ if (pgetc_eatbnl() == ';')
RETURN(TENDCASE);
pungetc();
RETURN(TSEMI);
RETURN(TLP);
case ')':
RETURN(TRP);
- default:
- goto breakloop;
}
+ break;
}
- breakloop:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}
--- /dev/null
+Quoted heredoc:
+a\
+ b
+a\\
+ b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
+c\
+
+Unquoted heredoc:
+a b
+a\
+ b
+ 123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
+ -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
+ 123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
+ 123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
+cEOF2
+
+Quoted -heredoc:
+a\
+b
+a\\
+b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
+c\
+
+Unquoted -heredoc:
+a b
+a\
+b
+ 123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
+-qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
+ 123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
+ 123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
+cEOF4
+
+Done: 0
--- /dev/null
+# Test for correct handling of backslashes.
+# Note that some lines in each heredoc start with a tab.
+
+a=qwerty
+
+echo Quoted heredoc:
+cat <<"EOF1"
+a\
+ b
+a\\
+ b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
+c\
+EOF1
+echo
+
+echo Unquoted heredoc:
+cat <<EOF2
+a\
+ b
+a\\
+ b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
+c\
+EOF2
+EOF2
+echo
+
+echo Quoted -heredoc:
+cat <<-"EOF3"
+a\
+ b
+a\\
+ b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
+c\
+ EOF3
+# In -heredoc case the marker is detected even if it is indented.
+echo
+
+echo Unquoted -heredoc:
+cat <<-EOF4
+a\
+ b
+a\\
+ b
+ 123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
+ 123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
+ 123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
+c\
+EOF4
+ EOF4
+# The marker is not detected if preceding line ends in backslash.
+# TODO: marker should be detected even if it is split by line continuation:
+# EOF\
+# 4
+# but currently hush doesn't do it. (Tab before "4" is not allowed, though.)
+echo
+
+echo "Done: $?"
--- /dev/null
+heredoc0
+Ok0:0
+heredoc1
+Ok1:0
+heredoc2
+Ok2:0
+heredoc3
+Ok4:0
--- /dev/null
+cat <\
+<\
+EOF
+heredoc0
+EOF
+echo Ok0:$?
+
+cat <<\
+ EOF
+heredoc1
+EOF
+echo Ok1:$?
+
+cat <<\
+- EOF
+heredoc2
+ EOF
+echo Ok2:$?
+
+cat <\
+<\
+- EOF
+heredoc3
+ EOF
+echo Ok4:$?
--- /dev/null
+heredoc0
+Ok0:0
+heredoc1
+Ok1:0
+heredoc2
+Ok2:0
+heredoc3
+Ok4:0
--- /dev/null
+cat <\
+<\
+EOF
+heredoc0
+EOF
+echo Ok0:$?
+
+cat <<\
+ EOF
+heredoc1
+EOF
+echo Ok1:$?
+
+cat <<\
+- EOF
+heredoc2
+ EOF
+echo Ok2:$?
+
+cat <\
+<\
+- EOF
+heredoc3
+ EOF
+echo Ok4:$?