github.com/tul/gopher-lua@v0.0.0-20181008131706-f6fcaab0c612/loadlib.go (about) 1 package lua 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 ) 9 10 /* load lib {{{ */ 11 12 var loLoaders = []LGFunction{loLoaderPreload, loLoaderLua} 13 14 func loGetPath(env string, defpath string) string { 15 path := os.Getenv(env) 16 if len(path) == 0 { 17 path = defpath 18 } 19 path = strings.Replace(path, ";;", ";"+defpath+";", -1) 20 if os.PathSeparator != '/' { 21 dir, err := filepath.Abs(filepath.Dir(os.Args[0])) 22 if err != nil { 23 panic(err) 24 } 25 path = strings.Replace(path, "!", dir, -1) 26 } 27 return path 28 } 29 30 func loFindFile(L *LState, name, pname string) (string, string) { 31 name = strings.Replace(name, ".", string(os.PathSeparator), -1) 32 lv := L.GetField(L.GetField(L.Get(EnvironIndex), "package"), pname) 33 path, ok := lv.(LString) 34 if !ok { 35 L.RaiseError("package.%s must be a string", pname) 36 } 37 messages := []string{} 38 for _, pattern := range strings.Split(string(path), ";") { 39 luapath := strings.Replace(pattern, "?", name, -1) 40 if _, err := os.Stat(luapath); err == nil { 41 return luapath, "" 42 } else { 43 messages = append(messages, err.Error()) 44 } 45 } 46 return "", strings.Join(messages, "\n\t") 47 } 48 49 func OpenPackage(L *LState) int { 50 packagemod := L.RegisterModule(LoadLibName, loFuncs) 51 52 L.SetField(packagemod, "preload", L.NewTable()) 53 54 loaders := L.CreateTable(len(loLoaders), 0) 55 for i, loader := range loLoaders { 56 L.RawSetInt(loaders, i+1, L.NewFunction(loader)) 57 } 58 L.SetField(packagemod, "loaders", loaders) 59 L.SetField(L.Get(RegistryIndex), "_LOADERS", loaders) 60 61 loaded := L.NewTable() 62 L.SetField(packagemod, "loaded", loaded) 63 L.SetField(L.Get(RegistryIndex), "_LOADED", loaded) 64 65 L.SetField(packagemod, "path", LString(loGetPath(LuaPath, LuaPathDefault))) 66 L.SetField(packagemod, "cpath", emptyLString) 67 68 L.Push(packagemod) 69 return 1 70 } 71 72 var loFuncs = map[string]LGFunction{ 73 "loadlib": loLoadLib, 74 "seeall": loSeeAll, 75 } 76 77 func loLoaderPreload(L *LState) int { 78 name := L.CheckString(1) 79 preload := L.GetField(L.GetField(L.Get(EnvironIndex), "package"), "preload") 80 if _, ok := preload.(*LTable); !ok { 81 L.RaiseError("package.preload must be a table") 82 } 83 lv := L.GetField(preload, name) 84 if lv == LNil { 85 L.Push(LString(fmt.Sprintf("no field package.preload['%s']", name))) 86 return 1 87 } 88 L.Push(lv) 89 return 1 90 } 91 92 func loLoaderLua(L *LState) int { 93 name := L.CheckString(1) 94 path, msg := loFindFile(L, name, "path") 95 if len(path) == 0 { 96 L.Push(LString(msg)) 97 return 1 98 } 99 fn, err1 := L.LoadFile(path) 100 if err1 != nil { 101 L.RaiseError(err1.Error()) 102 } 103 L.Push(fn) 104 return 1 105 } 106 107 func loLoadLib(L *LState) int { 108 L.RaiseError("loadlib is not supported") 109 return 0 110 } 111 112 func loSeeAll(L *LState) int { 113 mod := L.CheckTable(1) 114 mt := L.GetMetatable(mod) 115 if mt == LNil { 116 mt = L.CreateTable(0, 1) 117 L.SetMetatable(mod, mt) 118 } 119 L.SetField(mt, "__index", L.Get(GlobalsIndex)) 120 return 0 121 } 122 123 /* }}} */ 124 125 //