commit bash-20120914 snapshot

This commit is contained in:
Chet Ramey
2012-10-10 09:36:15 -04:00
parent c84e520283
commit f14388d3aa
23 changed files with 19680 additions and 3830 deletions
+40
View File
@@ -3537,3 +3537,43 @@ expr.c
short-circuiting evaluation completely. readtok will leave curtok
set correctly without re-entering the evaluator at all. Rest of
fix for bug reported by Dan Douglas <ormaaj@gmail.com>
9/11
----
parse.y
- parse_comsub: make sure the `reserved word ok in this context' flag
is preserved after we read `do' followed by whitespace. Fixes bug
reported by Benoit Vaugon <benoit.vaugon@gmail.com>
9/13
----
configure.ac,config.h.in
- enable-direxpand-default: new configure option, turns the `direxpand'
shell option on by default
bashline.c
- dircomplete_expand, dircomplete_expand_relpath: initialize to 1 if
DIRCOMPLETE_EXPAND_DEFAULT is defined and non-zero
doc/bashref.texi
- enable-direxpand-default: document new configure option
9/14
----
shell.c
- --protected: make option valid only when wordexp is compiled into
the shell. Fix from Roman Rakus <rrakus@redhat.com>
configure.ac
- HP NonStop (*-nsk*): compile --without-bash-malloc. Change from
Joachim Schmitz <jojo@schmitz-digital.de>
9/16
----
subst.c,execute_cmd.c,lib/glob/sm_loop.c,lib/sh/shquote.c
- minor code cleanups from Joachim Schmitz <jojo@schmitz-digital.de>
lib/readline/colors.h
- workaround for HP NonStop compiler issue with <stdbool.h> from
Joachim Schmitz <jojo@schmitz-digital.de>
+42 -4
View File
@@ -3508,10 +3508,6 @@ redir.c
9/8
---
expr.c
- expr_streval: save and restore the value of `noeval' around any call
to get_array_value, since that can end up recursively calling
evalexp to perform array subscript evaluation. Fixes bug reported
by Dan Douglas <ormaaj@gmail.com>
- readtok: invalidate previous contents of `curlval' before freeing
and reallocating tokstr (which, chances are, will get the same
pointer as before and render curlval inconsistent). Fixes other
@@ -3535,3 +3531,45 @@ lib/readline/display.c
lib/readline/{terminal.c,rlprivate.h}
- move CUSTOM_REDISPLAY_FUNC and CUSTOM_INPUT_FUNC defines from
terminal.c to rlprivate.h so other files can use them
expr.c
- expr_streval: if noeval is non-zero, just return 0 right away,
short-circuiting evaluation completely. readtok will leave curtok
set correctly without re-entering the evaluator at all. Rest of
fix for bug reported by Dan Douglas <ormaaj@gmail.com>
9/11
----
parse.y
- parse_comsub: make sure the `reserved word ok in this context' flag
is preserved after we read `do' followed by whitespace. Fixes bug
reported by Benoit Vaugon <benoit.vaugon@gmail.com>
9/13
----
configure.ac,config.h.in
- enable-direxpand-default: new configure option, turns the `direxpand'
shell option on by default
bashline.c
- dircomplete_expand, dircomplete_expand_relpath: initialize to 1 if
DIRCOMPLETE_EXPAND_DEFAULT is defined and non-zero
doc/bashref.texi
- enable-direxpand-default: document new configure option
9/14
----
shell.c
- --protected: make option valid only when wordexp is compiled into
the shell. Fix from Roman Rakus <rrakus@redhat.com>
configure.ac
- HP NonStop (*-nsk*): compile --without-bash-malloc. Change from
Joachim Schmitz <jojo@schmitz-digital.de>
9/16
----
subst.c,execute_cmd.c,lib/glob/sm_loop.c,lib/sh/shquote.c
- minor code cleanups from Joachim Schmitz <jojo@schmitz-digital.de>
+15 -1
View File
@@ -1,5 +1,5 @@
@%:@! /bin/sh
@%:@ From configure.ac for Bash 4.2, version 4.050.
@%:@ From configure.ac for Bash 4.2, version 4.052.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.68 for bash 4.2-maint.
@%:@
@@ -783,6 +783,7 @@ enable_cond_command
enable_cond_regexp
enable_coprocesses
enable_debugger
enable_direxpand_default
enable_directory_stack
enable_disabled_builtins
enable_dparen_arithmetic
@@ -1466,6 +1467,8 @@ Optional Features:
--enable-coprocesses enable coprocess support and the coproc reserved
word
--enable-debugger enable support for bash debugger
--enable-direxpand-default
enable the direxpand shell option by default
--enable-directory-stack
enable builtins pushd/popd/dirs
--enable-disabled-builtins
@@ -2837,6 +2840,7 @@ sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
*-beos*) opt_bash_malloc=no ;; # they say it's suitable
*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
esac
# memory scrambling on free()
@@ -2967,6 +2971,7 @@ opt_single_longdoc_strings=yes
opt_casemod_attrs=yes
opt_casemod_expansions=yes
opt_extglob_default=no
opt_dircomplete_expand_default=no
opt_static_link=no
opt_profiling=no
@@ -3049,6 +3054,11 @@ if test "${enable_debugger+set}" = set; then :
enableval=$enable_debugger; opt_debugger=$enableval
fi
@%:@ Check whether --enable-direxpand-default was given.
if test "${enable_direxpand_default+set}" = set; then :
enableval=$enable_direxpand_default; opt_dircomplete_expand_default=$enableval
fi
@%:@ Check whether --enable-directory-stack was given.
if test "${enable_directory_stack+set}" = set; then :
enableval=$enable_directory_stack; opt_dirstack=$enableval
@@ -3284,6 +3294,10 @@ fi
if test $opt_casemod_expansions = yes; then
$as_echo "@%:@define CASEMOD_EXPANSIONS 1" >>confdefs.h
fi
if test $opt_dircomplete_expand_default = yes; then
$as_echo "@%:@define DIRCOMPLETE_EXPAND_DEFAULT 1" >>confdefs.h
fi
if test $opt_memscramble = yes; then
+1706 -1701
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -255,8 +255,13 @@ int force_fignore = 1;
int dircomplete_spelling = 0;
/* Expand directory names during word/filename completion. */
#if DIRCOMPLETE_EXPAND_DEFAULT
int dircomplete_expand = 1;
int dircomplete_expand_relpath = 1;
#else
int dircomplete_expand = 0;
int dircomplete_expand_relpath = 0;
#endif
/* When non-zero, perform `normal' shell quoting on completed filenames
even when the completed name contains a directory name with a shell
+6 -3
View File
@@ -160,9 +160,6 @@
memory contents on malloc() and free(). */
#undef MEMSCRAMBLE
/* Define AFS if you are using Transarc's AFS. */
#undef AFS
/* Define for case-modifying variable attributes; variables modified on
assignment */
#undef CASEMOD_ATTRS
@@ -170,6 +167,12 @@
/* Define for case-modifying word expansions */
#undef CASEMOD_EXPANSIONS
/* Define to make the `direxpand' shopt option enabled by default. */
#undef DIRCOMPLETE_EXPAND_DEFAULT
/* Define AFS if you are using Transarc's AFS. */
#undef AFS
#undef ENABLE_NLS
/* End of configuration settings controllable by autoconf. */
Vendored
+15 -1
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.ac for Bash 4.2, version 4.050.
# From configure.ac for Bash 4.2, version 4.052.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.68 for bash 4.2-maint.
#
@@ -783,6 +783,7 @@ enable_cond_command
enable_cond_regexp
enable_coprocesses
enable_debugger
enable_direxpand_default
enable_directory_stack
enable_disabled_builtins
enable_dparen_arithmetic
@@ -1466,6 +1467,8 @@ Optional Features:
--enable-coprocesses enable coprocess support and the coproc reserved
word
--enable-debugger enable support for bash debugger
--enable-direxpand-default
enable the direxpand shell option by default
--enable-directory-stack
enable builtins pushd/popd/dirs
--enable-disabled-builtins
@@ -2837,6 +2840,7 @@ sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
*-beos*) opt_bash_malloc=no ;; # they say it's suitable
*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
esac
# memory scrambling on free()
@@ -2967,6 +2971,7 @@ opt_single_longdoc_strings=yes
opt_casemod_attrs=yes
opt_casemod_expansions=yes
opt_extglob_default=no
opt_dircomplete_expand_default=no
opt_static_link=no
opt_profiling=no
@@ -3049,6 +3054,11 @@ if test "${enable_debugger+set}" = set; then :
enableval=$enable_debugger; opt_debugger=$enableval
fi
# Check whether --enable-direxpand-default was given.
if test "${enable_direxpand_default+set}" = set; then :
enableval=$enable_direxpand_default; opt_dircomplete_expand_default=$enableval
fi
# Check whether --enable-directory-stack was given.
if test "${enable_directory_stack+set}" = set; then :
enableval=$enable_directory_stack; opt_dirstack=$enableval
@@ -3284,6 +3294,10 @@ fi
if test $opt_casemod_expansions = yes; then
$as_echo "#define CASEMOD_EXPANSIONS 1" >>confdefs.h
fi
if test $opt_dircomplete_expand_default = yes; then
$as_echo "#define DIRCOMPLETE_EXPAND_DEFAULT 1" >>confdefs.h
fi
if test $opt_memscramble = yes; then
+7 -1
View File
@@ -21,7 +21,7 @@ dnl Process this file with autoconf to produce a configure script.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AC_REVISION([for Bash 4.2, version 4.050])dnl
AC_REVISION([for Bash 4.2, version 4.052])dnl
define(bashvers, 4.2)
define(relstatus, maint)
@@ -89,6 +89,7 @@ sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
*-beos*) opt_bash_malloc=no ;; # they say it's suitable
*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
esac
# memory scrambling on free()
@@ -188,6 +189,7 @@ opt_single_longdoc_strings=yes
opt_casemod_attrs=yes
opt_casemod_expansions=yes
opt_extglob_default=no
opt_dircomplete_expand_default=no
dnl options that affect how bash is compiled and linked
opt_static_link=no
@@ -222,6 +224,7 @@ AC_ARG_ENABLE(cond-command, AC_HELP_STRING([--enable-cond-command], [enable the
AC_ARG_ENABLE(cond-regexp, AC_HELP_STRING([--enable-cond-regexp], [enable extended regular expression matching in conditional commands]), opt_cond_regexp=$enableval)
AC_ARG_ENABLE(coprocesses, AC_HELP_STRING([--enable-coprocesses], [enable coprocess support and the coproc reserved word]), opt_coproc=$enableval)
AC_ARG_ENABLE(debugger, AC_HELP_STRING([--enable-debugger], [enable support for bash debugger]), opt_debugger=$enableval)
AC_ARG_ENABLE(direxpand-default, AC_HELP_STRING([--enable-direxpand-default], [enable the direxpand shell option by default]), opt_dircomplete_expand_default=$enableval)
AC_ARG_ENABLE(directory-stack, AC_HELP_STRING([--enable-directory-stack], [enable builtins pushd/popd/dirs]), opt_dirstack=$enableval)
AC_ARG_ENABLE(disabled-builtins, AC_HELP_STRING([--enable-disabled-builtins], [allow disabled builtins to still be invoked]), opt_disabled_builtins=$enableval)
AC_ARG_ENABLE(dparen-arithmetic, AC_HELP_STRING([--enable-dparen-arithmetic], [include ((...)) command]), opt_dparen_arith=$enableval)
@@ -341,6 +344,9 @@ fi
if test $opt_casemod_expansions = yes; then
AC_DEFINE(CASEMOD_EXPANSIONS)
fi
if test $opt_dircomplete_expand_default = yes; then
AC_DEFINE(DIRCOMPLETE_EXPAND_DEFAULT)
fi
if test $opt_memscramble = yes; then
AC_DEFINE(MEMSCRAMBLE)
+5
View File
@@ -7955,6 +7955,11 @@ Include support for coprocesses and the @code{coproc} reserved word
@item --enable-debugger
Include support for the bash debugger (distributed separately).
@item --enable-direxpand-default
Cause the @code{direxpand} shell option (@pxref{The Shopt Builtin})
to be enabled by default when the shell starts.
It is normally disabled by default.
@item --enable-directory-stack
Include support for a @code{csh}-like directory stack and the
@code{pushd}, @code{popd}, and @code{dirs} builtins
+3 -9
View File
@@ -2,15 +2,9 @@
Copyright (C) 1988-2012 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Tue Aug 28 17:19:20 EDT 2012
@set LASTCHANGE Thu Sep 13 17:12:28 EDT 2012
@set EDITION 4.2
@set VERSION 4.2
@set UPDATED 28 August 2012
@set UPDATED-MONTH August 2012
@set UPDATED 13 September 2012
@set UPDATED-MONTH September 2012
+2 -2
View File
@@ -698,7 +698,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
if (variable_context != 0)
{
ofifo = num_fifos ();
ofifo_list = copy_fifo_list (&osize);
ofifo_list = copy_fifo_list ((int *)&osize);
saved_fifo = 1;
}
else
@@ -1017,7 +1017,7 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
{
nfifo = num_fifos ();
if (nfifo > ofifo)
close_new_fifos (ofifo_list, osize);
close_new_fifos ((char *)ofifo_list, osize);
free (ofifo_list);
}
#endif
+5363
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -291,7 +291,7 @@ BRACKMATCH (p, test, flags)
{
register CHAR cstart, cend, c;
register int not; /* Nonzero if the sense of the character class is inverted. */
int brcnt, forcecoll;;
int brcnt, forcecoll;
INT pc;
CHAR *savep;
+773
View File
@@ -0,0 +1,773 @@
/* Copyright (C) 1991-2011 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/>.
*/
int FCT __P((CHAR *, CHAR *, int));
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
/*static*/ CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
int
FCT (pattern, string, flags)
CHAR *pattern;
CHAR *string;
int flags;
{
CHAR *se, *pe;
if (string == 0 || pattern == 0)
return FNM_NOMATCH;
se = string + STRLEN ((XCHAR *)string);
pe = pattern + STRLEN ((XCHAR *)pattern);
return (GMATCH (string, se, pattern, pe, flags));
}
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, FNM_NOMATCH if not. */
static int
GMATCH (string, se, pattern, pe, flags)
CHAR *string, *se;
CHAR *pattern, *pe;
int flags;
{
CHAR *p, *n; /* pattern, string */
INT c; /* current pattern character - XXX U_CHAR? */
INT sc; /* current string character - XXX U_CHAR? */
p = pattern;
n = string;
if (string == 0 || pattern == 0)
return FNM_NOMATCH;
#if DEBUG_MATCHING
fprintf(stderr, "gmatch: string = %s; se = %s\n", string, se);
fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
#endif
while (p < pe)
{
c = *p++;
c = FOLD (c);
sc = n < se ? *n : '\0';
#ifdef EXTENDED_GLOB
/* EXTMATCH () will handle recursively calling GMATCH, so we can
just return what EXTMATCH() returns. */
if ((flags & FNM_EXTMATCH) && *p == L('(') &&
(c == L('+') || c == L('*') || c == L('?') || c == L('@') || c == L('!'))) /* ) */
{
int lflags;
/* If we're not matching the start of the string, we're not
concerned about the special cases for matching `.' */
lflags = (n == string) ? flags : (flags & ~FNM_PERIOD);
return (EXTMATCH (c, n, se, p, pe, lflags));
}
#endif /* EXTENDED_GLOB */
switch (c)
{
case L('?'): /* Match single character */
if (sc == '\0')
return FNM_NOMATCH;
else if ((flags & FNM_PATHNAME) && sc == L('/'))
/* If we are matching a pathname, `?' can never match a `/'. */
return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && sc == L('.') &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
/* `?' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return FNM_NOMATCH;
break;
case L('\\'): /* backslash escape removes special meaning */
if (p == pe)
return FNM_NOMATCH;
if ((flags & FNM_NOESCAPE) == 0)
{
c = *p++;
/* A trailing `\' cannot match. */
if (p > pe)
return FNM_NOMATCH;
c = FOLD (c);
}
if (FOLD (sc) != (U_CHAR)c)
return FNM_NOMATCH;
break;
case '*': /* Match zero or more characters */
if (p == pe)
return 0;
if ((flags & FNM_PERIOD) && sc == L('.') &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
/* `*' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return FNM_NOMATCH;
/* Collapse multiple consecutive `*' and `?', but make sure that
one character of the string is consumed for each `?'. */
for (c = *p++; (c == L('?') || c == L('*')); c = *p++)
{
if ((flags & FNM_PATHNAME) && sc == L('/'))
/* A slash does not match a wildcard under FNM_PATHNAME. */
return FNM_NOMATCH;
#ifdef EXTENDED_GLOB
else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */
{
CHAR *newn;
for (newn = n; newn < se; ++newn)
{
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
return (0);
}
/* We didn't match. If we have a `?(...)', that's failure. */
return FNM_NOMATCH;
}
#endif
else if (c == L('?'))
{
if (sc == L('\0'))
return FNM_NOMATCH;
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
fewer than three characters. */
n++;
sc = n < se ? *n : '\0';
}
#ifdef EXTENDED_GLOB
/* Handle ******(patlist) */
if ((flags & FNM_EXTMATCH) && c == L('*') && *p == L('(')) /*)*/
{
CHAR *newn;
/* We need to check whether or not the extended glob
pattern matches the remainder of the string.
If it does, we match the entire pattern. */
for (newn = n; newn < se; ++newn)
{
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
return (0);
}
/* We didn't match the extended glob pattern, but
that's OK, since we can match 0 or more occurrences.
We need to skip the glob pattern and see if we
match the rest of the string. */
newn = PATSCAN (p + 1, pe, 0);
/* If NEWN is 0, we have an ill-formed pattern. */
p = newn ? newn : pe;
}
#endif
if (p == pe)
break;
}
/* If we've hit the end of the pattern and the last character of
the pattern was handled by the loop above, we've succeeded.
Otherwise, we need to match that last character. */
if (p == pe && (c == L('?') || c == L('*')))
return (0);
/* General case, use recursion. */
{
U_CHAR c1;
c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c;
c1 = FOLD (c1);
for (--p; n < se; ++n)
{
/* Only call strmatch if the first character indicates a
possible match. We can check the first character if
we're not doing an extended glob match. */
if ((flags & FNM_EXTMATCH) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/
continue;
/* If we're doing an extended glob match and the pattern is not
one of the extended glob patterns, we can check the first
character. */
if ((flags & FNM_EXTMATCH) && p[1] != L('(') && /*)*/
STRCHR (L("?*+@!"), *p) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/
continue;
/* Otherwise, we just recurse. */
if (GMATCH (n, se, p, pe, flags & ~FNM_PERIOD) == 0)
return (0);
}
return FNM_NOMATCH;
}
case L('['):
{
if (sc == L('\0') || n == se)
return FNM_NOMATCH;
/* A character class cannot match a `.' if it is the first
character of the string or if it is the first character
following a slash and we are matching a pathname. */
if ((flags & FNM_PERIOD) && sc == L('.') &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
return (FNM_NOMATCH);
p = BRACKMATCH (p, sc, flags);
if (p == 0)
return FNM_NOMATCH;
}
break;
default:
if ((U_CHAR)c != FOLD (sc))
return (FNM_NOMATCH);
}
++n;
}
if (n == se)
return (0);
if ((flags & FNM_LEADING_DIR) && *n == L('/'))
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
return (FNM_NOMATCH);
}
/* Parse a bracket expression collating symbol ([.sym.]) starting at P, find
the value of the symbol, and move P past the collating symbol expression.
The value is returned in *VP, if VP is not null. */
static CHAR *
PARSE_COLLSYM (p, vp)
CHAR *p;
INT *vp;
{
register int pc;
INT val;
p++; /* move past the `.' */
for (pc = 0; p[pc]; pc++)
if (p[pc] == L('.') && p[pc+1] == L(']'))
break;
val = COLLSYM (p, pc);
if (vp)
*vp = val;
return (p + pc + 2);
}
/* Use prototype definition here because of type promotion. */
static CHAR *
#if defined (PROTOTYPES)
BRACKMATCH (CHAR *p, U_CHAR test, int flags)
#else
BRACKMATCH (p, test, flags)
CHAR *p;
U_CHAR test;
int flags;
#endif
{
register CHAR cstart, cend, c;
register int not; /* Nonzero if the sense of the character class is inverted. */
int brcnt, forcecoll;;
INT pc;
CHAR *savep;
test = FOLD (test);
savep = p;
/* POSIX.2 3.13.1 says that an exclamation mark (`!') shall replace the
circumflex (`^') in its role in a `nonmatching list'. A bracket
expression starting with an unquoted circumflex character produces
unspecified results. This implementation treats the two identically. */
if (not = (*p == L('!') || *p == L('^')))
++p;
c = *p++;
for (;;)
{
/* Initialize cstart and cend in case `-' is the last
character of the pattern. */
cstart = cend = c;
forcecoll = 0;
/* POSIX.2 equivalence class: [=c=]. See POSIX.2 2.8.3.2. Find
the end of the equivalence class, move the pattern pointer past
it, and check for equivalence. XXX - this handles only
single-character equivalence classes, which is wrong, or at
least incomplete. */
if (c == L('[') && *p == L('=') && p[2] == L('=') && p[3] == L(']'))
{
pc = FOLD (p[1]);
p += 4;
if (COLLEQUIV (test, pc))
{
/*[*/ /* Move past the closing `]', since the first thing we do at
the `matched:' label is back p up one. */
p++;
goto matched;
}
else
{
c = *p++;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
c = FOLD (c);
continue;
}
}
/* POSIX.2 character class expression. See POSIX.2 2.8.3.2. */
if (c == L('[') && *p == L(':'))
{
CHAR *close, *ccname;
pc = 0; /* make sure invalid char classes don't match. */
/* Find end of character class name */
for (close = p + 1; *close != '\0'; close++)
if (*close == L(':') && *(close+1) == L(']'))
break;
if (*close != L('\0'))
{
ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR));
if (ccname == 0)
pc = 0;
else
{
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
*(ccname + (close - p - 1)) = L('\0');
pc = IS_CCLASS (test, (XCHAR *)ccname);
}
if (pc == -1)
pc = 0;
else
p = close + 2;
free (ccname);
}
if (pc)
{
/*[*/ /* Move past the closing `]', since the first thing we do at
the `matched:' label is back p up one. */
p++;
goto matched;
}
else
{
/* continue the loop here, since this expression can't be
the first part of a range expression. */
c = *p++;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L(']'))
break;
c = FOLD (c);
continue;
}
}
/* POSIX.2 collating symbols. See POSIX.2 2.8.3.2. Find the end of
the symbol name, make sure it is terminated by `.]', translate
the name to a character using the external table, and do the
comparison. */
if (c == L('[') && *p == L('.'))
{
p = PARSE_COLLSYM (p, &pc);
/* An invalid collating symbol cannot be the first point of a
range. If it is, we set cstart to one greater than `test',
so any comparisons later will fail. */
cstart = (pc == INVALID) ? test + 1 : pc;
forcecoll = 1;
}
if (!(flags & FNM_NOESCAPE) && c == L('\\'))
{
if (*p == '\0')
return (CHAR *)0;
cstart = cend = *p++;
}
cstart = cend = FOLD (cstart);
/* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that
is not preceded by a backslash and is not part of a bracket
expression produces undefined results.' This implementation
treats the `[' as just a character to be matched if there is
not a closing `]'. */
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
c = *p++;
c = FOLD (c);
if ((flags & FNM_PATHNAME) && c == L('/'))
/* [/] can never match when matching a pathname. */
return (CHAR *)0;
/* This introduces a range, unless the `-' is the last
character of the class. Find the end of the range
and move past it. */
if (c == L('-') && *p != L(']'))
{
cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
cend = *p++;
if (cend == L('\0'))
return (CHAR *)0;
if (cend == L('[') && *p == L('.'))
{
p = PARSE_COLLSYM (p, &pc);
/* An invalid collating symbol cannot be the second part of a
range expression. If we get one, we set cend to one fewer
than the test character to make sure the range test fails. */
cend = (pc == INVALID) ? test - 1 : pc;
forcecoll = 1;
}
cend = FOLD (cend);
c = *p++;
/* POSIX.2 2.8.3.2: ``The ending range point shall collate
equal to or higher than the starting range point; otherwise
the expression shall be treated as invalid.'' Note that this
applies to only the range expression; the rest of the bracket
expression is still checked for matches. */
if (RANGECMP (cstart, cend, forcecoll) > 0)
{
if (c == L(']'))
break;
c = FOLD (c);
continue;
}
}
if (RANGECMP (test, cstart, forcecoll) >= 0 && RANGECMP (test, cend, forcecoll) <= 0)
goto matched;
if (c == L(']'))
break;
}
/* No match. */
return (!not ? (CHAR *)0 : p);
matched:
/* Skip the rest of the [...] that already matched. */
c = *--p;
brcnt = 1;
while (brcnt > 0)
{
/* A `[' without a matching `]' is just another character to match. */
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
c = *p++;
if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.')))
brcnt++;
else if (c == L(']'))
brcnt--;
else if (!(flags & FNM_NOESCAPE) && c == L('\\'))
{
if (*p == '\0')
return (CHAR *)0;
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
}
return (not ? (CHAR *)0 : p);
}
#if defined (EXTENDED_GLOB)
/* ksh-like extended pattern matching:
[?*+@!](pat-list)
where pat-list is a list of one or patterns separated by `|'. Operation
is as follows:
?(patlist) match zero or one of the given patterns
*(patlist) match zero or more of the given patterns
+(patlist) match one or more of the given patterns
@(patlist) match exactly one of the given patterns
!(patlist) match anything except one of the given patterns
*/
/* Scan a pattern starting at STRING and ending at END, keeping track of
embedded () and []. If DELIM is 0, we scan until a matching `)'
because we're scanning a `patlist'. Otherwise, we scan until we see
DELIM. In all cases, we never scan past END. The return value is the
first character after the matching DELIM. */
/*static*/ CHAR *
PATSCAN (string, end, delim)
CHAR *string, *end;
INT delim;
{
int pnest, bnest, skip;
INT cchar;
CHAR *s, c, *bfirst;
pnest = bnest = skip = 0;
cchar = 0;
bfirst = NULL;
for (s = string; c = *s; s++)
{
if (s >= end)
return (s);
if (skip)
{
skip = 0;
continue;
}
switch (c)
{
case L('\\'):
skip = 1;
break;
case L('\0'):
return ((CHAR *)NULL);
/* `[' is not special inside a bracket expression, but it may
introduce one of the special POSIX bracket expressions
([.SYM.], [=c=], [: ... :]) that needs special handling. */
case L('['):
if (bnest == 0)
{
bfirst = s + 1;
if (*bfirst == L('!') || *bfirst == L('^'))
bfirst++;
bnest++;
}
else if (s[1] == L(':') || s[1] == L('.') || s[1] == L('='))
cchar = s[1];
break;
/* `]' is not special if it's the first char (after a leading `!'
or `^') in a bracket expression or if it's part of one of the
special POSIX bracket expressions ([.SYM.], [=c=], [: ... :]) */
case L(']'):
if (bnest)
{
if (cchar && s[-1] == cchar)
cchar = 0;
else if (s != bfirst)
{
bnest--;
bfirst = 0;
}
}
break;
case L('('):
if (bnest == 0)
pnest++;
break;
case L(')'):
if (bnest == 0 && pnest-- <= 0)
return ++s;
break;
case L('|'):
if (bnest == 0 && pnest == 0 && delim == L('|'))
return ++s;
break;
}
}
return (NULL);
}
/* Return 0 if dequoted pattern matches S in the current locale. */
static int
STRCOMPARE (p, pe, s, se)
CHAR *p, *pe, *s, *se;
{
int ret;
CHAR c1, c2;
c1 = *pe;
c2 = *se;
*pe = *se = '\0';
#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL)
ret = STRCOLL ((XCHAR *)p, (XCHAR *)s);
#else
ret = STRCMP ((XCHAR *)p, (XCHAR *)s);
#endif
*pe = c1;
*se = c2;
return (ret == 0 ? ret : FNM_NOMATCH);
}
/* Match a ksh extended pattern specifier. Return FNM_NOMATCH on failure or
0 on success. This is handed the entire rest of the pattern and string
the first time an extended pattern specifier is encountered, so it calls
gmatch recursively. */
static int
EXTMATCH (xc, s, se, p, pe, flags)
INT xc; /* select which operation */
CHAR *s, *se;
CHAR *p, *pe;
int flags;
{
CHAR *prest; /* pointer to rest of pattern */
CHAR *psub; /* pointer to sub-pattern */
CHAR *pnext; /* pointer to next sub-pattern */
CHAR *srest; /* pointer to rest of string */
int m1, m2, xflags; /* xflags = flags passed to recursive matches */
#if DEBUG_MATCHING
fprintf(stderr, "extmatch: xc = %c\n", xc);
fprintf(stderr, "extmatch: s = %s; se = %s\n", s, se);
fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe);
fprintf(stderr, "extmatch: flags = %d\n", flags);
#endif
prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
if (prest == 0)
/* If PREST is 0, we failed to scan a valid pattern. In this
case, we just want to compare the two as strings. */
return (STRCOMPARE (p - 1, pe, s, se));
switch (xc)
{
case L('+'): /* match one or more occurrences */
case L('*'): /* match zero or more occurrences */
/* If we can get away with no matches, don't even bother. Just
call GMATCH on the rest of the pattern and return success if
it succeeds. */
if (xc == L('*') && (GMATCH (s, se, prest, pe, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we make sure one of
the subpatterns matches, then we try to match the rest of the
string. */
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
for (srest = s; srest <= se; srest++)
{
/* Match this substring (S -> SREST) against this
subpattern (psub -> pnext - 1) */
m1 = GMATCH (s, srest, psub, pnext - 1, flags) == 0;
/* OK, we matched a subpattern, so make sure the rest of the
string matches the rest of the pattern. Also handle
multiple matches of the pattern. */
if (m1)
{
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
m2 = (GMATCH (srest, se, prest, pe, xflags) == 0) ||
(s != srest && GMATCH (srest, se, p - 1, pe, xflags) == 0);
}
if (m1 && m2)
return (0);
}
if (pnext == prest)
break;
}
return (FNM_NOMATCH);
case L('?'): /* match zero or one of the patterns */
case L('@'): /* match one (or more) of the patterns */
/* If we can get away with no matches, don't even bother. Just
call gmatch on the rest of the pattern and return success if
it succeeds. */
if (xc == L('?') && (GMATCH (s, se, prest, pe, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we see if one of
the subpatterns matches, then, if it does, we try to match the
rest of the string. */
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
srest = (prest == pe) ? se : s;
for ( ; srest <= se; srest++)
{
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
if (GMATCH (s, srest, psub, pnext - 1, flags) == 0 &&
GMATCH (srest, se, prest, pe, xflags) == 0)
return (0);
}
if (pnext == prest)
break;
}
return (FNM_NOMATCH);
case '!': /* match anything *except* one of the patterns */
for (srest = s; srest <= se; srest++)
{
m1 = 0;
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
/* If one of the patterns matches, just bail immediately. */
if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))
break;
if (pnext == prest)
break;
}
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
if (m1 == 0 && GMATCH (srest, se, prest, pe, xflags) == 0)
return (0);
}
return (FNM_NOMATCH);
}
return (FNM_NOMATCH);
}
#endif /* EXTENDED_GLOB */
#undef IS_CCLASS
#undef FOLD
#undef CHAR
#undef U_CHAR
#undef XCHAR
#undef INT
#undef INVALID
#undef FCT
#undef GMATCH
#undef COLLSYM
#undef PARSE_COLLSYM
#undef PATSCAN
#undef STRCOMPARE
#undef EXTMATCH
#undef BRACKMATCH
#undef STRCHR
#undef STRCOLL
#undef STRLEN
#undef STRCMP
#undef COLLEQUIV
#undef RANGECMP
#undef L
+4
View File
@@ -29,6 +29,10 @@
#include <stdio.h> // size_t
#if defined(__TANDEM) && defined(HAVE_STDBOOL_H) && (__STDC_VERSION__ < 199901L)
typedef int _Bool;
#endif
#if defined (HAVE_STDBOOL_H)
# include <stdbool.h> // bool
#else
+118
View File
@@ -0,0 +1,118 @@
/* `dir', `vdir' and `ls' directory listing programs for GNU.
Modified by Chet Ramey for Readline.
Copyright (C) 1985, 1988, 1990-1991, 1995-2010, 2012 Free Software Foundation,
Inc.
This program 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.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
/* Written by Richard Stallman and David MacKenzie. */
/* Color support by Peter Anvin <Peter.Anvin@linux.org> and Dennis
Flaherty <dennisf@denix.elk.miles.com> based on original patches by
Greg Lee <lee@uhunix.uhcc.hawaii.edu>. */
#ifndef _COLORS_H_
#define _COLORS_H_
#include <stdio.h> // size_t
#if defined (HAVE_STDBOOL_H)
# include <stdbool.h> // bool
#else
typedef int _rl_bool_t;
#ifdef bool
# undef bool
#endif
#define bool _rl_bool_t
#ifndef true
# define true 1
# define false 0
#endif
#endif /* !HAVE_STDBOOL_H */
/* Null is a valid character in a color indicator (think about Epson
printers, for example) so we have to use a length/buffer string
type. */
struct bin_str
{
size_t len;
const char *string;
};
/* file type indicators (dir, sock, fifo, ...)
Default value is initialized in parse-colors.c.
It is then modified from the values of $LS_COLORS. */
extern struct bin_str _rl_color_indicator[];
/* The LS_COLORS variable is in a termcap-like format. */
typedef struct _color_ext_type
{
struct bin_str ext; /* The extension we're looking for */
struct bin_str seq; /* The sequence to output when we do */
struct _color_ext_type *next; /* Next in list */
} COLOR_EXT_TYPE;
/* file extensions indicators (.txt, .log, .jpg, ...)
Values are taken from $LS_COLORS in rl_parse_colors(). */
extern COLOR_EXT_TYPE *_rl_color_ext_list;
#define FILETYPE_INDICATORS \
{ \
C_ORPHAN, C_FIFO, C_CHR, C_DIR, C_BLK, C_FILE, \
C_LINK, C_SOCK, C_FILE, C_DIR \
}
/* Whether we used any colors in the output so far. If so, we will
need to restore the default color later. If not, we will need to
call prep_non_filename_text before using color for the first time. */
enum indicator_no
{
C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
C_FIFO, C_SOCK,
C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE, C_CAP, C_MULTIHARDLINK,
C_CLR_TO_EOL
};
#if !S_IXUGO
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif
enum filetype
{
unknown,
fifo,
chardev,
directory,
blockdev,
normal,
symbolic_link,
sock,
whiteout,
arg_directory
};
extern void _rl_put_indicator (const struct bin_str *ind);
extern void _rl_set_normal_color (void);
extern bool _rl_print_color_indicator (char *f);
extern void _rl_prep_non_filename_text (void);
#endif /* !_COLORS_H_ */
+1 -1
View File
@@ -222,7 +222,7 @@ sh_backslash_quote (string, table, flags)
result = (char *)xmalloc (2 * strlen (string) + 1);
backslash_table = table ? table : bstab;
backslash_table = table ? table : (char *)bstab;
for (r = result, s = string; s && (c = *s); s++)
{
if (backslash_table[c] == 1)
+304
View File
@@ -0,0 +1,304 @@
/* shquote - functions to quote and dequote strings */
/* Copyright (C) 1999 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>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "syntax.h"
#include <xmalloc.h>
/* Default set of characters that should be backslash-quoted in strings */
static const char bstab[256] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, /* TAB, NL */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 0, 1, 0, 1, 1, /* SPACE, !, DQUOTE, DOL, AMP, SQUOTE */
1, 1, 1, 0, 1, 0, 0, 0, /* LPAR, RPAR, STAR, COMMA */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 0, 1, 1, /* SEMI, LESSTHAN, GREATERTHAN, QUEST */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 0, /* LBRACK, BS, RBRACK, CARAT */
1, 0, 0, 0, 0, 0, 0, 0, /* BACKQ */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 0, 0, /* LBRACE, BAR, RBRACE */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
/* **************************************************************** */
/* */
/* Functions for quoting strings to be re-read as input */
/* */
/* **************************************************************** */
/* Return a new string which is the single-quoted version of STRING.
Used by alias and trap, among others. */
char *
sh_single_quote (string)
const char *string;
{
register int c;
char *result, *r;
const char *s;
result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result;
*r++ = '\'';
for (s = string; s && (c = *s); s++)
{
*r++ = c;
if (c == '\'')
{
*r++ = '\\'; /* insert escaped single quote */
*r++ = '\'';
*r++ = '\''; /* start new quoted string */
}
}
*r++ = '\'';
*r = '\0';
return (result);
}
/* Quote STRING using double quotes. Return a new string. */
char *
sh_double_quote (string)
const char *string;
{
register unsigned char c;
char *result, *r;
const char *s;
result = (char *)xmalloc (3 + (2 * strlen (string)));
r = result;
*r++ = '"';
for (s = string; s && (c = *s); s++)
{
/* Backslash-newline disappears within double quotes, so don't add one. */
if ((sh_syntaxtab[c] & CBSDQUOTE) && c != '\n')
*r++ = '\\';
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r++ = '"';
*r = '\0';
return (result);
}
/* Turn S into a simple double-quoted string. If FLAGS is non-zero, quote
double quote characters in S with backslashes. */
char *
sh_mkdoublequoted (s, slen, flags)
const char *s;
int slen, flags;
{
char *r, *ret;
int rlen;
rlen = (flags == 0) ? slen + 3 : (2 * slen) + 1;
ret = r = (char *)xmalloc (rlen);
*r++ = '"';
while (*s)
{
if (flags && *s == '"')
*r++ = '\\';
*r++ = *s++;
}
*r++ = '"';
*r = '\0';
return ret;
}
/* Remove backslashes that are quoting characters that are special between
double quotes. Return a new string. XXX - should this handle CTLESC
and CTLNUL? */
char *
sh_un_double_quote (string)
char *string;
{
register int c, pass_next;
char *result, *r, *s;
r = result = (char *)xmalloc (strlen (string) + 1);
for (pass_next = 0, s = string; s && (c = *s); s++)
{
if (pass_next)
{
*r++ = c;
pass_next = 0;
continue;
}
if (c == '\\' && (sh_syntaxtab[(unsigned char) s[1]] & CBSDQUOTE))
{
pass_next = 1;
continue;
}
*r++ = c;
}
*r = '\0';
return result;
}
/* Quote special characters in STRING using backslashes. Return a new
string. NOTE: if the string is to be further expanded, we need a
way to protect the CTLESC and CTLNUL characters. As I write this,
the current callers will never cause the string to be expanded without
going through the shell parser, which will protect the internal
quoting characters. TABLE, if set, points to a map of the ascii code
set with char needing to be backslash-quoted if table[char]==1. FLAGS,
if 1, causes tildes to be quoted as well. */
char *
sh_backslash_quote (string, table, flags)
char *string;
char *table;
int flags;
{
int c;
char *result, *r, *s, *backslash_table;
result = (char *)xmalloc (2 * strlen (string) + 1);
backslash_table = table ? table : bstab;
for (r = result, s = string; s && (c = *s); s++)
{
if (backslash_table[c] == 1)
*r++ = '\\';
else if (c == '#' && s == string) /* comment char */
*r++ = '\\';
else if ((flags&1) && c == '~' && (s == string || s[-1] == ':' || s[-1] == '='))
/* Tildes are special at the start of a word or after a `:' or `='
(technically unquoted, but it doesn't make a difference in practice) */
*r++ = '\\';
*r++ = c;
}
*r = '\0';
return (result);
}
#if defined (PROMPT_STRING_DECODE)
/* Quote characters that get special treatment when in double quotes in STRING
using backslashes. Return a new string. */
char *
sh_backslash_quote_for_double_quotes (string)
char *string;
{
unsigned char c;
char *result, *r, *s;
result = (char *)xmalloc (2 * strlen (string) + 1);
for (r = result, s = string; s && (c = *s); s++)
{
if (sh_syntaxtab[c] & CBSDQUOTE)
*r++ = '\\';
/* I should probably add flags for these to sh_syntaxtab[] */
else if (c == CTLESC || c == CTLNUL)
*r++ = CTLESC; /* could be '\\'? */
*r++ = c;
}
*r = '\0';
return (result);
}
#endif /* PROMPT_STRING_DECODE */
int
sh_contains_shell_metas (string)
char *string;
{
char *s;
for (s = string; s && *s; s++)
{
switch (*s)
{
case ' ': case '\t': case '\n': /* IFS white space */
case '\'': case '"': case '\\': /* quoting chars */
case '|': case '&': case ';': /* shell metacharacters */
case '(': case ')': case '<': case '>':
case '!': case '{': case '}': /* reserved words */
case '*': case '[': case '?': case ']': /* globbing chars */
case '^':
case '$': case '`': /* expansion chars */
return (1);
case '~': /* tilde expansion */
if (s == string || s[-1] == '=' || s[-1] == ':')
return (1);
break;
case '#':
if (s == string) /* comment char */
return (1);
/* FALLTHROUGH */
default:
break;
}
}
return (0);
}
+20
View File
@@ -3675,6 +3675,17 @@ eof_error:
}
else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0)))
; /* don't modify LEX_RESWDOK if we're starting a comment */
/* Allow `do' followed by space, tab, or newline to preserve the
RESWDOK flag, but reset the reserved word length counter so we
can read another one. */
else if MBTEST(((tflags & LEX_INCASE) == 0) &&
(isblank(ch) || ch == '\n') &&
lex_rwlen == 2 &&
STREQN (ret + retind - 2, "do", 2))
{
/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', found \"do\"", line_number, ch);*/
lex_rwlen = 0;
}
else if MBTEST((tflags & LEX_INCASE) && ch != '\n')
/* If we can read a reserved word and we're in case, we're at the
point where we can read a new pattern list or an esac. We
@@ -3690,6 +3701,15 @@ eof_error:
tflags &= ~LEX_RESWDOK;
/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
}
#if 0
/* If we find a space or tab but have read something and it's not
`do', turn off the reserved-word-ok flag */
else if MBTEST(isblank (ch) && lex_rwlen > 0)
{
tflags &= ~LEX_RESWDOK;
/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/
}
#endif
}
/* Might be the start of a here-doc delimiter */
+1732 -2105
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -252,7 +252,9 @@ static const struct {
{ "noprofile", Int, &no_profile, (char **)0x0 },
{ "norc", Int, &no_rc, (char **)0x0 },
{ "posix", Int, &posixly_correct, (char **)0x0 },
#if defined (WORDEXP_OPTION)
{ "protected", Int, &protected_mode, (char **)0x0 },
#endif
{ "rcfile", Charp, (int *)0x0, &bashrc_file },
#if defined (RESTRICTED_SHELL)
{ "restricted", Int, &restricted, (char **)0x0 },
+1 -1
View File
@@ -7875,7 +7875,7 @@ comsub:
temp = nameref_cell (var);
if (temp && *temp && valid_array_reference (temp))
{
tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, (int *)NULL);
tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, (arrayind_t *)NULL);
if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
return (tdesc);
ret = tdesc;
+9515
View File
File diff suppressed because it is too large Load Diff