/*
 * troffcvt.h -- troffcvt interface stuff
 */


/*
 * Param - internal parameter type (should be 4 bytes at least), used
 * for passing around generic signed integer values.
 */

typedef	long		Param;

/*
 * XChar - "extended" character.  This is the type used internally to hold
 * character values.
 *
 * The encoding is as follows:
 * 1) plain (ASCII) character - the character is stored in the low-order byte.
 * Since ASCII characters are < 128, only the lower 7 bits are used.  Null
 * bytes are stripped, so a zero value is never stored.
 * 2) 8-bit character - the character is stored in the low-order byte, but the
 * values are in the range 128-255.
 * 3) escaped character (\c) - the character c is stored in the low-order byte,
 * and the first bit of the second byte is turned on.  Thus escape codes are
 * in the range 1-511.  (256 will never occur because that would be an escaped
 * null.)
 * 4) special characters (\(xx or \[xxx]) - the characters xx or xxx are
 * converted to a special-character code (a value >= 512).
 *
 * An unsigned value is used to avoid problems with sign bits.
 */

typedef unsigned long	XChar;

#define	escBase		0x100	/* escape code base (9th bit turned on) */
#define	spCharBase	0x200	/* first special-char code */


/*
 * Some convenience defines for typecasting operations on XChar
 * strings.
 */

#define	XStrFree(s)	Free ((char *) s)


/*
 * Internal end-of-input-source indicator.  EOF isn't used because that's
 * -1 on many (all?) systems, and the input routines return an unsigned
 * value.
 */

#define	endOfInput	0


/*
 * Debugging flags and macro for testing debug setting.
 * To turn on flag 1L<<n, specify -dn on the command line.
 */

#define	Debug(n)	(debug & (n))

#define	bugActionParse		(1L<<0)
#define	bugActionProcess	(1L<<1)
#define	bugMacroDef		(1L<<2)
#define bugFChIn		(1L<<3)
#define bugMChIn		(1L<<4)
#define bugSChIn		(1L<<5)
#define bugAChIn		(1L<<6)
#define	bugChIn0		(1L<<7)
#define	bugChIn02		(1L<<8)
#define	bugChIn			(1L<<9)
#define	bugUnChIn		(1L<<10)
#define	bugInputStack		(1L<<11)
#define	bugReqProcess		(1L<<12)
#define	bugConditional		(1L<<13)

/*
 * Unit conversion stuff.  ToBU() is seldom used directly so that
 * it isn't necessary to mess around casting the first argument to
 * double all the time.  (BU = basic units)
 *
 * Actually, this is vestigial now that function prototypes are used
 * in the troffcvt source.
 */


#define	Units(n,u)	ToBU ((double) (n), (u))


/*
 * Allocate object of type t, returning properly cast pointer.
 * Panics if no memory available.
 */

#define	New(t)	((t *) Alloc ((int) sizeof (t)))


#ifndef	bufSiz
#define	bufSiz		1024
#endif
#define	maxTabStops	35
#define	maxMacroArgs	99	/* $1..$[99] */
#define	maxActionArgs	11	/* 10 + null on end */
#define	maxFonts	10	/* 0(reserved),1..9 */
#define	maxFontNameLen	30

#define	macroAllocSize	512	/* macro body allocation increment */

#define	lf		'\n'
#define	cr		'\r'

#define	defEscChar	'\\'	/* default escape char */
#define	defCtrlChar	'.'	/* default control char */
#define	defNbCtrlChar	'\''	/* default no-break control */



#define	fill		1
#define	nofill		2

/* adjustment modes must be 1..4 */

#define	adjCenter	1
#define	adjLeft		2
#define	adjRight	3
#define	adjFull		4

/*
 * Name types: request, macro/string, register
 */

#define	reqDef	1
#define	macDef	2
#define	regDef	4

/*
 * Number register formats
 */

#define	numFmt		1
#define	lRomanFmt	2
#define	uRomanFmt	3
#define	lAlphaFmt	4
#define	uAlphaFmt	5



