1 /* $MirOS: src/usr.bin/oldroff/nroff/n9.c,v 1.3 2008/11/08 23:04:42 tg Exp $ */
2 
3 /*-
4  * Copyright (c) 1979, 1980, 1981, 1986, 1988, 1990, 1991, 1992
5  *     The Regents of the University of California.
6  * Copyright (C) Caldera International Inc.  2001-2002.
7  * Copyright (c) 2003, 2004
8  *	Thorsten "mirabilos" Glaser <tg@mirbsd.org>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms,
12  * with or without modification, are permitted provided
13  * that the following conditions are met:
14  *
15  * Redistributions of source code and documentation must retain
16  * the above copyright notice, this list of conditions and the
17  * following disclaimer.  Redistributions in binary form must
18  * reproduce the above copyright notice, this list of conditions
19  * and the following disclaimer in the documentation and/or other
20  * materials provided with the distribution.
21  *
22  * All advertising materials mentioning features or use of this
23  * software must display the following acknowledgement:
24  *   This product includes software developed or owned by
25  *   Caldera International, Inc.
26  *
27  * Neither the name of Caldera International, Inc. nor the names
28  * of other contributors may be used to endorse or promote products
29  * derived from this software without specific prior written permission.
30  *
31  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
32  * INTERNATIONAL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
33  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35  * ARE DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE
36  * LIABLE FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR
37  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
41  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
42  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  */
44 
45 #include <sys/cdefs.h>
46 __SCCSID("@(#)n9.c	4.3 (Berkeley) 4/18/91");
47 __RCSID("$MirOS: src/usr.bin/oldroff/nroff/n9.c,v 1.3 2008/11/08 23:04:42 tg Exp $");
48 
49 #include "tdef.h"
50 extern
51 #include "d.h"
52 extern
53 #include "v.h"
54 #ifdef NROFF
55 extern
56 #include "tw.h"
57 #endif
58 /*
59 troff9.c
60 
61 misc functions
62 */
63 
64 extern int cbuf[];
65 extern int *cp;
66 extern int ch;
67 extern int chbits;
68 extern int dfact;
69 extern int vflag;
70 extern int pts;
71 extern int fc;
72 extern int padc;
73 extern int tabtab[];
74 extern int nlflg;
75 extern int lss;
76 extern int tabch, ldrch;
77 extern int tabc, dotc;
78 extern int nchar, rchar;
79 extern int xxx;
80 
setz()81 setz(){
82 	register i;
83 
84 	if(!((i = getch()) & MOT))i |= ZBIT;
85 	return(i);
86 }
setline()87 setline(){
88 	register *i, length, c;
89 	int w, cnt, delim, rem, temp;
90 
91 	if((delim = getch()) & MOT)return;
92 		else delim &= CMASK;
93 	vflag = 0;
94 	dfact = EM;
95 	length = quant(nr_atoi(),HOR);
96 	dfact = 1;
97 	if(!length){
98 		eat(delim);
99 		return;
100 	}
101 s0:
102 	if(((c = getch()) & CMASK) == delim){
103 		ch = c;
104 		c = 0204 | chbits;
105 	}else if((c & CMASK) == FILLER)goto s0;
106 	w = width(c);
107 	i = cbuf;
108 	if(length < 0){
109 		*i++ = makem(length);
110 		length = -length;
111 	}
112 	if(!(cnt = length/w)){
113 		*i++ = makem(-(temp = ((w-length)/2)));
114 		*i++ = c;
115 		*i++ = makem(-(w - length - temp));
116 		goto s1;
117 	}
118 	if(rem = length%w){
119 		switch(c & CMASK){
120 			case 0204: /*rule*/
121 			case 0224: /*underrule*/
122 			case 0276: /*root en*/
123 				*i++ = c | ZBIT;
124 			default:
125 				*i++ = makem(rem);
126 		}
127 	}
128 	if(cnt){
129 		*i++ = RPT;
130 		*i++ = cnt;
131 		*i++ = c;
132 	}
133 s1:
134 	*i++ = 0;
135 	eat(delim);
136 	cp = cbuf;
137 }
eat(c)138 eat(c)
139 int c;
140 {
141 	register i;
142 
143 	while(((i = getch() & CMASK) != c) &&
144 		(i != '\n'));
145 	return(i);
146 }
setov()147 setov(){
148 	register i, j, k;
149 	int *p, delim, o[NOV+1], w[NOV+1];
150 
151 	if((delim = getch()) & MOT)return;
152 		else delim &= CMASK;
153 	for(k=0; (k<NOV) && ((j=(i = getch()) & CMASK) != delim) &&
154 		(j != '\n'); k++){
155 			o[k] = i;
156 			w[k] = width(i);
157 	}
158 	o[k] = w[k] = 0;
159 	if(o[0])for(j=1; j;){
160 		j = 0;
161 		for(k=1; o[k] ; k++){
162 			if(w[k-1] < w[k]){
163 				j++;
164 				i = w[k];
165 				w[k] = w[k-1];
166 				w[k-1] = i;
167 				i = o[k];
168 				o[k] = o[k-1];
169 				o[k-1] = i;
170 			}
171 		}
172 	}else return;
173 	p = cbuf;
174 	for(k=0; o[k]; k++){
175 		*p++ = o[k];
176 		*p++ = makem(-((w[k]+w[k+1])/2));
177 	}
178 	*p++ = makem(w[0]/2);
179 	*p = 0;
180 	cp = cbuf;
181 }
setbra()182 setbra(){
183 	register i, *j, k;
184 	int cnt, delim, dwn;
185 
186 	if((delim = getch()) & MOT)return;
187 		else delim &= CMASK;
188 	j = cbuf + 1;
189 	cnt = 0;
190 #ifdef NROFF
191 	dwn = (2*t.Halfline) | MOT | VMOT;
192 #endif
193 #ifndef NROFF
194 	dwn = EM | MOT | VMOT;
195 #endif
196 	while(((k = (i = getch()) & CMASK) != delim) && (k != '\n') &&
197 		(j <= (cbuf+NC-4))){
198 		*j++ = i | ZBIT;
199 		*j++ = dwn;
200 		cnt++;
201 	}
202 	if(--cnt < 0)return;
203 		else if (!cnt){
204 			ch = *(j-2);
205 			return;
206 	}
207 	*j = 0;
208 #ifdef NROFF
209 	*--j = *cbuf = (cnt*t.Halfline) | MOT | NMOT | VMOT;
210 #endif
211 #ifndef NROFF
212 	*--j = *cbuf = (cnt*EM)/2 | MOT | NMOT | VMOT;
213 #endif
214 	*--j &= ~ZBIT;
215 	cp = cbuf;
216 }
setvline()217 setvline(){
218 	register i, c, *k;
219 	int cnt, neg, rem, ver, delim;
220 
221 	if((delim = getch()) & MOT)return;
222 		else delim &= CMASK;
223 	dfact = lss;
224 	vflag++;
225 	i = quant(nr_atoi(),VERT);
226 	dfact = 1;
227 	if(!i){
228 		eat(delim);
229 		vflag = 0;
230 		return;
231 	}
232 	if(((c = getch()) & CMASK) == delim){
233 		c = 0337 | chbits;	/*default box rule*/
234 	}else getch();
235 	c |= ZBIT;
236 	neg = 0;
237 	if(i < 0){
238 		i = -i;
239 		neg = NMOT;
240 	}
241 #ifdef NROFF
242 	ver = 2*t.Halfline;
243 #endif
244 #ifndef NROFF
245 	ver = EM;
246 #endif
247 	cnt = i/ver;
248 	rem = makem(i%ver) | neg;
249 	ver = makem(ver) | neg;
250 	k = cbuf;
251 	if(!neg)*k++ = ver;
252 	if(rem & ~MOTV){
253 		*k++ = c;
254 		*k++ = rem;
255 	}
256 	while((k < (cbuf+NC-3)) && cnt--){
257 		*k++ = c;
258 		*k++ = ver;
259 	}
260 	*(k-2) &= ~ZBIT;
261 	if(!neg)k--;
262 	*k = 0;
263 	cp = cbuf;
264 	vflag = 0;
265 }
casefc()266 casefc(){
267 	register i;
268 
269 	fc = IMP;
270 	padc = ' ';
271 	if(skip() ||
272 	   ((i = getch()) & MOT) ||
273 	   ((i &= CMASK) == '\n'))return;
274 	fc = i;
275 	if(skip() || (ch & MOT) || ((ch &= CMASK) == fc))return;
276 	padc = ch;
277 }
setfield(x)278 setfield(x)
279 int x;
280 {
281 	register i, j, *fp;
282 	int length, ws, npad, temp, type;
283 	int **pp, *padptr[NPP];
284 	static int fbuf[FBUFSZ];
285 	int savfc, savtc, savlc;
286 
287 	if(x == tabch) rchar = tabc | chbits;
288 	else if(x ==  ldrch) rchar = dotc | chbits;
289 	temp = npad = ws = 0;
290 	savfc = fc; savtc = tabch; savlc = ldrch;
291 	tabch = ldrch = fc = IMP;
292 	for(j=0;;j++){
293 		if((tabtab[j] & TMASK)== 0){
294 			if(x==savfc)prstr("Zero field width.\n");
295 			j = 0;
296 			goto rtn;
297 		}
298 		v.hp = sumhp();	/* XXX */
299 		if((length = ((tabtab[j] & TMASK) - v.hp)) > 0 )break;
300 	}
301 	type = tabtab[j] & (~TMASK);
302 	fp = fbuf;
303 	pp = padptr;
304 	if(x == savfc){while(1){
305 		if(((j = (i = getch()) & CMASK)) == padc){
306 			npad++;
307 			*pp++ = fp;
308 			if(pp > (padptr + NPP - 1))break;
309 			goto s1;
310 		}else if(j == savfc) break;
311 			else if(j == '\n'){
312 				temp = j;
313 				nlflg = 0;
314 				break;
315 			}
316 		ws += width(i);
317 	s1:
318 		*fp++ = i;
319 		if(fp > (fbuf + FBUFSZ -3))break;
320 	}
321 	if(!npad){
322 		npad++;
323 		*pp++ = fp;
324 		*fp++ = 0;
325 	}
326 	*fp++ = temp;
327 	*fp++ = 0;
328 	temp = i = (j = length-ws)/npad;
329 	i = (i/HOR)*HOR;
330 	if((j -= i*npad) <0)j = -j;
331 	i = makem(i);
332 	if(temp <0)i |= NMOT;
333 	for(;npad > 0; npad--){
334 		*(*--pp) = i;
335 		if(j){
336 			j -= HOR;
337 			(*(*pp)) += HOR;
338 		}
339 	}
340 	cp = fbuf;
341 	j = 0;
342 	}else if(type == 0){
343 	/*plain tab or leader*/
344 		if((j = width(rchar)) == 0)nchar = 0;
345 		else{
346 			nchar = length /j;
347 			length %= j;
348 		}
349 		if(length)j = length | MOT;
350 		else j = getch0();
351 	}else{
352 	/*center tab*/
353 	/*right tab*/
354 		while(((j = (i = getch()) & CMASK) != savtc) &&
355 			(j != '\n') && (j != savlc)){
356 			ws += width(i);
357 			*fp++ = i;
358 			if(fp > (fbuf +FBUFSZ - 3)) break;
359 		}
360 		*fp++ = i;
361 		*fp++ = 0;
362 		if(type == RTAB)length -= ws;
363 		else length -= ws/2; /*CTAB*/
364 		if(((j = width(rchar)) == 0) || (length <= 0))nchar = 0;
365 		else{
366 			nchar = length/j;
367 			length %= j;
368 		}
369 		length = (length/HOR)*HOR;
370 		j = makem(length);
371 		cp = fbuf;
372 		nlflg = 0;
373 	}
374 rtn:
375 	fc = savfc; tabch = savtc; ldrch = savlc;
376 	return(j);
377 }
378