Add glob conversion

This commit is contained in:
Elara 2022-05-18 23:27:47 -07:00
parent 9d969a1382
commit e03c680213
2 changed files with 96 additions and 0 deletions

58
glob.go Normal file
View File

@ -0,0 +1,58 @@
package pcre
import (
"unsafe"
"go.arsenm.dev/pcre/lib"
"modernc.org/libc"
)
// CompileGlob converts the given glob into a
// pcre regular expression, and then compiles it,
// returning the result.
func CompileGlob(glob string) (*Regexp, error) {
tls := libc.NewTLS()
defer tls.Close()
// Get C string from given glob
cGlob, err := libc.CString(glob)
if err != nil {
return nil, err
}
defer libc.Xfree(tls, cGlob)
// Convert length to size_t
cGlobLen := lib.Tsize_t(len(glob))
// Create null pointer
outPtr := uintptr(0)
// Get pointer to pointer
cOutPtr := uintptr(unsafe.Pointer(&outPtr))
// Create 0 size_t
outLen := lib.Tsize_t(0)
// Get pointer to size_t
cOutLen := uintptr(unsafe.Pointer(&outLen))
// Convert glob to regular expression
ret := lib.Xpcre2_pattern_convert_8(
tls,
cGlob,
cGlobLen,
lib.DPCRE2_CONVERT_GLOB,
cOutPtr,
cOutLen,
0,
)
if ret != 0 {
return nil, codeToError(tls, ret)
}
// Get output as byte slice
out := unsafe.Slice((*byte)(unsafe.Pointer(outPtr)), outLen)
// Convert output to string
// This copies the data, so it's safe for later use
pattern := string(out)
// Compile converted glob and return results
return Compile(pattern)
}

38
glob_test.go Normal file
View File

@ -0,0 +1,38 @@
package pcre_test
import (
"testing"
"go.arsenm.dev/pcre"
)
func TestCompileGlob(t *testing.T) {
r, err := pcre.CompileGlob("/**/bin")
if err != nil {
t.Fatal(err)
}
if !r.MatchString("/bin") {
t.Error("expected /bin to match")
}
if !r.MatchString("/usr/bin") {
t.Error("expected /usr/bin to match")
}
if !r.MatchString("/usr/local/bin") {
t.Error("expected /usr/local/bin to match")
}
if r.MatchString("/usr") {
t.Error("expected /usr not to match")
}
if r.MatchString("/usr/local") {
t.Error("expected /usr/local not to match")
}
if r.MatchString("/home") {
t.Error("expected /home not to match")
}
}