Annotation of 42BSD/ucb/compact/compact.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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