diff options
author | Jari Aalto <jari.aalto@cante.net> | 2006-10-10 14:15:34 +0000 |
---|---|---|
committer | Jari Aalto <jari.aalto@cante.net> | 2009-09-12 16:46:58 +0000 |
commit | 0628567a28f3510f506ae46cb9b24b73a6d2dc5d (patch) | |
tree | da84934c41272cdc655694846c15c1c5db807445 /parse.y | |
parent | 95732b497d12c98613bb3c5db16b61f377501a59 (diff) | |
download | android_external_bash-0628567a28f3510f506ae46cb9b24b73a6d2dc5d.tar.gz android_external_bash-0628567a28f3510f506ae46cb9b24b73a6d2dc5d.tar.bz2 android_external_bash-0628567a28f3510f506ae46cb9b24b73a6d2dc5d.zip |
Imported from ../bash-3.2.tar.gz.
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 122 |
1 files changed, 76 insertions, 46 deletions
@@ -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; } |