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  }