Allow to build zlib and lzma statically

This should fix issues on Darwin.
This commit is contained in:
2020-05-08 20:13:10 +02:00
parent 378942cbce
commit bf6e94cfb2
227 changed files with 46996 additions and 3 deletions

45
3rdparty/zlib/test/Makefile vendored Normal file
View File

@@ -0,0 +1,45 @@
HSC=ghc
CC=gcc # can also use $(HSC)
UNCOMPRESSED=`find .. -type f`
GZIPPED=`find .. -type f -name \*.gz`
HSC_OPTS=-hide-package zlib -i
HSBINS=hszpipe hsgzip hsgunzip test-hs
BINS=$(HSBINS) zpipe
ALL:
clean:
rm -f $(BINS) *.o *.hi
bins: hszpipe zpipe hsgzip hsgunzip
%.hs : %.hsc
hsc2hs --cc=$(HSC) --ld=$(HSC) --lflag=-lz -o $@ $<
hs%: ../examples/%.hs
$(HSC) $(HSC_OPTS) -lz -i.. -o $@ --make $<
$(HSBINS) : ../Codec/Compression/Zlib/Stream.hs
test-hs: Test.hs
$(HSC) $(HSC_OPTS) -Wall -lz -i. -i.. -o $@ --make $<
zpipe: zpipe.c
$(CC) -lz -o zpipe zpipe.c
test: run-test-hs run-test-sh-zpipe run-test-sh-gzip run-test-sh-gunzip
run-test-hs: test-hs
./test-hs
run-test-sh-zpipe: zpipe hszpipe
./zpipe-compress.sh $(UNCOMPRESSED)
run-test-sh-gzip: hsgzip hsgunzip
./gzip-compress.sh $(UNCOMPRESSED)
run-test-sh-gunzip: hsgunzip
./gzip-uncompress.sh $(GZIPPED)

338
3rdparty/zlib/test/Test.hs vendored Normal file
View File

