mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
141 lines
4.6 KiB
Lua
141 lines
4.6 KiB
Lua
-- A module to convert an entire directory to a C array, in the "romfs" format
|
|
module( ..., package.seeall )
|
|
require "pack"
|
|
local sf = string.format
|
|
local b = require "utils.build"
|
|
local utils = b.utils
|
|
|
|
local _crtline = ' '
|
|
local _numdata = 0
|
|
local _bytecnt = 0
|
|
local maxlen = 30
|
|
local outfile
|
|
|
|
-- Line output function
|
|
local function _add_data( data, outfile, moredata )
|
|
if moredata == nil then moredata = true end
|
|
_bytecnt = _bytecnt + 1
|
|
if moredata then
|
|
_crtline = _crtline .. sf( "0x%02X, ", data )
|
|
else
|
|
_crtline = _crtline .. sf( "0x%02X", data )
|
|
end
|
|
_numdata = _numdata + 1
|
|
if _numdata == 16 or not moredata then
|
|
outfile:write( _crtline .. '\n' )
|
|
_crtline = ' '
|
|
_numdata = 0
|
|
end
|
|
end
|
|
|
|
-- dirname - the directory where the files are located.
|
|
-- outname - the name of the C output
|
|
-- flist - list of files
|
|
-- mode - preprocess the file system:
|
|
-- "verbatim" - copy the files directly to the FS as they are
|
|
-- "compile" - precompile all files to Lua bytecode and then copy them
|
|
-- "compress" - keep the source code, but compress it with LuaSrcDiet
|
|
-- compcmd - the command to use for compiling if "mode" is "compile"
|
|
-- Returns true for OK, false for error
|
|
function mkfs( dirname, outname, flist, mode, compcmd )
|
|
-- Try to create the output files
|
|
local outfname = outname .. ".h"
|
|
outfile = io.open( outfname, "wb" )
|
|
if not outfile then
|
|
print "Unable to create output file"
|
|
return false
|
|
end
|
|
|
|
_crtline = ' '
|
|
_numdata = 0
|
|
_bytecnt = 0
|
|
|
|
-- Generate headers
|
|
outfile:write( "// Generated by mkfs.lua\n// DO NOT MODIFY\n\n" )
|
|
outfile:write( sf( "#ifndef __%s_H__\n#define __%s_H__\n\n", outname:upper(), outname:upper() ) )
|
|
|
|
outfile:write( sf( "const unsigned char %s_fs[] = \n{\n", outname:lower() ) )
|
|
|
|
-- Process all files
|
|
for _, fname in pairs( flist ) do
|
|
if #fname > maxlen then
|
|
print( sf( "Skipping %s (name longer than %d chars)", fname, maxlen ) )
|
|
else
|
|
-- Get actual file name
|
|
local realname = dirname .. utils.dir_sep .. fname
|
|
-- Ensure it actually is a file
|
|
if not utils.is_file( realname ) then
|
|
print( sf( "Skipping %s ... (not found or not a regular file)", fname ) )
|
|
else
|
|
-- Try to open and read the file
|
|
local crtfile = io.open( realname, "rb" )
|
|
if not crtfile then
|
|
outfile:close()
|
|
os.remove( outfname )
|
|
print( sf( "Unable to read %s", fname ) )
|
|
return false
|
|
end
|
|
-- Do we need to process the file?
|
|
local fextpart, fnamepart = ''
|
|
if mode == "compile" or mode == "compress" then
|
|
fnamepart, fextpart = utils.split_path( realname )
|
|
local newext = mode == "compress" and ".lua.tmp" or ".lc"
|
|
if fextpart == ".lua" then
|
|
newname = fnamepart .. newext
|
|
if mode == "compress" then
|
|
print( sf( "Compressing %s to %s ...", realname, newname ) )
|
|
else
|
|
print( sf( "Cross compiling %s to %s ...", realname, newname ) )
|
|
end
|
|
if os.execute( sf( compcmd, newname, realname ) ) ~= 0 then
|
|
print "Cross-compilation error, aborting"
|
|
outfile:close()
|
|
crtfile:close()
|
|
return false
|
|
end
|
|
crtfile:close()
|
|
crtfile = io.open( newname, "rb" )
|
|
if not crtfile then
|
|
outfile:close()
|
|
os.remove( outfname )
|
|
print( sf( "Unable to read %s", newname ) )
|
|
return false
|
|
end
|
|
if mode == "compile" then
|
|
fnamepart, fextpart = utils.split_path( fname )
|
|
fname = fnamepart .. ".lc"
|
|
end
|
|
end
|
|
end
|
|
local filedata = crtfile:read( '*a' )
|
|
crtfile:close()
|
|
if fextpart == ".lua" and mode ~= "verbatim" then
|
|
os.remove( newname )
|
|
end
|
|
-- Write name, size, id, numpars
|
|
for i = 1, #fname do
|
|
_add_data( fname:byte( i ), outfile )
|
|
end
|
|
_add_data( 0, outfile ) -- ASCIIZ
|
|
local plen = string.pack( "<h", #filedata )
|
|
_add_data( plen:byte( 1 ), outfile )
|
|
_add_data( plen:byte( 2 ), outfile )
|
|
-- Then write the rest of the file
|
|
for i = 1, #filedata do
|
|
_add_data( filedata:byte( i ), outfile )
|
|
end
|
|
-- Report
|
|
print( sf( "Encoded file %s (%d bytes)", fname, #filedata ) )
|
|
end
|
|
end
|
|
end
|
|
|
|
-- All done, write the final "0" (terminator)
|
|
_add_data( 0, outfile, false )
|
|
outfile:write( "};\n\n#endif\n" );
|
|
outfile:close()
|
|
print( sf( "Done, total size is %d bytes", _bytecnt ) )
|
|
return true
|
|
end
|
|
|