Annotation of 42BSD/ucb/compact/compact.c, revision 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.