@@ -0,0 +1,338 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Main where
import Codec.Compression.Zlib.Internal
import qualified Codec.Compression.Zlib as Zlib
import qualified Codec.Compression.GZip as GZip
import qualified Codec.Compression.Zlib.Raw as Raw
import Test.Codec.Compression.Zlib.Internal ()
import Test.Codec.Compression.Zlib.Stream ()
import Test.QuickCheck
import Test.Tasty
import Test.Tasty.QuickCheck
import Test.Tasty.HUnit
import Utils ()
import Control.Monad
import Control.Monad.ST.Lazy (ST)
import Control.Exception
import qualified Data.ByteString.Char8 as BS.Char8
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import System.IO
#if !(MIN_VERSION_base(4,6,0))
import Prelude hiding (catch)
#endif
main :: IO ()
main = defaultMain $
testGroup "zlib tests" [
testGroup "property tests" [
testProperty "decompress . compress = id (standard)" prop_decompress_after_compress,
testProperty "decompress . compress = id (Zlib -> GZipOrZLib)" prop_gziporzlib1,
testProperty "decompress . compress = id (GZip -> GZipOrZlib)" prop_gziporzlib2,
testProperty "concatenated gzip members" prop_gzip_concat,
testProperty "multiple gzip members, boundaries (all 2-chunks)" prop_multiple_members_boundary2,
testProperty "multiple gzip members, boundaries (all 3-chunks)" prop_multiple_members_boundary3,
testProperty "prefixes of valid stream detected as truncated" prop_truncated
],
testGroup "unit tests" [
testCase "simple gzip case" test_simple_gzip,
testCase "detect bad crc" test_bad_crc,
testCase "detect non-gzip" test_non_gzip,
testCase "detect custom dictionary" test_custom_dict,
testCase "dectect inflate with wrong dict" test_wrong_dictionary,
testCase "dectect inflate with right dict" test_right_dictionary,
testCase "handle trailing data" test_trailing_data,
testCase "multiple gzip members" test_multiple_members,
testCase "check small input chunks" test_small_chunks,
testCase "check empty input" test_empty,
testCase "check exception raised" test_exception
]
]
prop_decompress_after_compress :: Format
-> CompressParams
-> DecompressParams
-> Property
prop_decompress_after_compress w cp dp =
(w /= zlibFormat || decompressWindowBits dp >= compressWindowBits cp) &&
(decompressWindowBits dp > compressWindowBits cp) &&
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
liftM2 (==) (decompress w dp . compress w cp) id
prop_gziporzlib1 :: CompressParams
-> DecompressParams
-> Property
prop_gziporzlib1 cp dp =
decompressWindowBits dp > compressWindowBits cp &&
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
liftM2 (==) (decompress gzipOrZlibFormat dp . compress zlibFormat cp) id
prop_gziporzlib2 :: CompressParams
-> DecompressParams
-> Property
prop_gziporzlib2 cp dp =
decompressWindowBits dp >= compressWindowBits cp &&
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
liftM2 (==) (decompress gzipOrZlibFormat dp . compress gzipFormat cp) id
prop_gzip_concat :: CompressParams
-> DecompressParams
-> BL.ByteString
-> Property
prop_gzip_concat cp dp input =
decompressWindowBits dp >= compressWindowBits cp &&
decompressBufferSize dp > 0 && compressBufferSize cp > 0 ==>
let catComp = BL.concat (replicate 5 (compress gzipFormat cp input))
compCat = compress gzipFormat cp (BL.concat (replicate 5 input))
in decompress gzipFormat dp { decompressAllMembers = True } catComp
== decompress gzipFormat dp { decompressAllMembers = True } compCat
prop_multiple_members_boundary2 :: Property
prop_multiple_members_boundary2 =
forAll shortStrings $ \bs ->
all (\c -> decomp c == BL.append bs bs)
(twoChunkSplits (comp bs `BL.append` comp bs))
where
comp = compress gzipFormat defaultCompressParams
decomp = decompress gzipFormat defaultDecompressParams
shortStrings = fmap BL.pack $ listOf arbitrary
prop_multiple_members_boundary3 :: Property
prop_multiple_members_boundary3 =
forAll shortStrings $ \bs ->
all (\c -> decomp c == BL.append bs bs)
(threeChunkSplits (comp bs `BL.append` comp bs))
where
comp = compress gzipFormat defaultCompressParams
decomp = decompress gzipFormat defaultDecompressParams
shortStrings = sized $ \sz -> resize (sz `div` 10) $
fmap BL.pack $ listOf arbitrary
prop_truncated :: Format -> Property
prop_truncated format =
forAll shortStrings $ \bs ->
all (truncated decomp)
(init (BL.inits (comp bs)))
-- All the initial prefixes of a valid compressed stream should be detected
-- as truncated.
where
comp = compress format defaultCompressParams
decomp = decompressST format defaultDecompressParams
truncated :: (forall s. DecompressStream (ST s)) -> BL.ByteString -> Bool
truncated = foldDecompressStreamWithInput (\_ r -> r) (\_ -> False)
(\err -> case err of TruncatedInput -> True; _ -> False)
shortStrings = sized $ \sz -> resize (sz `div` 6) arbitrary
test_simple_gzip :: Assertion
test_simple_gzip =
withSampleData "hello.gz" $ \hnd ->
let decomp = decompressIO gzipFormat defaultDecompressParams
in assertDecompressOk hnd decomp
test_bad_crc :: Assertion
test_bad_crc =
withSampleData "bad-crc.gz" $ \hnd -> do
let decomp = decompressIO gzipFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
msg <- assertDataFormatError err
msg @?= "incorrect data check"
test_non_gzip :: Assertion
test_non_gzip = do
withSampleData "not-gzip" $ \hnd -> do
let decomp = decompressIO gzipFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
msg <- assertDataFormatError err
msg @?= "incorrect header check"
withSampleData "not-gzip" $ \hnd -> do
let decomp = decompressIO zlibFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
msg <- assertDataFormatError err
msg @?= "incorrect header check"
withSampleData "not-gzip" $ \hnd -> do
let decomp = decompressIO rawFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
msg <- assertDataFormatError err
msg @?= "invalid code lengths set"
withSampleData "not-gzip" $ \hnd -> do
let decomp = decompressIO gzipOrZlibFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
msg <- assertDataFormatError err
msg @?= "incorrect header check"
test_custom_dict :: Assertion
test_custom_dict =
withSampleData "custom-dict.zlib" $ \hnd -> do
let decomp = decompressIO zlibFormat defaultDecompressParams
err <- assertDecompressError hnd decomp
err @?= DictionaryRequired
test_wrong_dictionary :: Assertion
test_wrong_dictionary = do
withSampleData "custom-dict.zlib" $ \hnd -> do
let decomp = decompressIO zlibFormat defaultDecompressParams {
decompressDictionary = -- wrong dict!
Just (BS.pack [65,66,67])
}
err <- assertDecompressError hnd decomp
err @?= DictionaryMismatch
test_right_dictionary :: Assertion
test_right_dictionary = do
withSampleData "custom-dict.zlib" $ \hnd -> do
dict <- readSampleData "custom-dict.zlib-dict"
let decomp = decompressIO zlibFormat defaultDecompressParams {
decompressDictionary =
Just (toStrict dict)
}
assertDecompressOk hnd decomp
test_trailing_data :: Assertion
test_trailing_data =
withSampleData "two-files.gz" $ \hnd -> do
let decomp = decompressIO gzipFormat defaultDecompressParams {
decompressAllMembers = False
}
chunks <- assertDecompressOkChunks hnd decomp
case chunks of
[chunk] -> chunk @?= BS.Char8.pack "Test 1"
_ -> assertFailure "expected single chunk"
test_multiple_members :: Assertion
test_multiple_members =
withSampleData "two-files.gz" $ \hnd -> do
let decomp = decompressIO gzipFormat defaultDecompressParams {
decompressAllMembers = True
}
chunks <- assertDecompressOkChunks hnd decomp
case chunks of
[chunk1,
chunk2] -> do chunk1 @?= BS.Char8.pack "Test 1"
chunk2 @?= BS.Char8.pack "Test 2"
_ -> assertFailure "expected two chunks"
test_small_chunks :: Assertion
test_small_chunks = do
uncompressedFile <- readSampleData "not-gzip"
GZip.compress (smallChunks uncompressedFile) @?= GZip.compress uncompressedFile
Zlib.compress (smallChunks uncompressedFile) @?= Zlib.compress uncompressedFile
Raw.compress (smallChunks uncompressedFile) @?= Raw.compress uncompressedFile
GZip.decompress (smallChunks (GZip.compress uncompressedFile)) @?= uncompressedFile
Zlib.decompress (smallChunks (Zlib.compress uncompressedFile)) @?= uncompressedFile
Raw.decompress (smallChunks (Raw.compress uncompressedFile)) @?= uncompressedFile
compressedFile <- readSampleData "hello.gz"
(GZip.decompress . smallChunks) compressedFile @?= GZip.decompress compressedFile
test_empty :: Assertion
test_empty = do
-- Regression test to make sure we only ask for input once in the case of
-- initially empty input. We previously asked for input twice before
-- returning the error.
let decomp = decompressIO zlibFormat defaultDecompressParams
case decomp of
DecompressInputRequired next -> do
decomp' <- next BS.empty
case decomp' of
DecompressStreamError TruncatedInput -> return ()
_ -> assertFailure "expected truncated error"
_ -> assertFailure "expected input"
test_exception :: Assertion
test_exception =
(do
compressedFile <- readSampleData "bad-crc.gz"
_ <- evaluate (BL.length (GZip.decompress compressedFile))
assertFailure "expected exception")
`catch` \err -> do
msg <- assertDataFormatError err
msg @?= "incorrect data check"
toStrict :: BL.ByteString -> BS.ByteString
#if MIN_VERSION_bytestring(0,10,0)
toStrict = BL.toStrict
#else
toStrict = BS.concat . BL.toChunks
#endif
-----------------------
-- Chunk boundary utils
smallChunks :: BL.ByteString -> BL.ByteString
smallChunks = BL.fromChunks . map (\c -> BS.pack [c]) . BL.unpack
twoChunkSplits :: BL.ByteString -> [BL.ByteString]
twoChunkSplits bs = zipWith (\a b -> BL.fromChunks [a,b]) (BS.inits sbs) (BS.tails sbs)
where
sbs = toStrict bs
threeChunkSplits :: BL.ByteString -> [BL.ByteString]
threeChunkSplits bs =
[ BL.fromChunks [a,b,c]
| (a,x) <- zip (BS.inits sbs) (BS.tails sbs)
, (b,c) <- zip (BS.inits x) (BS.tails x) ]
where
sbs = toStrict bs
--------------
-- HUnit Utils
readSampleData :: FilePath -> IO BL.ByteString
readSampleData file = BL.readFile ("test/data/" ++ file)
withSampleData :: FilePath -> (Handle -> IO a) -> IO a
withSampleData file = withFile ("test/data/" ++ file) ReadMode
expected :: String -> String -> IO a
expected e g = assertFailure ("expected: " ++ e ++ "\nbut got: " ++ g)
>> fail ""
assertDecompressOk :: Handle -> DecompressStream IO -> Assertion
assertDecompressOk hnd =
foldDecompressStream
(BS.hGet hnd 4000 >>=)
(\_ r -> r)
(\_ -> return ())
(\err -> expected "decompress ok" (show err))
assertDecompressOkChunks :: Handle -> DecompressStream IO -> IO [BS.ByteString]
assertDecompressOkChunks hnd =
foldDecompressStream
(BS.hGet hnd 4000 >>=)
(\chunk -> liftM (chunk:))
(\_ -> return [])
(\err -> expected "decompress ok" (show err))
assertDecompressError :: Handle -> DecompressStream IO -> IO DecompressError
assertDecompressError hnd =
foldDecompressStream
(BS.hGet hnd 4000 >>=)
(\_ r -> r)
(\_ -> expected "StreamError" "StreamEnd")
return
assertDataFormatError :: DecompressError -> IO String
assertDataFormatError (DataFormatError detail) = return detail
assertDataFormatError _ = assertFailure "expected DataError"
>> return ""

