tdef.h (18400B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <limits.h> 4 #include <ctype.h> 5 #include <string.h> 6 #include <unistd.h> 7 8 #undef MB_CUR_MAX 9 #define MB_CUR_MAX 3 10 11 #define NROFF (!TROFF) 12 13 /* Site dependent definitions */ 14 15 #ifndef TMACDIR 16 #define TMACDIR "lib/tmac/tmac." 17 #endif 18 #ifndef FONTDIR 19 #define FONTDIR "lib/font" 20 #endif 21 #ifndef NTERMDIR 22 #define NTERMDIR "lib/term/tab." 23 #endif 24 #ifndef TDEVNAME 25 #define TDEVNAME "post" 26 #endif 27 #ifndef NDEVNAME 28 #define NDEVNAME "37" 29 #endif 30 #ifndef TEXHYPHENS 31 #define TEXHYPHENS "/usr/lib/tex/macros/hyphen.tex" 32 #endif 33 #ifndef ALTHYPHENS 34 #define ALTHYPHENS "lib/tmac/hyphen.tex" /* another place to look */ 35 #endif 36 37 typedef unsigned char Uchar; 38 typedef unsigned short Ushort; 39 40 typedef /*unsigned*/ long Tchar; 41 42 typedef struct Blockp Blockp; 43 typedef struct Diver Diver; 44 typedef struct Stack Stack; 45 typedef struct Divsiz Divsiz; 46 typedef struct Contab Contab; 47 typedef struct Numtab Numtab; 48 typedef struct Numerr Numerr; 49 typedef struct Env Env; 50 typedef struct Term Term; 51 typedef struct Chwid Chwid; 52 typedef struct Font Font; 53 typedef struct Spnames Spnames; 54 typedef struct Wcache Wcache; 55 typedef struct Tbuf Tbuf; 56 57 /* this simulates printf into a buffer that gets flushed sporadically */ 58 /* the BSD goo is because SunOS sprintf doesn't return anything useful */ 59 60 #ifdef BSD4_2 61 #define OUT (obufp += strlen((sprintf)(obufp, 62 #define PUT ))) > obuf+BUFSIZ ? flusho() : 1 63 #else 64 #define OUT (obufp += (sprintf)(obufp, 65 #define PUT )) > obuf+BUFSIZ ? flusho() : 1 66 #endif 67 68 #define oputs(a) OUT "%s", a PUT 69 #define oput(c) ( *obufp++ = (c), obufp > obuf+BUFSIZ ? flusho() : 1 ) 70 71 extern char errbuf[]; 72 #define ERROR (sprintf)(errbuf, 73 #define WARN ), errprint() 74 #define FATAL ), errprint(), exit(1) 75 76 /* starting values for typesetting parameters: */ 77 78 #define PS 10 /* default point size */ 79 #define FT 1 /* default font position */ 80 #define ULFONT 2 /* default underline font */ 81 #define BDFONT 3 /* default emboldening font */ 82 #define BIFONT 4 /* default bold italic font */ 83 #define LL (unsigned) 65*INCH/10 /* line length; 39picas=6.5in */ 84 #define VS ((12*INCH)/72) /* initial vert space */ 85 86 87 #define EMPTS(pts) (((long)Inch*(pts) + 36) / 72) 88 #define EM (TROFF? EMPTS(pts): t.Em) 89 #define INCH (TROFF? Inch: 240) 90 #define HOR (TROFF? Hor: t.Adj) 91 #define VERT (TROFF? Vert: t.Vert) 92 #define PO (TROFF? Inch: 0) 93 #define SPS (TROFF? EMPTS(pts)/3: INCH/10) 94 #define SS (TROFF? 12: INCH/10) 95 #define ICS (TROFF? EMPTS(pts): 2*INCH/10) 96 #define DTAB (TROFF? (INCH/2): 0) 97 98 /* These "characters" are used to encode various internal functions 99 /* Some make use of the fact that most ascii characters between 100 /* 0 and 040 don't have any graphic or other function. 101 /* The few that do have a purpose (e.g., \n, \b, \t, ... 102 /* are avoided by the ad hoc choices here. 103 /* See ifilt[] in n1.c for others -- 1, 2, 3, 5, 6, 7, 010, 011, 012 104 */ 105 106 #define LEADER 001 107 #define IMP 004 /* impossible char; glues things together */ 108 #define TAB 011 109 #define RPT 014 /* next character is to be repeated many times */ 110 #define CHARHT 015 /* size field sets character height */ 111 #define SLANT 016 /* size field sets amount of slant */ 112 #define DRAWFCN 017 /* next several chars describe arb drawing fcns */ 113 # define DRAWLINE 'l' /* line: 'l' dx dy char */ 114 # define DRAWCIRCLE 'c' /* circle: 'c' r */ 115 # define DRAWELLIPSE 'e' /* ellipse: 'e' rx ry */ 116 # define DRAWARC 'a' /* arc: 'a' dx dy dx dy */ 117 # define DRAWSPLINE '~' /* quadratic B spline: '~' dx dy dx dy ... */ 118 /* other splines go thru too */ 119 /* NOTE: the use of ~ is a botch since it's often used in .tr commands */ 120 /* better to use a letter like s, but change it in the postprocessors too */ 121 /* for now, this is taken care of in n9.c and t10.c */ 122 # define DRAWBUILD 'b' /* built-up character (e.g., { */ 123 124 #define LEFT 020 /* \{ */ 125 #define RIGHT 021 /* \} */ 126 #define FILLER 022 /* \& and similar purposes */ 127 #define XON 023 /* \X'...' starts here */ 128 #define OHC 024 /* optional hyphenation character \% */ 129 #define CONT 025 /* \c character */ 130 #define PRESC 026 /* printable escape */ 131 #define UNPAD 027 /* unpaddable blank */ 132 #define XPAR 030 /* transparent mode indicator */ 133 #define FLSS 031 /* next Tchar contains vertical space */ 134 /* used when recalling diverted text */ 135 #define WORDSP 032 /* paddable word space */ 136 #define ESC 033 /* current escape character */ 137 #define XOFF 034 /* \X'...' ends here */ 138 /* matches XON, but they will probably never nest */ 139 /* so could drop this when another control is needed */ 140 #define HX 035 /* next character is value of \x'...' */ 141 #define MOTCH 036 /* this "character" is really motion; used by cbits() */ 142 143 #define HYPHEN c_hyphen 144 #define EMDASH c_emdash /* \(em */ 145 #define RULE c_rule /* \(ru */ 146 #define MINUS c_minus /* minus sign on current font */ 147 #define LIG_FI c_fi /* \(ff */ 148 #define LIG_FL c_fl /* \(fl */ 149 #define LIG_FF c_ff /* \(ff */ 150 #define LIG_FFI c_ffi /* \(Fi */ 151 #define LIG_FFL c_ffl /* \(Fl */ 152 #define ACUTE c_acute /* acute accent \(aa */ 153 #define GRAVE c_grave /* grave accent \(ga */ 154 #define UNDERLINE c_under /* \(ul */ 155 #define ROOTEN c_rooten /* root en \(rn */ 156 #define BOXRULE c_boxrule /* box rule \(br */ 157 #define LEFTHAND c_lefthand /* left hand for word overflow */ 158 #define DAGGER c_dagger /* dagger for end of sentence/footnote */ 159 160 #define HYPHALG 1 /* hyphenation algorithm: 0=>good old troff, 1=>tex */ 161 162 163 /* array sizes, and similar limits: */ 164 165 #define MAXFONTS 99 /* Maximum number of fonts in fontab */ 166 #define NM 91 /* requests + macros */ 167 #define NN NNAMES /* number registers */ 168 #define NNAMES 15 /* predefined reg names */ 169 #define NIF 15 /* if-else nesting */ 170 #define NS 128 /* name buffer */ 171 #define NTM 1024 /* tm buffer */ 172 #define NEV 3 /* environments */ 173 #define EVLSZ 10 /* size of ev stack */ 174 175 #define STACKSIZE (12*1024) /* stack for macros and strings in progress */ 176 #define NHYP 10 /* max hyphens per word */ 177 #define NHEX 512 /* byte size of exception word list */ 178 #define NTAB 100 /* tab stops */ 179 #define NSO 5 /* "so" depth */ 180 #define NMF 5 /* number of -m flags */ 181 #define WDSIZE 500 /* word buffer click size */ 182 #define LNSIZE 4000 /* line buffer click size */ 183 #define OLNSIZE 5000 /* output line buffer click; bigger for 'w', etc. */ 184 #define NDI 5 /* number of diversions */ 185 186 #define ALPHABET alphabet /* number of characters in basic alphabet. */ 187 /* 128 for parochial USA 7-bit ascii, */ 188 /* 256 for "European" mode with e.g., Latin-1 */ 189 190 /* NCHARS must be greater than 191 ALPHABET (ascii stuff) + total number of distinct char names 192 from all fonts that will be run in this job (including 193 unnamed ones and \N's) 194 */ 195 196 #define NCHARS (8*1024) /* maximum size of troff character set*/ 197 198 199 /* However for nroff you want only : 200 1. number of special codes in charset of DESC, which ends up being the 201 value of nchtab and which must be less than 512. 202 2. ALPHABET, which apparently is the size of the portion of the tables reserved 203 for special control symbols 204 Apparently the max N of \N is irrelevant; */ 205 /* to allow \N of up to 254 with up to 338 special characters 206 you need NCHARS of 338 + ALPHABET = 466 */ 207 208 #define NROFFCHARS 1024 /* maximum size of nroff character set */ 209 210 #define NTRTAB NCHARS /* number of items in trtab[] */ 211 #define NWIDCACHE NCHARS /* number of items in widcache[] */ 212 213 #define NTRAP 20 /* number of traps */ 214 #define NPN 20 /* numbers in "-o" */ 215 #define FBUFSZ 512 /* field buf size words */ 216 #define IBUFSZ 4096 /* bytes */ 217 #define NC 1024 /* cbuf size words */ 218 #define NOV 10 /* number of overstrike chars */ 219 #define NPP 10 /* pads per field */ 220 221 /* 222 Internal character representation: 223 Internally, every character is carried around as 224 a 32 bit cookie, called a "Tchar" (typedef long). 225 Bits are numbered 31..0 from left to right. 226 If bit 15 is 1, the character is motion, with 227 if bit 16 it's vertical motion 228 if bit 17 it's negative motion 229 If bit 15 is 0, the character is a real character. 230 if bit 31 zero motion 231 bits 30..24 size 232 bits 23..16 font 233 */ 234 235 /* in the following, "L" should really be a Tchar, but ... */ 236 /* numerology leaves room for 16 bit chars */ 237 238 #define MOT (01uL << 16) /* motion character indicator */ 239 #define VMOT (01uL << 30) /* vertical motion bit */ 240 #define NMOT (01uL << 29) /* negative motion indicator */ 241 /* #define MOTV (MOT|VMOT|NMOT) /* motion flags */ 242 /* #define MAXMOT (~MOTV) /* maximum motion permitted */ 243 #define MAXMOT 0xFFFF 244 245 #define ismot(n) ((n) & MOT) 246 #define isvmot(n) (((n) & (MOT|VMOT)) == (MOT|VMOT)) /* must have tested MOT previously */ 247 #define isnmot(n) (((n) & (MOT|NMOT)) == (MOT|NMOT)) /* ditto */ 248 #define absmot(n) ((n) & 0xFFFF) 249 250 #define ZBIT (01uL << 31) /* zero width char */ 251 #define iszbit(n) ((n) & ZBIT) 252 253 #define FSHIFT 17 254 #define SSHIFT (FSHIFT+7) 255 #define SMASK (0177uL << SSHIFT) /* 128 distinct sizes */ 256 #define FMASK (0177uL << FSHIFT) /* 128 distinct fonts */ 257 #define SFMASK (SMASK|FMASK) /* size and font in a Tchar */ 258 #define sbits(n) (((n) >> SSHIFT) & 0177) 259 #define fbits(n) (((n) >> FSHIFT) & 0177) 260 #define sfbits(n) (((n) & SFMASK) >> FSHIFT) 261 #define cbits(n) ((n) & 0x1FFFF) /* isolate character bits, */ 262 /* but don't include motions */ 263 extern int realcbits(Tchar); 264 265 #define setsbits(n,s) n = (n & ~SMASK) | (Tchar)(s) << SSHIFT 266 #define setfbits(n,f) n = (n & ~FMASK) | (Tchar)(f) << FSHIFT 267 #define setsfbits(n,sf) n = (n & ~SFMASK) | (Tchar)(sf) << FSHIFT 268 #define setcbits(n,c) n = (n & ~0xFFFFuL | (c)) /* set character bits */ 269 270 #define BYTEMASK 0377 271 #define BYTE 8 272 273 #define SHORTMASK 0XFFFF 274 #define SHORT 16 275 276 #define TABMASK ((unsigned) INT_MAX >> 1) 277 #define RTAB ((TABMASK << 1) & ~TABMASK) 278 #define CTAB (RTAB << 1) 279 280 #define TABBIT 02 /* bits in gchtab */ 281 #define LDRBIT 04 282 #define FCBIT 010 283 284 #define PAIR(A,B) (A|(B<<SHORT)) 285 286 287 extern int Inch, Hor, Vert, Unitwidth; 288 289 struct Spnames 290 { 291 int *n; 292 char *v; 293 }; 294 295 extern Spnames spnames[]; 296 297 /* 298 String and macro definitions are stored conceptually in a giant array 299 indexed by type Offset. In olden times, this array was real, and thus 300 both huge and limited in size, leading to the "Out of temp file space" 301 error. In this version, the array is represented by a list of blocks, 302 pointed to by blist[].bp. Each block is of size BLK Tchars, and BLK 303 MUST be a power of 2 for the macros below to work. 304 305 The blocks associated with a particular string or macro are chained 306 together in the array blist[]. Each blist[i].nextoff contains the 307 Offset associated with the next block in the giant array, or -1 if 308 this is the last block in the chain. If .nextoff is 0, the block is 309 free. 310 311 To find the right index in blist for an Offset, divide by BLK. 312 */ 313 314 #define NBLIST 2048 /* starting number of blocks in all definitions */ 315 316 #define BLK 128 /* number of Tchars in a block; must be 2^N with defns below */ 317 318 #define rbf0(o) (blist[bindex(o)].bp[boffset(o)]) 319 #define bindex(o) ((o) / BLK) 320 #define boffset(o) ((o) & (BLK-1)) 321 #define pastend(o) (((o) & (BLK-1)) == 0) 322 /* #define incoff(o) ( (++o & (BLK-1)) ? o : blist[bindex(o-1)].nextoff ) */ 323 #define incoff(o) ( (((o)+1) & (BLK-1)) ? o+1 : blist[bindex(o)].nextoff ) 324 325 #define skipline(f) while (getc(f) != '\n') 326 #define is(s) (strcmp(cmd, s) == 0) 327 #define eq(s1, s2) (strcmp(s1, s2) == 0) 328 329 330 typedef unsigned long Offset; /* an offset in macro/string storage */ 331 332 struct Blockp { /* info about a block: */ 333 Tchar *bp; /* the data */ 334 Offset nextoff; /* offset of next block in a chain */ 335 }; 336 337 extern Blockp *blist; 338 339 #define RD_OFFSET (1 * BLK) /* .rd command uses block 1 */ 340 341 struct Diver { /* diversion */ 342 Offset op; 343 int dnl; 344 int dimac; 345 int ditrap; 346 int ditf; 347 int alss; 348 int blss; 349 int nls; 350 int mkline; 351 int maxl; 352 int hnl; 353 int curd; 354 }; 355 356 struct Stack { /* stack frame */ 357 int nargs; 358 Stack *pframe; 359 Offset pip; 360 int pnchar; 361 Tchar prchar; 362 int ppendt; 363 Tchar pch; 364 Tchar *lastpbp; 365 int mname; 366 }; 367 368 extern Stack s; 369 370 struct Divsiz { 371 int dix; 372 int diy; 373 }; 374 375 struct Contab { /* command or macro */ 376 unsigned int rq; 377 Contab *link; 378 void (*f)(void); 379 Offset mx; 380 Offset emx; 381 Divsiz *divsiz; 382 }; 383 384 #define C(a,b) {a, 0, b, 0, 0} /* how to initialize a contab entry */ 385 386 extern Contab contab[NM]; 387 388 struct Numtab { /* number registers */ 389 unsigned int r; /* name */ 390 int val; 391 short fmt; 392 short inc; 393 Numtab *link; 394 }; 395 396 extern Numtab numtab[NN]; 397 398 #define PN 0 399 #define NL 1 400 #define YR 2 401 #define HP 3 402 #define CT 4 403 #define DN 5 404 #define MO 6 405 #define DY 7 406 #define DW 8 407 #define LN 9 408 #define DL 10 409 #define ST 11 410 #define SB 12 411 #define CD 13 412 #define PID 14 413 414 struct Wcache { /* width cache, indexed by character */ 415 short fontpts; 416 short width; 417 }; 418 419 struct Tbuf { /* growable Tchar buffer */ 420 Tchar *_bufp; 421 unsigned int _size; 422 }; 423 424 /* the infamous environment block */ 425 426 #define ics envp->_ics 427 #define sps envp->_sps 428 #define spacesz envp->_spacesz 429 #define lss envp->_lss 430 #define lss1 envp->_lss1 431 #define ll envp->_ll 432 #define ll1 envp->_ll1 433 #define lt envp->_lt 434 #define lt1 envp->_lt1 435 #define ic envp->_ic 436 #define icf envp->_icf 437 #define chbits envp->_chbits 438 #define spbits envp->_spbits 439 #define nmbits envp->_nmbits 440 #define apts envp->_apts 441 #define apts1 envp->_apts1 442 #define pts envp->_pts 443 #define pts1 envp->_pts1 444 #define font envp->_font 445 #define font1 envp->_font1 446 #define ls envp->_ls 447 #define ls1 envp->_ls1 448 #define ad envp->_ad 449 #define nms envp->_nms 450 #define ndf envp->_ndf 451 #define nmwid envp->_nmwid 452 #define fi envp->_fi 453 #define cc envp->_cc 454 #define c2 envp->_c2 455 #define ohc envp->_ohc 456 #define tdelim envp->_tdelim 457 #define hyf envp->_hyf 458 #define hyoff envp->_hyoff 459 #define hyphalg envp->_hyphalg 460 #define un1 envp->_un1 461 #define tabc envp->_tabc 462 #define dotc envp->_dotc 463 #define adsp envp->_adsp 464 #define adrem envp->_adrem 465 #define lastl envp->_lastl 466 #define nel envp->_nel 467 #define admod envp->_admod 468 #define wordp envp->_wordp 469 #define spflg envp->_spflg 470 #define linep envp->_linep 471 #define wdend envp->_wdend 472 #define wdstart envp->_wdstart 473 #define wne envp->_wne 474 #define ne envp->_ne 475 #define nc envp->_nc 476 #define nb envp->_nb 477 #define lnmod envp->_lnmod 478 #define nwd envp->_nwd 479 #define nn envp->_nn 480 #define ni envp->_ni 481 #define ul envp->_ul 482 #define cu envp->_cu 483 #define ce envp->_ce 484 #define in envp->_in 485 #define in1 envp->_in1 486 #define un envp->_un 487 #define wch envp->_wch 488 #define pendt envp->_pendt 489 #define pendw envp->_pendw 490 #define pendnf envp->_pendnf 491 #define spread envp->_spread 492 #define it envp->_it 493 #define itmac envp->_itmac 494 #define hyptr envp->_hyptr 495 #define tabtab envp->_tabtab 496 #define line envp->_line._bufp 497 #define lnsize envp->_line._size 498 #define word envp->_word._bufp 499 #define wdsize envp->_word._size 500 501 #define oline _oline._bufp 502 #define olnsize _oline._size 503 504 /* 505 * Note: 506 * If this structure changes in ni.c, you must change 507 * this as well, and vice versa. 508 */ 509 510 struct Env { 511 int _ics; 512 int _sps; 513 int _spacesz; 514 int _lss; 515 int _lss1; 516 int _ll; 517 int _ll1; 518 int _lt; 519 int _lt1; 520 Tchar _ic; 521 int _icf; 522 Tchar _chbits; 523 Tchar _spbits; 524 Tchar _nmbits; 525 int _apts; 526 int _apts1; 527 int _pts; 528 int _pts1; 529 int _font; 530 int _font1; 531 int _ls; 532 int _ls1; 533 int _ad; 534 int _nms; 535 int _ndf; 536 int _nmwid; 537 int _fi; 538 int _cc; 539 int _c2; 540 int _ohc; 541 int _tdelim; 542 int _hyf; 543 int _hyoff; 544 int _hyphalg; 545 int _un1; 546 int _tabc; 547 int _dotc; 548 int _adsp; 549 int _adrem; 550 int _lastl; 551 int _nel; 552 int _admod; 553 Tchar *_wordp; 554 int _spflg; 555 Tchar *_linep; 556 Tchar *_wdend; 557 Tchar *_wdstart; 558 int _wne; 559 int _ne; 560 int _nc; 561 int _nb; 562 int _lnmod; 563 int _nwd; 564 int _nn; 565 int _ni; 566 int _ul; 567 int _cu; 568 int _ce; 569 int _in; 570 int _in1; 571 int _un; 572 int _wch; 573 int _pendt; 574 Tchar *_pendw; 575 int _pendnf; 576 int _spread; 577 int _it; 578 int _itmac; 579 Tchar *_hyptr[NHYP]; 580 long _tabtab[NTAB]; 581 Tbuf _line; 582 Tbuf _word; 583 }; 584 585 extern Env env[]; 586 extern Env *envp; 587 588 enum { MBchar = 'U', Troffchar = 'C', Number = 'N', Install = 'i', Lookup = 'l' }; 589 /* U => utf, for instance; C => \(xx, N => \N'...' */ 590 591 592 593 struct Chwid { /* data on one character */ 594 Ushort num; /* character number: 595 0 -> not on this font 596 >= ALPHABET -> its number among all Cxy's */ 597 Ushort code; /* char code for actual device. used for \N */ 598 char *str; /* code string for nroff */ 599 Uchar wid; /* width */ 600 Uchar kern; /* ascender/descender */ 601 }; 602 603 struct Font { /* characteristics of a font */ 604 int name; /* int name, e.g., BI (2 chars) */ 605 char longname[64]; /* long name of this font (e.g., "Bembo" */ 606 char *truename; /* path name of table if not in standard place */ 607 int nchars; /* number of width entries for this font */ 608 char specfont; /* 1 == special font */ 609 int spacewidth; /* width of space on this font */ 610 int defaultwidth; /* default width of characters on this font */ 611 Chwid *wp; /* widths, etc., of the real characters */ 612 char ligfont; /* 1 == ligatures exist on this font */ 613 }; 614 615 /* ligatures, ORed into ligfont */ 616 617 #define LFF 01 618 #define LFI 02 619 #define LFL 04 620 #define LFFI 010 621 #define LFFL 020 622 623 /* tracing modes */ 624 #define TRNARGS 01 /* trace legality of numeric arguments */ 625 #define TRREQ 02 /* trace requests */ 626 #define TRMAC 04 /* trace macros */ 627 #define RQERR 01 /* processing request/macro */ 628 629 /* typewriter driving table structure */ 630 631 632 extern Term t; 633 struct Term { 634 int bset; /* these bits have to be on */ 635 int breset; /* these bits have to be off */ 636 int Hor; /* #units in minimum horiz motion */ 637 int Vert; /* #units in minimum vert motion */ 638 int Newline; /* #units in single line space */ 639 int Char; /* #units in character width */ 640 int Em; /* ditto */ 641 int Halfline; /* half line units */ 642 int Adj; /* minimum units for horizontal adjustment */ 643 char *twinit; /* initialize terminal */ 644 char *twrest; /* reinitialize terminal */ 645 char *twnl; /* terminal sequence for newline */ 646 char *hlr; /* half-line reverse */ 647 char *hlf; /* half-line forward */ 648 char *flr; /* full-line reverse */ 649 char *bdon; /* turn bold mode on */ 650 char *bdoff; /* turn bold mode off */ 651 char *iton; /* turn italic mode on */ 652 char *itoff; /* turn italic mode off */ 653 char *ploton; /* turn plot mode on */ 654 char *plotoff; /* turn plot mode off */ 655 char *up; /* sequence to move up in plot mode */ 656 char *down; /* ditto */ 657 char *right; /* ditto */ 658 char *left; /* ditto */ 659 660 Font tfont; /* widths and other info, as in a troff font */ 661 }; 662 663 extern Term t; 664 665 /* 666 * for error reporting; keep track of escapes/requests with numeric arguments 667 */ 668 struct Numerr { 669 char type; /* request or escape? */ 670 char esc; /* was escape sequence named esc */ 671 char escarg; /* argument of esc's like \D'l' */ 672 unsigned int req; /* was request or macro named req */ 673 };