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