/*
 * datatypes.h
 */

typedef	char	generic;
typedef	int	bool;
#define FALSE	(bool)0
#define	TRUE	(!FALSE)
typedef	float	FLOAT;

#if	defined(ibmRT)
#	define	MAX_FLOAT	1.701e38
#endif
#if	defined(vax) || defined(vax3200) || defined(dgmv)
#	define	MAX_FLOAT	1.701e38
#endif

struct list_atom {
	generic *la_p;
	struct list_atom	*la_next;
};
typedef	struct list_atom LATOM;
typedef	struct list {
	int	list_n;
	LATOM	*list_head;
	LATOM	*list_tail;
	} LIST;

typedef enum data_type {
	integer,
	dbl,
	flt,
	byte,
	string,
	interval,
	boolean,
	set,
	rect
	} DATATYPE;
#define	isInteger(V) (V.val_type == integer? TRUE : FALSE)
#define	isDbl(V) (V.val_type == dbl? TRUE : FALSE)
#define	isFlt(V) (V.val_type == flt? TRUE : FALSE)
#define	isByte(V) (V.val_type == byte? TRUE : FALSE)
#define	isString(V) (V.val_type == string? TRUE : FALSE)
#define	isInterval(V) (V.val_type == interval? TRUE : FALSE)
#define	isBoolean(V) (V.val_type == boolean? TRUE : FALSE)
#define	isSet(V) (V.val_type == set? TRUE : FALSE)
#define	isRect(V) (V.val_type == rect? TRUE : FALSE)

#define	VtoInteger(V) (V).val_u.udt_int
#define	VtoDbl(V) (V).val_u.udt_dbl
#define	VtoFlt(V) (V).val_u.udt_flt
#define	VtoByte(V) (V).val_u.udt_byte
#define	VtoString(V) (V).val_u.udt_string
#define	VtoInterval(V) (V).val_u.udt_interval
#define	VtoBoolean(V) (V).val_u.udt_bool
#define	VtoSet(V) (V).val_u.udt_set
#define	VtoRect(V) (V).val_u.udt_rect



typedef	struct interval {
	double	int_lo, int_hi;
	} INTERVAL;

typedef	LIST	SET;

typedef	struct rect {
		FLOAT	r_diag[4];		/* xmin,ymin, xmax,ymax */
	} RECT;
#define	XMin	r_diag[0]
#define	YMin	r_diag[1]
#define	XMax	r_diag[2]
#define	YMax	r_diag[3]

typedef union data_types {
	char		udt_byte;
	int		udt_int;
	bool		udt_bool;
	double		udt_dbl;
	float		udt_flt;
	char		*udt_string;
	INTERVAL	udt_interval;
	SET		udt_set; 		/* {a,b,c,...}	*/
	RECT		udt_rect;
	} UTYPE;

typedef	struct	value	{
	DATATYPE	val_type;
	UTYPE		val_u;
	} VALUE;

#define	Vstrcmp(V, S)	(V.val_type==string? strcmp(V.val_u.udt_string,S)==0? TRUE : FALSE : FALSE)
#define	Vstrchr(V, C)	(V.val_type==string? strchr(V.val_u.udt_string,C)==(char *)NULL? FALSE : TRUE : FALSE)

typedef struct arg_def {
	VALUE	*ad_value;
	char	*ad_id;
	char	*ad_options;
	char	*ad_opttype;
	char	*ad_default;
	char	*ad_defaultType;
	char	**ad_helptext;
} ARGDEF;


#ifdef	ANSI_C
void	ErrorExit();
bool	Append(LIST *L, generic *Ptr);
char	*malloc(unsigned int);
char	*calloc(unsigned int, unsigned int);
char	*StrDup(char *Str);
void	get_args(
		int argc,
		char **argv,
		ARGDEF *Symbols[],
		char *Usage[],
		char *Function[]
	);
void	PrintArgDef(FILE *Fp, ARGDEF *D);
void	PrintArg(FILE *Fp, ARGDEF *D);
bool	ParseArg(ARGDEF *Symbols[], char *arg);
bool	ParseEntry(ARGDEF *Entry, char  *arg);
bool	ParseString(ARGDEF *Entry, char *Option, int n, char *arg);
bool	ParseDbl(ARGDEF *Entry, char *arg);
bool	ParseFloat(ARGDEF *Entry, char *arg);
bool	ParseInt(ARGDEF *Entry, char *arg);
bool	ParseBool(ARGDEF *Entry, char *arg);
bool	ParseByte(ARGDEF *Entry, char *arg);
bool	ParseInterval(ARGDEF *Entry, char *arg);
bool	ParseSet(ARGDEF *Entry, char *arg, char *Type, int TypeWidth);
bool	ParseRect(ARGDEF *Entry, char *arg);

void	PrintUsage(
		FILE	*Fp,
		char	*Usage[],
		char	*Function[],
		ARGDEF	*Symbols[]
	);
void	SetDefaults(ARGDEF *Symbols[]);
bool	SetValue(VALUE *, char *Value, char *Type);
bool	SetString(VALUE *, char *);
bool	SetDbl(VALUE *, char *);
bool	SetFloat(VALUE *, char *);
bool	SetInt(VALUE *, char *);
bool	SetBool(VALUE *, char *);
bool	SetByte(VALUE *, char *);
bool	SetInterval(VALUE *, char *);
bool	SetSet(VALUE *, char *, char *, int);
bool	SetRect(VALUE *, char *);

#else
#endif
