// 	LISTING 5. DFA.H
// Definitions and structs for DFA_CLASS object

// User-defined constants here;
//	these are the defaults		*/
#define LBR		'{'
#define RBR		'}'
#define GS		':'
#define FS		'\\'
#define EOR		'\n'
#define TAB		'\t'
#define DOT     '.'
#define WSPACE		' '
#define MAXBUFLEN	512

// Control modes for file operations
#define READ_TEXT		"rt"
#define READ_BINARY		"rb"
#define WRITE_TEXT		"wt"
#define WRITE_BINARY	"wb"

// DFA-specific constants are here,
//	and following. Dangerous to edit these.
#define GOOD    1
#define BAD	0
#define ERR    -1
#define OK	0
#define OUT	99
#define YES	1
#define NO	0
#define EMPTY  ((char) '\0')

// Definition of state table
// (a data table to the state machine)
typedef struct dfa {
    short (*target)(char *);   // validate token fcn
    short good;                // passed dest state
    short bad;                 // failed dest state
    short (*goodfcn)(char *);  // target passed
    short (*badfcn)(char *);   // target failed
} DFATBL;

// Definition of the state machinery:
typedef struct object {
// public-overidable elements
    DFATBL *tbl; 	// ptr to the state table
    FILE *infile;	// input file to be parsed
    char *(*get_token)(struct object *); // tokenizer
    char *delim;        // ptr to string of delimiters
// Internal working variables
    short (*movest)(struct object *, short);
    short ndx;	    	// current index (substate)
    short oflag;        // general work flag
    char *wp;           // ptr into workbuf
    int  cp;            // character holding area
    char workbuf[MAXBUFLEN];// working area
} DFA_CLASS;


extern DFA_CLASS *o;
extern short need_token;
extern short linenbr;
extern short StateMachine(DFA_CLASS *);
extern void InitStateMachine(DFA_CLASS *,
            	void *, char *, FILE *, char *);

// declarations for DFA_CLASS functions	*/
extern short block(char *);
extern short errmsg(char *);
extern char *get_token(DFA_CLASS *);
extern short isEOF(char *);
extern short isFS(char *);
extern short isGS(char *);
extern short isLBR(char *);
extern short isRBR(char *);
extern short move(DFA_CLASS *, short);
extern void  mystrtok(char *, char *, char *);
extern short skip(char *);

#define IGNORE(x)       (x);      // for portability
#define CURRENT_STATE   (o->ndx)
#define STATE_TBL       o->tbl
#define GOODSTATE   (STATE_TBL[CURRENT_STATE].good)
#define BADSTATE    (STATE_TBL[CURRENT_STATE].bad)
#define GOODFCN(x)  \
	((*(STATE_TBL[CURRENT_STATE].goodfcn))(x))
#define BADFCN(x)   \
	((*(STATE_TBL[CURRENT_STATE].badfcn))(x))
#define TARGET(x)   \
        ((*(STATE_TBL[CURRENT_STATE].target))(x))
#define NEXT_STATE(x)   ((*o->movest)(o,x))
#define GET_TOKEN       ((*o->get_token)(o))
#define INFILE			(o->infile)

// Useful Macros
#define PTRSUB(p,x)     ((long) p - (long) x)
#define PTRADD(p,x)     ((long) p + (long) x)
#define LASTBYTE(x)     (x[strlen(x)-1])
#define DIMEN(x)	(sizeof(x)/sizeof(x[0]))


