Skip to content

Commit

Permalink
Add MaskToRegex helper
Browse files Browse the repository at this point in the history
  • Loading branch information
belak committed Dec 28, 2016
1 parent 9106fa6 commit e33b8f6
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
64 changes: 64 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package irc

import (
"bytes"
"fmt"
"regexp"
"strings"
)

// MaskToRegex converts an irc mask to a go Regexp for more convenient
// use. This should never return an error, but we have this here just
// in case.
func MaskToRegex(rawMask string) (*regexp.Regexp, error) {
backslashed := false
unprocessed := rawMask
buf := &bytes.Buffer{}
buf.WriteByte('^')

for len(unprocessed) > 0 {
i := strings.IndexAny(unprocessed, "\\?*")
if i < 0 {
if backslashed {
buf.WriteString(regexp.QuoteMeta("\\"))
backslashed = false
}

buf.WriteString(regexp.QuoteMeta(unprocessed))
unprocessed = ""
break
}

if backslashed && i > 0 {
buf.WriteString(regexp.QuoteMeta("\\"))
backslashed = false
} else if backslashed && i == 0 {
buf.WriteString(regexp.QuoteMeta(string(unprocessed[0])))
unprocessed = unprocessed[1:]
backslashed = false
continue
}

buf.WriteString(regexp.QuoteMeta(unprocessed[:i]))

switch unprocessed[i] {
case '\\':
backslashed = true
case '?':
buf.WriteString(".")
case '*':
buf.WriteString(".*")
}

unprocessed = unprocessed[i+1:]
fmt.Println(unprocessed)
}

if backslashed {
buf.WriteString(regexp.QuoteMeta("\\"))
}

buf.WriteByte('$')

return regexp.Compile(buf.String())
}
61 changes: 61 additions & 0 deletions utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package irc

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMaskToRegex(t *testing.T) {
var testCases = []struct {
Input string
Expect string
}{
{ // Empty should be fine
Input: "",
Expect: "^$",
},
{ // EVERYONE!
Input: "*!*@*",
Expect: "^.*!.*@.*$",
},
{
Input: "",
Expect: "^$",
},
{
Input: "",
Expect: "^$",
},
{ // Escape the slash
Input: "a\\\\b",
Expect: "^a\\\\b$",
},
{ // Escape a *
Input: "a\\*b",
Expect: "^a\\*b$",
},
{ // Escape a ?
Input: "a\\?b",
Expect: "^a\\?b$",
},
{ // Single slash in the middle of a string should be a slash
Input: "a\\b",
Expect: "^a\\\\b$",
},
{ // Single slash should just match a single slash
Input: "\\",
Expect: "^\\\\$",
},
{
Input: "\\a?",
Expect: "^\\\\a.$",
},
}

for _, testCase := range testCases {
ret, err := MaskToRegex(testCase.Input)
assert.NoError(t, err)
assert.Equal(t, testCase.Expect, ret.String())
}
}

0 comments on commit e33b8f6

Please sign in to comment.