-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
introduce golua to operate lua script in go application
- Loading branch information
Showing
51 changed files
with
9,750 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/aarzilli/golua/lua" | ||
) | ||
|
||
type ExternalHandler struct { | ||
l *lua.State | ||
} | ||
|
||
func newExternalHandler() *ExternalHandler { | ||
h := &ExternalHandler{} | ||
h.l = lua.NewState() | ||
h.l.OpenLibs() | ||
|
||
// get current executable path | ||
exePath, err := os.Executable() | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
exePath = filepath.Dir(exePath) | ||
|
||
h.l.DoFile(exePath + `/lua/init.lua`) | ||
|
||
// traverse ./handler directory, find all .lua files and load them | ||
directory := exePath + "/handlers" | ||
files, err := os.ReadDir(directory) | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
|
||
for _, file := range files { | ||
if filepath.Ext(file.Name()) == ".lua" { | ||
h.l.DoFile(filepath.Join(directory, file.Name())) | ||
} | ||
} | ||
|
||
return h | ||
} | ||
|
||
func (h *ExternalHandler) preprocessExternalChapterListURL(u string) string { | ||
h.l.GetGlobal("PreprocessChapterListURL") | ||
h.l.PushString(u) | ||
h.l.Call(1, 1) | ||
if !h.l.IsString(-1) { | ||
return u | ||
} | ||
return h.l.ToString(-1) | ||
} | ||
|
||
func (h *ExternalHandler) extractExternalChapterList(u string, rawPageContent []byte) (title string, chapters []*NovelChapterInfo) { | ||
h.l.GetGlobal("ExtractChapterList") | ||
h.l.PushString(u) | ||
h.l.PushBytes(rawPageContent) | ||
h.l.Call(2, 2) | ||
if !h.l.IsString(-2) || !h.l.IsTable(-1) { | ||
return | ||
} | ||
|
||
title = h.l.ToString(-2) | ||
h.l.PushNil() | ||
for h.l.Next(-2) != 0 { | ||
// 现在栈的情况:-1 => 值(表),-2 => 键,-3 => 章节表 | ||
if h.l.IsTable(-1) { | ||
chapter := &NovelChapterInfo{} | ||
h.l.PushString("Index") | ||
h.l.GetTable(-2) | ||
if !h.l.IsNumber(-1) { | ||
continue | ||
} | ||
chapter.Index = int(h.l.ToInteger(-1)) | ||
h.l.Pop(1) | ||
|
||
h.l.PushString("Title") | ||
h.l.GetTable(-2) | ||
if !h.l.IsString(-1) { | ||
continue | ||
} | ||
chapter.Title = h.l.ToString(-1) | ||
h.l.Pop(1) | ||
|
||
h.l.PushString("URL") | ||
h.l.GetTable(-2) | ||
if !h.l.IsString(-1) { | ||
continue | ||
} | ||
chapter.URL = h.l.ToString(-1) | ||
h.l.Pop(1) | ||
|
||
chapters = append(chapters, chapter) | ||
} | ||
h.l.Pop(1) | ||
} | ||
|
||
return | ||
} | ||
|
||
func (h *ExternalHandler) extractExternalChapterContent(rawPageContent []byte) (c []byte) { | ||
h.l.GetGlobal("ExtractChapterContent") | ||
h.l.PushBytes(rawPageContent) | ||
h.l.Call(1, 1) | ||
if !h.l.IsString(-1) { | ||
return | ||
} | ||
return []byte(h.l.ToString(-1)) | ||
} | ||
|
||
func (h *ExternalHandler) canHandleExternalSite(u string) bool { | ||
h.l.GetGlobal("FindHandler") | ||
h.l.PushString(u) | ||
h.l.Call(1, 1) | ||
if !h.l.IsNumber(-1) { | ||
return false | ||
} | ||
return h.l.ToBoolean(-1) | ||
} | ||
|
||
func init() { | ||
handler := newExternalHandler() | ||
|
||
registerNovelSiteHandler(&NovelSiteHandler{ | ||
Title: `飘天文学`, | ||
Urls: []string{`https://www.piaotia.com/`}, | ||
CanHandle: handler.canHandleExternalSite, | ||
PreprocessChapterListURL: handler.preprocessExternalChapterListURL, | ||
ExtractChapterList: handler.extractExternalChapterList, | ||
ExtractChapterContent: handler.extractExternalChapterContent, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
language: go | ||
dist: xenial | ||
before_install: | ||
- sudo add-apt-repository ppa:vbernat/haproxy-1.6 -y | ||
- sudo apt-get -qq update | ||
- sudo apt-get install -y liblua5.1-dev | ||
- sudo apt-get install -y liblua5.2-dev | ||
- sudo apt-get install -y liblua5.3-dev | ||
install: true | ||
script: | ||
- go test -v github.com/aarzilli/golua/lua | ||
- go test -v -tags lua52 github.com/aarzilli/golua/lua | ||
- go test -v -tags lua53 github.com/aarzilli/golua/lua | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License | ||
|
||
Copyright (c) 2010 | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
Go Bindings for the lua C API | ||
========================= | ||
|
||
[![Build Status](https://travis-ci.org/aarzilli/golua.svg?branch=master)](https://travis-ci.org/aarzilli/golua) | ||
|
||
Simplest way to install: | ||
|
||
# go get github.com/aarzilli/golua/lua | ||
|
||
You can then try to run the examples: | ||
|
||
$ cd golua/_example/ | ||
$ go run basic.go | ||
$ go run alloc.go | ||
$ go run panic.go | ||
$ go run userdata.go | ||
|
||
This library is configured using build tags. By default it will look for a library (or "shared object") called: | ||
|
||
* lua5.1 on Linux and macOS | ||
* lua on Windows | ||
* lua-5.1 on FreeBSD | ||
|
||
If this doesn't work `-tags luadash5.1` can be used to force `lua-5.1`, and `-tags llua` can be used to force `lua`. | ||
|
||
If you want to statically link to liblua.a you can do that with `-tags luaa`. Luajit can also be used by | ||
specifying `-tags luajit`. | ||
|
||
The library uses lua5.1 by default but also supports lua5.2 by specifying `-tags lua52`, lua5.3 by | ||
specifying `-tags lua53`, and lua5.4 by specifying `-tags lua54`. | ||
|
||
QUICK START | ||
--------------------- | ||
|
||
Create a new Virtual Machine with: | ||
|
||
```go | ||
L := lua.NewState() | ||
L.OpenLibs() | ||
defer L.Close() | ||
``` | ||
|
||
Lua's Virtual Machine is stack based, you can call lua functions like this: | ||
|
||
```go | ||
// push "print" function on the stack | ||
L.GetGlobal("print") | ||
// push the string "Hello World!" on the stack | ||
L.PushString("Hello World!") | ||
// call print with one argument, expecting no results | ||
L.Call(1, 0) | ||
``` | ||
|
||
Of course this isn't very useful, more useful is executing lua code from a file or from a string: | ||
|
||
```go | ||
// executes a string of lua code | ||
err := L.DoString("...") | ||
// executes a file | ||
err = L.DoFile(filename) | ||
``` | ||
|
||
You will also probably want to publish go functions to the virtual machine, you can do it by: | ||
|
||
```go | ||
func adder(L *lua.State) int { | ||
a := L.ToInteger(1) | ||
b := L.ToInteger(2) | ||
L.PushInteger(a + b) | ||
return 1 // number of return values | ||
} | ||
|
||
func main() { | ||
L := lua.NewState() | ||
defer L.Close() | ||
L.OpenLibs() | ||
|
||
L.Register("adder", adder) | ||
L.DoString("print(adder(2, 2))") | ||
} | ||
``` | ||
|
||
ON ERROR HANDLING | ||
--------------------- | ||
|
||
Lua's exceptions are incompatible with Go, golua works around this incompatibility by setting up protected execution environments in `lua.State.DoString`, `lua.State.DoFile` and lua.State.Call and turning every exception into a Go panic. | ||
|
||
This means that: | ||
|
||
1. In general you can't do any exception handling from Lua, `pcall` and `xpcall` are renamed to `unsafe_pcall` and `unsafe_xpcall`. They are only safe to be called from Lua code that never calls back to Go. Use at your own risk. | ||
|
||
2. The call to lua.State.Error, present in previous versions of this library, has been removed as it is nonsensical | ||
|
||
3. Method calls on a newly created `lua.State` happen in an unprotected environment, if Lua throws an exception as a result your program will be terminated. If this is undesirable perform your initialization like this: | ||
|
||
```go | ||
func LuaStateInit(L *lua.State) int { | ||
… initialization goes here… | ||
return 0 | ||
} | ||
|
||
… | ||
L.PushGoFunction(LuaStateInit) | ||
err := L.Call(0, 0) | ||
… | ||
``` | ||
|
||
ON THREADS AND COROUTINES | ||
--------------------- | ||
|
||
'lua.State' is not thread safe, but the library itself is. Lua's coroutines exist but (to my knowledge) have never been tested and are likely to encounter the same problems that errors have, use at your own peril. | ||
|
||
ODDS AND ENDS | ||
--------------------- | ||
|
||
* If you want to build against lua5.2, lua5.3, or lua5.4 use the build tags lua52, lua53, or lua54 respectively. | ||
* Compiling from source yields only a static link library (liblua.a), you can either produce the dynamic link library on your own or use the `luaa` build tag. | ||
|
||
LUAJIT | ||
--------------------- | ||
|
||
To link with [luajit-2.0.x](http://luajit.org/luajit.html), you can use CGO_CFLAGS and CGO_LDFLAGS environment variables | ||
|
||
``` | ||
$ CGO_CFLAGS=`pkg-config luajit --cflags` | ||
$ CGO_LDFLAGS=`pkg-config luajit --libs-only-L` | ||
$ go get -f -u -tags luajit github.com/aarzilli/golua/lua | ||
``` | ||
|
||
CONTRIBUTORS | ||
--------------------- | ||
|
||
* Adam Fitzgerald (original author) | ||
* Alessandro Arzilli | ||
* Steve Donovan | ||
* Harley Laue | ||
* James Nurmi | ||
* Ruitao | ||
* Xushiwei | ||
* Isaint | ||
* hsinhoyeh | ||
* Viktor Palmkvist | ||
* HongZhen Peng | ||
* Admin36 | ||
* Pierre Neidhardt (@Ambrevar) | ||
* HuangWei (@huangwei1024) | ||
* Adam Saponara | ||
|
||
SEE ALSO | ||
--------------------- | ||
|
||
- [Luar](https://github.com/stevedonovan/luar/) is a reflection layer on top of golua API providing a simplified way to publish go functions to a Lua VM. | ||
- [lunatico](https://github.com/fiatjaf/lunatico) is a reflection layer that allows you to push and read Go values to a Lua VM without understanding the Lua stack. | ||
- [Golua unicode](https://github.com/Ambrevar/golua) is an extension library that adds unicode support to golua and replaces lua regular expressions with re2. | ||
|
||
Licensing | ||
------------- | ||
GoLua is released under the MIT license. | ||
Please see the LICENSE file for more information. | ||
|
||
Lua is Copyright (c) Lua.org, PUC-Rio. All rights reserved. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
- find all calls to lua api that can result in lua_error calls and rework them (for example checkarg stuff) | ||
- lua.go: Dump implementing lua_dump | ||
- lua.go: Load implementing lua_load | ||
- AtPanic slightly broken when nil is passed, if we think passing nil has value to extract the current atpanic function we should also make sure it doesn't break everything | ||
- threads implementation is probably fucked completely should look into it | ||
- lauxlib.go:CheckOption is not implemented |
Oops, something went wrong.