diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | README.md (renamed from README.txt) | 0 | ||||
-rwxr-xr-x | configure | 144 | ||||
-rw-r--r-- | contrib/build-using-docker/Dockerfile | 34 | ||||
-rw-r--r-- | src/main/c/commonbase.h | 31 | ||||
-rw-r--r-- | src/main/c/deflate.c | 33 | ||||
-rw-r--r-- | src/main/c/inflate.c | 44 |
7 files changed, 233 insertions, 54 deletions
@@ -1,4 +1,5 @@ +/Makefile /build /dist /external @@ -7,28 +7,27 @@ if test -n "$BASH_VERSION"; then set -o posix; fi prefix=/usr/local exec_prefix='$(PREFIX)' bindir='$(EXEC_PREFIX)/bin' -host= +verbose=0 -main() { +main () { parseArgs "$@" - echo TODO create Makefile + printMakefile > Makefile } -printHelp() { +printHelp () { echo '' echo "Example usage: $0 --prefix /usr/local" echo '' echo 'Options:' echo ' --prefix <path> Default "/usr/local"' echo ' --bindir <path> Default "$(EXEC_PREFIX)/bin"' - echo ' --host <name> Default <empty> (Eg "x86_64-w64-mingw32")' echo '' } -parseArgs() { +parseArgs () { # See: https://stackoverflow.com/a/14203146/4415884 while test $# -gt 0 ; do case $1 in @@ -36,12 +35,141 @@ parseArgs() { --prefix) prefix="$2" shift; shift; ;; --exec_prefix) exec_prefix="$2" shift; shift; ;; --bindir) bindir="$2" shift; shift; ;; - --host) host="$2" shift; shift; ;; - *) echo "[ERROR] Unexpected argument: $1" exit 1 ;; + --verbose) verbose="$2" shift; shift; ;; + *) echo "[ERROR] Unexpected argument: $1"; exit 1 ;; esac done } +printMakefile () { + printf '\n' + printf '%s\n' 'CC=gcc' + printf '%s\n' 'RIMRAF=rm -rf' + printf '%s\n' 'MKDIRS=mkdir -p' + printf '%s\n' 'COPYTO=cp -t' + + printf '\n' + printf '%s\n' "PREFIX=$prefix" + printf '%s\n' "EXEC_PREFIX=$exec_prefix" + printf '%s\n' "BINDIR=$bindir" + + printf '\n' + printf '%s' 'PROJECT_VERSION=$(shell' + printf '%s' ' ret=$$(git describe --tags 2>/dev/null |sed -E "s;^v;;");' + printf '%s' ' if test -n "$$ret" -a -n "$$(git status --porcelain 2>/dev/null)"; then' + printf '%s' ' ret="$$ret+dirt";' + printf '%s' ' fi;' + printf '%s' ' if test -z "$$ret"; then ret=$$(date -u +0.0.0-%Y%m%d.%H%M%S); fi;' + printf '%s\n' ' echo "$$ret")' + + if test "$verbose" = "0"; then printf '\n%s\n' '.SILENT:'; fi + printf '%s\n' '.SUFFIXES:' + + printf '\n' + printf '%s' 'CFLAGS=--std=c99 -fPIC -Wall -Wextra -Werror -fmax-errors=3' + printf '%s' ' -Wno-error=unused-function -Wno-error=unused-label -Wno-error=unused-variable' + printf '%s' ' -Wno-error=unused-parameter -Wno-error=unused-const-variable' + printf '%s' ' -Wno-error=unused-but-set-variable' + printf '%s' ' -Wno-error=discarded-qualifiers -Wno-error=sign-compare -Wno-error=pointer-sign' + printf '%s' ' -Wno-error=maybe-uninitialized -Werror=implicit-fallthrough=1' + printf '%s' ' -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers' + printf '%s\n' ' -DPROJECT_VERSION=$(PROJECT_VERSION)' + + printf '\n' + printf '%s\n' 'LDFLAGS=-Wl,--no-demangle,--fatal-warnings' + + # TODO replace gnumake by $(shell if ..) + printf '\n' + printf '%s\n' 'ifndef NDEBUG' + printf '%s\n' ' CFLAGS := $(CFLAGS) -ggdb -O0 -g3' + printf '%s\n' 'else' + printf '%s\n' ' CFLAGS := $(CFLAGS) -ffunction-sections -fdata-sections -Os -s "-DNDEBUG=1"' + printf '%s\n' ' LDFLAGS := $(LDFLAGS) -Wl,--gc-sections,--as-needed -s' + printf '%s\n' 'endif' + + printf '\n' + printf '%s\n' 'INCDIRS=-Isrc/main/c' + printf '%s\n' 'LIBSDIR=' + + printf '\n' + printf '%s\n' '.PHONY: default' + printf '%s\n' 'default: link dist' + + printf '\n' + printf '%s\n' '.PHONY: link' + printf '%s' 'link:' + printf '%s' ' build/bin/deflate$(BINEXT)' + printf '%s\n' ' build/bin/inflate$(BINEXT)' + + printf '%s\n' '.PHONY: clean' + printf '%s\n' 'clean:' + printf '%s\n' ' echo "rm -rf build dist"' + printf '%s\n' ' rm -rf build dist' + + # Create synthetic entrypoints + printf '%s\n' 'build/link/%.c:' + printf '%s\n' ' echo " Gen $@"' + printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"' + printf '%s\n' ' @echo "#include \"commonbase.h\"" >> $@' + printf '%s\n' ' @echo "int main( int err, char**argv ){" >> $@' + printf '%s\n' ' @echo " err = $*(err, argv);" >> $@' + printf '%s\n' ' @echo " if( err < 0 ){ err = 0 - err; }" >> $@' + printf '%s\n' ' @echo " return (err > 127) ? 1 : err;" >> $@' + printf '%s\n' ' @echo "}" >> $@' + + printf '%s\n' 'build/link/%.o: build/link/%.c' + printf '%s\n' ' echo " CC $@"' + printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"' + printf '%s\n' ' $(CC) -c -o $@ $(CFLAGS) -Wno-implicit-function-declaration build/link/$*.c $(INCDIRS)' + + printf '\n' + printf '%s\n' 'build/obj/main/%.o: src/main/c/%.c' + printf '%s\n' ' echo " CC $@"' + printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"' + printf '%s\n' ' $(CC) -c -o $@ $^ $(CFLAGS) $(INCDIRS)' + + printf '%s' 'build/bin/deflate$(BINEXT):' + printf '%s' ' build/obj/main/deflate.o' + printf '%s\n' ' build/link/deflate_main.o' + printf '%s\n' ' @echo " LN $@"' + printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"' + printf '%s\n' ' $(CC) -o $@ $(LDFLAGS) $^ $(INCDIRS) $(LIBSDIR) -Wl,-Bdynamic -lz' + + printf '%s' 'build/bin/inflate$(BINEXT):' + printf '%s' ' build/obj/main/inflate.o' + printf '%s\n' ' build/link/inflate_main.o' + printf '%s\n' ' echo " LN $@"' + printf '%s\n' ' $(MKDIRS) "$(shell T=$@; echo $${T%/*})"' + printf '%s\n' ' $(CC) -o $@ $(LDFLAGS) $^ $(INCDIRS) $(LIBSDIR) -Wl,-Bdynamic -lz' + + printf '\n' + printf '%s\n' '.PHONY: dist' + printf '%s\n' 'dist: link' + printf '%s\n' ' echo " Package"' + printf '%s\n' ' $(RIMRAF) build/dist-* dist' + printf '%s\n' ' $(MKDIRS) dist' + # Create Executable bundle. + printf '%s\n' ' $(MKDIRS) build/dist-bin' + printf '%s\n' ' $(COPYTO) build/dist-bin README* LICENCE*' + printf '%s\n' ' $(MKDIRS) build/dist-bin/bin' + printf '%s\n' ' $(COPYTO) build/dist-bin/bin build/bin/*' + printf '%s' ' (cd build/dist-bin && find . -type f -not -name MD5SUM -exec md5sum -b {} +)' + printf '%s\n' ' > build/dist-bin/MD5SUM' + printf '%s' ' (cd build/dist-bin && tar --owner=0 --group=0' + printf '%s\n' ' -czf "../../dist/BulkLn-$(PROJECT_VERSION).tgz" *)' + printf '%s\n' ' echo "" && echo "See '\''./dist/'\'' for result." && echo ""' + printf '%s' ' if test -n "$$(git status --porcelain 2>/dev/null)"; then' + printf '%s' ' echo "[WARN ] Worktree dirty!"; sleep 2;' + printf '%s\n' ' fi' + + printf '\n' + printf '%s\n' '.PHONY: install' + printf '%s\n' 'install:' + printf '%s\n' ' $(MKDIRS) "$(BINDIR)"' + printf '%s\n' ' tar --strip-components=1 -C "$(BINDIR)" -xzf "$(shell ls dist/BulkLn-*.tgz)" -- bin' +} + + main "$@" diff --git a/contrib/build-using-docker/Dockerfile b/contrib/build-using-docker/Dockerfile new file mode 100644 index 0000000..aaca6ad --- /dev/null +++ b/contrib/build-using-docker/Dockerfile @@ -0,0 +1,34 @@ + +ARG PARENT_IMAGE=alpine:3.16.0 +FROM $PARENT_IMAGE + +ARG GIT_TAG= +ARG CONFIGURE_OPTS= +ARG PKGS_TO_INSTALL="curl gcc git make musl-dev tar zlib-dev" +ARG PKGINIT=true +ARG PKGADD="apk add" +ARG PKGDEL="apk del" +ARG PKGCLEAN=true + +WORKDIR /work + +RUN true \ + && $PKGINIT \ + && $PKGADD $PKGS_TO_INSTALL \ + && git clone http://git.hiddenalpha.ch/DeflateAndInflate.git . \ + && git config advice.detachedHead false \ + && if test -n "$GIT_TAG"; then git checkout "$GIT_TAG"; fi \ + && ./configure $CONFIGURE_OPTS \ + && make clean && make && make install \ + && find . -not -wholename './dist*' -delete \ + && find /work -exec chown 1000:1000 {} + \ + && $PKGDEL $PKGS_TO_INSTALL \ + && $PKGCLEAN \ + && true + +USER 1000:1000 + +# run for max 10 hrs. Because this container is not meant to stay running +# forever. +CMD ["sleep 36000"] + diff --git a/src/main/c/commonbase.h b/src/main/c/commonbase.h new file mode 100644 index 0000000..581bf54 --- /dev/null +++ b/src/main/c/commonbase.h @@ -0,0 +1,31 @@ + +/* common config. Stuff like feature-test-macros for example */ + +#define _POSIX_C_SOURCE 200809L + +#define STR_QUOT_IAHGEWIH(s) #s +#define STR_QUOT(s) STR_QUOT_IAHGEWIH(s) + +#define STR_CAT(a, b) a ## b + +#ifndef likely +# define likely(a) (a) +#endif +#ifndef unlikely +# define unlikely(a) (a) +#endif + +#ifdef _WIN32 +# define WINDOOF 1 +#endif + + +#if WINDOOF +static inline void fixBrokenStdio( void ){ + _setmode(_fileno(stdin), O_BINARY); + _setmode(_fileno(stdout), O_BINARY); +} +#else +# define fixBrokenStdio() +#endif + diff --git a/src/main/c/deflate.c b/src/main/c/deflate.c index 9043c10..f1e761b 100644 --- a/src/main/c/deflate.c +++ b/src/main/c/deflate.c @@ -1,6 +1,8 @@ /* - See "./inflate.c" for bash helpers. + QuickNDirty bash equivalent: + + bash-deflate(){ gzip -c | tail -c +10; } */ @@ -10,16 +12,14 @@ #include <assert.h> #include <errno.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> /* libs */ -#include "zlib.h" - -/* project */ -#include "string-util.h" -#include "log.h" +#include <zlib.h> +typedef unsigned char uchar; /* TODO rm */ typedef struct Deflate Deflate; @@ -48,7 +48,7 @@ static void printHelp( void ){ static int parseArgs( int argc, char**argv, Deflate*deflateCls ){ deflateCls->level = Z_DEFAULT_COMPRESSION; deflateCls->useZlibHdr = 0; - for( uint i=1 ; i<argc ; ++i ){ + for( int i = 1 ; i < argc ; ++i ){ char *arg = argv[i]; if( !strcmp(arg,"--help") ){ printHelp(); return -1; @@ -75,7 +75,6 @@ static int parseArgs( int argc, char**argv, Deflate*deflateCls ){ static int doDeflate( Deflate*deflateCls ){ int err; z_stream strm; - long tmpLong; uchar innBuf[65536]; const int innBuf_cap = sizeof innBuf; int innBuf_len = 0, innBuf_off = 0; @@ -94,7 +93,7 @@ static int doDeflate( Deflate*deflateCls ){ err = deflateInit(&strm, deflateCls->level); if( err != Z_OK ){ - LOG_ERROR("deflateInit(): (ret=%d): %s", err, strerror(errno)); + fprintf(stderr, "Error: deflateInit(): (ret=%d): %s", err, strerror(errno)); return -1; } @@ -103,9 +102,7 @@ static int doDeflate( Deflate*deflateCls ){ /* input */ { int space = innBuf_cap - innBuf_len; /* look if we can shift */ - //LOG_DEBUG("space=%d\n", space); if( space <= 0 && innBuf_off > 0 ){ - //LOG_DEBUG("do shifting\n"); int wr = 0, rd = innBuf_off; for(;;){ err = rd - wr; /* chunk length to copy */ @@ -118,7 +115,6 @@ static int doDeflate( Deflate*deflateCls ){ innBuf_len -= innBuf_off; innBuf_off = 0; space = innBuf_cap - innBuf_len; - //LOG_DEBUG("space=%d (after shift)\n", space); } if( space > 0 && !inputIsEOF ){ err = fread(innBuf + innBuf_len, 1, space, stdin); @@ -126,7 +122,7 @@ static int doDeflate( Deflate*deflateCls ){ if( feof(stdin) ){ inputIsEOF = !0; }else{ - LOG_ERROR("fread(): %s", strerror(errno)); + fprintf(stderr, "Error: fread(): %s", strerror(errno)); return -1; } } @@ -142,14 +138,13 @@ static int doDeflate( Deflate*deflateCls ){ strm.next_out = outBuf; strm.avail_out = outBuf_cap; assert(strm.avail_out > 0); - //LOG_DEBUG("avail_in=%d, inputIsEOF=%d\n", strm.avail_in, inputIsEOF); assert(strm.avail_in > 0 || inputIsEOF); err = deflate(&strm, inputIsEOF ? Z_FINISH : Z_NO_FLUSH); if(unlikely( err != Z_OK )){ if( err == Z_STREAM_END ){ outputIsEOF = !0; }else{ - LOG_ERROR("deflate(): %s\n", strm.msg); + fprintf(stderr, "Error: deflate(): %s\n", strm.msg); return -1; } } @@ -168,7 +163,7 @@ static int doDeflate( Deflate*deflateCls ){ } err = fwrite(outBuf + outBuf_off, 1, outBuf_len - outBuf_off, stdout); if(unlikely( err != outBuf_len - outBuf_off )){ - LOG_ERROR("fwrite(): %s\n", strerror(errno)); + fprintf(stderr, "Error: fwrite(): %s\n", strerror(errno)); return -1; } outBuf_len = 0; @@ -177,7 +172,8 @@ static int doDeflate( Deflate*deflateCls ){ err = deflateEnd(&strm); if( err != Z_OK ){ - LOG_WARN("deflateEnd() ret=%d: %s\n", err, strm.msg); + fprintf(stderr, "Warn: deflateEnd() ret=%d: %s\n", err, strm.msg); + return -2; } return 0; @@ -192,8 +188,7 @@ int deflate_main( int argc, char**argv ){ err = parseArgs(argc, argv, deflateCls); if( err < 0 ){ return err; } - stdinModeBinary(); - stdoutModeBinary(); + fixBrokenStdio(); err = doDeflate(deflateCls); if( err < 0 ){ return err; } diff --git a/src/main/c/inflate.c b/src/main/c/inflate.c index 67ddb71..437cfd4 100644 --- a/src/main/c/inflate.c +++ b/src/main/c/inflate.c @@ -1,6 +1,5 @@ /* - bash-deflate(){ gzip -c | tail -c +10; } bash-inflate(){ (printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00"&&cat -)|gzip -dc; } */ @@ -16,11 +15,8 @@ /* libs */ #include "zlib.h" -/* project */ -#include "log.h" -#include "string-util.h" - +typedef unsigned char uchar; /* TODO cleanup */ typedef struct MyInflate MyInflate; @@ -47,7 +43,7 @@ static void printHelp( void ){ static int parseArgs( int argc, char**argv, MyInflate*myInflate ){ myInflate->tryParseHeaders = !0; /* enabled by default */ - for( uint i=1 ; i<argc ; ++i ){ + for( int i = 1 ; i < argc ; ++i ){ char *arg = argv[i]; if( !strcmp(arg,"--help") ){ printHelp(); return -1; @@ -88,7 +84,7 @@ static int doInflate( MyInflate*myInflate ){ // Pass special 2nd arg. See "https://codeandlife.com/2014/01/01/unzip-library-for-c/" err = inflateInit2(&strm, -MAX_WBITS); if( err != Z_OK ){ - LOG_ERROR("inflateInit() ret=%d: %s", err, strerror(errno)); + fprintf(stderr, "Error: inflateInit() ret=%d: %s", err, strerror(errno)); return -1; } @@ -98,7 +94,6 @@ static int doInflate( MyInflate*myInflate ){ int space = innBuf_cap - innBuf_len; /* look if we can shift */ if( space <= 0 && innBuf_off > 0 ){ - //LOG_DEBUG("try-shift space=%d, innBuf_off=%d\n", space, innBuf_off); int wr = 0, rd = innBuf_off; for(;;){ err = rd - wr; /* chunk length to copy */ @@ -111,17 +106,14 @@ static int doInflate( MyInflate*myInflate ){ innBuf_len -= innBuf_off; innBuf_off = 0; space = innBuf_cap - innBuf_len; - //LOG_DEBUG("after shift space=%d, innBuf_off=%d, innBuf_len=%d\n", space, innBuf_off, innBuf_len); } if( space > 0 && !inputIsEOF ){ - //LOG_TRACE("go read space=%d, inputIsEOF=%d\n", space, inputIsEOF); err = fread(innBuf + innBuf_len, 1, space, stdin); - //LOG_TRACE("fread() -> %d\n", err); if(unlikely( err <= 0 )){ if( feof(stdin) ){ inputIsEOF = !0; }else{ - LOG_ERROR("fread(): %s", strerror(errno)); + fprintf(stderr, "Error: fread(): %s", strerror(errno)); return -1; } } @@ -133,13 +125,16 @@ static int doInflate( MyInflate*myInflate ){ if(unlikely( !headerIsPassed )){ #define avail (innBuf_len - innBuf_off) /* Ensure we have at least two bytes for zlib header detection */ - if( avail < 2 && !inputIsEOF ){ LOG_DEBUG("Not enough data for header detection. have" - " %d\n", avail); continue; } + if( avail < 2 && !inputIsEOF ){ + #ifndef NDEBUG + fprintf(stderr, "[DEBUG] Not enough data for header detection. have %d\n", avail); + #endif + continue; + } headerIsPassed = !0; if( myInflate->tryParseHeaders ){ int b0 = innBuf[0], b1 = innBuf[1]; if( b0 == 0x78 && (b1 == 0x01 || b1 == 0x5E || b1 == 0x9C || b1 == 0xDA) ){ - //LOG_DEBUG("looks like a zlib header. Skip it\n"); innBuf_off += 2; } } @@ -154,27 +149,25 @@ static int doInflate( MyInflate*myInflate ){ // TODO remove assert(strm.avail_in >= 0 || inputIsEOF); assert(strm.avail_out > 0); int flush = inputIsEOF ? Z_FINISH : Z_NO_FLUSH; - //LOG_DEBUG("inflate(in=0x%p, inLen=%d, %s)\n", strm.next_in, strm.avail_in, - // (flush==Z_FINISH) ? "Z_FINISH" : (flush==Z_FULL_FLUSH) ? "Z_FULL_FLUSH" : "Z_NO_FLUSH"); errno = 0; err = inflate(&strm, flush); if(unlikely( err != Z_OK )){ if( err == Z_STREAM_END ){ - //LOG_DEBUG("inflate() -> Z_STREAM_END\n"); outputIsEOF = !0; }else if( err == Z_BUF_ERROR ){ /* Could not make any progress. Have to call again with updated buffers */ noProgressSince += 1; if( noProgressSince > 42 ){ - LOG_WARN("inflate() -> Z_BUF_ERROR: %s (maybe EOF came too early?)\n", + fprintf(stderr, "Warn: inflate() -> Z_BUF_ERROR: %s (maybe EOF came too early?)\n", (strm.msg == NULL) ? "Could not make any progress" : strm.msg); return -1; } }else if( strm.msg != NULL || errno ){ - LOG_ERROR("inflate(): %s\n", (strm.msg != NULL) ? strm.msg : strerror(errno)); + fprintf(stderr, "Error: inflate(): %s\n", (strm.msg != NULL) ? strm.msg : + strerror(errno)); return -1; }else{ - LOG_ERROR("inflate(): -> %d\n", err); + fprintf(stderr, "Error: inflate(): -> %d\n", err); return -1; } }else{ @@ -183,14 +176,12 @@ static int doInflate( MyInflate*myInflate ){ innBuf_off += strm.next_in - innBuf; outBuf_len = strm.next_out - outBuf; if( innBuf_off > innBuf_len ){ innBuf_off = innBuf_len; } - //LOG_DEBUG("strm.remain=%d, outputIsEOF=%d\n", innBuf_len - innBuf_off, outputIsEOF); } /* output */ { err = fwrite(outBuf, 1, outBuf_len, stdout); - //LOG_DEBUG("fwrite(0x%p, 1, %d, stdout) -> %d\n", outBuf, outBuf_len, err); if(unlikely( err != outBuf_len )){ - LOG_ERROR("fwrite(): %s\n", strerror(errno)); + fprintf(stderr, "Errro: fwrite(): %s\n", strerror(errno)); return -1; } outBuf_len = 0; @@ -199,7 +190,7 @@ static int doInflate( MyInflate*myInflate ){ err = inflateEnd(&strm); if( err != Z_OK ){ - LOG_WARN("inflateEnd() ret=%d: %s\n", err, strm.msg); + fprintf(stderr, "Warn: inflateEnd() ret=%d: %s\n", err, strm.msg); } return 0; @@ -215,8 +206,7 @@ int inflate_main( int argc, char**argv ){ err = parseArgs(argc, argv, myInflate); if( err < 0 ){ return err; } - stdinModeBinary(); - stdoutModeBinary(); + fixBrokenStdio(); err = doInflate(myInflate); if( err < 0 ){ return err; } |