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