#include	<stdio.h>
#include	<ctype.h>
#include    <string.h>

/*
 *	tt2ht1.c
 *
 *	convert input file into html data table
 *
 */ 

#define	LINESIZE	     		512
#define MAXFIELDS               20
#define MAXFLDLEN               512
#define MAXDELIM                10




void trimWhiteSpace(char source[], char target[]) {
	//
	// remove all leading and trailing whitespace (including '\n')
	
	int i;
	
	// strip trailing whitespace
	for (i = strlen(source)-1; isspace(source[i]) && i >= 0 ; i-- ) {
		source[i] = '\0';
	}

	// count leading whitespace
	for (i = 0; isspace(source[i]) ; i++) {
	}

	// copy into target
	strcpy(target, &source[i]);
}


	
int parse_line(int itemDel[], char mString[], char fields[MAXFIELDS][MAXFLDLEN]) 
//
// parse mString into an array of separate fields
// 			accepts an array of item delimiters to determine breaks
//
//  method: loop through mString looking for delimiters
//  		while coping to target array.
//
	
{
		int     i           = 0,		// general purpose counter
				endFlag     = 0,        // flag for indicating record is finished
				readAt      = -1,       // reading position in source array
                currentFld  = 0,        // item in fields[] array
				destination = 0;        // destination in current field				
		
        do {
                // loop through mString
			
				readAt++;
				
				// loop through each possible delimiter
				for (i = 0; itemDel[i] != NULL && ! endFlag ; i++) {
					
					// check for delimeter or the end of string
					if ( mString[readAt] == itemDel[i] || mString[readAt]  == NULL )
						endFlag = 1;			// flag record as ended
				}

				// 

                if ( ! endFlag ) {
						//
                 		// copy the char
					
                        fields[currentFld][destination] = mString[readAt];
                        destination++;
                }
                else {
						//
						// end record, terminate this field
					
						fields[currentFld][destination] = '\0';    

						// check if field is empty before incrementing
						if ( fields[currentFld][0] != '\0')
                        	currentFld++;

						// reset for new field
						destination = 0;
						endFlag = 0;
                }    
				
				// error check: array limits
				if ( readAt      == LINESIZE  ||
				     currentFld  == MAXFIELDS ||
					 destination == MAXFLDLEN )
					break;
					
        } while ( mString[readAt] != NULL );
		
		// return number of fields found in line
        return currentFld;
}


main()
{
	char    oLine         [LINESIZE],							// original line from stdin
			line          [LINESIZE],							// edited   line from stdin
		    attributes	  [MAXFIELDS][MAXFLDLEN],				// attributes	
			record		  [MAXFIELDS][MAXFLDLEN];				// records from parse_line()
	int 	itemDelimeters[MAXDELIM] = {' ','\n','\t','\0'}, 	// item delimeters, space, tab, newline
		  	i                        = 0,						// general purpose counter
	        numberOfColumns          = 0,						// column count
			numberOfRows             = 0,						// row count
			mode 					 = 0,						// Modes, 0 = table, 1 = <top>, 2 = <attributes>
			attCnt 					 = 0;						// attribute counter
	char *cp;													// general purpose character pointer
	
			
	// loop through input
	while ( fgets( oLine, LINESIZE, stdin) != NULL ) {
				
		trimWhiteSpace(oLine, line);
		
		// switch various modes
		if (strcmp(line, "<top>")              == 0) {
			mode = 1; // mode = <top>
		}
		else if (strcmp(line, "<attributes>")  == 0) {
			mode = 2; // mode = <attributes>
		}
		else if (strcmp(line, "</top>")        == 0) {
			mode = 0; // mode = table
		}
		else if (strcmp(line, "</attributes>") == 0) {
			mode = 0; // mode = table
		}
		else if (strstr(line, "<delim")) {
			cp = strstr(line, "value=");
			itemDelimeters[0] = cp[6];
			itemDelimeters[1] = ' ';
			itemDelimeters[2] = '\n';
			itemDelimeters[3] = '\0';

			// sprintf(itemDelimeters, ":\n%c", cp[6]);  
		}
		else {
			//
			// handle data according to mode
			
			switch (mode) {
				case 1:
					//
					// reading <top>
					
					printf("%s\n", line);
					break;
					
				case 2:
					//
					// reading <attributes>
					
					strcpy(attributes[attCnt], line);
					
					attCnt++;
					break;
					
				default:
					//

					// reading table

					// parse line into columns
					numberOfColumns = parse_line(itemDelimeters, line, record);
		
					// if a column, display a row
					if (numberOfColumns > 0) {
						
						// new row
						numberOfRows++;
						printf("<!-- Row %d -->\n", numberOfRows);
						printf("<tr>\n");

						// loop through each record
						for ( i = 0 ; i < numberOfColumns ; i++ ) {
							printf("<td %s>%s</td>\n", attributes[i], record[i]);
						}
						printf("</tr>\n");
						printf("\n");
					}
					
			}
		}
	}	
}
