Annotation of 3BSD/cmd/compact/compact.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *  Adaptive Huffman code input to output
                      3:  *
                      4:  *  On - line algorithm
                      5:  *
                      6:  *  Does not prepend decoding tree
                      7:  *
                      8:  *  Written by Colin L. Mc Master (UCB) February 28, 1979
                      9:  */
                     10: 
                     11: 
                     12: #include "compact.h"
                     13: 
                     14: union cio d;
                     15: int bits;
                     16: 
                     17: 
                     18: main (argc, argv)
                     19: short argc;
                     20: char *argv [ ];
                     21: {
                     22:        register short i, j;
                     23:        register int m;
                     24:        union cio c;
                     25:        short l;
                     26:        longint ic, n;
                     27:        char *cp, fname [LNAME];
                     28: 
                     29:        dir [513] . next = NULL;
                     30:        for (head = dir + (j = 513); j--; ) {
                     31:                dirp = head--;
                     32:                head -> next = dirp;
                     33:        }
                     34:        bottom = dirp -> pt = dict;
                     35:        dict [0] . top [0] = dict [0] . top [1] = dirp;
                     36:        dirq = dirp -> next;
                     37:        in [EF] . flags = FBIT | SEEN;
                     38: 
                     39:        for (i = 1; ; i++) {
                     40:                ic = oc =  0;
                     41:                (bottom -> top [1]) -> next = flist;
                     42:                bottom -> top [1] = dirp;
                     43:                flist = dirq;
                     44:                if (i >= argc) {
                     45:                        uncfp = stdin;
                     46:                        cfp = stdout;
                     47:                }
                     48:                else {
                     49:                        m = -1;
                     50:                        cp = fname;
                     51:                        for (l = 0; l < (LNAME - 3) && (*cp = argv [i][l]); l++)
                     52:                                if (*cp++ == '/') m = l;
                     53:                        if (l >= (LNAME - 3) || (l - m) > 13) {
                     54:                                fprintf (stderr, "%s: File name too long\n", argv [i]);
                     55:                                if (i == argc - 1) break;
                     56:                                continue;
                     57:                        }
                     58:                        if ((uncfp = fopen (argv [i], "r")) == NULL) {
                     59:                                perror (argv [i]);
                     60:                                if (i == argc - 1) break;
                     61:                                continue;
                     62:                        }
                     63:                }
                     64: 
                     65:                fstat (fileno (uncfp), &status);
                     66:                if ((status.st_mode & 040000) == 040000) {
                     67:                        fprintf (stderr, "%s: Can't compact a directory\n", argv [i]);
                     68:                        if (i < argc) goto closein;
                     69:                        break;
                     70:                }
                     71: 
                     72:                if ((d . integ = getc (uncfp)) != EOF) {
                     73:                        ic++;
                     74:                        if ((c . integ = getc (uncfp)) != EOF) {
                     75:                                d . chars . hib = c . integ & 0377;
                     76:                                if ((d . integ &= 0177777) == COMPACTED) {
                     77:                                        fprintf (stderr, "%s: Already compacted.\n", argv [i]);
                     78:                                        if (i < argc) goto closein;
                     79:                                        break;
                     80:                                }
                     81:                                if (d . integ == PACKED) {
                     82:                                        fprintf (stderr, "%s: Already packed using program pack.  Use unpack.\n", argv [i]);
                     83:                                        if (i < argc) goto closein;
                     84:                                        break;
                     85:                                }
                     86:                                if (i < argc) {
                     87:                                        *cp++ = '.'; *cp++ = 'C'; *cp = '\0';
                     88:                                        if ((cfp = fopen (fname, "w")) == NULL) {
                     89:                                                perror (fname);
                     90:                                                goto closein;
                     91:                                        }
                     92:                                        chmod (fname, status.st_mode);
                     93:                                }
                     94:                                c . integ = COMPACTED;
                     95:                                putc (c . chars . lob, cfp);
                     96:                                putc (c . chars . hib, cfp);
                     97:                                if (ferror (cfp))
                     98:                                        if (i < argc) {
                     99:                                                perror (fname);
                    100:                                                unlink (fname);
                    101:                                                goto closeboth;
                    102:                                        }
                    103:                                        else goto fail;
                    104:                                bits = 8;
                    105:                                oc = 2;
                    106:                                c . integ = d . integ & 0377;
                    107:        
                    108:                                in [NC] . fp = in [EF] . fp = dict [0] . sp [0] . p = bottom = dict + 1;
                    109:                                bottom -> count [0] = bottom -> count [1] = dict [0] . count [1] = 1;
                    110:                                dirp -> next = dict [0] . top [1] = bottom -> top [0] = bottom -> top [1] = dirq = NEW;
                    111:                                dirq -> next = NULL;
                    112:                                dict [0] . fath . fp = NULL;
                    113:                                dirq -> pt = bottom -> fath . fp = in [c . integ] . fp = dict;
                    114:                                in [c . integ] . flags = (FBIT | SEEN);
                    115:                                in [NC] . flags = SEEN;
                    116:                                dict [0] . fath . flags = RLEAF;
                    117:                                bottom -> fath . flags = (LLEAF | RLEAF);
                    118:                                dict [0] . count [0] = 2;
                    119:        
                    120:                                dict [0] . sp [1] . ch = c . integ;
                    121:                                bottom -> sp [0] . ch = NC;
                    122:                                bottom -> sp [1] . ch = EF;
                    123:        
                    124:                                for (c . integ = ((d . integ >> 8) & 0377); c . integ != EOF; c . integ = getc (uncfp)) {
                    125:                                        ic++;
                    126:                                        if (in [c . integ] . flags & SEEN) encode (c . integ);
                    127:                                        else {
                    128:                                                encode (NC);
                    129:                                                uptree (NC);
                    130:                                                insert (c . integ);
                    131:        
                    132:                                                m = 0200;
                    133:                                                for (j = 8; j--; m >>= 1) {
                    134:                                                        d . integ <<= 1;
                    135:                                                        if (m & c . integ) d . integ++;
                    136:                                                        ++bits;
                    137:                                                        if ((bits &= 017) == 0) {
                    138:                                                                putc (d . chars . hib, cfp);
                    139:                                                                putc (d . chars . lob, cfp);
                    140:                                                                oc += 2;
                    141:                                                        }
                    142:                                                }
                    143:                                        }
                    144:                                        if (ferror (cfp))
                    145:                                                if (i < argc) {
                    146:                                                        perror (fname);
                    147:                                                        unlink (fname);
                    148:                                                        goto closeboth;
                    149:                                                }
                    150:                                                else goto fail;
                    151:                                        uptree (c . integ);
                    152:        
                    153:                                }
                    154: 
                    155:                                if (ferror (uncfp))
                    156:                                        if (i < argc) {
                    157:                                                perror (argv [i]);
                    158:                                                unlink (fname);
                    159:                                                goto closeboth;
                    160:                                        }
                    161:                                        else goto fail;
                    162:        
                    163:                                encode (EF);
                    164:        
                    165:                                if (bits) {
                    166:                                        d . integ <<= (16 - bits);
                    167:                                        oc++;
                    168:                                        putc (d . chars . hib, cfp);
                    169:                                        if (bits > 8) {
                    170:                                                oc++;
                    171:                                                putc (d . chars . lob, cfp);
                    172:                                        }
                    173:                                        bits = 0;
                    174:                                }
                    175:                        }
                    176:                        else oc = ic;
                    177:                }
                    178: 
                    179:                if (ferror (uncfp) || ferror (cfp))
                    180:                        if (i < argc) {
                    181:                                if (ferror (cfp))
                    182:                                        perror (fname);
                    183:                                else
                    184:                                        perror (argv [i]);
                    185:                                if (oc > 1) {
                    186:                                        unlink (fname);
                    187:                                        goto closeboth;
                    188:                                }
                    189:                                goto closein;
                    190:                        }
                    191:                        else goto fail;
                    192:                else {
                    193:                        if (oc >= ic) {
                    194:                                if (i < argc) fprintf (stderr, "%s: ", argv [i]);
                    195:                                if (i < argc) fprintf (stderr, "Not compacted.  ");
                    196:                                fprintf (stderr, "Does not save bytes.\n");
                    197:                                if (i < argc) {
                    198:                                        if (oc > 1) {
                    199:                                                unlink (fname);
                    200:                                                goto closeboth;
                    201:                                        }
                    202:                                        goto closein;
                    203:                                }
                    204:                                else break;
                    205:                        }
                    206:                        while ((ic - oc) > 21474) {
                    207:                                ic /= 10;
                    208:                                oc /= 10;
                    209:                        }
                    210:                        n = 100000 * (ic - oc) / ic + 5;
                    211:                        m = (n % 1000) / 10;
                    212:                        bits = m % 10 + '0';
                    213:                        c . integ = m / 10 + '0';
                    214:                        if (i < argc) fprintf (stderr, "%s:  ", argv [i]);
                    215:                        fprintf (stderr, "Compression : %4ld.%c%c%%\n", n / 1000, c . chars . lob, bits);
                    216:                }
                    217: 
                    218:                            if (i >= argc) break;
                    219:                            unlink (argv [i]);
                    220:                closeboth : fclose (cfp);
                    221:                closein   : fclose (uncfp);
                    222:                            if (i == argc - 1) break;
                    223:                            for (j = 256; j--; ) in [j] . flags = 0;
                    224:                            continue;
                    225:                fail      : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
                    226:                            break;
                    227:        }
                    228: }
                    229: 
                    230: encode (ch)
                    231: int ch;
                    232: {
                    233: 
                    234:        register struct node *pp;
                    235:        register char j;
                    236:        union cio c;
                    237:        int stack [17], stp, stbits;
                    238: 
                    239:        c . integ = ch;
                    240:        stack [stp = 0] = in [c . integ] . flags & FBIT;
                    241:        stbits = 1;
                    242:        pp = in [c . integ] . fp;
                    243: 
                    244:        while (pp -> fath . fp) {
                    245:                stack [stp] <<= 1;
                    246:                if (pp -> fath . flags & FBIT) stack [stp]++;
                    247:                stbits++;
                    248:                if ((stbits &= 017) == 0) stp++;
                    249:                pp = pp ->  fath . fp;
                    250:        }
                    251: 
                    252:        /* pop the output stack */
                    253: 
                    254:        for (stp++; stp--; ) {
                    255:                for (j = 0; j < stbits; j++) {
                    256:                        d . integ <<= 1;
                    257:                        if (stack [stp] & 01) d . integ++;
                    258:                        ++bits;
                    259:                        if ((bits &= 017) == 0) {
                    260:                                putc (d . chars . hib, cfp);
                    261:                                putc (d . chars . lob, cfp);
                    262:                                if (ferror (cfp)) return;
                    263:                                oc += 2;
                    264:                        }
                    265:                        stack [stp] >>= 1;
                    266:                }
                    267:                stbits = 16;
                    268:        }
                    269: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.