forked from elua/elua
-
Notifications
You must be signed in to change notification settings - Fork 1
/
mkfs.py
141 lines (127 loc) · 4.31 KB
/
mkfs.py
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# A script to convert an entire directory to a C array, in the "romfs" format
import os, sys
import re
import struct
_crtline = ' '
_numdata = 0
_bytecnt = 0
_fcnt = 0
maxlen = 30
alignment = 4
# Line output function
def _add_data( data, outfile, moredata = True ):
global _crtline, _numdata, _bytecnt, _fcnt
_bytecnt = _bytecnt + 1
_fcnt = _fcnt + 1
if moredata:
_crtline = _crtline + "0x%02X, " % data
else:
_crtline = _crtline + "0x%02X" % data
_numdata = _numdata + 1
if _numdata == 16 or not moredata:
outfile.write( _crtline + '\n' )
_crtline = ' '
_numdata = 0
# 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
def mkfs( dirname, outname, flist, mode, compcmd ):
# Try to create the output files
outfname = outname + ".h"
try:
outfile = file( outfname, "wb" )
except:
print "Unable to create output file"
return False
global _crtline, _numdata, _bytecnt, _fcnt
_crtline = ' '
_numdata = 0
_bytecnt = 0
# Generate headers
outfile.write( "// Generated by mkfs.py\n// DO NOT MODIFY\n\n" )
outfile.write( "#ifndef __%s_H__\n#define __%s_H__\n\n" % ( outname.upper(), outname.upper() ) )
outfile.write( "const unsigned char %s_fs[] = \n{\n" % ( outname.lower() ) )
# Process all files
for fname in flist:
if len( fname ) > maxlen:
print "Skipping %s (name longer than %d chars)" % ( fname, maxlen )
continue
# Get actual file name
realname = os.path.join( dirname, fname )
# Ensure it actually is a file
if not os.path.isfile( realname ):
print "Skipping %s ... (not found or not a regular file)" % fname
continue
# Try to open and read the file
try:
crtfile = file( realname, "rb" )
except:
outfile.close()
os.remove( outfname )
print "Unable to read %s" % fname
return False
# Do we need to process the file?
fextpart = ''
if mode == "compile" or mode == "compress":
fnamepart, fextpart = os.path.splitext( realname )
if mode == "compress":
newext = ".lua.tmp"
else:
newext = ".lc"
if fextpart == ".lua":
newname = fnamepart + newext
if mode == "compress":
print "Compressing %s to %s ..." % ( realname, newname )
else:
print "Cross compiling %s to %s ..." % ( realname, newname )
os.system( compcmd % ( newname, realname ) )
# TODO: this assumes that the cross compiler ended OK
crtfile.close()
try:
crtfile = file( newname, "rb" )
except:
outfile.close()
os.remove( outfname )
print "Unable to read %s" % newname
return False
if mode == "compile":
fnamepart, fextpart = os.path.splitext( fname )
fname = fnamepart + ".lc"
filedata = crtfile.read()
crtfile.close()
if fextpart == ".lua" and mode != "verbatim":
os.remove( newname )
# Write name, size, id, numpars
_fcnt = 0
for c in fname:
_add_data( ord( c ), outfile )
_add_data( 0, outfile ) # ASCIIZ
size_ll = len( filedata ) & 0xFF
size_lh = ( len( filedata ) >> 8 ) & 0xFF
size_hl = ( len( filedata ) >> 16 ) & 0xFF
size_hh = ( len( filedata ) >> 24 ) & 0xFF
# Round to a multiple of 4
while _bytecnt & ( alignment - 1 ) != 0:
_add_data( 0, outfile )
# Write size
_add_data( size_ll, outfile )
_add_data( size_lh, outfile )
_add_data( size_hl, outfile )
_add_data( size_hh, outfile )
# Then write the rest of the file
for c in filedata:
_add_data( ord( c ), outfile )
# Report
print "Encoded file %s (%d bytes real size, %d bytes encoded size)" % ( fname, len( filedata ), _fcnt )
# All done, write the final "0xFF" (terminator)
_add_data( 0xFF, outfile, False )
outfile.write( "};\n\n#endif\n" );
outfile.close()
print "Done, total size is %d bytes" % _bytecnt
return True