/*
 * C compiler
 * ==========
 *
 * Copyright 1989, 1990, 1991 Christoph van Wuellen.
 * Credits to Matthew Brandt.
 * All commercial rights reserved.
 *
 * This compiler may be redistributed as long there is no
 * commercial interest. The compiler must not be redistributed
 * without its full sources. This notice must stay intact.
 *
 * History:
 *
 * 1989   starting an 68000 C compiler, starting with material
 *        originally by M. Brandt
 * 1990   68000 C compiler further bug fixes
 *        started i386 port (December)
 * 1991   i386 port finished (January)
 *        further corrections in the front end and in the 68000
 *        code generator.
 *        The next port will be a SPARC port
 */


#ifndef _CHDR_H
#define	_CHDR_H

#include "config.h"

#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifdef VERBOSE
#include <time.h>
#endif /* VERBOSE */


/*
**	Definitions used for I/O portability
*/
#ifdef EPOC
#include <plib.h>
#define	FHANDLE		void *
#undef	EXIT_FAILURE
#define	EXIT_FAILURE	1
#else /* not EPOC */
#include <stdio.h>
#define	FHANDLE		FILE *
#endif /* EPOC */

#ifdef HAS_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif /* HAS_STDARG */

/*
**	For NON-ANSI systems.....
*/
#ifndef EXIT_SUCCESS
#define	EXIT_SUCCESS	0
#endif /* EXIT_SUCCESS */

#ifndef EXIT_FAILURE
#define	EXIT_FAILURE	1
#endif /* EXIT_FAILURE */

#ifndef FILENAME_MAX
#define	FILENAME_MAX	127
#endif /* FILENAME_MAX */

#ifndef __STDC__
#define	const		/* nothing */
#endif /* __STDC__ */


/* documents paths which it should be impossible to reach */

#define	CANNOT_REACH_HERE()	assert(0)

/* the tokens returned from lexical analysis */

enum e_sym {
    /* Constants */
    tk_cconst,		/* Character Constant */
    tk_fconst,		/* Float Constant */
    tk_iconst,		/* Integer Constant */
    tk_lconst,		/* Long Integer Constant */
    tk_lrconst,		/* Long Double Constant */
    tk_rconst,		/* Double Constant */
    tk_wconst,		/* Wide Character Constant */
    tk_sconst,		/* String Constant */
    tk_wsconst,		/* Wide String Constant */
    tk_uconst,		/* Unsigned Integer Constant */
    tk_ulconst,		/* Unsigned Long Constant */

    /* Arithmetic Operators */
    tk_plus,		/* + symbol */
    tk_minus,		/* - symbol */
    tk_divide,		/* / symbol */
    tk_mod,		/* % symbol */

    /* Shift Operators */
    tk_lshift,		/* << symbol */
    tk_rshift,		/* >> symbol */

    /* Equality Operators */
    tk_eq,		/* == symbol */
    tk_neq,		/* != symbol */
    tk_lt,		/* < symbol */
    tk_leq,		/* <= symbol */
    tk_gt,		/* > symbol */
    tk_geq,		/* >= symbol */

    /* Assignement Operators */
    tk_assign,		/* = symbol */
    tk_asplus,		/* += symbol */
    tk_asminus,		/* -= symbol */
    tk_astimes,		/* *= symbol */
    tk_asdivide,	/* /= symbol */
    tk_asmod,		/* %= symbol */
    tk_asuparrow,	/* ^= symbol */
    tk_aslshift,	/* <<= symbol */
    tk_asrshift,	/* >>= symbol */
    tk_asand,		/* &= symbol */
    tk_asor,		/* |= symbol */

    /* Unary Operators */
    tk_autoinc,		/* ++ symbol */
    tk_autodec,		/* -- symbol */
    tk_not,		/* ! symbol */
    tk_compl,		/* ~ symbol */

    tk_hook,		/* ? symbol */
    tk_uparrow,		/* ^ symbol */
    tk_pointsto,	/* -> symbol */
    tk_dot,		/* . symbol */
    tk_lor,		/* || symbol */
    tk_land,		/* && symbol */
    tk_or,		/* | symbol */
    tk_and,		/* & symbol */

