forked from mirror/glob
fix
This commit is contained in:
parent
5b4ed87b27
commit
e39827db7b
20
glob.go
20
glob.go
|
@ -2,8 +2,8 @@ package glob
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"errors"
|
||||
"github.com/gobwas/glob/match"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -96,7 +96,7 @@ func parse(str string, sep string, st state) ([]token, error) {
|
|||
case range_open:
|
||||
closed := indexByteNonEscaped(str, range_close, escape, 0)
|
||||
if closed == -1 {
|
||||
return nil, errors.New("invalid format")
|
||||
return nil, fmt.Errorf("'%s' should be closed with '%s'", string(range_open), string(range_close))
|
||||
}
|
||||
|
||||
r := str[i+1:closed]
|
||||
|
@ -135,6 +135,7 @@ func parseRange(def string) (match.Matcher, error) {
|
|||
not bool
|
||||
esc bool
|
||||
minus bool
|
||||
minusIndex int
|
||||
b []byte
|
||||
)
|
||||
|
||||
|
@ -152,26 +153,31 @@ func parseRange(def string) (match.Matcher, error) {
|
|||
}
|
||||
case escape:
|
||||
if i == len(def) - 1 {
|
||||
return nil, errors.New("escape character without follower")
|
||||
return nil, fmt.Errorf("there should be any character after '%s'", string(escape))
|
||||
}
|
||||
|
||||
esc = true
|
||||
case inside_range_minus:
|
||||
minus = true
|
||||
minusIndex = len(b)
|
||||
default:
|
||||
b = append(b, c)
|
||||
}
|
||||
}
|
||||
|
||||
if len(b) == 0 {
|
||||
return nil, fmt.Errorf("range could not be empty")
|
||||
}
|
||||
|
||||
def = string(b)
|
||||
|
||||
if minus {
|
||||
r := []rune(def)
|
||||
if len(r) != 3 || r[1] != inside_range_minus {
|
||||
return nil, errors.New("invalid range syntax")
|
||||
if len(r) != 2 || minusIndex != 1 {
|
||||
return nil, fmt.Errorf("invalid range syntax: '%s' should be between two characters", string(inside_range_minus))
|
||||
}
|
||||
|
||||
return &match.Between{r[0], r[2], not}, nil
|
||||
return &match.Between{r[0], r[1], not}, nil
|
||||
}
|
||||
|
||||
return &match.RangeList{def, not}, nil
|
||||
|
@ -185,4 +191,4 @@ type token struct {
|
|||
type state struct {
|
||||
escape bool
|
||||
tokens []token
|
||||
}
|
||||
}
|
144
glob_test.go
144
glob_test.go
|
@ -1,11 +1,26 @@
|
|||
package glob
|
||||
|
||||
import (
|
||||
rGlob "github.com/ryanuber/go-glob"
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
pattern_all = "[a-z][!a-x]*cat*[h][!b]*eyes*"
|
||||
fixture_all = "my cat has very bright eyes"
|
||||
|
||||
pattern_plain = "google.com"
|
||||
fixture_plain = "google.com"
|
||||
|
||||
pattern_multiple = "https://*.google.*"
|
||||
fixture_multiple = "https://account.google.com"
|
||||
|
||||
pattern_prefix = "abc*"
|
||||
pattern_suffix = "*def"
|
||||
pattern_prefix_suffix = "ab*ef"
|
||||
fixture_prefix_suffix = "abcdef"
|
||||
)
|
||||
|
||||
|
||||
type test struct {
|
||||
pattern, match string
|
||||
should bool
|
||||
|
@ -16,7 +31,7 @@ func glob(s bool, p, m string, d ...string) test {
|
|||
return test{p, m, s, d}
|
||||
}
|
||||
|
||||
func TestIndexOfNonEscaped(t *testing.T) {
|
||||
func TestIndexByteNonEscaped(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
s string
|
||||
n, e byte
|
||||
|
@ -46,6 +61,12 @@ func TestIndexOfNonEscaped(t *testing.T) {
|
|||
'\\',
|
||||
-1,
|
||||
},
|
||||
{
|
||||
"\\b",
|
||||
'b',
|
||||
'\\',
|
||||
-1,
|
||||
},
|
||||
} {
|
||||
i := indexByteNonEscaped(test.s, test.n, test.e, 0)
|
||||
if i != test.i {
|
||||
|
@ -88,10 +109,18 @@ func TestGlob(t *testing.T) {
|
|||
|
||||
glob(false, "*is", "this is a test"),
|
||||
glob(false, "*no*", "this is a test"),
|
||||
glob(true, "[!a]*", "this is a test"),
|
||||
|
||||
glob(true, pattern_all, fixture_all),
|
||||
glob(true, pattern_plain, fixture_plain),
|
||||
glob(true, pattern_multiple, fixture_multiple),
|
||||
glob(true, pattern_prefix, fixture_prefix_suffix),
|
||||
glob(true, pattern_suffix, fixture_prefix_suffix),
|
||||
glob(true, pattern_prefix_suffix, fixture_prefix_suffix),
|
||||
} {
|
||||
g, err := New(test.pattern, test.delimiters...)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("parsing pattern %q error: %s", test.pattern, err)
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -102,94 +131,53 @@ func TestGlob(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
const Pattern = "*cat*eyes*"
|
||||
const ExpPattern = ".*cat.*eyes.*"
|
||||
const String = "my cat has very bright eyes"
|
||||
|
||||
const ProfPattern = "* ?at * eyes"
|
||||
const ProfString = "my cat has very bright eyes"
|
||||
|
||||
//const Pattern = "*.google.com"
|
||||
//const ExpPattern = ".*google\\.com"
|
||||
//const String = "mail.google.com"
|
||||
const PlainPattern = "google.com"
|
||||
const PlainExpPattern = "google\\.com"
|
||||
const PlainString = "google.com"
|
||||
|
||||
const PSPattern = "https://*.google.com"
|
||||
const PSExpPattern = `https:\/\/[a-z]+\.google\\.com`
|
||||
const PSString = "https://account.google.com"
|
||||
|
||||
func BenchmarkProf(b *testing.B) {
|
||||
m, _ := New(Pattern)
|
||||
|
||||
func BenchmarkParse(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(String)
|
||||
New(pattern_all)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGobwas(b *testing.B) {
|
||||
m, _ := New(Pattern)
|
||||
func BenchmarkAll(b *testing.B) {
|
||||
m, _ := New(pattern_all)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(String)
|
||||
}
|
||||
}
|
||||
func BenchmarkGobwasPlain(b *testing.B) {
|
||||
m, _ := New(PlainPattern)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(PlainString)
|
||||
}
|
||||
}
|
||||
func BenchmarkGobwasPrefix(b *testing.B) {
|
||||
m, _ := New("abc*")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match("abcdef")
|
||||
}
|
||||
}
|
||||
func BenchmarkGobwasSuffix(b *testing.B) {
|
||||
m, _ := New("*def")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match("abcdef")
|
||||
}
|
||||
}
|
||||
func BenchmarkGobwasPrefixSuffix(b *testing.B) {
|
||||
m, _ := New("ab*ef")
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match("abcdef")
|
||||
_ = m.Match(fixture_all)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRyanuber(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = rGlob.Glob(Pattern, String)
|
||||
}
|
||||
}
|
||||
func BenchmarkRyanuberPlain(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = rGlob.Glob(PlainPattern, PlainString)
|
||||
}
|
||||
}
|
||||
func BenchmarkRyanuberPrefixSuffix(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = rGlob.Glob(PSPattern, PSString)
|
||||
}
|
||||
}
|
||||
func BenchmarkMultiple(b *testing.B) {
|
||||
m, _ := New(pattern_multiple)
|
||||
|
||||
|
||||
func BenchmarkRegExp(b *testing.B) {
|
||||
r := regexp.MustCompile(ExpPattern)
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = r.Match([]byte(String))
|
||||
_ = m.Match(fixture_multiple)
|
||||
}
|
||||
}
|
||||
func BenchmarkRegExpPrefixSuffix(b *testing.B) {
|
||||
r := regexp.MustCompile(PSExpPattern)
|
||||
func BenchmarkPlain(b *testing.B) {
|
||||
m, _ := New(pattern_plain)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = r.Match([]byte(PSString))
|
||||
_ = m.Match(fixture_plain)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefix(b *testing.B) {
|
||||
m, _ := New(pattern_prefix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix)
|
||||
}
|
||||
}
|
||||
func BenchmarkSuffix(b *testing.B) {
|
||||
m, _ := New(pattern_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix)
|
||||
}
|
||||
}
|
||||
func BenchmarkPrefixSuffix(b *testing.B) {
|
||||
m, _ := New(pattern_prefix_suffix)
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_ = m.Match(fixture_prefix_suffix)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue