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