ergo/irc/utils/glob.go

64 lines
1.2 KiB
Go
Raw Normal View History

2020-05-05 04:29:10 +02:00
// Copyright (c) 2020 Shivaram Lingamneni <slingamn@cs.stanford.edu>
// released under the MIT license
package utils
import (
"bytes"
"regexp"
"regexp/syntax"
2020-05-05 04:29:10 +02:00
)
// yet another glob implementation in Go
2020-05-13 09:41:00 +02:00
func addRegexp(buf *bytes.Buffer, glob string, submatch bool) (err error) {
for _, r := range glob {
switch r {
case '*':
2020-05-13 09:41:00 +02:00
if submatch {
buf.WriteString("(.*)")
} else {
buf.WriteString(".*")
}
case '?':
2020-05-13 09:41:00 +02:00
if submatch {
buf.WriteString("(.)")
} else {
buf.WriteString(".")
}
case 0xFFFD:
2020-05-13 09:41:00 +02:00
return &syntax.Error{Code: syntax.ErrInvalidUTF8, Expr: glob}
default:
buf.WriteString(regexp.QuoteMeta(string(r)))
2020-05-05 04:29:10 +02:00
}
}
2020-05-13 09:41:00 +02:00
return
}
func CompileGlob(glob string, submatch bool) (result *regexp.Regexp, err error) {
var buf bytes.Buffer
buf.WriteByte('^')
err = addRegexp(&buf, glob, submatch)
if err != nil {
return
}
2020-05-05 04:29:10 +02:00
buf.WriteByte('$')
return regexp.Compile(buf.String())
}
2020-05-13 09:41:00 +02:00
func CompileMasks(masks []string) (result *regexp.Regexp, err error) {
var buf bytes.Buffer
buf.WriteString("^(")
for i, mask := range masks {
err = addRegexp(&buf, mask, false)
if err != nil {
return
}
if i != len(masks)-1 {
buf.WriteByte('|')
}
}
buf.WriteString(")$")
return regexp.Compile(buf.String())
}