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