129780Sjaap #ifndef lint
2*64044Sbostic /*
329790Sjaap static char sccsid[]="@(#)n10.c 1.2 (CWI) 86/08/15";
4*64044Sbostic */
5*64044Sbostic static char sccsid[] = "@(#)n10.c 1.3 (Berkeley) 07/27/93";
629780Sjaap #endif
729780Sjaap
829780Sjaap /*
929780Sjaap n10.c
1029780Sjaap
1129780Sjaap Device interfaces
1229780Sjaap */
1329780Sjaap
1429780Sjaap #include "tdef.h"
1529780Sjaap #include "ext.h"
1629780Sjaap #include "tw.h"
1729780Sjaap #include <sgtty.h>
1829780Sjaap #include <ctype.h>
1929780Sjaap #include <sys/types.h>
2029780Sjaap #include <sys/stat.h>
2129780Sjaap
2229780Sjaap struct t t; /* terminal characteristics */
2329780Sjaap
2429780Sjaap int dtab;
2529780Sjaap int plotmode;
2629780Sjaap int esct;
2729780Sjaap
2829780Sjaap char xchname[4 * (NROFFCHARS-128)]; /* hy, em, etc. */
2929780Sjaap short xchtab[NROFFCHARS-128]; /* indexes into chname[] */
3029780Sjaap char *codestr;
3129780Sjaap char *chname = xchname;
3229780Sjaap short *chtab = xchtab;
3329780Sjaap
3429780Sjaap
3529780Sjaap int Inch;
3629780Sjaap int Hor;
3729780Sjaap int Vert;
3829780Sjaap int nfonts = 4; /* R, I, B, S */
3929780Sjaap
4029780Sjaap /* these characters are used as various signals or values
4129780Sjaap /* in miscellaneous places.
4229780Sjaap /* values are set in specnames in t10.c
4329780Sjaap */
4429780Sjaap
4529780Sjaap int c_hyphen;
4629780Sjaap int c_emdash;
4729780Sjaap int c_rule;
4829780Sjaap int c_minus;
4929780Sjaap int c_fi;
5029780Sjaap int c_fl;
5129780Sjaap int c_ff;
5229780Sjaap int c_ffi;
5329780Sjaap int c_ffl;
5429780Sjaap int c_acute;
5529780Sjaap int c_grave;
5629780Sjaap int c_under;
5729780Sjaap int c_rooten;
5829780Sjaap int c_boxrule;
5929780Sjaap int c_lefthand;
6029780Sjaap int c_dagger;
6129780Sjaap int c_isalnum;
6229780Sjaap
ptinit()6329780Sjaap ptinit()
6429780Sjaap {
6529780Sjaap register int i, j;
6629780Sjaap register char *p, *cp, *q;
6729780Sjaap int nread, fd;
6829780Sjaap extern char *skipstr(), *getstr(), *getint();
6929780Sjaap struct stat stbuf;
7029780Sjaap char check[50];
7129780Sjaap
7229780Sjaap strcat(termtab, devname);
7329780Sjaap if ((fd = open(termtab, 0)) < 0) {
7429780Sjaap errprint("cannot open %s", termtab);
7529780Sjaap exit(-1);
7629780Sjaap }
7729780Sjaap
7829780Sjaap fstat(fd, &stbuf);
79*64044Sbostic codestr = malloc((int) stbuf.st_size);
8029780Sjaap
8129780Sjaap nread = read(fd, codestr, (int) stbuf.st_size);
8229780Sjaap close(fd);
8329780Sjaap
8429780Sjaap p = codestr;
8529780Sjaap p = skipstr(p); /* skip over type, could check */
8629780Sjaap p = skipstr(p); p = getint(p, &t.bset);
8729780Sjaap p = skipstr(p); p = getint(p, &t.breset);
8829780Sjaap p = skipstr(p); p = getint(p, &t.Hor);
8929780Sjaap p = skipstr(p); p = getint(p, &t.Vert);
9029780Sjaap p = skipstr(p); p = getint(p, &t.Newline);
9129780Sjaap p = skipstr(p); p = getint(p, &t.Char);
9229780Sjaap p = skipstr(p); p = getint(p, &t.Em);
9329780Sjaap p = skipstr(p); p = getint(p, &t.Halfline);
9429780Sjaap p = skipstr(p); p = getint(p, &t.Adj);
9529780Sjaap p = skipstr(p); p = getstr(p, t.twinit = p);
9629780Sjaap p = skipstr(p); p = getstr(p, t.twrest = p);
9729780Sjaap p = skipstr(p); p = getstr(p, t.twnl = p);
9829780Sjaap p = skipstr(p); p = getstr(p, t.hlr = p);
9929780Sjaap p = skipstr(p); p = getstr(p, t.hlf = p);
10029780Sjaap p = skipstr(p); p = getstr(p, t.flr = p);
10129780Sjaap p = skipstr(p); p = getstr(p, t.bdon = p);
10229780Sjaap p = skipstr(p); p = getstr(p, t.bdoff = p);
10329780Sjaap p = skipstr(p); p = getstr(p, t.iton = p);
10429780Sjaap p = skipstr(p); p = getstr(p, t.itoff = p);
10529780Sjaap p = skipstr(p); p = getstr(p, t.ploton = p);
10629780Sjaap p = skipstr(p); p = getstr(p, t.plotoff = p);
10729780Sjaap p = skipstr(p); p = getstr(p, t.up = p);
10829780Sjaap p = skipstr(p); p = getstr(p, t.down = p);
10929780Sjaap p = skipstr(p); p = getstr(p, t.right = p);
11029780Sjaap p = skipstr(p); p = getstr(p, t.left = p);
11129790Sjaap p = skipstr(p); p = getstr(p, t.eject = p);
11229780Sjaap
11329780Sjaap getstr(p, check);
11429780Sjaap if (strcmp(check, "charset") != 0) {
11529780Sjaap errprint("device table apparently curdled");
11629780Sjaap exit(1);
11729780Sjaap }
11829780Sjaap
11929780Sjaap for (i = 0; i < 128; i++)
12029780Sjaap t.width[i] = 1; /* default ascii widths */
12129780Sjaap
12229780Sjaap i = 0;
12329780Sjaap /* this ought to be a pointer array and in place in codestr */
12429780Sjaap cp = chname + 1; /* bug if starts at 0, in setch */
12529780Sjaap while (p < codestr + nread) {
12629780Sjaap while (*p == ' ' || *p == '\t' || *p == '\n')
12729780Sjaap p++;
12829780Sjaap chtab[i] = cp - chname; /* index, not pointer */
12929780Sjaap *cp++ = *p++; /* 2-char names */
13029780Sjaap *cp++ = *p++;
13129780Sjaap *cp++ = '\0';
13229780Sjaap while (*p == ' ' || *p == '\t')
13329780Sjaap p++;
13429780Sjaap t.width[i+128] = *p++ - '0';
13529780Sjaap while (*p == ' ' || *p == '\t')
13629780Sjaap p++;
13729780Sjaap t.codetab[i] = p;
13829780Sjaap p = getstr(p, p); /* compress string */
13929780Sjaap p++;
14029780Sjaap i++;
14129780Sjaap }
14229780Sjaap
14329780Sjaap sps = EM;
14429780Sjaap ics = EM * 2;
14529780Sjaap dtab = 8 * t.Em;
14629780Sjaap for (i = 0; i < 16; i++)
14729780Sjaap tabtab[i] = dtab * (i + 1);
14829780Sjaap pl = 11 * INCH;
14929780Sjaap po = PO;
15029780Sjaap spacesz = SS;
15129780Sjaap lss = lss1 = VS;
15229780Sjaap ll = ll1 = lt = lt1 = LL;
15329780Sjaap smnt = nfonts = 5; /* R I B BI S */
15429780Sjaap specnames(); /* install names like "hyphen", etc. */
15529780Sjaap if (eqflg)
15629780Sjaap t.Adj = t.Hor;
15729780Sjaap }
15829780Sjaap
skipstr(s)15929780Sjaap char *skipstr(s) /* skip over leading space plus string */
16029780Sjaap char *s;
16129780Sjaap {
16229780Sjaap while (*s == ' ' || *s == '\t' || *s == '\n')
16329780Sjaap s++;
16429780Sjaap while (*s != ' ' && *s != '\t' && *s != '\n')
16529780Sjaap if (*s++ == '\\')
16629780Sjaap s++;
16729780Sjaap return s;
16829780Sjaap }
16929780Sjaap
getstr(s,t)17029780Sjaap char *getstr(s, t) /* find next string in s, copy to t */
17129780Sjaap char *s, *t;
17229780Sjaap {
17329780Sjaap int quote = 0;
17429780Sjaap
17529780Sjaap while (*s == ' ' || *s == '\t' || *s == '\n')
17629780Sjaap s++;
17729780Sjaap if (*s == '"') {
17829780Sjaap s++;
17929780Sjaap quote = 1;
18029780Sjaap }
18129780Sjaap for (;;) {
18229780Sjaap if (quote && *s == '"') {
18329780Sjaap s++;
18429780Sjaap break;
18529780Sjaap }
18629780Sjaap if (!quote && (*s == ' ' || *s == '\t' || *s == '\n'))
18729780Sjaap break;
18829780Sjaap if (*s != '\\')
18929780Sjaap *t++ = *s++;
19029780Sjaap else {
19129780Sjaap s++; /* skip \\ */
19229780Sjaap if (isdigit(s[0]) && isdigit(s[1]) && isdigit(s[2])) {
19329780Sjaap *t++ = (s[0]-'0')<<6 | (s[1]-'0')<<3 | s[2]-'0';
19429780Sjaap s += 2;
19529780Sjaap } else if (isdigit(s[0])) {
19629780Sjaap *t++ = *s - '0';
19729780Sjaap } else if (*s == 'b') {
19829780Sjaap *t++ = '\b';
19929780Sjaap } else if (*s == 'n') {
20029780Sjaap *t++ = '\n';
20129780Sjaap } else if (*s == 'r') {
20229780Sjaap *t++ = '\r';
20329780Sjaap } else if (*s == 't') {
20429780Sjaap *t++ = '\t';
20529780Sjaap } else {
20629780Sjaap *t++ = *s;
20729780Sjaap }
20829780Sjaap s++;
20929780Sjaap }
21029780Sjaap }
21129780Sjaap *t = '\0';
21229780Sjaap return s;
21329780Sjaap }
21429780Sjaap
getint(s,pn)21529780Sjaap char *getint(s, pn) /* find integer at s */
21629780Sjaap char *s;
21729780Sjaap int *pn;
21829780Sjaap {
21929780Sjaap while (*s == ' ' || *s == '\t' || *s == '\n')
22029780Sjaap s++;
22129780Sjaap *pn = 0;
22229780Sjaap while (isdigit(*s))
22329780Sjaap *pn = 10 * *pn + *s++ - '0';
22429780Sjaap return s;
22529780Sjaap }
22629780Sjaap
specnames()22729780Sjaap specnames()
22829780Sjaap {
22929780Sjaap static struct {
23029780Sjaap int *n;
23129780Sjaap char *v;
23229780Sjaap } spnames[] = {
23329780Sjaap &c_hyphen, "hy",
23429780Sjaap &c_emdash, "em",
23529780Sjaap &c_rule, "ru",
23629780Sjaap &c_minus, "\\-",
23729780Sjaap &c_fi, "fi",
23829780Sjaap &c_fl, "fl",
23929780Sjaap &c_ff, "ff",
24029780Sjaap &c_ffi, "Fi",
24129780Sjaap &c_ffl, "Fl",
24229780Sjaap &c_acute, "aa",
24329780Sjaap &c_grave, "ga",
24429780Sjaap &c_under, "ul",
24529780Sjaap &c_rooten, "rn",
24629780Sjaap &c_boxrule, "br",
24729780Sjaap &c_lefthand, "lh",
24829780Sjaap &c_isalnum, "__",
24929780Sjaap 0, 0
25029780Sjaap };
25129780Sjaap int i;
25229780Sjaap
25329780Sjaap for (i = 0; spnames[i].n; i++)
25429780Sjaap *spnames[i].n = findch(spnames[i].v);
25529780Sjaap if (c_isalnum == 0)
25629780Sjaap c_isalnum = NROFFCHARS;
25729780Sjaap }
25829780Sjaap
25929780Sjaap
findch(s)26029780Sjaap findch(s) /* find char s in chname */
26129780Sjaap register char *s;
26229780Sjaap {
26329780Sjaap register int i;
26429780Sjaap
26529780Sjaap for (i = 0; chtab[i] != 0; i++)
26629780Sjaap if (strcmp(s, &chname[chtab[i]]) == 0)
26729780Sjaap return(i + 128);
26829780Sjaap return(0);
26929780Sjaap }
27029780Sjaap
twdone()27129780Sjaap twdone()
27229780Sjaap {
27329780Sjaap int waitf;
27429780Sjaap
27529780Sjaap oputs(t.twrest);
27629780Sjaap flusho();
27729780Sjaap if (pipeflg) {
278*64044Sbostic close(fileno(ptid));
27929780Sjaap wait(&waitf);
28029780Sjaap }
28129780Sjaap if (ttysave != -1) {
28229780Sjaap ttys.sg_flags = ttysave;
28329780Sjaap stty(1, &ttys);
28429780Sjaap }
28529780Sjaap }
28629780Sjaap
28729780Sjaap
ptout(i)28829780Sjaap ptout(i)
28929780Sjaap tchar i;
29029780Sjaap {
29129780Sjaap *olinep++ = i;
29229780Sjaap if (olinep >= &oline[LNSIZE])
29329780Sjaap olinep--;
29429780Sjaap if (cbits(i) != '\n')
29529780Sjaap return;
29629780Sjaap olinep--;
29729780Sjaap lead += dip->blss + lss - t.Newline;
29829780Sjaap dip->blss = 0;
29929780Sjaap esct = esc = 0;
30029780Sjaap if (olinep > oline) {
30129780Sjaap move();
30229780Sjaap ptout1();
30329780Sjaap oputs(t.twnl);
30429780Sjaap } else {
30529780Sjaap lead += t.Newline;
30629780Sjaap move();
30729780Sjaap }
30829780Sjaap lead += dip->alss;
30929780Sjaap dip->alss = 0;
31029780Sjaap olinep = oline;
31129780Sjaap }
31229780Sjaap
31329780Sjaap
ptout1()31429780Sjaap ptout1()
31529780Sjaap {
31629780Sjaap register k;
31729780Sjaap register char *codep;
31829780Sjaap extern char *plot();
31929780Sjaap int w, j, phyw;
32029780Sjaap tchar * q, i;
32129780Sjaap static int oxfont = FT; /* start off in roman */
32229780Sjaap
32329780Sjaap for (q = oline; q < olinep; q++) {
32429780Sjaap i = *q;
32529780Sjaap if (ismot(i)) {
32629780Sjaap j = absmot(i);
32729780Sjaap if (isnmot(i))
32829780Sjaap j = -j;
32929780Sjaap if (isvmot(i))
33029780Sjaap lead += j;
33129780Sjaap else
33229780Sjaap esc += j;
33329780Sjaap continue;
33429780Sjaap }
33529780Sjaap if ((k = cbits(i)) <= 040) {
33629780Sjaap switch (k) {
33729780Sjaap case ' ': /*space*/
33829780Sjaap esc += t.Char;
33929780Sjaap break;
34029780Sjaap case '\033':
34129780Sjaap case '\007':
34229780Sjaap case '\016':
34329780Sjaap case '\017':
34429780Sjaap oput(k);
34529780Sjaap break;
34629780Sjaap }
34729780Sjaap continue;
34829780Sjaap }
34929780Sjaap phyw = w = t.Char * t.width[k];
35029780Sjaap if (iszbit(i))
35129780Sjaap w = 0;
35229780Sjaap if (esc || lead)
35329780Sjaap move();
35429780Sjaap esct += w;
35529780Sjaap xfont = fbits(i);
35629780Sjaap if (xfont != oxfont) {
35729780Sjaap switch (oxfont) {
35829780Sjaap case ULFONT: oputs(t.itoff); break;
35929780Sjaap case BDFONT: oputs(t.bdoff); break;
36029780Sjaap case BIFONT: oputs(t.itoff); oputs(t.bdoff); break;
36129780Sjaap }
36229780Sjaap switch (xfont) {
36329780Sjaap case ULFONT:
36429780Sjaap if (*t.iton & 0377) oputs(t.iton); break;
36529780Sjaap case BDFONT:
36629780Sjaap if (*t.bdon & 0377) oputs(t.bdon); break;
36729780Sjaap case BIFONT:
36829780Sjaap if (*t.bdon & 0377) oputs(t.bdon);
36929780Sjaap if (*t.iton & 0377) oputs(t.iton);
37029780Sjaap break;
37129780Sjaap }
37229780Sjaap oxfont = xfont;
37329780Sjaap }
37429780Sjaap if ((xfont == ULFONT || xfont == BIFONT) && !(*t.iton & 0377)) {
37529780Sjaap for (j = w / t.Char; j > 0; j--)
37629780Sjaap oput('_');
37729780Sjaap for (j = w / t.Char; j > 0; j--)
37829780Sjaap oput('\b');
37929780Sjaap }
38029780Sjaap if (!(*t.bdon & 0377) && ((j = bdtab[xfont]) || xfont == BDFONT || xfont == BIFONT))
38129780Sjaap j++;
38229780Sjaap else
38329780Sjaap j = 1; /* number of overstrikes for bold */
38429780Sjaap if (k < 128) { /* ordinary ascii */
38529780Sjaap oput(k);
38629780Sjaap while (--j > 0) {
38729780Sjaap oput('\b');
38829780Sjaap oput(k);
38929780Sjaap }
39029780Sjaap } else {
39129780Sjaap int oj = j;
39229780Sjaap codep = t.codetab[k-128];
39329780Sjaap while (*codep != 0) {
39429780Sjaap if (*codep & 0200) {
39529780Sjaap codep = plot(codep);
39629780Sjaap oput(' ');
39729780Sjaap } else {
39829780Sjaap if (*codep == '%') /* escape */
39929780Sjaap codep++;
40029780Sjaap oput(*codep);
40129780Sjaap if (*codep != '\b')
40229780Sjaap for (j = oj; --j > 0; ) {
40329780Sjaap oput('\b');
40429780Sjaap oput(*codep);
40529780Sjaap }
40629780Sjaap codep++;
40729780Sjaap }
40829780Sjaap }
40929780Sjaap }
41029780Sjaap if (!w)
41129780Sjaap for (j = phyw / t.Char; j > 0; j--)
41229780Sjaap oput('\b');
41329780Sjaap }
41429780Sjaap }
41529780Sjaap
41629780Sjaap
plot(x)41729780Sjaap char *plot(x)
41829780Sjaap char *x;
41929780Sjaap {
42029780Sjaap register int i;
42129780Sjaap register char *j, *k;
42229780Sjaap
42329780Sjaap oputs(t.ploton);
42429780Sjaap k = x;
42529780Sjaap if ((*k & 0377) == 0200)
42629780Sjaap k++;
42729780Sjaap for (; *k; k++) {
42829780Sjaap if (*k == '%') { /* quote char within plot mode */
42929780Sjaap oput(*++k);
43029780Sjaap } else if (*k & 0200) {
43129780Sjaap if (*k & 0100) {
43229780Sjaap if (*k & 040)
43329780Sjaap j = t.up;
43429780Sjaap else
43529780Sjaap j = t.down;
43629780Sjaap } else {
43729780Sjaap if (*k & 040)
43829780Sjaap j = t.left;
43929780Sjaap else
44029780Sjaap j = t.right;
44129780Sjaap }
44229780Sjaap if ((i = *k & 037) == 0) { /* 2nd 0200 turns it off */
44329780Sjaap ++k;
44429780Sjaap break;
44529780Sjaap }
44629780Sjaap while (i--)
44729780Sjaap oputs(j);
44829780Sjaap } else
44929780Sjaap oput(*k);
45029780Sjaap }
45129780Sjaap oputs(t.plotoff);
45229780Sjaap return(k);
45329780Sjaap }
45429780Sjaap
45529780Sjaap
move()45629780Sjaap move()
45729780Sjaap {
45829780Sjaap register k;
45929780Sjaap register char *i, *j;
46029780Sjaap char *p, *q;
46129780Sjaap int iesct, dt;
46229780Sjaap
46329780Sjaap iesct = esct;
46429780Sjaap if (esct += esc)
46529780Sjaap i = "\0";
46629780Sjaap else
46729780Sjaap i = "\n\0";
46829780Sjaap j = t.hlf;
46929780Sjaap p = t.right;
47029780Sjaap q = t.down;
47129780Sjaap if (lead) {
47229780Sjaap if (lead < 0) {
47329780Sjaap lead = -lead;
47429780Sjaap i = t.flr;
47529780Sjaap /* if(!esct)i = t.flr; else i = "\0";*/
47629780Sjaap j = t.hlr;
47729780Sjaap q = t.up;
47829780Sjaap }
47929780Sjaap if (*i & 0377) {
48029780Sjaap k = lead / t.Newline;
48129780Sjaap lead = lead % t.Newline;
48229780Sjaap while (k--)
48329780Sjaap oputs(i);
48429780Sjaap }
48529780Sjaap if (*j & 0377) {
48629780Sjaap k = lead / t.Halfline;
48729780Sjaap lead = lead % t.Halfline;
48829780Sjaap while (k--)
48929780Sjaap oputs(j);
49029780Sjaap } else { /* no half-line forward, not at line begining */
49129780Sjaap k = lead / t.Newline;
49229780Sjaap lead = lead % t.Newline;
49329780Sjaap if (k > 0)
49429780Sjaap esc = esct;
49529780Sjaap i = "\n";
49629780Sjaap while (k--)
49729780Sjaap oputs(i);
49829780Sjaap }
49929780Sjaap }
50029780Sjaap if (esc) {
50129780Sjaap if (esc < 0) {
50229780Sjaap esc = -esc;
50329780Sjaap j = "\b";
50429780Sjaap p = t.left;
50529780Sjaap } else {
50629780Sjaap j = " ";
50729780Sjaap if (hflg)
50829780Sjaap while ((dt = dtab - (iesct % dtab)) <= esc) {
50929780Sjaap if (dt % t.Em)
51029780Sjaap break;
51129780Sjaap oput(TAB);
51229780Sjaap esc -= dt;
51329780Sjaap iesct += dt;
51429780Sjaap }
51529780Sjaap }
51629780Sjaap k = esc / t.Em;
51729780Sjaap esc = esc % t.Em;
51829780Sjaap while (k--)
51929780Sjaap oputs(j);
52029780Sjaap }
52129780Sjaap if ((*t.ploton & 0377) && (esc || lead)) {
52229780Sjaap oputs(t.ploton);
52329780Sjaap esc /= t.Hor;
52429780Sjaap lead /= t.Vert;
52529780Sjaap while (esc--)
52629780Sjaap oputs(p);
52729780Sjaap while (lead--)
52829780Sjaap oputs(q);
52929780Sjaap oputs(t.plotoff);
53029780Sjaap }
53129780Sjaap esc = lead = 0;
53229780Sjaap }
53329780Sjaap
53429780Sjaap
ptlead()53529780Sjaap ptlead()
53629780Sjaap {
53729780Sjaap move();
53829780Sjaap }
53929780Sjaap
54029780Sjaap
dostop()54129780Sjaap dostop()
54229780Sjaap {
54329780Sjaap char junk;
54429780Sjaap
54529780Sjaap flusho();
54629780Sjaap read(2, &junk, 1);
54729780Sjaap }
54829780Sjaap
54929780Sjaap
newpage()55029780Sjaap newpage(){;}
pttrailer()55129780Sjaap pttrailer(){;}
552