    tk_semicolon,	/* ; symbol */
    tk_closebr,		/* ] symbol */
    tk_end,		/* } symbol */
    tk_closepa,		/* ) symbol */

    tk_openbr,		/* [ symbol */
    tk_begin,		/* { symbol */
    tk_comma,		/* , symbol */
    tk_openpa,		/* ( */
    tk_star,		/* * symbol */
    tk_colon,		/* : symbol */
    tk_ellipsis,		/* ... */

    tk_id,		/* identifier */

    kw_char,		/* char */
    kw_double,		/* double */
    kw_enum,		/* enum */
    kw_float,		/* float */
    kw_int,		/* int */
    kw_long,		/* long */
    kw_short,		/* short */
    kw_signed,		/* signed */
    kw_struct,		/* struct */
    kw_union,		/* union */
    kw_unsigned,	/* unsigned */
    kw_void,		/* void */

    kw_auto,		/* auto */
    kw_extern,		/* extern */
    kw_register,	/* register */
    kw_static,		/* static */
    kw_typedef,		/* typedef */

    kw_const,		/* const */
    kw_volatile,	/* volatile */

#ifdef ASM
    kw_asm,		/* asm */
#endif /* ASM */
    kw_break,		/* break */
    kw_case,		/* case */
    kw_continue,	/* continue */
    kw_default,		/* default */
    kw_do,		/* do */
    kw_else,		/* else */
    kw_for,		/* for */
    kw_goto,		/* goto */
    kw_if,		/* if */
    kw_return,		/* return */
    kw_sizeof,		/* sizeof */
    kw_switch,		/* switch */
    kw_while,		/* while */

#ifdef TOPSPEED
    kw_cdecl,		/* cdecl */
#endif /* TOPSPEED */

#ifdef EXTENSION
    /* proposed extensions to ANSI C */
    kw_restrict,	/* restrict */
#endif /* EXTENSION */

#ifdef FACIST
    kw_id,		/* c++ symbol */
#endif /* FACIST */

    tk_eof			/* End-Of-File */
};

/* storage classes */

enum e_sc {
    /* Storage classes defined in the ANSI C Specification */
    sc_static,			/* Symbol is static */
    sc_auto,			/* Symbol is automatic */
    sc_global,			/* Symbol is global */
    sc_external,		/* Symbol is external */
    sc_typedef,			/* Symbol is a typedef */
    sc_register,		/* Symbol is a register */

    /* Pseudo storage classes - these classes exist in the symbol table */
    sc_parms,			/* Symbol is a parameter to a function */
    sc_tag,			/* Symbol is a struct/union/enum tag */
    sc_const,			/* Symbol is an enumeration constant */
    sc_member,			/* Symbol is a member of a struct/union */
    sc_label			/* Symbol is a label */
};

/* basic data types */

enum e_bt {
    bt_void,			/* void type */
    bt_char,			/* char type (signed) */
    bt_charu,			/* char type (unsigned) */
    bt_uchar,			/* unsigned char type */
    bt_schar,			/* signed char type */
    bt_short,			/* short type */
    bt_ushort,			/* unsigned short type */
    bt_int16,			/* int type (16 bits) */
    bt_uint16,			/* unsigned int type (16 bits) */
    bt_int32,			/* int type (32 bits) */
    bt_uint32,			/* unsigned int type (32 bits) */
    bt_long,			/* long type */
    bt_ulong,			/* unsigned long type */
    bt_float,			/* float type */
    bt_double,			/* double type */
    bt_longdouble,		/* long double type */
    bt_pointer16,		/* pointer type (16 bits) */
    bt_pointer32,		/* pointer type (32 bits) */
    bt_struct,			/* struct type */
    bt_union,			/* union type */
    bt_func,			/* function type */
    bt_bitfield,		/* Pseudo type - bitfield type */
    bt_ubitfield,		/* Pseudo type - unsigned bitfield type */
    bt_ellipsis			/* Pseudo type - parameter list ... */
};

