xref: /original-bsd/old/roff/common_source/n9.c (revision 883fb6be)
1 #ifndef lint
2 static char sccsid[] = "@(#)n9.c	4.2 07/07/86";
3 #endif lint
4 
5 #include "tdef.h"
6 extern
7 #include "d.h"
8 extern
9 #include "v.h"
10 #ifdef NROFF
11 extern
12 #include "tw.h"
13 #endif
14 /*
15 troff9.c
16 
17 misc functions
18 */
19 
20 extern int cbuf[];
21 extern int *cp;
22 extern int ch;
23 extern int chbits;
24 extern int dfact;
25 extern int vflag;
26 extern int pts;
27 extern int fc;
28 extern int padc;
29 extern int tabtab[];
30 extern int nlflg;
31 extern int lss;
32 extern int tabch, ldrch;
33 extern int tabc, dotc;
34 extern int nchar, rchar;
35 extern int xxx;
36 
37 setz(){
38 	register i;
39 
40 	if(!((i = getch()) & MOT))i |= ZBIT;
41 	return(i);
42 }
43 setline(){
44 	register *i, length, c;
45 	int w, cnt, delim, rem, temp;
46 
47 	if((delim = getch()) & MOT)return;
48 		else delim &= CMASK;
49 	vflag = 0;
50 	dfact = EM;
51 	length = quant(atoi(),HOR);
52 	dfact = 1;
53 	if(!length){
54 		eat(delim);
55 		return;
56 	}
57 s0:
58 	if(((c = getch()) & CMASK) == delim){
59 		ch = c;
60 		c = 0204 | chbits;
61 	}else if((c & CMASK) == FILLER)goto s0;
62 	w = width(c);
63 	i = cbuf;
64 	if(length < 0){
65 		*i++ = makem(length);
66 		length = -length;
67 	}
68 	if(!(cnt = length/w)){
69 		*i++ = makem(-(temp = ((w-length)/2)));
70 		*i++ = c;
71 		*i++ = makem(-(w - length - temp));
72 		goto s1;
73 	}
74 	if(rem = length%w){
75 		switch(c & CMASK){
76 			case 0204: /*rule*/
77 			case 0224: /*underrule*/
78 			case 0276: /*root en*/
79 				*i++ = c | ZBIT;
80 			default:
81 				*i++ = makem(rem);
82 		}
83 	}
84 	if(cnt){
85 		*i++ = RPT;
86 		*i++ = cnt;
87 		*i++ = c;
88 	}
89 s1:
90 	*i++ = 0;
91 	eat(delim);
92 	cp = cbuf;
93 }
94 eat(c)
95 int c;
96 {
97 	register i;
98 
99 	while(((i = getch() & CMASK) != c) &&
100 		(i != '\n'));
101 	return(i);
102 }
103 setov(){
104 	register i, j, k;
105 	int *p, delim, o[NOV+1], w[NOV+1];
106 
107 	if((delim = getch()) & MOT)return;
108 		else delim &= CMASK;
109 	for(k=0; (k<NOV) && ((j=(i = getch()) & CMASK) != delim) &&
110 		(j != '\n'); k++){
111 			o[k] = i;
112 			w[k] = width(i);
113 	}
114 	o[k] = w[k] = 0;
115 	if(o[0])for(j=1; j;){
116 		j = 0;
117 		for(k=1; o[k] ; k++){
118 			if(w[k-1] < w[k]){
119 				j++;
120 				i = w[k];
121 				w[k] = w[k-1];
122 				w[k-1] = i;
123 				i = o[k];
124 				o[k] = o[k-1];
125 				o[k-1] = i;
126 			}
127 		}
128 	}else return;
129 	p = cbuf;
130 	for(k=0; o[k]; k++){
131 		*p++ = o[k];
132 		*p++ = makem(-((w[k]+w[k+1])/2));
133 	}
134 	*p++ = makem(w[0]/2);
135 	*p = 0;
136 	cp = cbuf;
137 }
138 setbra(){
139 	register i, *j, k;
140 	int cnt, delim, dwn;
141 
142 	if((delim = getch()) & MOT)return;
143 		else delim &= CMASK;
144 	j = cbuf + 1;
145 	cnt = 0;
146 #ifdef NROFF
147 	dwn = (2*t.Halfline) | MOT | VMOT;
148 #endif
149 #ifndef NROFF
150 	dwn = EM | MOT | VMOT;
151 #endif
152 	while(((k = (i = getch()) & CMASK) != delim) && (k != '\n') &&
153 		(j <= (cbuf+NC-4))){
154 		*j++ = i | ZBIT;
155 		*j++ = dwn;
156 		cnt++;
157 	}
158 	if(--cnt < 0)return;
159 		else if (!cnt){
160 			ch = *(j-2);
161 			return;
162 	}
163 	*j = 0;
164 #ifdef NROFF
165 	*--j = *cbuf = (cnt*t.Halfline) | MOT | NMOT | VMOT;
166 #endif
167 #ifndef NROFF
168 	*--j = *cbuf = (cnt*EM)/2 | MOT | NMOT | VMOT;
169 #endif
170 	*--j &= ~ZBIT;
171 	cp = cbuf;
172 }
173 setvline(){
174 	register i, c, *k;
175 	int cnt, neg, rem, ver, delim;
176 
177 	if((delim = getch()) & MOT)return;
178 		else delim &= CMASK;
179 	dfact = lss;
180 	vflag++;
181 	i = quant(atoi(),VERT);
182 	dfact = 1;
183 	if(!i){
184 		eat(delim);
185 		vflag = 0;
186 		return;
187 	}
188 	if(((c = getch()) & CMASK) == delim){
189 		c = 0337 | chbits;	/*default box rule*/
190 	}else getch();
191 	c |= ZBIT;
192 	neg = 0;
193 	if(i < 0){
194 		i = -i;
195 		neg = NMOT;
196 	}
197 #ifdef NROFF
198 	ver = 2*t.Halfline;
199 #endif
200 #ifndef NROFF
201 	ver = EM;
202 #endif
203 	cnt = i/ver;
204 	rem = makem(i%ver) | neg;
205 	ver = makem(ver) | neg;
206 	k = cbuf;
207 	if(!neg)*k++ = ver;
208 	if(rem & ~MOTV){
209 		*k++ = c;
210 		*k++ = rem;
211 	}
212 	while((k < (cbuf+NC-3)) && cnt--){
213 		*k++ = c;
214 		*k++ = ver;
215 	}
216 	*(k-2) &= ~ZBIT;
217 	if(!neg)k--;
218 	*k = 0;
219 	cp = cbuf;
220 	vflag = 0;
221 }
222 casefc(){
223 	register i;
224 
225 	fc = IMP;
226 	padc = ' ';
227 	if(skip() ||
228 	   ((i = getch()) & MOT) ||
229 	   ((i &= CMASK) == '\n'))return;
230 	fc = i;
231 	if(skip() || (ch & MOT) || ((ch &= CMASK) == fc))return;
232 	padc = ch;
233 }
234 setfield(x)
235 int x;
236 {
237 	register i, j, *fp;
238 	int length, ws, npad, temp, type;
239 	int **pp, *padptr[NPP];
240 	static int fbuf[FBUFSZ];
241 	int savfc, savtc, savlc;
242 
243 	if(x == tabch) rchar = tabc | chbits;
244 	else if(x ==  ldrch) rchar = dotc | chbits;
245 	temp = npad = ws = 0;
246 	savfc = fc; savtc = tabch; savlc = ldrch;
247 	tabch = ldrch = fc = IMP;
248 	for(j=0;;j++){
249 		if((tabtab[j] & TMASK)== 0){
250 			if(x==savfc)prstr("Zero field width.\n");
251 			j = 0;
252 			goto rtn;
253 		}
254 		v.hp = sumhp();	/* XXX */
255 		if((length = ((tabtab[j] & TMASK) - v.hp)) > 0 )break;
256 	}
257 	type = tabtab[j] & (~TMASK);
258 	fp = fbuf;
259 	pp = padptr;
260 	if(x == savfc){while(1){
261 		if(((j = (i = getch()) & CMASK)) == padc){
262 			npad++;
263 			*pp++ = fp;
264 			if(pp > (padptr + NPP - 1))break;
265 			goto s1;
266 		}else if(j == savfc) break;
267 			else if(j == '\n'){
268 				temp = j;
269 				nlflg = 0;
270 				break;
271 			}
272 		ws += width(i);
273 	s1:
274 		*fp++ = i;
275 		if(fp > (fbuf + FBUFSZ -3))break;
276 	}
277 	if(!npad){
278 		npad++;
279 		*pp++ = fp;
280 		*fp++ = 0;
281 	}
282 	*fp++ = temp;
283 	*fp++ = 0;
284 	temp = i = (j = length-ws)/npad;
285 	i = (i/HOR)*HOR;
286 	if((j -= i*npad) <0)j = -j;
287 	i = makem(i);
288 	if(temp <0)i |= NMOT;
289 	for(;npad > 0; npad--){
290 		*(*--pp) = i;
291 		if(j){
292 			j -= HOR;
293 			(*(*pp)) += HOR;
294 		}
295 	}
296 	cp = fbuf;
297 	j = 0;
298 	}else if(type == 0){
299 	/*plain tab or leader*/
300 		if((j = width(rchar)) == 0)nchar = 0;
301 		else{
302 			nchar = length /j;
303 			length %= j;
304 		}
305 		if(length)j = length | MOT;
306 		else j = getch0();
307 	}else{
308 	/*center tab*/
309 	/*right tab*/
310 		while(((j = (i = getch()) & CMASK) != savtc) &&
311 			(j != '\n') && (j != savlc)){
312 			ws += width(i);
313 			*fp++ = i;
314 			if(fp > (fbuf +FBUFSZ - 3)) break;
315 		}
316 		*fp++ = i;
317 		*fp++ = 0;
318 		if(type == RTAB)length -= ws;
319 		else length -= ws/2; /*CTAB*/
320 		if(((j = width(rchar)) == 0) || (length <= 0))nchar = 0;
321 		else{
322 			nchar = length/j;
323 			length %= j;
324 		}
325 		length = (length/HOR)*HOR;
326 		j = makem(length);
327 		cp = fbuf;
328 		nlflg = 0;
329 	}
330 rtn:
331 	fc = savfc; tabch = savtc; ldrch = savlc;
332 	return(j);
333 }
334