/****************************************************/
/*	LISTING 2. SYNDOS.C                         */
/* Syntactically parse a testfile of restricted DOS */
/*      pathanames. Use the DFA state machine and   */
/*	the state table defined in dostbl1.h        */
/* Print out each component after parsing	    */
/* Parsing rule:   a: (\ax*)+ (.x)(x)(x) e	    */
/*                                                  */
/*  Copyright August 29, 1991 by Alan Cline	    */
/*      Carolla Development, Dublin, Ohio           */
/****************************************************/

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

#define TESTFILE    "testfile.dat"
#define DELIMSTR	":.\\"

// Global storage to test parsing
char drive;
char pathname[MAXBUFLEN];
char fname[9];
char ext[5];
char *tokeptr;
char tokebuf[15];

short reset(void);


void main(void)
{
	DFA_CLASS syndos_dfa;
	FILE *fp;
	short retval = OK;

	// Open the test names file
	fp = fopen(TESTFILE, READ_TEXT);

	while (!feof(fp) && retval != ERR) {
		// Init each component variable
		drive = EMPTY;
		pathname[0] = EMPTY;
		fname[0] = EMPTY;
		ext[0] = EMPTY;
		tokeptr = memset(tokebuf, 0, sizeof(tokebuf));

		// Initialize the DFA and begin parsing
		// Pass dfa, state table, override-tokenizer,
		//    input file, delimeters
		InitStateMachine(&syndos_dfa, &syndos_stt,
					NULL, fp, DELIMSTR);

		retval = StateMachine(&syndos_dfa);
	}

	// End test run; close file and quit
	fclose(fp);
	return;
}

/*********************************/
/* Application-specific routines */
/*********************************/


// Define the character-oriented tokenizer
char *get_token(
	DFA_CLASS *o)
{
	*o->wp = (char) getc(INFILE);

	// force EOR as front token
	if (*o->wp == EOR) {
		if (o->cp != (int) EOR){
			ungetc((int) *o->wp, INFILE);
			o->cp = (int) EOR;
		}
		else
			o->cp = 0;
	}

	return(o->wp);
}


/***************************/
/* DEFAULT TARGET ROUTINES */
/***************************/

// Check if the character is alphabetic
short alpha(
	char *token)
{
	return(isalpha((int) token[0]));
}

// Check if the character is alphanumeric
short alphanum(
	char *token)
{
	return(isalnum((int) token[0]));
}

// Check if character is a dot
short isdot(
	char *token)
{
	return(*token == '.');
}


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

// Move a character into the work buffer
// then increment the ptrs.
short pushchar(
	char *token)
{
	*tokeptr = token[0];
	tokeptr++;
	*tokeptr = '\0';
	return(1);
}

// NULL terminate workbuffer;
// Return ptr to start of workbuf
short reset(void)
{
	tokeptr = memset(tokebuf, 0, sizeof(tokebuf));
	return(1);
}


/*****************************************/
/* Application-specific action routines  */
/*****************************************/

// Save the drive letter tokenized;
// Reset the dfa workbuffer
short appendpath(
	char *token)
{
	strncat(pathname, tokebuf, strlen(tokebuf));
	strncat(pathname, token, 1);
	reset();
	return(1);

}

// Print out each component of the parsed pathname
short cleanup(
   char *token)
{
	IGNORE(token);
	printf("File: %s\n\tDrive: %c\n",
			fname, drive);
	printf("\tPath: %s\n\tExtension: %s\n",
			pathname, ext);
	return(1);
}

// Save the drive letter
short savedrive(
	char *token)
{
	IGNORE(token);
	drive = (toupper((int) tokebuf[0]));
	reset();
	return(1);
}

// Save the file extension
short saveext(
	char *token)
{
	IGNORE(token);
	strcpy(ext, tokebuf);
	reset();
	return(1);
}

// Save the filename
short savefname(
	char *token)
{
	IGNORE(token);
	strcpy(fname, tokebuf);
	reset();
	return(1);
}