typedef struct stab	TABLE;		/* symbol table */
typedef struct sblock	BLOCK;		/* scope table */
typedef struct typ	TYP;		/* type entry */
typedef struct sym	SYM;		/* symbol entry */
typedef	long		SIZE;		/* size of object */
typedef	unsigned int	LABEL;		/* internal label */
typedef	enum e_sym	TOKEN;		/* scanner token */
typedef	enum e_bt	BTYPE;		/* basic type */
typedef	unsigned char	STATUS;		/* status of symbol */
typedef	enum e_sc	STORAGE;	/* symbol storage class */
typedef	int		BOOL;		/* true/false value */
typedef	unsigned char	QUALIFIER;	/* type qualifiers */
typedef	unsigned char	STATE;		/* type state */
typedef	long		IVAL;		/* signed integral value */
typedef	unsigned long	UVAL;		/* unsigned integral value */
typedef	double		RVAL;		/* floating point value */
typedef	unsigned char	CHAR;		/* input character */
typedef	unsigned int	LEVEL;		/* scope level */
#ifdef SEQUENCE
typedef	unsigned int	SEQNUM;		/* sequence number */
#endif

#ifndef TRUE
#define	TRUE		((BOOL)1)
#define	FALSE		((BOOL)0)
#endif /* TRUE */

#define	NIL_TABLE	((TABLE *)0)
#define	NIL_BLOCK	((BLOCK *)0)
#define	NIL_TYP		((TYP *)0)
#define	NIL_SYM		((SYM *)0)
#define	UNDEF_LABEL	((LABEL)0)
#define	GLOBAL_SCOPE	((LEVEL)1)


/* these form the string literal pool */

struct slit {
    struct slit	*next;		/* next literal */
    const CHAR	*str;		/* pointer to the literal string */
    LABEL	label;		/* label to use when referncing a literal */
    size_t	len;		/* length of the literal */
};

/*
**	Symbol Table Entry
*/
struct stab {
    SYM     *head;		/* pointer to symbol at start of table */
    SYM     *tail;		/* pointer to symbol at end of table */
};

/*
**	Scope Table
*/
struct sblock {
    TABLE   symbols;		/* variable/functions etc */
    TABLE   tags;		/* struct/union/enum tags */
    BLOCK  *prev;		/* previous scope block */
    SIZE    offset;		/* stack offset for temporary variables */
};

/*
**	Symbol Table
*/
struct scopetbl {
    BLOCK  *global;		/* pointer to global scope table */
    BLOCK  *local;		/* pointer to current scope table */
};

/*
**	Type Entry
*/
struct typ {
    BTYPE	 type COLON(6) ;/* type */
    QUALIFIER	 qual COLON(2) ;/* type qualifier (const and/or volatile) */
    STATE	 state COLON(5);
    SIZE	 size;		/* size in bytes of the type */
    TYP		*btp;		/* derived type */
    TYP		*next;		/* next type in type table */
    const CHAR	*sname;		/* type name */
    union {
	BLOCK	*lst;		/* struct/union members / function param list */
	struct {
	    unsigned char width;	/* bit-field width */
	    unsigned char offset;	/* bit-field offset */
	} bitfield;
	SIZE	 index;		/* array size */
    } t;
};

#define	referenced_type(tp)	(tp)->btp	/* object pointer points at */
#define	returned_type(tp)	(tp)->btp	/* function return type */
#define	enumtype(tp)		(tp)->btp	/* type of the enumeration */
#define	parameters(tp)		(tp)->t.lst	/* function parameters */
#define	members(tp)		(tp)->t.lst	/* struct/union members */
#define	bitfield_width(tp)	(tp)->t.bitfield.width
#define	bitfield_offset(tp)	(tp)->t.bitfield.offset
#define	array_index(tp)		(tp)->t.index
#define	is_void(tp)		((tp)->type == bt_void)
#define	is_enum(tp)		((tp)->state & STATE_ENUM)
#define	is_derived_type(tp)	((tp)->state & STATE_DERIVED)
#define	is_ansi(tp)		((tp)->state & STATE_ANSI)
#define	is_array_assignment(tp)	((tp)->state & STATE_ARRAYASSIGN)
#define	is_qualified_type(tp)	((tp)->qual != 0)
#define	is_const_qualified(tp)	((tp)->qual & QUAL_CONST)
#define	is_volatile_qualified(tp)	((tp)->qual & QUAL_VOLATILE)
#define	is_restrict_qualified(tp)	((tp)->qual & QUAL_RESTRICT)

