glob/glob.go

78 lines
2.0 KiB
Go
Raw Normal View History

2015-11-30 17:58:20 +03:00
package glob
2015-11-30 18:33:50 +03:00
// Glob represents compiled glob pattern.
2015-11-30 18:24:20 +03:00
type Glob interface {
2015-11-30 17:58:20 +03:00
Match(string) bool
}
2016-05-06 00:37:58 +03:00
type Globs []Glob
2016-01-18 13:44:31 +03:00
// Compile creates Glob for given pattern and strings (if any present after pattern) as separators.
2015-11-30 19:01:49 +03:00
// The pattern syntax is:
//
2016-01-18 13:42:51 +03:00
// pattern:
// { term }
2016-01-18 13:38:19 +03:00
//
2016-01-18 13:42:51 +03:00
// term:
// `*` matches any sequence of non-separator characters
// `**` matches any sequence of characters
// `?` matches any single non-separator character
// `[` [ `!` ] { character-range } `]`
// character class (must be non-empty)
// `{` pattern-list `}`
// pattern alternatives
// c matches character c (c != `*`, `**`, `?`, `\`, `[`, `{`, `}`)
// `\` c matches character c
2016-01-18 13:38:19 +03:00
//
2016-01-18 13:42:51 +03:00
// character-range:
// c matches character c (c != `\\`, `-`, `]`)
// `\` c matches character c
// lo `-` hi matches character c for lo <= c <= hi
//
// pattern-list:
// pattern { `,` pattern }
// comma-separated (without spaces) patterns
2016-01-18 13:38:19 +03:00
//
2016-02-02 14:57:42 +03:00
func Compile(pattern string, separators ...rune) (Glob, error) {
2016-01-08 20:14:31 +03:00
ast, err := parse(newLexer(pattern))
2015-12-24 17:54:54 +03:00
if err != nil {
return nil, err
}
2015-11-30 17:58:20 +03:00
2016-02-02 14:57:42 +03:00
matcher, err := compile(ast, separators)
2016-01-08 20:14:31 +03:00
if err != nil {
return nil, err
2015-12-01 17:22:17 +03:00
}
2016-01-08 20:14:31 +03:00
return matcher, nil
2015-11-30 17:58:20 +03:00
}
2016-01-18 13:38:19 +03:00
// MustCompile is the same as Compile, except that if Compile returns error, this will panic
2016-02-02 22:03:37 +03:00
func MustCompile(pattern string, separators ...rune) Glob {
2016-01-08 20:14:31 +03:00
g, err := Compile(pattern, separators...)
if err != nil {
panic(err)
2015-11-30 18:24:20 +03:00
}
2016-01-08 20:14:31 +03:00
return g
2015-12-25 19:40:36 +03:00
}
2016-02-24 23:53:19 +03:00
2016-02-25 00:31:30 +03:00
// QuoteMeta returns a string that quotes all glob pattern meta characters
2016-02-24 23:53:19 +03:00
// inside the argument text; For example, QuoteMeta(`{foo*}`) returns `\[foo\*\]`.
func QuoteMeta(s string) string {
b := make([]byte, 2*len(s))
2016-02-25 00:31:30 +03:00
// a byte loop is correct because all meta characters are ASCII
2016-02-24 23:53:19 +03:00
j := 0
for i := 0; i < len(s); i++ {
if special(s[i]) {
b[j] = '\\'
j++
}
b[j] = s[i]
j++
}
return string(b[0:j])
}