|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.