#include "sh.h"
-__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.247 2018/01/14 01:44:01 tg Exp $");
+__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.250 2018/10/20 18:34:14 tg Exp $");
/*
* states while lexing word
short nparen;
/* type of this state */
uint8_t type;
+ /* extra flags */
+ uint8_t ls_flags;
} Lex_state;
#define ls_base u.base
#define ls_start u.start
#define ls_bool u.abool
#define ls_adelim u.adelim
+/* ls_flags */
+#define LS_HEREDOC BIT(0)
+
typedef struct {
Lex_state *base;
Lex_state *end;
#define STATE_BSIZE 8
#define PUSH_STATE(s) do { \
+ uint8_t state_flags = statep->ls_flags; \
if (++statep == state_info.end) \
statep = push_state_i(&state_info, statep); \
state = statep->type = (s); \
+ statep->ls_flags = state_flags; \
} while (/* CONSTCOND */ 0)
#define POP_STATE() do { \
/* Initial state: one of SWORD SLETPAREN SHEREDELIM SBASE */
statep->type = state;
+ statep->ls_flags = (cf & HEREDOC) ? LS_HEREDOC : 0;
/* collect non-special or quoted characters to form word */
while (!((c = getsc()) == 0 ||
break;
case ORD('\''):
open_ssquote_unless_heredoc:
- if ((cf & HEREDOC))
+ if ((statep->ls_flags & LS_HEREDOC))
goto store_char;
*wp++ = OQUOTE;
ignore_backslash_newline++;
c = getsc();
switch (c) {
case ORD('"'):
- if ((cf & HEREDOC))
+ if ((statep->ls_flags & LS_HEREDOC))
goto heredocquote;
/* FALLTHROUGH */
case ORD('\\'):
if ((unsigned int)c == ORD('(' /*)*/)) {
*wp++ = EXPRSUB;
PUSH_SRETRACE(SASPAREN);
+ /* unneeded? */
+ /*statep->ls_flags &= ~LS_HEREDOC;*/
statep->nparen = 2;
*retrace_info->xp++ = '(';
} else {
*wp++ = ADELIM;
*wp++ = ':';
PUSH_STATE(SBRACE);
+ /* perhaps unneeded? */
+ statep->ls_flags &= ~LS_HEREDOC;
PUSH_STATE(SADELIM);
statep->ls_adelim.delimiter = ':';
statep->ls_adelim.num = 1;
}
ungetsc(c);
PUSH_STATE(SBRACE);
+ /* perhaps unneeded? */
+ statep->ls_flags &= ~LS_HEREDOC;
PUSH_STATE(SADELIM);
statep->ls_adelim.delimiter = ':';
statep->ls_adelim.num = 2;
} else
ungetsc(c);
PUSH_STATE(SBRACE);
+ /* perhaps unneeded? */
+ statep->ls_flags &= ~LS_HEREDOC;
PUSH_STATE(SADELIM);
statep->ls_adelim.delimiter = '/';
statep->ls_adelim.num = 1;
PUSH_STATE(STBRACEBOURNE);
else
PUSH_STATE(STBRACEKORN);
+ /* single-quotes-in-heredoc-trim */
+ statep->ls_flags &= ~LS_HEREDOC;
} else {
ungetsc(c);
if (state == SDQUOTE ||
PUSH_STATE(SQBRACE);
else
PUSH_STATE(SBRACE);
+ /* here no LS_HEREDOC removal */
+ /* single-quotes-in-heredoc-braces */
}
} else if (ctype(c, C_ALPHX)) {
*wp++ = OSUBST;
case SSQUOTE:
if ((unsigned int)c == ORD('\'')) {
POP_STATE();
- if ((cf & HEREDOC) || state == SQBRACE)
+ if ((statep->ls_flags & LS_HEREDOC) ||
+ state == SQBRACE)
goto store_char;
*wp++ = CQUOTE;
ignore_backslash_newline--;
/* Newline terminates here document marker */
goto heredoc_found_terminator;
}
- } else if (c == *eofp++)
+ } else if ((unsigned int)c == ord(*eofp++))
/* store; then read and compare next character */
goto heredoc_store_and_loop;
/* nope, mismatch; read until end of line */
{
char *xp = Xstring(s->xs, xp), *cp;
bool interactive = Flag(FTALKING) && s->type == SSTDIN;
- bool have_tty = tobool(interactive && (s->flags & SF_TTY));
+ bool have_tty = interactive && (s->flags & SF_TTY) && tty_hasstate;
/* Done here to ensure nothing odd happens when a timeout occurs */
XcheckN(s->xs, xp, LINE);