|
|
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.