Advertisement
Oeed

Compilr

Nov 9th, 2014
750
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.15 KB | None | 0 0
  1. local file = [[--  Hideously Smashed Together by Compilr, a Hideous Smash-Stuff-Togetherer, (c) 2014 oeed  --
  2.  
  3. --  This file REALLLLLLLY isn't suitable to be used for anything other than being executed --
  4.  
  5. --  To extract all the files, run: "<filename> --extract" in the Shell --
  6. ]]
  7.  
  8. local files = {}
  9.  
  10. local function addFolder(path, tree)
  11.   for i, v in ipairs(fs.list(path)) do
  12.     local subPath = path .. '/' .. v
  13.     if v == '.DS_Store' or v == '.git' or subPath == '/rom' or subPath == '/build' or subPath == '/'..shell.getRunningProgram() then
  14.     elseif fs.isDir(subPath) then
  15.       tree[v] = {}
  16.       addFolder(subPath, tree[v])
  17.     else
  18.       local h = fs.open(subPath, 'r')
  19.       if h then
  20.         tree[v] = h.readAll()
  21.         h.close()
  22.       end
  23.     end
  24.   end
  25. end
  26.  
  27. addFolder('', files)
  28.  
  29. if not files['startup'] then
  30.   error('You must have a file called startup to be executed at runtime.')
  31. end
  32.  
  33. file = file .. 'local files = ' .. textutils.serialize(files) .. '\n'
  34.  
  35. file = file .. [[
  36.  
  37. local function run(tArgs)
  38.  
  39.   local fnFile, err = loadstring(files['startup'], 'startup')
  40.   if err then
  41.     error(err)
  42.   end
  43.  
  44.   local function split(str, pat)
  45.      local t = {}
  46.      local fpat = "(.-)" .. pat
  47.      local last_end = 1
  48.      local s, e, cap = str:find(fpat, 1)
  49.      while s do
  50.         if s ~= 1 or cap ~= "" then
  51.      table.insert(t,cap)
  52.         end
  53.         last_end = e+1
  54.         s, e, cap = str:find(fpat, last_end)
  55.      end
  56.      if last_end <= #str then
  57.         cap = str:sub(last_end)
  58.         table.insert(t, cap)
  59.      end
  60.      return t
  61.   end
  62.  
  63.   local function resolveTreeForPath(path, single)
  64.     local _files = files
  65.     local parts = split(path, '/')
  66.     if parts then
  67.       for i, v in ipairs(parts) do
  68.         if #v > 0 then
  69.           if _files[v] then
  70.             _files = _files[v]
  71.           else
  72.             _files = nil
  73.             break
  74.           end
  75.         end
  76.       end
  77.     elseif #path > 0 and path ~= '/' then
  78.       _files = _files[path]
  79.     end
  80.     if not single or type(_files) == 'string' then
  81.       return _files
  82.     end
  83.   end
  84.  
  85.   local oldFs = fs
  86.   local env
  87.   env = {
  88.     fs = {
  89.       list = function(path)
  90.               local list = {}
  91.               if fs.exists(path) then
  92.             list = fs.list(path)
  93.               end
  94.         for k, v in pairs(resolveTreeForPath(path)) do
  95.           if not fs.exists(path .. '/' ..k) then
  96.             table.insert(list, k)
  97.           end
  98.         end
  99.         return list
  100.       end,
  101.  
  102.       exists = function(path)
  103.         if fs.exists(path) then
  104.           return true
  105.         elseif resolveTreeForPath(path) then
  106.           return true
  107.         else
  108.           return false
  109.         end
  110.       end,
  111.  
  112.       isDir = function(path)
  113.         if fs.isDir(path) then
  114.           return true
  115.         else
  116.           local tree = resolveTreeForPath(path)
  117.           if tree and type(tree) == 'table' then
  118.             return true
  119.           else
  120.             return false
  121.           end
  122.         end
  123.       end,
  124.  
  125.       isReadOnly = function(path)
  126.         if not fs.isReadOnly(path) then
  127.           return false
  128.         else
  129.           return true
  130.         end
  131.       end,
  132.  
  133.       getName = fs.getName,
  134.  
  135.       getSize = fs.getSize,
  136.  
  137.       getFreespace = fs.getFreespace,
  138.  
  139.       makeDir = fs.makeDir,
  140.  
  141.       move = fs.move,
  142.  
  143.       copy = fs.copy,
  144.  
  145.       delete = fs.delete,
  146.  
  147.       combine = fs.combine,
  148.  
  149.       open = function(path, mode)
  150.         if fs.exists(path) then
  151.           return fs.open(path, mode)
  152.         elseif type(resolveTreeForPath(path)) == 'string' then
  153.           local handle = {close = function()end}
  154.           if mode == 'r' then
  155.             local content = resolveTreeForPath(path)
  156.             handle.readAll = function()
  157.               return content
  158.             end
  159.  
  160.             local line = 1
  161.             local lines = split(content, '\n')
  162.             handle.readLine = function()
  163.               if line > #lines then
  164.                 return nil
  165.               else
  166.                 return lines[line]
  167.               end
  168.               line = line + 1
  169.             end
  170.                       return handle
  171.           else
  172.             error('Cannot write to read-only file (compilr archived).')
  173.           end
  174.         else
  175.           return fs.open(path, mode)
  176.         end
  177.       end
  178.     },
  179.  
  180.     io = {
  181.       input = io.input,
  182.       output = io.output,
  183.       type = io.type,
  184.       close = io.close,
  185.       write = io.write,
  186.       flush = io.flush,
  187.       lines = io.lines,
  188.       read = io.read,
  189.       open = function(path, mode)
  190.         if fs.exists(path) then
  191.           return io.open(path, mode)
  192.         elseif type(resolveTreeForPath(path)) == 'string' then
  193.           local content = resolveTreeForPath(path)
  194.           local f = fs.open(path, 'w')
  195.           f.write(content)
  196.           f.close()
  197.           if mode == 'r' then
  198.             return io.open(path, mode)
  199.           else
  200.             error('Cannot write to read-only file (compilr archived).')
  201.           end
  202.         else
  203.           return io.open(path, mode)
  204.         end
  205.       end
  206.     },
  207.  
  208.     loadfile = function( _sFile )
  209.         local file = env.fs.open( _sFile, "r" )
  210.         if file then
  211.             local func, err = loadstring( file.readAll(), fs.getName( _sFile ) )
  212.             file.close()
  213.             return func, err
  214.         end
  215.         return nil, "File not found: ".._sFile
  216.     end,
  217.  
  218.     dofile = function( _sFile )
  219.         local fnFile, e = env.loadfile( _sFile )
  220.         if fnFile then
  221.             setfenv( fnFile, getfenv(2) )
  222.             return fnFile()
  223.         else
  224.             error( e, 2 )
  225.         end
  226.     end
  227.   }
  228.  
  229.   setmetatable( env, { __index = _G } )
  230.  
  231.   local tAPIsLoading = {}
  232.   env.os.loadAPI = function( _sPath )
  233.       local sName = fs.getName( _sPath )
  234.       if tAPIsLoading[sName] == true then
  235.           printError( "API "..sName.." is already being loaded" )
  236.           return false
  237.       end
  238.       tAPIsLoading[sName] = true
  239.          
  240.       local tEnv = {}
  241.       setmetatable( tEnv, { __index = env } )
  242.       local fnAPI, err = env.loadfile( _sPath )
  243.       if fnAPI then
  244.           setfenv( fnAPI, tEnv )
  245.           fnAPI()
  246.       else
  247.           printError( err )
  248.           tAPIsLoading[sName] = nil
  249.           return false
  250.       end
  251.      
  252.       local tAPI = {}
  253.       for k,v in pairs( tEnv ) do
  254.           tAPI[k] =  v
  255.       end
  256.      
  257.       env[sName] = tAPI    
  258.       tAPIsLoading[sName] = nil
  259.       return true
  260.   end
  261.  
  262.   env.shell = shell
  263.  
  264.   setfenv( fnFile, env )
  265.   fnFile(unpack(tArgs))
  266. end
  267.  
  268. local function extract()
  269.     local function node(path, tree)
  270.         if type(tree) == 'table' then
  271.             fs.makeDir(path)
  272.             for k, v in pairs(tree) do
  273.                 node(path .. '/' .. k, v)
  274.             end
  275.         else
  276.             local f = fs.open(path, 'w')
  277.             if f then
  278.                 f.write(tree)
  279.                 f.close()
  280.             end
  281.         end
  282.     end
  283.     node('', files)
  284. end
  285.  
  286. local tArgs = {...}
  287. if #tArgs == 1 and tArgs[1] == '--extract' then
  288.   extract()
  289. else
  290.   run(tArgs)
  291. end
  292. ]]
  293.  
  294. fs.delete('/build')
  295. local h = fs.open('/build', 'w')
  296. h.write(file)
  297. h.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement