loadlib.go 2.9 KB

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