#define	set_referenced_type(tp,t)	((tp)->btp = (t))
#define	set_returned_type(tp,t)	((tp)->btp = (t))
#define	set_enumtype(tp,t)	((tp)->btp = (t))
#define	set_members(tp,b)	((tp)->t.lst = b)
#define	set_parameters(tp,b)	((tp)->t.lst = b)
#define	set_bit_width(tp,w)	((tp)->t.bitfield.width = (w))
#define	set_bit_offset(tp,o)	((tp)->t.bitfield.offset = (o))
#define	set_array_index(tp,i)	((tp)->t.index = (i))
#define	set_state(tp,s)		((tp)->state |= (s))
#define	set_derived(tp)		set_state(tp, STATE_DERIVED)
#define	set_enum(tp)		set_state(tp, STATE_ENUM)
#define	set_typedef(tp)		set_state(tp, STATE_TYPEDEF)
#define	set_ansi(tp)		set_state(tp, STATE_ANSI)
#define	set_array_assignment(tp)	set_state(tp, STATE_ARRAYASSIGN)

/* values for "qual" field */
#define	QUAL_NONE	((QUALIFIER) 000)	/* no qualifiers */
#define	QUAL_CONST	((QUALIFIER) 001)	/* constant qualifier */
#define	QUAL_VOLATILE	((QUALIFIER) 002)	/* volatile qualifier */
#define	QUAL_RESTRICT	((QUALIFIER) 004)	/* restrict qualifier */

/* values for "state" field */
#define	STATE_NONE	((STATE) 000)	/* none */
#define	STATE_DERIVED	((STATE) 001)	/* array or function definition */
#define	STATE_TYPEDEF	((STATE) 002)	/* type defined by a typedef */
#define	STATE_ANSI	((STATE) 004)	/* parameters are ANSI */
#define	STATE_ENUM	((STATE) 010)	/* type derived from an enumeration */
#define	STATE_ARRAYASSIGN	((STATE) 020)	/* array assignement */

/* value for "size" field */
#define UNKNOWN_SIZE	-1L	/* value of 'size' if not known */

/*
**	Symbol Table Entry
*/
struct sym {
    SYM		*next;		/* next symbol in the table */
    SYM		*hnext;		/* next symbol in the hash chain */
    const CHAR	*name;		/* name of the symbol */
    TYP		*tp;		/* type of the symbol */
    union {			/* symbol value: */
	IVAL            i;	/*   signed */
	UVAL		u;	/*   unsigned */
	const CHAR	*s;	/*   string */
	LABEL		l;	/*   internal label */
    } value;
    LEVEL 	 level COLON(7);	/* scope level of this symbol */
    STORAGE	 storage_class COLON(4);	/* symbol storage class */
    STATUS	 status COLON(5);	/* various flags specific to the symbol */
#ifdef SEQUENCE
    SEQNUM	 sequence;	/* sequence point symbol last modeified */
#endif
};

/* value for the 'status' field */
#define	SYM_USED	((STATUS) 001)	/* Symbol has been used */
#define	SYM_DEFINED	((STATUS) 002)	/* Symbol has been defined */
#define	SYM_SET		((STATUS) 004)	/* Symbol contents have been set */
#define	SYM_OUTSCOPE	((STATUS) 010)	/* Symbol is out of scope */
#define	SYM_OUTPUT	((STATUS) 020)	/* Symbol has been output to assembler file */

#define	is_symbol_defined(s)	((s)->status & SYM_DEFINED)
#define	is_symbol_used(s)	((s)->status & SYM_USED)
#define	is_symbol_set(s)	((s)->status & SYM_SET)
#define	is_symbol_output(s)	((s)->status & SYM_OUTPUT)
#define	is_symbol_outscope(s)	((s)->status & SYM_OUTSCOPE)
#define	is_global(sp)		((sp)->level == GLOBAL_SCOPE)


