add xxd functionality to espfstool

master
Ondřej Hruška 2 years ago
parent c9b6fd5491
commit b60d333f69
  1. 48
      Makefile
  2. 88
      fstool/main.c

@ -6,22 +6,27 @@ DEBUG = 1
PLATFORM ?= POSIX # POSIX or ARM 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 DEMO_TARGET = ./spritehttpd-demo
FSTOOL_TARGET = ./espfstool # Note: keep ./ here so it can be called when building 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 all: demo lib fstool
demo: $(DEMO_TARGET) demo: $(DEMO_TARGET)
lib: $(LIB_TARGET) lib: $(LIB_TARGET)
fstool: $(FSTOOL_TARGET) fstool: $(FSTOOL_TARGET)
# -*- Tools -*-
# hex dump tool # -*- Tools -*-
XXD ?= xxd
HOST_CC = gcc HOST_CC = gcc
@ -43,6 +48,7 @@ GIT_HASH = $(shell git rev-parse --short HEAD)
# These flags are used by all targets # These flags are used by all targets
COMMON_CFLAGS = -Wall -Wextra -Werror \ COMMON_CFLAGS = -Wall -Wextra -Werror \
-Wshadow -Wfloat-equal -Wundef -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wwrite-strings -Wunreachable-code -Wconversion -Winit-self \ -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 -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 # The final binary linker should use -Wl,--gc-sections to take advantage of -ffunction-sections and -fdata-sections
@ -61,8 +67,6 @@ endif
# -*- Library -*- # -*- Library -*-
LIB_DIR = spritehttpd
LIB_SOURCES = \ LIB_SOURCES = \
lib/espfs/espfs.c \ lib/espfs/espfs.c \
lib/heatshrink/heatshrink_decoder.c \ lib/heatshrink/heatshrink_decoder.c \
@ -99,14 +103,13 @@ LIB_CFLAGS += $(addprefix -I$(LIB_DIR)/, $(LIB_INCLUDE_DIRS))
$(LIB_TARGET): $(LIB_OBJS) $(LIB_TARGET): $(LIB_OBJS)
$(AR) rcs $@ $^ $(AR) rcs $@ $^
# -*- Demo -*-
DEMO_DIR = demo # -*- Demo -*-
# these won't have dir prefix added - they can refer to other dirs # these won't have dir prefix added - they can refer to other dirs
DEMO_SOURCES = \ DEMO_SOURCES = \
$(DEMO_DIR)/server_demo.c \ $(DEMO_DIR)/server_demo.c \
$(DEMO_DIR)/staticfiles.embed.c $(DEMO_DIR)/staticfiles.bin.c
DEMO_INCLUDE_DIRS = \ DEMO_INCLUDE_DIRS = \
$(DEMO_DIR) \ $(DEMO_DIR) \
@ -121,25 +124,24 @@ DEMO_OBJS = $(DEMO_SOURCES:.c=.o)
DEMO_STATIC_FILES := $(addprefix $(DEMO_DIR)/staticfiles/, $(DEMO_STATIC_FILES)) DEMO_STATIC_FILES := $(addprefix $(DEMO_DIR)/staticfiles/, $(DEMO_STATIC_FILES))
DEMO_CFLAGS += $(addprefix -I, $(DEMO_INCLUDE_DIRS)) 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 # 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 # Show content of the image
$(FSTOOL_TARGET) -p $@ $(FSTOOL_TARGET) -p demo/staticfiles.bin
demo/staticfiles.embed.c: demo/staticfiles.bin
# Dump the FS image to a C file
$(XXD) -i -n espfs_image $< $@
$(DEMO_TARGET): $(DEMO_SOURCES) $(LIB_TARGET) $(DEMO_TARGET): $(DEMO_SOURCES) $(LIB_TARGET)
$(CC) $(DEMO_CFLAGS) $(DEMO_SOURCES) \ $(CC) $(DEMO_CFLAGS) $(DEMO_SOURCES) \
-o $@ \ -o $@ -l$(LIBBASENAME) -L.
-lspritehttpd -L.
# FS builder
FSTOOL_DIR = fstool # -*- FS builder -*-
FSTOOL_SOURCES = \ FSTOOL_SOURCES = \
$(FSTOOL_DIR)/main.c \ $(FSTOOL_DIR)/main.c \

