1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 #include <libintl.h> 43 #include <stdlib.h> 44 45 #include "tdef.h" 46 #ifdef NROFF 47 #include "tw.h" 48 #endif 49 #include "ext.h" 50 #ifdef EUC 51 #include <locale.h> 52 #include <wctype.h> 53 #include <langinfo.h> 54 55 #define ISO646 "646" 56 57 int multi_locale; 58 int (*wdbdg)(wchar_t, wchar_t, int); 59 wchar_t *(*wddlm)(wchar_t, wchar_t, int); 60 61 int csi_width[4] = { 62 1, 63 1, 64 2, 65 3, 66 }; 67 #endif /* EUC */ 68 69 /* 70 * troff9.c 71 * 72 * misc functions 73 */ 74 75 tchar setz() 76 { 77 tchar i; 78 79 if (!ismot(i = getch())) 80 i |= ZBIT; 81 return(i); 82 } 83 84 int 85 setline() 86 { 87 tchar *i; 88 tchar c; 89 int length; 90 int w, cnt, delim, rem, temp; 91 tchar linebuf[NC]; 92 93 if (ismot(c = getch())) 94 return (0); 95 delim = cbits(c); 96 vflag = 0; 97 dfact = EM; 98 length = quant(atoi(), HOR); 99 dfact = 1; 100 if (!length) { 101 eat(delim); 102 return (0); 103 } 104 s0: 105 if ((cbits(c = getch())) == delim) { 106 ch = c; 107 c = RULE | chbits; 108 } else if (cbits(c) == FILLER) 109 goto s0; 110 w = width(c); 111 i = linebuf; 112 if (length < 0) { 113 *i++ = makem(length); 114 length = -length; 115 } 116 if (!(cnt = length / w)) { 117 *i++ = makem(-(temp = ((w - length) / 2))); 118 *i++ = c; 119 *i++ = makem(-(w - length - temp)); 120 goto s1; 121 } 122 if (rem = length % w) { 123 if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN) 124 *i++ = c | ZBIT; 125 *i++ = makem(rem); 126 } 127 if (cnt) { 128 *i++ = RPT; 129 *i++ = cnt; 130 *i++ = c; 131 } 132 s1: 133 *i++ = 0; 134 eat(delim); 135 pushback(linebuf); 136 137 return (0); 138 } 139 140 141 int 142 eat(c) 143 int c; 144 { 145 int i; 146 147 while ((i = cbits(getch())) != c && (i != '\n')) 148 ; 149 return(i); 150 } 151 152 153 int 154 setov() 155 { 156 int j, k; 157 tchar i, o[NOV]; 158 int delim, w[NOV]; 159 160 if (ismot(i = getch())) 161 return (0); 162 delim = cbits(i); 163 for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) && (j != '\n'); k++) { 164 o[k] = i; 165 w[k] = width(i); 166 } 167 o[k] = w[k] = 0; 168 if (o[0]) 169 for (j = 1; j; ) { 170 j = 0; 171 for (k = 1; o[k] ; k++) { 172 if (w[k-1] < w[k]) { 173 j++; 174 i = w[k]; 175 w[k] = w[k-1]; 176 w[k-1] = i; 177 i = o[k]; 178 o[k] = o[k-1]; 179 o[k-1] = i; 180 } 181 } 182 } 183 else 184 return (0); 185 *pbp++ = makem(w[0] / 2); 186 for (k = 0; o[k]; k++) 187 ; 188 while (k>0) { 189 k--; 190 *pbp++ = makem(-((w[k] + w[k+1]) / 2)); 191 *pbp++ = o[k]; 192 } 193 194 return (0); 195 } 196 197 198 int 199 setbra() 200 { 201 int k; 202 tchar i, *j, dwn; 203 int cnt, delim; 204 tchar brabuf[NC]; 205 206 if (ismot(i = getch())) 207 return (0); 208 delim = cbits(i); 209 j = brabuf + 1; 210 cnt = 0; 211 #ifdef NROFF 212 dwn = (2 * t.Halfline) | MOT | VMOT; 213 #endif 214 #ifndef NROFF 215 dwn = EM | MOT | VMOT; 216 #endif 217 while (((k = cbits(i = getch())) != delim) && (k != '\n') && (j <= (brabuf + NC - 4))) { 218 *j++ = i | ZBIT; 219 *j++ = dwn; 220 cnt++; 221 } 222 if (--cnt < 0) 223 return (0); 224 else if (!cnt) { 225 ch = *(j - 2); 226 return (0); 227 } 228 *j = 0; 229 #ifdef NROFF 230 *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT; 231 #endif 232 #ifndef NROFF 233 *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT; 234 #endif 235 *--j &= ~ZBIT; 236 pushback(brabuf); 237 238 return (0); 239 } 240 241 242 int 243 setvline() 244 { 245 int i; 246 tchar c, rem, ver, neg; 247 int cnt, delim, v; 248 tchar vlbuf[NC]; 249 tchar *vlp; 250 251 if (ismot(c = getch())) 252 return (0); 253 delim = cbits(c); 254 dfact = lss; 255 vflag++; 256 i = quant(atoi(), VERT); 257 dfact = 1; 258 if (!i) { 259 eat(delim); 260 vflag = 0; 261 return (0); 262 } 263 if ((cbits(c = getch())) == delim) { 264 c = BOXRULE | chbits; /*default box rule*/ 265 } else 266 getch(); 267 c |= ZBIT; 268 neg = 0; 269 if (i < 0) { 270 i = -i; 271 neg = NMOT; 272 } 273 #ifdef NROFF 274 v = 2 * t.Halfline; 275 #endif 276 #ifndef NROFF 277 v = EM; 278 #endif 279 cnt = i / v; 280 rem = makem(i % v) | neg; 281 ver = makem(v) | neg; 282 vlp = vlbuf; 283 if (!neg) 284 *vlp++ = ver; 285 if (absmot(rem) != 0) { 286 *vlp++ = c; 287 *vlp++ = rem; 288 } 289 while ((vlp < (vlbuf + NC - 3)) && cnt--) { 290 *vlp++ = c; 291 *vlp++ = ver; 292 } 293 *(vlp - 2) &= ~ZBIT; 294 if (!neg) 295 vlp--; 296 *vlp++ = 0; 297 pushback(vlbuf); 298 vflag = 0; 299 300 return (0); 301 } 302 303 #define NPAIR (NC/2-6) /* max pairs in spline, etc. */ 304 305 int 306 setdraw() /* generate internal cookies for a drawing function */ 307 { 308 int i, j, k, dx[NPAIR], dy[NPAIR], delim, type; 309 tchar c, drawbuf[NC]; 310 311 /* input is \D'f dx dy dx dy ... c' (or at least it had better be) */ 312 /* this does drawing function f with character c and the */ 313 /* specified dx,dy pairs interpreted as appropriate */ 314 /* pairs are deltas from last point, except for radii */ 315 316 /* l dx dy: line from here by dx,dy */ 317 /* c x: circle of diameter x, left side here */ 318 /* e x y: ellipse of diameters x,y, left side here */ 319 /* a dx1 dy1 dx2 dy2: 320 ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */ 321 /* ~ dx1 dy1 dx2 dy2...: 322 spline to dx1,dy1 to dx2,dy2 ... */ 323 /* f dx dy ...: f is any other char: like spline */ 324 325 if (ismot(c = getch())) 326 return (0); 327 delim = cbits(c); 328 type = cbits(getch()); 329 for (i = 0; i < NPAIR ; i++) { 330 c = getch(); 331 if (cbits(c) == delim) 332 break; 333 /* ought to pick up optional drawing character */ 334 if (cbits(c) != ' ') 335 ch = c; 336 vflag = 0; 337 dfact = EM; 338 dx[i] = quant(atoi(), HOR); 339 if (dx[i] > MAXMOT) 340 dx[i] = MAXMOT; 341 else if (dx[i] < -MAXMOT) 342 dx[i] = -MAXMOT; 343 if (cbits((c = getch())) == delim) { /* spacer */ 344 dy[i++] = 0; 345 break; 346 } 347 vflag = 1; 348 dfact = lss; 349 dy[i] = quant(atoi(), VERT); 350 if (dy[i] > MAXMOT) 351 dy[i] = MAXMOT; 352 else if (dy[i] < -MAXMOT) 353 dy[i] = -MAXMOT; 354 } 355 dfact = 1; 356 vflag = 0; 357 #ifndef NROFF 358 drawbuf[0] = DRAWFCN | chbits | ZBIT; 359 drawbuf[1] = type | chbits | ZBIT; 360 drawbuf[2] = '.' | chbits | ZBIT; /* use default drawing character */ 361 for (k = 0, j = 3; k < i; k++) { 362 drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k])); 363 drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k])); 364 } 365 if (type == DRAWELLIPSE) { 366 drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */ 367 j = 6; 368 } 369 drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */ 370 drawbuf[j] = 0; 371 pushback(drawbuf); 372 #endif 373 return (0); 374 } 375 376 377 int 378 casefc() 379 { 380 int i; 381 tchar j; 382 383 gchtab[fc] &= ~FCBIT; 384 fc = IMP; 385 padc = ' '; 386 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n') 387 return (0); 388 fc = i; 389 gchtab[fc] |= FCBIT; 390 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc) 391 return (0); 392 padc = ch; 393 394 return (0); 395 } 396 397 398 tchar 399 setfield(x) 400 int x; 401 { 402 tchar ii, jj, *fp; 403 int i, j; 404 int length, ws, npad, temp, type; 405 tchar **pp, *padptr[NPP]; 406 tchar fbuf[FBUFSZ]; 407 int savfc, savtc, savlc; 408 tchar rchar; 409 int savepos; 410 411 if (x == tabch) 412 rchar = tabc | chbits; 413 else if (x == ldrch) 414 rchar = dotc | chbits; 415 temp = npad = ws = 0; 416 savfc = fc; 417 savtc = tabch; 418 savlc = ldrch; 419 tabch = ldrch = fc = IMP; 420 savepos = numtab[HP].val; 421 gchtab[tabch] &= ~TABBIT; 422 gchtab[ldrch] &= ~LDRBIT; 423 gchtab[fc] &= ~FCBIT; 424 gchtab[IMP] |= TABBIT|LDRBIT|FCBIT; 425 for (j = 0; ; j++) { 426 if ((tabtab[j] & TABMASK) == 0) { 427 if (x == savfc) 428 errprint(gettext("zero field width.")); 429 jj = 0; 430 goto rtn; 431 } 432 if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 ) 433 break; 434 } 435 type = tabtab[j] & (~TABMASK); 436 fp = fbuf; 437 pp = padptr; 438 if (x == savfc) { 439 while (1) { 440 j = cbits(ii = getch()); 441 jj = width(ii); 442 widthp = jj; 443 numtab[HP].val += jj; 444 if (j == padc) { 445 npad++; 446 *pp++ = fp; 447 if (pp > (padptr + NPP - 1)) 448 break; 449 goto s1; 450 } else if (j == savfc) 451 break; 452 else if (j == '\n') { 453 temp = j; 454 nlflg = 0; 455 break; 456 } 457 ws += jj; 458 s1: 459 *fp++ = ii; 460 if (fp > (fbuf + FBUFSZ - 3)) 461 break; 462 } 463 if (!npad) { 464 npad++; 465 *pp++ = fp; 466 *fp++ = 0; 467 } 468 *fp++ = temp; 469 *fp++ = 0; 470 temp = i = (j = length - ws) / npad; 471 i = (i / HOR) * HOR; 472 if ((j -= i * npad) < 0) 473 j = -j; 474 ii = makem(i); 475 if (temp < 0) 476 ii |= NMOT; 477 for (; npad > 0; npad--) { 478 *(*--pp) = ii; 479 if (j) { 480 j -= HOR; 481 (*(*pp)) += HOR; 482 } 483 } 484 pushback(fbuf); 485 jj = 0; 486 } else if (type == 0) { 487 /*plain tab or leader*/ 488 if ((j = width(rchar)) > 0) { 489 int nchar = length / j; 490 while (nchar-->0 && pbp < &pbbuf[NC-3]) { 491 numtab[HP].val += j; 492 widthp = j; 493 *pbp++ = rchar; 494 } 495 length %= j; 496 } 497 if (length) 498 jj = length | MOT; 499 else 500 jj = getch0(); 501 } else { 502 /*center tab*/ 503 /*right tab*/ 504 while (((j = cbits(ii = getch())) != savtc) && (j != '\n') && (j != savlc)) { 505 jj = width(ii); 506 ws += jj; 507 numtab[HP].val += jj; 508 widthp = jj; 509 *fp++ = ii; 510 if (fp > (fbuf + FBUFSZ - 3)) 511 break; 512 } 513 *fp++ = ii; 514 *fp++ = 0; 515 if (type == RTAB) 516 length -= ws; 517 else 518 length -= ws / 2; /*CTAB*/ 519 pushback(fbuf); 520 if ((j = width(rchar)) != 0 && length > 0) { 521 int nchar = length / j; 522 while (nchar-- > 0 && pbp < &pbbuf[NC-3]) 523 *pbp++ = rchar; 524 length %= j; 525 } 526 length = (length / HOR) * HOR; 527 jj = makem(length); 528 nlflg = 0; 529 } 530 rtn: 531 gchtab[fc] &= ~FCBIT; 532 gchtab[tabch] &= ~TABBIT; 533 gchtab[ldrch] &= ~LDRBIT; 534 fc = savfc; 535 tabch = savtc; 536 ldrch = savlc; 537 gchtab[fc] |= FCBIT; 538 gchtab[tabch] = TABBIT; 539 gchtab[ldrch] |= LDRBIT; 540 numtab[HP].val = savepos; 541 return(jj); 542 } 543 544 545 #ifdef EUC 546 #ifdef NROFF 547 /* locale specific initialization */ 548 int localize() 549 { 550 extern int wdbindf(); 551 extern wchar_t *wddelim(); 552 char *codeset; 553 554 codeset = nl_langinfo(CODESET); 555 556 if (MB_CUR_MAX > 1) 557 multi_locale = 1; 558 else { 559 if (*codeset == '\0' || 560 (strcmp(codeset, ISO646) == 0)) { 561 /* 562 * if codeset is an empty string 563 * assumes this is C locale (7-bit) locale. 564 * This happens in 2.5, 2.5.1, and 2.6 system 565 * Or, if codeset is "646" 566 * this is 7-bit locale. 567 */ 568 multi_locale = 0; 569 } else { 570 /* 8-bit locale */ 571 multi_locale = 1; 572 } 573 574 } 575 wdbdg = wdbindf; 576 wddlm = wddelim; 577 578 return (0); 579 } 580 #endif /* EUC */ 581 #endif /* NROFF */ 582