diff options
| author | Chet Ramey <chet.ramey@case.edu> | 2017-01-17 14:20:55 -0500 |
|---|---|---|
| committer | Chet Ramey <chet.ramey@case.edu> | 2017-01-17 14:20:55 -0500 |
| commit | 3e8a02a68917250f088a500b09543255364f6f2b (patch) | |
| tree | dccc69fc7b986d8dcf092fb0354b3751c6cacc5f | |
| parent | ee88838cf9421e2e40a7b7969cdf78a0010b075c (diff) | |
| download | bash-3e8a02a68917250f088a500b09543255364f6f2b.tar.gz | |
commit bash-20170113 snapshot
| -rw-r--r-- | CWRU/CWRU.chlog | 24 | ||||
| -rw-r--r-- | lib/glob/glob.c | 51 | ||||
| -rw-r--r-- | lib/glob/glob_loop.c | 31 | ||||
| -rw-r--r-- | lib/glob/gmisc.c | 19 | ||||
| -rwxr-xr-x | tests/RUN-ONE-TEST | 2 | ||||
| -rw-r--r-- | tests/extglob.right | 8 | ||||
| -rw-r--r-- | tests/extglob3.sub | 4 | ||||
| -rw-r--r-- | tests/extglob4.sub | 7 |
8 files changed, 107 insertions, 39 deletions
diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index e1826ba..2d2f7fc 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -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 + + diff --git a/lib/glob/glob.c b/lib/glob/glob.c index 796ee9d..1451afa 100644 --- a/lib/glob/glob.c +++ b/lib/glob/glob.c @@ -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); diff --git a/lib/glob/glob_loop.c b/lib/glob/glob_loop.c index 89e86af..9529ccb 100644 --- a/lib/glob/glob_loop.c +++ b/lib/glob/glob_loop.c @@ -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 diff --git a/lib/glob/gmisc.c b/lib/glob/gmisc.c index 31906a4..19065fb 100644 --- a/lib/glob/gmisc.c +++ b/lib/glob/gmisc.c @@ -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) \ diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 58c375b..554f3d6 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -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 diff --git a/tests/extglob.right b/tests/extglob.right index efb7e5f..8c50059 100644 --- a/tests/extglob.right +++ b/tests/extglob.right @@ -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 diff --git a/tests/extglob3.sub b/tests/extglob3.sub index 8511b67..3f51c40 100644 --- a/tests/extglob3.sub +++ b/tests/extglob3.sub @@ -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 diff --git a/tests/extglob4.sub b/tests/extglob4.sub index ccf74ef..2b4c53c 100644 --- a/tests/extglob4.sub +++ b/tests/extglob4.sub @@ -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 |
