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