Я сделал свой велосипед на 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;" }