/** * Parse the planet string and its sub elements * @param topLevel Pointer to the string structure to be parsed * @return Returns a pointer to a planet structure with associated data. Null on failure **/ pPlanet planetTopLevel( pstring topLevel ) { int endIndex = 0; int temp_index = 0; pPlanet newPlanet = NULL; element el; char *fl = NULL; int lastGood = 0; if ( topLevel == NULL ) { goto end; } /// Skip any leading spaces skipWhiteSpace( topLevel ); lastGood = topLevel->index; if ( topLevel->maxlength < 9 ) { goto end; } char *c = "{Planet}"; for ( int i = 0; i < 8; i++ ) { if ( topLevel->buffer[ topLevel->index + i ] != c[i] ) { goto end; } } /// Skip 8 bytes of top level then any whitespace topLevel->index += 8; skipWhiteSpace( topLevel ); /// Allocate a new planet structure if ( allocate( sizeof(Planet), 0, (void**)&newPlanet) != 0 ) { goto end; } initPlanet( newPlanet ); /// Extract the next element name fl = pullNextElementName( topLevel ); getIndex( topLevel, &lastGood); while ( fl != NULL ) { /// Convert the element name el = elementNameToEnum( fl ); /// The name is no longer needed so free it deallocate( fl, strlen(fl) + 1 ); switch (el) { case name: fl = extractName( topLevel ); if ( fl == NULL ) { goto error; } bzero( newPlanet->name, 20 ); strncpy( newPlanet->name, fl, 19 ); deallocate(fl, strlen(fl) + 1 ); fl = NULL; break; case population: newPlanet->population = extractPopulation( topLevel ); if ( newPlanet->population < 0 ) { goto error; } break; case period: /// Extract period and check result newPlanet->period = extractPeriod( topLevel ); if ( newPlanet->period < 0.0 ) { goto error; } break; case orbitspeed: newPlanet->orbitspeed = extractOrbitSpeed( topLevel ); if ( newPlanet->orbitspeed < 0.0 ) { goto error; } break; case aphelion: newPlanet->aphelion = extractAphelion( topLevel ); if ( newPlanet->aphelion < 0.0 ) { goto error; } break; case perihelion: newPlanet->perihelion = extractPerihelion( topLevel ); if ( newPlanet->perihelion < 0.0 ) { goto error; } break; case radius: newPlanet->radius = extractRadius( topLevel ); if ( newPlanet->radius < 0.0 ) { goto error; } break; case eradius: newPlanet->eradius = extractERadius( topLevel ); if ( newPlanet->eradius < 0.0 ) { goto error; } break; case mass: newPlanet->mass = extractMass( topLevel ); if ( newPlanet->mass < 0.0 ) { goto error; } break; case gravity: newPlanet->gravity = extractGravity( topLevel ); if ( newPlanet->gravity < 0.0 ) { goto error; } break; case country: if ( newPlanet->country_count >= COUNTRYMAX ) { printf("!!Only @d countries allowed\n", COUNTRYMAX); goto error; } newPlanet->countries[ newPlanet->country_count] = countryTopLevel(topLevel); if (newPlanet->countries[ newPlanet->country_count ] == NULL ) { goto error; } newPlanet->country_count++; break; default: printf("Not allowed under Planet\n", fl); goto error; break; }; getIndex( topLevel, &lastGood ); fl = pullNextElementName( topLevel ); } /// Since no more valid elements need to be parsed, check the closing element skipWhiteSpace( topLevel ); if ( !atChar( topLevel, '{' ) ) { printf("!!Closing value failed for Planet\n"); goto error; } /// Skip the open brace if ( incChar( topLevel ) < 0 ) { goto error; } skipWhiteSpace( topLevel ); if ( !atChar( topLevel, '#' ) ) { printf("!!Malformed closing element\n"); goto error; } /// Skip past # if ( incChar( topLevel ) == -1 ) { goto error; } getIndex( topLevel, &temp_index ); endIndex = skipAlpha( topLevel ); if ( endIndex == -1 ) { endIndex = 0; goto error; } if ( temp_index == endIndex ) { goto error; } fl = copyData( topLevel, temp_index, endIndex ); if ( fl == NULL ) { goto error; } if ( strcmp( fl, "Planet") != 0 ) { printf("!!Closing element malformed\n"); deallocate( fl, (endIndex-temp_index) + 1 ); goto error; } deallocate(fl, (endIndex-temp_index) + 1 ); skipWhiteSpace( topLevel ); if ( !atChar( topLevel, '}' ) ) { printf("!!Failed to find final closing brace\n"); goto error; } incChar(topLevel); goto end; error: topLevel->index = lastGood; printf("!!Error at: @s\n", topLevel->buffer + topLevel->index); if ( newPlanet != NULL ) { freePlanet( newPlanet ); newPlanet = NULL; } end: return newPlanet; }
/** * Top level function for parsing a City PML element * @param str Pointer to a string structure * @return Returns a pointer to a filled in city structure or NULL on failure **/ pCity cityTopLevel( pstring str ) { int lastGood = 0; pCity newCity = NULL; int startIndex = 0; int endIndex = 0; char *temp = NULL; int tempInt = 0; element el; if ( str == NULL ) { goto end; } /// Skip the opening "{" if ( skipOpen( str, 0 ) == 0 ) { goto end; } /// Get the start and end index of the element id getIndex( str, &startIndex); endIndex = skipAlpha(str); if ( endIndex == -1 ) { goto end; } if ( startIndex == endIndex ) { goto end; } temp = copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto end; } if ( strcmp( temp, "City") != 0 ) { deallocate(temp, cgc_strlen(temp) + 1 ); goto end; } deallocate(temp, cgc_strlen(temp) + 1 ); skipWhiteSpace( str ); if ( !atChar( str, '}') ) { goto end; } incChar( str ); skipWhiteSpace(str); lastGood = str->index; if ( allocate( sizeof(City), 0, (void**)&newCity) != 0 ) { newCity = NULL; goto error; } initCity( newCity ); temp = pullNextElementName( str ); while ( temp != NULL ) { el = elementNameToEnum( temp ); deallocate(temp, cgc_strlen(temp) + 1 ); switch (el) { case name: temp = extractName( str ); if ( temp == NULL ) { goto error; } /// Clear it out bzero( newCity->name, 20 ); /// Copy the name data. It has already been filtered /// for invalid characters. strncpy( newCity->name, temp, 19); /// Free the buffer deallocate( temp, cgc_strlen(temp) + 1 ); temp = NULL; break; case mayor: temp = extractMayor( str ); if ( temp == NULL ) { goto error; } bzero( newCity->mayor, 30 ); #ifdef PATCHED strncpy( newCity->mayor, temp, 29 ); #else strcpy( newCity->mayor, temp ); #endif freeCharPtr( &temp ); break; case url: temp = extractUrl( str ); if ( temp == NULL ) { goto error; } bzero( newCity->url, 30 ); strncpy( newCity->url, temp, 29 ); freeCharPtr( &temp ); break; case border: if ( newCity->border_count >= CITYBORDERMAX) { goto error; } tempInt = newCity->border_count; newCity->borders[ tempInt ] = extractBorder(str); if ( newCity->borders[ tempInt] == NULL ) { goto error; } newCity->border_count++; break; case population: newCity->population = extractPopulation( str ); if ( newCity->population < 0 ) { goto error; } break; default: printf("!!Invalid element ID for City\n"); goto error; break; }; lastGood = str->index; temp = pullNextElementName(str); } if ( skipOpen( str, 1) == 0 ) { goto error; } getIndex( str, &startIndex); endIndex = skipAlpha( str ); if ( endIndex == -1 ) { goto error; } else if ( startIndex == endIndex ) { goto error; } temp = copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto error; } if ( strcmp( temp, "City") != 0 ) { deallocate(temp, cgc_strlen(temp) + 1 ); goto error; } deallocate( temp, cgc_strlen(temp) + 1 ); skipWhiteSpace(str); if ( !atChar( str, '}') ) { goto error; } incChar(str); goto end; error: if ( newCity ) { freeCity( newCity ); newCity = NULL; } printf("!!Error at: @s\n", str->buffer + lastGood); str->index = lastGood; end: return newCity; }