|
|
1.1 root 1: /*
2: n10.c
3:
4: Device interfaces
5: */
6:
7: #include "tdef.h"
8: #include "ext.h"
9: #include "tw.h"
10: #include <ctype.h>
11: #include <sys/types.h>
12: #include <sys/stat.h>
13:
14: struct t t; /* terminal characteristics */
15:
16: int dtab;
17: int plotmode;
18: int esct;
19:
20: char xchname[4 * (NROFFCHARS-128)]; /* hy, em, etc. */
21: short xchtab[NROFFCHARS-128]; /* indexes into chname[] */
22: char *codestr;
23: char *chname = xchname;
24: short *chtab = xchtab;
25: int nchtab = 0;
26:
27:
28: int Inch;
29: int Hor;
30: int Vert;
31: int nfonts = 4; /* R, I, B, S */
32:
33: /* these characters are used as various signals or values
34: /* in miscellaneous places.
35: /* values are set in specnames in t10.c
36: */
37:
38: int c_hyphen;
39: int c_emdash;
40: int c_rule;
41: int c_minus;
42: int c_fi;
43: int c_fl;
44: int c_ff;
45: int c_ffi;
46: int c_ffl;
47: int c_acute;
48: int c_grave;
49: int c_under;
50: int c_rooten;
51: int c_boxrule;
52: int c_lefthand;
53: int c_dagger;
54: int c_isalnum;
55:
56: ptinit()
57: {
58: register int i;
59: register char *p, *cp;
60: int nread, fd;
61: extern char *skipstr(), *getstr(), *getint();
62: extern char *setbrk();
63: struct stat stbuf;
64: char check[50];
65:
66: strcat(termtab, devname);
67: if ((fd = open(termtab, 0)) < 0) {
68: errprint("cannot open %s", termtab);
69: exit(-1);
70: }
71:
72: fstat(fd, &stbuf);
73: codestr = setbrk((int) stbuf.st_size);
74:
75: nread = read(fd, codestr, (int) stbuf.st_size);
76: close(fd);
77:
78: p = codestr;
79: p = skipstr(p); /* skip over type, could check */
80: p = skipstr(p); p = getint(p, &t.bset);
81: p = skipstr(p); p = getint(p, &t.breset);
82: p = skipstr(p); p = getint(p, &t.Hor);
83: p = skipstr(p); p = getint(p, &t.Vert);
84: p = skipstr(p); p = getint(p, &t.Newline);
85: p = skipstr(p); p = getint(p, &t.Char);
86: p = skipstr(p); p = getint(p, &t.Em);
87: p = skipstr(p); p = getint(p, &t.Halfline);
88: p = skipstr(p); p = getint(p, &t.Adj);
89: p = skipstr(p); p = getstr(p, t.twinit = p);
90: p = skipstr(p); p = getstr(p, t.twrest = p);
91: p = skipstr(p); p = getstr(p, t.twnl = p);
92: p = skipstr(p); p = getstr(p, t.hlr = p);
93: p = skipstr(p); p = getstr(p, t.hlf = p);
94: p = skipstr(p); p = getstr(p, t.flr = p);
95: p = skipstr(p); p = getstr(p, t.bdon = p);
96: p = skipstr(p); p = getstr(p, t.bdoff = p);
97: p = skipstr(p); p = getstr(p, t.iton = p);
98: p = skipstr(p); p = getstr(p, t.itoff = p);
99: p = skipstr(p); p = getstr(p, t.ploton = p);
100: p = skipstr(p); p = getstr(p, t.plotoff = p);
101: p = skipstr(p); p = getstr(p, t.up = p);
102: p = skipstr(p); p = getstr(p, t.down = p);
103: p = skipstr(p); p = getstr(p, t.right = p);
104: p = skipstr(p); p = getstr(p, t.left = p);
105:
106: p = getstr(p, check);
107: if (strcmp(check, "charset") != 0) {
108: errprint("device table apparently curdled");
109: exit(1);
110: }
111:
112: for (i = 0; i < 128; i++)
113: t.width[i] = 1; /* default ascii widths */
114:
115: i = 0;
116: /* this ought to be a pointer array and in place in codestr */
117: cp = chname + 1; /* bug if starts at 0, in setch */
118: while (p < codestr + nread) {
119: while (*p == ' ' || *p == '\t' || *p == '\n')
120: p++;
121: if (i + 128 >= NROFFCHARS) {
122: errprint("too many names in charset for %s", termtab);
123: exit(1);
124: }
125: chtab[i] = cp - chname; /* index, not pointer */
126: *cp++ = *p++; /* 2-char names */
127: *cp++ = *p++;
128: *cp++ = '\0';
129: while (*p == ' ' || *p == '\t')
130: p++;
131: t.width[i+128] = *p++ - '0';
132: while (*p == ' ' || *p == '\t')
133: p++;
134: t.codetab[i] = p;
135: p = getstr(p, p); /* compress string */
136: p++;
137: i++;
138: nchtab++;
139: }
140:
141: sps = EM;
142: ics = EM * 2;
143: dtab = 8 * t.Em;
144: for (i = 0; i < 16; i++)
145: tabtab[i] = dtab * (i + 1);
146: pl = 11 * INCH;
147: po = PO;
148: spacesz = SS;
149: lss = lss1 = VS;
150: ll = ll1 = lt = lt1 = LL;
151: smnt = nfonts = 5; /* R I B BI S */
152: specnames(); /* install names like "hyphen", etc. */
153: if (eqflg)
154: t.Adj = t.Hor;
155: }
156:
157: char *skipstr(s) /* skip over leading space plus string */
158: char *s;
159: {
160: while (*s == ' ' || *s == '\t' || *s == '\n')
161: s++;
162: while (*s != ' ' && *s != '\t' && *s != '\n')
163: if (*s++ == '\\')
164: s++;
165: return s;
166: }
167:
168: char *getstr(s, t) /* find next string in s, copy to t */
169: char *s, *t;
170: {
171: int quote = 0;
172:
173: while (*s == ' ' || *s == '\t' || *s == '\n')
174: s++;
175: if (*s == '"') {
176: s++;
177: quote = 1;
178: }
179: for (;;) {
180: if (quote && *s == '"') {
181: s++;
182: break;
183: }
184: if (!quote && (*s == ' ' || *s == '\t' || *s == '\n'))
185: break;
186: if (*s != '\\')
187: *t++ = *s++;
188: else {
189: s++; /* skip \\ */
190: if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) {
191: *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0';
192: s += 2;
193: } else if (isdigit(s[0])) {
194: *t++ = *s - '0';
195: } else if (*s == 'b') {
196: *t++ = '\b';
197: } else if (*s == 'n') {
198: *t++ = '\n';
199: } else if (*s == 'r') {
200: *t++ = '\r';
201: } else if (*s == 't') {
202: *t++ = '\t';
203: } else {
204: *t++ = *s;
205: }
206: s++;
207: }
208: }
209: *t = '\0';
210: return s;
211: }
212:
213: char *getint(s, pn) /* find integer at s */
214: char *s;
215: int *pn;
216: {
217: int base;
218:
219: while (*s == ' ' || *s == '\t' || *s == '\n')
220: s++;
221: base = (*s == '0') ? 8 : 10;
222: *pn = 0;
223: while (isdigit(*s))
224: *pn = base * *pn + *s++ - '0';
225: return s;
226: }
227:
228: specnames()
229: {
230: static struct {
231: int *n;
232: char *v;
233: } spnames[] = {
234: &c_hyphen, "hy",
235: &c_emdash, "em",
236: &c_rule, "ru",
237: &c_minus, "\\-",
238: &c_fi, "fi",
239: &c_fl, "fl",
240: &c_ff, "ff",
241: &c_ffi, "Fi",
242: &c_ffl, "Fl",
243: &c_acute, "aa",
244: &c_grave, "ga",
245: &c_under, "ul",
246: &c_rooten, "rn",
247: &c_boxrule, "br",
248: &c_lefthand, "lh",
249: &c_isalnum, "__",
250: 0, 0
251: };
252: int i;
253:
254: for (i = 0; spnames[i].n; i++)
255: *spnames[i].n = findch(spnames[i].v);
256: if (c_isalnum == 0)
257: c_isalnum = NROFFCHARS;
258: }
259:
260:
261: findch(s) /* find char s in chname */
262: register char *s;
263: {
264: register int i;
265:
266: for (i = 0; chtab[i] != 0; i++)
267: if (strcmp(s, &chname[chtab[i]]) == 0)
268: return(i + 128);
269: return(0);
270: }
271:
272: twdone()
273: {
274: int waitf;
275:
276: obufp = obuf;
277: oputs(t.twrest);
278: flusho();
279: if (pipeflg) {
280: close(ptid);
281: wait(&waitf);
282: }
283: restore_tty();
284: }
285:
286:
287: ptout(i)
288: tchar i;
289: {
290: *olinep++ = i;
291: if (olinep >= &oline[LNSIZE])
292: olinep--;
293: if (cbits(i) != '\n')
294: return;
295: olinep--;
296: lead += dip->blss + lss - t.Newline;
297: dip->blss = 0;
298: esct = esc = 0;
299: if (olinep > oline) {
300: move();
301: ptout1();
302: oputs(t.twnl);
303: } else {
304: lead += t.Newline;
305: move();
306: }
307: lead += dip->alss;
308: dip->alss = 0;
309: olinep = oline;
310: }
311:
312:
313: ptout1()
314: {
315: register k;
316: register char *codep;
317: extern char *plot();
318: int w, j, phyw;
319: tchar * q, i;
320: static int oxfont = FT; /* start off in roman */
321:
322: for (q = oline; q < olinep; q++) {
323: i = *q;
324: if (ismot(i)) {
325: j = absmot(i);
326: if (isnmot(i))
327: j = -j;
328: if (isvmot(i))
329: lead += j;
330: else
331: esc += j;
332: continue;
333: }
334: if ((k = cbits(i)) <= 040) {
335: switch (k) {
336: case ' ': /*space*/
337: esc += t.Char;
338: break;
339: case '\033':
340: case '\007':
341: case '\016':
342: case '\017':
343: oput(k);
344: break;
345: }
346: continue;
347: }
348: phyw = w = t.Char * t.width[k];
349: if (iszbit(i))
350: w = 0;
351: if (esc || lead)
352: move();
353: esct += w;
354: xfont = fbits(i);
355: if (xfont != oxfont) {
356: switch (oxfont) {
357: case ULFONT: oputs(t.itoff); break;
358: case BDFONT: oputs(t.bdoff); break;
359: case BIFONT: oputs(t.itoff); oputs(t.bdoff); break;
360: }
361: switch (xfont) {
362: case ULFONT:
363: if (*t.iton & 0377) oputs(t.iton); break;
364: case BDFONT:
365: if (*t.bdon & 0377) oputs(t.bdon); break;
366: case BIFONT:
367: if (*t.bdon & 0377) oputs(t.bdon);
368: if (*t.iton & 0377) oputs(t.iton);
369: break;
370: }
371: oxfont = xfont;
372: }
373: if ((xfont == ulfont || xfont == BIFONT) && !(*t.iton & 0377)) {
374: for (j = w / t.Char; j > 0; j--)
375: oput('_');
376: for (j = w / t.Char; j > 0; j--)
377: oput('\b');
378: }
379: if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT))
380: j++;
381: else
382: j = 1; /* number of overstrikes for bold */
383: if (k < 128) { /* ordinary ascii */
384: oput(k);
385: while (--j > 0) {
386: oput('\b');
387: oput(k);
388: }
389: } else if (k >= nchtab + 128) {
390: oput(k - nchtab - 128);
391: } else {
392: int oj = j;
393: codep = t.codetab[k-128];
394: while (*codep != 0) {
395: if (*codep & 0200) {
396: codep = plot(codep);
397: oput(' ');
398: } else {
399: if (*codep == '%') /* escape */
400: codep++;
401: oput(*codep);
402: if (*codep == '\033')
403: oput(*++codep);
404: else if (*codep != '\b')
405: for (j = oj; --j > 0; ) {
406: oput('\b');
407: oput(*codep);
408: }
409: codep++;
410: }
411: }
412: }
413: if (!w)
414: for (j = phyw / t.Char; j > 0; j--)
415: oput('\b');
416: }
417: }
418:
419:
420: char *plot(x)
421: char *x;
422: {
423: register int i;
424: register char *j, *k;
425:
426: oputs(t.ploton);
427: k = x;
428: if ((*k & 0377) == 0200)
429: k++;
430: for (; *k; k++) {
431: if (*k == '%') { /* quote char within plot mode */
432: oput(*++k);
433: } else if (*k & 0200) {
434: if (*k & 0100) {
435: if (*k & 040)
436: j = t.up;
437: else
438: j = t.down;
439: } else {
440: if (*k & 040)
441: j = t.left;
442: else
443: j = t.right;
444: }
445: if ((i = *k & 037) == 0) { /* 2nd 0200 turns it off */
446: ++k;
447: break;
448: }
449: while (i--)
450: oputs(j);
451: } else
452: oput(*k);
453: }
454: oputs(t.plotoff);
455: return(k);
456: }
457:
458:
459: move()
460: {
461: register k;
462: register char *i, *j;
463: char *p, *q;
464: int iesct, dt;
465:
466: iesct = esct;
467: if (esct += esc)
468: i = "\0";
469: else
470: i = "\n\0";
471: j = t.hlf;
472: p = t.right;
473: q = t.down;
474: if (lead) {
475: if (lead < 0) {
476: lead = -lead;
477: i = t.flr;
478: /* if(!esct)i = t.flr; else i = "\0";*/
479: j = t.hlr;
480: q = t.up;
481: }
482: if (*i & 0377) {
483: k = lead / t.Newline;
484: lead = lead % t.Newline;
485: while (k--)
486: oputs(i);
487: }
488: if (*j & 0377) {
489: k = lead / t.Halfline;
490: lead = lead % t.Halfline;
491: while (k--)
492: oputs(j);
493: } else { /* no half-line forward, not at line begining */
494: k = lead / t.Newline;
495: lead = lead % t.Newline;
496: if (k > 0)
497: esc = esct;
498: i = "\n";
499: while (k--)
500: oputs(i);
501: }
502: }
503: if (esc) {
504: if (esc < 0) {
505: esc = -esc;
506: j = "\b";
507: p = t.left;
508: } else {
509: j = " ";
510: if (hflg)
511: while ((dt = dtab - (iesct % dtab)) <= esc) {
512: if (dt % t.Em)
513: break;
514: oput(TAB);
515: esc -= dt;
516: iesct += dt;
517: }
518: }
519: k = esc / t.Em;
520: esc = esc % t.Em;
521: while (k--)
522: oputs(j);
523: }
524: if ((*t.ploton & 0377) && (esc || lead)) {
525: oputs(t.ploton);
526: esc /= t.Hor;
527: lead /= t.Vert;
528: while (esc--)
529: oputs(p);
530: while (lead--)
531: oputs(q);
532: oputs(t.plotoff);
533: }
534: esc = lead = 0;
535: }
536:
537:
538: ptlead()
539: {
540: move();
541: }
542:
543:
544: dostop()
545: {
546: char junk;
547:
548: flusho();
549: read(2, &junk, 1);
550: }
551:
552:
553: newpage(n){ return n;}
554: pttrailer(){;}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.