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