mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-02 08:18:14 +02:00
commit bash-20111110 snapshot
This commit is contained in:
+60
-1
@@ -11657,7 +11657,7 @@ sig.c
|
||||
5/15
|
||||
----
|
||||
lib/readline/display.c
|
||||
- _rl_col_width: Mac OS X has a bug in wcwitdh: it does not return 0
|
||||
- _rl_col_width: Mac OS X has a bug in wcwidth: it does not return 0
|
||||
for UTF-8 combining characters. Added workaround dependent on
|
||||
MACOSX. Fixes problem pointed out by Thomas De Contes
|
||||
<d.l.tDecontes@free.fr>
|
||||
@@ -12549,3 +12549,62 @@ execute_cmd.c
|
||||
- cpl_reap: rewrote to avoid using pointer after freeing it; now builds
|
||||
new coproc list on the fly while traversing the old one and sets the
|
||||
right values for coproc_list when done
|
||||
|
||||
11/12
|
||||
-----
|
||||
builtins/set.def
|
||||
- if neither -f nor -v supplied, don't allow a readonly function to
|
||||
be implicitly unset. Fixes bug reported by Jens Schmidt
|
||||
<jens.schmidt35@arcor.de>
|
||||
|
||||
lib/readline/callback.c
|
||||
- change CALLBACK_READ_RETURN to clear signal handlers before returning
|
||||
from rl_callback_read_char so readline's signal handlers aren't
|
||||
installed when readline doesn't have control. Idea from Jan
|
||||
Kratochvil <jan.ktratochvil@redhat.com> and the GDB development
|
||||
team
|
||||
|
||||
pcomplete.h
|
||||
- COPT_NOQUOTE: new complete/compgen option value
|
||||
|
||||
builtins/complete.def
|
||||
- noquote: new complete/compgen option; will be used to disable
|
||||
filename completion quoting
|
||||
|
||||
pcomplete.c
|
||||
- pcomp_set_readline_variables: pay attention to COPT_NOQUOTE; turns
|
||||
of rl_filename_quoting_desired if set; turns it on if unset (value
|
||||
is inverted, since default is on)
|
||||
|
||||
doc/bash.1,lib/readline/doc/rluser.texi
|
||||
- document new -o noquote option to complete/compgen/compopt
|
||||
|
||||
pathexp.c
|
||||
- quote_string_for_globbing: if QGLOB_REGEXP, make sure characters
|
||||
between brackets in an ERE bracket expression are not inappropriately
|
||||
quoted with backslashes. This is a pretty substantial change,
|
||||
should be stressed when opening bash up for alpha and beta tests.
|
||||
Fixes bug pointed out by Stephane Chazleas
|
||||
<stephane_chazelas@yahoo.fr>
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document that regexp matches can be inconsistent when quoting
|
||||
characters in bracket expressions, since usual quoting characters
|
||||
lose their meaning within brackets
|
||||
- note that regular expression matching when the pattern is stored
|
||||
in a shell variable which is quoted for expansion causes string
|
||||
matching
|
||||
|
||||
redir.h
|
||||
- RX_SAVEFD: new flag value; notes that a redirection denotes an
|
||||
fd used to save another even if it's not >= SHELL_FD_BASE
|
||||
|
||||
redir.c
|
||||
- do_redirection_internal: when deciding whether or not to reset the
|
||||
close-on-exec flag on a restored file descriptor, trust the value
|
||||
of redirect->flags & RX_SAVCLEXEC even if the fd is < SHELL_FD_BASE
|
||||
if the RX_SAVEFD flag is set
|
||||
- add_undo_redirect: set the RX_SAVEFD flag if the file descriptor
|
||||
limit is such that the shell can't duplicate to a file descriptor
|
||||
>= 10. Fixes a limitation that tripped a coreutils test reported
|
||||
by Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
+67
-1
@@ -11657,7 +11657,7 @@ sig.c
|
||||
5/15
|
||||
----
|
||||
lib/readline/display.c
|
||||
- _rl_col_width: Mac OS X has a bug in wcwitdh: it does not return 0
|
||||
- _rl_col_width: Mac OS X has a bug in wcwidth: it does not return 0
|
||||
for UTF-8 combining characters. Added workaround dependent on
|
||||
MACOSX. Fixes problem pointed out by Thomas De Contes
|
||||
<d.l.tDecontes@free.fr>
|
||||
@@ -12542,3 +12542,69 @@ variables.c
|
||||
lib/sh/zmapfd.c
|
||||
- zmapfd: if read returns error, free result and return -1 immediately
|
||||
instead of trying to reallocate it
|
||||
|
||||
11/6
|
||||
----
|
||||
execute_cmd.c
|
||||
- cpl_reap: rewrote to avoid using pointer after freeing it; now builds
|
||||
new coproc list on the fly while traversing the old one and sets the
|
||||
right values for coproc_list when done
|
||||
|
||||
11/12
|
||||
-----
|
||||
builtins/set.def
|
||||
- if neither -f nor -v supplied, don't allow a readonly function to
|
||||
be implicitly unset. Fixes bug reported by Jens Schmidt
|
||||
<jens.schmidt35@arcor.de>
|
||||
|
||||
lib/readline/callback.c
|
||||
- change CALLBACK_READ_RETURN to clear signal handlers before returning
|
||||
from rl_callback_read_char so readline's signal handlers aren't
|
||||
installed when readline doesn't have control. Idea from Jan
|
||||
Kratochvil <jan.ktratochvil@redhat.com> and the GDB development
|
||||
team
|
||||
|
||||
pcomplete.h
|
||||
- COPT_NOQUOTE: new complete/compgen option value
|
||||
|
||||
builtins/complete.def
|
||||
- noquote: new complete/compgen option; will be used to disable
|
||||
filename completion quoting
|
||||
|
||||
pcomplete.c
|
||||
- pcomp_set_readline_variables: pay attention to COPT_NOQUOTE; turns
|
||||
of rl_filename_quoting_desired if set; turns it on if unset (value
|
||||
is inverted, since default is on)
|
||||
|
||||
doc/bash.1,lib/readline/doc/rluser.texi
|
||||
- document new -o noquote option to complete/compgen/compopt
|
||||
|
||||
pathexp.c
|
||||
- quote_string_for_globbing: if QGLOB_REGEXP, make sure characters
|
||||
between brackets in an ERE bracket expression are not inappropriately
|
||||
quoted with backslashes. This is a pretty substantial change,
|
||||
should be stressed when opening bash up for alpha and beta tests.
|
||||
Fixes bug pointed out by Stephane Chazleas
|
||||
<stephane_chazelas@yahoo.fr>
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- document that regexp matches can be inconsistent when quoting
|
||||
characters in bracket expressions, since usual quoting characters
|
||||
lose their meaning within brackets
|
||||
- note that regular expression matching when the pattern is stored
|
||||
in a shell variable which is quoted for expansion causes string
|
||||
matching
|
||||
|
||||
redir.h
|
||||
- RX_SAVEFD: new flag value; notes that a redirection denotes an
|
||||
fd used to save another even if it's not >= SHELL_FD_BASE
|
||||
|
||||
redir.c
|
||||
- do_redirection_internal: when deciding whether or not to reset the
|
||||
close-on-exec flag on a restored file descriptor, trust the value
|
||||
of redirect->flags & RX_SAVCLEXEC even if the fd is < SHELL_FD_BASE
|
||||
if the RX_SAVEFD flag is set
|
||||
- add_undo_redirect: set the RX_SAVEFD flag if the file descriptor
|
||||
limit is such that the shell can't duplicate to a file descriptor
|
||||
>= 10
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ static const struct _compopt {
|
||||
{ "default", COPT_DEFAULT },
|
||||
{ "dirnames", COPT_DIRNAMES },
|
||||
{ "filenames",COPT_FILENAMES},
|
||||
{ "noquote", COPT_NOQUOTE },
|
||||
{ "nospace", COPT_NOSPACE },
|
||||
{ "plusdirs", COPT_PLUSDIRS },
|
||||
{ (char *)NULL, 0 },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
This file is complete.def, from which is created complete.c.
|
||||
It implements the builtins "complete", "compgen", and "compopt" in Bash.
|
||||
|
||||
Copyright (C) 1999-2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -728,6 +728,7 @@ compgen_builtin (list)
|
||||
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
|
||||
{
|
||||
matches = rl_completion_matches (word, rl_filename_completion_function);
|
||||
strlist_dispose (sl);
|
||||
sl = completions_to_stringlist (matches);
|
||||
strvec_dispose (matches);
|
||||
}
|
||||
|
||||
+19
-4
@@ -1,7 +1,7 @@
|
||||
This file is set.def, from which is created set.c.
|
||||
It implements the "set" and "unset" builtins in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -791,6 +791,8 @@ unset_builtin (list)
|
||||
unset_array++;
|
||||
}
|
||||
#endif
|
||||
/* Get error checking out of the way first. The low-level functions
|
||||
just perform the unset, relying on the caller to verify. */
|
||||
|
||||
/* Bash allows functions with names which are not valid identifiers
|
||||
to be created when not in posix mode, so check only when in posix
|
||||
@@ -801,14 +803,26 @@ unset_builtin (list)
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* Only search for functions here if -f supplied. */
|
||||
var = unset_function ? find_function (name) : find_variable (name);
|
||||
|
||||
if (var && !unset_function && non_unsettable_p (var))
|
||||
/* Some variables (but not functions yet) cannot be unset, period. */
|
||||
if (var && unset_function == 0 && non_unsettable_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot unset"), name);
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* Posix.2 says try variables first, then functions. If we would
|
||||
find a function after unsuccessfully searching for a variable,
|
||||
note that we're acting on a function now as if -f were
|
||||
supplied. The readonly check below takes care of it. */
|
||||
if (var == 0 && unset_variable == 0 && unset_function == 0)
|
||||
{
|
||||
if (var = find_function (name))
|
||||
unset_function = 1;
|
||||
}
|
||||
|
||||
/* Posix.2 says that unsetting readonly variables is an error. */
|
||||
if (var && readonly_p (var))
|
||||
{
|
||||
@@ -817,6 +831,7 @@ unset_builtin (list)
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
|
||||
/* Unless the -f option is supplied, the name refers to a variable. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (var && unset_array)
|
||||
@@ -837,11 +852,11 @@ unset_builtin (list)
|
||||
#endif /* ARRAY_VARS */
|
||||
tem = unset_function ? unbind_func (name) : unbind_variable (name);
|
||||
|
||||
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
|
||||
/* This is what Posix.2 says: ``If neither -f nor -v
|
||||
is specified, the name refers to a variable; if a variable by
|
||||
that name does not exist, a function by that name, if any,
|
||||
shall be unset.'' */
|
||||
if (tem == -1 && !unset_function && !unset_variable)
|
||||
if (tem == -1 && unset_function == 0 && unset_variable == 0)
|
||||
tem = unbind_func (name);
|
||||
|
||||
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
|
||||
|
||||
+29
-7
@@ -1,7 +1,7 @@
|
||||
This file is set.def, from which is created set.c.
|
||||
It implements the "set" and "unset" builtins in Bash.
|
||||
|
||||
Copyright (C) 1987-2009 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -473,7 +473,6 @@ set_shellopts ()
|
||||
int vsize, i, vptr, *ip, exported;
|
||||
SHELL_VAR *v;
|
||||
|
||||
itrace("set_shellopts: entry");
|
||||
for (vsize = i = 0; o_options[i].name; i++)
|
||||
{
|
||||
tflag[i] = 0;
|
||||
@@ -510,7 +509,7 @@ itrace("set_shellopts: entry");
|
||||
value[vptr] = '\0';
|
||||
|
||||
v = find_variable ("SHELLOPTS");
|
||||
itrace("set_shellopts: v = %p", v);
|
||||
|
||||
/* Turn off the read-only attribute so we can bind the new value, and
|
||||
note whether or not the variable was exported. */
|
||||
if (v)
|
||||
@@ -531,7 +530,6 @@ itrace("set_shellopts: v = %p", v);
|
||||
VUNSETATTR (v, att_exported);
|
||||
|
||||
free (value);
|
||||
itrace("set_shellopts: return");
|
||||
}
|
||||
|
||||
void
|
||||
@@ -793,6 +791,8 @@ unset_builtin (list)
|
||||
unset_array++;
|
||||
}
|
||||
#endif
|
||||
/* Get error checking out of the way first. The low-level functions
|
||||
just perform the unset, relying on the caller to verify. */
|
||||
|
||||
/* Bash allows functions with names which are not valid identifiers
|
||||
to be created when not in posix mode, so check only when in posix
|
||||
@@ -805,12 +805,33 @@ unset_builtin (list)
|
||||
|
||||
var = unset_function ? find_function (name) : find_variable (name);
|
||||
|
||||
if (var && !unset_function && non_unsettable_p (var))
|
||||
/* Some variables (but not functions yet) cannot be unset, period. */
|
||||
if (var && unset_function == 0 && non_unsettable_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot unset"), name);
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* Posix.2 says try variables first, then functions. If we would
|
||||
find a function after unsuccessfully searching for a variable,
|
||||
check for readonly here. If we find one, note that we're
|
||||
acting on a function now. */
|
||||
if (var == 0 && unset_variable == 0 && unset_function == 0)
|
||||
{
|
||||
var = find_function (name);
|
||||
#if 0
|
||||
if (var && readonly_p (var))
|
||||
{
|
||||
builtin_error (_("%s: cannot unset: readonly function"), name);
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
var = 0;
|
||||
#else
|
||||
if (var)
|
||||
unset_function = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Posix.2 says that unsetting readonly variables is an error. */
|
||||
if (var && readonly_p (var))
|
||||
{
|
||||
@@ -819,6 +840,7 @@ unset_builtin (list)
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
|
||||
/* Unless the -f option is supplied, the name refers to a variable. */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (var && unset_array)
|
||||
@@ -839,11 +861,11 @@ unset_builtin (list)
|
||||
#endif /* ARRAY_VARS */
|
||||
tem = unset_function ? unbind_func (name) : unbind_variable (name);
|
||||
|
||||
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
|
||||
/* This is what Posix.2 says: ``If neither -f nor -v
|
||||
is specified, the name refers to a variable; if a variable by
|
||||
that name does not exist, a function by that name, if any,
|
||||
shall be unset.'' */
|
||||
if (tem == -1 && !unset_function && !unset_variable)
|
||||
if (tem == -1 && unset_function == 0 && unset_variable == 0)
|
||||
tem = unbind_func (name);
|
||||
|
||||
/* SUSv3, POSIX.1-2001 say: ``Unsetting a variable or function that
|
||||
|
||||
+10
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Sun Sep 25 22:01:16 EDT 2011
|
||||
.\" Last Change: Sat Nov 12 13:34:37 EST 2011
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2011 September 25" "GNU Bash 4.2"
|
||||
.TH BASH 1 "2011 November 12" "GNU Bash 4.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -729,6 +729,10 @@ is enabled, the match is performed without regard to the case
|
||||
of alphabetic characters.
|
||||
Any part of the pattern may be quoted to force the quoted portion
|
||||
to be matched as a string.
|
||||
Bracket expressions in regular expressions must be treated carefully,
|
||||
since normal quoting characters lose their meanings between brackets.
|
||||
If the pattern is stored in a shell variable, quoting the variable
|
||||
expansion forces the entire pattern to be matched as a string.
|
||||
Substrings matched by parenthesized subexpressions within the regular
|
||||
expression are saved in the array variable
|
||||
.SM
|
||||
@@ -7007,6 +7011,10 @@ filename\-specific processing (like adding a slash to directory names,
|
||||
quoting special characters, or suppressing trailing spaces).
|
||||
Intended to be used with shell functions.
|
||||
.TP 8
|
||||
.B noquote
|
||||
Tell readline not to quote the completed words if they are filenames
|
||||
(quoting filenames is the default).
|
||||
.TP 8
|
||||
.B nospace
|
||||
Tell readline not to append a space (the default) to words completed at
|
||||
the end of the line.
|
||||
|
||||
+11
-2
@@ -5,12 +5,12 @@
|
||||
.\" Case Western Reserve University
|
||||
.\" chet@po.cwru.edu
|
||||
.\"
|
||||
.\" Last Change: Sun Sep 25 22:01:16 EDT 2011
|
||||
.\" Last Change: Sat Nov 12 13:34:37 EST 2011
|
||||
.\"
|
||||
.\" bash_builtins, strip all but Built-Ins section
|
||||
.if \n(zZ=1 .ig zZ
|
||||
.if \n(zY=1 .ig zY
|
||||
.TH BASH 1 "2011 September 25" "GNU Bash 4.2"
|
||||
.TH BASH 1 "2011 November 12" "GNU Bash 4.2"
|
||||
.\"
|
||||
.\" There's some problem with having a `@'
|
||||
.\" in a tagged paragraph with the BSD man macros.
|
||||
@@ -729,6 +729,8 @@ is enabled, the match is performed without regard to the case
|
||||
of alphabetic characters.
|
||||
Any part of the pattern may be quoted to force the quoted portion
|
||||
to be matched as a string.
|
||||
If the pattern is stored in a shell variable, quoting the variable
|
||||
expansion forces the entire pattern to be matched as a string.
|
||||
Substrings matched by parenthesized subexpressions within the regular
|
||||
expression are saved in the array variable
|
||||
.SM
|
||||
@@ -7007,6 +7009,10 @@ filename\-specific processing (like adding a slash to directory names,
|
||||
quoting special characters, or suppressing trailing spaces).
|
||||
Intended to be used with shell functions.
|
||||
.TP 8
|
||||
.B noquote
|
||||
Tell readline not to quote the completed words if they are filenames
|
||||
(quoting filenames is the default).
|
||||
.TP 8
|
||||
.B nospace
|
||||
Tell readline not to append a space (the default) to words completed at
|
||||
the end of the line.
|
||||
@@ -8490,8 +8496,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
|
||||
|
||||
@@ -1034,6 +1034,10 @@ is enabled, the match is performed without regard to the case
|
||||
of alphabetic characters.
|
||||
Any part of the pattern may be quoted to force the quoted portion
|
||||
to be matched as a string.
|
||||
Bracket expressions in regular expressions must be treated carefully,
|
||||
since normal quoting characters lose their meanings between brackets.
|
||||
If the pattern is stored in a shell variable, quoting the variable
|
||||
expansion forces the entire pattern to be matched as a string.
|
||||
Substrings matched by parenthesized subexpressions within the regular
|
||||
expression are saved in the array variable @code{BASH_REMATCH}.
|
||||
The element of @code{BASH_REMATCH} with index 0 is the portion of the string
|
||||
|
||||
+6
-1
@@ -1034,6 +1034,8 @@ is enabled, the match is performed without regard to the case
|
||||
of alphabetic characters.
|
||||
Any part of the pattern may be quoted to force the quoted portion
|
||||
to be matched as a string.
|
||||
If the pattern is stored in a shell variable, quoting the variable
|
||||
expansion forces the entire pattern to be matched as a string.
|
||||
Substrings matched by parenthesized subexpressions within the regular
|
||||
expression are saved in the array variable @code{BASH_REMATCH}.
|
||||
The element of @code{BASH_REMATCH} with index 0 is the portion of the string
|
||||
@@ -3219,9 +3221,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
-3
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Mon Oct 24 08:43:33 EDT 2011
|
||||
@set LASTCHANGE Sat Nov 12 13:35:12 EST 2011
|
||||
|
||||
@set EDITION 4.2
|
||||
@set VERSION 4.2
|
||||
@set UPDATED 24 October 2011
|
||||
@set UPDATED-MONTH October 2011
|
||||
@set UPDATED 12 November 2011
|
||||
@set UPDATED-MONTH November 2011
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Sun Sep 25 22:01:31 EDT 2011
|
||||
@set LASTCHANGE Mon Oct 24 08:43:33 EDT 2011
|
||||
|
||||
@set EDITION 4.2
|
||||
@set VERSION 4.2
|
||||
@set UPDATED 25 September 2011
|
||||
@set UPDATED-MONTH September 2011
|
||||
@set UPDATED 24 October 2011
|
||||
@set UPDATED-MONTH October 2011
|
||||
|
||||
@@ -100,11 +100,15 @@ rl_callback_handler_install (prompt, linefunc)
|
||||
_rl_callback_newline ();
|
||||
}
|
||||
|
||||
/* Placeholder for now */
|
||||
#define CALLBACK_READ_RETURN() \
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
#define CALLBACK_READ_RETURN() \
|
||||
do { \
|
||||
rl_clear_signals (); \
|
||||
return; \
|
||||
} while (0)
|
||||
#else
|
||||
#define CALLBACK_READ_RETURN() return
|
||||
#endif
|
||||
|
||||
/* Read one character, and dispatch to the handler if it ends the line. */
|
||||
void
|
||||
|
||||
@@ -100,6 +100,16 @@ rl_callback_handler_install (prompt, linefunc)
|
||||
_rl_callback_newline ();
|
||||
}
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
#define CALLBACK_READ_RETURN \
|
||||
do { \
|
||||
rl_clear_signals (); \
|
||||
return; \
|
||||
} while (0)
|
||||
#else
|
||||
#define CALLBACK_READ_RETURN() return
|
||||
#endif
|
||||
|
||||
/* Read one character, and dispatch to the handler if it ends the line. */
|
||||
void
|
||||
rl_callback_read_char ()
|
||||
@@ -121,7 +131,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 +148,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 +165,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 +177,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 +244,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. */
|
||||
|
||||
@@ -1888,6 +1888,10 @@ quoting special characters, or suppressing trailing spaces).
|
||||
This option is intended to be used with shell functions specified
|
||||
with @option{-F}.
|
||||
|
||||
@item noquote
|
||||
Tell Readline not to quote the completed words if they are filenames
|
||||
(quoting filenames is the default).
|
||||
|
||||
@item nospace
|
||||
Tell Readline not to append a space (the default) to words completed at
|
||||
the end of the line.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@
|
||||
static int glob_name_is_acceptable __P((const char *));
|
||||
static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
|
||||
static char *split_ignorespec __P((char *, int *));
|
||||
|
||||
|
||||
#if defined (USE_POSIX_GLOB_LIBRARY)
|
||||
# include <glob.h>
|
||||
typedef int posix_glob_errfunc_t __P((const char *, int));
|
||||
@@ -157,7 +157,7 @@ glob_char_p (s)
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
if (s[1] == '(') /*(*/
|
||||
if (s[1] == '(') /*(*/
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
@@ -183,6 +183,7 @@ quote_string_for_globbing (pathname, qflags)
|
||||
{
|
||||
char *temp;
|
||||
register int i, j;
|
||||
int brack, cclass, collsym, equiv, c;
|
||||
|
||||
temp = (char *)xmalloc (strlen (pathname) + 1);
|
||||
|
||||
@@ -192,6 +193,7 @@ quote_string_for_globbing (pathname, qflags)
|
||||
return temp;
|
||||
}
|
||||
|
||||
brack = cclass = collsym = equiv = 0;
|
||||
for (i = j = 0; pathname[i]; i++)
|
||||
{
|
||||
if (pathname[i] == CTLESC)
|
||||
@@ -205,6 +207,71 @@ quote_string_for_globbing (pathname, qflags)
|
||||
if (pathname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
else if ((qflags & QGLOB_REGEXP) && (i == 0 || pathname[i-1] != CTLESC) && pathname[i] == '[') /*]*/
|
||||
{
|
||||
brack = 1;
|
||||
temp[j++] = pathname[i++]; /* open bracket */
|
||||
c = pathname[i++]; /* c == char after open bracket */
|
||||
do
|
||||
{
|
||||
if (c == 0)
|
||||
goto endpat;
|
||||
else if (c == CTLESC)
|
||||
{
|
||||
/* skip c, check for EOS, let assignment at end of loop */
|
||||
/* pathname[i] == backslash-escaped character */
|
||||
if (pathname[i] == 0)
|
||||
goto endpat;
|
||||
temp[j++] = pathname[i++];
|
||||
}
|
||||
else if (c == '[' && pathname[i] == ':')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
cclass = 1;
|
||||
}
|
||||
else if (cclass && c == ':' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
cclass = 0;
|
||||
}
|
||||
else if (c == '[' && pathname[i] == '=')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
if (pathname[i] == ']')
|
||||
temp[j++] = pathname[i++]; /* right brack can be in equiv */
|
||||
equiv = 1;
|
||||
}
|
||||
else if (equiv && c == '=' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
equiv = 0;
|
||||
}
|
||||
else if (c == '[' && pathname[i] == '.')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
if (pathname[i] == ']')
|
||||
temp[j++] = pathname[i++]; /* right brack can be in collsym */
|
||||
collsym = 1;
|
||||
}
|
||||
else if (collsym && c == '.' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
collsym = 0;
|
||||
}
|
||||
else
|
||||
temp[j++] = c;
|
||||
}
|
||||
while ((c = pathname[i++]) != ']');
|
||||
temp[j++] = c; /* closing right bracket */
|
||||
i--; /* increment will happen above in loop */
|
||||
continue; /* skip double assignment below */
|
||||
}
|
||||
else if (pathname[i] == '\\')
|
||||
{
|
||||
temp[j++] = '\\';
|
||||
@@ -214,6 +281,7 @@ quote_string_for_globbing (pathname, qflags)
|
||||
}
|
||||
temp[j++] = pathname[i];
|
||||
}
|
||||
endpat:
|
||||
temp[j] = '\0';
|
||||
|
||||
return (temp);
|
||||
@@ -237,7 +305,7 @@ quote_globbing_chars (string)
|
||||
*t++ = '\\';
|
||||
|
||||
/* Copy a single (possibly multibyte) character from s to t,
|
||||
incrementing both. */
|
||||
incrementing both. */
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
*t = '\0';
|
||||
|
||||
+585
@@ -0,0 +1,585 @@
|
||||
/* pathexp.c -- The shell interface to the globbing library. */
|
||||
|
||||
/* Copyright (C) 1995-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/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "pathexp.h"
|
||||
#include "flags.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
#include "bashintl.h"
|
||||
|
||||
#include <glob/strmatch.h>
|
||||
|
||||
static int glob_name_is_acceptable __P((const char *));
|
||||
static void ignore_globbed_names __P((char **, sh_ignore_func_t *));
|
||||
static char *split_ignorespec __P((char *, int *));
|
||||
|
||||
#if defined (USE_POSIX_GLOB_LIBRARY)
|
||||
# include <glob.h>
|
||||
typedef int posix_glob_errfunc_t __P((const char *, int));
|
||||
#else
|
||||
# include <glob/glob.h>
|
||||
#endif
|
||||
|
||||
/* Control whether * matches .files in globbing. */
|
||||
int glob_dot_filenames;
|
||||
|
||||
/* Control whether the extended globbing features are enabled. */
|
||||
int extended_glob = EXTGLOB_DEFAULT;
|
||||
|
||||
/* Control enabling special handling of `**' */
|
||||
int glob_star = 0;
|
||||
|
||||
/* Return nonzero if STRING has any unquoted special globbing chars in it. */
|
||||
int
|
||||
unquoted_glob_pattern_p (string)
|
||||
register char *string;
|
||||
{
|
||||
register int c;
|
||||
char *send;
|
||||
int open;
|
||||
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
open = 0;
|
||||
send = string + strlen (string);
|
||||
|
||||
while (c = *string++)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
case '*':
|
||||
return (1);
|
||||
|
||||
case '[':
|
||||
open++;
|
||||
continue;
|
||||
|
||||
case ']':
|
||||
if (open)
|
||||
return (1);
|
||||
continue;
|
||||
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
if (*string == '(') /*)*/
|
||||
return (1);
|
||||
continue;
|
||||
|
||||
case CTLESC:
|
||||
case '\\':
|
||||
if (*string++ == '\0')
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Advance one fewer byte than an entire multibyte character to
|
||||
account for the auto-increment in the loop above. */
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
string--;
|
||||
ADVANCE_CHAR_P (string, send - string);
|
||||
string++;
|
||||
#else
|
||||
ADVANCE_CHAR_P (string, send - string);
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return 1 if C is a character that is `special' in a POSIX ERE and needs to
|
||||
be quoted to match itself. */
|
||||
static inline int
|
||||
ere_char (c)
|
||||
int c;
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '.':
|
||||
case '[':
|
||||
case '\\':
|
||||
case '(':
|
||||
case ')':
|
||||
case '*':
|
||||
case '+':
|
||||
case '?':
|
||||
case '{':
|
||||
case '|':
|
||||
case '^':
|
||||
case '$':
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
glob_char_p (s)
|
||||
const char *s;
|
||||
{
|
||||
switch (*s)
|
||||
{
|
||||
case '*':
|
||||
case '[':
|
||||
case ']':
|
||||
case '?':
|
||||
case '\\':
|
||||
return 1;
|
||||
case '+':
|
||||
case '@':
|
||||
case '!':
|
||||
if (s[1] == '(') /*(*/
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* PATHNAME can contain characters prefixed by CTLESC; this indicates
|
||||
that the character is to be quoted. We quote it here in the style
|
||||
that the glob library recognizes. If flags includes QGLOB_CVTNULL,
|
||||
we change quoted null strings (pathname[0] == CTLNUL) into empty
|
||||
strings (pathname[0] == 0). If this is called after quote removal
|
||||
is performed, (flags & QGLOB_CVTNULL) should be 0; if called when quote
|
||||
removal has not been done (for example, before attempting to match a
|
||||
pattern while executing a case statement), flags should include
|
||||
QGLOB_CVTNULL. If flags includes QGLOB_FILENAME, appropriate quoting
|
||||
to match a filename should be performed. QGLOB_REGEXP means we're
|
||||
quoting for a Posix ERE (for [[ string =~ pat ]]) and that requires
|
||||
some special handling. */
|
||||
char *
|
||||
quote_string_for_globbing (pathname, qflags)
|
||||
const char *pathname;
|
||||
int qflags;
|
||||
{
|
||||
char *temp;
|
||||
register int i, j;
|
||||
int brack, cclass, collsym, equiv, c;
|
||||
|
||||
temp = (char *)xmalloc (strlen (pathname) + 1);
|
||||
|
||||
if ((qflags & QGLOB_CVTNULL) && QUOTED_NULL (pathname))
|
||||
{
|
||||
temp[0] = '\0';
|
||||
return temp;
|
||||
}
|
||||
|
||||
brack = cclass = collsym = equiv = 0;
|
||||
for (i = j = 0; pathname[i]; i++)
|
||||
{
|
||||
if (pathname[i] == CTLESC)
|
||||
{
|
||||
if ((qflags & QGLOB_FILENAME) && pathname[i+1] == '/')
|
||||
continue;
|
||||
if (pathname[i+1] != CTLESC && (qflags & QGLOB_REGEXP) && ere_char (pathname[i+1]) == 0)
|
||||
continue;
|
||||
temp[j++] = '\\';
|
||||
i++;
|
||||
if (pathname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
else if ((qflags & QGLOB_REGEXP) && (i == 0 || pathname[i-1] != CTLESC) && pathname[i] == '[') /*]*/
|
||||
{
|
||||
brack = 1;
|
||||
temp[j++] = pathname[i++]; /* open bracket */
|
||||
c = pathname[i++]; /* c == char after open bracket */
|
||||
do
|
||||
{
|
||||
if (c == 0)
|
||||
goto endpat;
|
||||
else if (c == CTLESC)
|
||||
{
|
||||
/* skip c, check for EOS, let assignment at end of loop */
|
||||
/* pathname[i] == backslash-escaped character */
|
||||
if (pathname[i] == 0 || pathname[++i] == 0)
|
||||
goto endpat;
|
||||
temp[j++] = pathname[i++];
|
||||
}
|
||||
else if (c == '[' && pathname[i] == ':')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
cclass = 1;
|
||||
}
|
||||
else if (cclass && c == ':' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
cclass = 0;
|
||||
}
|
||||
else if (c == '[' && pathname[i] == '=')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
if (pathname[i] == ']')
|
||||
temp[j++] = pathname[i++]; /* right brack can be in equiv */
|
||||
equiv = 1;
|
||||
}
|
||||
else if (equiv && c == '=' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
equiv = 0;
|
||||
}
|
||||
else if (c == '[' && pathname[i] == '.')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
if (pathname[i] == ']')
|
||||
temp[j++] = pathname[i++]; /* right brack can be in collsym */
|
||||
collsym = 1;
|
||||
}
|
||||
else if (collsym && c == '.' && pathname[i] == ']')
|
||||
{
|
||||
temp[j++] = c;
|
||||
temp[j++] = pathname[i++];
|
||||
collsym = 0;
|
||||
}
|
||||
else
|
||||
temp[j++] = c;
|
||||
}
|
||||
while ((c = pathname[i++]) != ']');
|
||||
temp[j++] = c; /* closing right bracket */
|
||||
i--; /* increment will happen above in loop */
|
||||
continue; /* skip double assignment below */
|
||||
}
|
||||
else if (pathname[i] == '\\')
|
||||
{
|
||||
temp[j++] = '\\';
|
||||
i++;
|
||||
if (pathname[i] == '\0')
|
||||
break;
|
||||
}
|
||||
temp[j++] = pathname[i];
|
||||
}
|
||||
endpat:
|
||||
temp[j] = '\0';
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
char *
|
||||
quote_globbing_chars (string)
|
||||
char *string;
|
||||
{
|
||||
size_t slen;
|
||||
char *temp, *s, *t, *send;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
|
||||
temp = (char *)xmalloc (slen * 2 + 1);
|
||||
for (t = temp, s = string; *s; )
|
||||
{
|
||||
if (glob_char_p (s))
|
||||
*t++ = '\\';
|
||||
|
||||
/* Copy a single (possibly multibyte) character from s to t,
|
||||
incrementing both. */
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
*t = '\0';
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* Call the glob library to do globbing on PATHNAME. */
|
||||
char **
|
||||
shell_glob_filename (pathname)
|
||||
const char *pathname;
|
||||
{
|
||||
#if defined (USE_POSIX_GLOB_LIBRARY)
|
||||
register int i;
|
||||
char *temp, **results;
|
||||
glob_t filenames;
|
||||
int glob_flags;
|
||||
|
||||
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
|
||||
|
||||
filenames.gl_offs = 0;
|
||||
|
||||
# if defined (GLOB_PERIOD)
|
||||
glob_flags = glob_dot_filenames ? GLOB_PERIOD : 0;
|
||||
# else
|
||||
glob_flags = 0;
|
||||
# endif /* !GLOB_PERIOD */
|
||||
|
||||
glob_flags |= (GLOB_ERR | GLOB_DOOFFS);
|
||||
|
||||
i = glob (temp, glob_flags, (posix_glob_errfunc_t *)NULL, &filenames);
|
||||
|
||||
free (temp);
|
||||
|
||||
if (i == GLOB_NOSPACE || i == GLOB_ABORTED)
|
||||
return ((char **)NULL);
|
||||
else if (i == GLOB_NOMATCH)
|
||||
filenames.gl_pathv = (char **)NULL;
|
||||
else if (i != 0) /* other error codes not in POSIX.2 */
|
||||
filenames.gl_pathv = (char **)NULL;
|
||||
|
||||
results = filenames.gl_pathv;
|
||||
|
||||
if (results && ((GLOB_FAILED (results)) == 0))
|
||||
{
|
||||
if (should_ignore_glob_matches ())
|
||||
ignore_glob_matches (results);
|
||||
if (results && results[0])
|
||||
strvec_sort (results);
|
||||
else
|
||||
{
|
||||
FREE (results);
|
||||
results = (char **)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (results);
|
||||
|
||||
#else /* !USE_POSIX_GLOB_LIBRARY */
|
||||
|
||||
char *temp, **results;
|
||||
|
||||
noglob_dot_filenames = glob_dot_filenames == 0;
|
||||
|
||||
temp = quote_string_for_globbing (pathname, QGLOB_FILENAME);
|
||||
results = glob_filename (temp, glob_star ? GX_GLOBSTAR : 0);
|
||||
free (temp);
|
||||
|
||||
if (results && ((GLOB_FAILED (results)) == 0))
|
||||
{
|
||||
if (should_ignore_glob_matches ())
|
||||
ignore_glob_matches (results);
|
||||
if (results && results[0])
|
||||
strvec_sort (results);
|
||||
else
|
||||
{
|
||||
FREE (results);
|
||||
results = (char **)&glob_error_return;
|
||||
}
|
||||
}
|
||||
|
||||
return (results);
|
||||
#endif /* !USE_POSIX_GLOB_LIBRARY */
|
||||
}
|
||||
|
||||
/* Stuff for GLOBIGNORE. */
|
||||
|
||||
static struct ignorevar globignore =
|
||||
{
|
||||
"GLOBIGNORE",
|
||||
(struct ign *)0,
|
||||
0,
|
||||
(char *)0,
|
||||
(sh_iv_item_func_t *)0,
|
||||
};
|
||||
|
||||
/* Set up to ignore some glob matches because the value of GLOBIGNORE
|
||||
has changed. If GLOBIGNORE is being unset, we also need to disable
|
||||
the globbing of filenames beginning with a `.'. */
|
||||
void
|
||||
setup_glob_ignore (name)
|
||||
char *name;
|
||||
{
|
||||
char *v;
|
||||
|
||||
v = get_string_value (name);
|
||||
setup_ignore_patterns (&globignore);
|
||||
|
||||
if (globignore.num_ignores)
|
||||
glob_dot_filenames = 1;
|
||||
else if (v == 0)
|
||||
glob_dot_filenames = 0;
|
||||
}
|
||||
|
||||
int
|
||||
should_ignore_glob_matches ()
|
||||
{
|
||||
return globignore.num_ignores;
|
||||
}
|
||||
|
||||
/* Return 0 if NAME matches a pattern in the globignore.ignores list. */
|
||||
static int
|
||||
glob_name_is_acceptable (name)
|
||||
const char *name;
|
||||
{
|
||||
struct ign *p;
|
||||
int flags;
|
||||
|
||||
/* . and .. are never matched */
|
||||
if (name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
|
||||
return (0);
|
||||
|
||||
flags = FNM_PATHNAME | FNMATCH_EXTFLAG;
|
||||
for (p = globignore.ignores; p->val; p++)
|
||||
{
|
||||
if (strmatch (p->val, (char *)name, flags) != FNM_NOMATCH)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Internal function to test whether filenames in NAMES should be
|
||||
ignored. NAME_FUNC is a pointer to a function to call with each
|
||||
name. It returns non-zero if the name is acceptable to the particular
|
||||
ignore function which called _ignore_names; zero if the name should
|
||||
be removed from NAMES. */
|
||||
|
||||
static void
|
||||
ignore_globbed_names (names, name_func)
|
||||
char **names;
|
||||
sh_ignore_func_t *name_func;
|
||||
{
|
||||
char **newnames;
|
||||
int n, i;
|
||||
|
||||
for (i = 0; names[i]; i++)
|
||||
;
|
||||
newnames = strvec_create (i + 1);
|
||||
|
||||
for (n = i = 0; names[i]; i++)
|
||||
{
|
||||
if ((*name_func) (names[i]))
|
||||
newnames[n++] = names[i];
|
||||
else
|
||||
free (names[i]);
|
||||
}
|
||||
|
||||
newnames[n] = (char *)NULL;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
names[0] = (char *)NULL;
|
||||
free (newnames);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy the acceptable names from NEWNAMES back to NAMES and set the
|
||||
new array end. */
|
||||
for (n = 0; newnames[n]; n++)
|
||||
names[n] = newnames[n];
|
||||
names[n] = (char *)NULL;
|
||||
free (newnames);
|
||||
}
|
||||
|
||||
void
|
||||
ignore_glob_matches (names)
|
||||
char **names;
|
||||
{
|
||||
if (globignore.num_ignores == 0)
|
||||
return;
|
||||
|
||||
ignore_globbed_names (names, glob_name_is_acceptable);
|
||||
}
|
||||
|
||||
static char *
|
||||
split_ignorespec (s, ip)
|
||||
char *s;
|
||||
int *ip;
|
||||
{
|
||||
char *t;
|
||||
int n, i;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
|
||||
i = *ip;
|
||||
if (s[i] == 0)
|
||||
return 0;
|
||||
|
||||
n = skip_to_delim (s, i, ":", SD_NOJMP|SD_EXTGLOB);
|
||||
t = substring (s, i, n);
|
||||
|
||||
if (s[n] == ':')
|
||||
n++;
|
||||
*ip = n;
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
setup_ignore_patterns (ivp)
|
||||
struct ignorevar *ivp;
|
||||
{
|
||||
int numitems, maxitems, ptr;
|
||||
char *colon_bit, *this_ignoreval;
|
||||
struct ign *p;
|
||||
|
||||
this_ignoreval = get_string_value (ivp->varname);
|
||||
|
||||
/* If nothing has changed then just exit now. */
|
||||
if ((this_ignoreval && ivp->last_ignoreval && STREQ (this_ignoreval, ivp->last_ignoreval)) ||
|
||||
(!this_ignoreval && !ivp->last_ignoreval))
|
||||
return;
|
||||
|
||||
/* Oops. The ignore variable has changed. Re-parse it. */
|
||||
ivp->num_ignores = 0;
|
||||
|
||||
if (ivp->ignores)
|
||||
{
|
||||
for (p = ivp->ignores; p->val; p++)
|
||||
free(p->val);
|
||||
free (ivp->ignores);
|
||||
ivp->ignores = (struct ign *)NULL;
|
||||
}
|
||||
|
||||
if (ivp->last_ignoreval)
|
||||
{
|
||||
free (ivp->last_ignoreval);
|
||||
ivp->last_ignoreval = (char *)NULL;
|
||||
}
|
||||
|
||||
if (this_ignoreval == 0 || *this_ignoreval == '\0')
|
||||
return;
|
||||
|
||||
ivp->last_ignoreval = savestring (this_ignoreval);
|
||||
|
||||
numitems = maxitems = ptr = 0;
|
||||
|
||||
#if 0
|
||||
while (colon_bit = extract_colon_unit (this_ignoreval, &ptr))
|
||||
#else
|
||||
while (colon_bit = split_ignorespec (this_ignoreval, &ptr))
|
||||
#endif
|
||||
{
|
||||
if (numitems + 1 >= maxitems)
|
||||
{
|
||||
maxitems += 10;
|
||||
ivp->ignores = (struct ign *)xrealloc (ivp->ignores, maxitems * sizeof (struct ign));
|
||||
}
|
||||
ivp->ignores[numitems].val = colon_bit;
|
||||
ivp->ignores[numitems].len = strlen (colon_bit);
|
||||
ivp->ignores[numitems].flags = 0;
|
||||
if (ivp->item_func)
|
||||
(*ivp->item_func) (&ivp->ignores[numitems]);
|
||||
numitems++;
|
||||
}
|
||||
ivp->ignores[numitems].val = (char *)NULL;
|
||||
ivp->num_ignores = numitems;
|
||||
}
|
||||
@@ -1461,6 +1461,10 @@ pcomp_set_readline_variables (flags, nval)
|
||||
/* If the user doesn't want a space appended, tell readline. */
|
||||
if (flags & COPT_NOSPACE)
|
||||
rl_completion_suppress_append = nval;
|
||||
/* The value here is inverted, since the default is on and the `noquote'
|
||||
option is supposed to turn it off */
|
||||
if (flags & COPT_NOQUOTE)
|
||||
rl_filename_quoting_desired = 1 - nval;
|
||||
}
|
||||
|
||||
/* Set or unset FLAGS in the options word of the current compspec.
|
||||
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
/* pcomplete.c - functions to generate lists of matches for programmable completion. */
|
||||
|
||||
/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1999-2011 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -372,6 +372,7 @@ it_init_aliases (itp)
|
||||
#else
|
||||
itp->slist = (STRINGLIST *)NULL;
|
||||
#endif
|
||||
free (alias_list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -71,9 +71,10 @@ typedef struct compspec {
|
||||
#define COPT_DEFAULT (1<<1)
|
||||
#define COPT_FILENAMES (1<<2)
|
||||
#define COPT_DIRNAMES (1<<3)
|
||||
#define COPT_NOSPACE (1<<4)
|
||||
#define COPT_BASHDEFAULT (1<<5)
|
||||
#define COPT_PLUSDIRS (1<<6)
|
||||
#define COPT_NOQUOTE (1<<4)
|
||||
#define COPT_NOSPACE (1<<5)
|
||||
#define COPT_BASHDEFAULT (1<<6)
|
||||
#define COPT_PLUSDIRS (1<<7)
|
||||
|
||||
/* List of items is used by the code that implements the programmable
|
||||
completions. */
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/* pcomplete.h - structure definitions and other stuff for programmable
|
||||
completion. */
|
||||
|
||||
/* Copyright (C) 1999-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/>.
|
||||
*/
|
||||
|
||||
#if !defined (_PCOMPLETE_H_)
|
||||
# define _PCOMPLETE_H_
|
||||
|
||||
#include "stdc.h"
|
||||
#include "hashlib.h"
|
||||
|
||||
typedef struct compspec {
|
||||
int refcount;
|
||||
unsigned long actions;
|
||||
unsigned long options;
|
||||
char *globpat;
|
||||
char *words;
|
||||
char *prefix;
|
||||
char *suffix;
|
||||
char *funcname;
|
||||
char *command;
|
||||
char *lcommand;
|
||||
char *filterpat;
|
||||
} COMPSPEC;
|
||||
|
||||
/* Values for COMPSPEC actions. These are things the shell knows how to
|
||||
build internally. */
|
||||
#define CA_ALIAS (1<<0)
|
||||
#define CA_ARRAYVAR (1<<1)
|
||||
#define CA_BINDING (1<<2)
|
||||
#define CA_BUILTIN (1<<3)
|
||||
#define CA_COMMAND (1<<4)
|
||||
#define CA_DIRECTORY (1<<5)
|
||||
#define CA_DISABLED (1<<6)
|
||||
#define CA_ENABLED (1<<7)
|
||||
#define CA_EXPORT (1<<8)
|
||||
#define CA_FILE (1<<9)
|
||||
#define CA_FUNCTION (1<<10)
|
||||
#define CA_GROUP (1<<11)
|
||||
#define CA_HELPTOPIC (1<<12)
|
||||
#define CA_HOSTNAME (1<<13)
|
||||
#define CA_JOB (1<<14)
|
||||
#define CA_KEYWORD (1<<15)
|
||||
#define CA_RUNNING (1<<16)
|
||||
#define CA_SERVICE (1<<17)
|
||||
#define CA_SETOPT (1<<18)
|
||||
#define CA_SHOPT (1<<19)
|
||||
#define CA_SIGNAL (1<<20)
|
||||
#define CA_STOPPED (1<<21)
|
||||
#define CA_USER (1<<22)
|
||||
#define CA_VARIABLE (1<<23)
|
||||
|
||||
/* Values for COMPSPEC options field. */
|
||||
#define COPT_RESERVED (1<<0) /* reserved for other use */
|
||||
#define COPT_DEFAULT (1<<1)
|
||||
#define COPT_FILENAMES (1<<2)
|
||||
#define COPT_DIRNAMES (1<<3)
|
||||
#define COPT_NOSPACE (1<<4)
|
||||
#define COPT_BASHDEFAULT (1<<5)
|
||||
#define COPT_PLUSDIRS (1<<6)
|
||||
|
||||
/* List of items is used by the code that implements the programmable
|
||||
completions. */
|
||||
typedef struct _list_of_items {
|
||||
int flags;
|
||||
int (*list_getter) __P((struct _list_of_items *)); /* function to call to get the list */
|
||||
|
||||
STRINGLIST *slist;
|
||||
|
||||
/* These may or may not be used. */
|
||||
STRINGLIST *genlist; /* for handing to the completion code one item at a time */
|
||||
int genindex; /* index of item last handed to completion code */
|
||||
|
||||
} ITEMLIST;
|
||||
|
||||
/* Values for ITEMLIST -> flags */
|
||||
#define LIST_DYNAMIC 0x001
|
||||
#define LIST_DIRTY 0x002
|
||||
#define LIST_INITIALIZED 0x004
|
||||
#define LIST_MUSTSORT 0x008
|
||||
#define LIST_DONTFREE 0x010
|
||||
#define LIST_DONTFREEMEMBERS 0x020
|
||||
|
||||
#define EMPTYCMD "_EmptycmD_"
|
||||
#define DEFAULTCMD "_DefaultCmD_"
|
||||
|
||||
extern HASH_TABLE *prog_completes;
|
||||
extern int prog_completion_enabled;
|
||||
|
||||
/* Not all of these are used yet. */
|
||||
extern ITEMLIST it_aliases;
|
||||
extern ITEMLIST it_arrayvars;
|
||||
extern ITEMLIST it_bindings;
|
||||
extern ITEMLIST it_builtins;
|
||||
extern ITEMLIST it_commands;
|
||||
extern ITEMLIST it_directories;
|
||||
extern ITEMLIST it_disabled;
|
||||
extern ITEMLIST it_enabled;
|
||||
extern ITEMLIST it_exports;
|
||||
extern ITEMLIST it_files;
|
||||
extern ITEMLIST it_functions;
|
||||
extern ITEMLIST it_groups;
|
||||
extern ITEMLIST it_helptopics;
|
||||
extern ITEMLIST it_hostnames;
|
||||
extern ITEMLIST it_jobs;
|
||||
extern ITEMLIST it_keywords;
|
||||
extern ITEMLIST it_running;
|
||||
extern ITEMLIST it_services;
|
||||
extern ITEMLIST it_setopts;
|
||||
extern ITEMLIST it_shopts;
|
||||
extern ITEMLIST it_signals;
|
||||
extern ITEMLIST it_stopped;
|
||||
extern ITEMLIST it_users;
|
||||
extern ITEMLIST it_variables;
|
||||
|
||||
extern COMPSPEC *pcomp_curcs;
|
||||
extern const char *pcomp_curcmd;
|
||||
|
||||
/* Functions from pcomplib.c */
|
||||
extern COMPSPEC *compspec_create __P((void));
|
||||
extern void compspec_dispose __P((COMPSPEC *));
|
||||
extern COMPSPEC *compspec_copy __P((COMPSPEC *));
|
||||
|
||||
extern void progcomp_create __P((void));
|
||||
extern void progcomp_flush __P((void));
|
||||
extern void progcomp_dispose __P((void));
|
||||
|
||||
extern int progcomp_size __P((void));
|
||||
|
||||
extern int progcomp_insert __P((char *, COMPSPEC *));
|
||||
extern int progcomp_remove __P((char *));
|
||||
|
||||
extern COMPSPEC *progcomp_search __P((const char *));
|
||||
|
||||
extern void progcomp_walk __P((hash_wfunc *));
|
||||
|
||||
/* Functions from pcomplete.c */
|
||||
extern void set_itemlist_dirty __P((ITEMLIST *));
|
||||
|
||||
extern STRINGLIST *completions_to_stringlist __P((char **));
|
||||
|
||||
extern STRINGLIST *gen_compspec_completions __P((COMPSPEC *, const char *, const char *, int, int, int *));
|
||||
extern char **programmable_completions __P((const char *, const char *, int, int, int *));
|
||||
|
||||
extern void pcomp_set_readline_variables __P((int, int));
|
||||
extern void pcomp_set_compspec_options __P((COMPSPEC *, int, int));
|
||||
#endif /* _PCOMPLETE_H_ */
|
||||
@@ -1051,7 +1051,7 @@ do_redirection_internal (redirect, flags)
|
||||
file descriptors >= SHELL_FD_BASE, we set the saving fd to be
|
||||
close-on-exec and use a flag to decide how to set close-on-exec
|
||||
when the fd is restored. */
|
||||
if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && redir_fd >= SHELL_FD_BASE)
|
||||
if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (redirect->flags & RX_SAVEFD)))
|
||||
SET_OPEN_ON_EXEC (redirector);
|
||||
|
||||
/* dup-and-close redirection */
|
||||
@@ -1123,13 +1123,19 @@ add_undo_redirect (fd, ri, fdbase)
|
||||
enum r_instruction ri;
|
||||
int fdbase;
|
||||
{
|
||||
int new_fd, clexec_flag;
|
||||
int new_fd, clexec_flag, savefd_flag;
|
||||
REDIRECT *new_redirect, *closer, *dummy_redirect;
|
||||
REDIRECTEE sd;
|
||||
|
||||
savefd_flag = 0;
|
||||
new_fd = fcntl (fd, F_DUPFD, (fdbase < SHELL_FD_BASE) ? SHELL_FD_BASE : fdbase+1);
|
||||
if (new_fd < 0)
|
||||
new_fd = fcntl (fd, F_DUPFD, SHELL_FD_BASE);
|
||||
if (new_fd < 0)
|
||||
{
|
||||
new_fd = fcntl (fd, F_DUPFD, 0);
|
||||
savefd_flag = 1;
|
||||
}
|
||||
|
||||
if (new_fd < 0)
|
||||
{
|
||||
@@ -1152,7 +1158,9 @@ add_undo_redirect (fd, ri, fdbase)
|
||||
else
|
||||
new_redirect = make_redirection (sd, r_duplicating_output, rd, 0);
|
||||
new_redirect->flags |= RX_INTERNAL;
|
||||
if (clexec_flag == 0 && fd >= 3 && new_fd >= SHELL_FD_BASE)
|
||||
if (savefd_flag)
|
||||
new_redirect->flags |= RX_SAVEFD;
|
||||
if (clexec_flag == 0 && fd >= 3 && (new_fd >= SHELL_FD_BASE || savefd_flag))
|
||||
new_redirect->flags |= RX_SAVCLEXEC;
|
||||
new_redirect->next = closer;
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ redirection_error (temp, error)
|
||||
|
||||
allocname = 0;
|
||||
if (temp->rflags & REDIR_VARASSIGN)
|
||||
filename = savestring (temp->redirector.filename->word);
|
||||
filename = allocname = savestring (temp->redirector.filename->word);
|
||||
else if (temp->redirector.dest < 0)
|
||||
/* This can happen when read_token_word encounters overflow, like in
|
||||
exec 4294967297>x */
|
||||
@@ -1051,7 +1051,7 @@ do_redirection_internal (redirect, flags)
|
||||
file descriptors >= SHELL_FD_BASE, we set the saving fd to be
|
||||
close-on-exec and use a flag to decide how to set close-on-exec
|
||||
when the fd is restored. */
|
||||
if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && redir_fd >= SHELL_FD_BASE)
|
||||
if ((redirect->flags & RX_INTERNAL) && (redirect->flags & RX_SAVCLEXEC) && redirector >= 3 && (redir_fd >= SHELL_FD_BASE || (redirect->flags & RX_SAVEFD)))
|
||||
SET_OPEN_ON_EXEC (redirector);
|
||||
|
||||
/* dup-and-close redirection */
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#define RX_INTERNAL 0x08
|
||||
#define RX_USER 0x10
|
||||
#define RX_SAVCLEXEC 0x20 /* set close-on-exec off in restored fd even though saved on has it on */
|
||||
#define RX_SAVEFD 0x40 /* fd used to save another even if < SHELL_FD_BASE */
|
||||
|
||||
extern void redirection_error __P((REDIRECT *, int));
|
||||
extern int do_redirections __P((REDIRECT *, int));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/* redir.h - functions from redir.c. */
|
||||
|
||||
/* Copyright (C) 1997, 2001, 2005, 2008,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/>.
|
||||
*/
|
||||
|
||||
#if !defined (_REDIR_H_)
|
||||
#define _REDIR_H_
|
||||
|
||||
#include "stdc.h"
|
||||
|
||||
/* Values for flags argument to do_redirections */
|
||||
#define RX_ACTIVE 0x01 /* do it; don't just go through the motions */
|
||||
#define RX_UNDOABLE 0x02 /* make a list to undo these redirections */
|
||||
#define RX_CLEXEC 0x04 /* set close-on-exec for opened fds > 2 */
|
||||
#define RX_INTERNAL 0x08
|
||||
#define RX_USER 0x10
|
||||
#define RX_SAVCLEXEC 0x20 /* set close-on-exec off in restored fd even though saved on has it on */
|
||||
|
||||
extern void redirection_error __P((REDIRECT *, int));
|
||||
extern int do_redirections __P((REDIRECT *, int));
|
||||
extern char *redirection_expand __P((WORD_DESC *));
|
||||
extern int stdin_redirects __P((REDIRECT *));
|
||||
|
||||
#endif /* _REDIR_H_ */
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
Reference in New Issue
Block a user