mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 00:19:51 +02:00
commit bash-20170113 snapshot
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user