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