diff --git a/_glua-tests/db.lua b/_glua-tests/db.lua index b0de5ad2..bac8af38 100644 --- a/_glua-tests/db.lua +++ b/_glua-tests/db.lua @@ -19,9 +19,9 @@ local function f2() assert(info.nups == 1) assert(info.name == "f2") assert(info.what == "Lua") - if string.find(_VERSION, "GopherLua") then - assert(info.source == "db.lua") - end + assert(info.source == "@db.lua") + assert(info.short_src == "db.lua") + assert(debug.getinfo(2, "S").short_src == "db.lua") end f2() @@ -35,9 +35,18 @@ assert(info.lastlinedefined == 29) assert(info.nups == 0) assert(info.name == nil) assert(info.what == "Lua") -if string.find(_VERSION, "GopherLua") then - assert(info.source == "db.lua") -end +assert(info.source == "@db.lua") +assert(info.short_src == "db.lua") + +-- source and short_src as in Lua 5.1 (#547) +local s = debug.getinfo(print, "S") +assert(s.source == "=[C]" and s.short_src == "[C]") +s = loadstring("return debug.getinfo(1, 'S')", "=custom")() +assert(s.source == "=custom" and s.short_src == "custom") +s = loadstring("return debug.getinfo(1, 'S')", "@virtual.lua")() +assert(s.source == "@virtual.lua" and s.short_src == "virtual.lua") +s = loadstring("return debug.getinfo(1, 'S')", "chunk\nsecond line")() +assert(s.short_src == '[string "chunk..."]') local function f4() local a,b,c = 1,2,3 diff --git a/_state.go b/_state.go index 6e9febfb..9ed96ac4 100644 --- a/_state.go +++ b/_state.go @@ -1556,8 +1556,13 @@ func (ls *LState) GetInfo(what string, dbg *Debug, fn LValue) (LValue, error) { } else { dbg.What = "Lua" } - if !f.IsG { + if f.IsG { + dbg.Source = "=[C]" // as Lua 5.1 reports a function that is not Lua code + } else { dbg.Source = f.Proto.SourceName + if f.Proto.fromFile { + dbg.Source = "@" + f.Proto.SourceName + } dbg.LineDefined = f.Proto.LineDefined dbg.LastLineDefined = f.Proto.LastLineDefined } diff --git a/auxlib.go b/auxlib.go index a022bdd8..2df546d6 100644 --- a/auxlib.go +++ b/auxlib.go @@ -386,7 +386,18 @@ func (ls *LState) LoadFile(path string) (*LFunction, error) { } } - return ls.Load(reader, path) + fn, err := ls.Load(reader, path) + if err == nil && len(path) > 0 { + markLoadedFromFile(fn.Proto) + } + return fn, err +} + +func markLoadedFromFile(proto *FunctionProto) { + proto.fromFile = true + for _, p := range proto.FunctionPrototypes { + markLoadedFromFile(p) + } } func (ls *LState) LoadString(source string) (*LFunction, error) { diff --git a/debuglib.go b/debuglib.go index da8f5254..14b16025 100644 --- a/debuglib.go +++ b/debuglib.go @@ -62,6 +62,7 @@ func debugGetInfo(L *LState) int { } tbl.RawSetString("what", LString(dbg.What)) tbl.RawSetString("source", LString(dbg.Source)) + tbl.RawSetString("short_src", LString(chunkID(dbg.Source))) tbl.RawSetString("currentline", LNumber(dbg.CurrentLine)) tbl.RawSetString("nups", LNumber(dbg.NUpvalues)) tbl.RawSetString("linedefined", LNumber(dbg.LineDefined)) @@ -171,3 +172,36 @@ func debugTraceback(L *LState) int { L.Push(LString(traceback)) return 1 } + +// chunkID is the short_src of a source, as luaO_chunkid in Lua 5.1: +// "=name" -> name, "@file" -> file, a string chunk -> [string "first line..."]. +func chunkID(source string) string { + const idSize = 60 + switch { + case strings.HasPrefix(source, "="): + s := source[1:] + if len(s) > idSize-1 { + s = s[:idSize-1] + } + return s + case strings.HasPrefix(source, "@"): + s := source[1:] + if len(s) > idSize-1 { + s = "..." + s[len(s)-(idSize-1-3):] + } + return s + default: + s := source + cut := false + if i := strings.IndexAny(s, "\r\n"); i >= 0 { + s, cut = s[:i], true + } + if max := idSize - len(`[string "..."]`) - 1; len(s) > max { + s, cut = s[:max], true + } + if cut { + s += "..." + } + return `[string "` + s + `"]` + } +} diff --git a/function.go b/function.go index 169e5407..8ea701b2 100644 --- a/function.go +++ b/function.go @@ -39,6 +39,8 @@ type FunctionProto struct { DbgCalls []DbgCall DbgUpvalues []string + fromFile bool // loaded by LoadFile: debug info reports the source as "@" + SourceName + stringConstants []string } diff --git a/state.go b/state.go index 292f93b4..f83512e4 100644 --- a/state.go +++ b/state.go @@ -1769,8 +1769,13 @@ func (ls *LState) GetInfo(what string, dbg *Debug, fn LValue) (LValue, error) { } else { dbg.What = "Lua" } - if !f.IsG { + if f.IsG { + dbg.Source = "=[C]" // as Lua 5.1 reports a function that is not Lua code + } else { dbg.Source = f.Proto.SourceName + if f.Proto.fromFile { + dbg.Source = "@" + f.Proto.SourceName + } dbg.LineDefined = f.Proto.LineDefined dbg.LastLineDefined = f.Proto.LastLineDefined }