Imported from ../bash-3.2.tar.gz.
This commit is contained in:
parent
95732b497d
commit
0628567a28
182 changed files with 17647 additions and 9477 deletions
122
parse.y
122
parse.y
|
@ -1,6 +1,6 @@
|
|||
/* Yacc grammar for bash. */
|
||||
|
||||
/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1989-2006 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
@ -118,7 +118,6 @@ extern int current_command_number;
|
|||
extern int sourcelevel;
|
||||
extern int posixly_correct;
|
||||
extern int last_command_exit_value;
|
||||
extern int interrupt_immediately;
|
||||
extern char *shell_name, *current_host_name;
|
||||
extern char *dist_version;
|
||||
extern int patch_level;
|
||||
|
@ -206,10 +205,6 @@ static void reset_readline_prompt __P((void));
|
|||
#endif
|
||||
static void print_prompt __P((void));
|
||||
|
||||
#if defined (HISTORY)
|
||||
char *history_delimiting_chars __P((void));
|
||||
#endif
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
static void set_line_mbstate __P((void));
|
||||
static char *shell_input_line_property = NULL;
|
||||
|
@ -1212,10 +1207,12 @@ yy_readline_get ()
|
|||
old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler);
|
||||
interrupt_immediately++;
|
||||
}
|
||||
terminate_immediately = 1;
|
||||
|
||||
current_readline_line = readline (current_readline_prompt ?
|
||||
current_readline_prompt : "");
|
||||
|
||||
terminate_immediately = 0;
|
||||
if (signal_is_ignored (SIGINT) == 0 && old_sigint)
|
||||
{
|
||||
interrupt_immediately--;
|
||||
|
@ -1347,10 +1344,16 @@ yy_stream_get ()
|
|||
if (bash_input.location.file)
|
||||
{
|
||||
if (interactive)
|
||||
interrupt_immediately++;
|
||||
{
|
||||
interrupt_immediately++;
|
||||
terminate_immediately++;
|
||||
}
|
||||
result = getc_with_restart (bash_input.location.file);
|
||||
if (interactive)
|
||||
interrupt_immediately--;
|
||||
{
|
||||
interrupt_immediately--;
|
||||
terminate_immediately--;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
@ -1869,7 +1872,6 @@ shell_getc (remove_quoted_newline)
|
|||
register int i;
|
||||
int c;
|
||||
unsigned char uc;
|
||||
static int mustpop = 0;
|
||||
|
||||
QUIT;
|
||||
|
||||
|
@ -2142,8 +2144,8 @@ discard_until (character)
|
|||
}
|
||||
|
||||
void
|
||||
execute_prompt_command (command)
|
||||
char *command;
|
||||
execute_variable_command (command, vname)
|
||||
char *command, *vname;
|
||||
{
|
||||
char *last_lastarg;
|
||||
sh_parser_state_t ps;
|
||||
|
@ -2153,7 +2155,7 @@ execute_prompt_command (command)
|
|||
if (last_lastarg)
|
||||
last_lastarg = savestring (last_lastarg);
|
||||
|
||||
parse_and_execute (savestring (command), "PROMPT_COMMAND", SEVAL_NONINT|SEVAL_NOHIST);
|
||||
parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
|
||||
|
||||
restore_parser_state (&ps);
|
||||
bind_variable ("_", last_lastarg, 0);
|
||||
|
@ -2556,7 +2558,7 @@ read_token (command)
|
|||
#endif /* ALIAS */
|
||||
|
||||
/* Read a single word from input. Start by skipping blanks. */
|
||||
while ((character = shell_getc (1)) != EOF && whitespace (character))
|
||||
while ((character = shell_getc (1)) != EOF && shellblank (character))
|
||||
;
|
||||
|
||||
if (character == EOF)
|
||||
|
@ -2716,6 +2718,7 @@ read_token (command)
|
|||
#define P_ALLOWESC 0x02
|
||||
#define P_DQUOTE 0x04
|
||||
#define P_COMMAND 0x08 /* parsing a command, so look for comments */
|
||||
#define P_BACKQUOTE 0x10 /* parsing a backquoted command substitution */
|
||||
|
||||
static char matched_pair_error;
|
||||
static char *
|
||||
|
@ -2725,12 +2728,13 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
|||
int *lenp, flags;
|
||||
{
|
||||
int count, ch, was_dollar, in_comment, check_comment;
|
||||
int pass_next_character, nestlen, ttranslen, start_lineno;
|
||||
int pass_next_character, backq_backslash, nestlen, ttranslen, start_lineno;
|
||||
char *ret, *nestret, *ttrans;
|
||||
int retind, retsize, rflags;
|
||||
|
||||
/* itrace("parse_matched_pair: open = %c close = %c", open, close); */
|
||||
count = 1;
|
||||
pass_next_character = was_dollar = in_comment = 0;
|
||||
pass_next_character = backq_backslash = was_dollar = in_comment = 0;
|
||||
check_comment = (flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0;
|
||||
|
||||
/* RFLAGS is the set of flags we want to pass to recursive calls. */
|
||||
|
@ -2742,11 +2746,8 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
|||
start_lineno = line_number;
|
||||
while (count)
|
||||
{
|
||||
#if 0
|
||||
ch = shell_getc ((qc != '\'' || (flags & P_ALLOWESC)) && pass_next_character == 0);
|
||||
#else
|
||||
ch = shell_getc (qc != '\'' && pass_next_character == 0);
|
||||
#endif
|
||||
ch = shell_getc (qc != '\'' && pass_next_character == 0 && backq_backslash == 0);
|
||||
|
||||
if (ch == EOF)
|
||||
{
|
||||
free (ret);
|
||||
|
@ -2770,10 +2771,19 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
|||
|
||||
continue;
|
||||
}
|
||||
/* Not exactly right yet */
|
||||
else if (check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind -1])))
|
||||
/* 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(check_comment && in_comment == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || whitespace (ret[retind - 1])))
|
||||
in_comment = 1;
|
||||
|
||||
/* last char was backslash inside backquoted command substitution */
|
||||
if (backq_backslash)
|
||||
{
|
||||
backq_backslash = 0;
|
||||
/* Placeholder for adding special characters */
|
||||
}
|
||||
|
||||
if (pass_next_character) /* last char was backslash */
|
||||
{
|
||||
pass_next_character = 0;
|
||||
|
@ -2798,11 +2808,9 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
|||
}
|
||||
else if MBTEST(ch == close) /* ending delimiter */
|
||||
count--;
|
||||
#if 1
|
||||
/* handle nested ${...} specially. */
|
||||
else if MBTEST(open != close && was_dollar && open == '{' && ch == open) /* } */
|
||||
count++;
|
||||
#endif
|
||||
else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */
|
||||
count++;
|
||||
|
||||
|
@ -2814,6 +2822,10 @@ parse_matched_pair (qc, open, close, lenp, flags)
|
|||
{
|
||||
if MBTEST((flags & P_ALLOWESC) && ch == '\\')
|
||||
pass_next_character++;
|
||||
#if 0
|
||||
else if MBTEST((flags & P_BACKQUOTE) && ch == '\\')
|
||||
backq_backslash++;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2896,18 +2908,24 @@ add_nestret:
|
|||
}
|
||||
FREE (nestret);
|
||||
}
|
||||
#if 0
|
||||
else if MBTEST(qc == '`' && (ch == '"' || ch == '\'') && in_comment == 0)
|
||||
{
|
||||
nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags);
|
||||
/* Add P_BACKQUOTE so backslash quotes the next character and
|
||||
shell_getc does the right thing with \<newline>. We do this for
|
||||
a measure of backwards compatibility -- it's not strictly the
|
||||
right POSIX thing. */
|
||||
nestret = parse_matched_pair (0, ch, ch, &nestlen, rflags|P_BACKQUOTE);
|
||||
goto add_nestret;
|
||||
}
|
||||
else if MBTEST(was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
|
||||
#endif
|
||||
else if MBTEST(open != '`' && was_dollar && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */
|
||||
/* check for $(), $[], or ${} inside quoted string. */
|
||||
{
|
||||
if (open == ch) /* undo previous increment */
|
||||
count--;
|
||||
if (ch == '(') /* ) */
|
||||
nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags);
|
||||
nestret = parse_matched_pair (0, '(', ')', &nestlen, rflags & ~P_DQUOTE);
|
||||
else if (ch == '{') /* } */
|
||||
nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|rflags);
|
||||
else if (ch == '[') /* ] */
|
||||
|
@ -2933,8 +2951,8 @@ static int
|
|||
parse_dparen (c)
|
||||
int c;
|
||||
{
|
||||
int cmdtyp, len, sline;
|
||||
char *wval, *wv2;
|
||||
int cmdtyp, sline;
|
||||
char *wval;
|
||||
WORD_DESC *wd;
|
||||
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
|
@ -2946,7 +2964,6 @@ parse_dparen (c)
|
|||
{
|
||||
wd = alloc_word_desc ();
|
||||
wd->word = wval;
|
||||
wd = make_word (wval);
|
||||
yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL);
|
||||
return (ARITH_FOR_EXPRS);
|
||||
}
|
||||
|
@ -3496,7 +3513,7 @@ read_token_word (character)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Try to locale)-expand the converted string. */
|
||||
/* Try to locale-expand the converted string. */
|
||||
ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen);
|
||||
free (ttok);
|
||||
|
||||
|
@ -3578,7 +3595,7 @@ read_token_word (character)
|
|||
FREE (ttok);
|
||||
all_digit_token = 0;
|
||||
compound_assignment = 1;
|
||||
#if 0
|
||||
#if 1
|
||||
goto next_character;
|
||||
#else
|
||||
goto got_token; /* ksh93 seems to do this */
|
||||
|
@ -3676,8 +3693,8 @@ got_token:
|
|||
if (dollar_present)
|
||||
the_word->flags |= W_HASDOLLAR;
|
||||
if (quoted)
|
||||
the_word->flags |= W_QUOTED;
|
||||
if (compound_assignment)
|
||||
the_word->flags |= W_QUOTED; /*(*/
|
||||
if (compound_assignment && token[token_index-1] == ')')
|
||||
the_word->flags |= W_COMPASSIGN;
|
||||
/* A word is an assignment if it appears at the beginning of a
|
||||
simple command, or after another assignment word. This is
|
||||
|
@ -3695,7 +3712,9 @@ got_token:
|
|||
struct builtin *b;
|
||||
b = builtin_address_internal (token, 0);
|
||||
if (b && (b->flags & ASSIGNMENT_BUILTIN))
|
||||
parser_state |= PST_ASSIGNOK;
|
||||
parser_state |= PST_ASSIGNOK;
|
||||
else if (STREQ (token, "eval") || STREQ (token, "let"))
|
||||
parser_state |= PST_ASSIGNOK;
|
||||
}
|
||||
|
||||
yylval.word = the_word;
|
||||
|
@ -3974,7 +3993,7 @@ decode_prompt_string (string)
|
|||
int last_exit_value;
|
||||
#if defined (PROMPT_STRING_DECODE)
|
||||
int result_size, result_index;
|
||||
int c, n;
|
||||
int c, n, i;
|
||||
char *temp, octal_string[4];
|
||||
struct tm *tm;
|
||||
time_t the_time;
|
||||
|
@ -4136,7 +4155,7 @@ decode_prompt_string (string)
|
|||
case 'W':
|
||||
{
|
||||
/* Use the value of PWD because it is much more efficient. */
|
||||
char t_string[PATH_MAX], *t;
|
||||
char t_string[PATH_MAX];
|
||||
int tlen;
|
||||
|
||||
temp = get_string_value ("PWD");
|
||||
|
@ -4246,9 +4265,12 @@ decode_prompt_string (string)
|
|||
break;
|
||||
}
|
||||
temp = (char *)xmalloc (3);
|
||||
temp[0] = '\001';
|
||||
temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
|
||||
temp[2] = '\0';
|
||||
n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
|
||||
i = 0;
|
||||
if (n == CTLESC || n == CTLNUL)
|
||||
temp[i++] = CTLESC;
|
||||
temp[i++] = n;
|
||||
temp[i] = '\0';
|
||||
goto add_string;
|
||||
#endif /* READLINE */
|
||||
|
||||
|
@ -4344,15 +4366,15 @@ yyerror (msg)
|
|||
}
|
||||
|
||||
static char *
|
||||
error_token_from_token (token)
|
||||
int token;
|
||||
error_token_from_token (tok)
|
||||
int tok;
|
||||
{
|
||||
char *t;
|
||||
|
||||
if (t = find_token_in_alist (token, word_token_alist, 0))
|
||||
if (t = find_token_in_alist (tok, word_token_alist, 0))
|
||||
return t;
|
||||
|
||||
if (t = find_token_in_alist (token, other_token_alist, 0))
|
||||
if (t = find_token_in_alist (tok, other_token_alist, 0))
|
||||
return t;
|
||||
|
||||
t = (char *)NULL;
|
||||
|
@ -4686,18 +4708,21 @@ parse_compound_assignment (retlenp)
|
|||
int *retlenp;
|
||||
{
|
||||
WORD_LIST *wl, *rl;
|
||||
int tok, orig_line_number, orig_token_size;
|
||||
int tok, orig_line_number, orig_token_size, orig_last_token, assignok;
|
||||
char *saved_token, *ret;
|
||||
|
||||
saved_token = token;
|
||||
orig_token_size = token_buffer_size;
|
||||
orig_line_number = line_number;
|
||||
orig_last_token = last_read_token;
|
||||
|
||||
last_read_token = WORD; /* WORD to allow reserved words here */
|
||||
|
||||
token = (char *)NULL;
|
||||
token_buffer_size = 0;
|
||||
|
||||
assignok = parser_state&PST_ASSIGNOK; /* XXX */
|
||||
|
||||
wl = (WORD_LIST *)NULL; /* ( */
|
||||
parser_state |= PST_COMPASSIGN;
|
||||
|
||||
|
@ -4740,7 +4765,8 @@ parse_compound_assignment (retlenp)
|
|||
jump_to_top_level (DISCARD);
|
||||
}
|
||||
|
||||
last_read_token = WORD;
|
||||
last_read_token = orig_last_token; /* XXX - was WORD? */
|
||||
|
||||
if (wl)
|
||||
{
|
||||
rl = REVERSE_LIST (wl, WORD_LIST *);
|
||||
|
@ -4752,6 +4778,10 @@ parse_compound_assignment (retlenp)
|
|||
|
||||
if (retlenp)
|
||||
*retlenp = (ret && *ret) ? strlen (ret) : 0;
|
||||
|
||||
if (assignok)
|
||||
parser_state |= PST_ASSIGNOK;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue