commit bash-20111021 snapshot

This commit is contained in:
Chet Ramey
2012-01-09 08:30:31 -05:00
parent c5402025f1
commit 3d4f66ca82
14 changed files with 497 additions and 27 deletions
+28
View File
@@ -12342,3 +12342,31 @@ pcomplete.c
dequoting function in the cases (as best as it can figure) where
readline won't do it via rl_filename_completion_function. Based
on reports from <lolilolicon@gmail.com>
10/19
-----
bashline.c
- attempt_shell_completion: add call to set_directory_hook() to make
sure the rewrite functions are correct. It's cheap and doesn't
hurt
- command_word_completion_function: if completing a command name that
starts with `.' or `..', temporarily suppress the effects of the
`direxpand' option and restore the correct value after calling
rl_filename_completion_function. If it's enabled, the directory
name will be rewritten and no longer match `./' or `../'. Fixes
problem reported by Michael Kalisz <michael@kalisz.homelinux.net>
10/22
-----
builtins/history.def
- push_history: make sure remember_on_history is enabled before we
try to delete the last history entry -- the `history -s' command
might not have been saved. Fixes bug reported by
lester@vmw-les.eng.vmware.com
lib/readline/complete.c
- rl_callback_read_char: add calls to a macro CALLBACK_READ_RETURN
instead of straight return; add same call at end of function.
Placeholder for future work in deinstalling signal handlers when
readline is not active
+29
View File
@@ -12334,3 +12334,32 @@ doc/{bash.1,bashref.texi}
causes other redirection operators to apply for sh and Posix
compatibility reasons. Suggested by Greg Wooledge
<wooledg@eeg.ccf.org>
10/15
-----
pcomplete.c
- change pcomp_filename_completion_function to only run the filename
dequoting function in the cases (as best as it can figure) where
readline won't do it via rl_filename_completion_function. Based
on reports from <lolilolicon@gmail.com>
10/19
-----
bashline.c
- attempt_shell_completion: add call to set_directory_hook() to make
sure the rewrite functions are correct. It's cheap and doesn't
hurt
- command_word_completion_function: if completing a command name that
starts with `.' or `..', temporarily suppress the effects of the
`direxpand' option and restore the correct value after calling
rl_filename_completion_function. If it's enabled, the directory
name will be rewritten and no longer match `./' or `../'. Fixes
problem reported by Michael Kalisz <michael@kalisz.homelinux.net>
10/22
-----
builtins/history.def
- push_history: make sure remember_on_history is enabled before we
try to delete the last history entry -- the `history -s' command
might not have been saved. Fixes bug reported by
lester@vmw-les.eng.vmware.com
+11 -1
View File
@@ -1339,6 +1339,7 @@ attempt_shell_completion (text, start, end)
rl_filename_quote_characters = default_filename_quote_characters;
set_filename_bstab (rl_filename_quote_characters);
set_directory_hook ();
/* Determine if this could be a command word. It is if it appears at
the start of the line (ignoring preceding whitespace), or if it
@@ -1670,6 +1671,12 @@ command_word_completion_function (hint_text, state)
}
else
{
if (dircomplete_expand && path_dot_or_dotdot (filename_hint))
{
dircomplete_expand = 0;
set_directory_hook ();
dircomplete_expand = 1;
}
mapping_over = 4;
goto inner;
}
@@ -1870,6 +1877,9 @@ globword:
inner:
val = rl_filename_completion_function (filename_hint, istate);
if (mapping_over == 4 && dircomplete_expand)
set_directory_hook ();
istate = 1;
if (val == 0)
@@ -2028,7 +2038,7 @@ command_subst_completion_function (text, state)
rl_completion_suppress_append = 1;
}
if (!matches || !matches[cmd_index])
if (matches == 0 || matches[cmd_index] == 0)
{
rl_filename_quoting_desired = 0; /* disable quoting */
return ((char *)NULL);
+3 -2
View File
@@ -324,9 +324,10 @@ push_history (list)
If you don't want history -s to remove the compound command from the
history, change #if 0 to #if 1 below. */
#if 0
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
if (remember_on_history && hist_last_line_pushed == 0 &&
hist_last_line_added && bash_delete_last_history () == 0)
#else
if (hist_last_line_pushed == 0 &&
if (remember_on_history && hist_last_line_pushed == 0 &&
(hist_last_line_added ||
(current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
&& bash_delete_last_history () == 0)
+380
View File
@@ -0,0 +1,380 @@
This file is history.def, from which is created history.c.
It implements the builtin "history" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES history.c
$BUILTIN history
$FUNCTION history_builtin
$DEPENDS_ON HISTORY
$SHORT_DOC history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
Display or manipulate the history list.
Display the history list with line numbers, prefixing each modified
entry with a `*'. An argument of N lists only the last N entries.
Options:
-c clear the history list by deleting all of the entries
-d offset delete the history entry at offset OFFSET.
-a append history lines from this session to the history file
-n read all history lines not already read from the history file
-r read the history file and append the contents to the history
list
-w write the current history to the history file
and append them to the history list
-p perform history expansion on each ARG and display the result
without storing it in the history list
-s append the ARGs to the history list as a single entry
If FILENAME is given, it is used as the history file. Otherwise,
if $HISTFILE has a value, that is used, else ~/.bash_history.
If the $HISTTIMEFORMAT variable is set and not null, its value is used
as a format string for strftime(3) to print the time stamp associated
with each displayed history entry. No time stamps are printed otherwise.
Exit Status:
Returns success unless an invalid option is given or an error occurs.
$END
#include <config.h>
#if defined (HISTORY)
#include "../bashtypes.h"
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
#include "filecntl.h"
#include <errno.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../bashhist.h"
#include <readline/history.h>
#include "bashgetopt.h"
#include "common.h"
#if !defined (errno)
extern int errno;
#endif
extern int current_command_line_count;
extern int force_append_history; /* shopt -s histappend */
static char *histtime __P((HIST_ENTRY *, const char *));
static int display_history __P((WORD_LIST *));
static void push_history __P((WORD_LIST *));
static int expand_and_print_history __P((WORD_LIST *));
#define AFLAG 0x01
#define RFLAG 0x02
#define WFLAG 0x04
#define NFLAG 0x08
#define SFLAG 0x10
#define PFLAG 0x20
#define CFLAG 0x40
#define DFLAG 0x80
int
history_builtin (list)
WORD_LIST *list;
{
int flags, opt, result, old_history_lines, obase;
char *filename, *delete_arg;
intmax_t delete_offset;
flags = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "acd:npsrw")) != -1)
{
switch (opt)
{
case 'a':
flags |= AFLAG;
break;
case 'c':
flags |= CFLAG;
break;
case 'n':
flags |= NFLAG;
break;
case 'r':
flags |= RFLAG;
break;
case 'w':
flags |= WFLAG;
break;
case 's':
flags |= SFLAG;
break;
case 'd':
flags |= DFLAG;
delete_arg = list_optarg;
break;
case 'p':
#if defined (BANG_HISTORY)
flags |= PFLAG;
#endif
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
opt = flags & (AFLAG|RFLAG|WFLAG|NFLAG);
if (opt && opt != AFLAG && opt != RFLAG && opt != WFLAG && opt != NFLAG)
{
builtin_error (_("cannot use more than one of -anrw"));
return (EXECUTION_FAILURE);
}
/* clear the history, but allow other arguments to add to it again. */
if (flags & CFLAG)
{
bash_clear_history ();
if (list == 0)
return (EXECUTION_SUCCESS);
}
if (flags & SFLAG)
{
if (list)
push_history (list);
return (EXECUTION_SUCCESS);
}
#if defined (BANG_HISTORY)
else if (flags & PFLAG)
{
if (list)
return (expand_and_print_history (list));
return (sh_chkwrite (EXECUTION_SUCCESS));
}
#endif
else if (flags & DFLAG)
{
if ((legal_number (delete_arg, &delete_offset) == 0)
|| (delete_offset < history_base)
|| (delete_offset > (history_base + history_length)))
{
sh_erange (delete_arg, _("history position"));
return (EXECUTION_FAILURE);
}
opt = delete_offset;
result = bash_delete_histent (opt - history_base);
/* Since remove_history changes history_length, this can happen if
we delete the last history entry. */
if (where_history () > history_length)
history_set_pos (history_length);
return (result ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
else if ((flags & (AFLAG|RFLAG|NFLAG|WFLAG|CFLAG)) == 0)
{
result = display_history (list);
return (sh_chkwrite (result));
}
filename = list ? list->word->word : get_string_value ("HISTFILE");
result = EXECUTION_SUCCESS;
if (flags & AFLAG) /* Append session's history to file. */
result = maybe_append_history (filename);
else if (flags & WFLAG) /* Write entire history. */
result = write_history (filename);
else if (flags & RFLAG) /* Read entire file. */
result = read_history (filename);
else if (flags & NFLAG) /* Read `new' history from file. */
{
/* Read all of the lines in the file that we haven't already read. */
old_history_lines = history_lines_in_file;
obase = history_base;
using_history ();
result = read_history_range (filename, history_lines_in_file, -1);
using_history ();
history_lines_in_file = where_history ();
/* If we're rewriting the history file at shell exit rather than just
appending the lines from this session to it, the question is whether
we reset history_lines_this_session to 0, losing any history entries
we had before we read the new entries from the history file, or
whether we count the new entries we just read from the file as
history lines added during this session.
Right now, we do the latter. This will cause these history entries
to be written to the history file along with any intermediate entries
we add when we do a `history -a', but the alternative is losing
them altogether. */
if (force_append_history == 0)
history_lines_this_session += history_lines_in_file - old_history_lines +
history_base - obase;
}
return (result ? EXECUTION_FAILURE : EXECUTION_SUCCESS);
}
/* Accessors for HIST_ENTRY lists that are called HLIST. */
#define histline(i) (hlist[(i)]->line)
#define histdata(i) (hlist[(i)]->data)
static char *
histtime (hlist, histtimefmt)
HIST_ENTRY *hlist;
const char *histtimefmt;
{
static char timestr[128];
time_t t;
t = history_get_time (hlist);
if (t)
strftime (timestr, sizeof (timestr), histtimefmt, localtime (&t));
else
strcpy (timestr, "??");
return timestr;
}
static int
display_history (list)
WORD_LIST *list;
{
register int i;
intmax_t limit;
HIST_ENTRY **hlist;
char *histtimefmt, *timestr;
if (list)
{
if (get_numeric_arg (list, 0, &limit) == 0)
return (EXECUTION_FAILURE);
if (limit < 0)
limit = -limit;
}
else
limit = -1;
hlist = history_list ();
if (hlist)
{
for (i = 0; hlist[i]; i++)
;
if (0 <= limit && limit < i)
i -= limit;
else
i = 0;
histtimefmt = get_string_value ("HISTTIMEFORMAT");
while (hlist[i])
{
QUIT;
timestr = (histtimefmt && *histtimefmt) ? histtime (hlist[i], histtimefmt) : (char *)NULL;
printf ("%5d%c %s%s\n", i + history_base,
histdata(i) ? '*' : ' ',
((timestr && *timestr) ? timestr : ""),
histline(i));
i++;
}
}
return (EXECUTION_SUCCESS);
}
/* Remove the last entry in the history list and add each argument in
LIST to the history. */
static void
push_history (list)
WORD_LIST *list;
{
char *s;
/* Delete the last history entry if it was a single entry added to the
history list (generally the `history -s' itself), or if `history -s'
is being used in a compound command and the compound command was
added to the history as a single element (command-oriented history).
If you don't want history -s to remove the compound command from the
history, change #if 0 to #if 1 below. */
#if 0
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
#else
if (remember_on_history && hist_last_line_pushed == 0 &&
(hist_last_line_added ||
(current_command_line_count > 0 && current_command_first_line_saved && command_oriented_history))
&& bash_delete_last_history () == 0)
#endif
return;
s = string_list (list);
/* Call check_add_history with FORCE set to 1 to skip the check against
current_command_line_count. If history -s is used in a compound
command, the above code will delete the compound command's history
entry and this call will add the line to the history as a separate
entry. Without FORCE=1, if current_command_line_count were > 1, the
line would be appended to the entry before the just-deleted entry. */
check_add_history (s, 1); /* obeys HISTCONTROL, HISTIGNORE */
hist_last_line_pushed = 1; /* XXX */
free (s);
}
#if defined (BANG_HISTORY)
static int
expand_and_print_history (list)
WORD_LIST *list;
{
char *s;
int r, result;
if (hist_last_line_pushed == 0 && hist_last_line_added && bash_delete_last_history () == 0)
return EXECUTION_FAILURE;
result = EXECUTION_SUCCESS;
while (list)
{
r = history_expand (list->word->word, &s);
if (r < 0)
{
builtin_error (_("%s: history expansion failed"), list->word->word);
result = EXECUTION_FAILURE;
}
else
{
fputs (s, stdout);
putchar ('\n');
}
FREE (s);
list = list->next;
}
fflush (stdout);
return result;
}
#endif /* BANG_HISTORY */
#endif /* HISTORY */
+3
View File
@@ -8490,8 +8490,11 @@ that script and return either
.I n
or the exit status of the last command executed within the
script as the exit status of the script.
If \fIn\fP is supplied, the return value is its least significant
8 bits.
The return status is non-zero if
.B return
is supplied a non-numeric argument, or
is used outside a
function and not during execution of a script by \fB.\fP\^ or \fBsource\fP.
Any command associated with the \fBRETURN\fP trap is executed
+4 -1
View File
@@ -3560,7 +3560,10 @@ This is semantically equivalent to
\fB>\fP\fIword\fP 2\fB>&\fP1
.RE
.PP
(see \fBDuplicating File Descriptors\fP below).
When using the second form, \fIword\fP may not expand to a number or
\fB\-\fP. If it does, other redirection operators apply
(see \fBDuplicating File Descriptors\fP below) for compatibility
reasons.
.SS Appending Standard Output and Standard Error
.PP
This construct allows both the
+4 -1
View File
@@ -3219,9 +3219,12 @@ being executed with the @code{.} (@code{source}) builtin,
returning either @var{n} or
the exit status of the last command executed within the script as the exit
status of the script.
If @var{n} is supplied, the return value is its least significant
8 bits.
Any command associated with the @code{RETURN} trap is executed
before execution resumes after the function or script.
The return status is non-zero if @code{return} is used outside a function
The return status is non-zero if @code{return} is supplied a non-numeric
argument or is used outside a function
and not during the execution of a script by @code{.} or @code{source}.
@item shift
+3 -1
View File
@@ -2358,7 +2358,9 @@ This is semantically equivalent to
@example
>@var{word} 2>&1
@end example
(see Duplicating File Descriptors below).
When using the second form, @var{word} may not expand to a number or
@samp{-}. If it does, other redirection operators apply
(see Duplicating File Descriptors below) for compatibility reasons.
@subsection Appending Standard Output and Standard Error
This construct allows both the
+1 -1
View File
@@ -562,7 +562,7 @@ file_iswdir (fn)
/* Return 1 if STRING is "." or "..", optionally followed by a directory
separator */
int
dot_or_dotdot (string)
path_dot_or_dotdot (string)
const char *string;
{
if (string == 0 || *string == '\0' || *string != '.')
+1 -1
View File
@@ -304,7 +304,7 @@ extern int sh_closepipe __P((int *));
extern int file_exists __P((char *));
extern int file_isdir __P((char *));
extern int file_iswdir __P((char *));
extern int dot_or_dotdot __P((const char *));
extern int path_dot_or_dotdot __P((const char *));
extern int absolute_pathname __P((const char *));
extern int absolute_program __P((const char *));
+14 -5
View File
@@ -100,6 +100,12 @@ rl_callback_handler_install (prompt, linefunc)
_rl_callback_newline ();
}
/* Placeholder for now */
#define CALLBACK_READ_RETURN() \
do { \
return; \
} while (0)
/* Read one character, and dispatch to the handler if it ends the line. */
void
rl_callback_read_char ()
@@ -121,7 +127,7 @@ rl_callback_read_char ()
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t));
return;
CALLBACK_READ_RETURN ();
}
#if defined (HANDLE_SIGNALS)
@@ -138,12 +144,13 @@ rl_callback_read_char ()
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
return;
CALLBACK_READ_RETURN ();
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
eof = _rl_nsearch_callback (_rl_nscxt);
return;
CALLBACK_READ_RETURN ();
}
#if defined (VI_MODE)
else if (RL_ISSTATE (RL_STATE_VIMOTION))
@@ -154,7 +161,7 @@ rl_callback_read_char ()
if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
CALLBACK_READ_RETURN ();
}
#endif
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
@@ -166,7 +173,7 @@ rl_callback_read_char ()
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
CALLBACK_READ_RETURN ();
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
@@ -233,6 +240,8 @@ rl_callback_read_char ()
}
}
while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
CALLBACK_READ_RETURN ();
}
/* Remove the handler, and make sure the terminal is in its normal state. */
+4 -2
View File
@@ -62,8 +62,10 @@ _rl_callback_generic_arg *_rl_callback_data = 0;
whenever a complete line of input is ready. The user must then
call rl_callback_read_char() every time some input is available, and
rl_callback_read_char() will call the user's function with the complete
text read in at each end of line. The terminal is kept prepped and
signals handled all the time, except during calls to the user's function. */
text read in at each end of line. The terminal is kept prepped
all the time, except during calls to the user's function. Signal
handlers are only installed when the application calls back into
readline, so readline doesn't `steal' signals from the application. */
rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */
+12 -12
View File
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: bash-4.2\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-01-28 22:09-0500\n"
"PO-Revision-Date: 2011-10-14 16:33+0200\n"
"PO-Revision-Date: 2011-10-17 09:14+0200\n"
"Last-Translator: Sergio Zanchetta <primes2h@ubuntu.com>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"Language: it\n"
@@ -2067,7 +2067,7 @@ msgstr "help [-dms] [modello ...]"
#: builtins.c:121
msgid "history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]"
msgstr "history [-c] [-d offset] [n] oppure history -anrw [nomefile] oppure history -ps arg [arg...]"
msgstr "history [-c] [-d posiz] [n] oppure history -anrw [nomefile] oppure history -ps arg [arg...]"
#: builtins.c:125
msgid "jobs [-lnprs] [jobspec ...] or jobs -x command [args]"
@@ -3219,19 +3219,19 @@ msgstr ""
" modificata il prefisso \"*\". Un argomento pari a N elenca solo le ultime N voci.\n"
" \n"
" Opzioni:\n"
" -c\t\tPulisce la cronologia eliminando tutte le voci\n"
" -d posizione\tElimina la voce della cronologia alla posizione OFFSET.\n"
" -c\tPulisce la cronologia eliminando tutte le voci\n"
" -d posiz\tElimina la voce della cronologia alla posizione POSIZ.\n"
" \n"
" -a\t\tAccoda righe al file della cronologia relative alla sessione attuale\n"
" -n\t\tLegge tutte le righe non ancora lette dal file della cronologia\n"
" -r\t\tLegge il file della cronologia e ne accoda il contenuto all'elenco della\n"
" -a\tAccoda righe al file della cronologia relative alla sessione attuale\n"
" -n\tLegge tutte le righe non ancora lette dal file della cronologia\n"
" -r\tLegge il file della cronologia e ne accoda il contenuto all'elenco della\n"
" \t\tcronologia\n"
" -w\t\tScrive la cronologia corrente nel file della cronologia\n"
" -w\tScrive la cronologia corrente nel file della cronologia\n"
" \t\te ne accoda le voci all'elenco della cronologia\n"
" \n"
" -p\t\tEffettua l'espansione della cronologia su ciascun ARG e visualizza il\n"
" -p\tEffettua l'espansione della cronologia su ciascun ARG e visualizza il\n"
" \t\trisultato senza memorizzarlo nell'elenco della cronologia\n"
" -s\t\tAccoda gli ARG all'elenco della cronologia come una voce singola\n"
" -s\tAccoda gli ARG all'elenco della cronologia come una voce singola\n"
" \n"
" Se viene fornito il NOMEFILE, viene usato come file della cronologia. Altrimenti,\n"
" se presente, viene usato il valore di $HISTFILE, in alternativa ~/.bash_history.\n"
@@ -4105,7 +4105,7 @@ msgstr ""
" Se uno SPEC_SEGNALE è EXIT (0) ARG viene eseguito all'uscita dalla shell. Se\n"
" lo SPEC_SEGNALE è DEBUG, ARG viene eseguito prima di ogni comando semplice. Se\n"
" uno SPEC_SEGNALE è RETURN, ARG viene eseguito al termine di ogni esecuzione\n"
" di una funzione di shell o di uno script avviato dai comandi interni . o sorgenti.\n"
" di una funzione di shell o di uno script avviato dai comandi interni . o source.\n"
" Un SPEC_SEGNALE di ERR significa eseguire ARG ogni volta che un errore di comando\n"
" causi l'uscita della shell quando è abilitata l'opzione -e.\n"
" \n"
@@ -4753,7 +4753,7 @@ msgstr ""
" \t\tuna shell in esecuzione.\n"
" HOME\tIl nome completo del percorso della propria directory di login.\n"
" HOSTNAME\tIl nome dell'host corrente.\n"
" HOSTTYPE\tIl tipo di cpu sulla quale è in esecuzione questa versione di bash.\n"
" HOSTTYPE\tIl tipo di CPU sulla quale è in esecuzione questa versione di bash.\n"
" IGNOREEOF\tControlla il comportamento della shell quando riceve un carattere EOF\n"
" \t\tcome unico input. Se impostato, il suo valore corrisponde al numero\n"
" \t\tdi caratteri EOF che si possono trovare in una fila in una riga vuota\n"