diff options
-rw-r--r-- | libbutl/filesystem.cxx | 29 | ||||
-rw-r--r-- | libbutl/filesystem.mxx | 8 | ||||
-rw-r--r-- | tests/wildcard/testscript | 134 |
3 files changed, 115 insertions, 56 deletions
diff --git a/libbutl/filesystem.cxx b/libbutl/filesystem.cxx index 736426b..2fae1f9 100644 --- a/libbutl/filesystem.cxx +++ b/libbutl/filesystem.cxx @@ -1737,32 +1737,11 @@ namespace butl // component omitted, unless this is the only pattern component. // if ((fl & path_match_flags::match_absent) != path_match_flags::none && + pc.to_directory () && + (!pattern_dir.empty () || !simple) && pc.string ().find_first_not_of ('*') == string::npos && - (!pattern_dir.empty () || !simple)) - { - // Stripping the (leading) absent-matching pattern component and calling - // search() with the resulting pattern and the same pattern dir works in - // most cases, except for a simple pattern. In the latter case, the - // pattern becomes empty and its type information gets lost. In other - // words, the patterns a/b/*/ and a/b/* become indistinguishable. Thus, - // for such a corner case we will strip the leaf from the pattern dir - // and use it as a pattern, stripping the trailing separator, if - // required. So for the above examples the search() calls will be as - // follows: - // - // search(b/, a/) - // search(b, a/) - // - const dir_path& d (!simple ? pattern_dir : pattern_dir.directory ()); - - const path& p ( - !simple ? pattern.leaf (pc) : - pattern.to_directory () ? pattern_dir.leaf () : - path (pattern_dir.leaf ().string ())); // Strip the trailing separator. - - if (!search (p, d, fl, func, filesystem)) - return false; - } + !search (pattern.leaf (pc), pattern_dir, fl, func, filesystem)) + return false; return true; } diff --git a/libbutl/filesystem.mxx b/libbutl/filesystem.mxx index f05e569..cf041c2 100644 --- a/libbutl/filesystem.mxx +++ b/libbutl/filesystem.mxx @@ -714,8 +714,12 @@ LIBBUTL_MODEXPORT namespace butl // set, the `a/*/b` pattern matches not only `a/x/b` path, but also `a/b`. // // Note that this does not apply to single-component patterns and the - // pattern type is always preserved. In particular, the `a/b/*` pattern - // matches `a/b` but not `a/b/`. + // pattern type is always preserved. In particular, the `a/*/` pattern + // matches `a/` but not `a`. + // + // Finally, keep in mind that only absent directory components can be + // matched this way. In particular, pattern `a*/*` does not match `ab` + // (but `a*/*/` matches `ab/`). // match_absent = 0x2, diff --git a/tests/wildcard/testscript b/tests/wildcard/testscript index 885a7d5..bc90468 100644 --- a/tests/wildcard/testscript +++ b/tests/wildcard/testscript @@ -1154,7 +1154,7 @@ : ignorable-components : { - test.options += -i + test.options += -i -n : middle : @@ -1164,25 +1164,58 @@ $* a/**/b a/b >/ a/b $* a/**/b a/x/b >/ a/x/b - $* a/***/b a/b >>/EOE + $* a/***/b a/b >>/EOO a/b a/b - EOE + EOO + + : multiple + : + { + $* a/**/*/b a/b >/ a/b + + $* a/**/*/b a/x/b >>/EOO + a/x/b + a/x/b + EOO + } } : top-level : if ($cxx.target.class != 'windows') { - $* -n /*/a /a > /a - $* -n /*/a /b/a > /b/a + $* /*/a /a > /a + $* /*/a /b/a > /b/a + + : multiple + : + { + $* /*/*/a /a > /a + + $* /*/*/a /b/a >>EOO + /b/a + /b/a + EOO + } } : leading : { - $* -n */a a >/ a - $* -n */a b/a >/ b/a + $* */a a >/ a + $* */a b/a >/ b/a + + : multiple + : + { + $* */*/a a >/ a + + $* */*/a b/a >>/EOO + b/a + b/a + EOO + } } : trailing @@ -1190,45 +1223,88 @@ { : file : + : Test that the pattern star-only component of the file type does not + : match an absent component. + : { - $* -n a/* a >/ a - $* -n a/* a/b >/ a/b + $* a/* a/b >/ a/b + + $* a/* a == 1 + $* a/* a/ == 1 + $* a/* a/b/ == 1 + + : multiple + : + { + $* a/*/* a/b >/ a/b - $* -n a/* a/ == 1 - $* -n a/* a/b/ == 1 + $* a/*/* a == 1 + $* a/*/* a/ == 1 + $* a/*/* a/b/ == 1 + } } : dir : { - $* -n a/*/ a/ >/ a/ - $* -n a/*/ a/b >/ a/ + $* a/*/ a/ >/ a/ + $* a/*/ a/b >/ a/ - $* -n a/*/ a/b/ >>/EOE + $* a/*/ a/b/ >>/EOO a/b/ a/ - EOE + EOO + + $* a/*/ a == 1 - $* -n a/*/ a == 1 + : multiple + : + { + $* a/*/*/ a/ >/ a/ + $* a/*/*/ a/b >/ a/ + + $* a/*/*/ a/b/ >>/EOO + a/b/ + a/b/ + a/ + EOO + + $* a/*/*/ a == 1 + } } } : leading-trailing { - $* -n */* a >/ a - $* -n */* a/b >/ a/b - - $* -n */a/* a >/ a - $* -n */a/* a/b >/ a/b - $* -n */a/* b/a >/ b/a - $* -n */a/* c/a/b >/ c/a/b - - $* -n **/a/** a >/ a - $* -n **/a/** a/b/c/d >/ a/b/c/d - $* -n **/a/** d/c/b/a >/ d/c/b/a - $* -n **/a/** d/c/b/a/b/c/d >/ d/c/b/a/b/c/d - } + : adjacent + : + { + $* */* a >/ a + $* */* a/b >/ a/b + + $* */* a/ == 1 + } + : apart + : + { + $* */a/* a/b >/ a/b + $* */a/* c/a/b >/ c/a/b + $* */a/* a == 1 + $* */a/* b/a == 1 + $* */a/* b/a/ == 1 + + : recursive + : + { + $* **/a/** a/b/c/d >/ a/b/c/d + $* **/a/** d/c/b/a/b/c/d >/ d/c/b/a/b/c/d + + $* **/a/** a == 1 + $* **/a/** d/c/b/a == 1 + } + } + } } } |