typedef struct Name	Name;		/* object name */
typedef	struct Object	Object;		/* request, macro, string, register */
typedef	struct Request	Request;	/* request defintion (actions) */
typedef	struct Macro	Macro;		/* macro definition */
typedef	struct Register	Register;	/* number register definition */
typedef	struct Action	Action;		/* request action */
typedef	struct SpChar	SpChar;		/* special char definition */

struct Name
{
	XChar	*nName;
	long	nHash;		/* hash value of name */
	Object	*nObject;
	Name	*nNext;
#define	nRequest	nObject->oRequest
#define	nMacro		nObject->oMacro
#define	nRegister	nObject->oRegister
};

struct Object
{
	short		oType;
	short		oRefCount;
	union ObjInfo
	{
		Request		*oReqPtr;
		Macro		*oMacPtr;
		Register	*oRegPtr;
	} oInfo;
#define	oRequest	oInfo.oReqPtr
#define	oMacro		oInfo.oMacPtr
#define	oRegister	oInfo.oRegPtr
};

struct Request
{
	Action	*reqPActions;	/* parsing actions */
	Action	*reqPPActions;	/* post-parsing actions */
};

/*
 * Macro structure is also used to hold troff strings.  A string
 * is treated like a macro without arguments.
 */

struct Macro
{
	XChar	*macBuf;	/* macro body */
	long	macSiz;		/* current size of macro body */
	long	macMaxSiz;	/* maximum size of macBuf */
};

struct Register
{
	Param	regValue;
	Param	regIncrement;
	short	regFormat;
	short	regFmtWidth;
	short	regReadOnly;
};

struct Action
{
	char	*actName;
	int	(*actFunc) ();
	int	actArgc;
	XChar	*actArgv[maxActionArgs];
	Action	*actNext;
};


/*
 * Special characters appear as \(xx or \[xxx] in the input, where xx or
 * xxx consist of plain (ASCII) characters.
 *
 * The name is the string xx or xxx.
 *
 * The hash value is computed from the name and is used to speed up lookups.
 *
 * The code is a value >=256 that is the internal representation of the
 * special character.
 *
 * The value is the string that appears in the output when the special
 * character appears in the input.  E.g., \(bu in the input turns into
 * @bullet in the output.  This value is written literally to the output,
 * so it cannot itself contain any special characters.  Because of that
 * it's sufficient for the spChar member to be char* rather than XChar*.
 * (NewSpChar() takes an XChar* argument for the value because it's easier
 * to arrange to pass that type of string, but it's converted in NewSpChar
 * to an ordinary char* string.)
 *
 * spNext points to the next structure in the list of special characters.
 */

struct SpChar
{
	XChar	*spName;
	long	spHash;
	XChar	spCode;
	char	*spValue;
	SpChar	*spNext;
};


/*
 * Environment structure
 */

typedef	struct Environ	Environ;

struct Environ
{
	XChar	*eName;			/* environment name */
	Param	eSize;
	Param	ePrevSize;
	Param	eSpaceSize;
	XChar	eFont[maxFontNameLen];
	XChar	ePrevFont[maxFontNameLen];
	Param	eFillMode;
	Param	eAdjust;
	Param	eAdjMode;
	Param	eCenterCount;
	Param	eVSize;
	Param	ePrevVSize;
	Param	eLineSpacing;
	Param	ePrevLineSpacing;
	Param	eLineLen;
	Param	ePrevLineLen;
	Param	eIndent;
	Param	ePrevIndent;
	Param	eTempIndent;
	XChar	*eItMacro;
	Param	eItCount;
	Param	eTabCount;
	Param	eTabPos[maxTabStops];
	char	eTabType[maxTabStops];
	XChar	eTabChar;
	XChar	eLeaderChar;
	Param	eUlCount;
	Param	eCUlCount;
	XChar	eCtrlChar;
	XChar	eNbCtrlChar;
	Param	eHyphenMode;
	XChar	eHyphenChar;
	Param	eTitleLen;
	Param	ePrevTitleLen;
	/* nm is not supported */
	/* nn is not supported */
	/* mc is not supported */
	Environ	*eNext;			/* next in environment list */
};


void	SetOpenMacroFileProc (FILE *(*proc) ());
FILE	*OpenMacroFile (char *file, char *mode);

