diff options
author | Yann Collet <yann.collet.73@gmail.com> | 2015-06-28 20:25:10 (GMT) |
---|---|---|
committer | Yann Collet <yann.collet.73@gmail.com> | 2015-06-28 20:25:10 (GMT) |
commit | 48feb909ddd2e3c151d0f9ea1a402f6b575c0bec (patch) | |
tree | c6a4f9c5bce6a2cfff2482825cb8a2fd3b54c063 | |
parent | baf78e7e4dcbdf824a76f990ffeb573d113bbbdb (diff) | |
parent | 57e14d4c178ca90588b1a1a12f235995cc868276 (diff) | |
download | lz4-48feb909ddd2e3c151d0f9ea1a402f6b575c0bec.zip lz4-48feb909ddd2e3c151d0f9ea1a402f6b575c0bec.tar.gz lz4-48feb909ddd2e3c151d0f9ea1a402f6b575c0bec.tar.bz2 |
Merge pull request #129 from Cyan4973/dev
Dev
-rw-r--r-- | .travis.yml | 4 | ||||
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | README.md | 23 | ||||
-rw-r--r-- | cmake_unofficial/CMakeLists.txt | 11 | ||||
-rw-r--r-- | contrib/djgpp/LICENSE | 24 | ||||
-rw-r--r-- | contrib/djgpp/Makefile | 130 | ||||
-rw-r--r-- | contrib/djgpp/README.MD | 21 | ||||
-rw-r--r-- | examples/.gitignore | 8 | ||||
-rw-r--r-- | examples/Makefile | 13 | ||||
-rw-r--r-- | examples/frameCompress.c | 169 | ||||
-rw-r--r-- | lib/Makefile | 4 | ||||
-rw-r--r-- | lib/README.md | 12 | ||||
-rw-r--r-- | lib/lz4.h | 2 | ||||
-rw-r--r-- | lib/xxhash.h | 33 | ||||
-rw-r--r-- | programs/.gitignore | 2 | ||||
-rw-r--r-- | programs/fuzzer.c | 6 | ||||
-rw-r--r-- | programs/lz4.1 | 2 | ||||
-rw-r--r-- | programs/lz4cli.c | 18 | ||||
-rw-r--r-- | programs/lz4io.c | 15 | ||||
-rw-r--r-- | versionsTest/Makefile (renamed from test/Makefile) | 4 | ||||
-rw-r--r-- | versionsTest/test-lz4-versions.py (renamed from test/test-lz4-versions.py) | 6 |
22 files changed, 481 insertions, 51 deletions
diff --git a/.travis.yml b/.travis.yml index 6c505bc..87cb9a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,14 +12,14 @@ before_install: env: - LZ4_TRAVIS_CI_ENV=travis-install - - LZ4_TRAVIS_CI_ENV=streaming-examples + - LZ4_TRAVIS_CI_ENV=examples - LZ4_TRAVIS_CI_ENV=cmake - LZ4_TRAVIS_CI_ENV=clangtest - LZ4_TRAVIS_CI_ENV=sanitize - LZ4_TRAVIS_CI_ENV=staticAnalyze - LZ4_TRAVIS_CI_ENV=gpptest - LZ4_TRAVIS_CI_ENV=armtest - - LZ4_TRAVIS_CI_ENV=versionstest + - LZ4_TRAVIS_CI_ENV=versionsTest - LZ4_TRAVIS_CI_ENV=test-lz4 - LZ4_TRAVIS_CI_ENV=test-lz4c - LZ4_TRAVIS_CI_ENV=test-lz4c32 @@ -58,12 +58,16 @@ VOID = /dev/null endif +.PHONY: default all lib lz4programs clean test versionsTest + default: lz4programs -all: - @cd $(LZ4DIR); $(MAKE) -e all +all: lib @cd $(PRGDIR); $(MAKE) -e all +lib: + @cd $(LZ4DIR); $(MAKE) -e all + lz4programs: @cd $(PRGDIR); $(MAKE) -e @@ -71,7 +75,7 @@ clean: @cd $(PRGDIR); $(MAKE) clean > $(VOID) @cd $(LZ4DIR); $(MAKE) clean > $(VOID) @cd examples; $(MAKE) clean > $(VOID) - @cd test; $(MAKE) clean > $(VOID) + @cd versionsTest; $(MAKE) clean > $(VOID) @echo Cleaning completed @@ -108,16 +112,18 @@ sanitize: clean $(MAKE) test CC=clang CPPFLAGS="-g -fsanitize=undefined" FUZZER_TIME="-T1mn" NB_LOOPS=-i1 staticAnalyze: clean - scan-build --status-bugs -v $(MAKE) all CFLAGS=-g + CPPFLAGS=-g scan-build --status-bugs -v $(MAKE) all armtest: clean cd lib; $(MAKE) -e all CC=arm-linux-gnueabi-gcc CPPFLAGS="-Werror" cd programs; $(MAKE) -e bins CC=arm-linux-gnueabi-gcc CPPFLAGS="-Werror" -versionstest: clean - @cd test; $(MAKE) +versionsTest: clean + @cd versionsTest; $(MAKE) -streaming-examples: +examples: + cd lib; $(MAKE) -e + cd programs; $(MAKE) -e lz4 cd examples; $(MAKE) -e test prg-travis: @@ -1,3 +1,8 @@ +r131 +New : Dos/DJGPP target, thanks to Louis Santillan (#114) +Added : Example using lz4frame library, by Zbigniew Jędrzejewski-Szmek (#118) +Changed: xxhash symbols are modified (namespace emulation) within liblz4 + r130: Fixed : incompatibility sparse mode vs console, reported by Yongwoon Cho (#105) Fixed : LZ4IO exits too early when frame crc not present, reported by Yongwoon Cho (#106) @@ -17,11 +17,17 @@ All versions feature the same excellent decompression speed. |Branch |Status | |------------|---------| -|master | [![Build Status](https://travis-ci.org/Cyan4973/lz4.svg?branch=master)](https://travis-ci.org/Cyan4973/lz4) [![Build status](https://ci.appveyor.com/api/projects/status/v6kxv9si529477cq/branch/master?svg=true)](https://ci.appveyor.com/project/YannCollet/lz4) | -|dev | [![Build Status](https://travis-ci.org/Cyan4973/lz4.svg?branch=dev)](https://travis-ci.org/Cyan4973/lz4) [![Build status](https://ci.appveyor.com/api/projects/status/v6kxv9si529477cq/branch/dev?svg=true)](https://ci.appveyor.com/project/YannCollet/lz4) | - - - +|master | [![Build Status][travisMasterBadge]][travisLink] [![Build status][AppveyorMasterBadge]][AppveyorLink] [![coverity][coverBadge]][coverlink] | +|dev | [![Build Status][travisDevBadge]][travisLink] [![Build status][AppveyorDevBadge]][AppveyorLink] | + +[travisMasterBadge]: https://travis-ci.org/Cyan4973/lz4.svg?branch=master "Continuous Integration test suite" +[travisDevBadge]: https://travis-ci.org/Cyan4973/lz4.svg?branch=dev "Continuous Integration test suite" +[travisLink]: https://ci.appveyor.com/project/YannCollet/lz4 +[AppveyorMasterBadge]: https://ci.appveyor.com/api/projects/status/v6kxv9si529477cq/branch/master?svg=true "Visual test suite" +[AppveyorDevBadge]: https://ci.appveyor.com/api/projects/status/v6kxv9si529477cq/branch/dev?svg=true "Visual test suite" +[AppveyorLink]: https://ci.appveyor.com/project/YannCollet/lz4 +[coverBadge]: https://scan.coverity.com/projects/4735/badge.svg "Static code analysis of Master branch" +[coverlink]: https://scan.coverity.com/projects/4735 > **Branch Policy:** @@ -70,12 +76,13 @@ Other source versions ------------------------- Beyond the C reference source, -many contributors have created versions of lz4 in multiple languages. -A list of these sources is maintained on the [LZ4 Homepage]. +many contributors have created versions of lz4 in multiple languages +(Java, C#, Python, Perl, Ruby, etc.). +A list of known source ports is maintained on the [LZ4 Homepage]. [Open-Source Benchmark program by m^2 (v0.14.3)]: http://encode.ru/threads/1371-Filesystem-benchmark?p=34029&viewfull=1#post34029 [Silesia Corpus]: http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia [lz4_Block_format]: lz4_Block_format.md [lz4_Frame_format]: lz4_Frame_format.md -[LZ4 Homepage]: http://www.lz4.org +[LZ4 Homepage]: http://www.lz4.org
\ No newline at end of file diff --git a/cmake_unofficial/CMakeLists.txt b/cmake_unofficial/CMakeLists.txt index 4c3eb65..a986f43 100644 --- a/cmake_unofficial/CMakeLists.txt +++ b/cmake_unofficial/CMakeLists.txt @@ -17,7 +17,12 @@ ENDIF() option(BUILD_TOOLS "Build the command line tools" ON) option(BUILD_LIBS "Build the libraries in addition to the tools" ON) -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) +IF("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") + SET(GNU_COMPATIBLE_COMPILER 1) +ENDIF() + +if(GNU_COMPATIBLE_COMPILER) if(UNIX AND BUILD_LIBS) add_definitions(-fPIC) endif() @@ -68,7 +73,7 @@ endif() if(MSVC) ADD_DEFINITIONS("-W4") endif() -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) +if(GNU_COMPATIBLE_COMPILER) ADD_DEFINITIONS("-Wall") endif() if(CMAKE_COMPILER_IS_GNUCXX) @@ -78,7 +83,7 @@ ADD_DEFINITIONS("-Wshadow") ADD_DEFINITIONS("-Wcast-align") ADD_DEFINITIONS("-Wstrict-prototypes") endif(CMAKE_COMPILER_IS_GNUCXX) -if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND +if(GNU_COMPATIBLE_COMPILER AND (NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")) ADD_DEFINITIONS("-std=c99") endif() diff --git a/contrib/djgpp/LICENSE b/contrib/djgpp/LICENSE new file mode 100644 index 0000000..fee0d3b --- /dev/null +++ b/contrib/djgpp/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2014, lpsantil +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/contrib/djgpp/Makefile b/contrib/djgpp/Makefile new file mode 100644 index 0000000..8cd3580 --- /dev/null +++ b/contrib/djgpp/Makefile @@ -0,0 +1,130 @@ +# Copyright (c) 2015, Louis P. Santillan <lpsantil@gmail.com> +# All rights reserved. +# See LICENSE for licensing details. +DESTDIR ?= /opt/local + +# Pulled the code below from lib/Makefile. Might be nicer to derive this somehow without sed +# Version numbers +VERSION ?= 129 +RELEASE ?= r$(VERSION) +LIBVER_MAJOR=$(shell sed -n '/define LZ4_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lib/lz4.h) +LIBVER_MINOR=$(shell sed -n '/define LZ4_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lib/lz4.h) +LIBVER_PATCH=$(shell sed -n '/define LZ4_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < lib/lz4.h) +LIBVER=$(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH) + +###################################################################### + +CROSS ?= i586-pc-msdosdjgpp +CC = $(CROSS)-gcc +AR = $(CROSS)-ar +LD = $(CROSS)-gcc + +CFLAGS ?= -O3 -std=gnu99 -Wall -Wextra -Wundef -Wshadow -Wcast-qual -Wcast-align -Wstrict-prototypes -pedantic -DLZ4_VERSION=\"$(RELEASE)\" +LDFLAGS ?= -s +SRC = programs/bench.c programs/lz4io.c programs/lz4cli.c +OBJ = $(SRC:.c=.o) +SDEPS = $(SRC:.c=.d) +IDIR = lib +EDIR = . +EXE = lz4.exe +LNK = lz4 +LDIR = lib +LSRC = lib/lz4.c lib/lz4hc.c lib/lz4frame.c lib/xxhash.c +INC = $(LSRC:.c=.h) +LOBJ = $(LSRC:.c=.o) +LSDEPS = $(LSRC:.c=.d) +LIB = $(LDIR)/lib$(LNK).a + +# Since LDFLAGS defaults to "-s", probably better to override unless +# you have a default you would like to maintain +ifeq ($(WITH_DEBUG), 1) + CFLAGS += -g + LDFLAGS += -g +endif + +# Since LDFLAGS defaults to "-s", probably better to override unless +# you have a default you would like to maintain +ifeq ($(WITH_PROFILING), 1) + CFLAGS += -pg + LDFLAGS += -pg +endif + +%.o: %.c $(INC) Makefile + $(CC) $(CFLAGS) -MMD -MP -I$(IDIR) -c $< -o $@ + +%.exe: %.o $(LIB) Makefile + $(LD) $< -L$(LDIR) -l$(LNK) $(LDFLAGS) $(LIBDEP) -o $@ + +###################################################################### +######################## DO NOT MODIFY BELOW ######################### +###################################################################### + +.PHONY: all install uninstall showconfig gstat gpush + +all: $(LIB) $(EXE) + +$(LIB): $(LOBJ) + $(AR) -rcs $@ $^ + +$(EXE): $(LOBJ) $(OBJ) + $(LD) $(LDFLAGS) $(LOBJ) $(OBJ) -o $(EDIR)/$@ + +clean: + rm -f $(OBJ) $(EXE) $(LOBJ) $(LIB) *.tmp $(SDEPS) $(LSDEPS) $(TSDEPS) + +install: $(INC) $(LIB) $(EXE) + mkdir -p $(DESTDIR)/bin $(DESTDIR)/include $(DESTDIR)/lib + rm -f .footprint + echo $(DESTDIR)/bin/$(EXE) >> .footprint + cp -v $(EXE) $(DESTDIR)/bin/ + @for T in $(LIB); \ + do ( \ + echo $(DESTDIR)/$$T >> .footprint; \ + cp -v --parents $$T $(DESTDIR) \ + ); done + @for T in $(INC); \ + do ( \ + echo $(DESTDIR)/include/`basename -a $$T` >> .footprint; \ + cp -v $$T $(DESTDIR)/include/ \ + ); done + +uninstall: .footprint + @for T in $(shell cat .footprint); do rm -v $$T; done + +-include $(SDEPS) $(LSDEPS) + +showconfig: + @echo "PWD="$(PWD) + @echo "VERSION="$(VERSION) + @echo "RELEASE="$(RELEASE) + @echo "LIBVER_MAJOR="$(LIBVER_MAJOR) + @echo "LIBVER_MINOR="$(LIBVER_MINOR) + @echo "LIBVER_PATCH="$(LIBVER_PATCH) + @echo "LIBVER="$(LIBVER) + @echo "CROSS="$(CROSS) + @echo "CC="$(CC) + @echo "AR="$(AR) + @echo "LD="$(LD) + @echo "DESTDIR="$(DESTDIR) + @echo "CFLAGS="$(CFLAGS) + @echo "LDFLAGS="$(LDFLAGS) + @echo "SRC="$(SRC) + @echo "OBJ="$(OBJ) + @echo "IDIR="$(IDIR) + @echo "INC="$(INC) + @echo "EDIR="$(EDIR) + @echo "EXE="$(EXE) + @echo "LDIR="$(LDIR) + @echo "LSRC="$(LSRC) + @echo "LOBJ="$(LOBJ) + @echo "LNK="$(LNK) + @echo "LIB="$(LIB) + @echo "SDEPS="$(SDEPS) + @echo "LSDEPS="$(LSDEPS) + +gstat: + git status + +gpush: + git commit + git push diff --git a/contrib/djgpp/README.MD b/contrib/djgpp/README.MD new file mode 100644 index 0000000..0f4cae6 --- /dev/null +++ b/contrib/djgpp/README.MD @@ -0,0 +1,21 @@ +# lz4 for DOS/djgpp +This file details on how to compile lz4.exe, and liblz4.a for use on DOS/djgpp using +Andrew Wu's build-djgpp cross compilers ([GH][0], [Binaries][1]) on OSX, Linux. + +## Setup +* Download a djgpp tarball [binaries][1] for your platform. +* Extract and install it (`tar jxvf djgpp-linux64-gcc492.tar.bz2`). Note the path. We'll assume `/home/user/djgpp`. +* Add the `bin` folder to your `PATH`. In bash, do `export PATH=/home/user/djgpp/bin:$PATH`. +* The `Makefile` in `contrib/djgpp/` sets up `CC`, `AR`, `LD` for you. So, `CC=i586-pc-msdosdjgpp-gcc`, `AR=i586-pc-msdosdjgpp-ar`, `LD=i586-pc-msdosdjgpp-gcc`. + +## Building LZ4 for DOS +In the base dir of lz4 and with `contrib/djgpp/Makefile`, try: +Try: +* `make -f contrib/djgpp/Makefile` +* `make -f contrib/djgpp/Makefile liblz4.a` +* `make -f contrib/djgpp/Makefile lz4.exe` +* `make -f contrib/djgpp/Makefile DESTDIR=/home/user/dos install`, however it doesn't make much sense on a \*nix. +* You can also do `make -f contrib/djgpp/Makefile uninstall` + +[0]: https://github.com/andrewwutw/build-djgpp +[1]: https://github.com/andrewwutw/build-djgpp/releases diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..4893866 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,8 @@ +/Makefile.lz4* +/printVersion +/doubleBuffer +/ringBuffer +/ringBufferHC +/lineCompress +/frameCompress +/*.exe diff --git a/examples/Makefile b/examples/Makefile index 808b511..069f7d9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -33,6 +33,7 @@ FLAGS := -I../lib $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) TESTFILE= Makefile LZ4DIR := ../lib +LZ4 = ../programs/lz4 # Define *.exe as extension for Windows systems @@ -47,7 +48,7 @@ endif default: all -all: printVersion doubleBuffer ringBuffer ringBufferHC lineCompress +all: printVersion doubleBuffer ringBuffer ringBufferHC lineCompress frameCompress printVersion: $(LZ4DIR)/lz4.c printVersion.c $(CC) $(FLAGS) $^ -o $@$(EXT) @@ -64,15 +65,21 @@ ringBufferHC: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c HCStreaming_ringBuffer.c lineCompress: $(LZ4DIR)/lz4.c blockStreaming_lineByLine.c $(CC) $(FLAGS) $^ -o $@$(EXT) +frameCompress: frameCompress.c + $(CC) $(FLAGS) $^ -o $@$(EXT) -L$(LZ4DIR) -llz4 + test : all ./printVersion$(EXT) ./doubleBuffer$(EXT) $(TESTFILE) ./ringBuffer$(EXT) $(TESTFILE) ./ringBufferHC$(EXT) $(TESTFILE) ./lineCompress$(EXT) $(TESTFILE) + LD_LIBRARY_PATH=$(LZ4DIR) ./frameCompress$(EXT) $(TESTFILE) + $(LZ4) -vt $(TESTFILE).lz4 clean: - @rm -f core *.o *.dec *-0 *-9 *-8192 *.lz4s \ - printVersion$(EXT) doubleBuffer$(EXT) ringBuffer$(EXT) ringBufferHC$(EXT) lineCompress$(EXT) + @rm -f core *.o *.dec *-0 *-9 *-8192 *.lz4s *.lz4 \ + printVersion$(EXT) doubleBuffer$(EXT) ringBuffer$(EXT) ringBufferHC$(EXT) \ + lineCompress$(EXT) frameCompress$(EXT) @echo Cleaning completed diff --git a/examples/frameCompress.c b/examples/frameCompress.c new file mode 100644 index 0000000..b52b042 --- /dev/null +++ b/examples/frameCompress.c @@ -0,0 +1,169 @@ +// LZ4frame API example : compress a file +// Based on sample code from Zbigniew Jędrzejewski-Szmek + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <lz4frame.h> + +#define BUF_SIZE (16*1024) +#define LZ4_HEADER_SIZE 19 +#define LZ4_FOOTER_SIZE 4 + +static const LZ4F_preferences_t lz4_preferences = { + { LZ4F_max256KB, LZ4F_blockLinked, LZ4F_noContentChecksum, LZ4F_frame, 0, { 0, 0 } }, + 0, /* compression level */ + 0, /* autoflush */ + { 0, 0, 0, 0 }, /* reserved, must be set to 0 */ +}; + +static int compress_file(FILE *in, FILE *out, size_t *size_in, size_t *size_out) { + LZ4F_errorCode_t r; + LZ4F_compressionContext_t ctx; + char *src, *buf = NULL; + size_t size, n, k, count_in = 0, count_out, offset = 0, frame_size; + + r = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION); + if (LZ4F_isError(r)) { + printf("Failed to create context: error %zu", r); + return 1; + } + r = 1; + + src = malloc(BUF_SIZE); + if (!src) { + printf("Not enough memory"); + goto cleanup; + } + + frame_size = LZ4F_compressBound(BUF_SIZE, &lz4_preferences); + size = frame_size + LZ4_HEADER_SIZE + LZ4_FOOTER_SIZE; + buf = malloc(size); + if (!buf) { + printf("Not enough memory"); + goto cleanup; + } + + n = offset = count_out = LZ4F_compressBegin(ctx, buf, size, &lz4_preferences); + if (LZ4F_isError(n)) { + printf("Failed to start compression: error %zu", n); + goto cleanup; + } + + printf("Buffer size is %zu bytes, header size %zu bytes\n", size, n); + + for (;;) { + k = fread(src, 1, BUF_SIZE, in); + if (k == 0) + break; + count_in += k; + + n = LZ4F_compressUpdate(ctx, buf + offset, size - offset, src, k, NULL); + if (LZ4F_isError(n)) { + printf("Compression failed: error %zu", n); + goto cleanup; + } + + offset += n; + count_out += n; + if (size - offset < frame_size + LZ4_FOOTER_SIZE) { + printf("Writing %zu bytes\n", offset); + + k = fwrite(buf, 1, offset, out); + if (k < offset) { + if (ferror(out)) + printf("Write failed"); + else + printf("Short write"); + goto cleanup; + } + + offset = 0; + } + } + + n = LZ4F_compressEnd(ctx, buf + offset, size - offset, NULL); + if (LZ4F_isError(n)) { + printf("Failed to end compression: error %zu", n); + goto cleanup; + } + + offset += n; + count_out += n; + printf("Writing %zu bytes\n", offset); + + k = fwrite(buf, 1, offset, out); + if (k < offset) { + if (ferror(out)) + printf("Write failed"); + else + printf("Short write"); + goto cleanup; + } + + *size_in = count_in; + *size_out = count_out; + r = 0; + cleanup: + if (ctx) + LZ4F_freeCompressionContext(ctx); + free(src); + free(buf); + return r; +} + +static int compress(const char *input, const char *output) { + char *tmp = NULL; + FILE *in = NULL, *out = NULL; + size_t size_in = 0, size_out = 0; + int r = 1; + + if (!output) { + size_t len = strlen(input); + + output = tmp = malloc(len + 5); + if (!tmp) { + printf("Not enough memory"); + return 1; + } + strcpy(tmp, input); + strcpy(tmp + len, ".lz4"); + } + + in = fopen(input, "rb"); + if (!in) { + fprintf(stderr, "Failed to open input file %s: %s\n", input, strerror(errno)); + goto cleanup; + } + + out = fopen(output, "wb"); + if (!out) { + fprintf(stderr, "Failed to open output file %s: %s\n", output, strerror(errno)); + goto cleanup; + } + + r = compress_file(in, out, &size_in, &size_out); + if (r == 0) + printf("%s: %zu → %zu bytes, %.1f%%\n", + input, size_in, size_out, + (double)size_out / size_in * 100); + cleanup: + if (in) + fclose(in); + if (out) + fclose(out); + free(tmp); + return r; +} + + +int main(int argc, char **argv) { + if (argc < 2 || argc > 3) { + fprintf(stderr, "Syntax: %s <input> <output>\n", argv[0]); + return EXIT_FAILURE; + } + + return compress(argv[1], argv[2]); +} diff --git a/lib/Makefile b/lib/Makefile index 4be1499..02ddd3b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -40,7 +40,7 @@ LIBVER=$(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH) DESTDIR?= PREFIX ?= /usr/local CFLAGS ?= -O3 -CFLAGS += -I. -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wcast-qual -Wstrict-prototypes -pedantic +CFLAGS += -I. -std=c99 -Wall -Wextra -Wundef -Wshadow -Wcast-align -Wcast-qual -Wstrict-prototypes -pedantic -DXXH_NAMESPACE=LZ4_ LIBDIR?= $(PREFIX)/lib INCLUDEDIR=$(PREFIX)/include @@ -66,7 +66,7 @@ all: liblz4 liblz4: lz4.c lz4hc.c lz4frame.c xxhash.c @echo compiling static library - @$(CC) $(CPPFLAGS) $(CFLAGS) -fPIC -c $^ + @$(CC) $(CPPFLAGS) $(CFLAGS) -c $^ @$(AR) rcs liblz4.a lz4.o lz4hc.o lz4frame.o xxhash.o @echo compiling dynamic library $(LIBVER) @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $^ -fPIC $(SONAME_FLAGS) -o $@.$(SHARED_EXT_VER) diff --git a/lib/README.md b/lib/README.md index 636c8be..f6ebf5e 100644 --- a/lib/README.md +++ b/lib/README.md @@ -1,15 +1,16 @@ LZ4 - Library Files ================================ -This directory contains many files, but you don't necessarily need them all. +The __lib__ directory contains several files, but you don't necessarily need them all. -If you want to integrate LZ4 compression/decompression into your program, you basically need to include "**lz4.c**" and "**lz4.h**" only. +To integrate fast LZ4 compression/decompression into your program, you basically just need "**lz4.c**" and "**lz4.h**". -If you want more compression, at the cost of compression speed (but preserving decompression speed), you will also have to include "**lz4hc.c**" and "**lz4hc.h**". Note that lz4hc needs lz4 to work properly. +For more compression at the cost of compression speed (while preserving decompression speed), use **lz4hc** on top of regular lz4. `lz4hc` only provides compression functions. It also needs `lz4` to compile properly. -Next level, if you want to produce files or data streams compatible with lz4 utility, you will have to use and include "**lz4frame.c**" and **lz4frame.h**". This library encapsulate lz4-compressed blocks into the official interoperable frame format. In order to work properly, lz4frame needs lz4 and lz4hc, and also "**xxhash.c**" and "**xxhash.h**", which provide the error detection algorithm. +If you want to produce files or data streams compatible with `lz4` command line utility, use **lz4frame**. This library encapsulates lz4-compressed blocks into the [official interoperable frame format]. In order to work properly, lz4frame needs lz4 and lz4hc, and also **xxhash**, which provides error detection algorithm. +(_Advanced stuff_ : It's possible to hide xxhash symbols into a local namespace. This is what `liblz4` does, to avoid symbol duplication in case a user program would link to several libraries containing xxhash symbols.) -A more complex "lz4frame_static.h" is also provided, although its usage is not recommended. It contains definitions which are not guaranteed to remain stable within future versions. Use only if you don't plan to update your lz4 version. +A more complex "lz4frame_static.h" is also provided, although its usage is not recommended. It contains definitions which are not guaranteed to remain stable within future versions. Use for static linking ***only***. The other files are not source code. There are : @@ -17,3 +18,4 @@ The other files are not source code. There are : - Makefile : script to compile or install lz4 library (static or dynamic) - liblz4.pc.in : for pkg-config (make install) +[official interoperable frame format]: ../lz4_Frame_format.md @@ -49,7 +49,7 @@ extern "C" { **************************************/ #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ #define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ -#define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ +#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) int LZ4_versionNumber (void); diff --git a/lib/xxhash.h b/lib/xxhash.h index 0df5ac1..c60aa61 100644 --- a/lib/xxhash.h +++ b/lib/xxhash.h @@ -78,6 +78,39 @@ extern "C" { typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; +/***************************** +* Namespace Emulation +*****************************/ +/* Motivations : + +If you need to include xxHash into your library, +but wish to avoid xxHash symbols to be present on your library interface +in an effort to avoid potential name collision if another library also includes xxHash, + +you can use XXH_NAMESPACE, which will automatically prefix any symbol from xxHash +with the value of XXH_NAMESPACE (so avoid to keep it NULL, and avoid numeric values). + +Note that no change is required within the calling program : +it can still call xxHash functions using their regular name. +They will be automatically translated by this header. +*/ +#ifdef XXH_NAMESPACE +# define XXH_CAT(A,B) A##B +# define XXH_NAME2(A,B) XXH_CAT(A,B) +# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) +# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) +# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) +# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) +# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) +# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) +# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) +# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) +# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) +# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) +# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) +# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) +#endif + /***************************** * Simple Hash Functions diff --git a/programs/.gitignore b/programs/.gitignore new file mode 100644 index 0000000..f7fc991 --- /dev/null +++ b/programs/.gitignore @@ -0,0 +1,2 @@ +/lz4 +/*.exe diff --git a/programs/fuzzer.c b/programs/fuzzer.c index 6588290..de12478 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -407,7 +407,7 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c FUZ_CHECKTEST(ret > targetSize, "LZ4_compress_destSize() result larger than dst buffer !"); FUZ_CHECKTEST(compressedBuffer[targetSize] != endCheck, "LZ4_compress_destSize() overwrite dst buffer !"); FUZ_CHECKTEST(srcSize > blockSize, "LZ4_compress_destSize() fed more than src buffer !"); - DISPLAY("destSize : %7i/%7i; content%7i/%7i ", ret, targetSize, srcSize, blockSize); + DISPLAYLEVEL(5, "destSize : %7i/%7i; content%7i/%7i ", ret, targetSize, srcSize, blockSize); if (targetSize>0) { FUZ_CHECKTEST((ret==0), "LZ4_compress_destSize() compression failed"); @@ -425,10 +425,10 @@ static int FUZ_test(U32 seed, U32 nbCycles, const U32 startCycle, const double c crcCheck = XXH32(decodedBuffer, srcSize, 0); FUZ_CHECKTEST(crcCheck!=crcOrig, "LZ4_decompress_safe() corrupted decoded data"); - DISPLAY(" OK \n"); + DISPLAYLEVEL(5, " OK \n"); } else - DISPLAY(" \n"); + DISPLAYLEVEL(5, " \n"); } /* Test compression HC */ diff --git a/programs/lz4.1 b/programs/lz4.1 index a79fed3..414da48 100644 --- a/programs/lz4.1 +++ b/programs/lz4.1 @@ -185,7 +185,7 @@ independently, and the resulting name of the compressed file will be hence for a file. It won't work with unknown source size, such as stdin or pipe. .TP .B \--[no-]sparse - sparse file support (default:enabled) + sparse mode support (default:enabled on file, disabled on stdout) .TP .B \-l use Legacy format (useful for Linux Kernel compression) diff --git a/programs/lz4cli.c b/programs/lz4cli.c index e5210c9..977c04e 100644 --- a/programs/lz4cli.c +++ b/programs/lz4cli.c @@ -67,6 +67,11 @@ *****************************/ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) # include <io.h> /* _isatty */ +# if defined(__DJGPP__) +# include <unistd.h> +# define _isatty isatty +# define _fileno fileno +# endif # ifdef __MINGW32__ int _fileno(FILE *stream); /* MINGW somehow forgets to include this prototype into <stdio.h> */ # endif @@ -175,7 +180,7 @@ static int usage_advanced(void) /* DISPLAY( " -BX : enable block checksum (default:disabled)\n"); *//* Option currently inactive */ DISPLAY( "--no-frame-crc : disable stream checksum (default:enabled)\n"); DISPLAY( "--content-size : compressed frame includes original size (default:not present)\n"); - DISPLAY( "--[no-]sparse : sparse file support (default:enabled)\n"); + DISPLAY( "--[no-]sparse : sparse mode (default:enabled on file, disabled on stdout)\n"); DISPLAY( "Benchmark arguments :\n"); DISPLAY( " -b : benchmark file(s)\n"); DISPLAY( " -i# : iteration loops [1-9](default : 3), benchmark mode only\n"); @@ -192,6 +197,7 @@ static int usage_advanced(void) static int usage_longhelp(void) { + usage_advanced(); DISPLAY( "\n"); DISPLAY( "Which values can get [output] ? \n"); DISPLAY( "[output] : a filename\n"); @@ -352,9 +358,9 @@ int main(int argc, char** argv) switch(argument[0]) { /* Display help */ - case 'V': DISPLAY(WELCOME_MESSAGE); return 0; /* Version */ - case 'h': usage_advanced(); return 0; - case 'H': usage_advanced(); usage_longhelp(); return 0; + case 'V': DISPLAY(WELCOME_MESSAGE); goto _cleanup; /* Version */ + case 'h': usage_advanced(); goto _cleanup; + case 'H': usage_longhelp(); goto _cleanup; /* Compression (default) */ case 'z': forceCompress = 1; break; @@ -552,9 +558,9 @@ int main(int argc, char** argv) } } +_cleanup: if (main_pause) waitEnter(); free(dynNameSpace); free((void*)inFileNames); - if (operationResult != 0) return operationResult; - return 0; + return operationResult; } diff --git a/programs/lz4io.c b/programs/lz4io.c index e782664..19db03b 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -64,11 +64,16 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) # include <fcntl.h> /* _O_BINARY */ # include <io.h> /* _setmode, _fileno, _get_osfhandle */ -# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) -# include <Windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */ -# define SET_SPARSE_FILE_MODE(file) { DWORD dw; DeviceIoControl((HANDLE) _get_osfhandle(_fileno(file)), FSCTL_SET_SPARSE, 0, 0, 0, 0, &dw, 0); } -# if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Avoid MSVC fseek()'s 2GiB barrier */ -# define fseek _fseeki64 +# if !defined(__DJGPP__) +# define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) +# include <Windows.h> /* DeviceIoControl, HANDLE, FSCTL_SET_SPARSE */ +# define SET_SPARSE_FILE_MODE(file) { DWORD dw; DeviceIoControl((HANDLE) _get_osfhandle(_fileno(file)), FSCTL_SET_SPARSE, 0, 0, 0, 0, &dw, 0); } +# if defined(_MSC_VER) && (_MSC_VER >= 1400) /* Avoid MSVC fseek()'s 2GiB barrier */ +# define fseek _fseeki64 +# endif +# else +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +# define SET_SPARSE_FILE_MODE(file) # endif #else # define SET_BINARY_MODE(file) diff --git a/test/Makefile b/versionsTest/Makefile index d1768d4..2ce719a 100644 --- a/test/Makefile +++ b/versionsTest/Makefile @@ -30,9 +30,9 @@ TESTDIR := lz4test default: all -all: versionstest +all: versionsTest -versionstest: +versionsTest: $(PYTHON) test-lz4-versions.py clean: diff --git a/test/test-lz4-versions.py b/versionsTest/test-lz4-versions.py index 5531a05..caf1922 100644 --- a/test/test-lz4-versions.py +++ b/versionsTest/test-lz4-versions.py @@ -9,7 +9,7 @@ import sys import hashlib repo_url = 'https://github.com/Cyan4973/lz4.git' -tmp_dir_name = 'test/lz4test' +tmp_dir_name = 'versionsTest/lz4test' make_cmd = 'make' git_cmd = 'git' test_dat_src = 'README.md' @@ -46,8 +46,8 @@ def sha1_of_file(filepath): if __name__ == '__main__': error_code = 0 base_dir = os.getcwd() + '/..' # /path/to/lz4 - tmp_dir = base_dir + '/' + tmp_dir_name # /path/to/lz4/test/lz4test - clone_dir = tmp_dir + '/' + 'lz4' # /path/to/lz4/test/lz4test/lz4 + tmp_dir = base_dir + '/' + tmp_dir_name # /path/to/lz4/versionsTest/lz4test + clone_dir = tmp_dir + '/' + 'lz4' # /path/to/lz4/versionsTest/lz4test/lz4 programs_dir = base_dir + '/programs' # /path/to/lz4/programs os.makedirs(tmp_dir, exist_ok=True) |