Annotation of researchv10no/cmd/troff/Drivers/dsort.c, revision 1.1.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.