regex2dfa.go 1.2 KB

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