github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/actions/lua/regexp/regexp.go (about) 1 package regexp 2 3 import ( 4 "regexp" 5 6 "github.com/Shopify/go-lua" 7 "github.com/treeverse/lakefs/pkg/actions/lua/util" 8 ) 9 10 // Open exposes the regexp functions to Lua code in the `regexp` 11 // namespace. 12 func Open(l *lua.State) { 13 reOpen := func(l *lua.State) int { 14 lua.NewLibrary(l, regexpLibrary) 15 return 1 16 } 17 lua.Require(l, "regexp", reOpen, false) 18 l.Pop(1) 19 } 20 21 var regexpLibrary = []lua.RegistryFunction{ 22 {Name: "match", Function: match}, 23 {Name: "quote_meta", Function: quoteMeta}, 24 {Name: "compile", Function: compile}, 25 } 26 27 func match(l *lua.State) int { 28 pattern := lua.CheckString(l, 1) 29 s := lua.CheckString(l, 2) 30 31 matched, err := regexp.MatchString(pattern, s) 32 if err != nil { 33 lua.Errorf(l, "%s", err.Error()) 34 panic("unreachable") 35 } 36 37 l.PushBoolean(matched) 38 return 1 39 } 40 41 func quoteMeta(l *lua.State) int { 42 s := lua.CheckString(l, 1) 43 quoted := regexp.QuoteMeta(s) 44 l.PushString(quoted) 45 return 1 46 } 47 48 func compile(l *lua.State) int { 49 expr := lua.CheckString(l, 1) 50 re, err := regexp.Compile(expr) 51 if err != nil { 52 lua.Errorf(l, "%s", err.Error()) 53 panic("unreachable") 54 } 55 56 l.NewTable() 57 for name, goFn := range regexpFunc { 58 // -1: tbl 59 l.PushGoFunction(goFn(re)) 60 // -1: fn, -2:tbl 61 l.SetField(-2, name) 62 } 63 64 return 1 65 } 66 67 var regexpFunc = map[string]func(*regexp.Regexp) lua.Function{ 68 "find_all": reFindAll, 69 "find_all_submatch": reFindAllSubmatch, 70 "find": reFind, 71 "find_submatch": reFindSubmatch, 72 } 73 74 func reFindAll(re *regexp.Regexp) lua.Function { 75 return func(l *lua.State) int { 76 s := lua.CheckString(l, 1) 77 n := lua.CheckInteger(l, 2) 78 all := re.FindAllString(s, n) 79 return util.DeepPush(l, all) 80 } 81 } 82 83 func reFindAllSubmatch(re *regexp.Regexp) lua.Function { 84 return func(l *lua.State) int { 85 s := lua.CheckString(l, 1) 86 n := lua.CheckInteger(l, 2) 87 allSubmatch := re.FindAllStringSubmatch(s, n) 88 return util.DeepPush(l, allSubmatch) 89 } 90 } 91 92 func reFind(re *regexp.Regexp) lua.Function { 93 return func(l *lua.State) int { 94 s := lua.CheckString(l, 1) 95 all := re.FindString(s) 96 return util.DeepPush(l, all) 97 } 98 } 99 100 func reFindSubmatch(re *regexp.Regexp) lua.Function { 101 return func(l *lua.State) int { 102 s := lua.CheckString(l, 1) 103 allSubmatch := re.FindStringSubmatch(s) 104 return util.DeepPush(l, allSubmatch) 105 } 106 }