aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/gobwas/glob/match
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-07-04 11:12:55 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-07-04 15:05:30 +0200
commitc7d7f10bdff703e4a3c0414e8a33d4e45c91eb35 (patch)
tree0dff0ee1f98dbfa3ad8776112053a450d176592b /vendor/github.com/gobwas/glob/match
parent9573094ce235bd9afe88f5da27a47dd6bcc1e13b (diff)
go.mod: vendor golangci-lint
Diffstat (limited to 'vendor/github.com/gobwas/glob/match')
-rw-r--r--vendor/github.com/gobwas/glob/match/any.go45
-rw-r--r--vendor/github.com/gobwas/glob/match/any_of.go82
-rw-r--r--vendor/github.com/gobwas/glob/match/btree.go146
-rw-r--r--vendor/github.com/gobwas/glob/match/contains.go58
-rw-r--r--vendor/github.com/gobwas/glob/match/every_of.go99
-rw-r--r--vendor/github.com/gobwas/glob/match/list.go49
-rw-r--r--vendor/github.com/gobwas/glob/match/match.go81
-rw-r--r--vendor/github.com/gobwas/glob/match/max.go49
-rw-r--r--vendor/github.com/gobwas/glob/match/min.go57
-rw-r--r--vendor/github.com/gobwas/glob/match/nothing.go27
-rw-r--r--vendor/github.com/gobwas/glob/match/prefix.go50
-rw-r--r--vendor/github.com/gobwas/glob/match/prefix_any.go55
-rw-r--r--vendor/github.com/gobwas/glob/match/prefix_suffix.go62
-rw-r--r--vendor/github.com/gobwas/glob/match/range.go48
-rw-r--r--vendor/github.com/gobwas/glob/match/row.go77
-rw-r--r--vendor/github.com/gobwas/glob/match/segments.go91
-rw-r--r--vendor/github.com/gobwas/glob/match/single.go43
-rw-r--r--vendor/github.com/gobwas/glob/match/suffix.go35
-rw-r--r--vendor/github.com/gobwas/glob/match/suffix_any.go43
-rw-r--r--vendor/github.com/gobwas/glob/match/super.go33
-rw-r--r--vendor/github.com/gobwas/glob/match/text.go45
21 files changed, 1275 insertions, 0 deletions
diff --git a/vendor/github.com/gobwas/glob/match/any.go b/vendor/github.com/gobwas/glob/match/any.go
new file mode 100644
index 000000000..514a9a5c4
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/any.go
@@ -0,0 +1,45 @@
+package match
+
+import (
+ "fmt"
+ "github.com/gobwas/glob/util/strings"
+)
+
+type Any struct {
+ Separators []rune
+}
+
+func NewAny(s []rune) Any {
+ return Any{s}
+}
+
+func (self Any) Match(s string) bool {
+ return strings.IndexAnyRunes(s, self.Separators) == -1
+}
+
+func (self Any) Index(s string) (int, []int) {
+ found := strings.IndexAnyRunes(s, self.Separators)
+ switch found {
+ case -1:
+ case 0:
+ return 0, segments0
+ default:
+ s = s[:found]
+ }
+
+ segments := acquireSegments(len(s))
+ for i := range s {
+ segments = append(segments, i)
+ }
+ segments = append(segments, len(s))
+
+ return 0, segments
+}
+
+func (self Any) Len() int {
+ return lenNo
+}
+
+func (self Any) String() string {
+ return fmt.Sprintf("<any:![%s]>", string(self.Separators))
+}
diff --git a/vendor/github.com/gobwas/glob/match/any_of.go b/vendor/github.com/gobwas/glob/match/any_of.go
new file mode 100644
index 000000000..8e65356cd
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/any_of.go
@@ -0,0 +1,82 @@
+package match
+
+import "fmt"
+
+type AnyOf struct {
+ Matchers Matchers
+}
+
+func NewAnyOf(m ...Matcher) AnyOf {
+ return AnyOf{Matchers(m)}
+}
+
+func (self *AnyOf) Add(m Matcher) error {
+ self.Matchers = append(self.Matchers, m)
+ return nil
+}
+
+func (self AnyOf) Match(s string) bool {
+ for _, m := range self.Matchers {
+ if m.Match(s) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (self AnyOf) Index(s string) (int, []int) {
+ index := -1
+
+ segments := acquireSegments(len(s))
+ for _, m := range self.Matchers {
+ idx, seg := m.Index(s)
+ if idx == -1 {
+ continue
+ }
+
+ if index == -1 || idx < index {
+ index = idx
+ segments = append(segments[:0], seg...)
+ continue
+ }
+
+ if idx > index {
+ continue
+ }
+
+ // here idx == index
+ segments = appendMerge(segments, seg)
+ }
+
+ if index == -1 {
+ releaseSegments(segments)
+ return -1, nil
+ }
+
+ return index, segments
+}
+
+func (self AnyOf) Len() (l int) {
+ l = -1
+ for _, m := range self.Matchers {
+ ml := m.Len()
+ switch {
+ case l == -1:
+ l = ml
+ continue
+
+ case ml == -1:
+ return -1
+
+ case l != ml:
+ return -1
+ }
+ }
+
+ return
+}
+
+func (self AnyOf) String() string {
+ return fmt.Sprintf("<any_of:[%s]>", self.Matchers)
+}
diff --git a/vendor/github.com/gobwas/glob/match/btree.go b/vendor/github.com/gobwas/glob/match/btree.go
new file mode 100644
index 000000000..a8130e93e
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/btree.go
@@ -0,0 +1,146 @@
+package match
+
+import (
+ "fmt"
+ "unicode/utf8"
+)
+
+type BTree struct {
+ Value Matcher
+ Left Matcher
+ Right Matcher
+ ValueLengthRunes int
+ LeftLengthRunes int
+ RightLengthRunes int
+ LengthRunes int
+}
+
+func NewBTree(Value, Left, Right Matcher) (tree BTree) {
+ tree.Value = Value
+ tree.Left = Left
+ tree.Right = Right
+
+ lenOk := true
+ if tree.ValueLengthRunes = Value.Len(); tree.ValueLengthRunes == -1 {
+ lenOk = false
+ }
+
+ if Left != nil {
+ if tree.LeftLengthRunes = Left.Len(); tree.LeftLengthRunes == -1 {
+ lenOk = false
+ }
+ }
+
+ if Right != nil {
+ if tree.RightLengthRunes = Right.Len(); tree.RightLengthRunes == -1 {
+ lenOk = false
+ }
+ }
+
+ if lenOk {
+ tree.LengthRunes = tree.LeftLengthRunes + tree.ValueLengthRunes + tree.RightLengthRunes
+ } else {
+ tree.LengthRunes = -1
+ }
+
+ return tree
+}
+
+func (self BTree) Len() int {
+ return self.LengthRunes
+}
+
+// todo?
+func (self BTree) Index(s string) (int, []int) {
+ return -1, nil
+}
+
+func (self BTree) Match(s string) bool {
+ inputLen := len(s)
+
+ // self.Length, self.RLen and self.LLen are values meaning the length of runes for each part
+ // here we manipulating byte length for better optimizations
+ // but these checks still works, cause minLen of 1-rune string is 1 byte.
+ if self.LengthRunes != -1 && self.LengthRunes > inputLen {
+ return false
+ }
+
+ // try to cut unnecessary parts
+ // by knowledge of length of right and left part
+ var offset, limit int
+ if self.LeftLengthRunes >= 0 {
+ offset = self.LeftLengthRunes
+ }
+ if self.RightLengthRunes >= 0 {
+ limit = inputLen - self.RightLengthRunes
+ } else {
+ limit = inputLen
+ }
+
+ for offset < limit {
+ // search for matching part in substring
+ index, segments := self.Value.Index(s[offset:limit])
+ if index == -1 {
+ releaseSegments(segments)
+ return false
+ }
+
+ l := s[:offset+index]
+ var left bool
+ if self.Left != nil {
+ left = self.Left.Match(l)
+ } else {
+ left = l == ""
+ }
+
+ if left {
+ for i := len(segments) - 1; i >= 0; i-- {
+ length := segments[i]
+
+ var right bool
+ var r string
+ // if there is no string for the right branch
+ if inputLen <= offset+index+length {
+ r = ""
+ } else {
+ r = s[offset+index+length:]
+ }
+
+ if self.Right != nil {
+ right = self.Right.Match(r)
+ } else {
+ right = r == ""
+ }
+
+ if right {
+ releaseSegments(segments)
+ return true
+ }
+ }
+ }
+
+ _, step := utf8.DecodeRuneInString(s[offset+index:])
+ offset += index + step
+
+ releaseSegments(segments)
+ }
+
+ return false
+}
+
+func (self BTree) String() string {
+ const n string = "<nil>"
+ var l, r string
+ if self.Left == nil {
+ l = n
+ } else {
+ l = self.Left.String()
+ }
+ if self.Right == nil {
+ r = n
+ } else {
+ r = self.Right.String()
+ }
+
+ return fmt.Sprintf("<btree:[%s<-%s->%s]>", l, self.Value, r)
+}
diff --git a/vendor/github.com/gobwas/glob/match/contains.go b/vendor/github.com/gobwas/glob/match/contains.go
new file mode 100644
index 000000000..0998e95b0
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/contains.go
@@ -0,0 +1,58 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+)
+
+type Contains struct {
+ Needle string
+ Not bool
+}
+
+func NewContains(needle string, not bool) Contains {
+ return Contains{needle, not}
+}
+
+func (self Contains) Match(s string) bool {
+ return strings.Contains(s, self.Needle) != self.Not
+}
+
+func (self Contains) Index(s string) (int, []int) {
+ var offset int
+
+ idx := strings.Index(s, self.Needle)
+
+ if !self.Not {
+ if idx == -1 {
+ return -1, nil
+ }
+
+ offset = idx + len(self.Needle)
+ if len(s) <= offset {
+ return 0, []int{offset}
+ }
+ s = s[offset:]
+ } else if idx != -1 {
+ s = s[:idx]
+ }
+
+ segments := acquireSegments(len(s) + 1)
+ for i := range s {
+ segments = append(segments, offset+i)
+ }
+
+ return 0, append(segments, offset+len(s))
+}
+
+func (self Contains) Len() int {
+ return lenNo
+}
+
+func (self Contains) String() string {
+ var not string
+ if self.Not {
+ not = "!"
+ }
+ return fmt.Sprintf("<contains:%s[%s]>", not, self.Needle)
+}
diff --git a/vendor/github.com/gobwas/glob/match/every_of.go b/vendor/github.com/gobwas/glob/match/every_of.go
new file mode 100644
index 000000000..7c968ee36
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/every_of.go
@@ -0,0 +1,99 @@
+package match
+
+import (
+ "fmt"
+)
+
+type EveryOf struct {
+ Matchers Matchers
+}
+
+func NewEveryOf(m ...Matcher) EveryOf {
+ return EveryOf{Matchers(m)}
+}
+
+func (self *EveryOf) Add(m Matcher) error {
+ self.Matchers = append(self.Matchers, m)
+ return nil
+}
+
+func (self EveryOf) Len() (l int) {
+ for _, m := range self.Matchers {
+ if ml := m.Len(); l > 0 {
+ l += ml
+ } else {
+ return -1
+ }
+ }
+
+ return
+}
+
+func (self EveryOf) Index(s string) (int, []int) {
+ var index int
+ var offset int
+
+ // make `in` with cap as len(s),
+ // cause it is the maximum size of output segments values
+ next := acquireSegments(len(s))
+ current := acquireSegments(len(s))
+
+ sub := s
+ for i, m := range self.Matchers {
+ idx, seg := m.Index(sub)
+ if idx == -1 {
+ releaseSegments(next)
+ releaseSegments(current)
+ return -1, nil
+ }
+
+ if i == 0 {
+ // we use copy here instead of `current = seg`
+ // cause seg is a slice from reusable buffer `in`
+ // and it could be overwritten in next iteration
+ current = append(current, seg...)
+ } else {
+ // clear the next
+ next = next[:0]
+
+ delta := index - (idx + offset)
+ for _, ex := range current {
+ for _, n := range seg {
+ if ex+delta == n {
+ next = append(next, n)
+ }
+ }
+ }
+
+ if len(next) == 0 {
+ releaseSegments(next)
+ releaseSegments(current)
+ return -1, nil
+ }
+
+ current = append(current[:0], next...)
+ }
+
+ index = idx + offset
+ sub = s[index:]
+ offset += idx
+ }
+
+ releaseSegments(next)
+
+ return index, current
+}
+
+func (self EveryOf) Match(s string) bool {
+ for _, m := range self.Matchers {
+ if !m.Match(s) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (self EveryOf) String() string {
+ return fmt.Sprintf("<every_of:[%s]>", self.Matchers)
+}
diff --git a/vendor/github.com/gobwas/glob/match/list.go b/vendor/github.com/gobwas/glob/match/list.go
new file mode 100644
index 000000000..7fd763ecd
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/list.go
@@ -0,0 +1,49 @@
+package match
+
+import (
+ "fmt"
+ "github.com/gobwas/glob/util/runes"
+ "unicode/utf8"
+)
+
+type List struct {
+ List []rune
+ Not bool
+}
+
+func NewList(list []rune, not bool) List {
+ return List{list, not}
+}
+
+func (self List) Match(s string) bool {
+ r, w := utf8.DecodeRuneInString(s)
+ if len(s) > w {
+ return false
+ }
+
+ inList := runes.IndexRune(self.List, r) != -1
+ return inList == !self.Not
+}
+
+func (self List) Len() int {
+ return lenOne
+}
+
+func (self List) Index(s string) (int, []int) {
+ for i, r := range s {
+ if self.Not == (runes.IndexRune(self.List, r) == -1) {
+ return i, segmentsByRuneLength[utf8.RuneLen(r)]
+ }
+ }
+
+ return -1, nil
+}
+
+func (self List) String() string {
+ var not string
+ if self.Not {
+ not = "!"
+ }
+
+ return fmt.Sprintf("<list:%s[%s]>", not, string(self.List))
+}
diff --git a/vendor/github.com/gobwas/glob/match/match.go b/vendor/github.com/gobwas/glob/match/match.go
new file mode 100644
index 000000000..f80e007fb
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/match.go
@@ -0,0 +1,81 @@
+package match
+
+// todo common table of rune's length
+
+import (
+ "fmt"
+ "strings"
+)
+
+const lenOne = 1
+const lenZero = 0
+const lenNo = -1
+
+type Matcher interface {
+ Match(string) bool
+ Index(string) (int, []int)
+ Len() int
+ String() string
+}
+
+type Matchers []Matcher
+
+func (m Matchers) String() string {
+ var s []string
+ for _, matcher := range m {
+ s = append(s, fmt.Sprint(matcher))
+ }
+
+ return fmt.Sprintf("%s", strings.Join(s, ","))
+}
+
+// appendMerge merges and sorts given already SORTED and UNIQUE segments.
+func appendMerge(target, sub []int) []int {
+ lt, ls := len(target), len(sub)
+ out := make([]int, 0, lt+ls)
+
+ for x, y := 0, 0; x < lt || y < ls; {
+ if x >= lt {
+ out = append(out, sub[y:]...)
+ break
+ }
+
+ if y >= ls {
+ out = append(out, target[x:]...)
+ break
+ }
+
+ xValue := target[x]
+ yValue := sub[y]
+
+ switch {
+
+ case xValue == yValue:
+ out = append(out, xValue)
+ x++
+ y++
+
+ case xValue < yValue:
+ out = append(out, xValue)
+ x++
+
+ case yValue < xValue:
+ out = append(out, yValue)
+ y++
+
+ }
+ }
+
+ target = append(target[:0], out...)
+
+ return target
+}
+
+func reverseSegments(input []int) {
+ l := len(input)
+ m := l / 2
+
+ for i := 0; i < m; i++ {
+ input[i], input[l-i-1] = input[l-i-1], input[i]
+ }
+}
diff --git a/vendor/github.com/gobwas/glob/match/max.go b/vendor/github.com/gobwas/glob/match/max.go
new file mode 100644
index 000000000..d72f69eff
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/max.go
@@ -0,0 +1,49 @@
+package match
+
+import (
+ "fmt"
+ "unicode/utf8"
+)
+
+type Max struct {
+ Limit int
+}
+
+func NewMax(l int) Max {
+ return Max{l}
+}
+
+func (self Max) Match(s string) bool {
+ var l int
+ for range s {
+ l += 1
+ if l > self.Limit {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (self Max) Index(s string) (int, []int) {
+ segments := acquireSegments(self.Limit + 1)
+ segments = append(segments, 0)
+ var count int
+ for i, r := range s {
+ count++
+ if count > self.Limit {
+ break
+ }
+ segments = append(segments, i+utf8.RuneLen(r))
+ }
+
+ return 0, segments
+}
+
+func (self Max) Len() int {
+ return lenNo
+}
+
+func (self Max) String() string {
+ return fmt.Sprintf("<max:%d>", self.Limit)
+}
diff --git a/vendor/github.com/gobwas/glob/match/min.go b/vendor/github.com/gobwas/glob/match/min.go
new file mode 100644
index 000000000..db57ac8eb
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/min.go
@@ -0,0 +1,57 @@
+package match
+
+import (
+ "fmt"
+ "unicode/utf8"
+)
+
+type Min struct {
+ Limit int
+}
+
+func NewMin(l int) Min {
+ return Min{l}
+}
+
+func (self Min) Match(s string) bool {
+ var l int
+ for range s {
+ l += 1
+ if l >= self.Limit {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (self Min) Index(s string) (int, []int) {
+ var count int
+
+ c := len(s) - self.Limit + 1
+ if c <= 0 {
+ return -1, nil
+ }
+
+ segments := acquireSegments(c)
+ for i, r := range s {
+ count++
+ if count >= self.Limit {
+ segments = append(segments, i+utf8.RuneLen(r))
+ }
+ }
+
+ if len(segments) == 0 {
+ return -1, nil
+ }
+
+ return 0, segments
+}
+
+func (self Min) Len() int {
+ return lenNo
+}
+
+func (self Min) String() string {
+ return fmt.Sprintf("<min:%d>", self.Limit)
+}
diff --git a/vendor/github.com/gobwas/glob/match/nothing.go b/vendor/github.com/gobwas/glob/match/nothing.go
new file mode 100644
index 000000000..0d4ecd36b
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/nothing.go
@@ -0,0 +1,27 @@
+package match
+
+import (
+ "fmt"
+)
+
+type Nothing struct{}
+
+func NewNothing() Nothing {
+ return Nothing{}
+}
+
+func (self Nothing) Match(s string) bool {
+ return len(s) == 0
+}
+
+func (self Nothing) Index(s string) (int, []int) {
+ return 0, segments0
+}
+
+func (self Nothing) Len() int {
+ return lenZero
+}
+
+func (self Nothing) String() string {
+ return fmt.Sprintf("<nothing>")
+}
diff --git a/vendor/github.com/gobwas/glob/match/prefix.go b/vendor/github.com/gobwas/glob/match/prefix.go
new file mode 100644
index 000000000..a7347250e
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/prefix.go
@@ -0,0 +1,50 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+ "unicode/utf8"
+)
+
+type Prefix struct {
+ Prefix string
+}
+
+func NewPrefix(p string) Prefix {
+ return Prefix{p}
+}
+
+func (self Prefix) Index(s string) (int, []int) {
+ idx := strings.Index(s, self.Prefix)
+ if idx == -1 {
+ return -1, nil
+ }
+
+ length := len(self.Prefix)
+ var sub string
+ if len(s) > idx+length {
+ sub = s[idx+length:]
+ } else {
+ sub = ""
+ }
+
+ segments := acquireSegments(len(sub) + 1)
+ segments = append(segments, length)
+ for i, r := range sub {
+ segments = append(segments, length+i+utf8.RuneLen(r))
+ }
+
+ return idx, segments
+}
+
+func (self Prefix) Len() int {
+ return lenNo
+}
+
+func (self Prefix) Match(s string) bool {
+ return strings.HasPrefix(s, self.Prefix)
+}
+
+func (self Prefix) String() string {
+ return fmt.Sprintf("<prefix:%s>", self.Prefix)
+}
diff --git a/vendor/github.com/gobwas/glob/match/prefix_any.go b/vendor/github.com/gobwas/glob/match/prefix_any.go
new file mode 100644
index 000000000..8ee58fe1b
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/prefix_any.go
@@ -0,0 +1,55 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+ "unicode/utf8"
+
+ sutil "github.com/gobwas/glob/util/strings"
+)
+
+type PrefixAny struct {
+ Prefix string
+ Separators []rune
+}
+
+func NewPrefixAny(s string, sep []rune) PrefixAny {
+ return PrefixAny{s, sep}
+}
+
+func (self PrefixAny) Index(s string) (int, []int) {
+ idx := strings.Index(s, self.Prefix)
+ if idx == -1 {
+ return -1, nil
+ }
+
+ n := len(self.Prefix)
+ sub := s[idx+n:]
+ i := sutil.IndexAnyRunes(sub, self.Separators)
+ if i > -1 {
+ sub = sub[:i]
+ }
+
+ seg := acquireSegments(len(sub) + 1)
+ seg = append(seg, n)
+ for i, r := range sub {
+ seg = append(seg, n+i+utf8.RuneLen(r))
+ }
+
+ return idx, seg
+}
+
+func (self PrefixAny) Len() int {
+ return lenNo
+}
+
+func (self PrefixAny) Match(s string) bool {
+ if !strings.HasPrefix(s, self.Prefix) {
+ return false
+ }
+ return sutil.IndexAnyRunes(s[len(self.Prefix):], self.Separators) == -1
+}
+
+func (self PrefixAny) String() string {
+ return fmt.Sprintf("<prefix_any:%s![%s]>", self.Prefix, string(self.Separators))
+}
diff --git a/vendor/github.com/gobwas/glob/match/prefix_suffix.go b/vendor/github.com/gobwas/glob/match/prefix_suffix.go
new file mode 100644
index 000000000..8208085a1
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/prefix_suffix.go
@@ -0,0 +1,62 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+)
+
+type PrefixSuffix struct {
+ Prefix, Suffix string
+}
+
+func NewPrefixSuffix(p, s string) PrefixSuffix {
+ return PrefixSuffix{p, s}
+}
+
+func (self PrefixSuffix) Index(s string) (int, []int) {
+ prefixIdx := strings.Index(s, self.Prefix)
+ if prefixIdx == -1 {
+ return -1, nil
+ }
+
+ suffixLen := len(self.Suffix)
+ if suffixLen <= 0 {
+ return prefixIdx, []int{len(s) - prefixIdx}
+ }
+
+ if (len(s) - prefixIdx) <= 0 {
+ return -1, nil
+ }
+
+ segments := acquireSegments(len(s) - prefixIdx)
+ for sub := s[prefixIdx:]; ; {
+ suffixIdx := strings.LastIndex(sub, self.Suffix)
+ if suffixIdx == -1 {
+ break
+ }
+
+ segments = append(segments, suffixIdx+suffixLen)
+ sub = sub[:suffixIdx]
+ }
+
+ if len(segments) == 0 {
+ releaseSegments(segments)
+ return -1, nil
+ }
+
+ reverseSegments(segments)
+
+ return prefixIdx, segments
+}
+
+func (self PrefixSuffix) Len() int {
+ return lenNo
+}
+
+func (self PrefixSuffix) Match(s string) bool {
+ return strings.HasPrefix(s, self.Prefix) && strings.HasSuffix(s, self.Suffix)
+}
+
+func (self PrefixSuffix) String() string {
+ return fmt.Sprintf("<prefix_suffix:[%s,%s]>", self.Prefix, self.Suffix)
+}
diff --git a/vendor/github.com/gobwas/glob/match/range.go b/vendor/github.com/gobwas/glob/match/range.go
new file mode 100644
index 000000000..ce30245a4
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/range.go
@@ -0,0 +1,48 @@
+package match
+
+import (
+ "fmt"
+ "unicode/utf8"
+)
+
+type Range struct {
+ Lo, Hi rune
+ Not bool
+}
+
+func NewRange(lo, hi rune, not bool) Range {
+ return Range{lo, hi, not}
+}
+
+func (self Range) Len() int {
+ return lenOne
+}
+
+func (self Range) Match(s string) bool {
+ r, w := utf8.DecodeRuneInString(s)
+ if len(s) > w {
+ return false
+ }
+
+ inRange := r >= self.Lo && r <= self.Hi
+
+ return inRange == !self.Not
+}
+
+func (self Range) Index(s string) (int, []int) {
+ for i, r := range s {
+ if self.Not != (r >= self.Lo && r <= self.Hi) {
+ return i, segmentsByRuneLength[utf8.RuneLen(r)]
+ }
+ }
+
+ return -1, nil
+}
+
+func (self Range) String() string {
+ var not string
+ if self.Not {
+ not = "!"
+ }
+ return fmt.Sprintf("<range:%s[%s,%s]>", not, string(self.Lo), string(self.Hi))
+}
diff --git a/vendor/github.com/gobwas/glob/match/row.go b/vendor/github.com/gobwas/glob/match/row.go
new file mode 100644
index 000000000..4379042e4
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/row.go
@@ -0,0 +1,77 @@
+package match
+
+import (
+ "fmt"
+)
+
+type Row struct {
+ Matchers Matchers
+ RunesLength int
+ Segments []int
+}
+
+func NewRow(len int, m ...Matcher) Row {
+ return Row{
+ Matchers: Matchers(m),
+ RunesLength: len,
+ Segments: []int{len},
+ }
+}
+
+func (self Row) matchAll(s string) bool {
+ var idx int
+ for _, m := range self.Matchers {
+ length := m.Len()
+
+ var next, i int
+ for next = range s[idx:] {
+ i++
+ if i == length {
+ break
+ }
+ }
+
+ if i < length || !m.Match(s[idx:idx+next+1]) {
+ return false
+ }
+
+ idx += next + 1
+ }
+
+ return true
+}
+
+func (self Row) lenOk(s string) bool {
+ var i int
+ for range s {
+ i++
+ if i > self.RunesLength {
+ return false
+ }
+ }
+ return self.RunesLength == i
+}
+
+func (self Row) Match(s string) bool {
+ return self.lenOk(s) && self.matchAll(s)
+}
+
+func (self Row) Len() (l int) {
+ return self.RunesLength
+}
+
+func (self Row) Index(s string) (int, []int) {
+ for i := range s {
+ if len(s[i:]) < self.RunesLength {
+ break
+ }
+ if self.matchAll(s[i:]) {
+ return i, self.Segments
+ }
+ }
+ return -1, nil
+}
+
+func (self Row) String() string {
+ return fmt.Sprintf("<row_%d:[%s]>", self.RunesLength, self.Matchers)
+}
diff --git a/vendor/github.com/gobwas/glob/match/segments.go b/vendor/github.com/gobwas/glob/match/segments.go
new file mode 100644
index 000000000..9ea6f3094
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/segments.go
@@ -0,0 +1,91 @@
+package match
+
+import (
+ "sync"
+)
+
+type SomePool interface {
+ Get() []int
+ Put([]int)
+}
+
+var segmentsPools [1024]sync.Pool
+
+func toPowerOfTwo(v int) int {
+ v--
+ v |= v >> 1
+ v |= v >> 2
+ v |= v >> 4
+ v |= v >> 8
+ v |= v >> 16
+ v++
+
+ return v
+}
+
+const (
+ cacheFrom = 16
+ cacheToAndHigher = 1024
+ cacheFromIndex = 15
+ cacheToAndHigherIndex = 1023
+)
+
+var (
+ segments0 = []int{0}
+ segments1 = []int{1}
+ segments2 = []int{2}
+ segments3 = []int{3}
+ segments4 = []int{4}
+)
+
+var segmentsByRuneLength [5][]int = [5][]int{
+ 0: segments0,
+ 1: segments1,
+ 2: segments2,
+ 3: segments3,
+ 4: segments4,
+}
+
+func init() {
+ for i := cacheToAndHigher; i >= cacheFrom; i >>= 1 {
+ func(i int) {
+ segmentsPools[i-1] = sync.Pool{New: func() interface{} {
+ return make([]int, 0, i)
+ }}
+ }(i)
+ }
+}
+
+func getTableIndex(c int) int {
+ p := toPowerOfTwo(c)
+ switch {
+ case p >= cacheToAndHigher:
+ return cacheToAndHigherIndex
+ case p <= cacheFrom:
+ return cacheFromIndex
+ default:
+ return p - 1
+ }
+}
+
+func acquireSegments(c int) []int {
+ // make []int with less capacity than cacheFrom
+ // is faster than acquiring it from pool
+ if c < cacheFrom {
+ return make([]int, 0, c)
+ }
+
+ return segmentsPools[getTableIndex(c)].Get().([]int)[:0]
+}
+
+func releaseSegments(s []int) {
+ c := cap(s)
+
+ // make []int with less capacity than cacheFrom
+ // is faster than acquiring it from pool
+ if c < cacheFrom {
+ return
+ }
+
+ segmentsPools[getTableIndex(c)].Put(s)
+}
diff --git a/vendor/github.com/gobwas/glob/match/single.go b/vendor/github.com/gobwas/glob/match/single.go
new file mode 100644
index 000000000..ee6e3954c
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/single.go
@@ -0,0 +1,43 @@
+package match
+
+import (
+ "fmt"
+ "github.com/gobwas/glob/util/runes"
+ "unicode/utf8"
+)
+
+// single represents ?
+type Single struct {
+ Separators []rune
+}
+
+func NewSingle(s []rune) Single {
+ return Single{s}
+}
+
+func (self Single) Match(s string) bool {
+ r, w := utf8.DecodeRuneInString(s)
+ if len(s) > w {
+ return false
+ }
+
+ return runes.IndexRune(self.Separators, r) == -1
+}
+
+func (self Single) Len() int {
+ return lenOne
+}
+
+func (self Single) Index(s string) (int, []int) {
+ for i, r := range s {
+ if runes.IndexRune(self.Separators, r) == -1 {
+ return i, segmentsByRuneLength[utf8.RuneLen(r)]
+ }
+ }
+
+ return -1, nil
+}
+
+func (self Single) String() string {
+ return fmt.Sprintf("<single:![%s]>", string(self.Separators))
+}
diff --git a/vendor/github.com/gobwas/glob/match/suffix.go b/vendor/github.com/gobwas/glob/match/suffix.go
new file mode 100644
index 000000000..85bea8c68
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/suffix.go
@@ -0,0 +1,35 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+)
+
+type Suffix struct {
+ Suffix string
+}
+
+func NewSuffix(s string) Suffix {
+ return Suffix{s}
+}
+
+func (self Suffix) Len() int {
+ return lenNo
+}
+
+func (self Suffix) Match(s string) bool {
+ return strings.HasSuffix(s, self.Suffix)
+}
+
+func (self Suffix) Index(s string) (int, []int) {
+ idx := strings.Index(s, self.Suffix)
+ if idx == -1 {
+ return -1, nil
+ }
+
+ return 0, []int{idx + len(self.Suffix)}
+}
+
+func (self Suffix) String() string {
+ return fmt.Sprintf("<suffix:%s>", self.Suffix)
+}
diff --git a/vendor/github.com/gobwas/glob/match/suffix_any.go b/vendor/github.com/gobwas/glob/match/suffix_any.go
new file mode 100644
index 000000000..c5106f819
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/suffix_any.go
@@ -0,0 +1,43 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+
+ sutil "github.com/gobwas/glob/util/strings"
+)
+
+type SuffixAny struct {
+ Suffix string
+ Separators []rune
+}
+
+func NewSuffixAny(s string, sep []rune) SuffixAny {
+ return SuffixAny{s, sep}
+}
+
+func (self SuffixAny) Index(s string) (int, []int) {
+ idx := strings.Index(s, self.Suffix)
+ if idx == -1 {
+ return -1, nil
+ }
+
+ i := sutil.LastIndexAnyRunes(s[:idx], self.Separators) + 1
+
+ return i, []int{idx + len(self.Suffix) - i}
+}
+
+func (self SuffixAny) Len() int {
+ return lenNo
+}
+
+func (self SuffixAny) Match(s string) bool {
+ if !strings.HasSuffix(s, self.Suffix) {
+ return false
+ }
+ return sutil.IndexAnyRunes(s[:len(s)-len(self.Suffix)], self.Separators) == -1
+}
+
+func (self SuffixAny) String() string {
+ return fmt.Sprintf("<suffix_any:![%s]%s>", string(self.Separators), self.Suffix)
+}
diff --git a/vendor/github.com/gobwas/glob/match/super.go b/vendor/github.com/gobwas/glob/match/super.go
new file mode 100644
index 000000000..3875950bb
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/super.go
@@ -0,0 +1,33 @@
+package match
+
+import (
+ "fmt"
+)
+
+type Super struct{}
+
+func NewSuper() Super {
+ return Super{}
+}
+
+func (self Super) Match(s string) bool {
+ return true
+}
+
+func (self Super) Len() int {
+ return lenNo
+}
+
+func (self Super) Index(s string) (int, []int) {
+ segments := acquireSegments(len(s) + 1)
+ for i := range s {
+ segments = append(segments, i)
+ }
+ segments = append(segments, len(s))
+
+ return 0, segments
+}
+
+func (self Super) String() string {
+ return fmt.Sprintf("<super>")
+}
diff --git a/vendor/github.com/gobwas/glob/match/text.go b/vendor/github.com/gobwas/glob/match/text.go
new file mode 100644
index 000000000..0a17616d3
--- /dev/null
+++ b/vendor/github.com/gobwas/glob/match/text.go
@@ -0,0 +1,45 @@
+package match
+
+import (
+ "fmt"
+ "strings"
+ "unicode/utf8"
+)
+
+// raw represents raw string to match
+type Text struct {
+ Str string
+ RunesLength int
+ BytesLength int
+ Segments []int
+}
+
+func NewText(s string) Text {
+ return Text{
+ Str: s,
+ RunesLength: utf8.RuneCountInString(s),
+ BytesLength: len(s),
+ Segments: []int{len(s)},
+ }
+}
+
+func (self Text) Match(s string) bool {
+ return self.Str == s
+}
+
+func (self Text) Len() int {
+ return self.RunesLength
+}
+
+func (self Text) Index(s string) (int, []int) {
+ index := strings.Index(s, self.Str)
+ if index == -1 {
+ return -1, nil
+ }
+
+ return index, self.Segments
+}
+
+func (self Text) String() string {
+ return fmt.Sprintf("<text:`%v`>", self.Str)
+}