Created
March 9, 2013 22:18
-
-
Save davidm/5126010 to your computer and use it in GitHub Desktop.
globalsplus.lua for DetectingUndefinedVariables
This file contains hidden or 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
-- globalsplus.lua | |
-- Like globals.lua in Lua 5.1.4 but records fields in global tables too. | |
-- Probably works but not well tested. Could be extended even further. | |
-- | |
-- usage: luac -p -l example.lua | lua globalsplus.lua | |
-- | |
-- D.Manura, 2010-07, public domain | |
local function parse(line) | |
local idx,linenum,opname,arga,argb,extra = | |
line:match('^%s+(%d+)%s+%[(%d+)%]%s+(%w+)%s+([-%d]+)%s+([-%d]+)%s*(.*)') | |
if idx then | |
idx = tonumber(idx) | |
linenum = tonumber(linenum) | |
arga = tonumber(arga) | |
argb = tonumber(argb) | |
end | |
local argc, const | |
if extra then | |
local extra2 | |
argc, extra2 = extra:match('^([-%d]+)%s*(.*)') | |
if argc then argc = tonumber(argc); extra = extra2 end | |
end | |
if extra then | |
const = extra:match('^; (.+)') | |
end | |
return {idx=idx,linenum=linenum,opname=opname,arga=arga,argb=argb,argc=argc,const=const} | |
end | |
local function getglobals(fh) | |
local globals = {} | |
local last | |
for line in fh:lines() do | |
local data = parse(line) | |
if data.opname == 'GETGLOBAL' then | |
data.gname = data.const | |
last = data | |
table.insert(globals, {linenum=last.linenum, name=data.const, isset=false}) | |
elseif data.opname == 'SETGLOBAL' then | |
last = data | |
table.insert(globals, {linenum=last.linenum, name=data.const, isset=true}) | |
elseif (data.opname == 'GETTABLE' or data.opname == 'SETTABLE') and last and | |
last.gname and last.idx == data.idx-1 and last.arga == data.arga and data.const | |
then | |
local const = data.const:match('^"(.*)"') | |
if const then | |
data.gname = last.gname .. '.' .. const | |
last = data | |
table.insert(globals, {linenum=last.linenum, name=data.gname, isset=data.opname=='SETTABLE'}) | |
end | |
else | |
last = nil | |
end | |
end | |
return globals | |
end | |
local function rindex(t, name) | |
for part in name:gmatch('%w+') do | |
t = t[part] | |
if t == nil then return nil end | |
end | |
return t | |
end | |
local whitelist = _G | |
local globals = getglobals(io.stdin) | |
table.sort(globals, function(a,b) return a.linenum < b.linenum end) | |
for i,v in ipairs(globals) do | |
local found = rindex(whitelist, v.name) | |
print(v.linenum, v.name, v.isset and 'set' or 'get', found and 'defined' or 'undefined') | |
end |
This file contains hidden or 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
luac -p -l test/sieve.lua | lua globalsplus.lua | |
5 gen set undefined | |
6 coroutine.wrap get defined | |
6 coroutine get defined | |
7 coroutine get defined | |
7 coroutine.yield get defined | |
12 filter set undefined | |
13 coroutine get defined | |
13 coroutine.wrap get defined | |
17 math get defined | |
17 math.mod get defined | |
17 coroutine get defined | |
17 coroutine.yield get defined | |
22 N set undefined | |
22 N get undefined | |
23 gen get undefined | |
23 x set undefined | |
23 N get undefined | |
25 x get undefined | |
27 print get defined | |
28 filter get undefined | |
28 x set undefined | |
28 x get undefined |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment