diff --git a/.appveyor.yml b/.appveyor.yml index 8ac47c1..81a09a5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,8 +2,8 @@ environment: matrix: - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - #- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - #- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" branches: only: diff --git a/.travis.yml b/.travis.yml index 755a9cb..ec4adf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: julia julia: - #- nightly + - nightly - 0.6 os: - linux diff --git a/README.md b/README.md index b53e687..94eeafd 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Glob is implemented to have both a functional form and an object-oriented form. "a/?/c" # equivalent to 1, above - 3. A vector of strings and/or objects which implement `ismatch`, including `Regex` and `Glob.FilenameMatch` objects + 3. A vector of strings and/or objects which implement `occursin`, including `Regex` and `Glob.FilenameMatch` objects ["a", r".", fn"c"] # again, equivalent to 1, above @@ -41,7 +41,7 @@ Glob is implemented to have both a functional form and an object-oriented form. * Returns a `Glob.GlobMatch` object, which can be used with `glob()` or `readdir()`. See above descriptions. * `fn"pattern"ipedx` :: - * Returns a `Glob.FilenameMatch` object, which can be used with `ismatch()`. Available flags are: + * Returns a `Glob.FilenameMatch` object, which can be used with `ismatch()` or `occursin()`. Available flags are: * `i` = `CASELESS` : Performs case-insensitive matching * `p` = `PERIOD` : A leading period (`.`) character must be exactly matched by a period (`.`) character (not a `?`, `*`, or `[]`). A leading period is a period at the beginning of a string, or a period after a slash if PATHNAME is true. * `e` = `NOESCAPE` : Do not treat backslash (`\`) as a special character (in extended mode, this only outside of `[]`) diff --git a/REQUIRE b/REQUIRE index 137767a..be3c06f 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1 +1,2 @@ julia 0.6 +Compat 0.68.0 diff --git a/src/Glob.jl b/src/Glob.jl index d5e597a..5d5b4ad 100644 --- a/src/Glob.jl +++ b/src/Glob.jl @@ -2,8 +2,17 @@ __precompile__() module Glob -import Base: ismatch, match, readdir, show -isdefined(Base, :isconcrete) || (const isconcrete = Base.isleaftype) # Compat for v0.7 +using Compat + +import Base: ismatch, readdir, show +import Compat: occursin + +@static if VERSION < v"0.7.0-DEV.5126" + function iterate(s::AbstractString, i::Int=firstindex(s)) + i > ncodeunits(s) && return nothing + return s[i], nextind(s, i) + end +end export glob, @fn_str, @fn_mstr, @glob_str, @glob_mstr @@ -46,33 +55,36 @@ function show(io::IO, fn::FilenameMatch) nothing end -function ismatch(fn::FilenameMatch, s::AbstractString) +function occursin(fn::FilenameMatch, s::AbstractString) pattern = fn.pattern caseless = (fn.options & CASELESS) != 0 periodfl = (fn.options & PERIOD ) != 0 noescape = (fn.options & NOESCAPE) != 0 pathname = (fn.options & PATHNAME) != 0 extended = (fn.options & EXTENDED) != 0 - mi = start(pattern) # current index into pattern - i = start(s) # current index into s + mi = firstindex(pattern) # current index into pattern + i = firstindex(s) # current index into s starmatch = i star = 0 period = periodfl - while !done(s, i) - if done(pattern, mi) + while true + matchnext = iterate(s, i) + matchnext === nothing && break + patnext = iterate(pattern, mi) + if patnext === nothing match = false # string characters left to match, but no pattern left else - mc, mi = next(pattern, mi) + mc, mi = patnext if mc == '*' starmatch = i # backup the current search index star = mi - c = next(s, i)[1] # peek-ahead + c, _ = matchnext # peek-ahead if period & (c == '.') return false # * does not match leading . end match = true else - c, i = next(s, i) + c, i = matchnext if mc == '[' mi, valid, match = _match(pattern, mi, c, caseless, extended) if pathname & valid & match & (c == '/') @@ -90,8 +102,11 @@ function ismatch(fn::FilenameMatch, s::AbstractString) end match = true else - if (!noescape) & (mc == '\\') & (!done(pattern, mi)) - mc, mi = next(pattern, mi) + if (!noescape) & (mc == '\\') # escape the next character after backslash, unless it is the last character + patnext = iterate(pattern, mi) + if patnext !== nothing + mc, mi = patnext + end end match = ((c == mc) || (caseless && uppercase(c)==uppercase(mc))) end @@ -99,7 +114,7 @@ function ismatch(fn::FilenameMatch, s::AbstractString) end if !match # try to backtrack and add another character to the last * star == 0 && return false - c, i = next(s, starmatch) + c, i = something(iterate(s, starmatch)) # starmatch is strictly <= i, so it is known that it must be a valid index if pathname & (c == '/') return false # * does not match / end @@ -108,47 +123,64 @@ function ismatch(fn::FilenameMatch, s::AbstractString) end period = (periodfl & pathname & (c == '/')) end - while !done(pattern, mi) # allow trailing *'s - mc, mi = next(pattern, mi) - if mc != '*' - return false # pattern characters left to match, but no string left - end + while true # allow trailing *'s + patnext = iterate(pattern, mi) + patnext === nothing && break + mc, mi = patnext + mc == '*' || return false # pattern characters left to match, but no string left end return true end -filter!(fn::FilenameMatch, v) = filter!(x->ismatch(fn,x), v) -filter(fn::FilenameMatch, v) = filter(x->ismatch(fn,x), v) -filter!(fn::FilenameMatch, d::Dict) = filter!((k,v)->ismatch(fn,k),d) -filter(fn::FilenameMatch, d::Dict) = filter!(fn,copy(d)) + +@static if VERSION < v"0.7.0-DEV.4637" + Base.ismatch(fn::FilenameMatch, s::AbstractString) = occursin(fn, s) +else + @deprecate ismatch(fn::FilenameMatch, s::AbstractString) occursin(fn, s) +end + +filter!(fn::FilenameMatch, v) = filter!(x -> occursin(fn, x), v) +filter(fn::FilenameMatch, v) = filter(x -> occursin(fn, x), v) +@static if VERSION < v"0.7.0-DEV.1378" + filter!(fn::FilenameMatch, d::Dict) = filter!((k, v) -> occursin(fn, k), d) +else + filter!(fn::FilenameMatch, d::Dict) = filter!(((k, v),) -> occursin(fn, k), d) +end +filter(fn::FilenameMatch, d::Dict) = filter!(fn, copy(d)) function _match_bracket(pat::AbstractString, mc::Char, i, cl::Char, cu::Char) # returns (mc, i, valid, match) - if done(pat, i) + next = iterate(pat, i) + if next === nothing return (mc, i, false, false) end - mc2, j = next(pat, i) + mc2, j = next if (mc2 != ':') & (mc2 != '.') & (mc2 != '=') return (mc, i, false, true) end mc3 = mc4 = '\0' k0 = k1 = k2 = k3 = j + next = iterate(pat, k3) matchfail = false while mc3 != mc2 && mc4 != ']' - if done(pat, k3) + if next === nothing return (mc, i, false, false) end mc3 = mc4 k0 = k1 k1 = k2 k2 = k3 - mc4, k3 = next(pat, k3) + next = iterate(pat, k3) + if next === nothing + return (mc, i, false, false) + end + mc4, k3 = next end if mc2 == ':' phrase = SubString(pat, j, k0) match = ( if phrase == "alnum" - isalnum(cl) + isletter(cl) || isnumeric(cl) elseif phrase == "alpha" - isalpha(cl) + isletter(cl) elseif phrase == "blank" (cl == ' ' || cl == '\t') elseif phrase == "cntrl" @@ -156,9 +188,9 @@ function _match_bracket(pat::AbstractString, mc::Char, i, cl::Char, cu::Char) # elseif phrase == "digit" isdigit(cl) elseif phrase == "graph" - isgraph(cl) + isprint(cl) && !isspace(cl) elseif phrase == "lower" - islower(cl) | islower(cu) + islowercase(cl) | islowercase(cu) elseif phrase == "print" isprint(cl) elseif phrase == "punct" @@ -166,7 +198,7 @@ function _match_bracket(pat::AbstractString, mc::Char, i, cl::Char, cu::Char) # elseif phrase == "space" isspace(cl) elseif phrase == "upper" - isupper(cl) | isupper(cu) + isuppercase(cl) | isuppercase(cu) elseif phrase == "xdigit" isxdigit(cl) else @@ -179,13 +211,13 @@ function _match_bracket(pat::AbstractString, mc::Char, i, cl::Char, cu::Char) # #match = (pat[j:k0] == s[ci:ci+(k0-j)]) #return (mc, k3, true, match) end - mc, j = next(pat, j) + mc, j = something(iterate(pat, j)) return (mc, k3, false, true) else #if mc2 == '=' if j != k0 error(string("only single characters are currently supported as character equivalents, got [=", SubString(pat, j, k0), "=]")) end - mc, j = next(pat, j) + mc, j = something(iterate(pat, j)) match = (cl==mc) | (cu==mc) return (mc, k3, true, match) end @@ -200,10 +232,11 @@ function _match(pat::AbstractString, i0, c::Char, caseless::Bool, extended::Bool cl = cu = c end i = i0 - if done(pat, i) + next = iterate(pat, i) + if next === nothing return (i0, false, c=='[') end - mc, j = next(pat, i) + mc, j = next negate = false if mc == '!' negate = true @@ -211,8 +244,10 @@ function _match(pat::AbstractString, i0, c::Char, caseless::Bool, extended::Bool end match = false notfirst = false - while !done(pat,i) - mc, i = next(pat, i) + while true + next = iterate(pat, i) + next === nothing && break + mc, i = next if (mc == ']') & notfirst return (i, true, match ⊻ negate) end @@ -226,20 +261,23 @@ function _match(pat::AbstractString, i0, c::Char, caseless::Bool, extended::Bool return (i0, false, c=='[') end elseif extended & (mc == '\\') - if done(pat, i) + next = iterate(pat, i) + if next === nothing return (i0, false, c=='[') end - mc, i = next(pat, i) + mc, i = next end - if done(pat, i) + next = iterate(pat, i) + if next === nothing return (i0, false, c=='[') end - mc2, j = next(pat, i) + mc2, j = next if mc2 == '-' - if done(pat, j) + next = iterate(pat, j) + if next === nothing return (i0, false, c=='[') end - mc2, j = next(pat, j) + mc2, j = next if mc2 == ']' match |= ((cl == mc) | (cu == mc) | (c == '-')) return (j, true, match ⊻ negate) @@ -252,10 +290,11 @@ function _match(pat::AbstractString, i0, c::Char, caseless::Bool, extended::Bool return (i0, false, c=='[') end elseif extended & (mc2 == '\\') - if done(pat, j) + next = iterate(pat, j) + if next === nothing return (i0, false, c=='[') end - mc2, j = next(pat, j) + mc2, j = next end match |= (mc <= cl <= mc2) match |= (mc <= cu <= mc2) @@ -281,24 +320,25 @@ function GlobMatch(pattern::AbstractString) end pat = split(pattern, '/') S = eltype(pat) - if !isconcrete(S) + if !isconcretetype(S) S = Any else S = Union{S, FilenameMatch{S}} end - glob = Array{S}(length(pat)) + glob = Array{S}(undef, length(pat)) extended = false for i = 1:length(pat) p = pat[i] - j = start(p) + next = iterate(p) ispattern = false - while !done(p, j) - c, j = next(p, j) + while next !== nothing + c, j = next + next = iterate(p, j) if extended & (c == '\\') - if done(p, j) + if next === nothing break end - c, j = next(p, j) + next = iterate(p, j) elseif (c == '*') | (c == '?') | (c == '[' && _match(p, j, '\0', false, extended)[2]) ispattern = true @@ -369,13 +409,13 @@ function _glob!(matches, pat) for m in matches if isempty(m) for d in readdir() - if ismatch(pat, d) + if occursin(pat, d) push!(m2, d) end end elseif isdir(m) for d in readdir(m) - if ismatch(pat, d) + if occursin(pat, d) push!(m2, joinpath(m, d)) end end diff --git a/test/runtests.jl b/test/runtests.jl index 050c505..9068258 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,6 @@ using Glob -using Base.Test +using Compat +using Compat.Test macro test_types(arr, types) return quote @@ -12,157 +13,157 @@ end # various unit tests, in no particular order -@test !ismatch(fn"abc*", "ABXABXAB") -@test ismatch(fn"AB*AB*AB", "ABXABXAB") -@test ismatch(fn"AB*AB*AB", "ABXABAB") -@test !ismatch(fn"AB*AB*AB", "AABAB") -@test ismatch(fn"AB*AB*AB", "ABABAB") -@test ismatch(fn"AB*AB*B", "ABABAB") -@test ismatch(fn"AB*AB*", "ABABAB") -@test ismatch(fn"AB*AB*??", "ABABAB") -@test !ismatch(fn"AB*AB*???", "ABABAB") -@test ismatch(fn"AB*AB*??***", "ABABAB") -@test ismatch(fn"AB*AB*??***", "ABABABC") -@test ismatch(fn"AB*AB*??***", "ABABABCDEFG") -@test ismatch(fn"?AB*AB*??***", ".ABABABCDEFG") -@test !ismatch(fn"?AB*AB*??***"p, ".ABABABCDEFG") +@test !occursin(fn"abc*", "ABXABXAB") +@test occursin(fn"AB*AB*AB", "ABXABXAB") +@test occursin(fn"AB*AB*AB", "ABXABAB") +@test !occursin(fn"AB*AB*AB", "AABAB") +@test occursin(fn"AB*AB*AB", "ABABAB") +@test occursin(fn"AB*AB*B", "ABABAB") +@test occursin(fn"AB*AB*", "ABABAB") +@test occursin(fn"AB*AB*??", "ABABAB") +@test !occursin(fn"AB*AB*???", "ABABAB") +@test occursin(fn"AB*AB*??***", "ABABAB") +@test occursin(fn"AB*AB*??***", "ABABABC") +@test occursin(fn"AB*AB*??***", "ABABABCDEFG") +@test occursin(fn"?AB*AB*??***", ".ABABABCDEFG") +@test !occursin(fn"?AB*AB*??***"p, ".ABABABCDEFG") @test_throws ErrorException Glob.FilenameMatch("?AB*AB*??***","z") -@test ismatch(fn"[abc]", "a") -@test !ismatch(fn"[abc]", "A") -@test ismatch(fn"[abc]"i, "A") -@test ismatch(fn"[abc]", "b") -@test ismatch(fn"[abc]", "c") -@test !ismatch(fn"[abc]", "x") -@test !ismatch(fn"[a-d]", "x") -@test ismatch(fn"[a-d]", "a") -@test ismatch(fn"[a-d]", "d") -@test !ismatch(fn"[a--]", "e") -@test ismatch(fn"[--e]", "e") -@test !ismatch(fn"[f-e]", "e") -@test !ismatch(fn"[g-e]", "e") -@test !ismatch(fn"[g-f]", "e") -@test ismatch(fn"[a-f]", "e") -@test ismatch(fn"[a-e]", "e") -@test ismatch(fn"[f-ee]", "e") -@test !ismatch(fn"[A-Z]", "e") -@test ismatch(fn"[A-z]", "e") -@test ismatch(fn"[\]", "\\") -@test_throws ErrorException ismatch(fn"[[:a:]]", "e") -@test_throws ErrorException !ismatch(fn"[\[:a:]]", "e") -@test !ismatch(fn"[\[:a:]]"x, "e") -@test_throws ErrorException ismatch(fn"[\\[:a:]]", "e") -@test ismatch(fn"[\[:a-e:]]"x, "e]") -@test ismatch(fn"[\[:a-e:]"x, "e") -@test !ismatch(fn"[\[:a-e:xxxx"x, "e") -@test ismatch(fn"[\[:a-e:xxxx-]"x, "e") -@test ismatch(fn"[a-]", "a") -@test ismatch(fn"[a-]", "-") -@test !ismatch(fn"[a-]", "b") -@test ismatch(fn"[!a-]", "b") -@test !ismatch(fn"[!a-]", "a") -@test ismatch(fn"[!a]", "!") -@test !ismatch(fn"[!!]", "!") -@test !ismatch(fn"[!a]", "a") -@test ismatch(fn"[!a]", "b") -@test !ismatch(fn"[][]", "") -@test ismatch(fn"[]", "[]") -@test ismatch(fn"[][]", "[") -@test ismatch(fn"[][]", "]") -@test !ismatch(fn"[][]", "x") -@test !ismatch(fn"[]-[]", "x") -@test !ismatch(fn"[]-[]", "-") -@test !ismatch(fn"[]-[]", "\\") -@test ismatch(fn"[\[-\]]*"x, "][") -@test ismatch(fn"[\]]*"x, "][") -@test ismatch(fn"[\[-\]]*"x, "][") -@test ismatch(fn"[[-\]]*"x, "][") -@test ismatch(fn"base/[\[-\]]*"dpx,"base/][x") -@test ismatch(fn"[\[-\]]"x, "\\") -@test ismatch(fn"[[-\]]"x, "\\") -@test ismatch(fn"[---]", "-") -@test !ismatch(fn"[!---]", "-") -@test ismatch(fn"[!---]", "0") -@test !ismatch(fn"[---a-zA-Z]", "0") -@test !ismatch(fn"[---a-zA-Z:]", "0") -@test !ismatch(fn"[---!]", "0") -@test ismatch(fn"[---!]", "!") -@test !ismatch(fn"[---!]", "a") -@test !ismatch(fn"[---!]", "\0") -@test ismatch(fn"ab/c/d"dp, "ab/c/d") -@test !ismatch(fn"ab/c/d"dp, "ab/c?d") -@test !ismatch(fn"ab/./d"dp, "ab/?/d") -@test !ismatch(fn"ab*d"dp, "aba/d") -@test !ismatch(fn"ab*d"dp, "ab/d") -@test ismatch(fn"ab*d", "ab/d") -@test ismatch(fn"ab*d", "aba/d") -@test ismatch(fn"[a-z]"i, "B") -@test !ismatch(fn"[a-z]"i, "_") -@test ismatch(fn"[A-z]"i, "_") -@test !ismatch(fn"[a-Z]"i, "_") -@test !ismatch(fn"#[a-Z]%"i, "#a%") -@test ismatch(fn"#[α-ω]%"i, "#Γ%") -@test !ismatch(fn"#[α-ω]%", "#Γ%") -@test ismatch(fn"#[α-ω]%", "#γ%") -@test !ismatch(fn"a?b"d, "a/b") -@test ismatch(fn"a?b", "a/b") -@test !ismatch(fn"?b"p, ".b") -@test ismatch(fn"?b", ".b") -@test ismatch(fn"?/?b", "./.b") -@test !ismatch(fn"?/?b"p, "./.b") -@test ismatch(fn"./?b"p, "./.b") -@test !ismatch(fn"./?b"pd, "./.b") -@test ismatch(fn"./.b"pd, "./.b") -@test !ismatch(fn"?/.b"pd, "./.b") -@test ismatch(fn"""./.b"""pd, "./.b") -@test !ismatch(fn"""?/.b"""pd, "./.b") -@test ismatch(fn"_[[:blank:][.a.]-c]_", "_b_") -@test !ismatch(fn"_[[:blank:][.a.]-c]_", "_-_") -@test ismatch(fn"_[[:blank:][.a.]-c]_", "_ _") -@test ismatch(fn"_[[:alnum:]]_", "_a_") -@test !ismatch(fn"_[[:alnum:]]_", "_[_") -@test !ismatch(fn"_[[:alnum:]]_", "_]_") -@test !ismatch(fn"_[[:alnum:]]_", "_:_") -@test ismatch(fn"_[[:alpha:]]_", "_z_") -@test !ismatch(fn"_[[:alpha:]]_", "_[_") -@test ismatch(fn"_[[:cntrl:]]_", "_\0_") -@test ismatch(fn"_[[:cntrl:]]_", "_\b_") -@test !ismatch(fn"_[[:cntrl:]]_", "_:_") -@test !ismatch(fn"_[[:cntrl:]]_", "_ _") -@test ismatch(fn"_[[:digit:]]_", "_0_") -@test !ismatch(fn"_[[:digit:]]_", "_:_") -@test ismatch(fn"_[[:graph:]]_", "_._") -@test !ismatch(fn"_[[:graph:]]_", "_ _") -@test ismatch(fn"_[[:lower:]]_", "_a_") -@test ismatch(fn"_[[:lower:]]_"i, "_A_") -@test !ismatch(fn"_[[:lower:]]_", "_A_") -@test !ismatch(fn"_[[:lower:]]_", "_:_") -@test ismatch(fn"_[[:print:]]_", "_a_") -@test !ismatch(fn"_[[:print:]]_", "_\7_") -@test ismatch(fn"_[[:punct:]]_", "_:_") -@test !ismatch(fn"_[[:punct:]]_", "_p_") -@test ismatch(fn"_[[:space:]]_", "_\f_") -@test !ismatch(fn"_[[:space:]]_", "_:_") -@test !ismatch(fn"_[[:space:]]_", "_\r\n_") -@test ismatch(fn"_[[:upper:]]_", "_A_") -@test ismatch(fn"_[[:upper:]]_"i, "_a_") -@test !ismatch(fn"_[[:upper:]]_", "_a_") -@test !ismatch(fn"_[[:upper:]]_", "_:_") -@test ismatch(fn"_[[:xdigit:]]_", "_a_") -@test !ismatch(fn"_[[:xdigit:]]_", "_:_") -@test ismatch(fn"_[[.a.]-[.z.]]_", "_c_") -@test !ismatch(fn"_[[.a.]-[.z.]]_", "_-_") -@test !ismatch(fn"_[[.a.]-[.z.]]_", "_]_") -@test !ismatch(fn"_[[.a.]-[.z.]]_", "_[_") -@test ismatch(fn"_[[=a=]]_", "_a_") -@test !ismatch(fn"_[[=a=]]_", "_=_") -@test !ismatch(fn"_[[=a=]]_", "_á_") -@test ismatch(fn"[[=a=]-z]", "-") -@test_throws ErrorException ismatch(fn"[a-[=z=]]", "e") +@test occursin(fn"[abc]", "a") +@test !occursin(fn"[abc]", "A") +@test occursin(fn"[abc]"i, "A") +@test occursin(fn"[abc]", "b") +@test occursin(fn"[abc]", "c") +@test !occursin(fn"[abc]", "x") +@test !occursin(fn"[a-d]", "x") +@test occursin(fn"[a-d]", "a") +@test occursin(fn"[a-d]", "d") +@test !occursin(fn"[a--]", "e") +@test occursin(fn"[--e]", "e") +@test !occursin(fn"[f-e]", "e") +@test !occursin(fn"[g-e]", "e") +@test !occursin(fn"[g-f]", "e") +@test occursin(fn"[a-f]", "e") +@test occursin(fn"[a-e]", "e") +@test occursin(fn"[f-ee]", "e") +@test !occursin(fn"[A-Z]", "e") +@test occursin(fn"[A-z]", "e") +@test occursin(fn"[\]", "\\") +@test_throws ErrorException occursin(fn"[[:a:]]", "e") +@test_throws ErrorException !occursin(fn"[\[:a:]]", "e") +@test !occursin(fn"[\[:a:]]"x, "e") +@test_throws ErrorException occursin(fn"[\\[:a:]]", "e") +@test occursin(fn"[\[:a-e:]]"x, "e]") +@test occursin(fn"[\[:a-e:]"x, "e") +@test !occursin(fn"[\[:a-e:xxxx"x, "e") +@test occursin(fn"[\[:a-e:xxxx-]"x, "e") +@test occursin(fn"[a-]", "a") +@test occursin(fn"[a-]", "-") +@test !occursin(fn"[a-]", "b") +@test occursin(fn"[!a-]", "b") +@test !occursin(fn"[!a-]", "a") +@test occursin(fn"[!a]", "!") +@test !occursin(fn"[!!]", "!") +@test !occursin(fn"[!a]", "a") +@test occursin(fn"[!a]", "b") +@test !occursin(fn"[][]", "") +@test occursin(fn"[]", "[]") +@test occursin(fn"[][]", "[") +@test occursin(fn"[][]", "]") +@test !occursin(fn"[][]", "x") +@test !occursin(fn"[]-[]", "x") +@test !occursin(fn"[]-[]", "-") +@test !occursin(fn"[]-[]", "\\") +@test occursin(fn"[\[-\]]*"x, "][") +@test occursin(fn"[\]]*"x, "][") +@test occursin(fn"[\[-\]]*"x, "][") +@test occursin(fn"[[-\]]*"x, "][") +@test occursin(fn"base/[\[-\]]*"dpx,"base/][x") +@test occursin(fn"[\[-\]]"x, "\\") +@test occursin(fn"[[-\]]"x, "\\") +@test occursin(fn"[---]", "-") +@test !occursin(fn"[!---]", "-") +@test occursin(fn"[!---]", "0") +@test !occursin(fn"[---a-zA-Z]", "0") +@test !occursin(fn"[---a-zA-Z:]", "0") +@test !occursin(fn"[---!]", "0") +@test occursin(fn"[---!]", "!") +@test !occursin(fn"[---!]", "a") +@test !occursin(fn"[---!]", "\0") +@test occursin(fn"ab/c/d"dp, "ab/c/d") +@test !occursin(fn"ab/c/d"dp, "ab/c?d") +@test !occursin(fn"ab/./d"dp, "ab/?/d") +@test !occursin(fn"ab*d"dp, "aba/d") +@test !occursin(fn"ab*d"dp, "ab/d") +@test occursin(fn"ab*d", "ab/d") +@test occursin(fn"ab*d", "aba/d") +@test occursin(fn"[a-z]"i, "B") +@test !occursin(fn"[a-z]"i, "_") +@test occursin(fn"[A-z]"i, "_") +@test !occursin(fn"[a-Z]"i, "_") +@test !occursin(fn"#[a-Z]%"i, "#a%") +@test occursin(fn"#[α-ω]%"i, "#Γ%") +@test !occursin(fn"#[α-ω]%", "#Γ%") +@test occursin(fn"#[α-ω]%", "#γ%") +@test !occursin(fn"a?b"d, "a/b") +@test occursin(fn"a?b", "a/b") +@test !occursin(fn"?b"p, ".b") +@test occursin(fn"?b", ".b") +@test occursin(fn"?/?b", "./.b") +@test !occursin(fn"?/?b"p, "./.b") +@test occursin(fn"./?b"p, "./.b") +@test !occursin(fn"./?b"pd, "./.b") +@test occursin(fn"./.b"pd, "./.b") +@test !occursin(fn"?/.b"pd, "./.b") +@test occursin(fn"""./.b"""pd, "./.b") +@test !occursin(fn"""?/.b"""pd, "./.b") +@test occursin(fn"_[[:blank:][.a.]-c]_", "_b_") +@test !occursin(fn"_[[:blank:][.a.]-c]_", "_-_") +@test occursin(fn"_[[:blank:][.a.]-c]_", "_ _") +@test occursin(fn"_[[:alnum:]]_", "_a_") +@test !occursin(fn"_[[:alnum:]]_", "_[_") +@test !occursin(fn"_[[:alnum:]]_", "_]_") +@test !occursin(fn"_[[:alnum:]]_", "_:_") +@test occursin(fn"_[[:alpha:]]_", "_z_") +@test !occursin(fn"_[[:alpha:]]_", "_[_") +@test occursin(fn"_[[:cntrl:]]_", "_\0_") +@test occursin(fn"_[[:cntrl:]]_", "_\b_") +@test !occursin(fn"_[[:cntrl:]]_", "_:_") +@test !occursin(fn"_[[:cntrl:]]_", "_ _") +@test occursin(fn"_[[:digit:]]_", "_0_") +@test !occursin(fn"_[[:digit:]]_", "_:_") +@test occursin(fn"_[[:graph:]]_", "_._") +@test !occursin(fn"_[[:graph:]]_", "_ _") +@test occursin(fn"_[[:lower:]]_", "_a_") +@test occursin(fn"_[[:lower:]]_"i, "_A_") +@test !occursin(fn"_[[:lower:]]_", "_A_") +@test !occursin(fn"_[[:lower:]]_", "_:_") +@test occursin(fn"_[[:print:]]_", "_a_") +@test !occursin(fn"_[[:print:]]_", "_\7_") +@test occursin(fn"_[[:punct:]]_", "_:_") +@test !occursin(fn"_[[:punct:]]_", "_p_") +@test occursin(fn"_[[:space:]]_", "_\f_") +@test !occursin(fn"_[[:space:]]_", "_:_") +@test !occursin(fn"_[[:space:]]_", "_\r\n_") +@test occursin(fn"_[[:upper:]]_", "_A_") +@test occursin(fn"_[[:upper:]]_"i, "_a_") +@test !occursin(fn"_[[:upper:]]_", "_a_") +@test !occursin(fn"_[[:upper:]]_", "_:_") +@test occursin(fn"_[[:xdigit:]]_", "_a_") +@test !occursin(fn"_[[:xdigit:]]_", "_:_") +@test occursin(fn"_[[.a.]-[.z.]]_", "_c_") +@test !occursin(fn"_[[.a.]-[.z.]]_", "_-_") +@test !occursin(fn"_[[.a.]-[.z.]]_", "_]_") +@test !occursin(fn"_[[.a.]-[.z.]]_", "_[_") +@test occursin(fn"_[[=a=]]_", "_a_") +@test !occursin(fn"_[[=a=]]_", "_=_") +@test !occursin(fn"_[[=a=]]_", "_á_") +@test occursin(fn"[[=a=]-z]", "-") +@test_throws ErrorException occursin(fn"[a-[=z=]]", "e") -@test !ismatch(fn"\?", "\\?") -@test ismatch(fn"\?", "?") -@test ismatch(fn"\?"e, "\\!") -@test !ismatch(fn"\?"e, "?") +@test !occursin(fn"\?", "\\?") +@test occursin(fn"\?", "?") +@test occursin(fn"\?"e, "\\!") +@test !occursin(fn"\?"e, "?") @test_types glob"ab/?/d".pattern (AbstractString, Glob.FilenameMatch, AbstractString) @test_types glob"""ab/*/d""".pattern (AbstractString, Glob.FilenameMatch, AbstractString) @@ -181,7 +182,11 @@ end @test all([!startswith(x,'.') for x in Glob.glob("*.*")]) function test_string(x1) - x2 = string(eval(parse(x1))) + @static if VERSION < v"0.7.0-DEV.2437" + x2 = string(eval(parse(x1))) + else + x2 = string(eval(Meta.parse(x1))) + end x1 == x2 ? nothing : error(string( "string test failed:", "\noriginal: ", x1,