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