|
|
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 wflag = 0; /* wait, looping, for new input if on */
56:
57: struct dev dev;
58: struct font *fontbase[NFONT];
59: short psizes[] ={ 11, 16, 22, 36, 0}; /* approx sizes available */
60: short *pstab = psizes;
61: int nsizes = 1;
62: int nfonts;
63: int smnt; /* index of first special font */
64: int nchtab;
65: char *chname;
66: short *chtab;
67: char *fitab[NFONT];
68: char *widthtab[NFONT]; /* widtab would be a better name */
69: char *codetab[NFONT]; /* device codes */
70:
71: #define FATAL 1
72: #define BMASK 0377
73: int dbg = 0;
74: int res = 972; /* input assumed computed according to this resolution */
75: /* initial value to avoid 0 divide */
76: FILE *tf = stdout; /* output file */
77: char *fontdir = "/usr/lib/font";
78: extern char devname[];
79:
80: FILE *fp = stdin; /* input file pointer */
81:
82: main(argc, argv)
83: char *argv[];
84: {
85: char buf[BUFSIZ];
86: int done();
87: float atof();
88:
89: setbuf(stdout, buf);
90: while (argc > 1 && argv[1][0] == '-') {
91: switch (argv[1][1]) {
92: case 'o':
93: outlist(&argv[1][2]);
94: break;
95: case 'd':
96: dbg = atoi(&argv[1][2]);
97: if (dbg == 0) dbg = 1;
98: break;
99: }
100: argc--;
101: argv++;
102: }
103:
104: if (argc <= 1)
105: conv(stdin);
106: else
107: while (--argc > 0) {
108: if (strcmp(*++argv, "-") == 0)
109: fp = stdin;
110: else if ((fp = fopen(*argv, "r")) == NULL)
111: error(FATAL, "can't open %s", *argv);
112: conv(fp);
113: fclose(fp);
114: }
115: done();
116: }
117:
118: outlist(s) /* process list of page numbers to be printed */
119: char *s;
120: {
121: int n1, n2, i;
122:
123: nolist = 0;
124: while (*s) {
125: n1 = 0;
126: if (isdigit(*s))
127: do
128: n1 = 10 * n1 + *s++ - '0';
129: while (isdigit(*s));
130: else
131: n1 = -9999;
132: n2 = n1;
133: if (*s == '-') {
134: s++;
135: n2 = 0;
136: if (isdigit(*s))
137: do
138: n2 = 10 * n2 + *s++ - '0';
139: while (isdigit(*s));
140: else
141: n2 = 9999;
142: }
143: olist[nolist++] = n1;
144: olist[nolist++] = n2;
145: if (*s != '\0')
146: s++;
147: }
148: olist[nolist] = 0;
149: if (dbg)
150: for (i=0; i<nolist; i += 2)
151: printf("%3d %3d\n", olist[i], olist[i+1]);
152: }
153:
154: in_olist(n) /* is n in olist? */
155: int n;
156: {
157: int i;
158:
159: if (nolist == 0)
160: return(1); /* everything is included */
161: for (i = 0; i < nolist; i += 2)
162: if (n >= olist[i] && n <= olist[i+1])
163: return(1);
164: return(0);
165: }
166:
167: conv(fp)
168: register FILE *fp;
169: {
170: register int c, k;
171: int m, n, i, n1, m1;
172: char str[100], buf[300];
173:
174: while ((c = getc(fp)) != EOF) {
175: switch (c) {
176: case '\n': /* when input is text */
177: case ' ':
178: case 0: /* occasional noise creeps in */
179: break;
180: case '{': /* push down current environment */
181: t_push();
182: break;
183: case '}':
184: t_pop();
185: break;
186: case '0': case '1': case '2': case '3': case '4':
187: case '5': case '6': case '7': case '8': case '9':
188: /* two motion digits plus a character */
189: hmot((c-'0')*10 + getc(fp)-'0');
190: put1(getc(fp));
191: break;
192: case 'c': /* single ascii character */
193: put1(getc(fp));
194: break;
195: case 'C':
196: fscanf(fp, "%s", str);
197: put1s(str);
198: break;
199: case 't': /* straight text */
200: fgets(buf, sizeof(buf), fp);
201: t_text(buf);
202: break;
203: case 'D': /* draw function */
204: fgets(buf, sizeof(buf), fp);
205: switch (buf[0]) {
206: case 'l': /* draw a line */
207: sscanf(buf+1, "%d %d", &n, &m);
208: drawline(n, m, ".");
209: break;
210: case 'c': /* circle */
211: sscanf(buf+1, "%d", &n);
212: drawcirc(n);
213: break;
214: case 'e': /* ellipse */
215: sscanf(buf+1, "%d %d", &m, &n);
216: drawellip(m, n);
217: break;
218: case 'a': /* arc */
219: sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
220: drawarc(n, m, n1, m1);
221: break;
222: case '~': /* wiggly line */
223: drawwig(buf+1);
224: break;
225: default:
226: error(FATAL, "unknown drawing function %s\n", buf);
227: break;
228: }
229: break;
230: case 's':
231: fscanf(fp, "%d", &n); /* ignore fractional sizes */
232: setsize(t_size(n));
233: break;
234: case 'f':
235: fscanf(fp, "%s", str);
236: setfont(t_font(str));
237: break;
238: case 'H': /* absolute horizontal motion */
239: /* fscanf(fp, "%d", &n); */
240: while ((c = getc(fp)) == ' ')
241: ;
242: k = 0;
243: do {
244: k = 10 * k + c - '0';
245: } while (isdigit(c = getc(fp)));
246: ungetc(c, fp);
247: hgoto(k);
248: break;
249: case 'h': /* relative 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: hmot(k);
259: break;
260: case 'w': /* word space */
261: putc(' ', stdout);
262: break;
263: case 'V':
264: fscanf(fp, "%d", &n);
265: vgoto(n);
266: break;
267: case 'v':
268: fscanf(fp, "%d", &n);
269: vmot(n);
270: break;
271: case 'p': /* new page */
272: fscanf(fp, "%d", &n);
273: t_page(n);
274: break;
275: case 'n': /* end of line */
276: while (getc(fp) != '\n')
277: ;
278: t_newline();
279: break;
280: case '#': /* comment */
281: while (getc(fp) != '\n')
282: ;
283: break;
284: case 'x': /* device control */
285: devcntrl(fp);
286: break;
287: default:
288: error(!FATAL, "unknown input character %o %c\n", c, c);
289: done();
290: }
291: }
292: }
293:
294: devcntrl(fp) /* interpret device control functions */
295: FILE *fp;
296: {
297: char str[20];
298: int c, n;
299:
300: fscanf(fp, "%s", str);
301: switch (str[0]) { /* crude for now */
302: case 'i': /* initialize */
303: fileinit();
304: t_init(0);
305: break;
306: case 'T': /* device name */
307: fscanf(fp, "%s", devname);
308: break;
309: case 't': /* trailer */
310: t_trailer();
311: break;
312: case 'p': /* pause -- can restart */
313: t_reset('p');
314: break;
315: case 's': /* stop */
316: t_reset('s');
317: break;
318: case 'r': /* resolution assumed when prepared */
319: fscanf(fp, "%d", &res);
320: break;
321: case 'f': /* font used */
322: fscanf(fp, "%d %s", &n, str);
323: loadfont(n, str);
324: break;
325: }
326: while (getc(fp) != '\n') /* skip rest of input line */
327: ;
328: }
329:
330: fileinit() /* read in font and code files, etc. */
331: {
332: }
333:
334: fontprint(i) /* debugging print of font i (0,...) */
335: {
336: }
337:
338: loadcode(n, nw) /* load codetab on position n (0...); #chars is nw */
339: int n, nw;
340: {
341: }
342:
343: loadfont(n, s) /* load font info for font s on position n (1...) */
344: int n;
345: char *s;
346: {
347: }
348:
349: error(f, s, a1, a2, a3, a4, a5, a6, a7) {
350: fprintf(stderr, "ta: ");
351: fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
352: fprintf(stderr, "\n");
353: if (f)
354: exit(1);
355: }
356:
357:
358: /*
359: Here beginneth all the stuff that really depends
360: on the 202 (we hope).
361: */
362:
363:
364: char devname[20] = "hp2621";
365:
366: #define ESC 033
367: #define HOME 'H'
368: #define CLEAR 'J'
369: #define FF 014
370:
371: int size = 1;
372: int font = 1; /* current font */
373: int hpos; /* horizontal position where we are supposed to be next (left = 0) */
374: int vpos; /* current vertical position (down positive) */
375:
376: int horig; /* h origin of current block; hpos rel to this */
377: int vorig; /* v origin of current block; vpos rel to this */
378:
379: int DX = 10; /* step size in x for drawing */
380: int DY = 10; /* step size in y for drawing */
381: int drawdot = '.'; /* draw with this character */
382: int drawsize = 1; /* shrink by this factor when drawing */
383:
384: t_init(reinit) /* initialize device */
385: int reinit;
386: {
387: int i, j;
388:
389: fflush(stdout);
390: hpos = vpos = 0;
391: }
392:
393: #define MAXSTATE 5
394:
395: struct state {
396: int ssize;
397: int sfont;
398: int shpos;
399: int svpos;
400: int shorig;
401: int svorig;
402: };
403: struct state state[MAXSTATE];
404: struct state *statep = state;
405:
406: t_push() /* begin a new block */
407: {
408: hflush();
409: statep->ssize = size;
410: statep->sfont = font;
411: statep->shorig = horig;
412: statep->svorig = vorig;
413: statep->shpos = hpos;
414: statep->svpos = vpos;
415: horig = hpos;
416: vorig = vpos;
417: hpos = vpos = 0;
418: if (statep++ >= state+MAXSTATE)
419: error(FATAL, "{ nested too deep");
420: hpos = vpos = 0;
421: }
422:
423: t_pop() /* pop to previous state */
424: {
425: if (--statep < state)
426: error(FATAL, "extra }");
427: size = statep->ssize;
428: font = statep->sfont;
429: hpos = statep->shpos;
430: vpos = statep->svpos;
431: horig = statep->shorig;
432: vorig = statep->svorig;
433: }
434:
435: int np; /* number of pages seen */
436: int npmax; /* high-water mark of np */
437: int pgnum[40]; /* their actual numbers */
438: long pgadr[40]; /* their seek addresses */
439:
440: t_page(n) /* do whatever new page functions */
441: {
442: long ftell();
443: int c, m, i;
444: char buf[100], *bp;
445:
446: pgnum[np++] = n;
447: pgadr[np] = ftell(fp);
448: if (np > npmax)
449: npmax = np;
450: if (output == 0) {
451: output = in_olist(n);
452: t_init(1);
453: return;
454: }
455: /* have just printed something, and seen p<n> for next one */
456: putpage();
457: fflush(stdout);
458: }
459:
460: putpage()
461: {
462: int i, j, k;
463:
464: fflush(stdout);
465: }
466:
467: t_newline() /* do whatever for the end of a line */
468: {
469: printf("\n");
470: hpos = 0;
471: }
472:
473: t_size(n) /* convert integer to internal size number*/
474: int n;
475: {
476: }
477:
478: t_font(s) /* convert string to internal font number */
479: char *s;
480: {
481: }
482:
483: t_text(s) /* print string s as text */
484: char *s;
485: {
486: int c, w;
487: char str[100];
488:
489: if (!output)
490: return;
491: while ((c = *s++) != '\n') {
492: if (c == '\\') {
493: switch (c = *s++) {
494: case '\\':
495: case 'e':
496: put1('\\');
497: break;
498: case '(':
499: str[0] = *s++;
500: str[1] = *s++;
501: str[2] = '\0';
502: put1s(str);
503: break;
504: }
505: } else {
506: put1(c);
507: }
508: hmot(w);
509: }
510: }
511:
512: t_reset(c)
513: {
514: int n;
515:
516: output = 1;
517: fflush(stdout);
518: if (c == 's')
519: t_page(9999);
520: }
521:
522: t_trailer()
523: {
524: }
525:
526: hgoto(n)
527: {
528: hpos = n; /* this is where we want to be */
529: /* before printing a character, */
530: /* have to make sure it's true */
531: }
532:
533: hmot(n) /* generate n units of horizontal motion */
534: int n;
535: {
536: hgoto(hpos + n);
537: }
538:
539: hflush() /* actual horizontal output occurs here */
540: {
541: }
542:
543: vgoto(n)
544: {
545: vpos = n;
546: }
547:
548: vmot(n) /* generate n units of vertical motion */
549: int n;
550: {
551: vgoto(vpos + n); /* ignores rounding */
552: }
553:
554: put1s(s) /* s is a funny char name */
555: char *s;
556: {
557: int i;
558: char *p;
559: extern char *spectab[];
560: static char prev[10] = "";
561: static int previ;
562:
563: if (!output)
564: return;
565: if (strcmp(s, prev) != 0) {
566: previ = -1;
567: for (i = 0; spectab[i] != 0; i += 2)
568: if (strcmp(spectab[i], s) == 0) {
569: strcpy(prev, s);
570: previ = i;
571: break;
572: }
573: }
574: if (previ >= 0) {
575: for (p = spectab[previ+1]; *p; p++)
576: putc(*p, stdout);
577: } else
578: prev[0] = 0;
579: }
580:
581: put1(c) /* output char c */
582: int c;
583: {
584: if (!output)
585: return;
586: putc(c, stdout);
587: }
588:
589: setsize(n) /* set point size to n (internal) */
590: int n;
591: {
592: }
593:
594: t_fp(n, s) /* font position n now contains font s */
595: int n;
596: char *s;
597: {
598: }
599:
600: setfont(n) /* set font to n */
601: int n;
602: {
603: }
604:
605: done()
606: {
607: output = 1;
608: putpage();
609: fflush(stdout);
610: exit(0);
611: }
612:
613: char *spectab[] ={
614: "em", "-",
615: "hy", "-",
616: "en", "-",
617: "ru", "_",
618: "l.", ".",
619: "br", "|",
620: "vr", "|",
621: "fm", "'",
622: "or", "|",
623: 0, 0,
624: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.