commit bash-20090305 snapshot

This commit is contained in:
Chet Ramey
2011-12-08 20:06:13 -05:00
parent 6932f7f549
commit 602bb73910
38 changed files with 13470 additions and 5936 deletions
+94 -51
View File
@@ -2670,6 +2670,7 @@ reset_parser ()
FREE (word_desc_to_read);
word_desc_to_read = (WORD_DESC *)NULL;
current_token = '\n'; /* XXX */
last_read_token = '\n';
token_to_read = '\n';
}
@@ -2917,19 +2918,21 @@ tokword:
#define P_DQUOTE 0x04
#define P_COMMAND 0x08 /* parsing a command, so look for comments */
#define P_BACKQUOTE 0x10 /* parsing a backquoted command substitution */
#define P_ARRAY 0x20 /* parsing a [...] array assignment */
#define P_ARRAYSUB 0x20 /* parsing a [...] array subscript for assignment */
/* Lexical state while parsing a grouping construct or $(...). */
#define LEX_WASDOL 0x001
#define LEX_CKCOMMENT 0x002
#define LEX_INCOMMENT 0x004
#define LEX_PASSNEXT 0x008
#define LEX_RESWDOK 0x010
#define LEX_CKCASE 0x020
#define LEX_INCASE 0x040
#define LEX_INHEREDOC 0x080
#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
#define LEX_WASDOL 0x0001
#define LEX_CKCOMMENT 0x0002
#define LEX_INCOMMENT 0x0004
#define LEX_PASSNEXT 0x0008
#define LEX_RESWDOK 0x0010
#define LEX_CKCASE 0x0020
#define LEX_INCASE 0x0040
#define LEX_INHEREDOC 0x0080
#define LEX_HEREDELIM 0x0100 /* reading here-doc delimiter */
#define LEX_STRIPDOC 0x0200 /* <<- strip tabs from here doc delim */
#define LEX_WASQUOTED 0x0400
#define LEX_INWORD 0x0800
#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
@@ -2952,6 +2955,11 @@ tokword:
} \
} while (0)
/* Not exactly right yet, should handle shell metacharacters, too. If
any changes are made to this test, make analogous changes to subst.c:
extract_delimited_string(). */
#define COMMENT_BEGIN(x) ((x) == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
static char matched_pair_error;
static char *
@@ -2965,7 +2973,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
char *ret, *nestret, *ttrans;
int retind, retsize, rflags;
/* itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
/*itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
count = 1;
tflags = 0;
@@ -3009,10 +3017,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
continue;
}
/* Not exactly right yet, should handle shell metacharacters, too. If
any changes are made to this test, make analogous changes to subst.c:
extract_delimited_string(). */
else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && COMMENT_BEGIN (ch))
tflags |= LEX_INCOMMENT;
if (tflags & LEX_PASSNEXT) /* last char was backslash */
@@ -3132,6 +3137,8 @@ parse_matched_pair (qc, open, close, lenp, flags)
APPEND_NESTRET ();
FREE (nestret);
}
else if ((flags & P_ARRAYSUB) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
goto parse_dollar_word;
}
/* Parse an old-style command substitution within double quotes as a
single word. */
@@ -3148,6 +3155,7 @@ parse_matched_pair (qc, open, close, lenp, flags)
else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
/* check for $(), $[], or ${} inside quoted string. */
{
parse_dollar_word:
if (open == ch) /* undo previous increment */
count--;
if (ch == '(') /* ) */
@@ -3182,14 +3190,14 @@ parse_comsub (qc, open, close, lenp, flags)
int open, close;
int *lenp, flags;
{
int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
int nestlen, ttranslen, start_lineno;
char *ret, *nestret, *ttrans, *heredelim;
int retind, retsize, rflags, hdlen;
/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/
count = 1;
tflags = LEX_RESWDOK;
tflags = LEX_RESWDOK|LEX_INWORD;
if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0)
tflags |= LEX_CKCASE;
@@ -3203,7 +3211,7 @@ parse_comsub (qc, open, close, lenp, flags)
retind = 0;
start_lineno = line_number;
lex_rwlen = 0;
lex_rwlen = lex_wlen = 0;
heredelim = 0;
lex_firstind = -1;
@@ -3270,6 +3278,46 @@ eof_error:
continue;
}
if (tflags & LEX_PASSNEXT) /* last char was backslash */
{
/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
tflags &= ~LEX_PASSNEXT;
if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
{
if (retind > 0)
retind--; /* swallow previously-added backslash */
continue;
}
RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
if MBTEST(ch == CTLESC || ch == CTLNUL)
ret[retind++] = CTLESC;
ret[retind++] = ch;
continue;
}
/* If this is a shell break character, we are not in a word. If not,
we either start or continue a word. */
if MBTEST(shellbreak (ch))
{
tflags &= ~LEX_INWORD;
/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/
}
else
{
if (tflags & LEX_INWORD)
{
lex_wlen++;
/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/
}
else
{
/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/
tflags |= LEX_INWORD;
lex_wlen = 0;
}
}
/* Skip whitespace */
if MBTEST(shellblank (ch) && lex_rwlen == 0)
{
@@ -3319,7 +3367,7 @@ eof_error:
{
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
ret[retind++] = peekc;
/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch); */
/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
tflags |= LEX_RESWDOK;
lex_rwlen = 0;
continue;
@@ -3327,8 +3375,8 @@ eof_error:
else if (ch == '\n' || COMSUB_META(ch))
{
shell_ungetc (peekc);
tflags |= LEX_RESWDOK;
/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
tflags |= LEX_RESWDOK;
lex_rwlen = 0;
continue;
}
@@ -3367,14 +3415,17 @@ eof_error:
}
tflags &= ~LEX_RESWDOK;
}
else if (shellbreak (ch) == 0)
else if MBTEST((tflags & LEX_CKCOMMENT) && ((lex_rwlen == 0 && ch == '#') || COMMENT_BEGIN(ch)))
; /* don't turn off LEX_RESWDOK if we're starting a comment */
else if MBTEST(shellbreak (ch) == 0)
{
tflags &= ~LEX_RESWDOK;
/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
}
}
if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
/* Might be the start of a here-doc delimiter */
if MBTEST((tflags & (LEX_PASSNEXT|LEX_INCOMMENT)) == 0 && (tflags & LEX_CKCASE) && ch == '<')
{
/* Add this character. */
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
@@ -3397,36 +3448,27 @@ eof_error:
}
else
shell_ungetc (peekc);
tflags |= LEX_HEREDELIM;
lex_firstind = -1;
if (peekc != '<')
{
tflags |= LEX_HEREDELIM;
lex_firstind = -1;
}
continue;
}
else
ch = peekc; /* fall through and continue XXX - this skips comments if peekc == '#' */
ch = peekc; /* fall through and continue XXX */
}
/* Not exactly right yet, should handle shell metacharacters, too. If
any changes are made to this test, make analogous changes to subst.c:
extract_delimited_string(). */
else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1])))
#if 0
else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0) || COMMENT_BEGIN(ch)))
#else
else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
#endif
{
/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
tflags |= LEX_INCOMMENT;
}
if (tflags & LEX_PASSNEXT) /* last char was backslash */
{
tflags &= ~LEX_PASSNEXT;
if (qc != '\'' && ch == '\n') /* double-quoted \<newline> disappears. */
{
if (retind > 0)
retind--; /* swallow previously-added backslash */
continue;
}
RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
if MBTEST(ch == CTLESC || ch == CTLNUL)
ret[retind++] = CTLESC;
ret[retind++] = ch;
continue;
}
else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
{
RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
ret[retind++] = CTLESC;
@@ -4251,7 +4293,7 @@ read_token_word (character)
((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) ||
(token_index == 0 && (parser_state&PST_COMPASSIGN))))
{
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
if (ttok == &matched_pair_error)
return -1; /* Bail immediately. */
RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2,
@@ -4452,6 +4494,7 @@ reserved_word_acceptable (toksym)
case '}': /* XXX */
case AND_AND:
case BANG:
case BAR_AND:
case DO:
case DONE:
case ELIF:
@@ -5186,7 +5229,7 @@ report_syntax_error (message)
parser_error (line_number, "%s", message);
if (interactive && EOF_Reached)
EOF_Reached = 0;
last_command_exit_value = EX_USAGE;
last_command_exit_value = EX_BADUSAGE;
return;
}
@@ -5201,7 +5244,7 @@ report_syntax_error (message)
if (interactive == 0)
print_offending_line ();
last_command_exit_value = EX_USAGE;
last_command_exit_value = EX_BADUSAGE;
return;
}
@@ -5232,7 +5275,7 @@ report_syntax_error (message)
EOF_Reached = 0;
}
last_command_exit_value = EX_USAGE;
last_command_exit_value = EX_BADUSAGE;
}
/* ??? Needed function. ??? We have to be able to discard the constructs