Fri, 13 Nov 2009 16:24:48 +0000
Initial commit
lua2html.lua | file | annotate | diff | comparison | revisions |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lua2html.lua Fri Nov 13 16:24:48 2009 +0000 @@ -0,0 +1,111 @@ + +local keywords = { "function", "for", "if", "elseif", "then", "else", "do", "repeat", "until", "end", "return", "true", "false", "and", "not", "or", "local", "nil", "break" } +for _, keyword in ipairs(keywords) do keywords[keyword] = true; end + +local ops = {}; + +local bytelisting, err = io.popen("luac -l -p "..arg[1]); +if not bytelisting then print(err); return 1; end + +for line in bytelisting:lines() do + local opnum, linenum, opname, comments = line:match("^\t(%d+)%s*%[(%d+)%]%s*(%u+)[^;]*;? ?(.*)$"); + if opnum then + linenum = tonumber(linenum); +-- print(string.format("opnum: %d line: %d op: %s ; %s", opnum, linenum, opname, comments)); + if not ops[linenum] then + ops[linenum] = { }; + if ops[linenum-1] then + table.sort(ops[linenum-1], function (a,b) return a.comment and b.comment and #a.comment > #b.comment; end); + end + end + table.insert(ops[linenum], { name = opname, comment = comments }); + end +end + +local test_coverage = {}; + +local test_report, test_report_err = io.open("tests/reports/coverage_"..arg[1]:gsub("^%W", ""):gsub("%W+", "_")..".report"); +if test_report then + for line in test_report:lines() do + local f, linenum, test, success = line:match("^(.-)|(.-)|(.-)|(.-)$"); + if linenum and success then + test_coverage[tonumber(linenum)] = success; + else + io.stderr:write("Warning: Can't parse this: [[", line, "]] in test report\n"); + end + end +else + test_coverage = nil; +end + + + +local linenum = 1; +local html_spaces = { ["\t"] = " ", [" "] = " " }; +function escape_html(s) + return (s and s:gsub("[^%w]", { ["<"] = "<", [">"] = ">", ["&"] = "&", ["\""] = """, ["'"] = "'" })) or ""; +end + +function escape_pattern(s) + return s:gsub("(%p)", "%%%1"); +end + +local sub; + +print("<html><head><title>"..escape_html(arg[1]).."</title><style type='text/css'>"); +print [[ + .getglobal { color:#cc0000 !important; text-decoration:underline; } + .setglobal { color:#ff0000; font-weight:bold; text-decoration:underline; } + .getupval { color:#00cc00; } + .nop { color:#cccccc; } + .keyword { color:#0000cc; } + .comment, .comment .keyword { color:#007733; } + .string, .string * { color:#007755; } + + td .test-false, .test-false { background-color:#ffa6be !important; display:block; width:100%; } + td .test-true, .test-true { background-color:#beffa6; display:block; width:100%; } + td .test-miss, .test-miss { background-color:#a6beff; display:block; width:100%; } + + table { border-collapse: collapse; } + span, tr, *, table { padding:2px; } + td { padding:0px; padding-right:2em; } +]] +print("</style></head><body>\n<br/>\n<table>"); +for line in io.lines(arg[1]) do + line = " "..line:gsub("%s", html_spaces).." "; + line = line:gsub("FIXME:?", "<b>%1</b>"); + line = line:gsub("TODO:?", "<b>%1</b>"); + line = line:gsub("%-%-.*$", "<span class='comment'>%1</span>"); + line = line:gsub("\".-[^\\]\"", "<span class='string'>%1</span>"); + if ops[linenum] then + for _, op in pairs(ops[linenum]) do + if op.comment and #op.comment > 0 and op.name ~= "JMP" then + --print("Replacing "..escape_pattern(op.comment).."("..op.comment..") for "..op.name); + line, sub = line:gsub("([^%w_])("..escape_pattern(op.comment)..")([^%w_])", "%1<span class='"..op.name:lower().."'>"..escape_html(op.comment).."</span>%3"); + if sub == 0 and op.name == "GETTABLE" then + --print("Trying again..."); + local id = op.comment:match("[%w_]+"); + if id then + --print("Got "..id); + line = line:gsub(escape_pattern("."..id), ".<span class='"..op.name:lower().."'>"..escape_html(id).."</span>"); + end + end + else + --print("??", tostring(op.comment), tostring(#op.comment)); + end + end + line = line:gsub("[%w_]+", function (id) if keywords[id] then return "<span class='keyword'>"..id.."</span>"; end end); + local classes = { "line" }; + + if test_coverage and test_coverage[linenum] ~= nil then + table.insert(classes, "test-"..test_coverage[linenum]); + end + print("<tr><td><span class='"..table.concat(classes, " ").."'>"..linenum.."</span></td><td>", line, "</td></tr>"); + else + line = line:gsub("[%w_]+", function (id) if keywords[id] then return "<span class='keyword'>"..id.."</span>"; end end); + print("<tr><td><span class='line nop'>"..linenum.."</span></td><td>", line, "</td></tr>"); + end + linenum = linenum + 1; +end + +print("</table>\n</body>\n</html>");