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
setz()44 setz(){
45 register i;
46
47 if(!((i = getch()) & MOT))i |= ZBIT;
48 return(i);
49 }
setline()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 }
eat(c)101 eat(c)
102 int c;
103 {
104 register i;
105
106 while(((i = getch() & CMASK) != c) &&
107 (i != '\n'));
108 return(i);
109 }
setov()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 }
setbra()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 }
setvline()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 }
casefc()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 }
setfield(x)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