luapre.lua 2.25 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
local FILE_SEP = "/"
local PACK_SEP = "."
local PATH_PAT = FILE_SEP.."$"

local Options = {
	luapath = ".",
	output  = "out.loh",
	prefix  = "",
}

local Alias = {
	l = "luapath",
	o = "output",
	p = "prefix",
}

function adjustpath(path)
	if string.find(path, PATH_PAT)
		then return path
		else return path..FILE_SEP
	end
end

function processargs(arg)
	local i = 1
	if not arg then
		io.stderr:write("usage: luapre.lua [options] <scripts>")
	end
	while arg[i] do
		local opt = string.match(arg[i], "^%-(.+)$")
		if not opt then break end
		
		opt = Alias[opt] or opt
		local opkind = type(Options[opt])
		if opkind == "boolean" then
			Options[opt] = true
		elseif opkind == "number" then
			i = i + 1
			Options[opt] = tonumber(arg[i])
		elseif opkind == "string" then
			i = i + 1
			Options[opt] = arg[i]
		elseif opkind == "table" then
			i = i + 1
			table.insert(Options[opt], arg[i])
		else
			io.stderr:write("unknown option ", opt)
		end
		i = i + 1
	end
	
	return i, table.getn(arg)
end

function getname(file)
	local name = file:match("(.+)%..+")
	if name:find("init$") then
		name = name:sub(1, -6)
	end
	return name:gsub(FILE_SEP, PACK_SEP)
end

--------------------------------------------------------------------------------

local start, finish = processargs(arg)

Options.luapath = adjustpath(Options.luapath)

local output = assert(io.open(Options.output, "w"))

output:write([[
/* code automatically generated by luapre.lua -- DO NOT EDIT */
{
]])

for i = start, finish do local file = arg[i]
	local bytecodes = string.dump(assert(loadfile(Options.luapath..file)))
	output:write("/* ",file," */\n")
	output:write("static const unsigned char B",i-start,"[]={\n")
	for index = 1, string.len(bytecodes) do
  	output:write(string.format("%3u,", string.byte(bytecodes, index)))
		if math.fmod(index, 20) == 0 then output:write("\n") end
  end
	output:write("\n};\n\n")
end

output:write([[
lua_getfield(L, LUA_GLOBALSINDEX, "package");
lua_getfield(L, -1, "preload");
]])

for index = start, finish do local file = arg[index]
	local i = index - start
	local module = Options.prefix..getname(file)
	output:write([[
luaL_loadbuffer(L,(const char*)B]],i,[[,sizeof(B]],i,[[),"]],file,[[");
lua_setfield(L, -2, "]],module,[[");
]])
end

output:write([[
lua_pop(L, 2);
}
]])

output:close()