Annotation of researchv10no/cmd/troff/Drivers/dsort.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *     dsort
        !             3:  *
        !             4:  *     sort troff output into troff output that only goes one
        !             5:  *     direction down the page.
        !             6:  *     caveat user:
        !             7:  *             there are bugs herein
        !             8:  *             it doesn't do anything with graphics like \D'...'
        !             9:  */
        !            10: 
        !            11: /*
        !            12: output language from troff:
        !            13: all numbers are character strings
        !            14: 
        !            15: sn     size in points
        !            16: fn     font as number from 1-n
        !            17: cx     ascii character x
        !            18: Cxyz   funny char xyz. terminated by white space
        !            19: Hn     go to absolute horizontal position n
        !            20: Vn     go to absolute vertical position n (down is positive)
        !            21: hn     go n units horizontally (relative)
        !            22: vn     ditto vertically
        !            23: nnc    move right nn, then print c (exactly 2 digits!)
        !            24:                (this wart is an optimization that shrinks output file size
        !            25:                 about 35% and run-time about 15% while preserving ascii-ness)
        !            26: Dt ...\n       draw operation 't':
        !            27:        Dl x y          line from here by x,y
        !            28:        Dc d            circle of diameter d with left side here
        !            29:        De x y          ellipse of axes x,y with left side here
        !            30:        Da x y r        arc counter-clockwise by x,y of radius r
        !            31:        D~ x y x y ...  wiggly line by x,y then x,y ...
        !            32: nb a   end of line (information only -- no action needed)
        !            33:        b = space before line, a = after
        !            34: p      new page begins -- set v to 0
        !            35: #...\n comment
        !            36: x ...\n        device control functions:
        !            37:        x i     init
        !            38:        x T s   name of device is s
        !            39:        x r n h v       resolution is n/inch
        !            40:                h = min horizontal motion, v = min vert
        !            41:        x p     pause (can restart)
        !            42:        x s     stop -- done for ever
        !            43:        x t     generate trailer
        !            44:        x f n s font position n contains font s
        !            45:        x H n   set character height to n
        !            46:        x S n   set slant to N
        !            47: 
        !            48:        Subcommands like "i" are often spelled out like "init".
        !            49: */
        !            50: 
        !            51: #include       <stdio.h>
        !            52: #include       <ctype.h>
        !            53: 
        !            54: #define        FATAL   1
        !            55: int    dbg     = 0;
        !            56: int    res;            /* input assumed computed according to this resolution */
        !            57: int    size    = 0;    /* current size */
        !            58: int    font    = 0;    /* current font */
        !            59: int    hpos;           /* horizontal position where we are supposed to be next (left = 0) */
        !            60: int    vpos;           /* current vertical position (down positive) */
        !            61: int    horig;          /* h origin of current block; hpos rel to this */
        !            62: int    vorig;
        !            63: 
        !            64: 
        !            65: main(argc, argv)
        !            66: char *argv[];
        !            67: {
        !            68:        FILE *fp;
        !            69:        int i;
        !            70:        int done();
        !            71:        extern int obufsize;
        !            72: 
        !            73:        while (argc > 1 && argv[1][0] == '-') {
        !            74:                switch (argv[1][1]) {
        !            75:                case 'd':
        !            76:                        dbg = atoi(&argv[1][2]);
        !            77:                        if (dbg == 0) dbg = 1;
        !            78:                        obufsize = 50;
        !            79:                        break;
        !            80:                }
        !            81:                argc--;
        !            82:                argv++;
        !            83:        }
        !            84:        if (argc <= 1)
        !            85:                conv(stdin);
        !            86:        else
        !            87:                while (--argc > 0) {
        !            88:                        if (strcmp(*++argv, "-") == 0)
        !            89:                                fp = stdin;
        !            90:                        else if ((fp = fopen(*argv, "r")) == NULL)
        !            91:                                error(FATAL, "can't open %s", *argv);
        !            92:                        conv(fp);
        !            93:                        fclose(fp);
        !            94:                }
        !            95:        done();
        !            96: }
        !            97: 
        !            98: /* new data declarations go here */
        !            99: struct vlist {
        !           100:        int     v;
        !           101:        int     h;
        !           102:        int     s;
        !           103:        int     f;
        !           104:        char    *p;
        !           105: };
        !           106: 
        !           107: #define        NVLIST  1500
        !           108: struct vlist   vlist[NVLIST + 1];
        !           109: struct vlist   *vlp    = vlist;
        !           110: int    nvlist  = 0;
        !           111: #define        OBUFSIZE        32000
        !           112: int    obufsize        = OBUFSIZE;
        !           113: #define        SLOP            500
        !           114: char   obuf[OBUFSIZE + SLOP];
        !           115: char   *op     = obuf;
        !           116: 
        !           117: conv(fp)
        !           118: register FILE *fp;
        !           119: {
        !           120:        register int c, k;
        !           121:        int m, n, i, n1, m1;
        !           122:        char str[100], buf[300];
        !           123: 
        !           124:        while ((c = getc(fp)) != EOF) {
        !           125:                if(dbg)fprintf(stderr, "%c i=%d V=%d\n", c, op-obuf, vpos);
        !           126:                pause();
        !           127:                if (op >= obuf + obufsize)
        !           128:                        oflush();
        !           129:                switch (c) {
        !           130:                case '\n':      /* when input is text */
        !           131:                case ' ':
        !           132:                        *op++ = c;
        !           133:                        break;
        !           134:                case '{':       /* push down current environment */
        !           135:                        *op++ = c;
        !           136:                        t_push();
        !           137:                        break;
        !           138:                case '}':
        !           139:                        *op++ = c;
        !           140:                        t_pop();
        !           141:                        break;
        !           142:                case '0': case '1': case '2': case '3': case '4':
        !           143:                case '5': case '6': case '7': case '8': case '9':
        !           144:                        /* two motion digits plus a character */
        !           145:                        *op++ = c;
        !           146:                        *op++ = getc(fp);
        !           147:                        hmot((op[-2]-'0') * 10 + op[-1] - '0');
        !           148:                        *op++ = getc(fp);
        !           149:                        break;
        !           150:                case 'c':       /* single ascii character */
        !           151:                        *op++ = c;
        !           152:                        *op++ = getc(fp);
        !           153:                        break;
        !           154:                case 'C':
        !           155:                        *op++ = c;
        !           156:                        while ((c = getc(fp)) != ' ' && c != '\n')
        !           157:                                *op++ = c;
        !           158:                        ungetc(c, fp);
        !           159:                        break;
        !           160:                case 't':       /* straight text */
        !           161:                        *op++ = c;
        !           162:                        fgets(op, SLOP, fp);
        !           163:                        op += strlen(op);
        !           164:                        break;
        !           165:                case 'D':       /* draw function */
        !           166:                        *op++ = c;
        !           167:                        fgets(op, SLOP, fp);
        !           168:                        switch (*op) {
        !           169:                        case 'l':       /* draw a line */
        !           170:                                sscanf(op+1, "%d %d", &n, &m);
        !           171:                                hmot(n);
        !           172:                                break;
        !           173:                        case 'c':       /* circle */
        !           174:                                sscanf(op+1, "%d", &n);
        !           175:                                hmot(n);
        !           176:                                break;
        !           177:                        case 'e':       /* ellipse */
        !           178:                                sscanf(op+1, "%d %d", &m, &n);
        !           179:                                hmot(m);
        !           180:                                break;
        !           181:                        case 'a':       /* arc */
        !           182:                                sscanf(op+1, "%d %d %d", &n, &m, &n1);
        !           183:                                hmot(n);
        !           184:                                break;
        !           185:                        case '~':       /* wiggly line */
        !           186:                                hmot(0);        /* bug */
        !           187:                                break;
        !           188:                        default:
        !           189:                                error(FATAL, "unknown drawing function %s\n", buf);
        !           190:                                break;
        !           191:                        }
        !           192:                        op += strlen(op);       /* skip over new stuff */
        !           193:                        break;
        !           194:                case 's':
        !           195:                        *op++ = c;
        !           196:                        fscanf(fp, "%s", op);   /* ignore fractional sizes */
        !           197:                        size = atoi(op);
        !           198:                        op += strlen(op);
        !           199:                        break;
        !           200:                case 'f':
        !           201:                        *op++ = c;
        !           202:                        fscanf(fp, "%s", op);
        !           203:                        font = atoi(op);
        !           204:                        op += strlen(op);
        !           205:                        break;
        !           206:                case 'H':       /* absolute horizontal motion */
        !           207:                        /* fscanf(fp, "%d", &n); */
        !           208:                        *op++ = c;
        !           209:                        while ((c = getc(fp)) == ' ')
        !           210:                                ;
        !           211:                        k = 0;
        !           212:                        do {
        !           213:                                *op++ = c;
        !           214:                                k = 10 * k + c - '0';
        !           215:                        } while (isdigit(c = getc(fp)));
        !           216:                        ungetc(c, fp);
        !           217:                        hgoto(k);
        !           218:                        break;
        !           219:                case 'h':       /* relative horizontal motion */
        !           220:                        /* fscanf(fp, "%d", &n); */
        !           221:                        *op++ = c;
        !           222:                        while ((c = getc(fp)) == ' ')
        !           223:                                ;
        !           224:                        k = 0;
        !           225:                        do {
        !           226:                                *op++ = c;
        !           227:                                k = 10 * k + c - '0';
        !           228:                        } while (isdigit(c = getc(fp)));
        !           229:                        ungetc(c, fp);
        !           230:                        hmot(k);
        !           231:                        break;
        !           232:                case 'w':
        !           233:                        break;
        !           234:                case 'V':
        !           235:                        *op++ = 0;
        !           236:                        if (vlp >= vlist + NVLIST) {
        !           237:                                oflush();
        !           238:                        }
        !           239:                        vlp->p = op;
        !           240:                        *op++ = c;
        !           241:                        fscanf(fp, "%s", op);
        !           242:                        n = atoi(op);
        !           243:                        vgoto(n);
        !           244:                        op += strlen(op);
        !           245:                        vlp->v = vpos;
        !           246:                        vlp->h = hpos;
        !           247:                        vlp->s = size;
        !           248:                        vlp->f = font;
        !           249:                        vlp++;
        !           250:                        nvlist++;
        !           251:                        break;
        !           252:                case 'v':
        !           253:                        *op++ = c;
        !           254:                        fscanf(fp, "%d", &n);
        !           255:                        vmot(n);
        !           256: /* punt for now, since never occurs */
        !           257:                        break;
        !           258:                case 'p':       /* new page */
        !           259:                        vpos = 0;
        !           260:                        oflush();
        !           261:                        *op++ = c;
        !           262:                        fscanf(fp, "%s", op);
        !           263:                        op += strlen(op);
        !           264:                        break;
        !           265:                case 'n':       /* end of line */
        !           266:                        *op++ = c;
        !           267:                        while ((*op++ = getc(fp)) != '\n')
        !           268:                                ;
        !           269:                        hpos = 0;
        !           270:                        break;
        !           271:                case '#':       /* comment */
        !           272:                        *op++ = c;
        !           273:                        while ((*op++ = getc(fp)) != '\n')
        !           274:                                ;
        !           275:                        break;
        !           276:                case 'x':       /* device control */
        !           277:                        oflush();
        !           278:                        putchar(c);
        !           279:                        fgets(buf, sizeof buf, fp);
        !           280:                        fputs(buf, stdout);
        !           281:                        fflush(stdout);
        !           282:                        break;
        !           283:                default:
        !           284:                        error(!FATAL, "unknown input character %o %c\n", c, c);
        !           285:                        done();
        !           286:                }
        !           287:        }
        !           288: }
        !           289: 
        !           290: pause(i, j, k)
        !           291: {
        !           292: }
        !           293: 
        !           294: oflush()       /* sort, then dump out contents of obuf */
        !           295: {
        !           296:        char *p;
        !           297:        struct vlist *vp;
        !           298:        int i;
        !           299:        int compar();
        !           300: 
        !           301:        if(dbg)fprintf(stderr, "into oflush, V=%d\n", vpos);
        !           302:        if (op == obuf)
        !           303:                return;
        !           304:        qsort((char *) vlist, nvlist, sizeof (struct vlist), compar);
        !           305:        *op++ = 0;
        !           306:        vp = vlist;
        !           307:        printf("V%d\n",  vp->v);
        !           308:        for (i = 0; i < nvlist; i++, vp++) {
        !           309:                printf("H%ds%df%d\n", vp->h, vp->s, vp->f);
        !           310:                for (p = vp->p; *p != 0; p++)
        !           311:                        putchar(*p);
        !           312:        }
        !           313:        fflush(stdout);
        !           314:        vlp = vlist;
        !           315:        vlp->p = op = obuf;
        !           316:        sprintf(op, "V%dH%d\n", vpos, hpos);
        !           317:        op += strlen(op);
        !           318:        vlp->h = hpos;
        !           319:        vlp->v = vpos;
        !           320:        vlp->s = size;
        !           321:        vlp->f = font;
        !           322:        *op = 0;
        !           323:        vlp++;
        !           324:        nvlist = 1;
        !           325: }
        !           326: 
        !           327: 
        !           328: compar(p1, p2)
        !           329: struct vlist *p1, *p2;
        !           330: {
        !           331:        return(p1->v - p2->v);
        !           332: }
        !           333: 
        !           334: done()
        !           335: {
        !           336:        oflush();
        !           337:        exit(0);
        !           338: }
        !           339: 
        !           340: error(f, s, a1, a2, a3, a4, a5, a6, a7) {
        !           341:        fprintf(stderr, "dsort: ");
        !           342:        fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
        !           343:        fprintf(stderr, "\n");
        !           344:        if (f)
        !           345:                done();
        !           346: }
        !           347: 
        !           348: #define        MAXSTATE        5
        !           349: 
        !           350: struct state {
        !           351:        int     ssize;
        !           352:        int     sfont;
        !           353:        int     shpos;
        !           354:        int     svpos;
        !           355:        int     shorig;
        !           356:        int     svorig;
        !           357: };
        !           358: struct state   state[MAXSTATE];
        !           359: struct state   *statep = state;
        !           360: 
        !           361: t_push()       /* begin a new block */
        !           362: {
        !           363:        statep->ssize = size;
        !           364:        statep->sfont = font;
        !           365:        statep->shorig = horig;
        !           366:        statep->svorig = vorig;
        !           367:        statep->shpos = hpos;
        !           368:        statep->svpos = vpos;
        !           369:        horig = hpos;
        !           370:        vorig = vpos;
        !           371:        hpos = vpos = 0;
        !           372:        if (statep++ >= state+MAXSTATE)
        !           373:                error(FATAL, "{ nested too deep");
        !           374:        hpos = vpos = 0;
        !           375: }
        !           376: 
        !           377: t_pop()        /* pop to previous state */
        !           378: {
        !           379:        if (--statep < state)
        !           380:                error(FATAL, "extra }");
        !           381:        size = statep->ssize;
        !           382:        font = statep->sfont;
        !           383:        hpos = statep->shpos;
        !           384:        vpos = statep->svpos;
        !           385:        horig = statep->shorig;
        !           386:        vorig = statep->svorig;
        !           387: }
        !           388: 
        !           389: t_page(n)      /* do whatever new page functions */
        !           390: {
        !           391:        int i;
        !           392: 
        !           393:        vpos = 0;
        !           394: }
        !           395: 
        !           396: hgoto(n)
        !           397: {
        !           398:        hpos = n;       /* this is where we want to be */
        !           399:                        /* before printing a character, */
        !           400:                        /* have to make sure it's true */
        !           401: }
        !           402: 
        !           403: hmot(n)        /* generate n units of horizontal motion */
        !           404: int n;
        !           405: {
        !           406:        hgoto(hpos + n);
        !           407: }
        !           408: 
        !           409: vgoto(n)
        !           410: {
        !           411:        vpos = n;
        !           412: }
        !           413: 
        !           414: vmot(n)        /* generate n units of vertical motion */
        !           415: int n;
        !           416: {
        !           417:        vgoto(vpos + n);        /* ignores rounding */
        !           418: }

unix.superglobalmegacorp.com

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