mirror of https://github.com/tidwall/tile38.git
support for parsing globs
This commit is contained in:
parent
388409072c
commit
4fd7e1f821
|
@ -0,0 +1,91 @@
|
||||||
|
package glob
|
||||||
|
|
||||||
|
import "path"
|
||||||
|
|
||||||
|
type Glob struct {
|
||||||
|
Pattern string
|
||||||
|
Desc bool
|
||||||
|
Limits []string
|
||||||
|
IsGlob bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func Match(pattern, name string) (matched bool, err error) {
|
||||||
|
return path.Match(pattern, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsGlob(pattern string) bool {
|
||||||
|
for i := 0; i < len(pattern); i++ {
|
||||||
|
switch pattern[i] {
|
||||||
|
case '[', '*', '?':
|
||||||
|
_, err := Match(pattern, "whatever")
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func Parse(pattern string, desc bool) *Glob {
|
||||||
|
g := &Glob{Pattern: pattern, Desc: desc, Limits: []string{"", ""}}
|
||||||
|
if pattern == "*" {
|
||||||
|
g.IsGlob = true
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
if pattern == "" {
|
||||||
|
g.IsGlob = false
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
n := 0
|
||||||
|
isGlob := false
|
||||||
|
outer:
|
||||||
|
for i := 0; i < len(pattern); i++ {
|
||||||
|
switch pattern[i] {
|
||||||
|
case '[', '*', '?':
|
||||||
|
_, err := Match(pattern, "whatever")
|
||||||
|
if err == nil {
|
||||||
|
isGlob = true
|
||||||
|
}
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
g.Limits = []string{pattern, pattern}
|
||||||
|
g.IsGlob = false
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
var a, b string
|
||||||
|
if desc {
|
||||||
|
a = pattern[:n]
|
||||||
|
b = a
|
||||||
|
if b[n-1] == 0x00 {
|
||||||
|
for len(b) > 0 && b[len(b)-1] == 0x00 {
|
||||||
|
if len(b) > 1 {
|
||||||
|
if b[len(b)-2] == 0x00 {
|
||||||
|
b = b[:len(b)-1]
|
||||||
|
} else {
|
||||||
|
b = string(append([]byte(b[:len(b)-2]), b[len(b)-2]-1, 0xFF))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b = string(append([]byte(b[:n-1]), b[n-1]-1))
|
||||||
|
}
|
||||||
|
if a[n-1] == 0xFF {
|
||||||
|
a = string(append([]byte(a), 0x00))
|
||||||
|
} else {
|
||||||
|
a = string(append([]byte(a[:n-1]), a[n-1]+1))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a = pattern[:n]
|
||||||
|
if a[n-1] == 0xFF {
|
||||||
|
b = string(append([]byte(a), 0x00))
|
||||||
|
} else {
|
||||||
|
b = string(append([]byte(a[:n-1]), a[n-1]+1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.Limits = []string{a, b}
|
||||||
|
g.IsGlob = isGlob
|
||||||
|
return g
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package glob
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGlob(t *testing.T) {
|
||||||
|
test := func(pattern string, desc bool, limitsExpect []string, isGlobExpect bool) {
|
||||||
|
g := Parse(pattern, desc)
|
||||||
|
if g.IsGlob != isGlobExpect {
|
||||||
|
t.Fatalf("pattern[%v] desc[%v] (isGlob=%v, expected=%v)", pattern, desc, g.IsGlob, isGlobExpect)
|
||||||
|
}
|
||||||
|
if g.Limits[0] != limitsExpect[0] || g.Limits[1] != limitsExpect[1] {
|
||||||
|
t.Fatalf("pattern[%v] desc[%v] (limits=%v, expected=%v)", pattern, desc, g.Limits, limitsExpect)
|
||||||
|
}
|
||||||
|
if g.Pattern != pattern {
|
||||||
|
t.Fatalf("pattern[%v] desc[%v] (pattern=%v, expected=%v)", pattern, desc, g.Pattern, pattern)
|
||||||
|
}
|
||||||
|
if g.Desc != desc {
|
||||||
|
t.Fatalf("pattern[%v] desc[%v] (desc=%v, expected=%v)", pattern, desc, g.Desc, desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test("*", false, []string{"", ""}, true)
|
||||||
|
test("", false, []string{"", ""}, false)
|
||||||
|
test("hello*", false, []string{"hello", "hellp"}, true)
|
||||||
|
test("hello", false, []string{"hello", "hellp"}, false)
|
||||||
|
test("\xff*", false, []string{"\xff", "\xff\x00"}, true)
|
||||||
|
test("\x00*", false, []string{"\x00", "\x01"}, true)
|
||||||
|
test("\xff", false, []string{"\xff", "\xff\x00"}, false)
|
||||||
|
|
||||||
|
test("*", true, []string{"", ""}, true)
|
||||||
|
test("", true, []string{"", ""}, false)
|
||||||
|
test("hello*", true, []string{"hellp", "helln"}, true)
|
||||||
|
test("hello", true, []string{"hellp", "helln"}, false)
|
||||||
|
test("a\xff*", true, []string{"a\xff\x00", "a\xfe"}, true)
|
||||||
|
test("\x00*", true, []string{"\x01", ""}, true)
|
||||||
|
test("\x01*", true, []string{"\x02", "\x00"}, true)
|
||||||
|
test("b\x00*", true, []string{"b\x01", "a\xff"}, true)
|
||||||
|
test("\x00\x00*", true, []string{"\x00\x01", ""}, true)
|
||||||
|
test("\x00\x01\x00*", true, []string{"\x00\x01\x01", "\x00\x00\xff"}, true)
|
||||||
|
}
|
Loading…
Reference in New Issue