|
|
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.