-
Notifications
You must be signed in to change notification settings - Fork 2
/
lua-filter.go
93 lines (76 loc) · 1.68 KB
/
lua-filter.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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main
import (
"bufio"
"errors"
"github.com/yuin/gopher-lua"
"os"
)
type Filter struct {
state *lua.LState
exceptionHandlerFunction *lua.LFunction
}
func NewFilter() *Filter {
state := lua.NewState()
filter := &Filter{
state: state,
}
filter.exceptionHandlerFunction = state.NewFunction(
filter.exceptionHandler)
return filter
}
func (f *Filter) exceptionHandler(L *lua.LState) int {
panic("exception in lua code")
return 0
}
func (f *Filter) LoadScript(filename string) error {
return f.state.DoFile(filename)
}
func (f *Filter) ValidateScript() error {
fn := f.state.GetGlobal("filter")
if fn.Type() != lua.LTFunction {
return errors.New("Function 'filter' not found")
}
return nil
}
func (f *Filter) ValidateEvent(event string) (bool, error) {
fn := f.state.GetGlobal("filter")
f.state.Push(fn.(*lua.LFunction))
f.state.Push(lua.LString(event))
// one argument and one return value
err := f.state.PCall(1, 1, f.exceptionHandlerFunction)
if err != nil {
return false, err
}
top := f.state.GetTop()
returnValue := f.state.Get(top)
if returnValue.Type() != lua.LTBool {
return false, errors.New("Invalid return value")
}
return lua.LVAsBool(returnValue), err
}
func main() {
if len(os.Args) != 2 {
println("provide filter script")
return
}
filter := NewFilter()
err := filter.LoadScript(os.Args[1])
if err != nil {
panic(err.Error())
}
err = filter.ValidateScript()
if err != nil {
panic(err.Error())
}
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
event := scanner.Text()
isValid, err := filter.ValidateEvent(event)
if err != nil {
panic(err.Error())
}
if isValid {
println(event)
}
}
}