Advertisement
Xetrill

LuaCheck.lua

Dec 11th, 2013
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.12 KB | None | 0 0
  1. -- uses the lua command line compiler to check the syntax of a lua file
  2. -- formats the output so as to MS DevStudio can understand the output
  3. -- and jump to the next error line
  4. --
  5. -- how to make it work?
  6. --
  7. -- just set up a new Tool (Tools/Customize/Tools) with the following options:
  8. -- Command                   : lua.exe
  9. -- Arguments                 : -f LuaCheck.lua "$(FilePath)"
  10. -- Initial directory : c:\lua (or wherever your lua.exe is located)
  11. -- Use Output Window : (checked)
  12. --
  13. -- After that, you can add a keyboard shortcut for this tool:
  14. -- (Tools/Customize/Tools) (select from Category: Tools, then from
  15. -- Commands: UserToolX (where X is the number of the newly defined tool)
  16. -- then assign a new key to it...
  17. --
  18. -- Have Fun!
  19. -- Peter Prade
  20.  
  21. function string.ends(s, p)
  22.    return s == "" or s:sub(-p:len()) == p
  23. end
  24.  
  25. function printf(fmt, ...)
  26.     if ... == nil then
  27.         print(fmt)
  28.     else
  29.         print(fmt:format(...))
  30.     end
  31. end
  32.  
  33. function sprintf(fmt, ...)
  34.     return fmt:format(...)
  35. end
  36.  
  37. -- from shell.lua, by Peter Odding
  38. function escape(...)
  39.     local command = type(...) == 'table' and ... or { ... }
  40.     for i, s in ipairs(command) do
  41.         s = (tostring(s) or ''):gsub('"', '\\"')
  42.         if s:find('[^A-Za-z0-9_."/-]') then
  43.             s = '"' .. s .. '"'
  44.         elseif s == '' then
  45.             s = '""'
  46.         end
  47.         command[i] = s
  48.     end
  49.     return table.concat(command, ' ')
  50. end
  51.  
  52. -- get argument - the file name
  53. local file, cwd, fullpath
  54. if arg and #arg > 0 then
  55.     fullpath = escape(arg[1])
  56.  
  57.     if #arg >= 2 then
  58.         file = arg[1]:sub(arg[2]:len() + 2)
  59.         cwd  = arg[2]
  60.     else
  61.         file = arg[1]
  62.         local cd = io.popen("cd")
  63.         cwd = cd:read('*l')
  64.         cd:close()
  65.     end
  66.  
  67.     if not string.ends(file, ".lua") and not string.ends(file, ".script") then
  68.         print("warning: file has invalid extension!")
  69.         os.exit(-1)
  70.     elseif string.ends(file, "lua_help.script") then
  71.         print("skipping: 'lua_help.script'")
  72.         os.exit(-2)
  73.     end
  74.     -- for i = 0, #arg do
  75.     --  printf("\targ[%d] = `%s'", i, arg[i])
  76.     -- end
  77. end
  78. -- printf("full: `%s'", fullpath)
  79. -- printf("file: `%s'", file)
  80. -- printf("cwd:  `%s'", cwd)
  81.  
  82. function readfile(path)
  83.     assert(type(path) == 'string')
  84.     local file, errmsg = io.open(path, 'r')
  85.     if not file then
  86.         error(errmsg)
  87.     end
  88.     local data = file:read('*a')
  89.     file:close()
  90.     return data
  91.     -- if h == nil then
  92.     --  h = io.input()
  93.     -- elseif type(h) == "string" then
  94.     --  h = io.open(h, 'r')
  95.     --  if h == nil then
  96.     --      print("error: failed to open LuaCheck.log")
  97.     --      os.exit(-4)
  98.     --  end
  99.     -- end
  100.     -- local s = ""
  101.     -- for line in h:lines() do
  102.     --  s = sprintf("%s%s\n", s, line)
  103.     -- end
  104.     -- h:close()
  105.     -- return s
  106. end
  107.  
  108. function tfind(t, s)
  109.     local i, v
  110.     for i, v in ipairs(t) do
  111.         if v == s then
  112.             return i
  113.         end
  114.     end
  115. end
  116.  
  117. function tadd(t, v)
  118.     if not tfind(t, v) then
  119.         table.insert(t, v)
  120.     end
  121. end
  122.  
  123. -- reformat errors so that visual studio understands them:
  124. function outputerror(msg, last, line, file)
  125.     printf("%s(%d): error: %s", file, line, msg)
  126.     string.gsub(msg, "%((.-) at line (.-)%)%;$", function(msg, line)
  127.         printf("%s(%d): error: ... %s", file, line, msg)
  128.     end)
  129.     printf("%s(%d): error: %s", file, line, last)
  130. end
  131.  
  132. -- format list of globals nicely:
  133. function printnice(t)
  134.     local n = #t
  135.     local l = n - 1
  136.     for i, v in ipairs(t) do
  137.         print(v)
  138.  
  139.         if i < l then
  140.             print(", ")
  141.         elseif i < n then
  142.             print(" and ")
  143.         end
  144.  
  145.         if math.fmod(i, 5) ~= 0 then
  146.             print("\n")
  147.         end
  148.     end
  149.     if math.fmod(i, 5) ~= 0 then
  150.         print("\n")
  151.     end
  152. end
  153.  
  154. if file then -- check the specified file:
  155.     printf("LuaCheck: `%s'", file)
  156.  
  157.     -- local luacExePath = escape(os.getenv('LUA_DEV') .. '\\luac.exe')
  158.     local luacExePath = escape('%LUA_DEV%\\luac.exe')
  159.  
  160.     local outFilePath     = '%TEMP%\\LuaCheck.out'
  161.     local logFilePath     = '%TEMP%\\LuaCheck.log'
  162.     local logFileFullPath = os.getenv('TEMP') .. '\\LuaCheck.log'
  163.  
  164.     -- local logFilePath     = 'LuaCheck.log'
  165.     -- local logFileFullPath = 'LuaCheck.log'
  166.  
  167.     local shellCommand = sprintf(
  168.         '"%s -o %s -p %s 2>%s"',
  169.         luacExePath,
  170.         outFilePath,
  171.         fullpath,
  172.         logFilePath
  173.     )
  174.  
  175. -- printf("\nlog: `%s'", logFilePath)
  176. -- printf("lua: `%s'", luacExePath)
  177. -- printf("\ncmd: `%s'\n", shellCommand)
  178.     local shellResult  = os.execute(shellCommand)
  179.  
  180.     local _, errorCount = string.gsub(
  181.         readfile(logFileFullPath),
  182.         "luac%:(.-)\n   (last token read: `.-') at line (.-) in file `(.-)'",
  183.         outputerror
  184.     )
  185.     errorCount = tonumber(errorCount)
  186.     printf("%d syntax error(s) found.", errorCount)
  187.  
  188.     shellResult = errorCount
  189.  
  190.     if errorCount == 0 then
  191.         shellCommand = sprintf(
  192.             '"%s -o %s -l %s >%s"',
  193.             luacExePath,
  194.             outFilePath,
  195.             fullpath,
  196.             logFilePath
  197.         )
  198.  
  199. -- printf("\ncmd: `%s'\n", shellCommand)
  200.         shellResult = os.execute(shellCommand)
  201.  
  202.         names_set = {}
  203.         string.gsub(
  204.             readfile(logFileFullPath),
  205.             "%d+    %[%d+%] SETGLOBAL       %d+ ; (.-)\n",
  206.             function(name)
  207.                 tadd(names_set, name)
  208.             end
  209.         )
  210.  
  211.         if #names_set > 0 then
  212.             table.sort(names_set)
  213.             printf("%d global variable(s) are created in the file: ", #names_set)
  214.             printnice(names_set)
  215.         end
  216.     end
  217.  
  218.     os.remove(outFilePath)
  219.     os.remove(logFilePath)
  220.  
  221.     os.exit(shellResult)
  222. else
  223.     print("error: no file to scan specified")
  224.     os.exit(-3)
  225. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement