# 2.11BSD#431 - /usr/src/ucb/compress/compress.c

##### Functions

    Usage             X
    cl_block          X
    cl_hash           X
    compress          X
    copystat          X
    decompress        X
    dump_tab          X
    getcode           X
    in_stack          X
    main              X
    onintr            X
    oops              X
    output            X
    printcodes        X
    prratio           X
    rindex            X
    version           X
    writeerr          X

##### Variables

    bgnd_flag         X
    block_compress    X
    bytes_out         X
    checkpoint        X
    clear_flg         X
    code0tab          X
    code1tab          X
    code2tab          X
    code3tab          X
    code4tab          X
    codetab           X
    debug             X
    do_decomp         X
    exit_stat         X
    force             X
    free_ent          X
    fsize             X
    hsize             X
    htab              X
    htab0             X
    htab1             X
    htab2             X
    htab3             X
    htab4             X
    htab5             X
    htab6             X
    htab7             X
    htab8             X
    in_count          X
    lmask             X
    magic_header      X
    maxbits           X
    maxcode           X
    maxmaxcode        X
    n_bits            X
    nomagic           X
    ofname            X
    out_count         X
    perm_stat         X
    precious          X
    quiet             X
    ratio             X
    rmask             X
    sorttab           X
    verbose           X
    zcat_flg          X

##### Macros

    ARGVAL            X
    BITS              X
    BIT_MASK          X
    BLOCK_MASK        X
    CHECK_GAP         X
    CLEAR             X
    FIRST             X
    HSIZE             X
    INIT_BITS         X
    MAXCODE           X
    NO_UCHAR          X
    PBITS             X
    SACREDMEM         X
    SIGNED_COMPARE_SLOWX
    STACK_SIZE        X
    USERMEM           X
    XENIX_16          X
    codetabof         X
    de_stack          X
    htabof            X
    min               X
    tab_prefixof      X
    tab_suffixof      X

##### typedef's

    char_type         X
    code_int          X
    count_int         X
    count_short       X

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

#### Defined functions

Usage defined in line 346; used 2 times

- in line 522, 535

cl_block defined in line 1369; used 1 times

- in line 827

cl_hash defined in line 1411; used 2 times

- in line 785, 1400

compress defined in line 745; used 2 times

- in line 669, 686

copystat defined in line 1305; used 1 times

- in line 678

decompress defined in line 1011; used 4 times

- in line 671-673(2), 713-715(2)

dump_tab defined in line 1216; used 4 times

- in line 675, 688, 717, 1398

getcode defined in line 1101; used 5 times

- in line 344, 1026, 1034, 1041, 1196

in_stack defined in line 1272; used 4 times

- in line 1237-1245(3), 1264

main defined in line 423; never used
onintr defined in line 1354; used 2 times

- in line 431-435(2)

oops defined in line 1361; used 2 times

- in line 431-436(2)

output defined in line 885; used 4 times

- in line 815, 832-834(2), 1403

printcodes defined in line 1185; used 2 times

- in line 674, 716

prratio defined in line 1463; used 4 times

- in line 844-847(2), 853, 1377

rindex defined in line 1173; used 3 times

- in line 429, 454, 625

version defined in line 1481; used 2 times

- in line 495-499(2)

writeerr defined in line 1298; used 5 times

- in line 763, 963, 1000, 1031, 1088

#### Defined variables

bgnd_flag defined in line 382; used 4 times

- in line 438-443(3), 640

block_compress defined in line 364; used 11 times

- in line 517, 578, 701, 761, 775, 826, 1024, 1036, 1195-1197(2), 1232

buf defined in line 878; used 7 times

- in line 897, 942, 962, 991, 1109-1111(2), 1130

bytes_out defined in line 726; used 12 times

- in line 768, 843-847(3), 853-856(2), 944, 964, 992, 1377, 1383, 1390

checkpoint defined in line 368; used 3 times

- in line 773, 826, 1373

clear_flg defined in line 365; used 10 times

- in line 770, 955, 968-970(2), 1039, 1113, 1126-1128(2), 1199, 1402

code0tab defined in line 294; used 1 times

- in line 300

code1tab defined in line 295; used 1 times

- in line 300

code2tab defined in line 296; used 1 times

- in line 300

code3tab defined in line 297; used 1 times

- in line 300

code4tab defined in line 298; used 1 times

- in line 300

codetab defined in line 313; used 2 times

- in line 302, 317

debug defined in line 350; used 7 times

- in line 491, 673, 715, 980, 1249, 1375, 1405

do_decomp defined in line 384; used 8 times

- in line 460-462(2), 506, 555, 669, 685, 1224, 1363

exit_stat defined in line 341; used 8 times

- in line 554, 680, 721, 857, 1321, 1328-1334(3)

force defined in line 376; used 2 times

- in line 511, 1330

free_ent defined in line 340; used 20 times

- in line 775, 819-823(3), 850, 955, 1024, 1040, 1048, 1076-1079(2), 1113, 1119, 1195-1202(4), 1233, 1251, 1401

fsize defined in line 320; used 7 times

- in line 604, 611-619(5), 704

hsize defined in line 319; used 15 times

- in line 610-620(6), 780-784(2), 1227, 1400, 1411-1418(4), 1434

htab defined in line 312; used 6 times

- in line 293, 316, 333-336(2), 1415, 1430

htab0 defined in line 281; used 1 times

- in line 291

htab1 defined in line 282; used 1 times

- in line 291

htab2 defined in line 283; used 2 times

- in line 291, 334

htab3 defined in line 284; used 1 times

- in line 291

htab4 defined in line 285; used 1 times

- in line 291

htab5 defined in line 286; used 1 times

- in line 291

htab6 defined in line 287; used 1 times

- in line 291

htab7 defined in line 288; used 1 times

- in line 291

htab8 defined in line 289; used 1 times

- in line 291

in_count defined in line 725; used 16 times

- in line 772, 792, 826, 843-847(4), 853-856(3), 1373-1390(6)

lmask defined in line 881; used 1 times

- in line 926

magic_header defined in line 125; used 6 times

- in line 571-572(2), 695-696(2), 760(2)

maxbits defined in line 271; used 26 times

- in line 525, 548-550(5), 577-584(6), 700-708(6), 761, 793, 974, 1121, 1237-1242(4)

maxcode defined in line 272; used 12 times

- in line 774, 955, 969, 975-977(2), 1019, 1113, 1119-1127(4), 1194

maxmaxcode defined in line 273; used 9 times

- in line 550, 580, 703, 819-821(2), 975, 1076, 1122, 1201

n_bits defined in line 270; used 32 times

- in line 275-277(4), 774, 850, 896, 940-943(3), 962-981(8), 1019, 1120-1138(7), 1168, 1193-1194(2), 1203-1205(3)

nomagic defined in line 355; used 5 times

- in line 448, 514, 570, 694, 759

offset defined in line 724; used 16 times

- in line 767, 896, 940-941(2), 948, 961-966(2), 990-993(4), 1108-1113(2), 1133-1137(2), 1168

ofname defined in line 377; used 25 times

- in line 589-590(2), 623-626(3), 632-642(4), 658-659(2), 678, 1300-1306(4), 1336-1351(7), 1357, 1365

out_count defined in line 727; used 4 times

- in line 769, 816, 833, 843

perm_stat defined in line 342; used 7 times

- in line 566, 600, 660, 721(2), 1322, 1329

precious defined in line 357; used 3 times

- in line 663, 679, 1356

quiet defined in line 358; used 10 times

- in line 503, 531, 664, 680, 690, 839, 1318, 1324, 1331, 1344

ratio defined in line 366; used 4 times

- in line 771, 1392-1395(3)

rcs_ident defined in line 257; used 1 times

- in line 1483

rmask defined in line 882; used 3 times

- in line 926, 1149, 1166

sccsid defined in line 2; never used
sorttab defined in line 1214; used 5 times

- in line 1229, 1237-1242(4)

verbose defined in line 379; used 7 times

- in line 494, 675, 688, 717, 900, 996, 1397

zcat_flg defined in line 356; used 6 times

- in line 463, 528, 635, 657, 677, 839

#### Defined typedef's

char_type defined in line 121; used 12 times

- in line 123-125(2), 881-882(2), 1012-337(5), 1022, 1109-1111(2)

code_int defined in line 108; used 20 times

- in line 110, 272-273(2), 319, 340-344(2), 747-755(4), 886, 1014, 1101, 1214-815(2), 832-834(2), 1107, 1190, 1403

count_int defined in line 114; used 21 times

- in line 117, 281-290(10), 308-312(2), 320, 368, 1412-785(2), 826, 1400, 1415-1419(2)

count_short defined in line 115; never used

#### Defined macros

ARGVAL defined in line 268; used 1 times

- in line 520

BITS defined in line 99; used 22 times

- in line 73-98(8), 107, 271-273(2), 337, 549(2), 581-584(2), 705-708(2), 878, 1109, 1214, 1506

BIT_MASK defined in line 128; used 2 times

- in line 579, 702

BLOCK_MASK defined in line 129; used 3 times

- in line 364, 578, 701

CHECK_GAP defined in line 367; used 3 times

- in line 368, 773, 1373

CLEAR defined in line 374; used 3 times

- in line 1036, 1197, 1403

FIRST defined in line 373; used 8 times

- in line 775, 1024, 1040, 1195-1198(2), 1232, 1263, 1401

HSIZE defined in line 91; used 12 times

- in line 289, 308-313(4), 319, 610-620(6)

INIT_BITS defined in line 133; used 7 times

- in line 548(2), 774, 969, 1019, 1127, 1193

MAXCODE defined in line 277; used 7 times

- in line 774, 969, 977, 1019, 1124-1127(2), 1194

NO_UCHAR defined in line 36; used 4 times

- in line 120, 1148, 1157, 1488

PBITS defined in line 64; used 2 times

- in line 72-74(2)

SACREDMEM defined in line 23; used 5 times

- in line 22, 52-61(4)

SIGNED_COMPARE_SLOW defined in line 31; used 5 times

- in line 113, 787, 818, 1056, 1491

STACK_SIZE defined in line 1220; used 5 times

- in line 1221, 1246-1247(2), 1266-1267(2)

USERMEM defined in line 27; used 10 times

- in line 26, 37, 43-61(7), 69

XENIX_16 defined in line 96; used 7 times

- in line 280, 332, 750, 1414, 1424, 1455, 1494

codetabof defined in line 317; used 5 times

- in line 331, 797, 809, 823, 1229

de_stack defined in line 337; used 19 times

- in line 1032, 1071, 1235-1236(2), 1246, 1260-1266(3), 1277-1292(11)

htabof defined in line 316; used 10 times

- in line 796-799(2), 808-812(2), 824, 1228, 1237-1242(4)

min defined in line 8; used 5 times

- in line 612-620(5)

tab_prefixof defined in line 331; used 7 times

- in line 1021, 1038, 1062, 1077, 1256-1263(3)

tab_suffixof defined in line 336; used 7 times

- in line 337, 1022, 1061-1064(2), 1078, 1253, 1264

Last modified: 1988-10-13 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3971 |