From b60d333f6900e7693f2cc482d863eccc2a050d56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sat, 28 Jan 2023 19:26:01 +0100 Subject: [PATCH] add xxd functionality to espfstool --- Makefile | 48 ++++++++++++++-------------- fstool/main.c | 88 +++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index 6d0006c..3666d44 100644 --- a/Makefile +++ b/Makefile @@ -6,22 +6,27 @@ DEBUG = 1 PLATFORM ?= POSIX # POSIX or ARM -# -*- Target names -*- +# -*- Target names & dirs -*- -LIB_TARGET = ./libspritehttpd.a +LIBBASENAME = spritehttpd +LIB_TARGET = ./lib$(LIBBASENAME).a DEMO_TARGET = ./spritehttpd-demo FSTOOL_TARGET = ./espfstool # Note: keep ./ here so it can be called when building demo -# Handy targets +LIB_DIR = spritehttpd +DEMO_DIR = demo +FSTOOL_DIR = fstool + + +# -*- Shurtcut targets -*- + all: demo lib fstool demo: $(DEMO_TARGET) lib: $(LIB_TARGET) fstool: $(FSTOOL_TARGET) -# -*- Tools -*- -# hex dump tool -XXD ?= xxd +# -*- Tools -*- HOST_CC = gcc @@ -43,6 +48,7 @@ GIT_HASH = $(shell git rev-parse --short HEAD) # These flags are used by all targets COMMON_CFLAGS = -Wall -Wextra -Werror \ -Wshadow -Wfloat-equal -Wundef -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wwrite-strings -Wunreachable-code -Wconversion -Winit-self \ + -Wnull-dereference -Winfinite-recursion \ -std=gnu99 -DGIT_HASH='"$(GIT_HASH)"' -ffunction-sections -fdata-sections # The final binary linker should use -Wl,--gc-sections to take advantage of -ffunction-sections and -fdata-sections @@ -61,8 +67,6 @@ endif # -*- Library -*- -LIB_DIR = spritehttpd - LIB_SOURCES = \ lib/espfs/espfs.c \ lib/heatshrink/heatshrink_decoder.c \ @@ -99,14 +103,13 @@ LIB_CFLAGS += $(addprefix -I$(LIB_DIR)/, $(LIB_INCLUDE_DIRS)) $(LIB_TARGET): $(LIB_OBJS) $(AR) rcs $@ $^ -# -*- Demo -*- -DEMO_DIR = demo +# -*- Demo -*- # these won't have dir prefix added - they can refer to other dirs DEMO_SOURCES = \ $(DEMO_DIR)/server_demo.c \ - $(DEMO_DIR)/staticfiles.embed.c + $(DEMO_DIR)/staticfiles.bin.c DEMO_INCLUDE_DIRS = \ $(DEMO_DIR) \ @@ -121,25 +124,24 @@ DEMO_OBJS = $(DEMO_SOURCES:.c=.o) DEMO_STATIC_FILES := $(addprefix $(DEMO_DIR)/staticfiles/, $(DEMO_STATIC_FILES)) DEMO_CFLAGS += $(addprefix -I, $(DEMO_INCLUDE_DIRS)) -demo/staticfiles.bin: $(FSTOOL_TARGET) $(DEMO_STATIC_FILES) +demo/staticfiles.bin.c: $(FSTOOL_TARGET) $(DEMO_STATIC_FILES) # Create the FS image - $(FSTOOL_TARGET) -c1 -g jpg --strip-path demo/staticfiles -o $@ $(DEMO_STATIC_FILES) + $(FSTOOL_TARGET) \ + --compress=1 \ + --gzip-exts=jpg \ + --output=demo/staticfiles.bin \ + --c-output=demo/staticfiles.bin.c \ + --strip-path=demo/staticfiles \ + $(DEMO_STATIC_FILES) # Show content of the image - $(FSTOOL_TARGET) -p $@ - -demo/staticfiles.embed.c: demo/staticfiles.bin - # Dump the FS image to a C file - $(XXD) -i -n espfs_image $< $@ + $(FSTOOL_TARGET) -p demo/staticfiles.bin $(DEMO_TARGET): $(DEMO_SOURCES) $(LIB_TARGET) $(CC) $(DEMO_CFLAGS) $(DEMO_SOURCES) \ - -o $@ \ - -lspritehttpd -L. - + -o $@ -l$(LIBBASENAME) -L. -# FS builder -FSTOOL_DIR = fstool +# -*- FS builder -*- FSTOOL_SOURCES = \ $(FSTOOL_DIR)/main.c \ diff --git a/fstool/main.c b/fstool/main.c index 414e722..07f8d09 100644 --- a/fstool/main.c +++ b/fstool/main.c @@ -370,6 +370,8 @@ int main(int argc, char **argv) int c; char *outfile = NULL; + char *c_outfile = NULL; + char *c_varname = NULL; char *parseFile = NULL; char *stripPath = NULL; char *extractFile = NULL; @@ -386,12 +388,14 @@ int main(int argc, char **argv) {"gzip-exts", required_argument, 0, 'g'}, {"input", required_argument, 0, 'i'}, {"output", required_argument, 0, 'o'}, + {"c-output", required_argument, 0, 'C'}, + {"c-varname", required_argument, 0, 'N'}, {"strip-path", required_argument, 0, 'S'}, {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} + { /* end marker */ } }; - c = getopt_long(argc, argv, "c:l:g:zGS:e:hp:i:o:0123456789", + c = getopt_long(argc, argv, "c:l:g:zGS:e:hp:C:i:o:0123456789", long_options, &option_index); if (c == -1) { break; @@ -417,6 +421,14 @@ int main(int argc, char **argv) extractFile = strdup(optarg); break; + case 'C': + c_outfile = strdup(optarg); + break; + + case 'N': + c_varname = strdup(optarg); + break; + case 'S': stripPath = strdup(optarg); break; @@ -463,7 +475,7 @@ int main(int argc, char **argv) } FILE *outfp = NULL; - if (outfile) { + if (outfile && 0 != strcmp("-", outfile)) { fprintf(stderr, "Writing to %s\n", outfile); outfp = fopen(outfile, "w+"); if (!outfp) { @@ -473,6 +485,10 @@ int main(int argc, char **argv) s_outFd = fileno(outfp); ftruncate(s_outFd, 0); } else { + if (outfile) { + free(outfile); + outfile = NULL; + } fprintf(stderr, "Writing to stdout\n\n"); } @@ -540,6 +556,34 @@ int main(int argc, char **argv) fsync(s_outFd); if (outfp) { + if (outfile && c_outfile) { + const size_t imagelen = (size_t) lseek(s_outFd, 0, SEEK_END); + lseek(s_outFd, 0, SEEK_SET); + + FILE *coutf = fopen(c_outfile, "w+"); + if (!coutf) { + perror(c_outfile); + return 1; + } + int cfd = fileno(coutf); + ftruncate(cfd, 0); + + if (!c_varname) { + c_varname = strdup("espfs_image"); + } + + fprintf(coutf, "unsigned char %s[%lu] = {", c_varname, imagelen); + for (size_t i = 0; i < imagelen; i++) { + fprintf(coutf, (i % 16) ? " " : "\n "); + uint8_t u; + read(s_outFd, &u, 1); + fprintf(coutf, "0x%02x,", u); + } + fprintf(coutf, "\n};\nunsigned int %s_len = %lu;\n", c_varname, imagelen); + fsync(cfd); + fclose(coutf); + } + fclose(outfp); } @@ -547,19 +591,35 @@ int main(int argc, char **argv) show_help: + // ##########**********##########**********##########----------$$$$$$$$$$----------$$$$$$$$$$----------| 80 chars fprintf(stderr, "%s - Program to create espfs images\n", argv[0]); fprintf(stderr, "Options:\n"); - fprintf(stderr, "[-p|--parse FILE]\n Parse an espfs file and show a list of its contents. No other options apply in this mode.\n"); - fprintf(stderr, "[-e|--extract FILE]\n Extract a file with the given name from the parsed file (-p)\n"); - fprintf(stderr, "[-S|--strip-path PATH]\n Remove the given path from input file names before packing\n"); - fprintf(stderr, "[-c|--compress COMPRESSOR]\n 0 - None, 1 - Heatshrink (default)\n"); - fprintf(stderr, "[-l|--level LEVEL] or [-0 through -9]\n compression level 1-9, higher is better but uses more RAM\n"); - fprintf(stderr, "[-z|--gzip]\n use gzip for files with extensions matching "DEFAULT_GZIP_EXTS"\n"); - fprintf(stderr, "[-G|--gzip-all]\n use gzip for all files\n"); - fprintf(stderr, "[-g|--gzip-exts GZIPPED_EXTENSIONS]\n use gzip for files with custom extensions, comma-separated\n"); - fprintf(stderr, "[-i|--input FILE]\n Input file, can be multiple. Files can also be passed at the end without -i, or as lines on stdin if not specified by args\n"); - fprintf(stderr, "[-o|--output FILE]\n Output file name; if not specified, outputs to stdout\n"); - fprintf(stderr, "[-h|--help\n Show help.\n\n"); + fprintf(stderr, "[-p|--parse FILE]\n" + " Parse an espfs file and show a list of its contents. No other options apply in this mode.\n"); + fprintf(stderr, "[-e|--extract FILE]\n" + " Extract a file with the given name from the parsed file (-p)\n"); + fprintf(stderr, "[-S|--strip-path PATH]\n" + " Remove the given path from input file names before packing\n"); + fprintf(stderr, "[-c|--compress COMPRESSOR]\n" + " 0 - None, 1 - Heatshrink (default)\n"); + fprintf(stderr, "[-l|--level LEVEL] or [-0 through -9]\n" + " compression level 1-9, higher is better but uses more RAM\n"); + fprintf(stderr, "[-z|--gzip]\n" + " use gzip for files with extensions matching "DEFAULT_GZIP_EXTS"\n"); + fprintf(stderr, "[-G|--gzip-all]\n" + " use gzip for all files\n"); + fprintf(stderr, "[-g|--gzip-exts GZIPPED_EXTENSIONS]\n" + " use gzip for files with custom extensions, comma-separated\n"); + fprintf(stderr, "[-i|--input FILE]\n" + " Input file, can be multiple. Files can also be passed at the end without -i, or as lines on stdin\n" + " if not specified by args\n"); + fprintf(stderr, "[-o|--output FILE]\n" + " Output file name; if not specified or equal to \"-\", outputs to stdout\n"); + fprintf(stderr, "[-C|--c-output FILE]\n" + " C embed output file name (an uint8_t array for embedding); can be used only if a binary output\n" + " file is specified as well (using -o), as this reads the output file and converts it as a second step.\n"); + fprintf(stderr, "[-h|--help\n" + " Show help.\n\n"); exit(err); }