1*433d6423SLionel Sambuc /* compress - Reduce file size using Modified Lempel-Ziv encoding */
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc /*
4*433d6423SLionel Sambuc * compress.c - File compression ala IEEE Computer, June 1984.
5*433d6423SLionel Sambuc *
6*433d6423SLionel Sambuc * Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
7*433d6423SLionel Sambuc * Jim McKie (decvax!mcvax!jim)
8*433d6423SLionel Sambuc * Steve Davies (decvax!vax135!petsd!peora!srd)
9*433d6423SLionel Sambuc * Ken Turkowski (decvax!decwrl!turtlevax!ken)
10*433d6423SLionel Sambuc * James A. Woods (decvax!ihnp4!ames!jaw)
11*433d6423SLionel Sambuc * Joe Orost (decvax!vax135!petsd!joe)
12*433d6423SLionel Sambuc *
13*433d6423SLionel Sambuc * Richard Todd Port to MINIX
14*433d6423SLionel Sambuc * Andy Tanenbaum Cleanup
15*433d6423SLionel Sambuc *
16*433d6423SLionel Sambuc *
17*433d6423SLionel Sambuc * Algorithm from "A Technique for High Performance Data Compression",
18*433d6423SLionel Sambuc * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.
19*433d6423SLionel Sambuc *
20*433d6423SLionel Sambuc * Usage: compress [-dfvc] [-b bits] [file ...]
21*433d6423SLionel Sambuc * Inputs:
22*433d6423SLionel Sambuc * -d: If given, decompression is done instead.
23*433d6423SLionel Sambuc *
24*433d6423SLionel Sambuc * -c: Write output on stdout.
25*433d6423SLionel Sambuc *
26*433d6423SLionel Sambuc * -b: Parameter limits the max number of bits/code.
27*433d6423SLionel Sambuc *
28*433d6423SLionel Sambuc * -f: Forces output file to be generated, even if one already
29*433d6423SLionel Sambuc * exists, and even if no space is saved by compressing.
30*433d6423SLionel Sambuc * If -f is not used, the user will be prompted if stdin is
31*433d6423SLionel Sambuc * a tty, otherwise, the output file will not be overwritten.
32*433d6423SLionel Sambuc *
33*433d6423SLionel Sambuc * -v: Write compression statistics
34*433d6423SLionel Sambuc *
35*433d6423SLionel Sambuc * file ...: Files to be compressed. If none specified, stdin
36*433d6423SLionel Sambuc * is used.
37*433d6423SLionel Sambuc * Outputs:
38*433d6423SLionel Sambuc * file.Z: Compressed form of file with same mode, owner, and utimes
39*433d6423SLionel Sambuc * or stdout (if stdin used as input)
40*433d6423SLionel Sambuc *
41*433d6423SLionel Sambuc * Assumptions:
42*433d6423SLionel Sambuc * When filenames are given, replaces with the compressed version
43*433d6423SLionel Sambuc * (.Z suffix) only if the file decreases in size.
44*433d6423SLionel Sambuc * Algorithm:
45*433d6423SLionel Sambuc * Modified Lempel-Ziv method (LZW). Basically finds common
46*433d6423SLionel Sambuc * substrings and replaces them with a variable size code. This is
47*433d6423SLionel Sambuc * deterministic, and can be done on the fly. Thus, the decompression
48*433d6423SLionel Sambuc * procedure needs no input table, but tracks the way the table was built.
49*433d6423SLionel Sambuc */
50*433d6423SLionel Sambuc
51*433d6423SLionel Sambuc
52*433d6423SLionel Sambuc #define AZTEC86 1
53*433d6423SLionel Sambuc
54*433d6423SLionel Sambuc #define min(a,b) ((a>b) ? b : a)
55*433d6423SLionel Sambuc
56*433d6423SLionel Sambuc /*
57*433d6423SLionel Sambuc * Set USERMEM to the maximum amount of physical user memory available
58*433d6423SLionel Sambuc * in bytes. USERMEM is used to determine the maximum BITS that can be used
59*433d6423SLionel Sambuc * for compression.
60*433d6423SLionel Sambuc *
61*433d6423SLionel Sambuc * SACREDMEM is the amount of physical memory saved for others; compress
62*433d6423SLionel Sambuc * will hog the rest.
63*433d6423SLionel Sambuc */
64*433d6423SLionel Sambuc #ifndef SACREDMEM
65*433d6423SLionel Sambuc #define SACREDMEM 0
66*433d6423SLionel Sambuc #endif
67*433d6423SLionel Sambuc
68*433d6423SLionel Sambuc #ifndef USERMEM
69*433d6423SLionel Sambuc # define USERMEM 450000 /* default user memory */
70*433d6423SLionel Sambuc #endif
71*433d6423SLionel Sambuc
72*433d6423SLionel Sambuc #define REGISTER register
73*433d6423SLionel Sambuc #define DOTZ ".Z"
74*433d6423SLionel Sambuc
75*433d6423SLionel Sambuc #include <limits.h>
76*433d6423SLionel Sambuc #include <dirent.h>
77*433d6423SLionel Sambuc
78*433d6423SLionel Sambuc /* The default for Minix is -b13, but we can do -b16 if the machine can. */
79*433d6423SLionel Sambuc #define DEFAULTBITS 13
80*433d6423SLionel Sambuc #if INT_MAX == 32767
81*433d6423SLionel Sambuc # define BITS 13
82*433d6423SLionel Sambuc #else
83*433d6423SLionel Sambuc # define BITS 16
84*433d6423SLionel Sambuc #endif
85*433d6423SLionel Sambuc
86*433d6423SLionel Sambuc #ifdef USERMEM
87*433d6423SLionel Sambuc # if USERMEM >= (433484+SACREDMEM)
88*433d6423SLionel Sambuc # define PBITS 16
89*433d6423SLionel Sambuc # else
90*433d6423SLionel Sambuc # if USERMEM >= (229600+SACREDMEM)
91*433d6423SLionel Sambuc # define PBITS 15
92*433d6423SLionel Sambuc # else
93*433d6423SLionel Sambuc # if USERMEM >= (127536+SACREDMEM)
94*433d6423SLionel Sambuc # define PBITS 14
95*433d6423SLionel Sambuc # else
96*433d6423SLionel Sambuc # if USERMEM >= (73464+SACREDMEM)
97*433d6423SLionel Sambuc # define PBITS 13
98*433d6423SLionel Sambuc # else
99*433d6423SLionel Sambuc # define PBITS 12
100*433d6423SLionel Sambuc # endif
101*433d6423SLionel Sambuc # endif
102*433d6423SLionel Sambuc # endif
103*433d6423SLionel Sambuc # endif
104*433d6423SLionel Sambuc # undef USERMEM
105*433d6423SLionel Sambuc #endif /* USERMEM */
106*433d6423SLionel Sambuc
107*433d6423SLionel Sambuc #ifdef PBITS /* Preferred BITS for this memory size */
108*433d6423SLionel Sambuc # ifndef BITS
109*433d6423SLionel Sambuc # define BITS PBITS
110*433d6423SLionel Sambuc # endif
111*433d6423SLionel Sambuc #endif /* PBITS */
112*433d6423SLionel Sambuc
113*433d6423SLionel Sambuc #if BITS == 16
114*433d6423SLionel Sambuc # define HSIZE 69001 /* 95% occupancy */
115*433d6423SLionel Sambuc #endif
116*433d6423SLionel Sambuc #if BITS == 15
117*433d6423SLionel Sambuc # define HSIZE 35023 /* 94% occupancy */
118*433d6423SLionel Sambuc #endif
119*433d6423SLionel Sambuc #if BITS == 14
120*433d6423SLionel Sambuc # define HSIZE 18013 /* 91% occupancy */
121*433d6423SLionel Sambuc #endif
122*433d6423SLionel Sambuc #if BITS == 13
123*433d6423SLionel Sambuc # define HSIZE 9001 /* 91% occupancy */
124*433d6423SLionel Sambuc #endif
125*433d6423SLionel Sambuc #if BITS <= 12
126*433d6423SLionel Sambuc # define HSIZE 5003 /* 80% occupancy */
127*433d6423SLionel Sambuc #endif
128*433d6423SLionel Sambuc
129*433d6423SLionel Sambuc
130*433d6423SLionel Sambuc /*
131*433d6423SLionel Sambuc * a code_int must be able to hold 2**BITS values of type int, and also -1
132*433d6423SLionel Sambuc */
133*433d6423SLionel Sambuc #if BITS > 15
134*433d6423SLionel Sambuc typedef long int code_int;
135*433d6423SLionel Sambuc #else
136*433d6423SLionel Sambuc typedef int code_int;
137*433d6423SLionel Sambuc #endif
138*433d6423SLionel Sambuc
139*433d6423SLionel Sambuc #ifdef SIGNED_COMPARE_SLOW
140*433d6423SLionel Sambuc typedef unsigned long int count_int;
141*433d6423SLionel Sambuc typedef unsigned short int count_short;
142*433d6423SLionel Sambuc #else
143*433d6423SLionel Sambuc typedef long int count_int;
144*433d6423SLionel Sambuc #endif
145*433d6423SLionel Sambuc
146*433d6423SLionel Sambuc #ifdef NO_UCHAR
147*433d6423SLionel Sambuc typedef char char_type;
148*433d6423SLionel Sambuc #else
149*433d6423SLionel Sambuc typedef unsigned char char_type;
150*433d6423SLionel Sambuc #endif /* UCHAR */
151*433d6423SLionel Sambuc char_type magic_header[] = "\037\235"; /* 1F 9D */
152*433d6423SLionel Sambuc
153*433d6423SLionel Sambuc /* Defines for third byte of header */
154*433d6423SLionel Sambuc #define BIT_MASK 0x1f
155*433d6423SLionel Sambuc #define BLOCK_MASK 0x80
156*433d6423SLionel Sambuc /* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is
157*433d6423SLionel Sambuc a fourth header byte (for expansion).
158*433d6423SLionel Sambuc */
159*433d6423SLionel Sambuc #define INIT_BITS 9 /* initial number of bits/code */
160*433d6423SLionel Sambuc
161*433d6423SLionel Sambuc #include <sys/types.h>
162*433d6423SLionel Sambuc #include <sys/stat.h>
163*433d6423SLionel Sambuc #include <fcntl.h>
164*433d6423SLionel Sambuc #include <ctype.h>
165*433d6423SLionel Sambuc #include <signal.h>
166*433d6423SLionel Sambuc #include <stdlib.h>
167*433d6423SLionel Sambuc #include <string.h>
168*433d6423SLionel Sambuc #include <unistd.h>
169*433d6423SLionel Sambuc #include <utime.h>
170*433d6423SLionel Sambuc #include <stdio.h>
171*433d6423SLionel Sambuc
172*433d6423SLionel Sambuc #define ARGVAL() (*++(*argv) || (--argc && *++argv))
173*433d6423SLionel Sambuc
174*433d6423SLionel Sambuc int n_bits; /* number of bits/code */
175*433d6423SLionel Sambuc int maxbits = DEFAULTBITS; /* user settable max # bits/code */
176*433d6423SLionel Sambuc code_int maxcode; /* maximum code, given n_bits */
177*433d6423SLionel Sambuc code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */
178*433d6423SLionel Sambuc #ifdef COMPATIBLE /* But wrong! */
179*433d6423SLionel Sambuc # define MAXCODE(n_bits) (1 << (n_bits) - 1)
180*433d6423SLionel Sambuc #else
181*433d6423SLionel Sambuc # define MAXCODE(n_bits) ((1 << (n_bits)) - 1)
182*433d6423SLionel Sambuc #endif /* COMPATIBLE */
183*433d6423SLionel Sambuc
184*433d6423SLionel Sambuc #ifndef AZTEC86
185*433d6423SLionel Sambuc count_int htab [HSIZE];
186*433d6423SLionel Sambuc unsigned short codetab [HSIZE];
187*433d6423SLionel Sambuc #else
188*433d6423SLionel Sambuc count_int *htab;
189*433d6423SLionel Sambuc unsigned short *codetab;
190*433d6423SLionel Sambuc # define HTABSIZE ((size_t)(HSIZE*sizeof(count_int)))
191*433d6423SLionel Sambuc # define CODETABSIZE ((size_t)(HSIZE*sizeof(unsigned short)))
192*433d6423SLionel Sambuc
193*433d6423SLionel Sambuc
194*433d6423SLionel Sambuc #define htabof(i) htab[i]
195*433d6423SLionel Sambuc #define codetabof(i) codetab[i]
196*433d6423SLionel Sambuc #endif /* XENIX_16 */
197*433d6423SLionel Sambuc code_int hsize = HSIZE; /* for dynamic table sizing */
198*433d6423SLionel Sambuc count_int fsize;
199*433d6423SLionel Sambuc
200*433d6423SLionel Sambuc /*
201*433d6423SLionel Sambuc * To save much memory, we overlay the table used by compress() with those
202*433d6423SLionel Sambuc * used by decompress(). The tab_prefix table is the same size and type
203*433d6423SLionel Sambuc * as the codetab. The tab_suffix table needs 2**BITS characters. We
204*433d6423SLionel Sambuc * get this from the beginning of htab. The output stack uses the rest
205*433d6423SLionel Sambuc * of htab, and contains characters. There is plenty of room for any
206*433d6423SLionel Sambuc * possible stack (stack used to be 8000 characters).
207*433d6423SLionel Sambuc */
208*433d6423SLionel Sambuc
209*433d6423SLionel Sambuc #define tab_prefixof(i) codetabof(i)
210*433d6423SLionel Sambuc #ifdef XENIX_16
211*433d6423SLionel Sambuc # define tab_suffixof(i) ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
212*433d6423SLionel Sambuc # define de_stack ((char_type *)(htab2))
213*433d6423SLionel Sambuc #else /* Normal machine */
214*433d6423SLionel Sambuc # define tab_suffixof(i) ((char_type *)(htab))[i]
215*433d6423SLionel Sambuc # define de_stack ((char_type *)&tab_suffixof(1<<BITS))
216*433d6423SLionel Sambuc #endif /* XENIX_16 */
217*433d6423SLionel Sambuc
218*433d6423SLionel Sambuc code_int free_ent = 0; /* first unused entry */
219*433d6423SLionel Sambuc int exit_stat = 0;
220*433d6423SLionel Sambuc
221*433d6423SLionel Sambuc int main(int argc, char **argv);
222*433d6423SLionel Sambuc void Usage(void);
223*433d6423SLionel Sambuc void compress(void);
224*433d6423SLionel Sambuc void onintr(int dummy);
225*433d6423SLionel Sambuc void oops(int dummy);
226*433d6423SLionel Sambuc void output(code_int code);
227*433d6423SLionel Sambuc int foreground(void);
228*433d6423SLionel Sambuc void decompress(void);
229*433d6423SLionel Sambuc code_int getcode(void);
230*433d6423SLionel Sambuc void writeerr(void);
231*433d6423SLionel Sambuc void copystat(char *ifname, char *ofname);
232*433d6423SLionel Sambuc int foreground(void);
233*433d6423SLionel Sambuc void cl_block(void);
234*433d6423SLionel Sambuc void cl_hash(count_int hsize);
235*433d6423SLionel Sambuc void prratio(FILE *stream, long int num, long int den);
236*433d6423SLionel Sambuc void version(void);
237*433d6423SLionel Sambuc
Usage()238*433d6423SLionel Sambuc void Usage() {
239*433d6423SLionel Sambuc #ifdef DEBUG
240*433d6423SLionel Sambuc fprintf(stderr,"Usage: compress [-dDVfc] [-b maxbits] [file ...]\n");
241*433d6423SLionel Sambuc }
242*433d6423SLionel Sambuc int debug = 0;
243*433d6423SLionel Sambuc #else
244*433d6423SLionel Sambuc fprintf(stderr,"Usage: compress [-dfvcV] [-b maxbits] [file ...]\n");
245*433d6423SLionel Sambuc }
246*433d6423SLionel Sambuc #endif /* DEBUG */
247*433d6423SLionel Sambuc int nomagic = 0; /* Use a 3-byte magic number header, unless old file */
248*433d6423SLionel Sambuc int zcat_flg = 0; /* Write output on stdout, suppress messages */
249*433d6423SLionel Sambuc int quiet = 0; /* don't tell me about compression */
250*433d6423SLionel Sambuc
251*433d6423SLionel Sambuc /*
252*433d6423SLionel Sambuc * block compression parameters -- after all codes are used up,
253*433d6423SLionel Sambuc * and compression rate changes, start over.
254*433d6423SLionel Sambuc */
255*433d6423SLionel Sambuc int block_compress = BLOCK_MASK;
256*433d6423SLionel Sambuc int clear_flg = 0;
257*433d6423SLionel Sambuc long int ratio = 0;
258*433d6423SLionel Sambuc #define CHECK_GAP 10000 /* ratio check interval */
259*433d6423SLionel Sambuc count_int checkpoint = CHECK_GAP;
260*433d6423SLionel Sambuc /*
261*433d6423SLionel Sambuc * the next two codes should not be changed lightly, as they must not
262*433d6423SLionel Sambuc * lie within the contiguous general code space.
263*433d6423SLionel Sambuc */
264*433d6423SLionel Sambuc #define FIRST 257 /* first free entry */
265*433d6423SLionel Sambuc #define CLEAR 256 /* table clear output code */
266*433d6423SLionel Sambuc
267*433d6423SLionel Sambuc int force = 0;
268*433d6423SLionel Sambuc char ofname [100];
269*433d6423SLionel Sambuc #ifdef DEBUG
270*433d6423SLionel Sambuc int verbose = 0;
271*433d6423SLionel Sambuc #endif /* DEBUG */
272*433d6423SLionel Sambuc
273*433d6423SLionel Sambuc #ifndef METAWARE
274*433d6423SLionel Sambuc #ifdef AZTEC86
275*433d6423SLionel Sambuc void
276*433d6423SLionel Sambuc #else
277*433d6423SLionel Sambuc int
278*433d6423SLionel Sambuc #endif
279*433d6423SLionel Sambuc #ifndef __STDC__
280*433d6423SLionel Sambuc (*bgnd_flag)();
281*433d6423SLionel Sambuc #else
282*433d6423SLionel Sambuc (*bgnd_flag)(int);
283*433d6423SLionel Sambuc #endif
284*433d6423SLionel Sambuc #endif
285*433d6423SLionel Sambuc
286*433d6423SLionel Sambuc int do_decomp = 0;
287*433d6423SLionel Sambuc
288*433d6423SLionel Sambuc
main(argc,argv)289*433d6423SLionel Sambuc int main(argc, argv)
290*433d6423SLionel Sambuc int argc;
291*433d6423SLionel Sambuc char **argv;
292*433d6423SLionel Sambuc {
293*433d6423SLionel Sambuc int overwrite = 0; /* Do not overwrite unless given -f flag */
294*433d6423SLionel Sambuc char tempname[100];
295*433d6423SLionel Sambuc char **filelist, **fileptr;
296*433d6423SLionel Sambuc char *cp;
297*433d6423SLionel Sambuc struct stat statbuf;
298*433d6423SLionel Sambuc #ifndef METAWARE
299*433d6423SLionel Sambuc if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
300*433d6423SLionel Sambuc signal ( SIGINT, onintr );
301*433d6423SLionel Sambuc signal ( SIGSEGV, oops );
302*433d6423SLionel Sambuc }
303*433d6423SLionel Sambuc #endif
304*433d6423SLionel Sambuc #ifdef AZTEC86
305*433d6423SLionel Sambuc #ifdef METAWARE
306*433d6423SLionel Sambuc _setmode(NULL,_ALL_FILES_BINARY);
307*433d6423SLionel Sambuc _setmode(stdin,_BINARY);
308*433d6423SLionel Sambuc _setmode(stdout,_BINARY);
309*433d6423SLionel Sambuc _setmode(stderr,_TEXT);
310*433d6423SLionel Sambuc #endif
311*433d6423SLionel Sambuc if (NULL == (htab = (count_int *)malloc(HTABSIZE)))
312*433d6423SLionel Sambuc {
313*433d6423SLionel Sambuc fprintf(stderr,"Can't allocate htab\n");
314*433d6423SLionel Sambuc exit(1);
315*433d6423SLionel Sambuc }
316*433d6423SLionel Sambuc if (NULL == (codetab = (unsigned short *)malloc(CODETABSIZE)))
317*433d6423SLionel Sambuc {
318*433d6423SLionel Sambuc fprintf(stderr,"Can't allocate codetab\n");
319*433d6423SLionel Sambuc exit(1);
320*433d6423SLionel Sambuc }
321*433d6423SLionel Sambuc #endif
322*433d6423SLionel Sambuc #ifdef COMPATIBLE
323*433d6423SLionel Sambuc nomagic = 1; /* Original didn't have a magic number */
324*433d6423SLionel Sambuc #endif /* COMPATIBLE */
325*433d6423SLionel Sambuc
326*433d6423SLionel Sambuc filelist = fileptr = (char **)(malloc((size_t)(argc * sizeof(*argv))));
327*433d6423SLionel Sambuc *filelist = NULL;
328*433d6423SLionel Sambuc
329*433d6423SLionel Sambuc if((cp = strrchr(argv[0], '/')) != 0) {
330*433d6423SLionel Sambuc cp++;
331*433d6423SLionel Sambuc } else {
332*433d6423SLionel Sambuc cp = argv[0];
333*433d6423SLionel Sambuc }
334*433d6423SLionel Sambuc if(strcmp(cp, "uncompress") == 0) {
335*433d6423SLionel Sambuc do_decomp = 1;
336*433d6423SLionel Sambuc } else if(strcmp(cp, "zcat") == 0) {
337*433d6423SLionel Sambuc do_decomp = 1;
338*433d6423SLionel Sambuc zcat_flg = 1;
339*433d6423SLionel Sambuc }
340*433d6423SLionel Sambuc
341*433d6423SLionel Sambuc #ifdef BSD4_2
342*433d6423SLionel Sambuc /* 4.2BSD dependent - take it out if not */
343*433d6423SLionel Sambuc setlinebuf( stderr );
344*433d6423SLionel Sambuc #endif /* BSD4_2 */
345*433d6423SLionel Sambuc
346*433d6423SLionel Sambuc /* Argument Processing
347*433d6423SLionel Sambuc * All flags are optional.
348*433d6423SLionel Sambuc * -D => debug
349*433d6423SLionel Sambuc * -V => print Version; debug verbose
350*433d6423SLionel Sambuc * -d => do_decomp
351*433d6423SLionel Sambuc * -v => unquiet
352*433d6423SLionel Sambuc * -f => force overwrite of output file
353*433d6423SLionel Sambuc * -n => no header: useful to uncompress old files
354*433d6423SLionel Sambuc * -b maxbits => maxbits. If -b is specified, then maxbits MUST be
355*433d6423SLionel Sambuc * given also.
356*433d6423SLionel Sambuc * -c => cat all output to stdout
357*433d6423SLionel Sambuc * -C => generate output compatible with compress 2.0.
358*433d6423SLionel Sambuc * if a string is left, must be an input filename.
359*433d6423SLionel Sambuc */
360*433d6423SLionel Sambuc for (argc--, argv++; argc > 0; argc--, argv++)
361*433d6423SLionel Sambuc {
362*433d6423SLionel Sambuc if (**argv == '-')
363*433d6423SLionel Sambuc { /* A flag argument */
364*433d6423SLionel Sambuc while (*++(*argv))
365*433d6423SLionel Sambuc { /* Process all flags in this arg */
366*433d6423SLionel Sambuc switch (**argv)
367*433d6423SLionel Sambuc {
368*433d6423SLionel Sambuc #ifdef DEBUG
369*433d6423SLionel Sambuc case 'D':
370*433d6423SLionel Sambuc debug = 1;
371*433d6423SLionel Sambuc break;
372*433d6423SLionel Sambuc case 'V':
373*433d6423SLionel Sambuc verbose = 1;
374*433d6423SLionel Sambuc version();
375*433d6423SLionel Sambuc break;
376*433d6423SLionel Sambuc #else
377*433d6423SLionel Sambuc case 'V':
378*433d6423SLionel Sambuc version();
379*433d6423SLionel Sambuc break;
380*433d6423SLionel Sambuc #endif /* DEBUG */
381*433d6423SLionel Sambuc case 'v':
382*433d6423SLionel Sambuc quiet = 0;
383*433d6423SLionel Sambuc break;
384*433d6423SLionel Sambuc case 'd':
385*433d6423SLionel Sambuc do_decomp = 1;
386*433d6423SLionel Sambuc break;
387*433d6423SLionel Sambuc case 'f':
388*433d6423SLionel Sambuc case 'F':
389*433d6423SLionel Sambuc overwrite = 1;
390*433d6423SLionel Sambuc force = 1;
391*433d6423SLionel Sambuc break;
392*433d6423SLionel Sambuc case 'n':
393*433d6423SLionel Sambuc nomagic = 1;
394*433d6423SLionel Sambuc break;
395*433d6423SLionel Sambuc case 'C':
396*433d6423SLionel Sambuc block_compress = 0;
397*433d6423SLionel Sambuc break;
398*433d6423SLionel Sambuc case 'b':
399*433d6423SLionel Sambuc if (!ARGVAL())
400*433d6423SLionel Sambuc {
401*433d6423SLionel Sambuc fprintf(stderr, "Missing maxbits\n");
402*433d6423SLionel Sambuc Usage();
403*433d6423SLionel Sambuc exit(1);
404*433d6423SLionel Sambuc }
405*433d6423SLionel Sambuc maxbits = atoi(*argv);
406*433d6423SLionel Sambuc goto nextarg;
407*433d6423SLionel Sambuc case 'c':
408*433d6423SLionel Sambuc zcat_flg = 1;
409*433d6423SLionel Sambuc break;
410*433d6423SLionel Sambuc case 'q':
411*433d6423SLionel Sambuc quiet = 1;
412*433d6423SLionel Sambuc break;
413*433d6423SLionel Sambuc default:
414*433d6423SLionel Sambuc fprintf(stderr, "Unknown flag: '%c'; ", **argv);
415*433d6423SLionel Sambuc Usage();
416*433d6423SLionel Sambuc exit(1);
417*433d6423SLionel Sambuc }
418*433d6423SLionel Sambuc }
419*433d6423SLionel Sambuc }
420*433d6423SLionel Sambuc else
421*433d6423SLionel Sambuc { /* Input file name */
422*433d6423SLionel Sambuc *fileptr++ = *argv; /* Build input file list */
423*433d6423SLionel Sambuc *fileptr = NULL;
424*433d6423SLionel Sambuc /* process nextarg; */
425*433d6423SLionel Sambuc }
426*433d6423SLionel Sambuc nextarg: continue;
427*433d6423SLionel Sambuc }
428*433d6423SLionel Sambuc
429*433d6423SLionel Sambuc if(maxbits < INIT_BITS) maxbits = INIT_BITS;
430*433d6423SLionel Sambuc if (maxbits > BITS) maxbits = BITS;
431*433d6423SLionel Sambuc maxmaxcode = 1 << maxbits;
432*433d6423SLionel Sambuc
433*433d6423SLionel Sambuc if (*filelist != NULL)
434*433d6423SLionel Sambuc {
435*433d6423SLionel Sambuc for (fileptr = filelist; *fileptr; fileptr++)
436*433d6423SLionel Sambuc {
437*433d6423SLionel Sambuc exit_stat = 0;
438*433d6423SLionel Sambuc if (do_decomp != 0)
439*433d6423SLionel Sambuc { /* DECOMPRESSION */
440*433d6423SLionel Sambuc /* Check for .Z suffix */
441*433d6423SLionel Sambuc #ifndef PCDOS
442*433d6423SLionel Sambuc if (strcmp(*fileptr + strlen(*fileptr) - 2, DOTZ) != 0)
443*433d6423SLionel Sambuc #else
444*433d6423SLionel Sambuc if (strcmp(*fileptr + strlen(*fileptr) - 1, DOTZ) != 0)
445*433d6423SLionel Sambuc #endif
446*433d6423SLionel Sambuc {
447*433d6423SLionel Sambuc /* No .Z: tack one on */
448*433d6423SLionel Sambuc strcpy(tempname, *fileptr);
449*433d6423SLionel Sambuc #ifndef PCDOS
450*433d6423SLionel Sambuc strcat(tempname, DOTZ);
451*433d6423SLionel Sambuc #else
452*433d6423SLionel Sambuc /* either tack one on or replace last character */
453*433d6423SLionel Sambuc {
454*433d6423SLionel Sambuc char *dot;
455*433d6423SLionel Sambuc if (NULL == (dot = strchr(tempname,'.')))
456*433d6423SLionel Sambuc {
457*433d6423SLionel Sambuc strcat(tempname,".Z");
458*433d6423SLionel Sambuc }
459*433d6423SLionel Sambuc else
460*433d6423SLionel Sambuc /* if there is a dot then either tack a z on
461*433d6423SLionel Sambuc or replace last character */
462*433d6423SLionel Sambuc {
463*433d6423SLionel Sambuc if (strlen(dot) < 4)
464*433d6423SLionel Sambuc strcat(tempname,DOTZ);
465*433d6423SLionel Sambuc else
466*433d6423SLionel Sambuc dot[3] = 'Z';
467*433d6423SLionel Sambuc }
468*433d6423SLionel Sambuc }
469*433d6423SLionel Sambuc #endif
470*433d6423SLionel Sambuc *fileptr = tempname;
471*433d6423SLionel Sambuc }
472*433d6423SLionel Sambuc /* Open input file */
473*433d6423SLionel Sambuc if ((freopen(*fileptr, "r", stdin)) == NULL)
474*433d6423SLionel Sambuc {
475*433d6423SLionel Sambuc perror(*fileptr); continue;
476*433d6423SLionel Sambuc }
477*433d6423SLionel Sambuc /* Check the magic number */
478*433d6423SLionel Sambuc if (nomagic == 0)
479*433d6423SLionel Sambuc {
480*433d6423SLionel Sambuc unsigned magic1, magic2;
481*433d6423SLionel Sambuc if (((magic1 = getc(stdin)) != (magic_header[0] & 0xFF))
482*433d6423SLionel Sambuc || ((magic2 = getc(stdin)) != (magic_header[1] & 0xFF)))
483*433d6423SLionel Sambuc {
484*433d6423SLionel Sambuc fprintf(stderr,
485*433d6423SLionel Sambuc "%s: not in compressed format %x %x\n",
486*433d6423SLionel Sambuc *fileptr,magic1,magic2);
487*433d6423SLionel Sambuc continue;
488*433d6423SLionel Sambuc }
489*433d6423SLionel Sambuc maxbits = getc(stdin); /* set -b from file */
490*433d6423SLionel Sambuc block_compress = maxbits & BLOCK_MASK;
491*433d6423SLionel Sambuc maxbits &= BIT_MASK;
492*433d6423SLionel Sambuc maxmaxcode = 1 << maxbits;
493*433d6423SLionel Sambuc if(maxbits > BITS)
494*433d6423SLionel Sambuc {
495*433d6423SLionel Sambuc fprintf(stderr,
496*433d6423SLionel Sambuc "%s: compressed with %d bits, can only handle %d bits\n",
497*433d6423SLionel Sambuc *fileptr, maxbits, BITS);
498*433d6423SLionel Sambuc continue;
499*433d6423SLionel Sambuc }
500*433d6423SLionel Sambuc }
501*433d6423SLionel Sambuc /* Generate output filename */
502*433d6423SLionel Sambuc strcpy(ofname, *fileptr);
503*433d6423SLionel Sambuc #ifndef PCDOS
504*433d6423SLionel Sambuc ofname[strlen(*fileptr) - 2] = '\0'; /* Strip off .Z */
505*433d6423SLionel Sambuc #else
506*433d6423SLionel Sambuc /* kludge to handle various common three character extension */
507*433d6423SLionel Sambuc {
508*433d6423SLionel Sambuc char *dot;
509*433d6423SLionel Sambuc char fixup = '\0';
510*433d6423SLionel Sambuc /* first off, map name to upper case */
511*433d6423SLionel Sambuc for (dot = ofname; *dot; dot++)
512*433d6423SLionel Sambuc *dot = toupper(*dot);
513*433d6423SLionel Sambuc if (NULL == (dot = strchr(ofname,'.')))
514*433d6423SLionel Sambuc {
515*433d6423SLionel Sambuc fprintf(stderr,"Bad filename %s\n",ofname);
516*433d6423SLionel Sambuc exit(1);
517*433d6423SLionel Sambuc }
518*433d6423SLionel Sambuc if (strlen(dot) == 4)
519*433d6423SLionel Sambuc /* we got three letter extensions */
520*433d6423SLionel Sambuc {
521*433d6423SLionel Sambuc if (strcmp(dot,".EXZ") == 0)
522*433d6423SLionel Sambuc fixup = 'E';
523*433d6423SLionel Sambuc else if (strcmp(dot,".COZ") == 0)
524*433d6423SLionel Sambuc fixup = 'M';
525*433d6423SLionel Sambuc else if (strcmp(dot,".BAZ") == 0)
526*433d6423SLionel Sambuc fixup = 'S';
527*433d6423SLionel Sambuc else if (strcmp(dot,".OBZ") == 0)
528*433d6423SLionel Sambuc fixup = 'J';
529*433d6423SLionel Sambuc else if (strcmp(dot,".SYZ") == 0)
530*433d6423SLionel Sambuc fixup = 'S';
531*433d6423SLionel Sambuc else if (strcmp(dot,".DOZ") == 0)
532*433d6423SLionel Sambuc fixup = 'C';
533*433d6423SLionel Sambuc
534*433d6423SLionel Sambuc }
535*433d6423SLionel Sambuc /* replace the Z */
536*433d6423SLionel Sambuc ofname[strlen(*fileptr) - 1] = fixup;
537*433d6423SLionel Sambuc }
538*433d6423SLionel Sambuc #endif
539*433d6423SLionel Sambuc } else
540*433d6423SLionel Sambuc { /* COMPRESSION */
541*433d6423SLionel Sambuc if (strcmp(*fileptr + strlen(*fileptr) - 2, DOTZ) == 0)
542*433d6423SLionel Sambuc {
543*433d6423SLionel Sambuc fprintf(stderr, "%s: already has .Z suffix -- no change\n",
544*433d6423SLionel Sambuc *fileptr);
545*433d6423SLionel Sambuc continue;
546*433d6423SLionel Sambuc }
547*433d6423SLionel Sambuc /* Open input file */
548*433d6423SLionel Sambuc if ((freopen(*fileptr, "r", stdin)) == NULL)
549*433d6423SLionel Sambuc {
550*433d6423SLionel Sambuc perror(*fileptr); continue;
551*433d6423SLionel Sambuc }
552*433d6423SLionel Sambuc (void)stat( *fileptr, &statbuf );
553*433d6423SLionel Sambuc fsize = (long) statbuf.st_size;
554*433d6423SLionel Sambuc /*
555*433d6423SLionel Sambuc * tune hash table size for small files -- ad hoc,
556*433d6423SLionel Sambuc * but the sizes match earlier #defines, which
557*433d6423SLionel Sambuc * serve as upper bounds on the number of output codes.
558*433d6423SLionel Sambuc */
559*433d6423SLionel Sambuc hsize = HSIZE; /*lint -e506 -e712 */
560*433d6423SLionel Sambuc if ( fsize < (1 << 12) )
561*433d6423SLionel Sambuc hsize = min ( 5003, HSIZE );
562*433d6423SLionel Sambuc else if ( fsize < (1 << 13) )
563*433d6423SLionel Sambuc hsize = min ( 9001, HSIZE );
564*433d6423SLionel Sambuc else if ( fsize < (1 << 14) )
565*433d6423SLionel Sambuc hsize = min ( 18013, HSIZE );
566*433d6423SLionel Sambuc else if ( fsize < (1 << 15) )
567*433d6423SLionel Sambuc hsize = min ( 35023, HSIZE );
568*433d6423SLionel Sambuc else if ( fsize < 47000 )
569*433d6423SLionel Sambuc hsize = min ( 50021, HSIZE ); /*lint +e506 +e712 */
570*433d6423SLionel Sambuc
571*433d6423SLionel Sambuc /* Generate output filename */
572*433d6423SLionel Sambuc strcpy(ofname, *fileptr);
573*433d6423SLionel Sambuc #ifndef BSD4_2 /* Short filenames */
574*433d6423SLionel Sambuc if ((cp=strrchr(ofname,'/')) != NULL)
575*433d6423SLionel Sambuc cp++;
576*433d6423SLionel Sambuc else
577*433d6423SLionel Sambuc cp = ofname;
578*433d6423SLionel Sambuc if (strlen(cp) >= NAME_MAX-3)
579*433d6423SLionel Sambuc {
580*433d6423SLionel Sambuc fprintf(stderr,"%s: filename too long to tack on .Z\n",cp);
581*433d6423SLionel Sambuc continue;
582*433d6423SLionel Sambuc }
583*433d6423SLionel Sambuc #ifdef PCDOS
584*433d6423SLionel Sambuc else
585*433d6423SLionel Sambuc {
586*433d6423SLionel Sambuc /* either tack one on or replace last character */
587*433d6423SLionel Sambuc char *dot;
588*433d6423SLionel Sambuc if (NULL == (dot = strchr(cp,'.')))
589*433d6423SLionel Sambuc {
590*433d6423SLionel Sambuc strcat(cp,".Z");
591*433d6423SLionel Sambuc }
592*433d6423SLionel Sambuc else
593*433d6423SLionel Sambuc /* if there is a dot then either tack a z on
594*433d6423SLionel Sambuc or replace last character */
595*433d6423SLionel Sambuc {
596*433d6423SLionel Sambuc if (strlen(dot) < 4)
597*433d6423SLionel Sambuc strcat(cp,DOTZ);
598*433d6423SLionel Sambuc else
599*433d6423SLionel Sambuc dot[3] = 'Z';
600*433d6423SLionel Sambuc }
601*433d6423SLionel Sambuc }
602*433d6423SLionel Sambuc #endif
603*433d6423SLionel Sambuc #endif /* BSD4_2 Long filenames allowed */
604*433d6423SLionel Sambuc #ifndef PCDOS
605*433d6423SLionel Sambuc /* PCDOS takes care of this above */
606*433d6423SLionel Sambuc strcat(ofname, DOTZ);
607*433d6423SLionel Sambuc #endif
608*433d6423SLionel Sambuc }
609*433d6423SLionel Sambuc /* Check for overwrite of existing file */
610*433d6423SLionel Sambuc if (overwrite == 0 && zcat_flg == 0)
611*433d6423SLionel Sambuc {
612*433d6423SLionel Sambuc if (stat(ofname, &statbuf) == 0)
613*433d6423SLionel Sambuc {
614*433d6423SLionel Sambuc char response[2]; int fd;
615*433d6423SLionel Sambuc response[0] = 'n';
616*433d6423SLionel Sambuc fprintf(stderr, "%s already exists;", ofname);
617*433d6423SLionel Sambuc if (foreground())
618*433d6423SLionel Sambuc {
619*433d6423SLionel Sambuc fd = open("/dev/tty", O_RDONLY);
620*433d6423SLionel Sambuc fprintf(stderr,
621*433d6423SLionel Sambuc " do you wish to overwrite %s (y or n)? ", ofname);
622*433d6423SLionel Sambuc fflush(stderr);
623*433d6423SLionel Sambuc (void)read(fd, response, 2);
624*433d6423SLionel Sambuc while (response[1] != '\n')
625*433d6423SLionel Sambuc {
626*433d6423SLionel Sambuc if (read(fd, response+1, 1) < 0)
627*433d6423SLionel Sambuc { /* Ack! */
628*433d6423SLionel Sambuc perror("stderr");
629*433d6423SLionel Sambuc break;
630*433d6423SLionel Sambuc }
631*433d6423SLionel Sambuc }
632*433d6423SLionel Sambuc close(fd);
633*433d6423SLionel Sambuc }
634*433d6423SLionel Sambuc if (response[0] != 'y')
635*433d6423SLionel Sambuc {
636*433d6423SLionel Sambuc fprintf(stderr, "\tnot overwritten\n");
637*433d6423SLionel Sambuc continue;
638*433d6423SLionel Sambuc }
639*433d6423SLionel Sambuc }
640*433d6423SLionel Sambuc }
641*433d6423SLionel Sambuc if(zcat_flg == 0)
642*433d6423SLionel Sambuc { /* Open output file */
643*433d6423SLionel Sambuc if (freopen(ofname, "w", stdout) == NULL)
644*433d6423SLionel Sambuc {
645*433d6423SLionel Sambuc perror(ofname);
646*433d6423SLionel Sambuc continue;
647*433d6423SLionel Sambuc }
648*433d6423SLionel Sambuc if(!quiet)
649*433d6423SLionel Sambuc fprintf(stderr, "%s: ", *fileptr);
650*433d6423SLionel Sambuc }
651*433d6423SLionel Sambuc
652*433d6423SLionel Sambuc /* Actually do the compression/decompression */
653*433d6423SLionel Sambuc if (do_decomp == 0)
654*433d6423SLionel Sambuc compress();
655*433d6423SLionel Sambuc #ifndef DEBUG
656*433d6423SLionel Sambuc else
657*433d6423SLionel Sambuc decompress();
658*433d6423SLionel Sambuc #else
659*433d6423SLionel Sambuc else if (debug == 0)
660*433d6423SLionel Sambuc decompress();
661*433d6423SLionel Sambuc else
662*433d6423SLionel Sambuc printcodes();
663*433d6423SLionel Sambuc if (verbose)
664*433d6423SLionel Sambuc dump_tab();
665*433d6423SLionel Sambuc #endif /* DEBUG */
666*433d6423SLionel Sambuc if(zcat_flg == 0)
667*433d6423SLionel Sambuc {
668*433d6423SLionel Sambuc copystat(*fileptr, ofname); /* Copy stats */
669*433d6423SLionel Sambuc if((exit_stat == 1) || (!quiet))
670*433d6423SLionel Sambuc putc('\n', stderr);
671*433d6423SLionel Sambuc }
672*433d6423SLionel Sambuc }
673*433d6423SLionel Sambuc } else
674*433d6423SLionel Sambuc { /* Standard input */
675*433d6423SLionel Sambuc if (do_decomp == 0)
676*433d6423SLionel Sambuc {
677*433d6423SLionel Sambuc compress();
678*433d6423SLionel Sambuc #ifdef DEBUG
679*433d6423SLionel Sambuc if(verbose) dump_tab();
680*433d6423SLionel Sambuc #endif /* DEBUG */
681*433d6423SLionel Sambuc if(!quiet)
682*433d6423SLionel Sambuc putc('\n', stderr);
683*433d6423SLionel Sambuc } else
684*433d6423SLionel Sambuc {
685*433d6423SLionel Sambuc /* Check the magic number */
686*433d6423SLionel Sambuc if (nomagic == 0)
687*433d6423SLionel Sambuc {
688*433d6423SLionel Sambuc if ((getc(stdin)!=(magic_header[0] & 0xFF))
689*433d6423SLionel Sambuc || (getc(stdin)!=(magic_header[1] & 0xFF)))
690*433d6423SLionel Sambuc {
691*433d6423SLionel Sambuc fprintf(stderr, "stdin: not in compressed format\n");
692*433d6423SLionel Sambuc exit(1);
693*433d6423SLionel Sambuc }
694*433d6423SLionel Sambuc maxbits = getc(stdin); /* set -b from file */
695*433d6423SLionel Sambuc block_compress = maxbits & BLOCK_MASK;
696*433d6423SLionel Sambuc maxbits &= BIT_MASK;
697*433d6423SLionel Sambuc maxmaxcode = 1 << maxbits;
698*433d6423SLionel Sambuc fsize = 100000; /* assume stdin large for USERMEM */
699*433d6423SLionel Sambuc if(maxbits > BITS)
700*433d6423SLionel Sambuc {
701*433d6423SLionel Sambuc fprintf(stderr,
702*433d6423SLionel Sambuc "stdin: compressed with %d bits, can only handle %d bits\n",
703*433d6423SLionel Sambuc maxbits, BITS);
704*433d6423SLionel Sambuc exit(1);
705*433d6423SLionel Sambuc }
706*433d6423SLionel Sambuc }
707*433d6423SLionel Sambuc #ifndef DEBUG
708*433d6423SLionel Sambuc decompress();
709*433d6423SLionel Sambuc #else
710*433d6423SLionel Sambuc if (debug == 0) decompress();
711*433d6423SLionel Sambuc else printcodes();
712*433d6423SLionel Sambuc if (verbose) dump_tab();
713*433d6423SLionel Sambuc #endif /* DEBUG */
714*433d6423SLionel Sambuc }
715*433d6423SLionel Sambuc }
716*433d6423SLionel Sambuc return(exit_stat);
717*433d6423SLionel Sambuc }
718*433d6423SLionel Sambuc
719*433d6423SLionel Sambuc static int offset;
720*433d6423SLionel Sambuc long int in_count = 1; /* length of input */
721*433d6423SLionel Sambuc long int bytes_out; /* length of compressed output */
722*433d6423SLionel Sambuc long int out_count = 0; /* # of codes output (for debugging) */
723*433d6423SLionel Sambuc
724*433d6423SLionel Sambuc /*
725*433d6423SLionel Sambuc * compress stdin to stdout
726*433d6423SLionel Sambuc *
727*433d6423SLionel Sambuc * Algorithm: use open addressing double hashing (no chaining) on the
728*433d6423SLionel Sambuc * prefix code / next character combination. We do a variant of Knuth's
729*433d6423SLionel Sambuc * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
730*433d6423SLionel Sambuc * secondary probe. Here, the modular division first probe is gives way
731*433d6423SLionel Sambuc * to a faster exclusive-or manipulation. Also do block compression with
732*433d6423SLionel Sambuc * an adaptive reset, whereby the code table is cleared when the compression
733*433d6423SLionel Sambuc * ratio decreases, but after the table fills. The variable-length output
734*433d6423SLionel Sambuc * codes are re-sized at this point, and a special CLEAR code is generated
735*433d6423SLionel Sambuc * for the decompressor. Late addition: construct the table according to
736*433d6423SLionel Sambuc * file size for noticeable speed improvement on small files. Please direct
737*433d6423SLionel Sambuc * questions about this implementation to ames!jaw.
738*433d6423SLionel Sambuc */
739*433d6423SLionel Sambuc
compress()740*433d6423SLionel Sambuc void compress()
741*433d6423SLionel Sambuc {
742*433d6423SLionel Sambuc REGISTER long fcode;
743*433d6423SLionel Sambuc REGISTER code_int i = 0;
744*433d6423SLionel Sambuc REGISTER int c;
745*433d6423SLionel Sambuc REGISTER code_int ent;
746*433d6423SLionel Sambuc #ifdef XENIX_16
747*433d6423SLionel Sambuc REGISTER code_int disp;
748*433d6423SLionel Sambuc #else /* Normal machine */
749*433d6423SLionel Sambuc REGISTER int disp;
750*433d6423SLionel Sambuc #endif
751*433d6423SLionel Sambuc REGISTER code_int hsize_reg;
752*433d6423SLionel Sambuc REGISTER int hshift;
753*433d6423SLionel Sambuc
754*433d6423SLionel Sambuc #ifndef COMPATIBLE
755*433d6423SLionel Sambuc if (nomagic == 0)
756*433d6423SLionel Sambuc {
757*433d6423SLionel Sambuc putc(magic_header[0],stdout);
758*433d6423SLionel Sambuc putc(magic_header[1],stdout);
759*433d6423SLionel Sambuc putc((char)(maxbits | block_compress),stdout);
760*433d6423SLionel Sambuc if(ferror(stdout))
761*433d6423SLionel Sambuc writeerr();
762*433d6423SLionel Sambuc }
763*433d6423SLionel Sambuc #endif /* COMPATIBLE */
764*433d6423SLionel Sambuc
765*433d6423SLionel Sambuc offset = 0;
766*433d6423SLionel Sambuc bytes_out = 3; /* includes 3-byte header mojo */
767*433d6423SLionel Sambuc out_count = 0;
768*433d6423SLionel Sambuc clear_flg = 0;
769*433d6423SLionel Sambuc ratio = 0;
770*433d6423SLionel Sambuc in_count = 1;
771*433d6423SLionel Sambuc checkpoint = CHECK_GAP;
772*433d6423SLionel Sambuc maxcode = MAXCODE(n_bits = INIT_BITS);
773*433d6423SLionel Sambuc free_ent = ((block_compress) ? FIRST : 256 );
774*433d6423SLionel Sambuc
775*433d6423SLionel Sambuc ent = getc(stdin);
776*433d6423SLionel Sambuc
777*433d6423SLionel Sambuc hshift = 0;
778*433d6423SLionel Sambuc for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L )
779*433d6423SLionel Sambuc hshift++;
780*433d6423SLionel Sambuc hshift = 8 - hshift; /* set hash code range bound */
781*433d6423SLionel Sambuc
782*433d6423SLionel Sambuc hsize_reg = hsize;
783*433d6423SLionel Sambuc cl_hash( (count_int) hsize_reg); /* clear hash table */
784*433d6423SLionel Sambuc
785*433d6423SLionel Sambuc #ifdef SIGNED_COMPARE_SLOW
786*433d6423SLionel Sambuc while ( (c = getc(stdin)) != (unsigned) EOF )
787*433d6423SLionel Sambuc #else
788*433d6423SLionel Sambuc while ( (c = getc(stdin)) != EOF )
789*433d6423SLionel Sambuc #endif
790*433d6423SLionel Sambuc {
791*433d6423SLionel Sambuc in_count++;
792*433d6423SLionel Sambuc fcode = (long) (((long) c << maxbits) + ent);
793*433d6423SLionel Sambuc i = ((c << hshift) ^ ent); /* xor hashing */
794*433d6423SLionel Sambuc
795*433d6423SLionel Sambuc if ( htabof (i) == fcode )
796*433d6423SLionel Sambuc {
797*433d6423SLionel Sambuc ent = codetabof (i);
798*433d6423SLionel Sambuc continue;
799*433d6423SLionel Sambuc } else if ( (long)htabof (i) < 0 ) /* empty slot */
800*433d6423SLionel Sambuc goto nomatch;
801*433d6423SLionel Sambuc disp = hsize_reg - i; /* secondary hash (after G. Knott) */
802*433d6423SLionel Sambuc if ( i == 0 )
803*433d6423SLionel Sambuc disp = 1;
804*433d6423SLionel Sambuc probe:
805*433d6423SLionel Sambuc if ( (i -= disp) < 0 )
806*433d6423SLionel Sambuc i += hsize_reg;
807*433d6423SLionel Sambuc
808*433d6423SLionel Sambuc if ( htabof (i) == fcode )
809*433d6423SLionel Sambuc {
810*433d6423SLionel Sambuc ent = codetabof (i);
811*433d6423SLionel Sambuc continue;
812*433d6423SLionel Sambuc }
813*433d6423SLionel Sambuc if ( (long)htabof (i) > 0 )
814*433d6423SLionel Sambuc goto probe;
815*433d6423SLionel Sambuc nomatch:
816*433d6423SLionel Sambuc output ( (code_int) ent );
817*433d6423SLionel Sambuc out_count++;
818*433d6423SLionel Sambuc ent = c;
819*433d6423SLionel Sambuc #ifdef SIGNED_COMPARE_SLOW
820*433d6423SLionel Sambuc if ( (unsigned) free_ent < (unsigned) maxmaxcode)
821*433d6423SLionel Sambuc #else
822*433d6423SLionel Sambuc if ( free_ent < maxmaxcode )
823*433d6423SLionel Sambuc #endif
824*433d6423SLionel Sambuc {
825*433d6423SLionel Sambuc codetabof (i) = free_ent++; /* code -> hashtable */
826*433d6423SLionel Sambuc htabof (i) = fcode;
827*433d6423SLionel Sambuc }
828*433d6423SLionel Sambuc else if ( (count_int)in_count >= checkpoint && block_compress )
829*433d6423SLionel Sambuc cl_block ();
830*433d6423SLionel Sambuc }
831*433d6423SLionel Sambuc /*
832*433d6423SLionel Sambuc * Put out the final code.
833*433d6423SLionel Sambuc */
834*433d6423SLionel Sambuc output( (code_int)ent );
835*433d6423SLionel Sambuc out_count++;
836*433d6423SLionel Sambuc output( (code_int)-1 );
837*433d6423SLionel Sambuc
838*433d6423SLionel Sambuc /*
839*433d6423SLionel Sambuc * Print out stats on stderr
840*433d6423SLionel Sambuc */
841*433d6423SLionel Sambuc if(zcat_flg == 0 && !quiet)
842*433d6423SLionel Sambuc {
843*433d6423SLionel Sambuc #ifdef DEBUG
844*433d6423SLionel Sambuc fprintf( stderr,
845*433d6423SLionel Sambuc "%ld chars in, %ld codes (%ld bytes) out, compression factor: ",
846*433d6423SLionel Sambuc in_count, out_count, bytes_out );
847*433d6423SLionel Sambuc prratio( stderr, in_count, bytes_out );
848*433d6423SLionel Sambuc fprintf( stderr, "\n");
849*433d6423SLionel Sambuc fprintf( stderr, "\tCompression as in compact: " );
850*433d6423SLionel Sambuc prratio( stderr, in_count-bytes_out, in_count );
851*433d6423SLionel Sambuc fprintf( stderr, "\n");
852*433d6423SLionel Sambuc fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n",
853*433d6423SLionel Sambuc free_ent - 1, n_bits );
854*433d6423SLionel Sambuc #else /* !DEBUG */
855*433d6423SLionel Sambuc fprintf( stderr, "Compression: " );
856*433d6423SLionel Sambuc prratio( stderr, in_count-bytes_out, in_count );
857*433d6423SLionel Sambuc #endif /* DEBUG */
858*433d6423SLionel Sambuc }
859*433d6423SLionel Sambuc if(bytes_out > in_count) /* exit(2) if no savings */
860*433d6423SLionel Sambuc exit_stat = 2;
861*433d6423SLionel Sambuc return;
862*433d6423SLionel Sambuc }
863*433d6423SLionel Sambuc
864*433d6423SLionel Sambuc /*****************************************************************
865*433d6423SLionel Sambuc * TAG( output )
866*433d6423SLionel Sambuc *
867*433d6423SLionel Sambuc * Output the given code.
868*433d6423SLionel Sambuc * Inputs:
869*433d6423SLionel Sambuc * code: A n_bits-bit integer. If == -1, then EOF. This assumes
870*433d6423SLionel Sambuc * that n_bits =< (long)wordsize - 1.
871*433d6423SLionel Sambuc * Outputs:
872*433d6423SLionel Sambuc * Outputs code to the file.
873*433d6423SLionel Sambuc * Assumptions:
874*433d6423SLionel Sambuc * Chars are 8 bits long.
875*433d6423SLionel Sambuc * Algorithm:
876*433d6423SLionel Sambuc * Maintain a BITS character long buffer (so that 8 codes will
877*433d6423SLionel Sambuc * fit in it exactly). Use the VAX insv instruction to insert each
878*433d6423SLionel Sambuc * code in turn. When the buffer fills up empty it and start over.
879*433d6423SLionel Sambuc */
880*433d6423SLionel Sambuc
881*433d6423SLionel Sambuc static char buf[BITS];
882*433d6423SLionel Sambuc
883*433d6423SLionel Sambuc #ifndef vax
884*433d6423SLionel Sambuc char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
885*433d6423SLionel Sambuc char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
886*433d6423SLionel Sambuc #endif /* vax */
output(code)887*433d6423SLionel Sambuc void output( code )
888*433d6423SLionel Sambuc code_int code;
889*433d6423SLionel Sambuc {
890*433d6423SLionel Sambuc #ifdef DEBUG
891*433d6423SLionel Sambuc static int col = 0;
892*433d6423SLionel Sambuc #endif /* DEBUG */
893*433d6423SLionel Sambuc
894*433d6423SLionel Sambuc /*
895*433d6423SLionel Sambuc * On the VAX, it is important to have the REGISTER declarations
896*433d6423SLionel Sambuc * in exactly the order given, or the asm will break.
897*433d6423SLionel Sambuc */
898*433d6423SLionel Sambuc REGISTER int r_off = offset, bits= n_bits;
899*433d6423SLionel Sambuc REGISTER char * bp = buf;
900*433d6423SLionel Sambuc #ifndef BREAKHIGHC
901*433d6423SLionel Sambuc #ifdef METAWARE
902*433d6423SLionel Sambuc int temp;
903*433d6423SLionel Sambuc #endif
904*433d6423SLionel Sambuc #endif
905*433d6423SLionel Sambuc #ifdef DEBUG
906*433d6423SLionel Sambuc if ( verbose )
907*433d6423SLionel Sambuc fprintf( stderr, "%5d%c", code,
908*433d6423SLionel Sambuc (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
909*433d6423SLionel Sambuc #endif /* DEBUG */
910*433d6423SLionel Sambuc if ( code >= 0 )
911*433d6423SLionel Sambuc {
912*433d6423SLionel Sambuc #ifdef vax
913*433d6423SLionel Sambuc /* VAX DEPENDENT!! Implementation on other machines is below.
914*433d6423SLionel Sambuc *
915*433d6423SLionel Sambuc * Translation: Insert BITS bits from the argument starting at
916*433d6423SLionel Sambuc * offset bits from the beginning of buf.
917*433d6423SLionel Sambuc */
918*433d6423SLionel Sambuc 0; /* Work around for pcc -O bug with asm and if stmt */
919*433d6423SLionel Sambuc asm( "insv 4(ap),r11,r10,(r9)" );
920*433d6423SLionel Sambuc #else /* not a vax */
921*433d6423SLionel Sambuc /*
922*433d6423SLionel Sambuc * byte/bit numbering on the VAX is simulated by the following code
923*433d6423SLionel Sambuc */
924*433d6423SLionel Sambuc /*
925*433d6423SLionel Sambuc * Get to the first byte.
926*433d6423SLionel Sambuc */
927*433d6423SLionel Sambuc bp += (r_off >> 3);
928*433d6423SLionel Sambuc r_off &= 7;
929*433d6423SLionel Sambuc /*
930*433d6423SLionel Sambuc * Since code is always >= 8 bits, only need to mask the first
931*433d6423SLionel Sambuc * hunk on the left.
932*433d6423SLionel Sambuc */
933*433d6423SLionel Sambuc #ifndef BREAKHIGHC
934*433d6423SLionel Sambuc #ifdef METAWARE
935*433d6423SLionel Sambuc *bp &= rmask[r_off];
936*433d6423SLionel Sambuc temp = (code << r_off) & lmask[r_off];
937*433d6423SLionel Sambuc *bp |= temp;
938*433d6423SLionel Sambuc #else
939*433d6423SLionel Sambuc *bp = (*bp & rmask[r_off]) | ((code << r_off) & lmask[r_off]);
940*433d6423SLionel Sambuc #endif
941*433d6423SLionel Sambuc #else
942*433d6423SLionel Sambuc *bp = (*bp & rmask[r_off]) | ((code << r_off) & lmask[r_off]);
943*433d6423SLionel Sambuc #endif
944*433d6423SLionel Sambuc bp++;
945*433d6423SLionel Sambuc bits -= (8 - r_off);
946*433d6423SLionel Sambuc code >>= (8 - r_off);
947*433d6423SLionel Sambuc /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
948*433d6423SLionel Sambuc if ( bits >= 8 )
949*433d6423SLionel Sambuc {
950*433d6423SLionel Sambuc *bp++ = code;
951*433d6423SLionel Sambuc code >>= 8;
952*433d6423SLionel Sambuc bits -= 8;
953*433d6423SLionel Sambuc }
954*433d6423SLionel Sambuc /* Last bits. */
955*433d6423SLionel Sambuc if(bits)
956*433d6423SLionel Sambuc *bp = code;
957*433d6423SLionel Sambuc #endif /* vax */
958*433d6423SLionel Sambuc offset += n_bits;
959*433d6423SLionel Sambuc if ( offset == (n_bits << 3) )
960*433d6423SLionel Sambuc {
961*433d6423SLionel Sambuc bp = buf;
962*433d6423SLionel Sambuc bits = n_bits;
963*433d6423SLionel Sambuc bytes_out += bits;
964*433d6423SLionel Sambuc do
965*433d6423SLionel Sambuc putc(*bp++,stdout);
966*433d6423SLionel Sambuc while(--bits);
967*433d6423SLionel Sambuc offset = 0;
968*433d6423SLionel Sambuc }
969*433d6423SLionel Sambuc
970*433d6423SLionel Sambuc /*
971*433d6423SLionel Sambuc * If the next entry is going to be too big for the code size,
972*433d6423SLionel Sambuc * then increase it, if possible.
973*433d6423SLionel Sambuc */
974*433d6423SLionel Sambuc if ( free_ent > maxcode || (clear_flg > 0))
975*433d6423SLionel Sambuc {
976*433d6423SLionel Sambuc /*
977*433d6423SLionel Sambuc * Write the whole buffer, because the input side won't
978*433d6423SLionel Sambuc * discover the size increase until after it has read it.
979*433d6423SLionel Sambuc */
980*433d6423SLionel Sambuc if ( offset > 0 )
981*433d6423SLionel Sambuc {
982*433d6423SLionel Sambuc if( fwrite( buf, (size_t)1, (size_t)n_bits, stdout ) != n_bits)
983*433d6423SLionel Sambuc writeerr();
984*433d6423SLionel Sambuc bytes_out += n_bits;
985*433d6423SLionel Sambuc }
986*433d6423SLionel Sambuc offset = 0;
987*433d6423SLionel Sambuc
988*433d6423SLionel Sambuc if ( clear_flg )
989*433d6423SLionel Sambuc {
990*433d6423SLionel Sambuc maxcode = MAXCODE (n_bits = INIT_BITS);
991*433d6423SLionel Sambuc clear_flg = 0;
992*433d6423SLionel Sambuc }
993*433d6423SLionel Sambuc else
994*433d6423SLionel Sambuc {
995*433d6423SLionel Sambuc n_bits++;
996*433d6423SLionel Sambuc if ( n_bits == maxbits )
997*433d6423SLionel Sambuc maxcode = maxmaxcode;
998*433d6423SLionel Sambuc else
999*433d6423SLionel Sambuc maxcode = MAXCODE(n_bits);
1000*433d6423SLionel Sambuc }
1001*433d6423SLionel Sambuc #ifdef DEBUG
1002*433d6423SLionel Sambuc if ( debug )
1003*433d6423SLionel Sambuc {
1004*433d6423SLionel Sambuc fprintf( stderr, "\nChange to %d bits\n", n_bits );
1005*433d6423SLionel Sambuc col = 0;
1006*433d6423SLionel Sambuc }
1007*433d6423SLionel Sambuc #endif /* DEBUG */
1008*433d6423SLionel Sambuc }
1009*433d6423SLionel Sambuc } else
1010*433d6423SLionel Sambuc {
1011*433d6423SLionel Sambuc /*
1012*433d6423SLionel Sambuc * At EOF, write the rest of the buffer.
1013*433d6423SLionel Sambuc */
1014*433d6423SLionel Sambuc if ( offset > 0 )
1015*433d6423SLionel Sambuc fwrite( buf, (size_t)1, (size_t)(offset + 7) / 8, stdout );
1016*433d6423SLionel Sambuc bytes_out += (offset + 7) / 8;
1017*433d6423SLionel Sambuc offset = 0;
1018*433d6423SLionel Sambuc fflush( stdout );
1019*433d6423SLionel Sambuc #ifdef DEBUG
1020*433d6423SLionel Sambuc if ( verbose )
1021*433d6423SLionel Sambuc fprintf( stderr, "\n" );
1022*433d6423SLionel Sambuc #endif /* DEBUG */
1023*433d6423SLionel Sambuc if( ferror( stdout ) )
1024*433d6423SLionel Sambuc writeerr();
1025*433d6423SLionel Sambuc }
1026*433d6423SLionel Sambuc }
1027*433d6423SLionel Sambuc /*
1028*433d6423SLionel Sambuc * Decompress stdin to stdout. This routine adapts to the codes in the
1029*433d6423SLionel Sambuc * file building the "string" table on-the-fly; requiring no table to
1030*433d6423SLionel Sambuc * be stored in the compressed file. The tables used herein are shared
1031*433d6423SLionel Sambuc * with those of the compress() routine. See the definitions above.
1032*433d6423SLionel Sambuc */
1033*433d6423SLionel Sambuc
decompress()1034*433d6423SLionel Sambuc void decompress() {
1035*433d6423SLionel Sambuc REGISTER char_type *stackp;
1036*433d6423SLionel Sambuc REGISTER int finchar;
1037*433d6423SLionel Sambuc REGISTER code_int code, oldcode, incode;
1038*433d6423SLionel Sambuc
1039*433d6423SLionel Sambuc /*
1040*433d6423SLionel Sambuc * As above, initialize the first 256 entries in the table.
1041*433d6423SLionel Sambuc */
1042*433d6423SLionel Sambuc maxcode = MAXCODE(n_bits = INIT_BITS);
1043*433d6423SLionel Sambuc for ( code = 255; code >= 0; code-- ) {
1044*433d6423SLionel Sambuc tab_prefixof(code) = 0;
1045*433d6423SLionel Sambuc tab_suffixof(code) = (char_type)code;
1046*433d6423SLionel Sambuc }
1047*433d6423SLionel Sambuc free_ent = ((block_compress) ? FIRST : 256 );
1048*433d6423SLionel Sambuc
1049*433d6423SLionel Sambuc finchar = oldcode = getcode();
1050*433d6423SLionel Sambuc if(oldcode == -1) /* EOF already? */
1051*433d6423SLionel Sambuc return; /* Get out of here */
1052*433d6423SLionel Sambuc putc( (char)finchar,stdout ); /* first code must be 8 bits = char */
1053*433d6423SLionel Sambuc if(ferror(stdout)) /* Crash if can't write */
1054*433d6423SLionel Sambuc writeerr();
1055*433d6423SLionel Sambuc stackp = de_stack;
1056*433d6423SLionel Sambuc
1057*433d6423SLionel Sambuc while ( (code = getcode()) > -1 ) {
1058*433d6423SLionel Sambuc
1059*433d6423SLionel Sambuc if ( (code == CLEAR) && block_compress ) {
1060*433d6423SLionel Sambuc for ( code = 255; code >= 0; code-- )
1061*433d6423SLionel Sambuc tab_prefixof(code) = 0;
1062*433d6423SLionel Sambuc clear_flg = 1;
1063*433d6423SLionel Sambuc free_ent = FIRST - 1;
1064*433d6423SLionel Sambuc if ( (code = getcode ()) == -1 ) /* O, untimely death! */
1065*433d6423SLionel Sambuc break;
1066*433d6423SLionel Sambuc }
1067*433d6423SLionel Sambuc incode = code;
1068*433d6423SLionel Sambuc /*
1069*433d6423SLionel Sambuc * Special case for KwKwK string.
1070*433d6423SLionel Sambuc */
1071*433d6423SLionel Sambuc if ( code >= free_ent ) {
1072*433d6423SLionel Sambuc *stackp++ = finchar;
1073*433d6423SLionel Sambuc code = oldcode;
1074*433d6423SLionel Sambuc }
1075*433d6423SLionel Sambuc
1076*433d6423SLionel Sambuc /*
1077*433d6423SLionel Sambuc * Generate output characters in reverse order
1078*433d6423SLionel Sambuc */
1079*433d6423SLionel Sambuc #ifdef SIGNED_COMPARE_SLOW
1080*433d6423SLionel Sambuc while ( ((unsigned long)code) >= ((unsigned long)256) ) {
1081*433d6423SLionel Sambuc #else
1082*433d6423SLionel Sambuc while ( code >= 256 ) {
1083*433d6423SLionel Sambuc #endif
1084*433d6423SLionel Sambuc *stackp++ = tab_suffixof(code);
1085*433d6423SLionel Sambuc code = tab_prefixof(code);
1086*433d6423SLionel Sambuc }
1087*433d6423SLionel Sambuc *stackp++ = finchar = tab_suffixof(code);
1088*433d6423SLionel Sambuc
1089*433d6423SLionel Sambuc /*
1090*433d6423SLionel Sambuc * And put them out in forward order
1091*433d6423SLionel Sambuc */
1092*433d6423SLionel Sambuc do
1093*433d6423SLionel Sambuc putc ( *--stackp ,stdout);
1094*433d6423SLionel Sambuc while ( stackp > de_stack );
1095*433d6423SLionel Sambuc
1096*433d6423SLionel Sambuc /*
1097*433d6423SLionel Sambuc * Generate the new entry.
1098*433d6423SLionel Sambuc */
1099*433d6423SLionel Sambuc if ( (code=free_ent) < maxmaxcode )
1100*433d6423SLionel Sambuc {
1101*433d6423SLionel Sambuc tab_prefixof(code) = (unsigned short)oldcode;
1102*433d6423SLionel Sambuc tab_suffixof(code) = finchar;
1103*433d6423SLionel Sambuc free_ent = code+1;
1104*433d6423SLionel Sambuc }
1105*433d6423SLionel Sambuc /*
1106*433d6423SLionel Sambuc * Remember previous code.
1107*433d6423SLionel Sambuc */
1108*433d6423SLionel Sambuc oldcode = incode;
1109*433d6423SLionel Sambuc }
1110*433d6423SLionel Sambuc fflush( stdout );
1111*433d6423SLionel Sambuc if(ferror(stdout))
1112*433d6423SLionel Sambuc writeerr();
1113*433d6423SLionel Sambuc }
1114*433d6423SLionel Sambuc
1115*433d6423SLionel Sambuc /*****************************************************************
1116*433d6423SLionel Sambuc * TAG( getcode )
1117*433d6423SLionel Sambuc *
1118*433d6423SLionel Sambuc * Read one code from the standard input. If EOF, return -1.
1119*433d6423SLionel Sambuc * Inputs:
1120*433d6423SLionel Sambuc * stdin
1121*433d6423SLionel Sambuc * Outputs:
1122*433d6423SLionel Sambuc * code or -1 is returned.
1123*433d6423SLionel Sambuc */
1124*433d6423SLionel Sambuc
1125*433d6423SLionel Sambuc code_int
1126*433d6423SLionel Sambuc getcode()
1127*433d6423SLionel Sambuc {
1128*433d6423SLionel Sambuc /*
1129*433d6423SLionel Sambuc * On the VAX, it is important to have the REGISTER declarations
1130*433d6423SLionel Sambuc * in exactly the order given, or the asm will break.
1131*433d6423SLionel Sambuc */
1132*433d6423SLionel Sambuc REGISTER code_int code;
1133*433d6423SLionel Sambuc static int offset = 0, size = 0;
1134*433d6423SLionel Sambuc static char_type buf[BITS];
1135*433d6423SLionel Sambuc REGISTER int r_off, bits;
1136*433d6423SLionel Sambuc REGISTER char_type *bp = buf;
1137*433d6423SLionel Sambuc
1138*433d6423SLionel Sambuc if ( clear_flg > 0 || offset >= size || free_ent > maxcode )
1139*433d6423SLionel Sambuc {
1140*433d6423SLionel Sambuc /*
1141*433d6423SLionel Sambuc * If the next entry will be too big for the current code
1142*433d6423SLionel Sambuc * size, then we must increase the size. This implies reading
1143*433d6423SLionel Sambuc * a new buffer full, too.
1144*433d6423SLionel Sambuc */
1145*433d6423SLionel Sambuc if ( free_ent > maxcode )
1146*433d6423SLionel Sambuc {
1147*433d6423SLionel Sambuc n_bits++;
1148*433d6423SLionel Sambuc if ( n_bits == maxbits )
1149*433d6423SLionel Sambuc maxcode = maxmaxcode; /* won't get any bigger now */
1150*433d6423SLionel Sambuc else
1151*433d6423SLionel Sambuc maxcode = MAXCODE(n_bits);
1152*433d6423SLionel Sambuc }
1153*433d6423SLionel Sambuc if ( clear_flg > 0)
1154*433d6423SLionel Sambuc {
1155*433d6423SLionel Sambuc maxcode = MAXCODE (n_bits = INIT_BITS);
1156*433d6423SLionel Sambuc clear_flg = 0;
1157*433d6423SLionel Sambuc }
1158*433d6423SLionel Sambuc size = fread( buf, (size_t)1, (size_t)n_bits, stdin );
1159*433d6423SLionel Sambuc if ( size <= 0 )
1160*433d6423SLionel Sambuc return -1; /* end of file */
1161*433d6423SLionel Sambuc offset = 0;
1162*433d6423SLionel Sambuc /* Round size down to integral number of codes */
1163*433d6423SLionel Sambuc size = (size << 3) - (n_bits - 1);
1164*433d6423SLionel Sambuc }
1165*433d6423SLionel Sambuc r_off = offset;
1166*433d6423SLionel Sambuc bits = n_bits;
1167*433d6423SLionel Sambuc #ifdef vax
1168*433d6423SLionel Sambuc asm( "extzv r10,r9,(r8),r11" );
1169*433d6423SLionel Sambuc #else /* not a vax */
1170*433d6423SLionel Sambuc /*
1171*433d6423SLionel Sambuc * Get to the first byte.
1172*433d6423SLionel Sambuc */
1173*433d6423SLionel Sambuc bp += (r_off >> 3);
1174*433d6423SLionel Sambuc r_off &= 7;
1175*433d6423SLionel Sambuc /* Get first part (low order bits) */
1176*433d6423SLionel Sambuc #ifdef NO_UCHAR
1177*433d6423SLionel Sambuc code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff;
1178*433d6423SLionel Sambuc #else
1179*433d6423SLionel Sambuc code = (*bp++ >> r_off);
1180*433d6423SLionel Sambuc #endif /* NO_UCHAR */
1181*433d6423SLionel Sambuc bits -= (8 - r_off);
1182*433d6423SLionel Sambuc r_off = 8 - r_off; /* now, offset into code word */
1183*433d6423SLionel Sambuc /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
1184*433d6423SLionel Sambuc if ( bits >= 8 )
1185*433d6423SLionel Sambuc {
1186*433d6423SLionel Sambuc #ifdef NO_UCHAR
1187*433d6423SLionel Sambuc code |= (*bp++ & 0xff) << r_off;
1188*433d6423SLionel Sambuc #else
1189*433d6423SLionel Sambuc code |= *bp++ << r_off;
1190*433d6423SLionel Sambuc #endif /* NO_UCHAR */
1191*433d6423SLionel Sambuc r_off += 8;
1192*433d6423SLionel Sambuc bits -= 8;
1193*433d6423SLionel Sambuc }
1194*433d6423SLionel Sambuc /* high order bits. */
1195*433d6423SLionel Sambuc code |= (*bp & rmask[bits]) << r_off;
1196*433d6423SLionel Sambuc #endif /* vax */
1197*433d6423SLionel Sambuc offset += n_bits;
1198*433d6423SLionel Sambuc
1199*433d6423SLionel Sambuc return code;
1200*433d6423SLionel Sambuc }
1201*433d6423SLionel Sambuc
1202*433d6423SLionel Sambuc #ifndef AZTEC86
1203*433d6423SLionel Sambuc char *
1204*433d6423SLionel Sambuc strrchr(s, c) /* For those who don't have it in libc.a */
1205*433d6423SLionel Sambuc REGISTER char *s, c;
1206*433d6423SLionel Sambuc {
1207*433d6423SLionel Sambuc char *p;
1208*433d6423SLionel Sambuc for (p = NULL; *s; s++)
1209*433d6423SLionel Sambuc if (*s == c)
1210*433d6423SLionel Sambuc p = s;
1211*433d6423SLionel Sambuc return(p);
1212*433d6423SLionel Sambuc }
1213*433d6423SLionel Sambuc #endif
1214*433d6423SLionel Sambuc
1215*433d6423SLionel Sambuc
1216*433d6423SLionel Sambuc #ifndef METAWARE
1217*433d6423SLionel Sambuc #ifdef DEBUG
1218*433d6423SLionel Sambuc printcodes()
1219*433d6423SLionel Sambuc {
1220*433d6423SLionel Sambuc /*
1221*433d6423SLionel Sambuc * Just print out codes from input file. For debugging.
1222*433d6423SLionel Sambuc */
1223*433d6423SLionel Sambuc code_int code;
1224*433d6423SLionel Sambuc int col = 0, bits;
1225*433d6423SLionel Sambuc
1226*433d6423SLionel Sambuc bits = n_bits = INIT_BITS;
1227*433d6423SLionel Sambuc maxcode = MAXCODE(n_bits);
1228*433d6423SLionel Sambuc free_ent = ((block_compress) ? FIRST : 256 );
1229*433d6423SLionel Sambuc while ( ( code = getcode() ) >= 0 ) {
1230*433d6423SLionel Sambuc if ( (code == CLEAR) && block_compress ) {
1231*433d6423SLionel Sambuc free_ent = FIRST - 1;
1232*433d6423SLionel Sambuc clear_flg = 1;
1233*433d6423SLionel Sambuc }
1234*433d6423SLionel Sambuc else if ( free_ent < maxmaxcode )
1235*433d6423SLionel Sambuc free_ent++;
1236*433d6423SLionel Sambuc if ( bits != n_bits ) {
1237*433d6423SLionel Sambuc fprintf(stderr, "\nChange to %d bits\n", n_bits );
1238*433d6423SLionel Sambuc bits = n_bits;
1239*433d6423SLionel Sambuc col = 0;
1240*433d6423SLionel Sambuc }
1241*433d6423SLionel Sambuc fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );
1242*433d6423SLionel Sambuc }
1243*433d6423SLionel Sambuc putc( '\n', stderr );
1244*433d6423SLionel Sambuc exit( 0 );
1245*433d6423SLionel Sambuc }
1246*433d6423SLionel Sambuc #ifdef DEBUG2
1247*433d6423SLionel Sambuc code_int sorttab[1<<BITS]; /* sorted pointers into htab */
1248*433d6423SLionel Sambuc #define STACK_SIZE 500
1249*433d6423SLionel Sambuc static char stack[STACK_SIZE];
1250*433d6423SLionel Sambuc /* dumptab doesn't use main stack now -prevents distressing crashes */
1251*433d6423SLionel Sambuc dump_tab() /* dump string table */
1252*433d6423SLionel Sambuc {
1253*433d6423SLionel Sambuc REGISTER int i, first;
1254*433d6423SLionel Sambuc REGISTER ent;
1255*433d6423SLionel Sambuc int stack_top = STACK_SIZE;
1256*433d6423SLionel Sambuc REGISTER c;
1257*433d6423SLionel Sambuc
1258*433d6423SLionel Sambuc if(do_decomp == 0) { /* compressing */
1259*433d6423SLionel Sambuc REGISTER int flag = 1;
1260*433d6423SLionel Sambuc
1261*433d6423SLionel Sambuc for(i=0; i<hsize; i++) { /* build sort pointers */
1262*433d6423SLionel Sambuc if((long)htabof(i) >= 0) {
1263*433d6423SLionel Sambuc sorttab[codetabof(i)] = i;
1264*433d6423SLionel Sambuc }
1265*433d6423SLionel Sambuc }
1266*433d6423SLionel Sambuc first = block_compress ? FIRST : 256;
1267*433d6423SLionel Sambuc for(i = first; i < free_ent; i++) {
1268*433d6423SLionel Sambuc fprintf(stderr, "%5d: \"", i);
1269*433d6423SLionel Sambuc stack[--stack_top] = '\n';
1270*433d6423SLionel Sambuc stack[--stack_top] = '"'; /* " */
1271*433d6423SLionel Sambuc stack_top = in_stack((int)(htabof(sorttab[i])>>maxbits)&0xff,
1272*433d6423SLionel Sambuc stack_top);
1273*433d6423SLionel Sambuc for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);
1274*433d6423SLionel Sambuc ent > 256;
1275*433d6423SLionel Sambuc ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {
1276*433d6423SLionel Sambuc stack_top = in_stack((int)(htabof(sorttab[ent]) >> maxbits),
1277*433d6423SLionel Sambuc stack_top);
1278*433d6423SLionel Sambuc }
1279*433d6423SLionel Sambuc stack_top = in_stack(ent, stack_top);
1280*433d6423SLionel Sambuc fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE-stack_top), stderr);
1281*433d6423SLionel Sambuc stack_top = STACK_SIZE;
1282*433d6423SLionel Sambuc }
1283*433d6423SLionel Sambuc } else if(!debug) { /* decompressing */
1284*433d6423SLionel Sambuc
1285*433d6423SLionel Sambuc for ( i = 0; i < free_ent; i++ ) {
1286*433d6423SLionel Sambuc ent = i;
1287*433d6423SLionel Sambuc c = tab_suffixof(ent);
1288*433d6423SLionel Sambuc if ( isascii(c) && isprint(c) )
1289*433d6423SLionel Sambuc fprintf( stderr, "%5d: %5d/'%c' \"",
1290*433d6423SLionel Sambuc ent, tab_prefixof(ent), c );
1291*433d6423SLionel Sambuc else
1292*433d6423SLionel Sambuc fprintf( stderr, "%5d: %5d/\\%03o \"",
1293*433d6423SLionel Sambuc ent, tab_prefixof(ent), c );
1294*433d6423SLionel Sambuc stack[--stack_top] = '\n';
1295*433d6423SLionel Sambuc stack[--stack_top] = '"'; /* " */
1296*433d6423SLionel Sambuc for ( ; ent != NULL;
1297*433d6423SLionel Sambuc ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {
1298*433d6423SLionel Sambuc stack_top = in_stack(tab_suffixof(ent), stack_top);
1299*433d6423SLionel Sambuc }
1300*433d6423SLionel Sambuc fwrite( &stack[stack_top], (size_t)1, (size_t)(STACK_SIZE - stack_top), stderr );
1301*433d6423SLionel Sambuc stack_top = STACK_SIZE;
1302*433d6423SLionel Sambuc }
1303*433d6423SLionel Sambuc }
1304*433d6423SLionel Sambuc }
1305*433d6423SLionel Sambuc
1306*433d6423SLionel Sambuc int
1307*433d6423SLionel Sambuc in_stack(c, stack_top)
1308*433d6423SLionel Sambuc REGISTER int c, stack_top;
1309*433d6423SLionel Sambuc {
1310*433d6423SLionel Sambuc if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {
1311*433d6423SLionel Sambuc stack[--stack_top] = c;
1312*433d6423SLionel Sambuc } else {
1313*433d6423SLionel Sambuc switch( c ) {
1314*433d6423SLionel Sambuc case '\n': stack[--stack_top] = 'n'; break;
1315*433d6423SLionel Sambuc case '\t': stack[--stack_top] = 't'; break;
1316*433d6423SLionel Sambuc case '\b': stack[--stack_top] = 'b'; break;
1317*433d6423SLionel Sambuc case '\f': stack[--stack_top] = 'f'; break;
1318*433d6423SLionel Sambuc case '\r': stack[--stack_top] = 'r'; break;
1319*433d6423SLionel Sambuc case '\\': stack[--stack_top] = '\\'; break;
1320*433d6423SLionel Sambuc default:
1321*433d6423SLionel Sambuc stack[--stack_top] = '0' + c % 8;
1322*433d6423SLionel Sambuc stack[--stack_top] = '0' + (c / 8) % 8;
1323*433d6423SLionel Sambuc stack[--stack_top] = '0' + c / 64;
1324*433d6423SLionel Sambuc break;
1325*433d6423SLionel Sambuc }
1326*433d6423SLionel Sambuc stack[--stack_top] = '\\';
1327*433d6423SLionel Sambuc }
1328*433d6423SLionel Sambuc if (stack_top<0) {
1329*433d6423SLionel Sambuc fprintf(stderr,"dump_tab stack overflow!!!\n");
1330*433d6423SLionel Sambuc exit(1);
1331*433d6423SLionel Sambuc }
1332*433d6423SLionel Sambuc return stack_top;
1333*433d6423SLionel Sambuc }
1334*433d6423SLionel Sambuc #else
1335*433d6423SLionel Sambuc dump_tab() {}
1336*433d6423SLionel Sambuc #endif /* DEBUG2 */
1337*433d6423SLionel Sambuc #endif /* DEBUG */
1338*433d6423SLionel Sambuc #endif /* METAWARE */
1339*433d6423SLionel Sambuc
1340*433d6423SLionel Sambuc void writeerr()
1341*433d6423SLionel Sambuc {
1342*433d6423SLionel Sambuc perror ( ofname );
1343*433d6423SLionel Sambuc unlink ( ofname );
1344*433d6423SLionel Sambuc exit ( 1 );
1345*433d6423SLionel Sambuc }
1346*433d6423SLionel Sambuc
1347*433d6423SLionel Sambuc void copystat(ifname, ofname)
1348*433d6423SLionel Sambuc char *ifname, *ofname;
1349*433d6423SLionel Sambuc {
1350*433d6423SLionel Sambuc struct stat statbuf;
1351*433d6423SLionel Sambuc int mode;
1352*433d6423SLionel Sambuc #ifndef AZTEC86
1353*433d6423SLionel Sambuc time_t timep[2];
1354*433d6423SLionel Sambuc #else
1355*433d6423SLionel Sambuc unsigned long timep[2];
1356*433d6423SLionel Sambuc #endif
1357*433d6423SLionel Sambuc fflush(stdout);
1358*433d6423SLionel Sambuc close(fileno(stdout));
1359*433d6423SLionel Sambuc if (stat(ifname, &statbuf))
1360*433d6423SLionel Sambuc { /* Get stat on input file */
1361*433d6423SLionel Sambuc perror(ifname);
1362*433d6423SLionel Sambuc return;
1363*433d6423SLionel Sambuc }
1364*433d6423SLionel Sambuc #ifndef PCDOS
1365*433d6423SLionel Sambuc /* meddling with UNIX-style file modes */
1366*433d6423SLionel Sambuc if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/)
1367*433d6423SLionel Sambuc {
1368*433d6423SLionel Sambuc if(quiet)
1369*433d6423SLionel Sambuc fprintf(stderr, "%s: ", ifname);
1370*433d6423SLionel Sambuc fprintf(stderr, " -- not a regular file: unchanged");
1371*433d6423SLionel Sambuc exit_stat = 1;
1372*433d6423SLionel Sambuc } else if (statbuf.st_nlink > 1)
1373*433d6423SLionel Sambuc {
1374*433d6423SLionel Sambuc if(quiet)
1375*433d6423SLionel Sambuc fprintf(stderr, "%s: ", ifname);
1376*433d6423SLionel Sambuc fprintf(stderr, " -- has %d other links: unchanged",
1377*433d6423SLionel Sambuc statbuf.st_nlink - 1);
1378*433d6423SLionel Sambuc exit_stat = 1;
1379*433d6423SLionel Sambuc } else
1380*433d6423SLionel Sambuc #endif
1381*433d6423SLionel Sambuc if (exit_stat == 2 && (!force))
1382*433d6423SLionel Sambuc { /* No compression: remove file.Z */
1383*433d6423SLionel Sambuc if(!quiet)
1384*433d6423SLionel Sambuc fprintf(stderr, " -- file unchanged");
1385*433d6423SLionel Sambuc } else
1386*433d6423SLionel Sambuc { /* ***** Successful Compression ***** */
1387*433d6423SLionel Sambuc exit_stat = 0;
1388*433d6423SLionel Sambuc #ifndef PCDOS
1389*433d6423SLionel Sambuc mode = statbuf.st_mode & 07777;
1390*433d6423SLionel Sambuc #else
1391*433d6423SLionel Sambuc mode = statbuf.st_attr & 07777;
1392*433d6423SLionel Sambuc #endif
1393*433d6423SLionel Sambuc if (chmod(ofname, mode)) /* Copy modes */
1394*433d6423SLionel Sambuc perror(ofname);
1395*433d6423SLionel Sambuc #ifndef PCDOS
1396*433d6423SLionel Sambuc chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
1397*433d6423SLionel Sambuc timep[0] = statbuf.st_atime;
1398*433d6423SLionel Sambuc timep[1] = statbuf.st_mtime;
1399*433d6423SLionel Sambuc #else
1400*433d6423SLionel Sambuc timep[0] = statbuf.st_mtime;
1401*433d6423SLionel Sambuc timep[1] = statbuf.st_mtime;
1402*433d6423SLionel Sambuc #endif
1403*433d6423SLionel Sambuc utime(ofname, (struct utimbuf *)timep); /* Update last accessed and modified times */
1404*433d6423SLionel Sambuc /*
1405*433d6423SLionel Sambuc if (unlink(ifname))
1406*433d6423SLionel Sambuc perror(ifname);
1407*433d6423SLionel Sambuc */
1408*433d6423SLionel Sambuc if(!quiet) {
1409*433d6423SLionel Sambuc if(do_decomp == 0)
1410*433d6423SLionel Sambuc fprintf(stderr, " -- compressed to %s", ofname);
1411*433d6423SLionel Sambuc else
1412*433d6423SLionel Sambuc fprintf(stderr, " -- decompressed to %s", ofname);
1413*433d6423SLionel Sambuc }
1414*433d6423SLionel Sambuc return; /* Successful return */
1415*433d6423SLionel Sambuc }
1416*433d6423SLionel Sambuc
1417*433d6423SLionel Sambuc /* Unsuccessful return -- one of the tests failed */
1418*433d6423SLionel Sambuc if (unlink(ofname))
1419*433d6423SLionel Sambuc perror(ofname);
1420*433d6423SLionel Sambuc }
1421*433d6423SLionel Sambuc /*
1422*433d6423SLionel Sambuc * This routine returns 1 if we are running in the foreground and stderr
1423*433d6423SLionel Sambuc * is a tty.
1424*433d6423SLionel Sambuc */
1425*433d6423SLionel Sambuc int foreground()
1426*433d6423SLionel Sambuc {
1427*433d6423SLionel Sambuc #ifndef METAWARE
1428*433d6423SLionel Sambuc if(bgnd_flag) { /* background? */
1429*433d6423SLionel Sambuc return(0);
1430*433d6423SLionel Sambuc } else { /* foreground */
1431*433d6423SLionel Sambuc #endif
1432*433d6423SLionel Sambuc if(isatty(2)) { /* and stderr is a tty */
1433*433d6423SLionel Sambuc return(1);
1434*433d6423SLionel Sambuc } else {
1435*433d6423SLionel Sambuc return(0);
1436*433d6423SLionel Sambuc }
1437*433d6423SLionel Sambuc #ifndef METAWARE
1438*433d6423SLionel Sambuc }
1439*433d6423SLionel Sambuc #endif
1440*433d6423SLionel Sambuc }
1441*433d6423SLionel Sambuc #ifndef METAWARE
1442*433d6423SLionel Sambuc void onintr (dummy)
1443*433d6423SLionel Sambuc int dummy; /* to keep the compiler happy */
1444*433d6423SLionel Sambuc {
1445*433d6423SLionel Sambuc (void)signal(SIGINT,SIG_IGN);
1446*433d6423SLionel Sambuc unlink ( ofname );
1447*433d6423SLionel Sambuc exit ( 1 );
1448*433d6423SLionel Sambuc }
1449*433d6423SLionel Sambuc
1450*433d6423SLionel Sambuc void oops (dummy) /* wild pointer -- assume bad input */
1451*433d6423SLionel Sambuc int dummy; /* to keep the compiler happy */
1452*433d6423SLionel Sambuc {
1453*433d6423SLionel Sambuc (void)signal(SIGSEGV,SIG_IGN);
1454*433d6423SLionel Sambuc if ( do_decomp == 1 )
1455*433d6423SLionel Sambuc fprintf ( stderr, "uncompress: corrupt input\n" );
1456*433d6423SLionel Sambuc unlink ( ofname );
1457*433d6423SLionel Sambuc exit ( 1 );
1458*433d6423SLionel Sambuc }
1459*433d6423SLionel Sambuc #endif
1460*433d6423SLionel Sambuc void cl_block () /* table clear for block compress */
1461*433d6423SLionel Sambuc {
1462*433d6423SLionel Sambuc REGISTER long int rat;
1463*433d6423SLionel Sambuc
1464*433d6423SLionel Sambuc checkpoint = in_count + CHECK_GAP;
1465*433d6423SLionel Sambuc #ifdef DEBUG
1466*433d6423SLionel Sambuc if ( debug ) {
1467*433d6423SLionel Sambuc fprintf ( stderr, "count: %ld, ratio: ", in_count );
1468*433d6423SLionel Sambuc prratio ( stderr, in_count, bytes_out );
1469*433d6423SLionel Sambuc fprintf ( stderr, "\n");
1470*433d6423SLionel Sambuc }
1471*433d6423SLionel Sambuc #endif /* DEBUG */
1472*433d6423SLionel Sambuc
1473*433d6423SLionel Sambuc if(in_count > 0x007fffff) { /* shift will overflow */
1474*433d6423SLionel Sambuc rat = bytes_out >> 8;
1475*433d6423SLionel Sambuc if(rat == 0) { /* Don't divide by zero */
1476*433d6423SLionel Sambuc rat = 0x7fffffff;
1477*433d6423SLionel Sambuc } else {
1478*433d6423SLionel Sambuc rat = in_count / rat;
1479*433d6423SLionel Sambuc }
1480*433d6423SLionel Sambuc } else {
1481*433d6423SLionel Sambuc rat = (in_count << 8) / bytes_out; /* 8 fractional bits */
1482*433d6423SLionel Sambuc }
1483*433d6423SLionel Sambuc if ( rat > ratio ) {
1484*433d6423SLionel Sambuc ratio = rat;
1485*433d6423SLionel Sambuc } else {
1486*433d6423SLionel Sambuc ratio = 0;
1487*433d6423SLionel Sambuc #ifdef DEBUG
1488*433d6423SLionel Sambuc if(verbose)
1489*433d6423SLionel Sambuc dump_tab(); /* dump string table */
1490*433d6423SLionel Sambuc #endif
1491*433d6423SLionel Sambuc cl_hash ( (count_int) hsize );
1492*433d6423SLionel Sambuc free_ent = FIRST;
1493*433d6423SLionel Sambuc clear_flg = 1;
1494*433d6423SLionel Sambuc output ( (code_int) CLEAR );
1495*433d6423SLionel Sambuc #ifdef DEBUG
1496*433d6423SLionel Sambuc if(debug)
1497*433d6423SLionel Sambuc fprintf ( stderr, "clear\n" );
1498*433d6423SLionel Sambuc #endif /* DEBUG */
1499*433d6423SLionel Sambuc }
1500*433d6423SLionel Sambuc }
1501*433d6423SLionel Sambuc
1502*433d6423SLionel Sambuc void cl_hash(hsize) /* reset code table */
1503*433d6423SLionel Sambuc REGISTER count_int hsize;
1504*433d6423SLionel Sambuc {
1505*433d6423SLionel Sambuc #ifdef AZTEC86
1506*433d6423SLionel Sambuc #ifdef PCDOS
1507*433d6423SLionel Sambuc /* This function only in PC-DOS lib, not in MINIX lib */
1508*433d6423SLionel Sambuc memset(htab,-1, hsize * sizeof(count_int));
1509*433d6423SLionel Sambuc #else
1510*433d6423SLionel Sambuc /* MINIX and all non-PC machines do it this way */
1511*433d6423SLionel Sambuc #ifndef XENIX_16 /* Normal machine */
1512*433d6423SLionel Sambuc REGISTER count_int *htab_p = htab+hsize;
1513*433d6423SLionel Sambuc #else
1514*433d6423SLionel Sambuc REGISTER j;
1515*433d6423SLionel Sambuc REGISTER long k = hsize;
1516*433d6423SLionel Sambuc REGISTER count_int *htab_p;
1517*433d6423SLionel Sambuc #endif
1518*433d6423SLionel Sambuc REGISTER long i;
1519*433d6423SLionel Sambuc REGISTER long m1 = -1;
1520*433d6423SLionel Sambuc
1521*433d6423SLionel Sambuc #ifdef XENIX_16
1522*433d6423SLionel Sambuc for(j=0; j<=8 && k>=0; j++,k-=8192)
1523*433d6423SLionel Sambuc {
1524*433d6423SLionel Sambuc i = 8192;
1525*433d6423SLionel Sambuc if(k < 8192)
1526*433d6423SLionel Sambuc {
1527*433d6423SLionel Sambuc i = k;
1528*433d6423SLionel Sambuc }
1529*433d6423SLionel Sambuc htab_p = &(htab[j][i]);
1530*433d6423SLionel Sambuc i -= 16;
1531*433d6423SLionel Sambuc if(i > 0)
1532*433d6423SLionel Sambuc {
1533*433d6423SLionel Sambuc #else
1534*433d6423SLionel Sambuc i = hsize - 16;
1535*433d6423SLionel Sambuc #endif
1536*433d6423SLionel Sambuc do
1537*433d6423SLionel Sambuc { /* might use Sys V memset(3) here */
1538*433d6423SLionel Sambuc *(htab_p-16) = m1;
1539*433d6423SLionel Sambuc *(htab_p-15) = m1;
1540*433d6423SLionel Sambuc *(htab_p-14) = m1;
1541*433d6423SLionel Sambuc *(htab_p-13) = m1;
1542*433d6423SLionel Sambuc *(htab_p-12) = m1;
1543*433d6423SLionel Sambuc *(htab_p-11) = m1;
1544*433d6423SLionel Sambuc *(htab_p-10) = m1;
1545*433d6423SLionel Sambuc *(htab_p-9) = m1;
1546*433d6423SLionel Sambuc *(htab_p-8) = m1;
1547*433d6423SLionel Sambuc *(htab_p-7) = m1;
1548*433d6423SLionel Sambuc *(htab_p-6) = m1;
1549*433d6423SLionel Sambuc *(htab_p-5) = m1;
1550*433d6423SLionel Sambuc *(htab_p-4) = m1;
1551*433d6423SLionel Sambuc *(htab_p-3) = m1;
1552*433d6423SLionel Sambuc *(htab_p-2) = m1;
1553*433d6423SLionel Sambuc *(htab_p-1) = m1;
1554*433d6423SLionel Sambuc htab_p -= 16;
1555*433d6423SLionel Sambuc } while ((i -= 16) >= 0);
1556*433d6423SLionel Sambuc #ifdef XENIX_16
1557*433d6423SLionel Sambuc }
1558*433d6423SLionel Sambuc }
1559*433d6423SLionel Sambuc #endif
1560*433d6423SLionel Sambuc for ( i += 16; i > 0; i-- )
1561*433d6423SLionel Sambuc *--htab_p = m1;
1562*433d6423SLionel Sambuc #endif
1563*433d6423SLionel Sambuc #endif
1564*433d6423SLionel Sambuc }
1565*433d6423SLionel Sambuc
1566*433d6423SLionel Sambuc void prratio(stream, num, den)
1567*433d6423SLionel Sambuc FILE *stream;
1568*433d6423SLionel Sambuc long int num;
1569*433d6423SLionel Sambuc long int den;
1570*433d6423SLionel Sambuc {
1571*433d6423SLionel Sambuc REGISTER int q; /* Doesn't need to be long */
1572*433d6423SLionel Sambuc if(num > 214748L)
1573*433d6423SLionel Sambuc { /* 2147483647/10000 */
1574*433d6423SLionel Sambuc q = (int)(num / (den / 10000L));
1575*433d6423SLionel Sambuc } else
1576*433d6423SLionel Sambuc {
1577*433d6423SLionel Sambuc q = (int)(10000L * num / den); /* Long calculations, though */
1578*433d6423SLionel Sambuc }
1579*433d6423SLionel Sambuc if (q < 0)
1580*433d6423SLionel Sambuc {
1581*433d6423SLionel Sambuc putc('-', stream);
1582*433d6423SLionel Sambuc q = -q;
1583*433d6423SLionel Sambuc }
1584*433d6423SLionel Sambuc fprintf(stream, "%d.%02d%c", q / 100, q % 100, '%');
1585*433d6423SLionel Sambuc }
1586*433d6423SLionel Sambuc
1587*433d6423SLionel Sambuc void version()
1588*433d6423SLionel Sambuc {
1589*433d6423SLionel Sambuc fprintf(stderr, "compress 4.1\n");
1590*433d6423SLionel Sambuc fprintf(stderr, "Options: ");
1591*433d6423SLionel Sambuc #ifdef vax
1592*433d6423SLionel Sambuc fprintf(stderr, "vax, ");
1593*433d6423SLionel Sambuc #endif
1594*433d6423SLionel Sambuc #ifdef __minix
1595*433d6423SLionel Sambuc fprintf(stderr, "MINIX, ");
1596*433d6423SLionel Sambuc #endif
1597*433d6423SLionel Sambuc #ifdef NO_UCHAR
1598*433d6423SLionel Sambuc fprintf(stderr, "NO_UCHAR, ");
1599*433d6423SLionel Sambuc #endif
1600*433d6423SLionel Sambuc #ifdef SIGNED_COMPARE_SLOW
1601*433d6423SLionel Sambuc fprintf(stderr, "SIGNED_COMPARE_SLOW, ");
1602*433d6423SLionel Sambuc #endif
1603*433d6423SLionel Sambuc #ifdef XENIX_16
1604*433d6423SLionel Sambuc fprintf(stderr, "XENIX_16, ");
1605*433d6423SLionel Sambuc #endif
1606*433d6423SLionel Sambuc #ifdef COMPATIBLE
1607*433d6423SLionel Sambuc fprintf(stderr, "COMPATIBLE, ");
1608*433d6423SLionel Sambuc #endif
1609*433d6423SLionel Sambuc #ifdef DEBUG
1610*433d6423SLionel Sambuc fprintf(stderr, "DEBUG, ");
1611*433d6423SLionel Sambuc #endif
1612*433d6423SLionel Sambuc #ifdef BSD4_2
1613*433d6423SLionel Sambuc fprintf(stderr, "BSD4_2, ");
1614*433d6423SLionel Sambuc #endif
1615*433d6423SLionel Sambuc fprintf(stderr, "BITS = %d\n", BITS);
1616*433d6423SLionel Sambuc }
1617*433d6423SLionel Sambuc /* End of text from uok.UUCP:net.sources */
1618*433d6423SLionel Sambuc
1619