1PROG=	vndcompress
2SRCS=	main.c offtab.c utils.c vndcompress.c vnduncompress.c
3
4LINKS=	${BINDIR}/vndcompress ${BINDIR}/vnduncompress
5MLINKS=	vndcompress.1 vnduncompress.1
6
7DPADD+=	${LIBZ}
8LDADD+=	-lz
9
10WARNS=	5
11
12.include <bsd.prog.mk>
13
14TESTFILES+=	oneblock
15XFAIL+=		oneblock.in-outx
16XFAIL+=		oneblock.cl2-cl2x
17oneblock.in:
18	head -c 512 < /usr/share/dict/words > ${.TARGET}.tmp \
19	&& mv -f ${.TARGET}.tmp ${.TARGET}
20
21TESTFILES+=	tenblock
22XFAIL+=		tenblock.in-outx
23XFAIL+=		tenblock.cl2-cl2x
24tenblock.in:
25	head -c 5120 < /usr/share/dict/words > ${.TARGET}.tmp \
26	&& mv -f ${.TARGET}.tmp ${.TARGET}
27
28TESTFILES+=	smallfile
29XFAIL+=		smallfile.in-outx
30XFAIL+=		smallfile.cl2-cl2x
31smallfile.in:
32	head -c 12345 < /usr/share/dict/words > ${.TARGET}.tmp \
33	&& mv -f ${.TARGET}.tmp ${.TARGET}
34
35CHECKS+=	check-pipe
36CLEANFILES+=	smallfile.cl2pipe
37check-pipe: .PHONY smallfile.cl2 smallfile.cl2pipe
38	cmp ${.ALLSRC}
39smallfile.cl2pipe: smallfile.in vndcompress
40	head -c 54321 < /usr/share/dict/words \
41	| ./vndcompress -l 12345 /dev/stdin ${.TARGET}.tmp \
42	&& mv -f ${.TARGET}.tmp ${.TARGET}
43
44TESTFILES+=	onechunk
45onechunk.in:
46	head -c 65536 < /usr/share/dict/words > ${.TARGET}.tmp \
47	&& mv -f ${.TARGET}.tmp ${.TARGET}
48
49TESTFILES+=	tenchunk
50tenchunk.in:
51	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
52	&& mv -f ${.TARGET}.tmp ${.TARGET}
53
54TESTFILES+=	extrablock
55XFAIL+=		extrablock.in-outx
56XFAIL+=		extrablock.cl2-cl2x
57extrablock.in:
58	head -c $$((65536 + 512)) < /usr/share/dict/words > ${.TARGET}.tmp \
59	&& mv -f ${.TARGET}.tmp ${.TARGET}
60
61TESTFILES+=	medfile
62XFAIL+=		medfile.in-outx
63XFAIL+=		medfile.cl2-cl2x
64medfile.in:
65	head -c 123456 < /usr/share/dict/words > ${.TARGET}.tmp \
66	&& mv -f ${.TARGET}.tmp ${.TARGET}
67
68TESTFILES+=		onetinyblock
69BLOCKSIZE.onetinyblock=	512
70onetinyblock.in:
71	head -c 512 < /usr/share/dict/words > ${.TARGET}.tmp \
72	&& mv -f ${.TARGET}.tmp ${.TARGET}
73
74TESTFILES+=		tentinyblock
75BLOCKSIZE.tentinyblock=	512
76tentinyblock.in:
77	head -c 5120 < /usr/share/dict/words > ${.TARGET}.tmp \
78	&& mv -f ${.TARGET}.tmp ${.TARGET}
79
80# Make sure we can restart from a pipe.
81CHECKS+=	check-pipe-restart
82CLEANFILES+=	piperestart.in piperestart.in.tmp
83CLEANFILES+=	piperestart.cl2 piperestart.cl2.tmp
84CLEANFILES+=	piperestart.cl2restart piperestart.cl2restart.tmp
85CLEANFILES+=	piperestart.cl2part piperestart.cl2part.tmp
86check-pipe-restart: .PHONY piperestart.cl2 piperestart.cl2restart
87	cmp ${.ALLSRC}
88piperestart.cl2restart: piperestart.cl2part vndcompress
89	cp piperestart.cl2part ${.TARGET}.tmp \
90	&& head -c 700000 < /usr/share/dict/words \
91	| ./vndcompress -l 655360 -k 1 -r -R /dev/stdin ${.TARGET}.tmp \
92	&& mv -f ${.TARGET}.tmp ${.TARGET}
93# The following rule uses ; and not && on purpose: vndcompress is
94# supposed to fail (and it is even OK to interrupt!) so we can restart
95# and fill in the rest.
96piperestart.cl2part: vndcompress
97	head -c 600000 < /usr/share/dict/words \
98	| ./vndcompress -l 655360 -k 1 /dev/stdin ${.TARGET}.tmp; \
99	mv -f ${.TARGET}.tmp ${.TARGET}
100piperestart.in:
101	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
102	&& mv -f ${.TARGET}.tmp ${.TARGET}
103
104# Make sure we can restart from a pipe even if the original start was
105# corrupted, as long as we don't pass -R.
106CHECKS+=	check-pipe-badstart
107CLEANFILES+=	pipebadstart.in pipebadstart.in.tmp
108CLEANFILES+=	pipebadstart.cl2 pipebadstart.cl2.tmp
109CLEANFILES+=	pipebadstart.cl2restart pipebadstart.cl2restart.tmp
110CLEANFILES+=	pipebadstart.cl2part pipebadstart.cl2part.tmp
111check-pipe-badstart: .PHONY pipebadstart.cl2 pipebadstart.cl2restart
112	cmp ${.ALLSRC}
113pipebadstart.cl2restart: pipebadstart.cl2part vndcompress
114	cp pipebadstart.cl2part ${.TARGET}.tmp \
115	&& head -c 700000 < /usr/share/dict/words \
116	| ./vndcompress -l 655360 -k 1 -r /dev/stdin ${.TARGET}.tmp \
117	&& mv -f ${.TARGET}.tmp ${.TARGET}
118pipebadstart.cl2part:
119	touch ${.TARGET}
120pipebadstart.in:
121	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
122	&& mv -f ${.TARGET}.tmp ${.TARGET}
123
124# Make sure we can `restart' even if there's nothing there.
125CHECKS+=	check-pipe-falsestart
126CLEANFILES+=	pipefalsestart.in pipefalsestart.in.tmp
127CLEANFILES+=	pipefalsestart.cl2 pipefalsestart.cl2.tmp
128CLEANFILES+=	pipefalsestart.cl2restart pipefalsestart.cl2restart.tmp
129check-pipe-falsestart: .PHONY pipefalsestart.cl2 pipefalsestart.cl2restart
130	cmp ${.ALLSRC}
131pipefalsestart.cl2restart: vndcompress
132	rm -f ${.TARGET}.tmp \
133	&& head -c 700000 < /usr/share/dict/words \
134	| ./vndcompress -l 655360 -k 1 -r /dev/stdin ${.TARGET}.tmp \
135	&& mv -f ${.TARGET}.tmp ${.TARGET}
136pipefalsestart.in:
137	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
138	&& mv -f ${.TARGET}.tmp ${.TARGET}
139
140# Make sure we can restart from a file, simulated with `-p'.
141CHECKS+=	check-part
142CLEANFILES+=	part.orig part.orig.tmp
143CLEANFILES+=	part.cl2part part.cl2part.tmp
144CLEANFILES+=	part.cl2 part.cl2.tmp
145CLEANFILES+=	part.out part.out.tmp
146check-part: .PHONY part.orig part.out
147	cmp part.orig part.out
148part.cl2: part.orig part.cl2part vndcompress
149	cp part.cl2part ${.TARGET}.tmp \
150	&& ./vndcompress -b 512 -r -R part.orig ${.TARGET}.tmp \
151	&& mv -f ${.TARGET}.tmp ${.TARGET}
152part.cl2part: part.orig vndcompress
153	./vndcompress -b 512 -p 10 part.orig ${.TARGET}.tmp \
154	&& mv -f ${.TARGET}.tmp ${.TARGET}
155part.orig:
156	head -c 12345 < /usr/share/dict/words > ${.TARGET}.tmp \
157	&& mv -f ${.TARGET}.tmp ${.TARGET}
158
159# Make sure we can `restart' even if there's nothing there.
160CHECKS+=	check-falsestart
161CLEANFILES+=	falsestart.in falsestart.in.tmp
162CLEANFILES+=	falsestart.cl2 falsestart.cl2.tmp
163CLEANFILES+=	falsestart.cl2restart falsestart.cl2restart.tmp
164check-falsestart: .PHONY falsestart.cl2 falsestart.cl2restart
165	cmp ${.ALLSRC}
166falsestart.cl2restart: vndcompress falsestart.in
167	rm -f ${.TARGET}.tmp \
168	&& ./vndcompress -r falsestart.in ${.TARGET}.tmp \
169	&& mv -f ${.TARGET}.tmp ${.TARGET}
170falsestart.in:
171	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
172	&& mv -f ${.TARGET}.tmp ${.TARGET}
173
174TESTFILES+=	smallwindow
175smallwindow.in:
176	head -c 655360 < /usr/share/dict/words > ${.TARGET}.tmp \
177	&& mv -f ${.TARGET}.tmp ${.TARGET}
178smallwindow.cl2: smallwindow.in
179	./vndcompress -w 1 ${.IMPSRC} ${.TARGET}.tmp \
180	&& mv -f ${.TARGET}.tmp ${.TARGET}
181smallwindow.out: smallwindow.cl2
182	./vndcompress -w 1 -d ${.IMPSRC} ${.TARGET}.tmp \
183	&& mv -f ${.TARGET}.tmp ${.TARGET}
184
185CHECKS+=	check-pipewindow
186check-pipewindow: smallwindow.cl2
187	@echo '# expecting failure...'
188	if cat smallwindow.cl2 | ./vndcompress -w 1 -d /dev/stdin /dev/null; \
189	then \
190	  echo 'unexpected pass!' && exit 1; \
191	fi
192
193# The following two tests try to ensure a limited window size means
194# limited memory allocation.  They don't work very well.  The virtual
195# address space rlimit (ulimit -v, RLIMIT_AS) must cover the stack size
196# that is allocated automatically for the process, which varies from
197# machine architecture to machine architecture (the kernel's MAXSSIZ
198# parameter), as well as any shared libraries that get loaded in and
199# other auxiliary crud the loader or libc might allocate.
200#
201# In principle, the overhead from that and the program image should be
202# constant, and the only substantial memory allocation performed by
203# vndcompress should be w*8 bytes or (n/b)*8, where w is the window
204# size if specified, n is the size of the input, and b is the block
205# size.
206#
207# We could perhaps do an exponential growth and then binary search on
208# the virtual address space limit to determine the overhead, but that's
209# more trouble than I care to do in a makefile right now.  Currently
210# this is calibrated for NetBSD/amd64 6, where 128 MB of virtual
211# address space is allocated for the stack.  (Note `ulimit -v' takes a
212# number of kilobytes, not a number of bytes.)  Since this is not
213# reliable, however, these are commented out.
214
215#CHECKS+=	check-ulimit
216#check-ulimit:
217#	@echo '# expecting failure...'
218#	if head -c $$((64 * 1024 * 1024)) < /dev/zero \
219#	    | (ulimit -v $$((139 * 1024)) && \
220#	        ./vndcompress -w 0 -l 64m -b 512 /dev/stdin /dev/null); then \
221#	  echo 'unexpected pass!' && exit 1; \
222#	fi
223#
224#CHECKS+=	check-ulimit-window
225#check-ulimit-window:
226#	head -c $$((64 * 1024 * 1024)) < /dev/zero \
227#	| (ulimit -v $$((139 * 1024)) && \
228#	    ./vndcompress -w 8192 -l 64m -b 512 /dev/stdin /dev/null)
229
230TESTSUFFIXES+=	in cl2 cl2x out outx
231
232TESTFORMS+=	cl2 cl2x
233TESTFORMS+=	in out
234TESTFORMS+=	in outx
235
236.for testfile in ${TESTFILES}
237.  for suffix in ${TESTSUFFIXES}
238CLEANFILES+=	${testfile}.${suffix}
239CLEANFILES+=	${testfile}.${suffix}.tmp
240.  endfor
241.  for left right in ${TESTFORMS}
242CHECKS.${testfile}+=	check-${testfile}.${left}-${right}
243check-${testfile}.${left}-${right}: .PHONY \
244  ${testfile}.${left} ${testfile}.${right}
245.    if empty(XFAIL:M${testfile}.${left}-${right})
246	cmp ${testfile}.${left} ${testfile}.${right}
247.    else
248	@echo '# expecting failure...' \
249	&& echo 'cmp ${testfile}.${left} ${testfile}.${right}' \
250	&& if cmp ${testfile}.${left} ${testfile}.${right}; then \
251	  echo 'unexpected pass!' \
252	  && exit 1; \
253	fi
254.    endif
255.  endfor
256check-${testfile}: ${CHECKS.${testfile}}
257CHECKS+=	check-${testfile}
258.endfor
259
260check: .PHONY ${CHECKS}
261
262.SUFFIXES: .cl2 .cl2x .in .out .outx
263
264# XXX These tests should automatically try different window sizes, but
265# that is tricky to express in make.
266
267.in.cl2: vndcompress
268	./vndcompress ${.IMPSRC} ${.TARGET}.tmp ${BLOCKSIZE.${.PREFIX}} \
269	&& mv -f ${.TARGET}.tmp ${.TARGET}
270
271.in.cl2x:
272	vndcompress ${.IMPSRC} ${.TARGET}.tmp ${BLOCKSIZE.${.PREFIX}} \
273	&& mv -f ${.TARGET}.tmp ${.TARGET}
274
275.cl2.out: vndcompress
276	./vndcompress -d ${.IMPSRC} ${.TARGET}.tmp \
277	&& mv -f ${.TARGET}.tmp ${.TARGET}
278
279.cl2.outx:
280	vnduncompress ${.IMPSRC} ${.TARGET}.tmp \
281	&& mv -f ${.TARGET}.tmp ${.TARGET}
282