forked from getlantern/marionette
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathregex2dfa.go
50 lines (40 loc) · 1.25 KB
/
regex2dfa.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package regex2dfa
// #cgo CXXFLAGS: -std=c++11 -DMARIONETTE -I${SRCDIR}/../third_party/re2/ -I${SRCDIR}/../third_party/openfst/src/include/
// #cgo LDFLAGS: ${SRCDIR}/../third_party/libs/libfst.a ${SRCDIR}/../third_party/libs/libfstscript.a ${SRCDIR}/../third_party/libs/libre2.a -ldl
// #include <stdlib.h>
// #include <stdint.h>
// int _regex2dfa(const char* input_regex, uint32_t input_regex_len, char **out, size_t *sz);
import "C"
import (
"errors"
"sync"
"unsafe"
)
// ErrInternal is returned any error occurs.
var ErrInternal = errors.New("regex2dfa: internal error")
// Shared mutex for all Regex2DFA calls.
var mu sync.Mutex
// Regex2DFA converts regex into a DFA table.
func Regex2DFA(regex string) (string, error) {
mu.Lock()
defer mu.Unlock()
regex = "^" + regex + "$"
cregex := C.CString(regex)
defer C.free(unsafe.Pointer(cregex))
var cout *C.char
var sz C.size_t
if errno := C._regex2dfa(cregex, C.uint32_t(len(regex)), &cout, &sz); errno != 0 {
return "", ErrInternal
}
out := C.GoStringN(cout, C.int(sz))
C.free(unsafe.Pointer(cout))
return out, nil
}
// MustRegex2DFA converts regex into a DFA table. Panic on error.
func MustRegex2DFA(regex string) string {
s, err := Regex2DFA(regex)
if err != nil {
panic(err)
}
return s
}