/*
 * roff.h - definitions for roff
 */
#include <stdio.h>
#include <ctype.h>

#define	PAGENUM '%'
#define	PAGEWIDTH 60
#define PAGELEN	66
#define	HUGE	10000

#define	LINESIZE	256

#define	TRUE	1
#define	FALSE	0

#define	MIN(x, y)	(((x) < (y)) ? (x) : (y))

/* commands */

#define	BP	1
#define BR	2
#define CE	3
#define	FI	4
#define	FO	5
#define	HE	6
#define	IND	7
#define	LS	8
#define	NF	9
#define	PL	10
#define	RM	11
#define	SP	12
#define	TI	14
#define	UL	15
#define	UNKNOWN	-1
			/* start of new commands */
#define SO	16	/* source input file */
#define DE	17	/* macro, definitions */
#define EN	18
#define	MACRO	19	/* have got a macro */

#define	FL	20	/* footer length */
#define HL	21	/* header length */

			/* odd and even headers */
#define	OH	22
#define	EH	23
#define	OF	24
#define	EF	25

#define	BO	26	/* boldify */
			/* registers, diversions, etc. */
#define	DS	27
#define AS	28
#define DI	29
#define	DA	30

#define WH	32	/* spring a macro */

#define	TL	33	/* a general title thing */

#define	NE	34	/* need N lines */

#define	NR	35	/* define a number register */
#define	AF	36	/* define format */

#define	IF	37	/* conditionals */
#define	EI	38
#define	EL	39

#define	EC	40	/* escape char processing */
#define	EO	41

#define	CH	42	/* change when position */

#define	SV	43	/* save vertical space */

#define	OS	44	/* output saved vertical space */

#define	PN	45	/* set next page number */
#define	AD	46	/* adjust */
#define	NA	47	/* no adjust */
#define	AM	48	/* append to macro */
#define	CC	49	/* control char1 */
#define	C2	50	/* control char2 */
#define	EM	51	/* end of input macro */

/*
 * argument types,
 */

#define	ARG_NUMB 1
#define	ARG_REL	 2

struct	cm {
	char	*se;
	int	sev;
	int	sea;	/* argument type */
};

extern	struct	cm cmd[];

/* page parameters */
extern	int	curpage;
extern	int	newpage;
extern	int	lineno;
extern	int	plval;
extern	int	m1val;
extern	int	m2val;
extern	int	m3val;
extern	int	m4val;
extern	int	bottom;

/* heads and tails */
struct	hft	{
	char	left[LINESIZE/2];
	char	center[LINESIZE/2];
	char	right[LINESIZE/2];
};

#define	ODD	1
#define	EVEN	0
extern	struct	hft	headers[];
extern	struct	hft	footers[];

/* global parameters */
extern	int	fill;
extern	int	lsval;
extern	int	spval;
extern	int	inval;
extern	int	rmval;
extern	int	tival;
extern	int	ceval;
extern	int	ulval;
extern	int	boval;

extern	int	dlval;	/* length of last diversion */
/* output */
extern	int	out_p;
extern	int	outw;
extern	int	outwds;
extern	char	outbuf[];
extern	int	dir;
extern	char	inbuf[];

/* sourceing */
#define	MAXSOURCE	5
extern	int	nsources;

/* sources */
#define	MAXMARGS	9
			/* bits for m_type */
#define	AMACRO	0	/* thing is a macro */
#define AREG	1	/* is a register */
#define	ASTR	2	/* is a string or a number */
#define	ARO	4	/* read only */
#define	ASYS	010	/* is a system defined item (can't delete ) */

struct	source {
	struct	source	*m_next;
	char	m_name[2];
	char	*m_curp;
	char	*m_scurp;	/* save curp while playing with args */
	char	*m_val;
	FILE	*m_fp;		/* when not a macro but an .so */
	struct	source	*m_last;	/* used to return to higher level */
	int	m_nargs;
	int	m_type;
	union	{
		char	*_m_args[MAXMARGS];
		struct	{
			char	*_m_sval[2];
			int	_m_ival[3];
		} ss;
	} s;
#define	m_args	s._m_args
#define m_sval	s.ss._m_sval[0]
#define m_eptr	s.ss._m_sval[1]
#define m_ival	s.ss._m_ival[2]
#define m_nlines s.ss._m_ival[1]
};

extern	struct	source	*macros;	/* list of all macros */
extern	struct	source	*mname;
extern	struct	source	*curmacro;	/* current macro being expanded */
extern	struct	source	*regstrs;	/* register list */
extern	struct	source	*curdiv;	/* current diversion */

/* registers etc */

#define	NRO	1			/* read only reg */
#define	NSYS	2			/* set by system */

struct	nregs	{
	struct	nregs	*n_next;
	char	n_name[2];
	int	n_value;
	int	n_incr;
	char	n_form;
	char	n_digits;
	char	n_status;
};

extern	struct	nregs	*numregs;	/* list of number registers */

struct	when	{
	struct	when	*w_next;
	char	w_name[2];
	int	w_lno;
};

extern	struct	when	*whens;

struct	font	{	/* font structure */
	int	(*f_putc)();		/* put out a char in this font */
	char	f_name[2];		/* name of font */
	char	f_pos;	/* 1 -> 4 */	/* position of font in system */
	int	(*f_start)();		/* turn on font */
	char	*fstrt_str;
	int	(*f_end)();		/* turn off font */
	char	*fend_str;
	struct	font	*f_next;	/* link to next font */
	char	*f_table;		/* pointer to font table */
};

extern	struct	font	*curfont;	/* current font */
extern	struct	font	*fonts;		/* fonts */
extern	int	nfonts;			/* number of fonts */

extern	char	pageo;	/* FF char */
extern	char	echar;	/* escape char */

extern	char	cmdchar1;	/* command char one, causes break */
extern	char	cmdchar2;	/* command char two, no break caused */

char	*malloc();
char	*mymalloc();

#define	PUT(c)	((curdiv->m_curp >= curdiv->m_eptr) ? dflsh(c) : \
		(*curdiv->m_curp++ =c))

#define	PUTNL()	dflsh('\n')

#define	SPRING(n)	((whens) ? spring(n) : 0)

#define	CMD(c)	((c) == cmdchar1 || (c) == cmdchar2)
