combine

#!/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