View File

@@ -0,0 +1,32 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | Test code and properties for "Codec.Compression.Zlib.Internal"
--
module Test.Codec.Compression.Zlib.Internal where
import Codec.Compression.Zlib.Internal
import Test.Codec.Compression.Zlib.Stream ()
import Test.QuickCheck
import Control.Monad (ap)
instance Arbitrary CompressParams where
arbitrary = return CompressParams `ap` arbitrary `ap` arbitrary
`ap` arbitrary `ap` arbitrary
`ap` arbitrary `ap` arbitraryBufferSize
`ap` return Nothing
arbitraryBufferSize :: Gen Int
arbitraryBufferSize = frequency $ [(10, return n) | n <- [1..1024]] ++
[(20, return n) | n <- [1025..8192]] ++
[(40, return n) | n <- [8193..131072]] ++
[(1, return n) | n <- [131072..1048576]]
instance Arbitrary DecompressParams where
arbitrary = return DecompressParams `ap` arbitrary
`ap` arbitraryBufferSize
`ap` return Nothing
`ap` arbitrary

View File

@@ -0,0 +1,40 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | Test code and properties for "Codec.Compression.Zlib.Stream"
--
module Test.Codec.Compression.Zlib.Stream where
import Codec.Compression.Zlib.Internal
import Test.QuickCheck
instance Arbitrary Format where
-- GZipOrZlib omitted since it's not symmetric
arbitrary = elements [gzipFormat, zlibFormat, rawFormat]
instance Arbitrary Method where
arbitrary = return deflateMethod
instance Arbitrary CompressionLevel where
arbitrary = elements $ [defaultCompression, noCompression,
bestCompression, bestSpeed]
++ map compressionLevel [1..9]
instance Arbitrary WindowBits where
arbitrary = elements $ defaultWindowBits:map windowBits [9..15]
instance Arbitrary MemoryLevel where
arbitrary = elements $ [defaultMemoryLevel, minMemoryLevel, maxMemoryLevel]
++ [memoryLevel n | n <- [1..9]]
instance Arbitrary CompressionStrategy where
arbitrary = elements $ [defaultStrategy, filteredStrategy, huffmanOnlyStrategy]
-- These are disabled by default in the package
-- as they are only available with zlib >=1.2
-- ++ [RLE, Fixed]

28
3rdparty/zlib/test/Utils.hs vendored Normal file
View File

@@ -0,0 +1,28 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Utils where
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString as BS
import Test.QuickCheck
-------------------
-- QuickCheck Utils
maxStrSize :: Double
maxStrSize = 500
-- convert a QC size parameter into one for generating long lists,
-- growing inverse exponentially up to maxStrSize
strSize :: Int -> Int
strSize n = floor (maxStrSize * (1 - 2 ** (-fromIntegral n/100)))
instance Arbitrary BL.ByteString where
arbitrary = sized $ \sz -> fmap BL.fromChunks $ listOf $ resize (sz `div` 2) arbitrary
shrink = map BL.pack . shrink . BL.unpack
instance Arbitrary BS.ByteString where
arbitrary = sized $ \sz -> resize (strSize sz) $ fmap BS.pack $ listOf $ arbitrary
shrink = map BS.pack . shrink . BS.unpack

BIN
3rdparty/zlib/test/data/bad-crc.gz vendored Normal file

Binary file not shown.

BIN
3rdparty/zlib/test/data/custom-dict.zlib vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1 @@
Haskell

BIN
3rdparty/zlib/test/data/hello.gz vendored Normal file

Binary file not shown.

1
3rdparty/zlib/test/data/not-gzip vendored Normal file
View File

@@ -0,0 +1 @@
This is not a gzip file!

BIN
3rdparty/zlib/test/data/two-files.gz vendored Normal file

Binary file not shown.

