Files
bash/parse.y.diff
T
2011-12-08 20:06:13 -05:00

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;
}