#define	symbol_defined(s)	((s)->status |= SYM_DEFINED)
#define	symbol_used(s)		((s)->status |= SYM_USED)
#define	symbol_set(s)		((s)->status |= SYM_SET)
#define	symbol_output(s)	((s)->status |= SYM_OUTPUT)
#define	symbol_outscope(s)	((s)->status |= SYM_OUTSCOPE)


#define MAX_ERROR_COUNT 200	/* compilation halts when MAX_ERROR_COUNT reached */
#define MAX_ID_LEN	50	/* initial default length of an identifier */

/* size of tables used in the global optimizer phase */
#define REG_LIST	20	/* maximum number of register variable tracked */
#define AUTO_LIST	100	/* maximum number of local variables tracked */

/* switch label table */
struct swtab {
    LABEL	   tablab;	/* label tag value */
    LABEL	   deflab;	/* default label */
    LABEL	   beglab;	/* label at start of switch */
    LABEL 	   numlabs;	/* number of labels */
    LABEL *	   labels;	/* array of label tags */
    struct swtab  *next;	/* next table */
};

#define	ERROR_RESYNC	3	/* number of tokens to successfully parse
				   after an error before reporting another
				   error */

#define	FACIST_LEVEL	8	/* warnings to this level forced to errors */

/*
 *	List of symbolic constants for message numbers.
 *
 *	For text of message types see the 'cglbdef.c' module
 *
 *	It is EXTREMELY important that the order of this 
 *	enum statement is kept consistent with the table
 *	of messages in 'cglbdef.c'
 */

