|
|
1.1 ! root 1: /* ! 2: * div.c ! 3: * Nroff/Troff. ! 4: * Traps and diversions. ! 5: */ ! 6: ! 7: #include "roff.h" ! 8: ! 9: /* ! 10: * Given a name, create and initialize a new diversion. ! 11: * For troff, the processed text in the diversion assumes the current font; ! 12: * if the current font is different when the diversion is read back (executed), ! 13: * the character widths will be wrong. ! 14: * Therefore the diversion starts with a font change to the current font. ! 15: */ ! 16: newdivn(name) ! 17: char name[2]; ! 18: { ! 19: register DIV *dp; ! 20: ! 21: dp = (DIV *) nalloc(sizeof (DIV)); ! 22: dp->d_next = cdivp; ! 23: dp->d_name[0] = name[0]; ! 24: dp->d_name[1] = name[1]; ! 25: dp->d_rpos = 0; ! 26: dp->d_nspm = 0; ! 27: dp->d_maxh = 0; ! 28: dp->d_maxw = 0; ! 29: dp->d_seek = tmpseek; ! 30: dp->d_macp = NULL; ! 31: dp->d_stpl = NULL; ! 32: dp->d_trap = NULL; ! 33: dp->d_ctpp = NULL; ! 34: cdivp = dp; ! 35: if (name[0] != '\0') ! 36: dev_font(curfont); ! 37: dprint3(DBGDIVR, "create diversion %c%c\n", name[0], name[1]); ! 38: } ! 39: ! 40: /* ! 41: * End a diversion. ! 42: * The diverted text may have changed the current font, ! 43: * but because it was diverted the output writer's notion of the current ! 44: * font remains unchanged. ! 45: * Therefore this writes a change to the current font after the diversion. ! 46: */ ! 47: enddivn() ! 48: { ! 49: register REG *rp; ! 50: register DIV *dp; ! 51: ! 52: if ((dp = cdivp) == mdivp) { ! 53: printe("cannot end diversion"); ! 54: return; ! 55: } ! 56: if ((rp = findreg(dp->d_name, RTEXT)) != (REG *)NULL) { ! 57: rp->t_reg.r_maxh = cdivp->d_maxh; ! 58: rp->t_reg.r_maxw = cdivp->d_maxw; ! 59: } ! 60: nrdnreg->n_reg.r_nval = cdivp->d_maxh; ! 61: nrdlreg->n_reg.r_nval = cdivp->d_maxw; ! 62: cdivp = cdivp->d_next; ! 63: dprint3(DBGDIVR, "ended diversion %c%c\n", dp->d_name[0], dp->d_name[1]); ! 64: nfree((char *)dp); ! 65: dev_font(curfont); ! 66: } ! 67: ! 68: /* ! 69: * Append the given buffer onto the end of the current diversion. ! 70: */ ! 71: flushd(buffer, bufend) ! 72: CODE *buffer, *bufend; ! 73: { ! 74: register DIV *dp; ! 75: register MAC *mp; ! 76: register unsigned n; ! 77: ! 78: if((dp = cdivp) == NULL) ! 79: panic("flushd -- current diversion null"); ! 80: dprint3(DBGDIVR, "flushing diversion %c%c\n", dp->d_name[0], dp->d_name[1]); ! 81: mp = dp->d_macp; ! 82: if (mp->t_div.m_type!=MDIVN || dp->d_seek!=tmpseek) { ! 83: dp->d_macp = dp->d_macp->t_div.m_next = mp = ! 84: (MAC *)nalloc(sizeof *mp); ! 85: mp->t_div.m_next = NULL; ! 86: mp->t_div.m_type = MDIVN; ! 87: mp->t_div.m_size = 0; ! 88: mp->t_div.m_core = NULL; ! 89: mp->t_div.m_seek = tmpseek; ! 90: } ! 91: n = bufend - buffer; ! 92: nwrite((char *)buffer, (unsigned)sizeof (CODE), n); ! 93: mp->t_div.m_size += n; ! 94: dp->d_seek = tmpseek; ! 95: if ((n=tmpseek%DBFSIZE) != 0) ! 96: nwrite(miscbuf, 1, DBFSIZE-n); ! 97: } ! 98: ! 99: /* ! 100: * Space the required distance after a line has been put out. ! 101: * If we sprung a trap, execute it. ! 102: */ ! 103: lspace(n) ! 104: { ! 105: register DIV *dp; ! 106: register TPL *tp; ! 107: ! 108: #if 0 ! 109: fprintf(stderr, "lspace(%d)\n", n); ! 110: #endif ! 111: dp = cdivp; ! 112: tp = dp->d_ctpp; ! 113: if (tp!=NULL && dp->d_rpos+n<tp->t_apos) ! 114: tp = NULL; ! 115: scroll(dp, n); ! 116: if (tp != NULL) ! 117: execute(tp->t_name); ! 118: } ! 119: ! 120: /* ! 121: * Space to the end of the current page. ! 122: */ ! 123: pspace() ! 124: { ! 125: register DIV *dp; ! 126: register TPL *tp; ! 127: int lpct; ! 128: register int npos; ! 129: ! 130: #if 0 ! 131: fprintf(stderr, "pspace()\n"); ! 132: #endif ! 133: dp = mdivp; ! 134: lpct = pct; ! 135: while (lpct == pct) { ! 136: npos = pgl; ! 137: tp = dp->d_ctpp; ! 138: if (tp!=NULL && npos>=tp->t_apos) ! 139: npos = tp->t_apos; ! 140: if (mdivp==dp && npos>=pgl) { ! 141: scroll(dp, (int)pgl-dp->d_rpos); ! 142: npos = dp->d_rpos; ! 143: tp = dp->d_trap; ! 144: } ! 145: scroll(dp, npos-dp->d_rpos); ! 146: if (tp!=NULL && dp->d_rpos==tp->t_apos) ! 147: execute(tp->t_name); ! 148: } ! 149: } ! 150: ! 151: /* ! 152: * Space the distance 'n'. If a trap is encountered, spring the ! 153: * trap and stop. ! 154: */ ! 155: sspace(n) ! 156: { ! 157: register DIV *dp; ! 158: register TPL *tp; ! 159: register int npos; ! 160: ! 161: #if 0 ! 162: fprintf(stderr, "sspace(%d)\n", n); ! 163: #endif ! 164: dp = cdivp; ! 165: tp = dp->d_ctpp; ! 166: npos = dp->d_rpos + n; ! 167: if (npos < 0) ! 168: npos = 0; ! 169: if (tp!=NULL && npos>=tp->t_apos) ! 170: npos = tp->t_apos; ! 171: if (mdivp==dp && npos>=pgl) { ! 172: scroll(dp, (int)pgl-dp->d_rpos); ! 173: npos = dp->d_rpos; ! 174: tp = dp->d_trap; ! 175: } ! 176: scroll(dp, npos-dp->d_rpos); ! 177: if (tp!=NULL && dp->d_rpos==tp->t_apos) ! 178: execute(tp->t_name); ! 179: } ! 180: ! 181: /* ! 182: * Space down the given distance, resetting page information ! 183: * if we pass a page boundary. 'dp' is a pointer to the ! 184: * diversion we are using. ! 185: */ ! 186: scroll(dp, n) ! 187: register DIV *dp; ! 188: { ! 189: CODE code[1]; ! 190: register TPL *tp; ! 191: char *s; ! 192: ! 193: #if 0 ! 194: fprintf(stderr, "scroll(..., %d)\n", n); ! 195: #endif ! 196: code[0].l_arg.c_code = DSPAR; ! 197: code[0].l_arg.c_iarg = n; ! 198: if (dp == mdivp) ! 199: flushl(code, &code[1]); ! 200: else ! 201: flushd(code, &code[1]); ! 202: if ((cdivp->d_rpos+=n) > cdivp->d_maxh) ! 203: cdivp->d_maxh = cdivp->d_rpos; ! 204: while (cdivp->d_rpos >= pgl) { ! 205: if (byeflag) { ! 206: #if ZKLUDGE ! 207: dev_close(); ! 208: #endif ! 209: s = (lflag) ? POST_L : POST_P; ! 210: if (lib_file(s, 0) == 0 & ntroff == TROFF) ! 211: printe("file \"%s\" not found", s); ! 212: leave(0); ! 213: } ! 214: pct++; ! 215: pno = npn++; ! 216: cdivp->d_rpos -= pgl; ! 217: cdivp->d_maxh = cdivp->d_rpos; ! 218: cdivp->d_ctpp = cdivp->d_trap; ! 219: } ! 220: tp = dp->d_ctpp; ! 221: while (tp!=NULL && tp->t_apos<=dp->d_rpos) ! 222: tp = tp->t_next; ! 223: dp->d_ctpp = tp; ! 224: } ! 225: ! 226: /* ! 227: * Execute a macro, given the name. ! 228: */ ! 229: execute(name) ! 230: char name[2]; ! 231: { ! 232: register REG *rp; ! 233: ! 234: dprint3(DBGMACX, "execute macro %c%c\n", name[0], name[1]); ! 235: if ((rp=findreg(name, RTEXT)) != (REG *)NULL) { ! 236: adstreg(rp); ! 237: strp->x1.s_eoff = 1; ! 238: process(); ! 239: } ! 240: } ! 241: ! 242: /* end of div.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.