commit bash-20170113 snapshot

This commit is contained in:
Chet Ramey
2017-01-17 14:20:55 -05:00
parent ee88838cf9
commit 3e8a02a689
8 changed files with 107 additions and 39 deletions
+24
View File
@@ -12973,3 +12973,27 @@ execute_cmd.c
the only time QUIT gets called is when the path is actually
searched. It doesn't happen for an absolute pathname. Fix for
bug reported by Russell King <rmk@armlinux.org.uk>
1/16
----
lib/glob/glob.c
- extglob_skipname,wextglob_skipname: if we don't find a reason to
not skip the name in any subpattern (r returns 0 for any subpattern),
return 1 because we should skip the name
- extglob_skipname,wextglob_skipname: if we don't find a reason to
not skip the name in any subpattern, but the first part of the extglob
pattern is a wildcard (`*(pat)'), check the rest of the pattern, if
any, to decide whether or not to skip the name. Fixes bug reported
by Grisha Levit <grishalevit@gmail.com>
lib/glob/glob_loop.c
- CHAR -> GCHAR (unsigned char); change uses of CHAR to GCHAR
- extglob_skipname: move here from gmisc.c, generalize for regular
and wide-char versions
lib/glob/glob.c
- wchkname -> wskipname
- wskipname: now takes a third `flags' argument, like the other variants
of skipname
+36 -15
View File
@@ -126,19 +126,23 @@ extern wchar_t *glob_patscan_wc __P((wchar_t *, wchar_t *, int));
extern char *glob_dirscan __P((char *, int));
/* Compile `glob_loop.c' for single-byte characters. */
#define CHAR unsigned char
#define GCHAR unsigned char
#define CHAR char
#define INT int
#define L(CS) CS
#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
#define EXTGLOB_PATTERN_P extglob_pattern_p
#include "glob_loop.c"
/* Compile `glob_loop.c' again for multibyte characters. */
#if HANDLE_MULTIBYTE
#define GCHAR wchar_t
#define CHAR wchar_t
#define INT wint_t
#define L(CS) L##CS
#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
#define EXTGLOB_PATTERN_P wextglob_pattern_p
#include "glob_loop.c"
#endif /* HANDLE_MULTIBYTE */
@@ -182,9 +186,10 @@ extglob_skipname (pat, dname, flags)
int flags;
{
char *pp, *pe, *t, *se;
int n, r, negate;
int n, r, negate, wild;
negate = *pat == '!';
wild = *pat == '*' || *pat == '?';
pp = pat + 2;
se = pp + strlen (pp) - 1; /* end of string */
pe = glob_patscan (pp, se, 0); /* end of extglob pattern (( */
@@ -203,14 +208,19 @@ extglob_skipname (pat, dname, flags)
r = skipname (pp, dname, flags); /*(*/
#endif
*pe = ')';
if (wild && pe[1]) /* if we can match zero instances, check further */
return (skipname (pe+1, dname, flags));
return r;
}
/* check every subpattern */
while (t = glob_patscan (pp, pe, '|'))
{
n = t[-1];
t[-1] = '\0';
n = t[-1]; /* ( */
if (extglob_pattern_p (pp) && n == ')')
t[-1] = n; /* no-op for now */
else
t[-1] = '\0';
#if defined (HANDLE_MULTIBYTE)
r = mbskipname (pp, dname, flags);
#else
@@ -222,12 +232,14 @@ extglob_skipname (pat, dname, flags)
pp = t;
} /*(*/
/* glob_patscan might find end of pattern */
/* glob_patscan might find end of string */
if (pp == se)
return r;
/* but if it doesn't then we didn't match a leading dot */
return 0;
if (wild && *pe) /* if we can match zero instances, check further */
return (skipname (pe, dname, flags));
return 1;
}
#endif
@@ -263,8 +275,9 @@ skipname (pat, dname, flags)
#if HANDLE_MULTIBYTE
static int
wchkname (pat_wc, dn_wc)
wskipname (pat_wc, dn_wc, flags)
wchar_t *pat_wc, *dn_wc;
int flags;
{
/* If a leading dot need not be explicitly matched, and the
pattern doesn't start with a `.', don't match `.' or `..' */
@@ -291,9 +304,10 @@ wextglob_skipname (pat, dname, flags)
{
#if EXTENDED_GLOB
wchar_t *pp, *pe, *t, n, *se;
int r, negate;
int r, negate, wild;
negate = *pat == L'!';
wild = *pat == L'*' || *pat == L'?';
pp = pat + 2;
se = pp + wcslen (pp) - 1; /*(*/
pe = glob_patscan_wc (pp, se, 0);
@@ -301,17 +315,22 @@ wextglob_skipname (pat, dname, flags)
if (pe == se && *pe == ')' && (t = wcschr (pp, L'|')) == 0)
{
*pe = L'\0';
r = wchkname (pp, dname); /*(*/
r = wskipname (pp, dname, flags); /*(*/
*pe = L')';
if (wild && pe[1] != L'\0')
return (wskipname (pe+1, dname, flags));
return r;
}
/* check every subpattern */
while (t = glob_patscan_wc (pp, pe, '|'))
{
n = t[-1];
t[-1] = L'\0';
r = wchkname (pp, dname);
n = t[-1]; /* ( */
if (wextglob_pattern_p (pp) && n == L')')
t[-1] = n; /* no-op for now */
else
t[-1] = L'\0';
r = wskipname (pp, dname, flags);
t[-1] = n;
if (r == 0)
return 0;
@@ -322,9 +341,11 @@ wextglob_skipname (pat, dname, flags)
return r;
/* but if it doesn't then we didn't match a leading dot */
return 0;
if (wild && *pe != L'\0')
return (wskipname (pe, dname, flags));
return 1;
#else
return (wchkname (pat, dname));
return (wskipname (pat, dname, flags));
#endif
}
@@ -355,7 +376,7 @@ mbskipname (pat, dname, flags)
ret = 0;
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
ret = ext ? wextglob_skipname (pat_wc, dn_wc, flags) : wchkname (pat_wc, dn_wc);
ret = ext ? wextglob_skipname (pat_wc, dn_wc, flags) : wskipname (pat_wc, dn_wc, flags);
else
ret = skipname (pat, dname, flags);
+27 -4
View File
@@ -16,16 +16,16 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
static int INTERNAL_GLOB_PATTERN_P __P((const CHAR *));
static int INTERNAL_GLOB_PATTERN_P __P((const GCHAR *));
/* Return nonzero if PATTERN has any special globbing chars in it.
Compiled twice, once each for single-byte and multibyte characters. */
static int
INTERNAL_GLOB_PATTERN_P (pattern)
const CHAR *pattern;
const GCHAR *pattern;
{
register const CHAR *p;
register CHAR c;
register const GCHAR *p;
register GCHAR c;
int bopen;
p = pattern;
@@ -61,7 +61,30 @@ INTERNAL_GLOB_PATTERN_P (pattern)
return 0;
}
#if EXTENDED_GLOB
int
EXTGLOB_PATTERN_P (pat)
const CHAR *pat;
{
switch (pat[0])
{
case L('*'):
case L('+'):
case L('!'):
case L('@'):
case L('?'):
return (pat[1] == L('(')); /* ) */
default:
return 0;
}
return 0;
}
#endif
#undef EXTGLOB_PATTERN_P
#undef INTERNAL_GLOB_PATTERN_P
#undef L
#undef INT
#undef CHAR
#undef GCHAR
-19
View File
@@ -213,25 +213,6 @@ bad_bracket:
}
#endif
int
extglob_pattern_p (pat)
char *pat;
{
switch (pat[0])
{
case '*':
case '+':
case '!':
case '@':
case '?':
return (pat[1] == LPAREN);
default:
return 0;
}
return 0;
}
#undef FOLD
#define FOLD(c) ((flags & FNM_CASEFOLD) \
? TOLOWER ((unsigned char)c) \
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+8
View File
@@ -94,14 +94,22 @@ a ab
a
. ..
. .. a.log
*(foo)
*(foo|bar)
a.log
?(foo)
a.log
a.log
. ..
. ..
a.log
a.log
.x .y .z
a b c
.x .y .z a b c
a b c
a b c
a b c
a b c
.x .y .z a b c
.x .y .z a b c
+4
View File
@@ -7,14 +7,18 @@ touch a.log
echo *(.)
echo *(.)*
echo *(foo)
echo *(foo|bar)
echo ?(foo)*
echo ?(foo)
echo *(foo)*
echo @(|foo)*
echo *(foo).*
echo *(foo|bar).*
echo !(foo)*
echo !(foo|bar)*
cd $OLDPWD
rm -rf $DIR
+7
View File
@@ -19,6 +19,13 @@ echo @(*|.!(|.)) # wrong, adds . and ..
echo @(*|@(f)) # ??
echo @(*|@(ff))
echo !(f)
echo !(f)!(f)
shopt -s dotglob
echo @(*|@(f))
echo @(*|@(ff))
cd $OLDPWD
rm -rf $GTDIR