Пример #1
0
/**
 * 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;
}
Пример #2
0
/**
 * 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;
}