Skip to content

Commit

Permalink
Fix 0.7 depwarns (#15)
Browse files Browse the repository at this point in the history
* Rename ismatch to occursin
* Update iterator protocol to iterate
  • Loading branch information
jmkuhn authored and vtjnash committed Jun 20, 2018
1 parent 8ca3670 commit 52e0ed0
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 210 deletions.
4 changes: 2 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: julia
julia:
#- nightly
- nightly
- 0.6
os:
- linux
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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 `[]`)
Expand Down
1 change: 1 addition & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
julia 0.6
Compat 0.68.0
148 changes: 94 additions & 54 deletions src/Glob.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 == '/')
Expand All @@ -90,16 +102,19 @@ 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
end
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
Expand All @@ -108,65 +123,82 @@ 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"
iscntrl(cl)
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"
ispunct(cl)
elseif phrase == "space"
isspace(cl)
elseif phrase == "upper"
isupper(cl) | isupper(cu)
isuppercase(cl) | isuppercase(cu)
elseif phrase == "xdigit"
isxdigit(cl)
else
Expand All @@ -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
Expand All @@ -200,19 +232,22 @@ 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
i = j
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
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 52e0ed0

Please sign in to comment.