#!/usr/local/bin/lua -- Combine libraries and a main file into something executable. -- Written by Rici Lake and released into the public domain -- Use at your own risk! If you find it useful, let me know. -- If main is repeated as a module, it is not included, so you -- can write: combine main.lua *.lua -- assumes that it will find import.lua in the current directory, if -- not specify the location with the -i flag. -- If -o is not specified, output is to stdout; you can specify main as -- - to take it from stdin. In case there is any point in using this in -- a pipe. local Usage = arg[0] .. " [-i import] [-o outfile] [-x exclusion]* main [module]..." local function insist(x, err) if x then return x end io.stderr:write(err, "\n") os.exit(1) end local function usage(x) return insist(x, Usage) end local function readall(f) if type(f) == "string" then f = insist(io.open(f, "r")) end local rv = insist(f:read "*a", "Read error") f:close() return rv end -- should be a command line option, blah, blah local function basename(f) local _, _, rv = string.find(f, "/?([^/]+)$") return insist(rv, "Could not get basename for '"..f.."'") end local files, exclusions, outfile, importer, main, err = {}, {} local function exclude(fn) exclusions[fn] = true; return fn end local i = 1 while arg[i] and string.find(arg[i], "^-.") do if arg[i] == "-i" then importer = exclude(usage(arg[i + 1])) elseif arg[i] == "-o" then outfile = exclude(usage(arg[i + 1])) -- in case there's an old one elseif arg[i] == "-x" then exclude(usage(arg[i + 1])) else usage() end i = i + 2 end main = exclude(usage(arg[i])) for j = i+1, arg.n do files[arg[j]] = true end insist(not (outfile and files[outfile]), "Cowardly refusing to overwrite input file") if main == "-" then main = io.stdin else main = insist(io.open(main, "r")) end if not importer then importer = exclude "import.lua" end importer = insist(io.open(importer, "r")) if outfile then outfile = insist(io.open(outfile, "w")) else outfile = io.stdout end local sep = "\n" .. string.rep("-", 78) .. "\n" local function box(str) local len = string.len(str) if len < 72 then return sep.."--"..string.rep(" ", math.floor((74 - len) / 2)) .. str ..string.rep(" ", math.ceil((74 - len) / 2)) .."--"..sep else return sep.."--"..str..sep end end outfile:write "#!/usr/local/bin/lua\n" outfile:write [[ local _CHUNKS, _FILES = {}, {} do local loadfile_ = loadfile loadfile = function(name) if _CHUNKS[name] then return _CHUNKS[name] else return loadfile_(name) end end end ]] outfile:write(sep) outfile:write(readall(importer)) for f in pairs(files) do outfile:write(box(f), "_CHUNKS['"..basename(f).."'] = function()",sep, readall(f), sep, "end\n") end outfile:write(box("MAIN"), readall(main)) outfile:close()
Produced by TNT, the Lua-linter. TNT/0.5 Copyright (C) 2004 Rici Lake