Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mobdebug tostring() is explicit #401

Closed
wants to merge 2 commits into from

Conversation

andrewstarks
Copy link

I did this because my Lua 5.3 interpreter has LUA_NOCVTN2S and LUA_NOCVTS2N turned on. With this patch, everything seems to work fine.

Please feel free to ignore this, if you don't wish to diverge from the mainline of mobdebug (maybe you wrote that too?). I'm passing this along, only if it is useful.

@pkulchenko
Copy link
Owner

Andrew, thank you for the patch. You (probably accidentally) added Lua 5.3 binaries, which I don't plan to upgrade for now since the changes are only in few C API calls (this matter only for those who compile their Lua binaries anyway).

Please feel free to ignore this, if you don't wish to diverge from the mainline of mobdebug (maybe you wrote that too?). I'm passing this along, only if it is useful.

yes, I wrote mobdebug. Some of this code is actually in Serpent (which I wrote as well), so it will need to be updated there and in mobdebug. I'll then pull the upgraded version into ZBS. Thanks!

@pkulchenko
Copy link
Owner

Andrew, I'm working through these changes; is this tostring really needed?

local head = indent and '{\n'.. tostring(prefix) .. indent or '{'`

prefix here is the result of string.rep(indent or '', level), which can't be anything than a string...

@andrewstarks
Copy link
Author

On Monday, January 19, 2015, Paul Kulchenko notifications@github.com
wrote:

Andrew, I'm working through these changes; is this tostring really needed?

local head = indent and '{\n'.. tostring(prefix) .. indent or '{'`

prefix here is the result of string.rep(indent or '', level), which can't
be anything than a string...

Reply to this email directly or view it on GitHub
#401 (comment)
.

No it isn't and this commit was much too rushed. I should not have sent
this in. I'll do a proper job of it tomorrow, for my uses, if nothing else.
I'm not sure that I even got every spot.

@pkulchenko
Copy link
Owner

I'll do a proper job of it tomorrow, for my uses, if nothing else. I'm not sure that I even got every spot.

Andrew, sounds good. Can you try the following patch (I think I got all the spots)?

diff --git a/src/mobdebug.lua b/src/mobdebug.lua
index 5e2a50b..fe50dbd 100644
--- a/src/mobdebug.lua
+++ b/src/mobdebug.lua
@@ -19,7 +19,7 @@ end)("os")

 local mobdebug = {
   _NAME = "mobdebug",
-  _VERSION = 0.611,
+  _VERSION = 0.612,
   _COPYRIGHT = "Paul Kulchenko",
   _DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
   port = os and os.getenv and tonumber((os.getenv("MOBDEBUG_PORT"))) or 8172,
@@ -127,7 +127,7 @@ end
 local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end

 local serpent = (function() ---- include Serpent module for serialization
-local n, v = "serpent", 0.272 -- (C) 2012-13 Paul Kulchenko; MIT License
+local n, v = "serpent", 0.273 -- (C) 2012-13 Paul Kulchenko; MIT License
 local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
 local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
 local badtype = {thread = true, userdata = true, cdata = true}
@@ -203,8 +203,8 @@ local function s(t, opts)
             local sname = safename(iname, gensym(key)) -- iname is table for local variables
             sref[#sref] = val2str(key,sname,indent,sname,iname,true) end
           sref[#sref+1] = 'placeholder'
-          local path = seen[t]..'['..(seen[key] or globals[key] or gensym(key))..']'
-          sref[#sref] = path..space..'='..space..(seen[value] or val2str(value,nil,indent,path))
+          local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']'
+          sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path))
         else
           out[#out+1] = val2str(value,key,indent,insref,seen[t],plainindex,level+1)
         end
@@ -768,12 +768,12 @@ local function debugger_loop(sev, svars, sfile, sline)
           status, res = stringify_results(pcall(func))
         end
         if status then
-          server:send("200 OK " .. #res .. "\n")
+          server:send("200 OK " .. tostring(#res) .. "\n")
           server:send(res)
         else
           -- fix error if not set (for example, when loadstring is not present)
           if not res then res = "Unknown error" end
-          server:send("401 Error in Expression " .. #res .. "\n")
+          server:send("401 Error in Expression " .. tostring(#res) .. "\n")
           server:send(res)
         end
       else
@@ -786,7 +786,7 @@ local function debugger_loop(sev, svars, sfile, sline)
       if abort == nil then -- no LOAD/RELOAD allowed inside start()
         if size > 0 then server:receive(size) end
         if sfile and sline then
-          server:send("201 Started " .. sfile .. " " .. sline .. "\n")
+          server:send("201 Started " .. sfile .. " " .. tostring(sline) .. "\n")
         else
           server:send("200 OK 0\n")
         end
@@ -810,7 +810,7 @@ local function debugger_loop(sev, svars, sfile, sline)
               debugee = func
               coroyield("load")
             else
-              server:send("401 Error in Expression " .. #res .. "\n")
+              server:send("401 Error in Expression " .. tostring(#res) .. "\n")
               server:send(res)
             end
           else
@@ -826,9 +826,9 @@ local function debugger_loop(sev, svars, sfile, sline)
           watchescnt = watchescnt + 1
           local newidx = #watches + 1
           watches[newidx] = func
-          server:send("200 OK " .. newidx .. "\n")
+          server:send("200 OK " .. tostring(newidx) .. "\n")
         else
-          server:send("401 Error in Expression " .. #res .. "\n")
+          server:send("401 Error in Expression " .. tostring(#res) .. "\n")
           server:send(res)
         end
       else
@@ -850,13 +850,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "STEP" then
@@ -866,13 +866,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "OVER" or command == "OUT" then
@@ -887,13 +887,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "BASEDIR" then
@@ -922,14 +922,14 @@ local function debugger_loop(sev, svars, sfile, sline)
         ev, vars = coroyield("stack")
       end
       if ev and ev ~= events.STACK then
-        server:send("401 Error in Execution " .. #vars .. "\n")
+        server:send("401 Error in Execution " .. tostring(#vars) .. "\n")
         server:send(vars)
       else
         local ok, res = pcall(mobdebug.dump, vars, {nocode = true, sparse = false})
         if ok then
-          server:send("200 OK " .. res .. "\n")
+          server:send("200 OK " .. tostring(res) .. "\n")
         else
-          server:send("401 Error in Execution " .. #res .. "\n")
+          server:send("401 Error in Execution " .. tostring(#res) .. "\n")
           server:send(res)
         end
       end
@@ -949,7 +949,7 @@ local function debugger_loop(sev, svars, sfile, sline)
             for n = 1, #tbl do
               tbl[n] = select(2, pcall(mobdebug.line, tbl[n], {nocode = true, comment = false})) end
             local file = table.concat(tbl, "\t").."\n"
-            server:send("204 Output " .. stream .. " " .. #file .. "\n" .. file)
+            server:send("204 Output " .. stream .. " " .. tostring(#file) .. "\n" .. file)
           end
         end)
         if not default then genv.print() end -- "fake" print to start printing loop
@@ -971,7 +971,7 @@ local function connect(controller_host, controller_port)
   if not sock then return nil, err end

   if sock.settimeout then sock:settimeout(mobdebug.connecttimeout) end
-  local res, err = sock:connect(controller_host, controller_port)
+  local res, err = sock:connect(controller_host, tostring(controller_port))
   if sock.settimeout then sock:settimeout() end

   if not res then return nil, err end
@@ -1050,7 +1050,7 @@ local function controller(controller_host, controller_port, scratchpad)
   if server then
     local function report(trace, err)
       local msg = err .. "\n" .. trace
-      server:send("401 Error in Execution " .. #msg .. "\n")
+      server:send("401 Error in Execution " .. tostring(#msg) .. "\n")
       server:send(msg)
       return err
     end
@@ -1320,7 +1320,7 @@ local function handle(params, client, options)
         if not file then
            _, _, file, lines = string.find(exp, "^(%S+)%s+(.+)")
         end
-        client:send("LOAD " .. #lines .. " " .. file .. "\n")
+        client:send("LOAD " .. tostring(#lines) .. " " .. file .. "\n")
         client:send(lines)
       else
         local file = io.open(exp, "r")
@@ -1338,7 +1338,7 @@ local function handle(params, client, options)

         local file = string.gsub(exp, "\\", "/") -- convert slash
         file = removebasedir(file, basedir)
-        client:send("LOAD " .. #lines .. " " .. file .. "\n")
+        client:send("LOAD " .. tostring(#lines) .. " " .. file .. "\n")
         if #lines > 0 then client:send(lines) end
       end
       while true do

Thanks!

@andrewstarks
Copy link
Author

this appears to work fine. I'll use it today and report any errors. So far so good, however.

@pkulchenko
Copy link
Owner

Andrew, thank you for checking...

pkulchenko added a commit to pkulchenko/serpent that referenced this pull request Jan 21, 2015
@andrewstarks
Copy link
Author

Hey Paul,

I found some more places where the conversion mattered. I made the changes in my local file, but wasn't sure if you'd like a diff or a pull request or or or...

I've been using it for a while and it seems good to go. I'm pretty sure i'm not hitting every edge case, but I'm also pretty sure that nothing new got broke, either.

Preference?

@pkulchenko
Copy link
Owner

Andrew, diff would be slightly better as I'll be merging Serpent changes along with Mobdebug changes in the same request. Thank you!

@pkulchenko pkulchenko self-assigned this Jan 22, 2015
@andrewstarks
Copy link
Author

Cool. I've never done this before (a patch file). Let me know if i didn't get it right.:

diff --git a/lualibs/mobdebug/mobdebug.lua b/lualibs/mobdebug/mobdebug.lua
index 5e2a50b..77c06a7 100644
--- a/lualibs/mobdebug/mobdebug.lua
+++ b/lualibs/mobdebug/mobdebug.lua
@@ -19,7 +19,7 @@ end)("os")

 local mobdebug = {
   _NAME = "mobdebug",
-  _VERSION = 0.611,
+  _VERSION = 0.612,
   _COPYRIGHT = "Paul Kulchenko",
   _DESCRIPTION = "Mobile Remote Debugger for the Lua programming language",
   port = os and os.getenv and tonumber((os.getenv("MOBDEBUG_PORT"))) or 8172,
@@ -127,7 +127,7 @@ end
 local function q(s) return s:gsub('([%(%)%.%%%+%-%*%?%[%^%$%]])','%%%1') end

 local serpent = (function() ---- include Serpent module for serialization
-local n, v = "serpent", 0.272 -- (C) 2012-13 Paul Kulchenko; MIT License
+local n, v = "serpent", 0.273 -- (C) 2012-13 Paul Kulchenko; MIT License
 local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
 local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
 local badtype = {thread = true, userdata = true, cdata = true}
@@ -147,8 +147,8 @@ local function s(t, opts)
   local seen, sref, syms, symn = {}, {'local '..iname..'={}'}, {}, 0
   local function gensym(val) return '_'..(tostring(tostring(val)):gsub("[^%w]",""):gsub("(%d%w+)",
     -- tostring(val) is needed because __tostring may return a non-string value
-    function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return syms[s] end)) end
-  local function safestr(s) return type(s) == "number" and (huge and snum[tostring(s)] or s)
+    function(s) if not syms[s] then symn = symn+1; syms[s] = symn end return tostring(syms[s]) end)) end
+  local function safestr(s) return type(s) == "number" and tostring(huge and snum[tostring(s)] or s)
     or type(s) ~= "string" and tostring(s) -- escape NEWLINE/010 and EOF/026
     or ("%q"):format(s):gsub("\010","n"):gsub("\026","\\026") end
   local function comment(s,l) return comm and (l or 0) < comm and ' --[['..tostring(s)..']]' or '' end
@@ -161,7 +161,7 @@ local function s(t, opts)
     return (path or '')..(plain and path and '.' or '')..safe, safe end
   local alphanumsort = type(opts.sortkeys) == 'function' and opts.sortkeys or function(k, o, n) -- k=keys, o=originaltable, n=padding
     local maxn, to = tonumber(n) or 12, {number = 'a', string = 'b'}
-    local function padnum(d) return ("%0"..maxn.."d"):format(d) end
+    local function padnum(d) return ("%0".. tostring(maxn) .."d"):format(tonumber(d)) end
     table.sort(k, function(a,b)
       -- sort numeric keys first: k[key] is not nil for numerical keys
       return (k[a] ~= nil and 0 or to[type(a)] or 'z')..(tostring(a):gsub("%d+",padnum))
@@ -203,8 +203,8 @@ local function s(t, opts)
             local sname = safename(iname, gensym(key)) -- iname is table for local variables
             sref[#sref] = val2str(key,sname,indent,sname,iname,true) end
           sref[#sref+1] = 'placeholder'
-          local path = seen[t]..'['..(seen[key] or globals[key] or gensym(key))..']'
-          sref[#sref] = path..space..'='..space..(seen[value] or val2str(value,nil,indent,path))
+          local path = seen[t]..'['..tostring(seen[key] or globals[key] or gensym(key))..']'
+          sref[#sref] = path..space..'='..space..tostring(seen[value] or val2str(value,nil,indent,path))
         else
           out[#out+1] = val2str(value,key,indent,insref,seen[t],plainindex,level+1)
         end
@@ -768,12 +768,12 @@ local function debugger_loop(sev, svars, sfile, sline)
           status, res = stringify_results(pcall(func))
         end
         if status then
-          server:send("200 OK " .. #res .. "\n")
+          server:send("200 OK " .. tostring(#res) .. "\n")
           server:send(res)
         else
           -- fix error if not set (for example, when loadstring is not present)
           if not res then res = "Unknown error" end
-          server:send("401 Error in Expression " .. #res .. "\n")
+          server:send("401 Error in Expression " .. tostring(#res) .. "\n")
           server:send(res)
         end
       else
@@ -786,7 +786,7 @@ local function debugger_loop(sev, svars, sfile, sline)
       if abort == nil then -- no LOAD/RELOAD allowed inside start()
         if size > 0 then server:receive(size) end
         if sfile and sline then
-          server:send("201 Started " .. sfile .. " " .. sline .. "\n")
+          server:send("201 Started " .. sfile .. " " .. tostring(sline) .. "\n")
         else
           server:send("200 OK 0\n")
         end
@@ -810,7 +810,7 @@ local function debugger_loop(sev, svars, sfile, sline)
               debugee = func
               coroyield("load")
             else
-              server:send("401 Error in Expression " .. #res .. "\n")
+              server:send("401 Error in Expression " .. tostring(#res) .. "\n")
               server:send(res)
             end
           else
@@ -826,9 +826,9 @@ local function debugger_loop(sev, svars, sfile, sline)
           watchescnt = watchescnt + 1
           local newidx = #watches + 1
           watches[newidx] = func
-          server:send("200 OK " .. newidx .. "\n")
+          server:send("200 OK " .. tostring(newidx) .. "\n")
         else
-          server:send("401 Error in Expression " .. #res .. "\n")
+          server:send("401 Error in Expression " .. tostring(#res) .. "\n")
           server:send(res)
         end
       else
@@ -850,13 +850,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "STEP" then
@@ -866,13 +866,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "OVER" or command == "OUT" then
@@ -887,13 +887,13 @@ local function debugger_loop(sev, svars, sfile, sline)
       local ev, vars, file, line, idx_watch = coroyield()
       eval_env = vars
       if ev == events.BREAK then
-        server:send("202 Paused " .. file .. " " .. line .. "\n")
+        server:send("202 Paused " .. file .. " " .. tostring(line) .. "\n")
       elseif ev == events.WATCH then
-        server:send("203 Paused " .. file .. " " .. line .. " " .. idx_watch .. "\n")
+        server:send("203 Paused " .. file .. " " .. tostring(line) .. " " .. tostring(idx_watch) .. "\n")
       elseif ev == events.RESTART then
         -- nothing to do
       else
-        server:send("401 Error in Execution " .. #file .. "\n")
+        server:send("401 Error in Execution " .. tostring(#file) .. "\n")
         server:send(file)
       end
     elseif command == "BASEDIR" then
@@ -922,14 +922,14 @@ local function debugger_loop(sev, svars, sfile, sline)
         ev, vars = coroyield("stack")
       end
       if ev and ev ~= events.STACK then
-        server:send("401 Error in Execution " .. #vars .. "\n")
+        server:send("401 Error in Execution " .. tostring(#vars) .. "\n")
         server:send(vars)
       else
         local ok, res = pcall(mobdebug.dump, vars, {nocode = true, sparse = false})
         if ok then
-          server:send("200 OK " .. res .. "\n")
+          server:send("200 OK " .. tostring(res) .. "\n")
         else
-          server:send("401 Error in Execution " .. #res .. "\n")
+          server:send("401 Error in Execution " .. tostring(#res) .. "\n")
           server:send(res)
         end
       end
@@ -949,7 +949,7 @@ local function debugger_loop(sev, svars, sfile, sline)
             for n = 1, #tbl do
               tbl[n] = select(2, pcall(mobdebug.line, tbl[n], {nocode = true, comment = false})) end
             local file = table.concat(tbl, "\t").."\n"
-            server:send("204 Output " .. stream .. " " .. #file .. "\n" .. file)
+            server:send("204 Output " .. stream .. " " .. tostring(#file) .. "\n" .. file)
           end
         end)
         if not default then genv.print() end -- "fake" print to start printing loop
@@ -971,7 +971,7 @@ local function connect(controller_host, controller_port)
   if not sock then return nil, err end

   if sock.settimeout then sock:settimeout(mobdebug.connecttimeout) end
-  local res, err = sock:connect(controller_host, controller_port)
+  local res, err = sock:connect(controller_host, tostring(controller_port))
   if sock.settimeout then sock:settimeout() end

   if not res then return nil, err end
@@ -1050,7 +1050,7 @@ local function controller(controller_host, controller_port, scratchpad)
   if server then
     local function report(trace, err)
       local msg = err .. "\n" .. trace
-      server:send("401 Error in Execution " .. #msg .. "\n")
+      server:send("401 Error in Execution " .. tostring(#msg) .. "\n")
       server:send(msg)
       return err
     end
@@ -1320,7 +1320,7 @@ local function handle(params, client, options)
         if not file then
            _, _, file, lines = string.find(exp, "^(%S+)%s+(.+)")
         end
-        client:send("LOAD " .. #lines .. " " .. file .. "\n")
+        client:send("LOAD " .. tostring(#lines) .. " " .. file .. "\n")
         client:send(lines)
       else
         local file = io.open(exp, "r")
@@ -1338,7 +1338,7 @@ local function handle(params, client, options)

         local file = string.gsub(exp, "\\", "/") -- convert slash
         file = removebasedir(file, basedir)
-        client:send("LOAD " .. #lines .. " " .. file .. "\n")
+        client:send("LOAD " .. tostring(#lines) .. " " .. file .. "\n")
         if #lines > 0 then client:send(lines) end
       end
       while true do

@pkulchenko
Copy link
Owner

Thanks Andrew! I have another Serpent update to include and will be merging this shortly...

pkulchenko added a commit to pkulchenko/serpent that referenced this pull request Jan 24, 2015
pkulchenko added a commit to pkulchenko/MobDebug that referenced this pull request Jan 27, 2015
@pkulchenko
Copy link
Owner

Andrew, upgraded Mobdebug with all the changes. Let me know how this works for you. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants