PROG= vndcompress SRCS= main.c offtab.c utils.c vndcompress.c vnduncompress.c LINKS= ${BINDIR}/vndcompress ${BINDIR}/vnduncompress MLINKS= vndcompress.1 vnduncompress.1 DPADD+= ${LIBZ} LDADD+= -lz WARNS= 5 .include TESTFILES+= oneblock XFAIL+= oneblock.in-outx XFAIL+= oneblock.cl2-cl2x oneblock.in: head -c 512 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= tenblock XFAIL+= tenblock.in-outx XFAIL+= tenblock.cl2-cl2x tenblock.in: head -c 5120 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= smallfile XFAIL+= smallfile.in-outx XFAIL+= smallfile.cl2-cl2x smallfile.in: head -c 12345 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} CHECKS+= check-pipe CLEANFILES+= smallfile.cl2pipe check-pipe: .PHONY smallfile.cl2 smallfile.cl2pipe cmp ${.ALLSRC} smallfile.cl2pipe: smallfile.in vndcompress head -c 54321 < /usr/share/dict/words \ | ./vndcompress -l 12345 /dev/stdin ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= onechunk onechunk.in: head -c 65536 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= tenchunk tenchunk.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= extrablock XFAIL+= extrablock.in-outx XFAIL+= extrablock.cl2-cl2x extrablock.in: head -c $$((65536 + 512)) < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= medfile XFAIL+= medfile.in-outx XFAIL+= medfile.cl2-cl2x medfile.in: head -c 123456 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= onetinyblock BLOCKSIZE.onetinyblock= 512 onetinyblock.in: head -c 512 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= tentinyblock BLOCKSIZE.tentinyblock= 512 tentinyblock.in: head -c 5120 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # Make sure we can restart from a pipe. CHECKS+= check-pipe-restart CLEANFILES+= piperestart.in piperestart.in.tmp CLEANFILES+= piperestart.cl2 piperestart.cl2.tmp CLEANFILES+= piperestart.cl2restart piperestart.cl2restart.tmp CLEANFILES+= piperestart.cl2part piperestart.cl2part.tmp check-pipe-restart: .PHONY piperestart.cl2 piperestart.cl2restart cmp ${.ALLSRC} piperestart.cl2restart: piperestart.cl2part vndcompress cp piperestart.cl2part ${.TARGET}.tmp \ && head -c 700000 < /usr/share/dict/words \ | ./vndcompress -l 655360 -k 1 -r -R /dev/stdin ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # The following rule uses ; and not && on purpose: vndcompress is # supposed to fail (and it is even OK to interrupt!) so we can restart # and fill in the rest. piperestart.cl2part: vndcompress head -c 600000 < /usr/share/dict/words \ | ./vndcompress -l 655360 -k 1 /dev/stdin ${.TARGET}.tmp; \ mv -f ${.TARGET}.tmp ${.TARGET} piperestart.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # Make sure we can restart from a pipe even if the original start was # corrupted, as long as we don't pass -R. CHECKS+= check-pipe-badstart CLEANFILES+= pipebadstart.in pipebadstart.in.tmp CLEANFILES+= pipebadstart.cl2 pipebadstart.cl2.tmp CLEANFILES+= pipebadstart.cl2restart pipebadstart.cl2restart.tmp CLEANFILES+= pipebadstart.cl2part pipebadstart.cl2part.tmp check-pipe-badstart: .PHONY pipebadstart.cl2 pipebadstart.cl2restart cmp ${.ALLSRC} pipebadstart.cl2restart: pipebadstart.cl2part vndcompress cp pipebadstart.cl2part ${.TARGET}.tmp \ && head -c 700000 < /usr/share/dict/words \ | ./vndcompress -l 655360 -k 1 -r /dev/stdin ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} pipebadstart.cl2part: touch ${.TARGET} pipebadstart.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # Make sure we can `restart' even if there's nothing there. CHECKS+= check-pipe-falsestart CLEANFILES+= pipefalsestart.in pipefalsestart.in.tmp CLEANFILES+= pipefalsestart.cl2 pipefalsestart.cl2.tmp CLEANFILES+= pipefalsestart.cl2restart pipefalsestart.cl2restart.tmp check-pipe-falsestart: .PHONY pipefalsestart.cl2 pipefalsestart.cl2restart cmp ${.ALLSRC} pipefalsestart.cl2restart: vndcompress rm -f ${.TARGET}.tmp \ && head -c 700000 < /usr/share/dict/words \ | ./vndcompress -l 655360 -k 1 -r /dev/stdin ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} pipefalsestart.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # Make sure we can restart from a file, simulated with `-p'. CHECKS+= check-part CLEANFILES+= part.orig part.orig.tmp CLEANFILES+= part.cl2part part.cl2part.tmp CLEANFILES+= part.cl2 part.cl2.tmp CLEANFILES+= part.out part.out.tmp check-part: .PHONY part.orig part.out cmp part.orig part.out part.cl2: part.orig part.cl2part vndcompress cp part.cl2part ${.TARGET}.tmp \ && ./vndcompress -b 512 -r -R part.orig ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} part.cl2part: part.orig vndcompress ./vndcompress -b 512 -p 10 part.orig ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} part.orig: head -c 12345 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} # Make sure we can `restart' even if there's nothing there. CHECKS+= check-falsestart CLEANFILES+= falsestart.in falsestart.in.tmp CLEANFILES+= falsestart.cl2 falsestart.cl2.tmp CLEANFILES+= falsestart.cl2restart falsestart.cl2restart.tmp check-falsestart: .PHONY falsestart.cl2 falsestart.cl2restart cmp ${.ALLSRC} falsestart.cl2restart: vndcompress falsestart.in rm -f ${.TARGET}.tmp \ && ./vndcompress -r falsestart.in ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} falsestart.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} TESTFILES+= smallwindow smallwindow.in: head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} smallwindow.cl2: smallwindow.in ./vndcompress -w 1 ${.IMPSRC} ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} smallwindow.out: smallwindow.cl2 ./vndcompress -w 1 -d ${.IMPSRC} ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} CHECKS+= check-pipewindow check-pipewindow: smallwindow.cl2 @echo '# expecting failure...' if cat smallwindow.cl2 | ./vndcompress -w 1 -d /dev/stdin /dev/null; \ then \ echo 'unexpected pass!' && exit 1; \ fi # The following two tests try to ensure a limited window size means # limited memory allocation. They don't work very well. The virtual # address space rlimit (ulimit -v, RLIMIT_AS) must cover the stack size # that is allocated automatically for the process, which varies from # machine architecture to machine architecture (the kernel's MAXSSIZ # parameter), as well as any shared libraries that get loaded in and # other auxiliary crud the loader or libc might allocate. # # In principle, the overhead from that and the program image should be # constant, and the only substantial memory allocation performed by # vndcompress should be w*8 bytes or (n/b)*8, where w is the window # size if specified, n is the size of the input, and b is the block # size. # # We could perhaps do an exponential growth and then binary search on # the virtual address space limit to determine the overhead, but that's # more trouble than I care to do in a makefile right now. Currently # this is calibrated for NetBSD/amd64 6, where 128 MB of virtual # address space is allocated for the stack. (Note `ulimit -v' takes a # number of kilobytes, not a number of bytes.) Since this is not # reliable, however, these are commented out. #CHECKS+= check-ulimit #check-ulimit: # @echo '# expecting failure...' # if head -c $$((64 * 1024 * 1024)) < /dev/zero \ # | (ulimit -v $$((139 * 1024)) && \ # ./vndcompress -w 0 -l 64m -b 512 /dev/stdin /dev/null); then \ # echo 'unexpected pass!' && exit 1; \ # fi # #CHECKS+= check-ulimit-window #check-ulimit-window: # head -c $$((64 * 1024 * 1024)) < /dev/zero \ # | (ulimit -v $$((139 * 1024)) && \ # ./vndcompress -w 8192 -l 64m -b 512 /dev/stdin /dev/null) TESTSUFFIXES+= in cl2 cl2x out outx TESTFORMS+= cl2 cl2x TESTFORMS+= in out TESTFORMS+= in outx .for testfile in ${TESTFILES} . for suffix in ${TESTSUFFIXES} CLEANFILES+= ${testfile}.${suffix} CLEANFILES+= ${testfile}.${suffix}.tmp . endfor . for left right in ${TESTFORMS} CHECKS.${testfile}+= check-${testfile}.${left}-${right} check-${testfile}.${left}-${right}: .PHONY \ ${testfile}.${left} ${testfile}.${right} . if empty(XFAIL:M${testfile}.${left}-${right}) cmp ${testfile}.${left} ${testfile}.${right} . else @echo '# expecting failure...' \ && echo 'cmp ${testfile}.${left} ${testfile}.${right}' \ && if cmp ${testfile}.${left} ${testfile}.${right}; then \ echo 'unexpected pass!' \ && exit 1; \ fi . endif . endfor check-${testfile}: ${CHECKS.${testfile}} CHECKS+= check-${testfile} .endfor check: .PHONY ${CHECKS} .SUFFIXES: .cl2 .cl2x .in .out .outx # XXX These tests should automatically try different window sizes, but # that is tricky to express in make. .in.cl2: vndcompress ./vndcompress ${.IMPSRC} ${.TARGET}.tmp ${BLOCKSIZE.${.PREFIX}} \ && mv -f ${.TARGET}.tmp ${.TARGET} .in.cl2x: vndcompress ${.IMPSRC} ${.TARGET}.tmp ${BLOCKSIZE.${.PREFIX}} \ && mv -f ${.TARGET}.tmp ${.TARGET} .cl2.out: vndcompress ./vndcompress -d ${.IMPSRC} ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET} .cl2.outx: vnduncompress ${.IMPSRC} ${.TARGET}.tmp \ && mv -f ${.TARGET}.tmp ${.TARGET}