Annotation of 43BSD/old/compact/compact.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)compact.c  4.7 (Berkeley) 8/25/84";
        !             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: #include <strings.h>
        !            15: #include "compact.h"
        !            16: 
        !            17: union  cio d;
        !            18: union  cio c;
        !            19: int    bits;
        !            20: char   *infname;                       /* input file's name */
        !            21: char   fname[MAXPATHLEN+1];            /* output file's name */
        !            22: struct stat ucfstatus;                 /* uncompacted file status */
        !            23: 
        !            24: int    verbose = 0;
        !            25: 
        !            26: main(argc, argv)
        !            27:        int argc;
        !            28:        char *argv[];
        !            29: {
        !            30:        register short j;
        !            31: 
        !            32:        argc--, argv++;
        !            33:        if (argc > 0 && strcmp(*argv, "-v") == 0) {
        !            34:                verbose++;
        !            35:                argc--, argv++;
        !            36:        }
        !            37:        dir[513].next = NULL;
        !            38:        for (head = dir + (j = 513); j--; ) {
        !            39:                dirp = head--;
        !            40:                head->next = dirp;
        !            41:        }
        !            42:        bottom = dirp->pt = dict;
        !            43:        dict[0].sons[LEFT].top = dict[0].sons[RIGHT].top = dirp;
        !            44:        dirq = dirp->next;
        !            45:        in[EF].flags = FBIT | SEEN;
        !            46:        if (argc == 0)
        !            47:                exit(compact("-"));
        !            48:        for (j = 0; j < argc; j++) {
        !            49:                if (verbose && argc > 0)
        !            50:                        printf("%s: ", argv[j]);
        !            51:                if (compact(argv[j]))
        !            52:                        exit(1);
        !            53:        }
        !            54:        exit(0);
        !            55: }
        !            56: 
        !            57: /*
        !            58:  * Compact a single file ("-" implies stdin).
        !            59:  */
        !            60: compact(file)
        !            61:        char *file;
        !            62: {
        !            63:        int j, ignore;
        !            64:        FILE *setup();
        !            65: 
        !            66:        for (j = 256; j--; )
        !            67:                in[j].flags = 0;
        !            68:        bottom->sons[RIGHT].top->next = flist;
        !            69:        bottom->sons[RIGHT].top = dirp;
        !            70:        flist = dirq;
        !            71:        cfp = uncfp = NULL;
        !            72:        if (strcmp(file, "-") != 0) {
        !            73:                char *cp, *tp;
        !            74: 
        !            75:                /* verify .C suffix fits */
        !            76:                cp = rindex(file, '/');
        !            77:                if (cp == 0)
        !            78:                        cp = file;
        !            79:                else
        !            80:                        cp++;
        !            81:                tp = index(cp, '\0');
        !            82:                if (tp - cp > MAXNAMLEN || strlen(file) + 2 >= MAXPATHLEN) {
        !            83:                        fprintf(stderr, "%s: File name too long\n", file);
        !            84:                        goto bad;
        !            85:                }
        !            86:                uncfp = fopen(file, "r");
        !            87:                if (uncfp == NULL) {
        !            88:                        fprintf(stderr, "compact: "), perror(file);
        !            89:                        goto bad;
        !            90:                }
        !            91:                fstat(fileno(uncfp), &ucfstatus);
        !            92:                if ((ucfstatus.st_mode & S_IFMT) != S_IFREG) {
        !            93:                        fprintf(stderr, "%s: Not a regular file.\n", file);
        !            94:                        goto bad;
        !            95:                }
        !            96:        } else
        !            97:                uncfp = stdin;
        !            98:        infname = file;
        !            99: 
        !           100:        cfp = setup(uncfp, &ignore);
        !           101:        if (cfp == NULL) {
        !           102:                if (ignore)
        !           103:                        goto done;
        !           104:                goto bad;
        !           105:        }
        !           106:        if (compress(uncfp, cfp)) {
        !           107:                if (cfp != stdout)
        !           108:                        (void) unlink(fname);
        !           109:                goto bad2;
        !           110:        }
        !           111:        encode(EF);
        !           112:        if (bits) {
        !           113:                d.integ <<= 16 - bits;
        !           114:                putc(d.chars.hib, cfp);
        !           115:                if (bits > 8)
        !           116:                        putc(d.chars.lob, cfp);
        !           117:                bits = 0;
        !           118:        }
        !           119:        fflush(cfp);
        !           120:        if (ferror(uncfp) || ferror(cfp)) {
        !           121:                if (cfp != stdout) {
        !           122:                        fprintf(stderr, "compact: ");
        !           123:                        if (ferror(cfp))
        !           124:                                perror(fname);
        !           125:                        else
        !           126:                                perror(infname);
        !           127:                        (void) unlink(fname);
        !           128:                }
        !           129:                goto bad;
        !           130:        }
        !           131:        if (cfp != stdout) {
        !           132:                struct stat cfstatus;
        !           133:                longint csize, ucsize;
        !           134: 
        !           135:                (void) fstat(fileno(cfp), &cfstatus);
        !           136:                csize = cfstatus.st_size;
        !           137:                ucsize = ucfstatus.st_size;
        !           138:                if (csize >= ucsize) {
        !           139:                        fprintf("%s: ", infname);
        !           140:                        (void) unlink(fname);
        !           141:                        printf("Not compacted, does not save bytes.\n");
        !           142:                        goto done;
        !           143:                }
        !           144:                if (verbose) {
        !           145:                        FILE *fd;
        !           146:                        longint n, m;
        !           147: 
        !           148:                        while (ucsize - csize > 21474) {
        !           149:                                ucsize /= 10;
        !           150:                                csize /= 10;
        !           151:                        }
        !           152:                        n = 100000 * (ucsize - csize) / ucsize + 5;
        !           153:                        m = (n % 1000) / 10;
        !           154:                        bits = m % 10 + '0';
        !           155:                        c.integ = m / 10 + '0';
        !           156:                        printf("%ld.%c%c%% compression\n",
        !           157:                            n / 1000, c.chars.lob, bits);
        !           158:                }
        !           159:                if (unlink(infname) < 0)
        !           160:                        fprintf(stderr, "compact: "), perror(infname);
        !           161:        }
        !           162: done:
        !           163:        if (cfp != NULL && cfp != stdout)
        !           164:                fclose(cfp);
        !           165:        if (uncfp != NULL)
        !           166:                fclose(uncfp);
        !           167:        return (0);
        !           168: bad2:
        !           169:        fprintf(stderr, "compact: ");
        !           170:        if (cfp != stdout)
        !           171:                perror(infname);
        !           172:        else
        !           173:                fprintf(stderr,
        !           174:            "Unsuccessful compact of standard input to standard output.\n");
        !           175: bad:
        !           176:        if (cfp != NULL && cfp != stdout)
        !           177:                fclose(cfp);
        !           178:        if (uncfp != NULL)
        !           179:                fclose(uncfp);
        !           180:        return (1);
        !           181: }
        !           182: 
        !           183: encode(ch)
        !           184:        int ch;
        !           185: {
        !           186:        register struct node *pp;
        !           187:        int stack[17];
        !           188:        register int stbits = 1, *sp = &stack[0], rbits = bits;
        !           189:        register union cio *dp = &d;
        !           190:        union cio c;
        !           191: 
        !           192:        c.integ = ch;
        !           193:        *sp = in[ch].flags & FBIT;
        !           194:        pp = in[ch].fp;
        !           195: 
        !           196:        while (pp->fath.fp) {
        !           197:                *sp <<= 1;
        !           198:                if (pp->fath.flags & FBIT)
        !           199:                        (*sp)++;
        !           200:                stbits++;
        !           201:                if ((stbits &= 017) == 0)
        !           202:                        sp++;
        !           203:                pp = pp->fath.fp;
        !           204:        }
        !           205: 
        !           206:        /* pop the output stack */
        !           207:        do {
        !           208:                while (stbits-- > 0) {
        !           209:                        dp->integ <<= 1;
        !           210:                        if (*sp & 01)
        !           211:                                dp->integ++;
        !           212:                        ++rbits;
        !           213:                        if ((rbits &= 017) == 0) {
        !           214:                                putc(dp->chars.hib, cfp);
        !           215:                                putc(dp->chars.lob, cfp);
        !           216:                                if (ferror(cfp))
        !           217:                                        goto done;
        !           218:                        }
        !           219:                        *sp >>= 1;
        !           220:                }
        !           221:                stbits = 16;
        !           222:        } while (--sp >= &stack[0]);
        !           223: done:
        !           224:        bits = rbits;
        !           225: }
        !           226: 
        !           227: compress(uncfp, cfp)
        !           228:        register FILE *uncfp, *cfp;
        !           229: {
        !           230:        register union cio *dp = &d;
        !           231:        register union cio *cp = &c;
        !           232: 
        !           233:        cp->integ = (dp->integ >> 8) & 0377;
        !           234:        for (; cp->integ != EOF; cp->integ = getc(uncfp)) {
        !           235:                if ((in[cp->integ].flags & SEEN) == 0) {
        !           236:                        register short j, m;
        !           237: 
        !           238:                        encode(NC);
        !           239:                        uptree(NC);
        !           240:                        insert(cp->integ);
        !           241: 
        !           242:                        m = 0200;
        !           243:                        for (j = 8; j--; m >>= 1) {
        !           244:                                dp->integ <<= 1;
        !           245:                                if (m & cp->integ)
        !           246:                                        dp->integ++;
        !           247:                                ++bits;
        !           248:                                if ((bits &= 017) == 0) {
        !           249:                                        putc(dp->chars.hib, cfp);
        !           250:                                        putc(dp->chars.lob, cfp);
        !           251:                                }
        !           252:                        }
        !           253:                } else
        !           254:                        encode(cp->integ);
        !           255:                if (ferror(cfp)) {
        !           256:                        perror(fname);
        !           257:                        return (1);
        !           258:                }
        !           259:                uptree(cp->integ);
        !           260:        }
        !           261:        if (ferror(uncfp)) {
        !           262:                perror(infname);
        !           263:                return (1);
        !           264:        }
        !           265:        return (0);
        !           266: }
        !           267: 
        !           268: FILE *
        !           269: setup(uncfp, ignore)
        !           270:        FILE *uncfp;
        !           271:        int *ignore;
        !           272: {
        !           273:        FILE *cfp = NULL;
        !           274:        register union cio *dp = &d;
        !           275:        register union cio *cp = &c;
        !           276: 
        !           277:        dp->integ = getc(uncfp);
        !           278:        if (*ignore = (dp->integ == EOF))
        !           279:                goto bad;
        !           280:        cp->integ = getc(uncfp);
        !           281:        if (*ignore = (cp->integ == EOF))
        !           282:                goto bad;
        !           283:        dp->chars.hib = cp->integ & 0377;
        !           284:        if ((dp->integ &= 0177777) == COMPACTED) {
        !           285:                fprintf(stderr, "%s: Already compacted.\n", infname);
        !           286:                *ignore = 1;
        !           287:                goto bad;
        !           288:        }
        !           289:        if (dp->integ == PACKED) {
        !           290:                fprintf(stderr,
        !           291:                    "%s: Already packed using pack program, use unpack.\n",
        !           292:                    infname);
        !           293:                *ignore = 1;
        !           294:                goto bad;
        !           295:        }
        !           296:        if (strcmp(infname, "-") != 0) {
        !           297:                sprintf(fname, "%s.C", infname);
        !           298:                cfp = fopen(fname, "w");
        !           299:                if (cfp == NULL)
        !           300:                        goto bad2;
        !           301:                (void) fchmod(fileno(cfp), ucfstatus.st_mode);
        !           302:        } else
        !           303:                cfp = stdout;
        !           304:        cp->integ = COMPACTED;
        !           305:        putc(cp->chars.lob, cfp);
        !           306:        putc(cp->chars.hib, cfp);
        !           307:        if (ferror(cfp))
        !           308:                goto bad2;
        !           309:        bits = 8;
        !           310:        cp->integ = dp->integ & 0377;
        !           311: 
        !           312:        in[NC].fp = in[EF].fp = dict[0].sons[LEFT].sp.p = bottom = dict + 1;
        !           313:        bottom->sons[LEFT].count = bottom->sons[RIGHT].count =
        !           314:            dict[0].sons[RIGHT].count = 1;
        !           315:        dirp->next = dict[0].sons[RIGHT].top = bottom->sons[LEFT].top =
        !           316:            bottom->sons[RIGHT].top = dirq = NEW;
        !           317:        dirq->next = NULL;
        !           318:        dict[0].fath.fp = NULL;
        !           319:        dirq->pt = bottom->fath.fp = in[cp->integ].fp = dict;
        !           320:        in[cp->integ].flags = (FBIT | SEEN);
        !           321:        in[NC].flags = SEEN;
        !           322:        dict[0].fath.flags = RLEAF;
        !           323:        bottom->fath.flags = (LLEAF | RLEAF);
        !           324:        dict[0].sons[LEFT].count = 2;
        !           325: 
        !           326:        dict[0].sons[RIGHT].sp.ch = cp->integ;
        !           327:        bottom->sons[LEFT].sp.ch = NC;
        !           328:        bottom->sons[RIGHT].sp.ch = EF;
        !           329:        return (cfp);
        !           330: bad2:
        !           331:        if (cfp && cfp != stdout) {
        !           332:                fprintf(stderr, "compact: "), perror(fname);
        !           333:                (void) unlink(fname);
        !           334:        }
        !           335: bad:
        !           336:        if (cfp && cfp != stdout)
        !           337:                fclose(cfp);
        !           338:        return (NULL);
        !           339: }

unix.superglobalmegacorp.com

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