#include "cgc_countyParsers.h" int cgc_countyMenu( pCounty co ) { int choice = 0; char selection[30]; pBorder pb = NULL; pCity pc = NULL; if ( co == NULL ) { return 0; } while ( 1 ) { cgc_printf("County: @s\n", co->name ); cgc_printf("1) Display County Info\n"); cgc_printf("2) Set Seat\n"); cgc_printf("3) Set Population\n"); cgc_printf("4) Set Area\n"); cgc_printf("5) Set Density\n"); cgc_printf("6) Add Border\n"); cgc_printf("7) Add City\n"); cgc_printf("8) Select City\n"); cgc_printf("9) Delete County and Exit Menu\n"); cgc_printf("10) Exit Menu\n"); cgc_printf("Selection: "); cgc_bzero(selection, 4 ); cgc_receive_until( selection, '\n', 3); choice = cgc_atoi( selection ); cgc_bzero( selection, 30 ); switch( choice ) { case 1: cgc_printCountyInfo( co ); break; case 2: // Set Seat cgc_printf("\n-> "); cgc_receive_until(selection, '\n', 19 ); choice = 0; while ( cgc_isalpha( selection[choice] ) ) { co->seat[choice] = selection[choice]; choice++; } /// NULL terminated co->seat[choice] = '\x00'; break; case 3: // Set Population cgc_printf("\n-> "); cgc_receive_until( selection, '\n', 19 ); co->population = cgc_atoi(selection); break; case 4: /// Set Area cgc_printf("\n-> "); cgc_receive_until( selection, '\n', 19); co->area = cgc_atof( selection ); break; case 5: /// Set Density cgc_printf("\n-> "); cgc_receive_until( selection, '\n', 19); co->density = cgc_atof( selection ); break; case 6: /// Add border if ( co->border_count >= COUNTYBORDERMAX) { cgc_printf("!!Max borders reached\n"); break; } if ( cgc_allocate( sizeof(Border), 0, (void**)&pb) != 0 ) { pb = NULL; break; } cgc_printf("Lat Start: "); cgc_bzero(selection, 30 ); cgc_receive_until( selection, '\n', 19 ); pb->latStart = cgc_atof(selection); cgc_printf("Long Start: "); cgc_bzero(selection, 30 ); cgc_receive_until( selection, '\n', 19 ); pb->lngStart = cgc_atof(selection); cgc_printf("Lat End: "); cgc_bzero(selection, 30 ); cgc_receive_until( selection, '\n', 19 ); pb->latEnd = cgc_atof(selection); cgc_printf("Long End: "); cgc_bzero(selection, 30 ); cgc_receive_until( selection, '\n', 19 ); pb->lngEnd = cgc_atof(selection); co->borders[ co->border_count ] = pb; co->border_count++; break; case 7: /// Add City /// Find a free slot choice = 0; while ( choice < COUNTYCITYMAX ) { if ( co->cities[choice] == NULL ) { break; } choice++; } if ( choice == COUNTYCITYMAX ) { cgc_printf("!!Max cities reached\n"); continue; } if ( cgc_allocate( sizeof(City), 0, (void**)(&pc)) != 0 ) { pc = NULL; continue; } cgc_initCity( pc ); co->cities[choice] = pc; cgc_printf("New City Name: "); cgc_receive_until( selection, '\n', 19 ); choice = 0; while( cgc_isalnum( selection[choice] ) ) { pc->name[choice] = selection[choice]; choice++; } pc->name[choice] = '\x00'; co->city_count++; break; case 8: /// cgc_select city for ( choice = 0; choice < COUNTYCITYMAX; choice++ ) { if ( co->cities[choice] != NULL ) { cgc_printf("@d) @s\n", choice + 1, co->cities[choice]); } } cgc_printf("\n-> "); cgc_bzero( selection, 30 ); cgc_receive_until( selection, '\n', 4 ); choice = cgc_atoi( selection ); if ( choice < 1 || choice > COUNTYCITYMAX || co->cities[choice-1] == NULL ) { cgc_printf("Invalid choice\n"); continue; } if ( cgc_cityMenu( co->cities[choice-1] ) == 0 ) { co->cities[choice-1] = NULL; co->city_count--; } break; case 9: cgc_freeCounty( co ); return 0; break; case 10: return 1; break; default: cgc_printf("Invalid choice\n"); continue; }; } return 1; } void cgc_freeCounty( pCounty co ) { int index = 0; if ( co == NULL ) { return; } for ( index = 0; index < co->border_count; index++ ) { if ( co->borders[index] != NULL ) { cgc_deallocate(co->borders[index], sizeof(Border) ); co->borders[index] = NULL; } } for (index = 0; index < COUNTYCITYMAX; index++ ) { cgc_freeCity( co->cities[index] ); co->cities[index] = NULL; } cgc_deallocate( co, sizeof(County) ); return; } void cgc_initCounty( pCounty co ) { int index = 0; if ( co == NULL ) { return; } for ( index = 0; index < 20; index++ ) { co->name[index] = 0; co->seat[index] = 0; co->cities[index] = NULL; co->borders[index] = NULL; } co->population = -1; co->area = -1.0; co->density = -1.0; co->city_count = 0; co->border_count = 0; return; } void cgc_printCountyInfo( pCounty co ) { int index = 0; if ( co == NULL ) { return; } cgc_printf("\t\t\tCounty: "); if ( co->name[0] == '\x00' ) { cgc_printf("Unknown\n"); } else { cgc_printf("@s\n", co->name); } cgc_printf("\t\t\t\tSeat: "); if ( co->seat[0] == '\x00' ) { cgc_printf("Unknown\n"); } else { cgc_printf("@s\n", co->seat); } if ( co->population >= 0 ) { cgc_printf("\t\t\t\tPopulation: @d\n", co->population); } if ( co->area >= 0 ) { cgc_printf("\t\t\t\tArea: @f\n", co->area); } if ( co->density >= 0 ) { cgc_printf("\t\t\t\tDensity: @f\n", co->density); } for (index = 0; index < co->border_count; index++ ) { cgc_printf("\t\t\t\tBorder: @f @f @f @f\n", co->borders[index]->latStart, co->borders[index]->lngStart, co->borders[index]->latEnd, co->borders[index]->lngEnd); } for (index = 0; index < COUNTYCITYMAX; index++ ) { if ( co->cities[index] != NULL ) { cgc_printCityInfo( co->cities[ index ]); } } return; } pCounty cgc_countyTopLevel( pstring str ) { pCounty newCounty = NULL; int startIndex = 0; int endIndex = 0; int lastGood = 0; int tempInt = 0; char *tempChar = NULL; element el; if ( str == NULL ) { return NULL; } cgc_skipWhiteSpace( str ); lastGood = str->index; if ( !cgc_atChar( str, '{' ) ) { goto end; } cgc_incChar( str ); cgc_skipWhiteSpace(str); cgc_getIndex( str, &startIndex ); endIndex = cgc_skipAlpha( str ); if ( endIndex == -1 ) { goto end; } if ( startIndex == endIndex ) { goto end; } tempChar = cgc_copyData( str, startIndex, endIndex ); if ( tempChar == NULL ) { goto end; } if ( cgc_strcmp( tempChar, "County" ) != 0 ) { goto end; } cgc_deallocate(tempChar, (endIndex-startIndex)+1); cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '}') ) { goto end; } cgc_skipWhiteSpace( str ); /// Skip past the closing brace cgc_incChar( str ); if ( cgc_allocate( sizeof(County), 0, (void**)&newCounty) != 0 ) { newCounty = NULL; goto end; } lastGood = str->index; cgc_initCounty( newCounty ); tempChar = cgc_pullNextElementName( str ); while (tempChar != NULL ) { el = cgc_elementNameToEnum( tempChar ); cgc_deallocate( tempChar, cgc_strlen(tempChar) + 1 ); switch ( el ) { case name: tempChar = cgc_extractName( str ); if ( tempChar == NULL ) { goto error; } cgc_bzero( newCounty->name, 20 ); cgc_strncpy( newCounty->name, tempChar, 19 ); cgc_deallocate( tempChar, cgc_strlen(tempChar) + 1 ); tempChar = NULL; break; case seat: tempChar = cgc_extractSeat( str ); if ( tempChar == NULL ) { goto error; } cgc_bzero( newCounty->seat, 20 ); cgc_strncpy( newCounty->seat, tempChar, 19); cgc_deallocate( tempChar, cgc_strlen(tempChar) + 1 ); tempChar = NULL; break; case density: newCounty->density = cgc_extractDensity( str ); if ( newCounty->density < 0.0 ) { goto error; } break; case population: newCounty->population = cgc_extractPopulation( str ); if ( newCounty->population < 0 ) { goto error; } break; case area: newCounty->area = cgc_extractArea( str ); if ( newCounty->area < 0.0 ) { goto error; } break; case border: tempInt = newCounty->border_count; if ( tempInt >= COUNTYBORDERMAX ) { goto error; } newCounty->borders[ tempInt ] = cgc_extractBorder( str ); if ( newCounty->borders[tempInt] == NULL ) { goto error; } newCounty->border_count++; break; case city: tempInt = newCounty->city_count; if ( tempInt >= COUNTYCITYMAX ) { goto error; } newCounty->cities[ tempInt ] = cgc_cityTopLevel( str ); if ( newCounty->cities[tempInt] == NULL ) { goto error; } newCounty->city_count++; break; default: cgc_printf("!!Element not allowed\n"); goto error; break; }; cgc_getIndex( str, &lastGood); tempChar = cgc_pullNextElementName( str ); } /// Skip any residual white space cgc_skipWhiteSpace( str ); /// It must be at the final opening brace if ( !cgc_atChar( str, '{') ) { goto error; } cgc_skipLength( str, 1); cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '#' ) ) { goto error; } cgc_skipLength(str, 1); cgc_getIndex( str, &startIndex ); cgc_skipAlpha( str ); cgc_getIndex( str, &endIndex); if ( startIndex == endIndex ) { goto error; } else if ( endIndex == -1 ) { goto error; } tempChar = cgc_copyData( str, startIndex, endIndex ); if ( cgc_strcmp( tempChar, "County" ) != 0 ) { cgc_deallocate( tempChar, cgc_strlen(tempChar) + 1 ); goto error; } cgc_deallocate( tempChar, cgc_strlen(tempChar) + 1 ); cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '}' ) ) { goto error; } cgc_incChar( str ); goto end; error: if ( newCounty ) { cgc_freeCounty( newCounty ); newCounty = NULL; } cgc_printf("!!Error at: @s\n", str->buffer + lastGood ); str->index = lastGood; end: return newCounty; } int cgc_checkId ( pstring str, char *id, int ending ) { int retval = 0; int startIndex = 0; int endIndex = 0; char *temp = NULL; if ( str == NULL ) { goto end; } cgc_skipWhiteSpace( str ); if ( !cgc_atChar(str, '{')) { goto end; } cgc_incChar( str ); /// If it is the end check for # if ( ending == 1 ) { cgc_skipWhiteSpace(str); if ( !cgc_atChar( str, '#' ) ) { goto end; } cgc_incChar( str ); } startIndex = cgc_skipWhiteSpace( str ); endIndex = cgc_skipAlpha( str ); if ( endIndex == -1 ) { goto end; } else if ( startIndex == endIndex ) { goto end; } temp = cgc_copyData( str, startIndex, endIndex ); if ( !temp ) { goto end; } if ( cgc_strcmp( temp, id ) != 0 ) { cgc_deallocate( temp, cgc_strlen(temp) + 1 ); goto end; } cgc_deallocate( temp, cgc_strlen(temp) + 1 ); cgc_skipWhiteSpace( str ); if ( str->buffer[str->index] != '}' ) { goto end; } cgc_incChar( str ); retval = 1; end: return retval; } double cgc_extractDensity( pstring str ) { double density = -1.0; register int startIndex = 0; register int endIndex = 0; char *temp = NULL; int lastGood = 0; if ( str == NULL ) { goto end; } cgc_getIndex( str, &lastGood ); if ( cgc_checkId( str, "Density", 0) == 0 ) { goto error; } startIndex = cgc_skipWhiteSpace(str); endIndex = cgc_skipFloat( str ); if ( startIndex == endIndex ) { goto end; } if ( endIndex == -1 ) { goto end; } temp = cgc_copyData( str, startIndex, endIndex ); if (temp == NULL) { goto end; } density = cgc_atof( temp ); cgc_deallocate( temp, (endIndex-startIndex) + 1 ); temp = NULL; if ( cgc_checkId( str, "Density", 1 ) == 0 ) { goto error; } goto end; error: str->index = lastGood; density = -1.0; end: return density; } double cgc_extractArea( pstring str ) { double area = -1.0; int startIndex = 0; int endIndex = 0; char *temp = NULL; int lastGood = 0; if ( str == NULL ) { goto end; } cgc_skipWhiteSpace( str ); cgc_getIndex( str, &lastGood ); if ( str->buffer[ str->index ] != '{' ) { goto end; } cgc_incChar( str ); cgc_skipWhiteSpace( str ); cgc_getIndex( str, &startIndex); endIndex = cgc_skipAlpha( str ); if ( endIndex == -1 || startIndex == endIndex ) { goto end; } temp = cgc_copyData( str, startIndex, endIndex ); if ( !temp ) { goto end; } if ( cgc_strcmp( temp, "Area" ) != 0 ) { cgc_deallocate( temp, cgc_strlen(temp) + 1 ); goto end; } cgc_deallocate( temp, cgc_strlen(temp) + 1 ); cgc_skipWhiteSpace( str ); if ( str->buffer[str->index] != '}' ) { goto end; } cgc_incChar( str ); startIndex = cgc_skipWhiteSpace(str); endIndex = cgc_skipFloat( str ); if ( startIndex == endIndex ) { goto end; } if ( endIndex == -1 ) { goto end; } temp = cgc_copyData( str, startIndex, endIndex ); if (temp == NULL) { goto end; } area = cgc_atof( temp ); cgc_deallocate( temp, (endIndex-startIndex) + 1 ); temp = NULL; cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '{' ) ) { goto error; } cgc_incChar( str ); cgc_skipWhiteSpace(str); if (!cgc_atChar( str, '#' ) ) { goto error; } startIndex = cgc_incChar( str ); endIndex = cgc_skipAlpha( str ); temp = cgc_copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto error; } if ( cgc_strcmp( temp, "Area") != 0 ) { cgc_deallocate( temp, cgc_strlen(temp) + 1 ); goto error; } cgc_deallocate( temp, cgc_strlen(temp) + 1 ); cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '}') ) { goto error; } cgc_incChar( str ); goto end; error: str->index = lastGood; area = -1.0; end: return area; } char *cgc_extractSeat( pstring str ) { char *seat = NULL; int startIndex = 0; int endIndex = 0; char *temp = NULL; int lastGood = 0; if ( str == NULL ) { goto end; } cgc_skipWhiteSpace( str ); cgc_getIndex( str, &lastGood ); if ( str->buffer[ str->index ] != '{' ) { goto end; } cgc_incChar( str ); cgc_skipWhiteSpace( str ); cgc_getIndex( str, &startIndex); endIndex = cgc_skipAlpha( str ); if ( endIndex == -1 || startIndex == endIndex ) { goto end; } temp = cgc_copyData( str, startIndex, endIndex ); if ( !temp ) { goto end; } if ( cgc_strcmp( temp, "Seat" ) != 0 ) { cgc_deallocate( temp, cgc_strlen(temp) + 1 ); goto end; } cgc_deallocate( temp, cgc_strlen(temp) + 1 ); cgc_skipWhiteSpace( str ); if ( str->buffer[str->index] != '}' ) { goto end; } cgc_incChar( str ); startIndex = cgc_skipWhiteSpace(str); endIndex = cgc_skipAlpha( str ); if ( startIndex == endIndex ) { goto end; } if ( endIndex == -1 ) { goto end; } seat = cgc_copyData( str, startIndex, endIndex ); if (seat == NULL) { goto end; } cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '{' ) ) { goto error; } cgc_incChar( str ); cgc_skipWhiteSpace(str); if (!cgc_atChar( str, '#' ) ) { goto error; } startIndex = cgc_incChar( str ); endIndex = cgc_skipAlpha( str ); if ( startIndex == endIndex ) { goto error; } if ( endIndex == -1 ) { goto error; } temp = cgc_copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto error; } if ( cgc_strcmp( temp, "Seat") != 0 ) { cgc_deallocate( temp, cgc_strlen(temp) + 1 ); goto error; } cgc_deallocate( temp, cgc_strlen(temp) + 1 ); cgc_skipWhiteSpace( str ); if ( !cgc_atChar( str, '}') ) { goto error; } cgc_incChar( str ); goto end; error: if ( seat ) { cgc_deallocate( seat, cgc_strlen(seat) + 1 ); seat = NULL; } str->index = lastGood; end: return seat; }