/*	    LISTING 7. DFAFCNS.C	            */
/* Collection of functions to support the DFA 	    */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dfa.h"

/****************************************************/
/* The first few routines are support routines for  */
/*      the state machine.                          */
/* The second set are default target routines       */
/* The third set are default action routines	    */
/****************************************************/

/****************************************************/
/* STATE-MACHINE-SPECIFIC SUPPORT ROUTINES          */
/****************************************************/

// Init the state machine object so tokenizer can be
//      extracted. Setup a DFA_CLASS to allow tokenizer
//	to run without the state machine.
void InitStateMachine(
    DFA_CLASS *p,   	// user class to init
    void *statetbl,     // user's state table
    char *tokenizer,    // user-defined tokenizer
    FILE *infile,       // input file
    char *tokelims)     // token delimiters
{
    // Set the user's state table address
    p->tbl = statetbl;

    // Set the input file
    p->infile = infile;

    // Set default, or user's override, as tokenizer
    if (tokenizer == NULL) {
        p->get_token = get_token;
    }
    else {
    	p->get_token = tokenizer;
    }

    // Set the tokenizer's delimiters
    p->delim = tokelims;

    // Set the internal working variables
    p->movest = move;	// state transition fcn
    p->ndx = 0;			// initial state
    p->oflag = 0;		// init to clear

    memset(p->workbuf, 0, MAXBUFLEN);
    p->wp = &(p->workbuf[0]);
    p->cp = 0;

    return;
}


// Update state table index as the machine moves
//      to the next state.
short move(
    DFA_CLASS *o,       // ptr to current dfa
    short value)        // GOOD or BAD to next state
{
    CURRENT_STATE = value ? GOODSTATE : BADSTATE;
    return(CURRENT_STATE);
}

/***************************/
/* DEFAULT TARGET ROUTINES */
/***************************/
// Check if end of buffer (record) has been reached
short isEOF(
   char *token)
{
    return(token[0] == '\0');
}

// Check if end of buffer (record) has been reached
short isEOR(
   char *token)
{
    return(token[0] == EOR);
}

// Check if a Field Separator has been found
short isFS(
   char *token)
{
    return(token[0] == FS);
}

// Check if a Group Separator has been found
short isGS(
   char *token)
{
    return(token[0] == GS);
}

// Check if a Left Brace has been found
short isLBR(
   char *token)
{
    return(token[0] == LBR);
}

// Check if a Group Separator has been found
short isRBR(
   char *token)
{
    return(token[0] == RBR);
}


/***************************/
/* DEFAULT ACTION ROUTINES */
/***************************/

// Print out an error message
short errmsg(
   char *token)
{
    fprintf(stderr,
        "Error in state machine for token '%s'\n",
	        token);
    return(ERR);
}

// Function that does nothing;
// Allows moving to next state
short skip(
   char *token)
{
    IGNORE(token);
    return(1);
}

// Block tokenizer so same token can be reused
short block(
   char *token)
{
    IGNORE(token);
    need_token = NO;
    return(1);
}
