X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=bashline.c;h=fbd196a718c24a622986cf5301b787132eb74be7;hb=d166f048818e10cf3799aa24a174fb22835f1acc;hp=7d2e5d7f8a5c6451689ca79f228d7ab960564079;hpb=ccc6cda312fea9f0468ee65b8f368e9653e1380b;p=platform%2Fupstream%2Fbash.git diff --git a/bashline.c b/bashline.c index 7d2e5d7..fbd196a 100644 --- a/bashline.c +++ b/bashline.c @@ -56,6 +56,11 @@ extern void bash_brace_completion (); static void shell_expand_line (); static void display_shell_version (), operate_and_get_next (); static void history_expand_line (), bash_ignore_filenames (); +#ifdef ALIAS +static void alias_expand_line (); +#endif +static void history_and_alias_expand_line (); +static void cleanup_expansion_error (), set_up_new_line (); /* Helper functions for Readline. */ static int bash_directory_completion_hook (); @@ -194,6 +199,11 @@ initialize_readline () rl_add_defun ("history-expand-line", (Function *)history_expand_line, -1); rl_bind_key_in_map ('^', (Function *)history_expand_line, emacs_meta_keymap); +#ifdef ALIAS + rl_add_defun ("alias-expand-line", (Function *)alias_expand_line, -1); + rl_add_defun ("history-and-alias-expand-line", (Function *)history_and_alias_expand_line, -1); +#endif + /* Backwards compatibility. */ rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1); @@ -285,7 +295,7 @@ initialize_readline () enable_hostname_completion (perform_hostname_completion); /* characters that need to be quoted when appearing in filenames. */ - rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!"; + rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:"; rl_filename_quoting_function = bash_quote_filename; rl_filename_dequoting_function = bash_dequote_filename; rl_char_is_quoted_p = char_is_quoted; @@ -592,13 +602,13 @@ vi_edit_and_execute_command (count, c) the end of the history because fc ignores the last command (assumes it's supposed to deal with the command before the `fc'). */ using_history (); - add_history (rl_line_buffer); - add_history (""); + bash_add_history (rl_line_buffer); + bash_add_history (""); history_lines_this_session++; using_history (); command = savestring (VI_EDIT_COMMAND); } - parse_and_execute (command, "v", -1); + parse_and_execute (command, "v", SEVAL_NOHIST); rl_line_buffer[0] = '\0'; /* XXX */ } #endif /* VI_MODE */ @@ -688,8 +698,18 @@ attempt_shell_completion (text, start, end) assignments. */ } - /* Special handling for command substitution. */ - if (*text == '`' && unclosed_pair (rl_line_buffer, start, "`")) + /* Check that we haven't incorrectly flagged a closed command substitution + as indicating we're in a command position. */ + if (in_command_position && rl_line_buffer[ti] == '`' && *text != '`' && + unclosed_pair (rl_line_buffer, 0, "`") == 0) + in_command_position = 0; + + /* Special handling for command substitution. If *TEXT is a backquote, + it can be the start or end of an old-style command substitution, or + unmatched. If it's unmatched, both calls to unclosed_pair will + succeed. */ + if (*text == '`' && unclosed_pair (rl_line_buffer, start, "`") && + unclosed_pair (rl_line_buffer, end, "`")) matches = completion_matches (text, command_subst_completion_function); /* Variable name? */ @@ -928,7 +948,7 @@ command_word_completion_function (hint_text, state) } else { - int match; + int match, freetemp; char *temp; if (absolute_program (hint)) @@ -948,6 +968,7 @@ command_word_completion_function (hint_text, state) } else temp = savestring (val); + freetemp = 1; } else { @@ -956,12 +977,12 @@ command_word_completion_function (hint_text, state) if (temp) { temp++; - match = strncmp (temp, hint, hint_len) == 0; + freetemp = match = strncmp (temp, hint, hint_len) == 0; if (match) temp = savestring (temp); } else - match = 0; + freetemp = match = 0; } /* If we have found a match, and it is an executable file or a @@ -974,12 +995,15 @@ command_word_completion_function (hint_text, state) } else { + if (freetemp) + free (temp); free (val); goto inner; } } } +/* Completion inside an unterminated command substitution. */ static char * command_subst_completion_function (text, state) char *text; @@ -1148,19 +1172,23 @@ history_expand_line_internal (line) char *new_line; new_line = pre_process_line (line, 0, 0); - return new_line; + return (new_line == line) ? savestring (line) : new_line; } #if defined (ALIAS) -/* Perform alias expansion on LINE and return the new line. */ -static char * -alias_expand_line_internal (line) - char *line; +/* Expand aliases in the current readline line. */ +static void +alias_expand_line (ignore) + int ignore; { - char *alias_line; + char *new_line; + + new_line = alias_expand (rl_line_buffer); - alias_line = alias_expand (line); - return alias_line; + if (new_line) + set_up_new_line (new_line); + else + cleanup_expansion_error (); } #endif @@ -1173,7 +1201,8 @@ cleanup_expansion_error () fprintf (rl_outstream, "\r\n"); to_free = pre_process_line (rl_line_buffer, 1, 0); - free (to_free); + if (to_free != rl_line_buffer) + free (to_free); putc ('\r', rl_outstream); rl_forced_update_display (); } @@ -1244,6 +1273,8 @@ history_and_alias_expand_line (ignore) char *new_line; new_line = pre_process_line (rl_line_buffer, 0, 0); + if (new_line == rl_line_buffer) + new_line = savestring (new_line); #if defined (ALIAS) if (new_line) @@ -1272,6 +1303,8 @@ shell_expand_line (ignore) WORD_LIST *expanded_string; new_line = pre_process_line (rl_line_buffer, 0, 0); + if (new_line == rl_line_buffer) + new_line = savestring (new_line); #if defined (ALIAS) if (new_line) @@ -1296,7 +1329,9 @@ shell_expand_line (ignore) /* If there is variable expansion to perform, do that as a separate operation to be undone. */ - expanded_string = expand_string (rl_line_buffer, 0); + new_line = savestring (rl_line_buffer); + expanded_string = expand_string (new_line, 0); + FREE (new_line); if (expanded_string == 0) { new_line = xmalloc (1); @@ -1862,7 +1897,44 @@ bash_dequote_filename (text, quote_char) return ret; } -/* Quote a filename using double quotes. */ +/* Quote characters that the readline completion code would treat as + word break characters with backslashes. Pass backslash-quoted + characters through without examination. */ +static char * +quote_word_break_chars (text) + char *text; +{ + char *ret, *r, *s; + int l; + + l = strlen (text); + ret = xmalloc ((2 * l) + 1); + for (s = text, r = ret; *s; s++) + { + /* Pass backslash-quoted characters through, including the backslash. */ + if (*s == '\\') + { + *r++ = '\\'; + *r++ = *++s; + if (*s == '\0') + break; + continue; + } + /* OK, we have an unquoted character. Check its presence in + rl_completer_word_break_characters. */ + if (strchr (rl_completer_word_break_characters, *s)) + *r++ = '\\'; + *r++ = *s; + } + *r = '\0'; + return ret; +} + +/* Quote a filename using double quotes, single quotes, or backslashes + depending on the value of completion_quoting_style. If we're + completing using backslashes, we need to quote some additional + characters (those that readline treats as word breaks), so we call + quote_word_break_chars on the result. */ static char * bash_quote_filename (s, rtype, qcp) char *s; @@ -1896,6 +1968,13 @@ bash_quote_filename (s, rtype, qcp) else if (*qcp == '\0' && history_expansion && cs == COMPLETE_DQUOTE && history_expansion_inhibited == 0 && strchr (mtext, '!')) cs = COMPLETE_BSQUOTE; + + if (*qcp == '"' && history_expansion && cs == COMPLETE_DQUOTE && + history_expansion_inhibited == 0 && strchr (mtext, '!')) + { + cs = COMPLETE_BSQUOTE; + *qcp = '\0'; + } #endif switch (cs) @@ -1914,6 +1993,15 @@ bash_quote_filename (s, rtype, qcp) if (mtext != s) free (mtext); + /* We may need to quote additional characters: those that readline treats + as word breaks that are not quoted by backslash_quote. */ + if (rtext && cs == COMPLETE_BSQUOTE) + { + mtext = quote_word_break_chars (rtext); + free (rtext); + rtext = mtext; + } + /* Leave the opening quote intact. The readline completion code takes care of avoiding doubled opening quotes. */ rlen = strlen (rtext);