#ifdef EPOC
#include "c86.rsg"
#define	WARN_LEVEL1	WARN_EXTERN
#define	WARN_LEVEL2	WARN_NOHEX
#define	WARN_LEVEL3	WARN_DUBIOUS
#define	WARN_LEVEL4	WARN_ADDFUNC
#define WARN_LEVEL5	WARN_ACCESS
#define WARN_LEVEL6	WARN_CHAR
#define WARN_LEVEL7	WARN_BITWISE
#define	WARN_LEVEL8	WARN_NOIMPLICIT
#define	MSG_BASE	MSG_DEFAULTS
typedef	unsigned int	MSGNUM;
#else
enum   err_msgs {
/*
 *	Parsing Error messages
 *
 *	The ERR_ family are always errors, whatever the current settings
 *	of the error message level and warning message level options.
 */
	ERR_ADDREGVAR,
	ERR_ARG	,
	ERR_ARITHMETIC,
	ERR_ARRAYRETURN,
	ERR_BITFIELD,
	ERR_BRACE,
	ERR_BREAK,
	ERR_CASE,
	ERR_CAST,
	ERR_CASTCON,
	ERR_CHARCONST,
	ERR_CONST,
	ERR_CONSTEXPR,
	ERR_CONSTFLOAT,
	ERR_CONSTINT,
	ERR_CONT,
	ERR_COUNTPARAM,
	ERR_DEREF,
	ERR_DUPCASE,
	ERR_DUPDEFAULT,
	ERR_DUPLABEL,
	ERR_ENUMWRAP,
	ERR_EOF	,
	ERR_ESCRANGE,
	ERR_EXPREXPECT,
	ERR_FPCON,
	ERR_FUNC,
	ERR_IDEXPECT,
	ERR_IDLIST,
	ERR_ILLCAST,
	ERR_ILLCHAR,
	ERR_ILLCLASS,
	ERR_ILLINIT,
	ERR_ILLSIZEOF,
	ERR_ILLTYPE,
	ERR_ILLXCHAR,
	ERR_IMPLICITADDR,
	ERR_INCOMPLETE,
	ERR_INITSIZE,
	ERR_INTEGER,
	ERR_INTEXPR,
	ERR_LINKAGE,
	ERR_LVALUE,
	ERR_MINUS,
	ERR_MISMATCH,
	ERR_NESTED,
	ERR_NOFUNC,
	ERR_NOINIT,
	ERR_NOMEMBER,
	ERR_NOPOINTER,
	ERR_OBJECT,
	ERR_PARMS,
	ERR_PREPROC,
	ERR_PROTODEF,
	ERR_PROTO,
	ERR_PUNCT,
	ERR_QUAL,
	ERR_QUALIFIER,
	ERR_REDECL,
	ERR_REPRESENT,
#ifdef EXTENSION
	ERR_RESTRICT,
#endif /* EXTENSION */
	ERR_SCALAR,
	ERR_SIZE,
	ERR_STATIC,
	ERR_STRINGCONST,
	ERR_TAG,
	ERR_TYPE,
	ERR_UNDEFINED,
	ERR_UNDEFLAB,
	ERR_VOIDFUNC,
	ERR_VOIDPARM,
	ERR_VOIDRETURN,
	ERR_WIDTH,
/*
 *	Error/Warning messages are ordered in order of decreasing severity
 *
 *	Whether the messages are treated as errors or merely warnings will
 *	depend on the current setting of the error_option and warn_option
 *	settings (these can be changed by the user at run-time)
 */

/*
 *	Level 1
 *	This is the most severe level of warnings.   These should
 *	not be suppressed unless one is certain that is OK.
 */
#define	WARN_LEVEL1	WARN_EXTERN
	WARN_EXTERN,
	WARN_FLDTYPE,
	WARN_PRAGMA,
/*
 *	Level 2
 *	Default warning level.  These should normally be fixed.
 *	Typically this just requires a cast or something similar.
 */
#define	WARN_LEVEL2	WARN_NOHEX
	WARN_NOHEX,
	WARN_PARAMSIZE,
	WARN_SIZEOF0,
	WARN_SIZEOFBIG,
	WARN_TYPECAST,
/*
 *	Level 3
 *	Warnings at this level are often encountered when porting
 *	code. They are quite likely to indicate an error.
 */
#define	WARN_LEVEL3	WARN_DUBIOUS
	WARN_DUBIOUS,
	WARN_ESCAPECH,
	WARN_IMPLICITFN,
	WARN_LOCAL,
	WARN_OUTSCOPE,
	WARN_PTRCAST,
	WARN_QUALIFIER,
	WARN_SHORTPTR,
	WARN_STATIC,
	WARN_STDARG,
	WARN_VALRETURN,
	WARN_UNSIGNED,
	WARN_ZERO,
/*
 *	Level 4
 *	Warnings at this level are often encountered when porting
 *	code, but are quite likely not be an error.
 */
#define	WARN_LEVEL4	WARN_ADDFUNC
	WARN_ADDFUNC,
	WARN_CASTCONST,
	WARN_CONDVOID,
	WARN_EMPTY,
	WARN_GLOBAL,
	WARN_HIDE,
	WARN_IMPLICIT,
	WARN_NOTREACHED,
	WARN_POINTER,
	WARN_PROTOTYPE,
	WARN_PROMOTE,
	WARN_SHIFT,
	WARN_STORAGE,
/*
 *	Level 5
 *	These are warnings for things that are common C practise, but
 *	that might possibly indicate an error if you are having trouble
 *	tracking down a particular problem
 */
#define WARN_LEVEL5	WARN_ACCESS
	WARN_ACCESS,
	WARN_ASSIGN,
	WARN_CONST,
	WARN_CONSTINIT,
	WARN_DISCARD,
	WARN_ELSE,
	WARN_FORMAT,
	WARN_IGNORE,
	WARN_IMPLICITRET,
	WARN_LABNOTUSED,
	WARN_MINUS,
	WARN_MODIFIED,
	WARN_NEGATIVE,
	WARN_NOPROTO,
	WARN_NOTSET,
	WARN_NOTUSED,
/*
 *	Level 6 - Only output if checking for portability
 *	Warnings at this level are normally too pedantic to be useful
 */
#define WARN_LEVEL6	WARN_CHAR
	WARN_CHAR,
	WARN_CONSTANT,
	WARN_CONSTCAST,
	WARN_ENUM,
#ifdef FLOAT_CHECK
	WARN_FLOAT,
#endif /* FLOAT_CHECK */
	WARN_INCOMPLETE,
	WARN_NARROWER,
/*
 *	Level 7 - Only output if "tidying" up your code
 *	Warnings at this level are normally too pedantic to be useful
 */
#define WARN_LEVEL7	WARN_BITWISE
	WARN_BITWISE,
	WARN_BRACE,
	WARN_DEFAULT,
#ifdef FACIST
	WARN_KEYWORD,
#endif /* FACIST */
	WARN_NULLCAST,
	WARN_OLDDEF,
	WARN_VOID,

/*
 *	level 8 - Only output if really strict checking is to be done.
 *	Warnings at this level are really "facist".
 */
#ifdef FACIST
#define	WARN_LEVEL8	WARN_NOIMPLICIT
	WARN_NOIMPLICIT,
#endif /* FACIST */
/*
 *	Messages below this point are output without file/line number details
 */
/*
 *	Miscellaneous messages
 */
#define	MSG_BASE	MSG_DEFAULTS
	MSG_DEFAULTS,
	MSG_ERROR,
	MSG_ERRORCNT,
	MSG_EXTRAPARAM,
	MSG_FATAL,
	MSG_FILENAMES,
	MSG_LABSYMTABLE,
	MSG_LINE,
	MSG_LOCALMEM,
	MSG_MAXERROR,
	MSG_MAXMEMORY,
	MSG_MEMORY,
	MSG_MISSING,
	MSG_NOMEMORY,
	MSG_OPENINPUT,
#ifdef LIST
	MSG_OPENLISTING,
#endif /* LIST */
	MSG_OPENOUTPUT,
	MSG_PEEPLABEL,
#ifdef VERBOSE
	MSG_PEEPCHANGES,
	MSG_RELEASEGLB,
	MSG_RELEASELOC,
#endif /* VERBOSE */
#ifdef SIGNAL
	MSG_SIGNAL,
#endif /* SIGNAL */
#ifdef VERBOSE
	MSG_TIMES,
#endif /* VERBOSE */
	MSG_UNKNOWNOPT,
	MSG_USEAGE,
	MSG_WARNING,
	MSG_WRITEFAIL
	};
