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