void	ReadInput (void);

int	ReadActionFile (char *filename);
void	FreeActions (Action *ap);

int	ProcessActionList (Action *ap);
int	ProcessLine (void);
void	ProcessRequest (short jiggerCompat);

void	ProcessText (void);
char	*CharToOutputStr (XChar c);

XChar	*InterpretActionArg (XChar *p);
int	ParseNumber (int defUnit, int relAllowed, Param curVal, Param *val);
Param	ParseSizeRef (void);
Name	*ParseRegisterRef (void);
XChar	*ParseNameRef (void);
void	ParseWidth (void);
void	ParseNameTest (void);

int	AParseARNumber (int argc, XChar **argv);
int	AParseChar (int argc, XChar **argv);
int	AParseCondition (int argc, XChar **argv);
int	AParseFileName (int argc, XChar **argv);
int	AParseMacroArgs (int argc, XChar **argv);
int	AParseName (int argc, XChar **argv);
int	AParseNames (int argc, XChar **argv);
int	AParseNumber (int argc, XChar **argv);
int	AParseEmbolden (int argc, XChar **argv);
int	AParseStringValue (int argc, XChar **argv);
int	AParseTabStops (int argc, XChar **argv);
int	AParseTitle (int argc, XChar **argv);
int	AParseTransList (int argc, XChar **argv);
int	AProcessCondition (int argc, XChar **argv);
int	AProcessDo (int argc, XChar **argv);

int	APointSize (int argc, XChar **argv);
int	ASpaceSize (int argc, XChar **argv);
int	AConstantWidth (int argc, XChar **argv);
int	AEmbolden (int argc, XChar **argv);
int	AFont (int argc, XChar **argv);
int	AFontPosition (int argc, XChar **argv);

int	APageLength (int argc, XChar **argv);
int	ABeginPage (int argc, XChar **argv);
int	APageNumber (int argc, XChar **argv);
int	AOffset (int argc, XChar **argv);
int	ANeed (int argc, XChar **argv);
int	AMarkVertical (int argc, XChar **argv);
int	AReturnVertical (int argc, XChar **argv);

int	AFlush (int argc, XChar **argv);
int	ABreak (int argc, XChar **argv);
int	AFill (int argc, XChar **argv);
int	ANofill (int argc, XChar **argv);
int	AAdjust (int argc, XChar **argv);
int	ANoAdjust (int argc, XChar **argv);
int	ACenter (int argc, XChar **argv);

int	ASpacing (int argc, XChar **argv);
int	ALineSpacing (int argc, XChar **argv);
int	ASpace (int argc, XChar **argv);
int	ASaveSpace (int argc, XChar **argv);
int	AOutputSpace (int argc, XChar **argv);
int	ANoSpace (int argc, XChar **argv);

int	ALineLength (int argc, XChar **argv);
int	AIndent (int argc, XChar **argv);
int	ATempIndent (int argc, XChar **argv);

int	ADefineMacro (int argc, XChar **argv);
int	AAppendMacro (int argc, XChar **argv);
int	AAliasMacro (int argc, XChar **argv);
int	ADefineString (int argc, XChar **argv);
int	AAppendString (int argc, XChar **argv);
int	ARenameName (int argc, XChar **argv);
int	ARemoveNames (int argc, XChar **argv);
int	ADiversion (int argc, XChar **argv);
int	AAppendDiversion (int argc, XChar **argv);
XChar	*CurrentDiversion (void);
int	AEndMacro (int argc, XChar **argv);
int	AInputTrap (int argc, XChar **argv);

int	ADefineRegister (int argc, XChar **argv);
int	AAliasRegister (int argc, XChar **argv);
int	ARegisterFormat (int argc, XChar **argv);

int	ATabStops (int argc, XChar **argv);
int	ASetTabChar (int argc, XChar **argv);
int	ASetLeaderChar (int argc, XChar **argv);
int	ASetFieldChars (int argc, XChar **argv);

int	ASetEscape (int argc, XChar **argv);
int	ANoEscape (int argc, XChar **argv);

int	ALigature (int argc, XChar **argv);