@ -370,6 +370,8 @@ int main(int argc, char **argv)
int c; int c;
char *outfile = NULL; char *outfile = NULL;
char *c_outfile = NULL;
char *c_varname = NULL;
char *parseFile = NULL; char *parseFile = NULL;
char *stripPath = NULL; char *stripPath = NULL;
char *extractFile = NULL; char *extractFile = NULL;
@ -386,12 +388,14 @@ int main(int argc, char **argv)
{"gzip-exts", required_argument, 0, 'g'}, {"gzip-exts", required_argument, 0, 'g'},
{"input", required_argument, 0, 'i'}, {"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'}, {"output", required_argument, 0, 'o'},
{"c-output", required_argument, 0, 'C'},
{"c-varname", required_argument, 0, 'N'},
{"strip-path", required_argument, 0, 'S'}, {"strip-path", required_argument, 0, 'S'},
{"help", no_argument, 0, 'h'}, {"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); long_options, &option_index);
if (c == -1) { if (c == -1) {
break; break;
@ -417,6 +421,14 @@ int main(int argc, char **argv)
extractFile = strdup(optarg); extractFile = strdup(optarg);
break; break;
case 'C':
c_outfile = strdup(optarg);
break;
case 'N':
c_varname = strdup(optarg);
break;
case 'S': case 'S':
stripPath = strdup(optarg); stripPath = strdup(optarg);
break; break;
@ -463,7 +475,7 @@ int main(int argc, char **argv)
} }
FILE *outfp = NULL; FILE *outfp = NULL;
if (outfile) { if (outfile && 0 != strcmp("-", outfile)) {
fprintf(stderr, "Writing to %s\n", outfile); fprintf(stderr, "Writing to %s\n", outfile);
outfp = fopen(outfile, "w+"); outfp = fopen(outfile, "w+");
if (!outfp) { if (!outfp) {
@ -473,6 +485,10 @@ int main(int argc, char **argv)
s_outFd = fileno(outfp); s_outFd = fileno(outfp);
ftruncate(s_outFd, 0); ftruncate(s_outFd, 0);
} else { } else {
if (outfile) {
free(outfile);
outfile = NULL;
}
fprintf(stderr, "Writing to stdout\n\n"); fprintf(stderr, "Writing to stdout\n\n");
} }
@ -540,6 +556,34 @@ int main(int argc, char **argv)
fsync(s_outFd); fsync(s_outFd);
if (outfp) { 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); fclose(outfp);
} }
@ -547,19 +591,35 @@ int main(int argc, char **argv)
show_help: show_help:
// ##########**********##########**********##########----------$$$$$$$$$$----------$$$$$$$$$$----------| 80 chars
fprintf(stderr, "%s - Program to create espfs images\n", argv[0]); fprintf(stderr, "%s - Program to create espfs images\n", argv[0]);
fprintf(stderr, "Options:\n"); 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, "[-p|--parse FILE]\n"
fprintf(stderr, "[-e|--extract FILE]\n Extract a file with the given name from the parsed file (-p)\n"); " Parse an espfs file and show a list of its contents. No other options apply in this mode.\n");
fprintf(stderr, "[-S|--strip-path PATH]\n Remove the given path from input file names before packing\n"); fprintf(stderr, "[-e|--extract FILE]\n"
fprintf(stderr, "[-c|--compress COMPRESSOR]\n 0 - None, 1 - Heatshrink (default)\n"); " Extract a file with the given name from the parsed file (-p)\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, "[-S|--strip-path PATH]\n"
fprintf(stderr, "[-z|--gzip]\n use gzip for files with extensions matching "DEFAULT_GZIP_EXTS"\n"); " Remove the given path from input file names before packing\n");
fprintf(stderr, "[-G|--gzip-all]\n use gzip for all files\n"); fprintf(stderr, "[-c|--compress COMPRESSOR]\n"
fprintf(stderr, "[-g|--gzip-exts GZIPPED_EXTENSIONS]\n use gzip for files with custom extensions, comma-separated\n"); " 0 - None, 1 - Heatshrink (default)\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, "[-l|--level LEVEL] or [-0 through -9]\n"
fprintf(stderr, "[-o|--output FILE]\n Output file name; if not specified, outputs to stdout\n"); " compression level 1-9, higher is better but uses more RAM\n");
fprintf(stderr, "[-h|--help\n Show help.\n\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); exit(err);
} }

Loading…
Cancel
Save