mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-14 07:30:49 +02:00
commit bash-20160401 snapshot
This commit is contained in:
@@ -3318,7 +3318,8 @@ tokword:
|
||||
#define LEX_INHEREDOC 0x080
|
||||
#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
|
||||
#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
|
||||
#define LEX_INWORD 0x400
|
||||
#define LEX_QUOTEDDOC 0x400 /* here doc with quoted delim */
|
||||
#define LEX_INWORD 0x800
|
||||
|
||||
#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
|
||||
|
||||
@@ -3610,6 +3611,81 @@ parse_dollar_word:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined (DEBUG)
|
||||
static void
|
||||
dump_tflags (flags)
|
||||
int flags;
|
||||
{
|
||||
int f;
|
||||
|
||||
f = flags;
|
||||
fprintf (stderr, "%d -> ", f);
|
||||
if (f & LEX_WASDOL)
|
||||
{
|
||||
f &= ~LEX_WASDOL;
|
||||
fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_CKCOMMENT)
|
||||
{
|
||||
f &= ~LEX_CKCOMMENT;
|
||||
fprintf (stderr, "LEX_CKCOMMENT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_INCOMMENT)
|
||||
{
|
||||
f &= ~LEX_INCOMMENT;
|
||||
fprintf (stderr, "LEX_INCOMMENT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_PASSNEXT)
|
||||
{
|
||||
f &= ~LEX_PASSNEXT;
|
||||
fprintf (stderr, "LEX_PASSNEXT%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_RESWDOK)
|
||||
{
|
||||
f &= ~LEX_RESWDOK;
|
||||
fprintf (stderr, "LEX_RESWDOK%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_CKCASE)
|
||||
{
|
||||
f &= ~LEX_CKCASE;
|
||||
fprintf (stderr, "LEX_CKCASE%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_INCASE)
|
||||
{
|
||||
f &= ~LEX_INCASE;
|
||||
fprintf (stderr, "LEX_INCASE%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_INHEREDOC)
|
||||
{
|
||||
f &= ~LEX_INHEREDOC;
|
||||
fprintf (stderr, "LEX_INHEREDOC%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_HEREDELIM)
|
||||
{
|
||||
f &= ~LEX_HEREDELIM;
|
||||
fprintf (stderr, "LEX_HEREDELIM%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_STRIPDOC)
|
||||
{
|
||||
f &= ~LEX_STRIPDOC;
|
||||
fprintf (stderr, "LEX_WASDOL%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_QUOTEDDOC)
|
||||
{
|
||||
f &= ~LEX_QUOTEDDOC;
|
||||
fprintf (stderr, "LEX_QUOTEDDOC%s", f ? "|" : "");
|
||||
}
|
||||
if (f & LEX_INWORD)
|
||||
{
|
||||
f &= ~LEX_INWORD;
|
||||
fprintf (stderr, "LEX_INWORD%s", f ? "|" : "");
|
||||
}
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
fflush (stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse a $(...) command substitution. This is messier than I'd like, and
|
||||
reproduces a lot more of the token-reading code than I'd like. */
|
||||
static char *
|
||||
@@ -3687,7 +3763,7 @@ eof_error:
|
||||
tind++;
|
||||
if (STREQN (ret + tind, heredelim, hdlen))
|
||||
{
|
||||
tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
|
||||
tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
|
||||
/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
|
||||
free (heredelim);
|
||||
heredelim = 0;
|
||||
@@ -3707,21 +3783,29 @@ eof_error:
|
||||
if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
|
||||
{
|
||||
int tind;
|
||||
/*itrace("parse_comsub: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", retind-lex_firstind, hdlen, retind);*/
|
||||
/*itrace("parse_comsub:%d: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", line_number, retind-lex_firstind, hdlen, retind);*/
|
||||
tind = lex_firstind;
|
||||
while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
|
||||
tind++;
|
||||
if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
|
||||
{
|
||||
tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC);
|
||||
/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/
|
||||
tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
|
||||
/*itrace("parse_comsub:%d: found here doc end `%*s'", line_number, hdlen, ret + tind);*/
|
||||
free (heredelim);
|
||||
heredelim = 0;
|
||||
lex_firstind = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't bother counting parens or doing anything else if in a comment */
|
||||
/* Don't bother counting parens or doing anything else if in a comment or
|
||||
here document (not exactly right for here-docs -- if we want to allow
|
||||
recursive calls to parse_comsub to have their own here documents,
|
||||
change the LEX_INHEREDOC to LEX_QUOTEDDOC here and uncomment the next
|
||||
clause below. Note that to make this work completely, we need to make
|
||||
additional changes to allow xparse_dolparen to work right when the
|
||||
command substitution is parsed, because read_secondary_line doesn't know
|
||||
to recursively parse through command substitutions embedded in here-
|
||||
documents */
|
||||
if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC))
|
||||
{
|
||||
/* Add this character. */
|
||||
@@ -3736,6 +3820,21 @@ eof_error:
|
||||
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
/* If we're going to recursively parse a command substitution inside a
|
||||
here-document, make sure we call parse_comsub recursively below. See
|
||||
above for additional caveats. */
|
||||
if ((tflags & LEX_INHEREDOC) && ((tflags & LEX_WASDOL) == 0 || ch != '(')) /*)*/
|
||||
{
|
||||
/* Add this character. */
|
||||
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
|
||||
ret[retind++] = ch;
|
||||
if MBTEST(ch == '$')
|
||||
tflags |= LEX_WASDOL;
|
||||
else
|
||||
tflags &= ~LEX_WASDOL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tflags & LEX_PASSNEXT) /* last char was backslash */
|
||||
{
|
||||
@@ -3816,6 +3915,8 @@ eof_error:
|
||||
free (nestret);
|
||||
hdlen = STRLEN(heredelim);
|
||||
/*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/
|
||||
if (STREQ (heredelim, nestret) == 0)
|
||||
tflags |= LEX_QUOTEDDOC;
|
||||
}
|
||||
if (ch == '\n')
|
||||
{
|
||||
@@ -3878,14 +3979,34 @@ eof_error:
|
||||
if (STREQN (ret + retind - 4, "case", 4))
|
||||
{
|
||||
tflags |= LEX_INCASE;
|
||||
tflags &= ~LEX_RESWDOK;
|
||||
/*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/
|
||||
}
|
||||
else if (STREQN (ret + retind - 4, "esac", 4))
|
||||
{
|
||||
tflags &= ~LEX_INCASE;
|
||||
/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 0", line_number);*/
|
||||
/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 1", line_number);*/
|
||||
tflags |= LEX_RESWDOK;
|
||||
lex_rwlen = 0;
|
||||
}
|
||||
else if (STREQN (ret + retind - 4, "done", 4) ||
|
||||
STREQN (ret + retind - 4, "then", 4) ||
|
||||
STREQN (ret + retind - 4, "else", 4) ||
|
||||
STREQN (ret + retind - 4, "elif", 4) ||
|
||||
STREQN (ret + retind - 4, "time", 4))
|
||||
{
|
||||
/* these are four-character reserved words that can be
|
||||
followed by a reserved word; anything else turns off
|
||||
the reserved-word-ok flag */
|
||||
/*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 1", line_number, ret+retind-4);*/
|
||||
tflags |= LEX_RESWDOK;
|
||||
lex_rwlen = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
tflags &= ~LEX_RESWDOK;
|
||||
/*itrace("parse_comsub:%d: found `%.4s', lex_reswdok -> 0", line_number, ret+retind-4);*/
|
||||
}
|
||||
tflags &= ~LEX_RESWDOK;
|
||||
}
|
||||
else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
|
||||
; /* don't modify LEX_RESWDOK if we're starting a comment */
|
||||
|
||||
Reference in New Issue
Block a user