14
3rdparty/zlib/test/gzip-compress.sh vendored Normal file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -e
for d in $*; do
# they don't actually produce the same output
# cmp <(./hsgzip < $d) <(gzip -c < $d)
cmp $d <(gzip -c < $d | gunzip -c) # just in case..
cmp $d <(gzip -c < $d | ./hsgunzip )
cmp $d <(./hsgzip < $d | gunzip -c)
cmp $d <(./hsgzip < $d | ./hsgunzip)
echo -n '.'
done
echo

16
3rdparty/zlib/test/gzip-uncompress.sh vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
for d in $*; do
if gunzip -c < $d &> /dev/null; then
if cmp <(./hsgunzip < $d) <(gunzip -c < $d) > /dev/null; then
echo -n '.'
else
echo '#'
echo "FAILED: $d"
exit 1
fi
else
echo -n '_'
fi
done
echo

11
3rdparty/zlib/test/zpipe-compress.sh vendored Normal file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
for d in $*; do
cmp <(./hszpipe < $d) <(./zpipe < $d)
cmp $d <(./zpipe < $d | ./zpipe -d) # just in case..
cmp $d <(./zpipe < $d | ./hszpipe -d)
echo -n .
done
echo

205
3rdparty/zlib/test/zpipe.c vendored Normal file
View File

@@ -0,0 +1,205 @@
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
Not copyrighted -- provided to the public domain
Version 1.4 11 December 2005 Mark Adler */
/* Version history:
1.0 30 Oct 2004 First version
1.1 8 Nov 2004 Add void casting for unused return values
Use switch statement for inflate() return values
1.2 9 Nov 2004 Add assertions to document zlib guarantees
1.3 6 Apr 2005 Remove incorrect assertion in inf()
1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
Avoid some compiler warnings for input and output buffers
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "zlib.h"
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
# include <fcntl.h>
# include <io.h>
# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
#else
# define SET_BINARY_MODE(file)
#endif
#define CHUNK 16384
/* Compress from file source to file dest until EOF on source.
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_STREAM_ERROR if an invalid compression
level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
version of the library linked do not match, or Z_ERRNO if there is
an error reading or writing the files. */
int def(FILE *source, FILE *dest, int level)
{
int ret, flush;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate deflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, level);
if (ret != Z_OK)
return ret;
/* compress until end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
strm.next_in = in;
/* run deflate() on input until output buffer not full, finish
compression if all of source has been read in */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = deflate(&strm, flush); /* no bad return value */
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)deflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
assert(strm.avail_in == 0); /* all input will be used */
/* done when last data in file processed */
} while (flush != Z_FINISH);
assert(ret == Z_STREAM_END); /* stream will be complete */
/* clean up and return */
(void)deflateEnd(&strm);
return Z_OK;
}
/* Decompress from file source to file dest until stream ends or EOF.
inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
allocated for processing, Z_DATA_ERROR if the deflate data is
invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
the version of the library linked do not match, or Z_ERRNO if there
is an error reading or writing the files. */
int inf(FILE *source, FILE *dest)
{
int ret;
unsigned have;
z_stream strm;
unsigned char in[CHUNK];
unsigned char out[CHUNK];
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
/* decompress until deflate stream ends or end of file */
do {
strm.avail_in = fread(in, 1, CHUNK, source);
if (ferror(source)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
if (strm.avail_in == 0)
break;
strm.next_in = in;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
(void)inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
(void)inflateEnd(&strm);
return Z_ERRNO;
}
} while (strm.avail_out == 0);
/* done when inflate() says it's done */
} while (ret != Z_STREAM_END);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
/* report a zlib or i/o error */
void zerr(int ret)
{
fputs("zpipe: ", stderr);
switch (ret) {
case Z_ERRNO:
if (ferror(stdin))
fputs("error reading stdin\n", stderr);
if (ferror(stdout))
fputs("error writing stdout\n", stderr);
break;
case Z_STREAM_ERROR:
fputs("invalid compression level\n", stderr);
break;
case Z_DATA_ERROR:
fputs("invalid or incomplete deflate data\n", stderr);
break;
case Z_MEM_ERROR:
fputs("out of memory\n", stderr);
break;
case Z_VERSION_ERROR:
fputs("zlib version mismatch!\n", stderr);
}
}
/* compress or decompress from stdin to stdout */
int main(int argc, char **argv)
{
int ret;
/* avoid end-of-line conversions */
SET_BINARY_MODE(stdin);
SET_BINARY_MODE(stdout);
/* do compression if no arguments */
if (argc == 1) {
ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* do decompression if -d specified */
else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
ret = inf(stdin, stdout);
if (ret != Z_OK)
zerr(ret);
return ret;
}
/* otherwise, report usage */
else {
fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
return 1;
}
}