int	AUnderline (int argc, XChar **argv);
int	ACUnderline (int argc, XChar **argv);
int	AUnderlineFont (int argc, XChar **argv);

int	ASetControl (int argc, XChar **argv);
int	ASetControl2 (int argc, XChar **argv);

int	ATransliterate (int argc, XChar **argv);

int	AHyphenation (int argc, XChar **argv);
int	ASetHyphenChar (int argc, XChar **argv);
int	AHyphenWords (int argc, XChar **argv);

int	ATitle (int argc, XChar **argv);
int	APageNumChar (int argc, XChar **argv);
int	ATitleLength (int argc, XChar **argv);

int	ALineNumbering (int argc, XChar **argv);
int	ANoNumbering (int argc, XChar **argv);

int	AEnvironment (int argc, XChar **argv);

int	AExit (int argc, XChar **argv);
int	AAbort (int argc, XChar **argv);

int	APushFile (int argc, XChar **argv);
int	APushMacroFile (int argc, XChar **argv);
int	AShiftArguments (int argc, XChar **argv);
int	ASwitchFile (int argc, XChar **argv);

int	ASetCompatibility (int argc, XChar **argv);

int	AEcho (int argc, XChar **argv);
int	AIgnore (int argc, XChar **argv);

int	ASpecialChar (int argc, XChar **argv);
int	APushStr (int argc, XChar **argv);
int	AEol (int argc, XChar **argv);
int	AWriteControl (int argc, XChar **argv);
int	AWriteText (int argc, XChar **argv);
int	AWriteSpecial (int argc, XChar **argv);

int	ADebugFlag (int argc, XChar **argv);
int	ADumpMacro (int argc, XChar **argv);
int	ADumpBadRequests (int argc, XChar **argv);
int	ADumpInputStack (int argc, XChar **argv);

Param	InterpretParam (XChar *s, Param defValue);
int	InterpretCharParam (XChar *s, int defValue);

void	SetPageLength (Param val);
void	SetCFA (Param nCenter, Param nFill, Param nAdjust, Param nAdjMode);
void	SetUnderline (Param ul, Param cul);
void	SetFont (XChar *name);
XChar	*GetFontName (XChar *p);
XChar	*GetFontNameBySlot (Param pos);
void	SetFontNameBySlot (Param pos, XChar *name);
void	SetRegisterFormat (Register *rp, XChar *format);
XChar	*FormatRegister (Register *rp);
Param	GetRegisterValue (XChar *name);
void	SetRegisterValue (XChar *name, Param value);
Param	StrGetRegisterValue (char *name);
void	StrSetRegisterValue (char *name, Param value);
void	SetSize (Param val);
void	SetSpaceSize (Param val);
void	SetOffset (Param val);
void	SetSpacing (Param val);
void	SetLineSpacing (Param val);
void	SetLineLength (Param val);
void	SetIndent (Param val);
void	SetTempIndent (Param val);
void	SetHyphenation (Param val);
void	SetTitleLength (Param val);
void	SetPageNumber (Param val);
void	SetTabStops (Param n, Param *pos, char *type);
Param	SetCompatMode (Param newCompat);

void	InitEnvironments (void);
void	PushEnvironment (XChar *name);
void	PopEnvironment (void);
XChar	*CurrentEnvironmentName (void);

void	RenameName (Name *nd, XChar *name);
Name	*NewName (XChar *name, Object *op, short type);
Request	*NewRequest (XChar *name);
Macro	*NewMacro (XChar *name);
Register *NewRegister (XChar *name, Param initial, Param increment,
					XChar *format, short readonly);
Register *StrNewRegister (char *name, Param initial, Param increment,
					char *format, short readonly);
Name	*LookupName (XChar *name, short type);
Request	*LookupRequest (XChar *name);
Macro	*LookupMacro (XChar *name);
Register	*LookupRegister (XChar *name);
void	RemoveNamedObject (XChar *name, short numReg);
void	GrabObject (Object *op);
void	ReleaseObject (Object *op);
SpChar	*NewSpChar (XChar *name, XChar *value);
SpChar	*LookupSpCharByName (XChar *name);
SpChar	*LookupSpCharByCode (XChar code);


