#!/usr/bin/env lua -- Copyright (C) 2008-2009 Matthew Wild -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. 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(""..escape_html(arg[1]).."\n
\n"); for line in io.lines(arg[1]) do line = " "..line:gsub("%s", html_spaces).." "; line = line:gsub("FIXME:?", "%1"); line = line:gsub("TODO:?", "%1"); line = line:gsub("%-%-.*$", "%1"); line = line:gsub("\".-[^\\]\"", "%1"); 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"..escape_html(op.comment).."%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), "."..escape_html(id)..""); end end else --print("??", tostring(op.comment), tostring(#op.comment)); end end line = line:gsub("[%w_]+", function (id) if keywords[id] then return ""..id..""; end end); local classes = { "line" }; if test_coverage and test_coverage[linenum] ~= nil then table.insert(classes, "test-"..test_coverage[linenum]); end print(""); else line = line:gsub("[%w_]+", function (id) if keywords[id] then return ""..id..""; end end); print(""); end linenum = linenum + 1; end print("
"..linenum.."", line, "
"..linenum.."", line, "
\n\n");