mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-22 05:17:59 +02:00
327 lines
9.3 KiB
Diff
327 lines
9.3 KiB
Diff
*** ../bash-4.0/parse.y 2009-01-08 08:29:12.000000000 -0500
|
|
--- parse.y 2009-03-06 20:32:35.000000000 -0500
|
|
***************
|
|
*** 1616,1623 ****
|
|
int *ret;
|
|
|
|
! ret = (int *)xmalloc (3 * sizeof (int));
|
|
ret[0] = last_read_token;
|
|
ret[1] = token_before_that;
|
|
ret[2] = two_tokens_ago;
|
|
return ret;
|
|
}
|
|
--- 1616,1624 ----
|
|
int *ret;
|
|
|
|
! ret = (int *)xmalloc (4 * sizeof (int));
|
|
ret[0] = last_read_token;
|
|
ret[1] = token_before_that;
|
|
ret[2] = two_tokens_ago;
|
|
+ ret[3] = current_token;
|
|
return ret;
|
|
}
|
|
***************
|
|
*** 1632,1635 ****
|
|
--- 1633,1637 ----
|
|
token_before_that = ts[1];
|
|
two_tokens_ago = ts[2];
|
|
+ current_token = ts[3];
|
|
}
|
|
|
|
***************
|
|
*** 2669,2672 ****
|
|
--- 2671,2675 ----
|
|
word_desc_to_read = (WORD_DESC *)NULL;
|
|
|
|
+ current_token = '\n'; /* XXX */
|
|
last_read_token = '\n';
|
|
token_to_read = '\n';
|
|
***************
|
|
*** 2916,2919 ****
|
|
--- 2919,2923 ----
|
|
#define P_COMMAND 0x08 /* parsing a command, so look for comments */
|
|
#define P_BACKQUOTE 0x10 /* parsing a backquoted command substitution */
|
|
+ #define P_ARRAYSUB 0x20 /* parsing a [...] array subscript for assignment */
|
|
|
|
/* Lexical state while parsing a grouping construct or $(...). */
|
|
***************
|
|
*** 2928,2931 ****
|
|
--- 2932,2936 ----
|
|
#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */
|
|
#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */
|
|
+ #define LEX_INWORD 0x400
|
|
|
|
#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|')
|
|
***************
|
|
*** 2963,2967 ****
|
|
int retind, retsize, rflags;
|
|
|
|
! /* itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
|
|
count = 1;
|
|
tflags = 0;
|
|
--- 2968,2972 ----
|
|
int retind, retsize, rflags;
|
|
|
|
! /*itrace("parse_matched_pair: open = %c close = %c flags = %d", open, close, flags); */
|
|
count = 1;
|
|
tflags = 0;
|
|
***************
|
|
*** 3130,3133 ****
|
|
--- 3135,3140 ----
|
|
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
|
|
***************
|
|
*** 3146,3149 ****
|
|
--- 3153,3157 ----
|
|
/* check for $(), $[], or ${} inside quoted string. */
|
|
{
|
|
+ parse_dollar_word:
|
|
if (open == ch) /* undo previous increment */
|
|
count--;
|
|
***************
|
|
*** 3180,3184 ****
|
|
int *lenp, flags;
|
|
{
|
|
! int count, ch, peekc, tflags, lex_rwlen, lex_firstind;
|
|
int nestlen, ttranslen, start_lineno;
|
|
char *ret, *nestret, *ttrans, *heredelim;
|
|
--- 3188,3192 ----
|
|
int *lenp, flags;
|
|
{
|
|
! int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind;
|
|
int nestlen, ttranslen, start_lineno;
|
|
char *ret, *nestret, *ttrans, *heredelim;
|
|
***************
|
|
*** 3201,3205 ****
|
|
|
|
start_lineno = line_number;
|
|
! lex_rwlen = 0;
|
|
|
|
heredelim = 0;
|
|
--- 3209,3213 ----
|
|
|
|
start_lineno = line_number;
|
|
! lex_rwlen = lex_wlen = 0;
|
|
|
|
heredelim = 0;
|
|
***************
|
|
*** 3268,3271 ****
|
|
--- 3276,3319 ----
|
|
}
|
|
|
|
+ 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)
|
|
***************
|
|
*** 3317,3321 ****
|
|
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
|
|
ret[retind++] = peekc;
|
|
! /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch); */
|
|
tflags |= LEX_RESWDOK;
|
|
lex_rwlen = 0;
|
|
--- 3365,3369 ----
|
|
RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64);
|
|
ret[retind++] = peekc;
|
|
! /*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
|
|
tflags |= LEX_RESWDOK;
|
|
lex_rwlen = 0;
|
|
***************
|
|
*** 3325,3330 ****
|
|
{
|
|
shell_ungetc (peekc);
|
|
- tflags |= LEX_RESWDOK;
|
|
/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
|
|
lex_rwlen = 0;
|
|
continue;
|
|
--- 3373,3378 ----
|
|
{
|
|
shell_ungetc (peekc);
|
|
/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/
|
|
+ tflags |= LEX_RESWDOK;
|
|
lex_rwlen = 0;
|
|
continue;
|
|
***************
|
|
*** 3365,3369 ****
|
|
tflags &= ~LEX_RESWDOK;
|
|
}
|
|
! else if (shellbreak (ch) == 0)
|
|
{
|
|
tflags &= ~LEX_RESWDOK;
|
|
--- 3413,3419 ----
|
|
tflags &= ~LEX_RESWDOK;
|
|
}
|
|
! else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
|
|
! ; /* don't turn off LEX_RESWDOK if we're starting a comment */
|
|
! else if MBTEST(shellbreak (ch) == 0)
|
|
{
|
|
tflags &= ~LEX_RESWDOK;
|
|
***************
|
|
*** 3372,3375 ****
|
|
--- 3422,3426 ----
|
|
}
|
|
|
|
+ /* Might be the start of a here-doc delimiter */
|
|
if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<')
|
|
{
|
|
***************
|
|
*** 3395,3428 ****
|
|
else
|
|
shell_ungetc (peekc);
|
|
! tflags |= LEX_HEREDELIM;
|
|
! lex_firstind = -1;
|
|
continue;
|
|
}
|
|
else
|
|
! ch = peekc; /* fall through and continue XXX - this skips comments if peekc == '#' */
|
|
}
|
|
! /* 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])))
|
|
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 */
|
|
{
|
|
RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
|
|
--- 3446,3466 ----
|
|
else
|
|
shell_ungetc (peekc);
|
|
! if (peekc != '<')
|
|
! {
|
|
! tflags |= LEX_HEREDELIM;
|
|
! lex_firstind = -1;
|
|
! }
|
|
continue;
|
|
}
|
|
else
|
|
! ch = peekc; /* fall through and continue XXX */
|
|
}
|
|
! else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0)))
|
|
! {
|
|
! /*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/
|
|
tflags |= LEX_INCOMMENT;
|
|
+ }
|
|
|
|
! if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */
|
|
{
|
|
RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64);
|
|
***************
|
|
*** 4249,4253 ****
|
|
(token_index == 0 && (parser_state&PST_COMPASSIGN))))
|
|
{
|
|
! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0);
|
|
if (ttok == &matched_pair_error)
|
|
return -1; /* Bail immediately. */
|
|
--- 4287,4291 ----
|
|
(token_index == 0 && (parser_state&PST_COMPASSIGN))))
|
|
{
|
|
! ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB);
|
|
if (ttok == &matched_pair_error)
|
|
return -1; /* Bail immediately. */
|
|
***************
|
|
*** 4450,4453 ****
|
|
--- 4488,4492 ----
|
|
case AND_AND:
|
|
case BANG:
|
|
+ case BAR_AND:
|
|
case DO:
|
|
case DONE:
|
|
***************
|
|
*** 5184,5188 ****
|
|
if (interactive && EOF_Reached)
|
|
EOF_Reached = 0;
|
|
! last_command_exit_value = EX_USAGE;
|
|
return;
|
|
}
|
|
--- 5223,5227 ----
|
|
if (interactive && EOF_Reached)
|
|
EOF_Reached = 0;
|
|
! last_command_exit_value = EX_BADUSAGE;
|
|
return;
|
|
}
|
|
***************
|
|
*** 5199,5203 ****
|
|
print_offending_line ();
|
|
|
|
! last_command_exit_value = EX_USAGE;
|
|
return;
|
|
}
|
|
--- 5238,5242 ----
|
|
print_offending_line ();
|
|
|
|
! last_command_exit_value = EX_BADUSAGE;
|
|
return;
|
|
}
|
|
***************
|
|
*** 5230,5234 ****
|
|
}
|
|
|
|
! last_command_exit_value = EX_USAGE;
|
|
}
|
|
|
|
--- 5269,5273 ----
|
|
}
|
|
|
|
! last_command_exit_value = EX_BADUSAGE;
|
|
}
|
|
|