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