void	CopyMode (int onoff);
void	ResumeInput (void);
short	ILevel (void);
char	*FileInfo (void);
void	DumpInputStack (void);
char	*FindMacroFile (char *name);
int	SwitchFile (char *name);
int	PushFile (char *name);
int	PushMacro (XChar *s, int argc, XChar *argv[]);
int	PushAnonString (XChar *s, short pauseAfter);
void	ShiftMacroArguments (short n);
XChar	ChPeek (void);
XChar	ChIn (void);
void	UnChIn (XChar c);

void	InitTransliterate (void);
void	Transliterate (int in, XChar out);
void	Break (void);
void	ControlOut (char *s);
void	CommentOut (char *s);
void	SpecialTextOut (char *s);
void	TextXStrOut (XChar *s);
void	TextXChOut (XChar c);
void	TextStrOut (char *s);
void	TextChOut (int c);
void	FlushOText (void);
void	StrOut (char *s);
void	ChOut (int c);
int	AllowOutput (int yesno);

void	SkipWhite (void);
void	SkipToEol (void);

XChar	ToEsc (XChar c);
XChar	FromEsc (XChar c);

int	Esc (XChar c);
int	Special (XChar c);
int	Eol (XChar c);
int	Sign (XChar c);
int	White (XChar c);
int	WhiteOrEol (XChar c);
int	UnitChar (XChar c);
int	Digit (XChar c);

int	EmptyArg (XChar *arg);
int	NumericArg (XChar *arg);

int	AsciiStr (XChar *s);

Param	ToBU (double n, int u);
double	FromBU (Param n, int u);

XChar	*XStrAlloc (XChar *xstr);
XChar	*XStrCpy (XChar *xdst, XChar *xsrc);
XChar	*XStrNCpy (XChar *xdst, XChar *xsrc, long n);
XChar	*XStrCat (XChar *xdst, XChar *xsrc);
int	XStrCmp (XChar *xstr1, XChar *xstr2);
int	XStrNCmp (XChar *xstr1, XChar *xstr2, long n);
int	XStrLen (XChar *xstr);
char	*XCharToStr (XChar xc);
char	*XStrToStr (XChar *xstr);
XChar	*StrToXStr (char *str);

Param	GetPid (void);

extern int	troff;

extern Param	resolution;

extern int	allowInput;
extern XChar	escChar;
extern int	doEscapes;
extern int	inCharTest;

extern XChar	ctrlChar;
extern XChar	nbCtrlChar;
extern XChar	curCtrlChar;
extern XChar	fieldDelimChar;
extern XChar	fieldPadChar;
extern int	fieldDelimCount;
extern XChar	optHyphenChar;

extern XChar	tabChar;
extern XChar	leaderChar;

extern long	debug;

extern Param	compatMode;

extern short	writeLineInfo;

extern short	dumpBadReq;

extern int	needSpace;
extern int	inContinuation;
extern int	ifLevel;
extern int	ifResult;

extern XChar	fontTab[maxFonts][maxFontNameLen];
extern XChar	curFont[];
extern XChar	prevFont[];

extern XChar	*itMacro;
extern Param	itCount;
extern XChar	*endMacro;

extern Param	centerCount;
extern Param	ulCount;
extern Param	cUlCount;

extern Param	fillMode;
extern Param	adjMode;
extern Param	adjust;

extern Param	curSize;
extern Param	prevSize;
extern Param	curSpaceSize;

extern Param	curVSize;
extern Param	prevVSize;
extern Param	curLineSpacing;
extern Param	prevLineSpacing;

extern Param	curIndent;
extern Param	prevIndent;
extern Param	curTempIndent;
extern Param	curLineLen;
extern Param	prevLineLen;

extern Param	curOffset;
extern Param	prevOffset;
extern Param	curPageLen;
extern Param	curPageNum;

extern Param	curHyphenMode;

extern Param	pageNumChar;
extern Param	curTitleLen;
extern Param	prevTitleLen;

extern Param	curTabCount;
extern Param	tabPos[];
extern char	tabType[];

extern XChar	lastCharRead;