typedef	enum err_msgs	MSGNUM;
#endif /* EPOC */

#ifdef DEBUG
/*
**	The following options are used to control internal debugging
**	options within the compiler.
*/
#define	DEBUG_GLOBAL	1	/* debugging the global optimiser */
#define	DEBUG_PEEP	2	/* debugging the peephole optimiser */
#define	DEBUG_EXPR	4	/* debugging the expression analysis */
#define	DEBUG_CODE	8	/* debugging the code generator */
#define	DEBUG_REGISTER	16	/* debugging the register handling */
#define	DEBUG_SYMBOL	32	/* debugging the symbol table handling */

#define	is_debugging(x)	(internal_option & (x))
#endif /* DEBUG */

/*
**	Some constants which cannot be easily represented by K&R compilers
**	as there is no such thing as an unsigned constant.   We instead
**	start it with a capital 'O' ... which makes it an identifier which
**	we can #define to the appropriate value depending on the compiler.
*/
#ifdef __STDC__
#define	Ox001fffffUL	(0x001fffffUL)
#define	Ox007fffffUL	(0x007fffffUL)
#define	Ox00ffffffUL	(0x00ffffffUL)
#define	Ox01ffffffUL	(0x01ffffffUL)
#define	Ox80000000UL	(0x80000000UL)
#define	Ox7fffffffUL	(0x7fffffffUL)
#define	OxffffffffUL	(0xffffffffUL)
#define	OxffefffffUL	(0xffefffffUL)
#else
#define	OxffefffffUL	((unsigned long)0xffefffff)
#define	Ox001fffffUL	((unsigned long)0x001fffff)
#define	Ox007fffffUL	((unsigned long)0x007fffff)
#define	Ox00ffffffUL	((unsigned long)0x00ffffff)
#define	Ox01ffffffUL	((unsigned long)0x01ffffff)
#define	Ox80000000UL	((unsigned long)0x80000000)
#define	Ox7fffffffUL	((unsigned long)0x7fffffff)
#define	OxffffffffUL	((unsigned long)0xffffffff)
#define	OxffefffffUL	((unsigned long)0xffefffff)
#endif /* __STDC__ */

