|
|
1.1 ! root 1: /* ! 2: * drive hp2621 terminal ! 3: * just to see stuff quickly. like troff -a ! 4: * blows up on vaxes ! 5: */ ! 6: ! 7: /* ! 8: output language from troff: ! 9: all numbers are character strings ! 10: ! 11: sn size in points ! 12: fn font as number from 1-n ! 13: cx ascii character x ! 14: Cxyz funny char xyz. terminated by white space ! 15: Hn go to absolute horizontal position n ! 16: Vn go to absolute vertical position n (down is positive) ! 17: hn go n units horizontally (relative) ! 18: vn ditto vertically ! 19: nnc move right nn, then print c (exactly 2 digits!) ! 20: (this wart is an optimization that shrinks output file size ! 21: about 35% and run-time about 15% while preserving ascii-ness) ! 22: dt ...\n draw operation 't': ! 23: d/ dx dy c line from here to dx,dy using c ! 24: dO r circle of radius r centered here ! 25: dE rx ry ellipse of semi-axes rx, ry centered here ! 26: dA dx1 dy1 dx2 dy2 arc counter-clockwise with center here ! 27: from dx1,dy1 to dx2,dy2. ! 28: nb a end of line (information only -- no action needed) ! 29: b = space before line, a = after ! 30: p new page begins -- set v to 0 ! 31: #...\n comment ! 32: x ...\n device control functions: ! 33: x i init ! 34: x T s name of device is s ! 35: x r n h v resolution is n/inch ! 36: h = min horizontal motion, v = min vert ! 37: x p pause (can restart) ! 38: x s stop -- done for ever ! 39: x t generate trailer ! 40: x f n s font position n contains font s ! 41: ! 42: Subcommands like "i" are often spelled out like "init". ! 43: */ ! 44: ! 45: #include <stdio.h> ! 46: #include <signal.h> ! 47: #include <ctype.h> ! 48: ! 49: #include "dev.h" ! 50: #define NFONT 10 ! 51: ! 52: int output = 0; /* do we do output at all? */ ! 53: int nolist = 0; /* output page list if > 0 */ ! 54: int olist[20]; /* pairs of page numbers */ ! 55: ! 56: int erase = 1; ! 57: float aspect = 1.5; /* default aspect ratio */ ! 58: int wflag = 0; /* wait, looping, for new input if on */ ! 59: int (*sigint)(); ! 60: int (*sigquit)(); ! 61: ! 62: struct dev dev; ! 63: struct font *fontbase[NFONT]; ! 64: short psizes[] ={ 11, 16, 22, 36, 0}; /* approx sizes available */ ! 65: short *pstab = psizes; ! 66: int nsizes = 1; ! 67: int nfonts; ! 68: int smnt; /* index of first special font */ ! 69: int nchtab; ! 70: char *chname; ! 71: short *chtab; ! 72: char *fitab[NFONT]; ! 73: char *widthtab[NFONT]; /* widtab would be a better name */ ! 74: char *codetab[NFONT]; /* device codes */ ! 75: ! 76: #define FATAL 1 ! 77: #define BMASK 0377 ! 78: int dbg = 0; ! 79: int res = 972; /* input assumed computed according to this resolution */ ! 80: /* initial value to avoid 0 divide */ ! 81: FILE *tf = stdout; /* output file */ ! 82: char *fontdir = "/usr/lib/font"; ! 83: extern char devname[]; ! 84: ! 85: FILE *fp = stdin; /* input file pointer */ ! 86: ! 87: main(argc, argv) ! 88: char *argv[]; ! 89: { ! 90: char buf[512]; ! 91: int done(); ! 92: float atof(); ! 93: ! 94: setbuf(stdout, buf); ! 95: while (argc > 1 && argv[1][0] == '-') { ! 96: switch (argv[1][1]) { ! 97: case 'a': ! 98: aspect = atof(&argv[1][2]); ! 99: break; ! 100: case 'e': ! 101: erase = 0; ! 102: break; ! 103: case 'o': ! 104: outlist(&argv[1][2]); ! 105: break; ! 106: case 'd': ! 107: dbg = atoi(&argv[1][2]); ! 108: if (dbg == 0) dbg = 1; ! 109: break; ! 110: } ! 111: argc--; ! 112: argv++; ! 113: } ! 114: ! 115: if (argc <= 1) ! 116: conv(stdin); ! 117: else ! 118: while (--argc > 0) { ! 119: if (strcmp(*++argv, "-") == 0) ! 120: fp = stdin; ! 121: else if ((fp = fopen(*argv, "r")) == NULL) ! 122: error(FATAL, "can't open %s", *argv); ! 123: conv(fp); ! 124: fclose(fp); ! 125: } ! 126: done(); ! 127: } ! 128: ! 129: outlist(s) /* process list of page numbers to be printed */ ! 130: char *s; ! 131: { ! 132: int n1, n2, i; ! 133: ! 134: nolist = 0; ! 135: while (*s) { ! 136: n1 = 0; ! 137: if (isdigit(*s)) ! 138: do ! 139: n1 = 10 * n1 + *s++ - '0'; ! 140: while (isdigit(*s)); ! 141: else ! 142: n1 = -9999; ! 143: n2 = n1; ! 144: if (*s == '-') { ! 145: s++; ! 146: n2 = 0; ! 147: if (isdigit(*s)) ! 148: do ! 149: n2 = 10 * n2 + *s++ - '0'; ! 150: while (isdigit(*s)); ! 151: else ! 152: n2 = 9999; ! 153: } ! 154: olist[nolist++] = n1; ! 155: olist[nolist++] = n2; ! 156: if (*s != '\0') ! 157: s++; ! 158: } ! 159: olist[nolist] = 0; ! 160: if (dbg) ! 161: for (i=0; i<nolist; i += 2) ! 162: printf("%3d %3d\n", olist[i], olist[i+1]); ! 163: } ! 164: ! 165: in_olist(n) /* is n in olist? */ ! 166: int n; ! 167: { ! 168: int i; ! 169: ! 170: if (nolist == 0) ! 171: return(1); /* everything is included */ ! 172: for (i = 0; i < nolist; i += 2) ! 173: if (n >= olist[i] && n <= olist[i+1]) ! 174: return(1); ! 175: return(0); ! 176: } ! 177: ! 178: conv(fp) ! 179: register FILE *fp; ! 180: { ! 181: register int c, k; ! 182: int m, n, i, n1, m1; ! 183: char str[100], buf[300]; ! 184: ! 185: while ((c = getc(fp)) != EOF) { ! 186: switch (c) { ! 187: case '\n': /* when input is text */ ! 188: case ' ': ! 189: case 0: /* occasional noise creeps in */ ! 190: break; ! 191: case '{': /* push down current environment */ ! 192: t_push(); ! 193: break; ! 194: case '}': ! 195: t_pop(); ! 196: break; ! 197: case '0': case '1': case '2': case '3': case '4': ! 198: case '5': case '6': case '7': case '8': case '9': ! 199: /* two motion digits plus a character */ ! 200: hmot((c-'0')*10 + getc(fp)-'0'); ! 201: put1(getc(fp)); ! 202: break; ! 203: case 'c': /* single ascii character */ ! 204: put1(getc(fp)); ! 205: break; ! 206: case 'C': ! 207: fscanf(fp, "%s", str); ! 208: put1s(str); ! 209: break; ! 210: case 't': /* straight text */ ! 211: fgets(buf, sizeof(buf), fp); ! 212: t_text(buf); ! 213: break; ! 214: case 'D': /* draw function */ ! 215: fgets(buf, sizeof(buf), fp); ! 216: switch (buf[0]) { ! 217: case 'l': /* draw a line */ ! 218: sscanf(buf+1, "%d %d", &n, &m); ! 219: drawline(n, m, "."); ! 220: break; ! 221: case 'c': /* circle */ ! 222: sscanf(buf+1, "%d", &n); ! 223: drawcirc(n); ! 224: break; ! 225: case 'e': /* ellipse */ ! 226: sscanf(buf+1, "%d %d", &m, &n); ! 227: drawellip(m, n); ! 228: break; ! 229: case 'a': /* arc */ ! 230: sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1); ! 231: drawarc(n, m, n1, m1); ! 232: break; ! 233: case '~': /* wiggly line */ ! 234: drawwig(buf+1); ! 235: break; ! 236: default: ! 237: error(FATAL, "unknown drawing function %s\n", buf); ! 238: break; ! 239: } ! 240: break; ! 241: case 's': ! 242: fscanf(fp, "%d", &n); /* ignore fractional sizes */ ! 243: setsize(t_size(n)); ! 244: break; ! 245: case 'f': ! 246: fscanf(fp, "%s", str); ! 247: setfont(t_font(str)); ! 248: break; ! 249: case 'H': /* absolute horizontal motion */ ! 250: /* fscanf(fp, "%d", &n); */ ! 251: while ((c = getc(fp)) == ' ') ! 252: ; ! 253: k = 0; ! 254: do { ! 255: k = 10 * k + c - '0'; ! 256: } while (isdigit(c = getc(fp))); ! 257: ungetc(c, fp); ! 258: hgoto(k); ! 259: break; ! 260: case 'h': /* relative horizontal motion */ ! 261: /* fscanf(fp, "%d", &n); */ ! 262: while ((c = getc(fp)) == ' ') ! 263: ; ! 264: k = 0; ! 265: do { ! 266: k = 10 * k + c - '0'; ! 267: } while (isdigit(c = getc(fp))); ! 268: ungetc(c, fp); ! 269: hmot(k); ! 270: break; ! 271: case 'w': /* word space */ ! 272: putc(' ', stdout); ! 273: break; ! 274: case 'V': ! 275: fscanf(fp, "%d", &n); ! 276: vgoto(n); ! 277: break; ! 278: case 'v': ! 279: fscanf(fp, "%d", &n); ! 280: vmot(n); ! 281: break; ! 282: case 'p': /* new page */ ! 283: fscanf(fp, "%d", &n); ! 284: t_page(n); ! 285: break; ! 286: case 'n': /* end of line */ ! 287: while (getc(fp) != '\n') ! 288: ; ! 289: t_newline(); ! 290: break; ! 291: case '#': /* comment */ ! 292: while (getc(fp) != '\n') ! 293: ; ! 294: break; ! 295: case 'x': /* device control */ ! 296: devcntrl(fp); ! 297: break; ! 298: default: ! 299: error(!FATAL, "unknown input character %o %c\n", c, c); ! 300: done(); ! 301: } ! 302: } ! 303: } ! 304: ! 305: devcntrl(fp) /* interpret device control functions */ ! 306: FILE *fp; ! 307: { ! 308: char str[20]; ! 309: int c, n; ! 310: ! 311: fscanf(fp, "%s", str); ! 312: switch (str[0]) { /* crude for now */ ! 313: case 'i': /* initialize */ ! 314: fileinit(); ! 315: t_init(0); ! 316: break; ! 317: case 'T': /* device name */ ! 318: fscanf(fp, "%s", devname); ! 319: break; ! 320: case 't': /* trailer */ ! 321: t_trailer(); ! 322: break; ! 323: case 'p': /* pause -- can restart */ ! 324: t_reset('p'); ! 325: break; ! 326: case 's': /* stop */ ! 327: t_reset('s'); ! 328: break; ! 329: case 'r': /* resolution assumed when prepared */ ! 330: fscanf(fp, "%d", &res); ! 331: break; ! 332: case 'f': /* font used */ ! 333: fscanf(fp, "%d %s", &n, str); ! 334: loadfont(n, str); ! 335: break; ! 336: } ! 337: while (getc(fp) != '\n') /* skip rest of input line */ ! 338: ; ! 339: } ! 340: ! 341: fileinit() /* read in font and code files, etc. */ ! 342: { ! 343: } ! 344: ! 345: fontprint(i) /* debugging print of font i (0,...) */ ! 346: { ! 347: } ! 348: ! 349: loadcode(n, nw) /* load codetab on position n (0...); #chars is nw */ ! 350: int n, nw; ! 351: { ! 352: } ! 353: ! 354: loadfont(n, s) /* load font info for font s on position n (1...) */ ! 355: int n; ! 356: char *s; ! 357: { ! 358: } ! 359: ! 360: error(f, s, a1, a2, a3, a4, a5, a6, a7) { ! 361: fprintf(stderr, "ta: "); ! 362: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7); ! 363: fprintf(stderr, "\n"); ! 364: if (f) ! 365: exit(1); ! 366: } ! 367: ! 368: ! 369: /* ! 370: Here beginneth all the stuff that really depends ! 371: on the 202 (we hope). ! 372: */ ! 373: ! 374: ! 375: char devname[20] = "hp2621"; ! 376: ! 377: #define ESC 033 ! 378: #define HOME 'H' ! 379: #define CLEAR 'J' ! 380: #define FF 014 ! 381: ! 382: int size = 1; ! 383: int font = 1; /* current font */ ! 384: int hpos; /* horizontal position where we are supposed to be next (left = 0) */ ! 385: int vpos; /* current vertical position (down positive) */ ! 386: ! 387: int horig; /* h origin of current block; hpos rel to this */ ! 388: int vorig; /* v origin of current block; vpos rel to this */ ! 389: ! 390: int DX = 10; /* step size in x for drawing */ ! 391: int DY = 10; /* step size in y for drawing */ ! 392: int drawdot = '.'; /* draw with this character */ ! 393: int drawsize = 1; /* shrink by this factor when drawing */ ! 394: ! 395: t_init(reinit) /* initialize device */ ! 396: int reinit; ! 397: { ! 398: int i, j; ! 399: ! 400: fflush(stdout); ! 401: hpos = vpos = 0; ! 402: } ! 403: ! 404: #define MAXSTATE 5 ! 405: ! 406: struct state { ! 407: int ssize; ! 408: int sfont; ! 409: int shpos; ! 410: int svpos; ! 411: int shorig; ! 412: int svorig; ! 413: }; ! 414: struct state state[MAXSTATE]; ! 415: struct state *statep = state; ! 416: ! 417: t_push() /* begin a new block */ ! 418: { ! 419: hflush(); ! 420: statep->ssize = size; ! 421: statep->sfont = font; ! 422: statep->shorig = horig; ! 423: statep->svorig = vorig; ! 424: statep->shpos = hpos; ! 425: statep->svpos = vpos; ! 426: horig = hpos; ! 427: vorig = vpos; ! 428: hpos = vpos = 0; ! 429: if (statep++ >= state+MAXSTATE) ! 430: error(FATAL, "{ nested too deep"); ! 431: hpos = vpos = 0; ! 432: } ! 433: ! 434: t_pop() /* pop to previous state */ ! 435: { ! 436: if (--statep < state) ! 437: error(FATAL, "extra }"); ! 438: size = statep->ssize; ! 439: font = statep->sfont; ! 440: hpos = statep->shpos; ! 441: vpos = statep->svpos; ! 442: horig = statep->shorig; ! 443: vorig = statep->svorig; ! 444: } ! 445: ! 446: int np; /* number of pages seen */ ! 447: int npmax; /* high-water mark of np */ ! 448: int pgnum[40]; /* their actual numbers */ ! 449: long pgadr[40]; /* their seek addresses */ ! 450: ! 451: t_page(n) /* do whatever new page functions */ ! 452: { ! 453: long ftell(); ! 454: int c, m, i; ! 455: char buf[100], *bp; ! 456: ! 457: pgnum[np++] = n; ! 458: pgadr[np] = ftell(fp); ! 459: if (np > npmax) ! 460: npmax = np; ! 461: if (output == 0) { ! 462: output = in_olist(n); ! 463: t_init(1); ! 464: return; ! 465: } ! 466: /* have just printed something, and seen p<n> for next one */ ! 467: putpage(); ! 468: fflush(stdout); ! 469: ! 470: next: ! 471: for (bp = buf; (*bp = readch()); ) ! 472: if (*bp++ == '\n') ! 473: break; ! 474: *bp = 0; ! 475: switch (buf[0]) { ! 476: case 0: ! 477: done(); ! 478: break; ! 479: case '\n': ! 480: output = in_olist(n); ! 481: t_init(1); ! 482: return; ! 483: case '!': ! 484: callunix(&buf[1]); ! 485: fputs("!\n", stderr); ! 486: break; ! 487: case 'e': ! 488: erase = 1 - erase; ! 489: break; ! 490: case 'w': ! 491: wflag = 1 - wflag; ! 492: break; ! 493: case 'a': ! 494: aspect = atof(&buf[1]); ! 495: break; ! 496: case '-': ! 497: case 'p': ! 498: m = atoi(&buf[1]) + 1; ! 499: if (fp == stdin) { ! 500: fputs("you can't; it's not a file\n", stderr); ! 501: break; ! 502: } ! 503: if (np - m <= 0) { ! 504: fputs("too far back\n", stderr); ! 505: break; ! 506: } ! 507: np -= m; ! 508: fseek(fp, pgadr[np], 0); ! 509: output = 1; ! 510: t_init(1); ! 511: return; ! 512: case '0': case '1': case '2': case '3': case '4': ! 513: case '5': case '6': case '7': case '8': case '9': ! 514: m = atoi(&buf[0]); ! 515: for (i = 0; i < npmax; i++) ! 516: if (m == pgnum[i]) ! 517: break; ! 518: if (i >= npmax || fp == stdin) { ! 519: fputs("you can't\n", stderr); ! 520: break; ! 521: } ! 522: np = i + 1; ! 523: fseek(fp, pgadr[np], 0); ! 524: output = 1; ! 525: t_init(1); ! 526: return; ! 527: case 'o': ! 528: outlist(&buf[1]); ! 529: output = 0; ! 530: t_init(1); ! 531: return; ! 532: case '?': ! 533: fputs("!cmd unix cmd\n", stderr); ! 534: fputs("p print this page again\n", stderr); ! 535: fputs("-n go back n pages\n", stderr); ! 536: fputs("n print page n (previously printed)\n", stderr); ! 537: fputs("o... set the -o output list to ...\n", stderr); ! 538: fputs("en n=0 -> don't erase; n=1 -> erase\n", stderr); ! 539: fputs("an sets aspect ratio to n\n", stderr); ! 540: break; ! 541: default: ! 542: fputs("?\n", stderr); ! 543: break; ! 544: } ! 545: goto next; ! 546: } ! 547: ! 548: putpage() ! 549: { ! 550: int i, j, k; ! 551: ! 552: fflush(stdout); ! 553: } ! 554: ! 555: t_newline() /* do whatever for the end of a line */ ! 556: { ! 557: printf("\n"); ! 558: hpos = 0; ! 559: } ! 560: ! 561: t_size(n) /* convert integer to internal size number*/ ! 562: int n; ! 563: { ! 564: } ! 565: ! 566: t_font(s) /* convert string to internal font number */ ! 567: char *s; ! 568: { ! 569: } ! 570: ! 571: t_text(s) /* print string s as text */ ! 572: char *s; ! 573: { ! 574: int c, w; ! 575: char str[100]; ! 576: ! 577: if (!output) ! 578: return; ! 579: while ((c = *s++) != '\n') { ! 580: if (c == '\\') { ! 581: switch (c = *s++) { ! 582: case '\\': ! 583: case 'e': ! 584: put1('\\'); ! 585: break; ! 586: case '(': ! 587: str[0] = *s++; ! 588: str[1] = *s++; ! 589: str[2] = '\0'; ! 590: put1s(str); ! 591: break; ! 592: } ! 593: } else { ! 594: put1(c); ! 595: } ! 596: hmot(w); ! 597: } ! 598: } ! 599: ! 600: t_reset(c) ! 601: { ! 602: int n; ! 603: ! 604: output = 1; ! 605: fflush(stdout); ! 606: if (c == 's') ! 607: t_page(9999); ! 608: } ! 609: ! 610: t_trailer() ! 611: { ! 612: } ! 613: ! 614: hgoto(n) ! 615: { ! 616: hpos = n; /* this is where we want to be */ ! 617: /* before printing a character, */ ! 618: /* have to make sure it's true */ ! 619: } ! 620: ! 621: hmot(n) /* generate n units of horizontal motion */ ! 622: int n; ! 623: { ! 624: hgoto(hpos + n); ! 625: } ! 626: ! 627: hflush() /* actual horizontal output occurs here */ ! 628: { ! 629: } ! 630: ! 631: vgoto(n) ! 632: { ! 633: vpos = n; ! 634: } ! 635: ! 636: vmot(n) /* generate n units of vertical motion */ ! 637: int n; ! 638: { ! 639: vgoto(vpos + n); /* ignores rounding */ ! 640: } ! 641: ! 642: put1s(s) /* s is a funny char name */ ! 643: char *s; ! 644: { ! 645: int i; ! 646: char *p; ! 647: extern char *spectab[]; ! 648: static char prev[10] = ""; ! 649: static int previ; ! 650: ! 651: if (!output) ! 652: return; ! 653: if (strcmp(s, prev) != 0) { ! 654: previ = -1; ! 655: for (i = 0; spectab[i] != 0; i += 2) ! 656: if (strcmp(spectab[i], s) == 0) { ! 657: strcpy(prev, s); ! 658: previ = i; ! 659: break; ! 660: } ! 661: } ! 662: if (previ >= 0) { ! 663: for (p = spectab[previ+1]; *p; p++) ! 664: putc(*p, stdout); ! 665: } else ! 666: prev[0] = 0; ! 667: } ! 668: ! 669: put1(c) /* output char c */ ! 670: int c; ! 671: { ! 672: if (!output) ! 673: return; ! 674: putc(c, stdout); ! 675: } ! 676: ! 677: setsize(n) /* set point size to n (internal) */ ! 678: int n; ! 679: { ! 680: } ! 681: ! 682: t_fp(n, s) /* font position n now contains font s */ ! 683: int n; ! 684: char *s; ! 685: { ! 686: } ! 687: ! 688: setfont(n) /* set font to n */ ! 689: int n; ! 690: { ! 691: } ! 692: ! 693: done() ! 694: { ! 695: output = 1; ! 696: putpage(); ! 697: fflush(stdout); ! 698: exit(0); ! 699: } ! 700: ! 701: callunix(line) ! 702: char line[]; ! 703: { ! 704: int rc, status, unixpid; ! 705: if( (unixpid=fork())==0 ) { ! 706: signal(SIGINT,sigint); signal(SIGQUIT,sigquit); ! 707: close(0); dup(2); ! 708: execl("/bin/sh", "-sh", "-c", line, 0); ! 709: exit(255); ! 710: } ! 711: else if(unixpid == -1) ! 712: return; ! 713: else{ signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); ! 714: while( (rc = wait(&status)) != unixpid && rc != -1 ) ; ! 715: signal(SIGINT,done); signal(SIGQUIT,sigquit); ! 716: } ! 717: } ! 718: ! 719: readch(){ ! 720: char c; ! 721: if (read(2,&c,1)<1) c=0; ! 722: return(c); ! 723: } ! 724: ! 725: char *spectab[] ={ ! 726: "em", "-", ! 727: "hy", "-", ! 728: "en", "-", ! 729: "ru", "_", ! 730: "l.", ".", ! 731: "br", "|", ! 732: "vr", "|", ! 733: "fm", "'", ! 734: "or", "|", ! 735: 0, 0, ! 736: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.