Я сделал свой велосипед на awk. Ни о чём не жалею:
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้
# Written for gawk
# Invocation
# Windows: gawk -v BINMODE=1 -f makefsdata.awk file1 file2 ... > fsdata.c
# Linux: LC_ALL=C gawk -f makefsdata.awk file1 file2 ... > fsdata.c
BEGIN {
RS = "$^"
FS = "[^0-9]"
srand()
"svnversion -c" | getline
revnum = (length($2) > 0 ? $2 : $1)
RND = length(revnum) ? RND : 1;
dir = "/" (RND ? int(999998 * rand() + 1) : revnum) "/"
for (i = 0; i < 256; i++) {
TAB256 = TAB256 sprintf("%c", i)
}
contyp["html"] = "text/html; charset=utf-8"
contyp["shtml"] = "text/html; charset=utf-8"
contyp["css"] = "text/css; charset=utf-8"
contyp["gif"] = "image/gif"
contyp["png"] = "image/png"
contyp["js"] = "text/javascript; charset=utf-8"
contyp["json"] = "application/json; charset=utf-8"
contyp["txt"] = "text/plain; charset=utf-8"
prev = "root_redirect"
print "#include \"lwip/apps/fs.h\""
print ""
print "static const char fdata_root_redirect[] __attribute__((section(\".fdata\"))) ="
print "\"HTTP/1.1 303 See Other\\r\\n\""
print "\"Location: " dir "index.html\\r\\n\\r\\n\";"
print ""
print "static const struct fsdata_file " prev " = {"
print " .next = 0,"
print " .name = \"/index.html\","
print " .data = fdata_root_redirect,"
print " .len = sizeof fdata_root_redirect - 1,"
print " .flags = FS_FILE_FLAGS_HEADER_INCLUDED"
print "};"
print ""
}
function prhdr(h) {
print "\"" h "\\r\\n\""
}
{
match(FILENAME, /([^\/]*)$/)
split(substr(FILENAME, RSTART), tmp, ".")
fbase = tmp[1]
ext = tmp[2]
gz = (tmp[3] == "gz")
cached = ext ~ /^(html|css|gif|png|js)$/
ssi = ext == "shtml" ? fbase !~ /^(204|404)$/ : ext ~ /^(json|txt)$/;
print "static const char fdata_" fbase "_" ext "[] __attribute__((section(\".fdata\"))) ="
if (fbase ~ /^[0-9]+$/) {
# headers already included in file
printf "\"";
} else {
prhdr("HTTP/1.1 200 OK")
prhdr("Content-Type: " contyp[ext])
gz && prhdr("Content-Encoding: gzip")
ext == "json" && prhdr("Access-Control-Allow-Origin: *")
prhdr("Cache-Control: " (cached ? "public, max-age=604800, immutable" : "no-store, max-age=0"))
prhdr("")
printf "\""
}
left = length($0)
i = 0
while (left > 0) {
if (i > 0 && i % 16 == 0)
{
print "\""
printf "\""
}
printf "\\x%02X", index(TAB256, substr($0, i + 1, 1)) - 1
i++
left--
}
print "\";"
print ""
varname = "file_" fbase "_" ext
print "static const struct fsdata_file " varname " = {"
print " .next = &" prev ","
print " .name = \"" (cached ? dir : "/") fbase "." ext "\","
print " .data = fdata_" fbase "_" ext ","
print " .len = sizeof fdata_" fbase "_" ext " - 1,"
print " .flags = FS_FILE_FLAGS_HEADER_INCLUDED" (ssi ? " | FS_FILE_FLAGS_SSI" : "")
print "};"
print ""
prev = varname
}
END {
print "static const struct fsdata_file* const FS_ROOT = 0;"
print "const struct fsdata_file* const fsroot = &" prev ";"
print "const char fsrootdir[] = \"" dir "\";"
print "const int fsrootdirlen = sizeof fsrootdir - 1;"
}