/*
**	The following definitions are used to define the floating point
**	operations that are used within the compiler.   This allows the
**	operations to be defined in the most efficient means for the
**	host system.
*/
#ifdef EPOC
#define	FTST(d)		(p_fcmp(&d, &F_zero) == 0)
#define	FNEG(d1)	p_fneg(&d1)
#define	FASSIGN(d1,d2)	p_fld(&d1, &d2)
#define	FEQ(d1,d2)	(p_fcmp(&d1, &d2) == 0)
#define	FNE(d1,d2)	(p_fcmp(&d1, &d2) != 0)
#define	FLT(d1,d2)	(p_fcmp(&d1, &d2) < 0)
#define	FGT(d1,d2)	(p_fcmp(&d1, &d2) > 0)
#define	FGE(d1,d2)	(p_fcmp(&d1, &d2) >= 0)
#define	FLE(d1,d2)	(p_fcmp(&d1, &d2) <= 0)
#define	FADD(d1,d2)	p_fadd(&d1,&d2)
#define	FSUB(d1,d2)	p_fsub(&d1,&d2)
#define	FMUL(d1,d2)	p_fmul(&d1,&d2)
#define	FDIV(d1,d2)	p_fdiv(&d1,&d2)
#define	FIADD(d1,i)	do {RVAL d2; ITOF(d2,i); FADD(d1,d2); } while(0)
#define	FUMINUS(d1,d2)	FASSIGN(d1,d2); FNEG(d1)
#define	FADD3(d1,d2,d3)	FASSIGN(d1,d2); FADD(d1,d3)
#define	FSUB3(d1,d2,d3)	FASSIGN(d1,d2); FSUB(d1,d3)
#define	FMUL3(d1,d2,d3)	FASSIGN(d1,d2); FMUL(d1,d3)
#define	FDIV3(d1,d2,d3)	FASSIGN(d1,d2); FDIV(d1,d3)
#define	ITOF(d,i)	p_itof(&d,(WORD*)&i)
#define	LTOF(d,l)	p_longtof(&d,(LONG*)&l)
#define	UTOF(d,u)	p_longtof(&d,(LONG*)&u)
#define	FTOL(l,d)	p_intl((LONG*)&l,&d)
#else
#define	FTST(d1)	(d1)
#define	FNEG(d1)	(d1 = -d1)
#define	FASSIGN(d1,d2)	(d1 = d2)
#define	FEQ(d1,d2)	(d1 == d2)
#define	FNE(d1,d2)	(d1 != d2)
#define	FLT(d1,d2)	(d1 < d2)
#define	FGT(d1,d2)	(d1 > d2)
#define	FLE(d1,d2)	(d1 <= d2)
#define	FGE(d1,d2)	(d1 >= d2)
#define	FADD(d1,d2)	(d1 = d1 + d2)
#define	FIADD(d1,i)	(d1 += (RVAL)i)
#define	FSUB(d1,d2)	(d1 -= d2)
#define	FMUL(d1,d2)	(d1 *= d2)
#define	FDIV(d1,d2)	(d1 /= d2)
#define	FUMINUS(d1,d2)	(d1 = -d2)
#define	FADD3(d1,d2,d3)	(d1 = d2 + d3)
#define	FSUB3(d1,d2,d3)	(d1 = d2 - d3)
#define	FMUL3(d1,d2,d3)	(d1 = d2 * d3)
#define	FDIV3(d1,d2,d3)	(d1 = d2 / d3)
#define	ITOF(d,i)	(d = (RVAL)i)
#define	LTOF(d,l)	(d = (RVAL)l)
#define	UTOF(d,u)	(d = (RVAL)u)
#define	FTOL(l,d)	(l = (IVAL)d)
#endif /* EPOC */

#endif /* _CHDR_H */
