From 4eeb10d4723deacf43ee1b66ed570d8534972245 Mon Sep 17 00:00:00 2001 From: Jay Lepreau Date: Tue, 17 Sep 1985 22:43:11 -0800 Subject: [PATCH] Compress 4.0 SCCS-vsn: usr.bin/compress/usermem.sh 5.2 SCCS-vsn: usr.bin/compress/compress.c 5.5 --- usr/src/usr.bin/compress/compress.c | 820 +++++++++++++++------------- usr/src/usr.bin/compress/usermem.sh | 19 +- 2 files changed, 446 insertions(+), 393 deletions(-) diff --git a/usr/src/usr.bin/compress/compress.c b/usr/src/usr.bin/compress/compress.c index 459481ab68..19456346c3 100644 --- a/usr/src/usr.bin/compress/compress.c +++ b/usr/src/usr.bin/compress/compress.c @@ -1,16 +1,20 @@ #ifndef lint -static char sccsid[] = "@(#)compress.c 5.4 (Berkeley) %G%"; +static char sccsid[] = "@(#)compress.c 5.5 (Berkeley) %G%"; #endif not lint +/* + * Compress - data compression program + */ #define min(a,b) ((a>b) ? b : a) /* * machine variants which require cc -Dmachine: pdp11, z8000, pcxt */ -/* Set USERMEM to the maximum amount of physical user memory available +/* + * Set USERMEM to the maximum amount of physical user memory available * in bytes. USERMEM is used to determine the maximum BITS that can be used - * for compression. If USERMEM is big enough, use fast compression algorithm. + * for compression. * * SACREDMEM is the amount of physical memory saved for others; compress * will hog the rest. @@ -20,93 +24,56 @@ static char sccsid[] = "@(#)compress.c 5.4 (Berkeley) %G%"; #endif #ifndef USERMEM -# define USERMEM 750000 /* default user memory */ +# define USERMEM 450000 /* default user memory */ +#endif + +#ifdef interdata /* (Perkin-Elmer) */ +#define SIGNED_COMPARE_SLOW /* signed compare is slower than unsigned */ #endif #ifdef pdp11 # define BITS 12 /* max bits/code for 16-bit machine */ # define NO_UCHAR /* also if "unsigned char" functions as signed char */ -# define SHORT_INT /* ints are short */ # undef USERMEM -#endif pdp11 +#endif /* pdp11 */ /* don't forget to compile with -i */ #ifdef z8000 # define BITS 12 -# define SHORT_INT # undef vax /* weird preprocessor */ # undef USERMEM -#endif z8000 +#endif /* z8000 */ #ifdef pcxt # define BITS 12 -# define SHORT_INT -# define SMALL_STACK /* at least for Latice C, sez Lauren */ # undef USERMEM -#endif pcxt - -/* - * Define FBITS for machines with several MB of physical memory, to use - * table lookup for (b <= FBITS). If FBITS is made too large, performance - * will decrease due to increased swapping/paging. Since the program minus - * the fast lookup table is about a half Meg, we can allocate the rest of - * available physical memory to the fast lookup table. - * - * If FBITS is set to 12, a 2 MB array is allocated, but only 1 MB is - * addressed for parity-free input (i.e. text). - * - * FBITS=10 yields 1/2 meg lookup table + 4K code memory - * FBITS=11 yields 1 meg lookup table + 8K code memory - * FBITS=12 yields 2 meg lookup table + 16K code memory - * FBITS=13 yields 4 meg lookup table + 32K code memory - * - */ +#endif /* pcxt */ #ifdef USERMEM -# if USERMEM >= (2621440+SACREDMEM) -# if USERMEM >= (4718592+SACREDMEM) -# define FBITS 13 -# define PBITS 16 -# else 2.5M <= USERMEM < 4.5M -# define FBITS 12 -# define PBITS 16 -# endif USERMEM <=> 4.5M -# else USERMEM < 2.5M -# if USERMEM >= (1572864+SACREDMEM) -# define FBITS 11 -# define PBITS 16 -# else USERMEM < 1.5M -# if USERMEM >= (1048576+SACREDMEM) -# define FBITS 10 -# define PBITS 16 -# else USERMEM < 1M -# if USERMEM >= (631808+SACREDMEM) -# define PBITS 16 +# if USERMEM >= (433484+SACREDMEM) +# define PBITS 16 +# else +# if USERMEM >= (229600+SACREDMEM) +# define PBITS 15 +# else +# if USERMEM >= (127536+SACREDMEM) +# define PBITS 14 +# else +# if USERMEM >= (73464+SACREDMEM) +# define PBITS 13 # else -# if USERMEM >= (329728+SACREDMEM) -# define PBITS 15 -# else -# if USERMEM >= (178176+SACREDMEM) -# define PBITS 14 -# else -# if USERMEM >= (99328+SACREDMEM) -# define PBITS 13 -# else -# define PBITS 12 -# endif -# endif -# endif +# define PBITS 12 # endif -# undef USERMEM -# endif USERMEM <=> 1M -# endif USERMEM <=> 1.5M -# endif USERMEM <=> 2.5M -#endif USERMEM +# endif +# endif +# endif +# undef USERMEM +#endif /* USERMEM */ #ifdef PBITS /* Preferred BITS for this memory size */ # ifndef BITS # define BITS PBITS # endif BITS -#endif PBITS +#endif /* PBITS */ #if BITS == 16 # define HSIZE 69001 /* 95% occupancy */ @@ -123,7 +90,16 @@ static char sccsid[] = "@(#)compress.c 5.4 (Berkeley) %G%"; #if BITS <= 12 # define HSIZE 5003 /* 80% occupancy */ #endif -/* BITS < 9 will cause an error */ + +#ifdef M_XENIX /* Stupid compiler can't handle arrays with */ +# if BITS == 16 /* more than 65535 bytes - so we fake it */ +# define XENIX_16 +# else +# if BITS > 13 /* Code only handles BITS = 12, 13, or 16 */ +# define BITS 13 +# endif +# endif +#endif /* * a code_int must be able to hold 2**BITS values of type int, and also -1 @@ -134,7 +110,7 @@ typedef long int code_int; typedef int code_int; #endif -#ifdef interdata +#ifdef SIGNED_COMPARE_SLOW typedef unsigned long int count_int; typedef unsigned short int count_short; #else @@ -143,9 +119,9 @@ typedef long int count_int; #ifdef NO_UCHAR typedef char char_type; -#else UCHAR +#else typedef unsigned char char_type; -#endif UCHAR +#endif /* UCHAR */ char_type magic_header[] = { "\037\235" }; /* 1F 9D */ /* Defines for third byte of header */ @@ -166,8 +142,30 @@ char_type magic_header[] = { "\037\235" }; /* 1F 9D */ * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * - * $Header: compress.c,v 3.2 85/06/06 21:53:24 jaw Exp $ + * $Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $ * $Log: compress.c,v $ + * Revision 4.0 85/07/30 12:50:00 joe + * Removed ferror() calls in output routine on every output except first. + * Prepared for release to the world. + * + * Revision 3.6 85/07/04 01:22:21 joe + * Remove much wasted storage by overlaying hash table with the tables + * used by decompress: tab_suffix[1< #include @@ -274,35 +270,60 @@ code_int maxcode; /* maximum code, given n_bits */ code_int maxmaxcode = 1 << BITS; /* should NEVER generate this code */ #ifdef COMPATIBLE /* But wrong! */ # define MAXCODE(n_bits) (1 << (n_bits) - 1) -#else COMPATIBLE +#else # define MAXCODE(n_bits) ((1 << (n_bits)) - 1) -#endif COMPATIBLE - -/* - * One code could conceivably represent (1<> 13][(i) & 0x1fff]) +unsigned short code0tab[16384]; +unsigned short code1tab[16384]; +unsigned short code2tab[16384]; +unsigned short code3tab[16384]; +unsigned short code4tab[16384]; +unsigned short * codetab[5] = { + code0tab, code1tab, code2tab, code3tab, code4tab }; + +#define codetabof(i) (codetab[(i) >> 14][(i) & 0x3fff]) + +#else /* Normal machine */ count_int htab [HSIZE]; unsigned short codetab [HSIZE]; +#define htabof(i) htab[i] +#define codetabof(i) codetab[i] +#endif /* XENIX_16 */ code_int hsize = HSIZE; /* for dynamic table sizing */ count_int fsize; -#define tab_prefix codetab /* prefix code for this entry */ -char_type tab_suffix[1<>15])[(i) & 0x7fff] +# define de_stack ((char_type *)(htab2)) +#else /* Normal machine */ +# define tab_suffixof(i) ((char_type *)(htab))[i] +# define de_stack ((char_type *)&tab_suffixof(1< debug - * -V => debug verbose + * -V => print Version; debug verbose * -d => do_decomp * -v => unquiet * -f => force overwrite of output file @@ -446,8 +469,13 @@ register int argc; char **argv; break; case 'V': verbose = 1; + version(); + break; +#else + case 'V': + version(); break; -#endif DEBUG +#endif /* DEBUG */ case 'v': quiet = 0; break; @@ -489,7 +517,7 @@ register int argc; char **argv; else { /* Input file name */ *fileptr++ = *argv; /* Build input file list */ *fileptr = NULL; - /* goto nextarg; */ + /* process nextarg; */ } nextarg: continue; } @@ -548,7 +576,9 @@ register int argc; char **argv; stat ( *fileptr, &statbuf ); fsize = (long) statbuf.st_size; /* - * tune hash table size for small files -- ad hoc + * tune hash table size for small files -- ad hoc, + * but the sizes match earlier #defines, which + * serve as upper bounds on the number of output codes. */ hsize = HSIZE; if ( fsize < (1 << 12) ) @@ -571,7 +601,7 @@ register int argc; char **argv; fprintf(stderr,"%s: filename too long to tack on .Z\n",cp); continue; } -#endif BSD4_2 /* Long filenames allowed */ +#endif /* BSD4_2 Long filenames allowed */ strcat(ofname, ".Z"); } /* Check for overwrite of existing file */ @@ -610,20 +640,23 @@ register int argc; char **argv; if (do_decomp == 0) compress(); #ifndef DEBUG else decompress(); -#else DEBUG +#else else if (debug == 0) decompress(); else printcodes(); if (verbose) dump_tab(); -#endif DEBUG +#endif /* DEBUG */ if(zcat_flg == 0) { copystat(*fileptr, ofname); /* Copy stats */ - if(exit_stat || (!quiet)) + if((exit_stat == 1) || (!quiet)) putc('\n', stderr); } } } else { /* Standard input */ if (do_decomp == 0) { compress(); +#ifdef DEBUG + if(verbose) dump_tab(); +#endif /* DEBUG */ if(!quiet) putc('\n', stderr); } else { @@ -648,11 +681,11 @@ register int argc; char **argv; } #ifndef DEBUG decompress(); -#else DEBUG +#else if (debug == 0) decompress(); else printcodes(); if (verbose) dump_tab(); -#endif DEBUG +#endif /* DEBUG */ } } exit(exit_stat); @@ -663,163 +696,106 @@ long int in_count = 1; /* length of input */ long int bytes_out; /* length of compressed output */ long int out_count = 0; /* # of codes output (for debugging) */ -#define HOG_CHECK ((count_int) 2000) /* Number of chars to read b4 check */ -#define MAX_CACHE ((count_int) 1<= 30000) ) { /* use hashing on small files */ - if ( nfiles++ > 0 ) /* clear table between files */ - cl_sparse (); + ent = getchar (); - while ( (c = getchar()) != (unsigned) EOF ) { - in_count++; - fcode = (long) (((long) c << maxbits) + ent); - if ( ftable [fcode] != 0 ) /* test for code in "string" table */ - ent = ftable [fcode]; - else { - output ( (code_int) ent ); - out_count++; - ent = c; - if ( free_ent >= maxmaxcode ) { - if ( (count_int)in_count < checkpoint || (!block_compress) ) - continue; - else { - cl_block (); - i = 0; - } - } else { /* put code in table */ - ftable [fcode] = (short) free_ent++; - fcodemem [i++] = fcode; /* memorize for block compression */ - } - } - } - goto fin; -} -#endif USERMEM + hshift = 0; + for ( fcode = (long) hsize; fcode < 65536L; fcode *= 2L ) + hshift++; + hshift = 8 - hshift; /* set hash code range bound */ - chog = CHOG; /* assumed character for the hog */ - cstat_flg = 0; hsize_reg = hsize; - cl_hash( (count_int) hsize_reg); /* clear hash tables */ + cl_hash( (count_int) hsize_reg); /* clear hash table */ +#ifdef SIGNED_COMPARE_SLOW while ( (c = getchar()) != (unsigned) EOF ) { +#else + while ( (c = getchar()) != EOF ) { +#endif in_count++; - if ( cstat_flg == 0 ) { - cfreq [c]++; /* gather frequencies at start of input */ - if ( (count_int)in_count > HOG_CHECK ) { - cstat_flg = 1; - chog = hogtally(); /* compute char hog */ - if(chog != CHOG) /* fixup for wrong assumption */ - cl_cache( (count_int) free_ent ); - } - } - if ( c == chog ) - if ( (i = hashcache [ent]) ) { /* cache -> code */ - ent = i; - continue; - } fcode = (long) (((long) c << maxbits) + ent); -#ifdef SHORT_INT - i = (((c + 12347) * ent) & 077777) % HSIZE; /* avoid 'lrem' call */ -#else !SHORT_INT - i = fcode % hsize_reg; /* division hashing */ -#endif SHORT_INT - - if ( htab [i] == fcode ) { - ent = codetab [i]; + i = ((c << hshift) ^ ent); /* xor hashing */ + + if ( htabof (i) == fcode ) { + ent = codetabof (i); continue; - } else if ( (long)htab [i] < 0 ) /* empty slot */ + } else if ( (long)htabof (i) < 0 ) /* empty slot */ goto nomatch; - disp = hsize_reg - i; /* secondary hash (G. Knott) */ + disp = hsize_reg - i; /* secondary hash (after G. Knott) */ if ( i == 0 ) disp = 1; probe: if ( (i -= disp) < 0 ) i += hsize_reg; - if ( htab [i] == fcode ) { - ent = codetab [i]; + if ( htabof (i) == fcode ) { + ent = codetabof (i); continue; } - if ( (long)htab [i] > 0 ) + if ( (long)htabof (i) > 0 ) goto probe; nomatch: output ( (code_int) ent ); out_count++; -#ifdef interdata + ent = c; +#ifdef SIGNED_COMPARE_SLOW if ( (unsigned) free_ent < (unsigned) maxmaxcode) { #else if ( free_ent < maxmaxcode ) { #endif - if ( c == chog ) /* code -> cache */ - hashcache [ent] = free_ent; - /* code -> hashtable */ - codetab [i] = free_ent++; - htab [i] = fcode; + codetabof (i) = free_ent++; /* code -> hashtable */ + htabof (i) = fcode; } else if ( (count_int)in_count >= checkpoint && block_compress ) cl_block (); - ent = c; } -fin: /* * Put out the final code. */ @@ -833,16 +809,19 @@ fin: if(zcat_flg == 0 && !quiet) { #ifdef DEBUG fprintf( stderr, - "%ld chars in, %ld codes (%ld bytes) out, compression factor %g\n", - in_count, out_count, bytes_out, - (double)in_count / (double)bytes_out ); - fprintf( stderr, "\tCompression as in compact: %5.2f%%\n", - 100.0 * ( in_count - bytes_out ) / (double) in_count ); - fprintf( stderr, "\tLargest code was %d (%d bits)\n", free_ent - 1, n_bits ); -#else DEBUG - fprintf( stderr, "Compression: %5.2f%%", - 100.0 * ( in_count - bytes_out ) / (double) in_count ); -#endif DEBUG + "%ld chars in, %ld codes (%ld bytes) out, compression factor: ", + in_count, out_count, bytes_out ); + prratio( stderr, in_count, bytes_out ); + fprintf( stderr, "\n"); + fprintf( stderr, "\tCompression as in compact: " ); + prratio( stderr, in_count-bytes_out, in_count ); + fprintf( stderr, "\n"); + fprintf( stderr, "\tLargest code (of last block) was %d (%d bits)\n", + free_ent - 1, n_bits ); +#else /* !DEBUG */ + fprintf( stderr, "Compression: " ); + prratio( stderr, in_count-bytes_out, in_count ); +#endif /* DEBUG */ } if(bytes_out > in_count) /* exit(2) if no savings */ exit_stat = 2; @@ -871,14 +850,14 @@ static char buf[BITS]; #ifndef vax char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; -#endif !vax +#endif /* vax */ output( code ) code_int code; { #ifdef DEBUG static int col = 0; -#endif DEBUG +#endif /* DEBUG */ /* * On the VAX, it is important to have the register declarations @@ -887,16 +866,21 @@ code_int code; register int r_off = offset, bits= n_bits; register char * bp = buf; +#ifdef DEBUG + if ( verbose ) + fprintf( stderr, "%5d%c", code, + (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); +#endif /* DEBUG */ if ( code >= 0 ) { #ifdef vax - /* VAX DEPENDENT!! Implementation on other machines may be difficult. + /* VAX DEPENDENT!! Implementation on other machines is below. * * Translation: Insert BITS bits from the argument starting at * offset bits from the beginning of buf. */ - 0; /* C compiler bug ?? */ + 0; /* Work around for pcc -O bug with asm and if stmt */ asm( "insv 4(ap),r11,r10,(r9)" ); -#else not a vax +#else /* not a vax */ /* * byte/bit numbering on the VAX is simulated by the following code */ @@ -922,7 +906,7 @@ code_int code; /* Last bits. */ if(bits) *bp = code; -#endif vax +#endif /* vax */ offset += n_bits; if ( offset == (n_bits << 3) ) { bp = buf; @@ -931,15 +915,8 @@ code_int code; do putchar(*bp++); while(--bits); - if (ferror(stdout)) - writeerr(); offset = 0; } -#ifdef DEBUG - if ( verbose ) - fprintf( stderr, "%5d%c", code, - (col+=6) >= 74 ? (col = 0, '\n') : ' ' ); -#endif DEBUG /* * If the next entry is going to be too big for the code size, @@ -974,7 +951,7 @@ code_int code; fprintf( stderr, "\nChange to %d bits\n", n_bits ); col = 0; } -#endif DEBUG +#endif /* DEBUG */ } } else { /* @@ -988,44 +965,47 @@ code_int code; #ifdef DEBUG if ( verbose ) fprintf( stderr, "\n" ); -#endif DEBUG +#endif /* DEBUG */ if( ferror( stdout ) ) writeerr(); } } -#ifdef SMALL_STACK - char_type stack[MAXSTACK]; -#endif +/* + * Decompress stdin to stdout. This routine adapts to the codes in the + * file building the "string" table on-the-fly; requiring no table to + * be stored in the compressed file. The tables used herein are shared + * with those of the compress() routine. See the definitions above. + */ decompress() { register char_type *stackp; register int finchar; register code_int code, oldcode, incode; -#ifndef SMALL_STACK - char_type stack[MAXSTACK]; -#endif - /* * As above, initialize the first 256 entries in the table. */ maxcode = MAXCODE(n_bits = INIT_BITS); for ( code = 255; code >= 0; code-- ) { - tab_prefix[code] = 0; - tab_suffix[code] = (char_type)code; + tab_prefixof(code) = 0; + tab_suffixof(code) = (char_type)code; } free_ent = ((block_compress) ? FIRST : 256 ); finchar = oldcode = getcode(); + if(oldcode == -1) /* EOF already? */ + return; /* Get out of here */ putchar( (char)finchar ); /* first code must be 8 bits = char */ - stackp = &stack[0]; + if(ferror(stdout)) /* Crash if can't write */ + writeerr(); + stackp = de_stack; - while ( (code = getcode()) != -1 ) { + while ( (code = getcode()) > -1 ) { if ( (code == CLEAR) && block_compress ) { for ( code = 255; code >= 0; code-- ) - tab_prefix[code] = 0; + tab_prefixof(code) = 0; clear_flg = 1; free_ent = FIRST - 1; if ( (code = getcode ()) == -1 ) /* O, untimely death! */ @@ -1043,31 +1023,29 @@ decompress() { /* * Generate output characters in reverse order */ -#ifdef interdata +#ifdef SIGNED_COMPARE_SLOW while ( ((unsigned long)code) >= ((unsigned long)256) ) { -#else !interdata +#else while ( code >= 256 ) { -#endif interdata - *stackp++ = tab_suffix[code]; - code = tab_prefix[code]; +#endif + *stackp++ = tab_suffixof(code); + code = tab_prefixof(code); } - *stackp++ = finchar = tab_suffix[code]; + *stackp++ = finchar = tab_suffixof(code); /* * And put them out in forward order */ - while ( --stackp > &stack[0] ) - putchar ( *stackp ); - putchar ( *stackp ); - if (ferror(stdout)) - writeerr ( ); + do + putchar ( *--stackp ); + while ( stackp > de_stack ); /* * Generate the new entry. */ if ( (code=free_ent) < maxmaxcode ) { - tab_prefix[code] = (unsigned short)oldcode; - tab_suffix[code] = finchar; + tab_prefixof(code) = (unsigned short)oldcode; + tab_suffixof(code) = finchar; free_ent = code+1; } /* @@ -1130,7 +1108,7 @@ getcode() { bits = n_bits; #ifdef vax asm( "extzv r10,r9,(r8),r11" ); -#else not a vax +#else /* not a vax */ /* * Get to the first byte. */ @@ -1139,24 +1117,24 @@ getcode() { /* Get first part (low order bits) */ #ifdef NO_UCHAR code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff; -#else NO_UCHAR +#else code = (*bp++ >> r_off); -#endif NO_UCHAR +#endif /* NO_UCHAR */ bits -= (8 - r_off); r_off = 8 - r_off; /* now, offset into code word */ /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ if ( bits >= 8 ) { #ifdef NO_UCHAR code |= (*bp++ & 0xff) << r_off; -#else NO_UCHAR +#else code |= *bp++ << r_off; -#endif NO_UCHAR +#endif /* NO_UCHAR */ r_off += 8; bits -= 8; } /* high order bits. */ code |= (*bp & rmask[bits]) << r_off; -#endif vax +#endif /* vax */ offset += n_bits; return code; @@ -1203,57 +1181,89 @@ printcodes() exit( 0 ); } +code_int sorttab[1<= FIRST ? tab_prefix[ent] : NULL) ) { - if ( isascii(tab_suffix[ent]) && isprint(tab_suffix[ent]) ) - stack[--stack_top] = tab_suffix[ent]; - else { - switch( tab_suffix[ent] ) { - case '\n': stack[--stack_top] = 'n'; break; - case '\t': stack[--stack_top] = 't'; break; - case '\b': stack[--stack_top] = 'b'; break; - case '\f': stack[--stack_top] = 'f'; break; - case '\r': stack[--stack_top] = 'r'; break; - default: - stack[--stack_top] = '0' + tab_suffix[ent] % 8; - stack[--stack_top] = '0' + (tab_suffix[ent] / 8) % 8; - stack[--stack_top] = '0' + tab_suffix[ent] / 64; - break; +#define STACK_SIZE 15000 + int stack_top = STACK_SIZE; + register c; + + if(do_decomp == 0) { /* compressing */ + register int flag = 1; + + for(i=0; i= 0) { + sorttab[codetabof(i)] = i; } - stack[--stack_top] = '\\'; - } } - fwrite( &stack[stack_top], 1, 4 * MAXSTACK - stack_top, stderr ); - stack_top = 4 * MAXSTACK; + first = block_compress ? FIRST : 256; + for(i = first; i < free_ent; i++) { + fprintf(stderr, "%5d: \"", i); + de_stack[--stack_top] = '\n'; + de_stack[--stack_top] = '"'; + stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff, + stack_top); + for(ent=htabof(sorttab[i]) & ((1< 256; + ent=htabof(sorttab[ent]) & ((1<> maxbits, + stack_top); + } + stack_top = in_stack(ent, stack_top); + fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr); + stack_top = STACK_SIZE; + } + } else if(!debug) { /* decompressing */ + + for ( i = 0; i < free_ent; i++ ) { + ent = i; + c = tab_suffixof(ent); + if ( isascii(c) && isprint(c) ) + fprintf( stderr, "%5d: %5d/'%c' \"", + ent, tab_prefixof(ent), c ); + else + fprintf( stderr, "%5d: %5d/\\%03o \"", + ent, tab_prefixof(ent), c ); + de_stack[--stack_top] = '\n'; + de_stack[--stack_top] = '"'; + for ( ; ent != NULL; + ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) { + stack_top = in_stack(tab_suffixof(ent), stack_top); + } + fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr ); + stack_top = STACK_SIZE; + } } } -#endif DEBUG -/***************************************************************** - * TAG( writeerr ) - * - * Exits with a message. We only check for write errors often enough - * to avoid a lot of "file system full" messages, not on every write. - * ferror() check after fflush will catch any others (I trust). - * - */ +int +in_stack(c, stack_top) + register c, stack_top; +{ + if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) { + de_stack[--stack_top] = c; + } else { + switch( c ) { + case '\n': de_stack[--stack_top] = 'n'; break; + case '\t': de_stack[--stack_top] = 't'; break; + case '\b': de_stack[--stack_top] = 'b'; break; + case '\f': de_stack[--stack_top] = 'f'; break; + case '\r': de_stack[--stack_top] = 'r'; break; + case '\\': de_stack[--stack_top] = '\\'; break; + default: + de_stack[--stack_top] = '0' + c % 8; + de_stack[--stack_top] = '0' + (c / 8) % 8; + de_stack[--stack_top] = '0' + c / 64; + break; + } + de_stack[--stack_top] = '\\'; + } + return stack_top; +} +#endif /* DEBUG */ writeerr() { @@ -1285,8 +1295,9 @@ char *ifname, *ofname; fprintf(stderr, " -- has %d other links: unchanged", statbuf.st_nlink - 1); exit_stat = 1; - } else if (exit_stat == 2 && (!force) && !quiet) { /* No compression: remove file.Z */ - fprintf(stderr, " -- file unchanged"); + } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */ + if(!quiet) + fprintf(stderr, " -- file unchanged"); } else { /* ***** Successful Compression ***** */ exit_stat = 0; mode = statbuf.st_mode & 07777; @@ -1326,95 +1337,86 @@ foreground() onintr ( ) { - if (!zcat_flg) - unlink ( ofname ); + unlink ( ofname ); + exit ( 1 ); +} + +oops ( ) /* wild pointer -- assume bad input */ +{ + if ( do_decomp == 1 ) + fprintf ( stderr, "uncompress: corrupt input\n" ); + unlink ( ofname ); exit ( 1 ); } cl_block () /* table clear for block compress */ { -#ifdef DEBUG - if(debug) - fprintf ( stderr, "count: %ld ratio: %f\n", in_count, - (double) in_count / (double) bytes_out ); -#endif DEBUG + register long int rat; checkpoint = in_count + CHECK_GAP; - if ( (double) in_count / (double) bytes_out > ratio ) - ratio = (double) in_count / (double) bytes_out; - else { - ratio = 0.0; -#ifdef USERMEM - if ( maxbits <= FBITS ) /* sparse array clear */ - cl_sparse (); - else -#endif USERMEM /* hash table clear */ - { - cl_hash ( (count_int) hsize ); +#ifdef DEBUG + if ( debug ) { + fprintf ( stderr, "count: %ld, ratio: ", in_count ); + prratio ( stderr, in_count, bytes_out ); + fprintf ( stderr, "\n"); + } +#endif /* DEBUG */ + + if(in_count > 0x007fffff) { /* shift will overflow */ + rat = bytes_out >> 8; + if(rat == 0) { /* Don't divide by zero */ + rat = 0x7fffffff; + } else { + rat = in_count / rat; } + } else { + rat = (in_count << 8) / bytes_out; /* 8 fractional bits */ + } + if ( rat > ratio ) { + ratio = rat; + } else { + ratio = 0; +#ifdef DEBUG + if(verbose) + dump_tab(); /* dump string table */ +#endif + cl_hash ( (count_int) hsize ); free_ent = FIRST; clear_flg = 1; output ( (code_int) CLEAR ); #ifdef DEBUG if(debug) fprintf ( stderr, "clear\n" ); -#endif DEBUG - } -} - -cl_cache ( n ) /* clear hash cache */ - register count_int n; /* clear at least this many entries */ -{ - register count_int i; - register unsigned short *hash_p; - register unsigned short zero = 0; - - if ( nfiles++ == 0 ) /* no clear needed if first time */ - return; - n = (n+15) & (-16); - hash_p = hashcache + n; - for ( i = n; i > 0; i -=16 ) { /* can do BSD bzero(3) or Sys V memset(3) */ - *(hash_p-16) = zero; - *(hash_p-15) = zero; - *(hash_p-14) = zero; - *(hash_p-13) = zero; - *(hash_p-12) = zero; - *(hash_p-11) = zero; - *(hash_p-10) = zero; - *(hash_p-9) = zero; - *(hash_p-8) = zero; - *(hash_p-7) = zero; - *(hash_p-6) = zero; - *(hash_p-5) = zero; - *(hash_p-4) = zero; - *(hash_p-3) = zero; - *(hash_p-2) = zero; - *(hash_p-1) = zero; - hash_p -= 16; +#endif /* DEBUG */ } } -hogtally () /* compute character code hog */ -{ - register int i, most; - - for ( i = most = 0; i < 256; i++ ) - if ( cfreq [i] >= cfreq [most] ) - most = i; - return ( most ); -} - -cl_hash(hsize) /* clear hash cache, re-init code table */ +cl_hash(hsize) /* reset code table */ register count_int hsize; { +#ifndef XENIX_16 /* Normal machine */ register count_int *htab_p = htab+hsize; +#else + register j; + register long k = hsize; + register count_int *htab_p; +#endif register long i; register long m1 = -1; - cl_cache( min((count_int)hsize, MAX_CACHE) ); - +#ifdef XENIX_16 + for(j=0; j<=8 && k>=0; j++,k-=8192) { + i = 8192; + if(k < 8192) { + i = k; + } + htab_p = &(htab[j][i]); + i -= 16; + if(i > 0) { +#else i = hsize - 16; - do { +#endif + do { /* might use Sys V memset(3) here */ *(htab_p-16) = m1; *(htab_p-15) = m1; *(htab_p-14) = m1; @@ -1433,16 +1435,56 @@ cl_hash(hsize) /* clear hash cache, re-init code table */ *(htab_p-1) = m1; htab_p -= 16; } while ((i -= 16) >= 0); +#ifdef XENIX_16 + } + } +#endif for ( i += 16; i > 0; i-- ) *--htab_p = m1; } -#ifdef USERMEM -cl_sparse ( ) /* clear sparse table indirectly thru "shadow" array */ +prratio(stream, num, den) +FILE *stream; +long int num, den; { - register code_int i; + register int q; /* Doesn't need to be long */ + + if(num > 214748L) { /* 2147483647/10000 */ + q = num / (den / 10000L); + } else { + q = 10000L * num / den; /* Long calculations, though */ + } + if (q < 0) { + putc('-', stream); + q = -q; + } + fprintf(stream, "%d.%02d%%", q / 100, q % 100); +} - for ( i = (1 << maxbits) - 1; i >= 0; i-- ) - ftable [fcodemem [i]] = 0; +version() +{ + fprintf(stderr, "%s\n", rcs_ident); + fprintf(stderr, "Options: "); +#ifdef vax + fprintf(stderr, "vax, "); +#endif +#ifdef NO_UCHAR + fprintf(stderr, "NO_UCHAR, "); +#endif +#ifdef SIGNED_COMPARE_SLOW + fprintf(stderr, "SIGNED_COMPARE_SLOW, "); +#endif +#ifdef XENIX_16 + fprintf(stderr, "XENIX_16, "); +#endif +#ifdef COMPATIBLE + fprintf(stderr, "COMPATIBLE, "); +#endif +#ifdef DEBUG + fprintf(stderr, "DEBUG, "); +#endif +#ifdef BSD4_2 + fprintf(stderr, "BSD4_2, "); +#endif + fprintf(stderr, "BITS = %d\n", BITS); } -#endif USERMEM diff --git a/usr/src/usr.bin/compress/usermem.sh b/usr/src/usr.bin/compress/usermem.sh index 59c68c7b14..527f8c6085 100644 --- a/usr/src/usr.bin/compress/usermem.sh +++ b/usr/src/usr.bin/compress/usermem.sh @@ -1,6 +1,6 @@ #!/bin/sh - # -# @(#)usermem.sh 5.1 (Berkeley) %G% +# @(#)usermem.sh 5.2 (Berkeley) %G% # : This shell script snoops around to find the maximum amount of available : user memory. These variables need to be set only if there is no @@ -46,17 +46,28 @@ then SIZE=`echo maxmem/D | adb $UNIX $KMEM | sed -n '$s/.*[ ]//p'` if test 0$SIZE -le 0 then - SIZE=`echo physmem/D | adb $UNIX $KMEM | sed -n '$s/.*[ - ]//p'` + SIZE=`echo physmem/D | adb $UNIX $KMEM | sed -n '$s/.*[ ]//p'` fi SIZE=`expr 0$SIZE '*' $CLICKSIZE` fi fi fi +case $UNIX in + /vmunix) # Assume 4.2bsd: check for resource limits + MAXSIZE=`csh -c limit | awk 'BEGIN { MAXSIZE = 1000000 } +/datasize|memoryuse/ && NF == 3 { if ($2 < MAXSIZE) MAXSIZE = $2 } +END { print MAXSIZE * 1000 }'` + if test $MAXSIZE -lt $SIZE + then + SIZE=$MAXSIZE + fi + ;; +esac + if test 0$SIZE -le 0 then - echo 0 + echo 0;exit 1 else echo $SIZE fi -- 2.20.1