/* 7.7.3 <SUFFIX PROGRAM DATA> */ int scpiLex_SuffixProgramData(lex_state_t * state, scpi_token_t * token) { token->ptr = state->pos; skipChr(state, '/'); // TODO: strict parsing : SLASH? (ALPHA+ (MINUS? DIGIT)?) ((SLASH | DOT) (ALPHA+ (MINUS? DIGIT)?))* if (skipAlpha(state)) { skipChr(state, '-'); skipDigit(state); while (skipSlashDot(state)) { skipAlpha(state); skipChr(state, '-'); skipDigit(state); } } token->len = state->pos - token->ptr; if ((token->len > 0)) { token->type = SCPI_TOKEN_SUFFIX_PROGRAM_DATA; } else { token->type = SCPI_TOKEN_UNKNOWN; state->pos = token->ptr; token->len = 0; } return token->len; }
/** * 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; }
/** * Extracts the data from the Name element * @param str Pointer to a string structure * @return Returns a pointer to the name data or NULL on failure * The calling function must free the name pointer **/ char *extractName( pstring str ) { char *temp = NULL; char *name = NULL; int start = 0; int end = 0; /// These will be used specifically for the name data int ns = 0; int ne = 0; if (str == NULL ) { return name; } skipWhiteSpace(str); if ( !atChar( str, '{' ) ) { printf("!!Failed to locate opening brace\n"); return name; } /// Skip past the curly brace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip opening brace\n"); return name; } /// Skip any additional whitespace skipWhiteSpace(str); /// Save the index start = str->index; /// This should skip any to either whitespace or a closing '}' end = skipAlpha( str ); if ( end == -1 ) { printf("!!Failed to locate the end of the element id\n"); return NULL; } /// Copy the element id from the string temp = copyData( str, start, end ); #ifdef PATCHED if ( temp == NULL ) { return NULL; } #endif if ( temp == NULL ) { printf("!!Copy from @d to @d failed\n", start, end); return NULL; } /// If the element id is not "Name" then this is the wrong function if ( strcmp( temp, "Name") != 0 ) { printf("!!Element id is not \"Name\"\n"); deallocate( temp, strlen(temp) + 1 ); temp = NULL; return NULL; } /// The buffer is no longer needed so free it deallocate(temp, strlen(temp) + 1); /// Skip to the end of the element id skipWhiteSpace( str ); /// If it is not a closing brace then this is improperly formatted. if ( !atChar( str, '}' ) ) { printf("!!Failed to locate initial closing brace\n"); return NULL; } /// Skip the closing brace as well as any whitespace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip initial closing brace\n"); return NULL; } skipWhiteSpace( str ); /// Copy the start index to store the data ns = str->index; /// The name data must be alphanumeric ne = skipToNonAlphaNum( str ); if ( ne == -1 ) { printf("!!Failed to locate the end of the name data\n"); return NULL; } /// The rest of this code is a check to ensure proper formatting except for the copy data skipWhiteSpace( str ); /// If this is not an opening curly brace then fail if ( !atChar( str, '{' ) ) { printf("!!Failed to locate the final opening brace\n"); return NULL; } /// Skip past the brace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip the final opening brace\n"); return NULL; } skipWhiteSpace(str); /// If this is not a # indicating the closing brace then fail if ( !atChar( str, '#' ) ) { printf("!!Failed to locate the closing mark\n"); return NULL; } /// Skip past the # but save the start start = skipLength( str, 1 ); if ( start == -1 ) { printf("!!Failed to skip closing mark\n"); return NULL; } end = skipAlpha( str ); if ( end == -1 ) { printf("!!Failed to locate the end of the closing element id\n"); return NULL; } temp = copyData( str, start, end ); #ifdef PATCHED if ( temp == NULL ) { return NULL; } #endif if ( strcmp( temp, "Name") != 0 ) { printf("!!Invalid closing element id: @s\n", temp); deallocate(temp, strlen(temp)+1); return NULL; } deallocate(temp, strlen(temp)+1); skipWhiteSpace( str ); /// Check the final curly brace if ( !atChar( str, '}' ) ) { printf("!!Failed to locate final closing brace\n"); return NULL; } /// Skip past the closing brace skipLength( str, 1 ); /// Copy the name element data name = copyData( str, ns, ne ); return name; }
/** * Parse the Border element and return a structure containing the data * @param str Pointer to a string structure * @return Returns a pointer to a border structure or NULL on failure **/ Border *extractBorder( pstring str ) { char *temp = NULL; pBorder bor = NULL; int start = 0; int end = 0; if (str == NULL ) { return bor; } /// Allocate a new border structure if ( allocate( sizeof(Border), 0, (void**)&bor) != 0 ) { bor = NULL; return bor; } skipWhiteSpace(str); /// If it does not open with a '{' then it is invalid. if ( !atChar( str, '{' ) ) { printf("!!Failed to locate opening brace\n"); goto error; } /// Skip past the curly brace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip opening brace\n"); goto error; } /// Skip any additional whitespace skipWhiteSpace(str); /// Save the index start = str->index; /// This should skip any to either whitespace or a closing '}' end = skipAlpha( str ); if ( end == -1 ) { printf("!!Failed to locate the end of the element id\n"); goto error; } /// If start and end are then same then it is an invalid character if ( start == end ) { goto error; } /// Copy the element id from the string temp = copyData( str, start, end ); if ( temp == NULL ) { printf("!!Copy from @d to @d failed\n", start, end); goto error; } /// If the element id is not "Border" then this is the wrong function if ( strcmp( temp, "Border") != 0 ) { printf("!!Element id is not \"Border\"\n"); deallocate( temp, strlen(temp) + 1 ); temp = NULL; goto error; } /// The buffer is no longer needed so free it deallocate(temp, strlen(temp) + 1); /// Skip to the end of the element id skipWhiteSpace( str ); /// If it is not a closing brace then this is improperly formatted. if ( !atChar( str, '}' ) ) { printf("!!Failed to locate initial closing brace\n"); goto error; } /// Skip the closing brace as well as any whitespace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip initial closing brace\n"); goto error; } start = skipWhiteSpace( str ); /// The border data must be a float end = skipFloat( str ); if ( start == end ) { printf("!!Failed to locate first lat\n"); goto error; } if ( end == -1 ) { printf("!!Failed to locate the end of the first latitude float\n"); goto error; } temp = copyData( str, start, end ); if (temp == NULL ) { printf("!!Failed to copy first latitude float\n"); goto error; } /// Convert the first value bor->latStart = atof( temp ); deallocate( temp, (end-start) + 1 ); /// Skip to the next value start = skipWhiteSpace( str ); end = skipFloat(str); if ( start == end ) { printf("!!Failed to locate first long\n"); goto error; } if ( start == -1 || end == -1 ) { printf("!!Failed to locate first longitude float\n"); goto error; } temp = copyData( str, start, end ); if ( temp == NULL ) { printf("!!Failed to copy first longitude float\n"); goto error; } /// Convert the first long bor->lngStart = atof( temp ); deallocate( temp, (end-start) + 1 ); /// Skip to the next value start = skipWhiteSpace( str ); end = skipFloat(str); if ( start == end ) { printf("!!Failed to locate second lat\n"); goto error; } if ( start == -1 || end == -1 ) { printf("!!Failed to locate second latitude float\n"); goto error; } temp = copyData( str, start, end ); if ( temp == NULL ) { printf("!!Failed to copy second latitude float\n"); goto error; } /// Convert the second lat bor->latEnd = atof( temp ); deallocate( temp, (end-start) + 1 ); /// Skip to the next value start = skipWhiteSpace( str ); end = skipFloat(str); if ( start == end ) { printf("!!Failed to locate second long\n"); goto error; } if ( start == -1 || end == -1 ) { printf("!!Failed to locate second longitude float\n"); goto error; } temp = copyData( str, start, end ); if ( temp == NULL ) { printf("!!Failed to copy second longitude float\n"); goto error; } /// Convert the second long bor->lngEnd = atof( temp ); deallocate( temp, (end-start) + 1 ); skipWhiteSpace( str ); /// If this is not an opening curly brace then fail if ( !atChar( str, '{' ) ) { printf("!!Failed to locate the final opening brace\n"); goto error; } /// Skip past the brace if ( skipLength( str, 1 ) == -1 ) { printf("!!Failed to skip the final opening brace\n"); goto error; } skipWhiteSpace(str); /// If this is not a # indicating the closing brace then fail if ( !atChar( str, '#' ) ) { printf("!!Failed to locate the closing mark\n"); goto error; } /// Skip past the # but save the start start = skipLength( str, 1 ); if ( start == -1 ) { printf("!!Failed to skip closing mark\n"); goto error; } end = skipAlpha( str ); if ( end == -1 ) { printf("!!Failed to locate the end of the closing element id\n"); goto error; } temp = copyData( str, start, end ); #ifdef PATCHED if ( temp == NULL ) { goto error; } #endif if ( strcmp( temp, "Border") != 0 ) { printf("!!Invalid closing element id: @s\n", temp); deallocate(temp, strlen(temp)+1); goto error; } deallocate(temp, strlen(temp)+1); skipWhiteSpace( str ); /// Check the final curly brace if ( !atChar( str, '}' ) ) { printf("!!Failed to locate final closing brace\n"); goto error; } /// Skip past the closing brace skipLength( str, 1 ); /// Everything succeeded, skip error goto fin; error: deallocate( bor, sizeof(Border) ); bor = NULL; fin: return bor; }
/** * Extract the data from the Url element. * This can be something such as http://www.rome.com * @param str Pointer to a string structure * @return Returns the element data or NULL on failure * The caller is responsible for freeing the pointer **/ char *extractUrl( pstring str ) { char *url = NULL; int startIndex = 0; char *temp = NULL; if ( str == NULL ) { goto end; } if ( skipOpen( str, 0 ) == 0 ) { goto end; } getIndex( str, &startIndex ); skipAlpha(str); url = copyData( str, startIndex, str->index); if ( url == NULL ) { goto end; } if ( strcmp( url, "Url" ) ) { freeCharPtr( &url ); goto end; } skipWhiteSpace( str ); if (!atChar( str, '}') ) { goto end; } incChar(str); skipWhiteSpace(str); getIndex( str, &startIndex); skipUrl( str ); url = copyData( str, startIndex, str->index ); if ( url == NULL ) { goto end; } skipWhiteSpace(str); if ( skipOpen( str, 1 ) == 0 ) { goto error; } getIndex( str, &startIndex ); skipAlpha(str); temp = copyData( str, startIndex, str->index); if ( temp == NULL ) { goto error; } if ( strcmp( temp, "Url") != 0 ) { freeCharPtr( &temp ); goto error; } freeCharPtr( &temp ); skipWhiteSpace(str); if ( !atChar( str, '}') ) { goto error; } incChar(str); goto end; error: if ( url ) { freeCharPtr( &url ); } end: return url; }
/** * Extracts the data from the Mayor element id * @param str Pointer to a string structure * @return Returns a pointer to the data or NULL on failure * The caller must free the pointer **/ char *extractMayor( pstring str ) { char *mayor = NULL; register int startIndex = 0; register int endIndex = 0; char *temp = NULL; if ( !str ) { return NULL; } /// This skips any whitespace and opening '{ ' if (skipOpen(str, 0 ) == 0 ) { return NULL; } startIndex = str->index; endIndex = skipAlpha(str); if ( endIndex == -1 || startIndex == endIndex ) { return NULL; } mayor = copyData( str, startIndex, endIndex ); if ( mayor == NULL ) { return NULL; } if ( strcmp( mayor, "Mayor") != 0 ) { freeCharPtr( &mayor ); return NULL; } freeCharPtr( &mayor ); skipWhiteSpace( str ); if (!atChar( str, '}') ) { return NULL; } /// Skip the Closing brace incChar( str ); startIndex = skipWhiteSpace(str); /// Using this function allows things like Sir Winston Churchill 3rd endIndex = skipToNonAlphaNumSpace( str ); if ( endIndex < 0 || startIndex == endIndex ) { return NULL; } while ( isspace( str->buffer[endIndex-1] ) ) { endIndex--; } mayor = copyData( str, startIndex, endIndex ); if ( mayor == NULL ) { return NULL; } skipWhiteSpace(str); /// Skip the opening brace and '#' if ( skipOpen( str, 1 ) == 0 ) { goto error; } startIndex = str->index; endIndex = skipAlpha( str ); if ( endIndex == -1 || startIndex == endIndex ) { goto error; } temp = copyData( str, startIndex, endIndex ); if ( temp == NULL ) { goto error; } if ( strcmp( temp, "Mayor") != 0 ) { freeCharPtr( &temp ); goto error; } skipWhiteSpace(str); if ( !atChar( str, '}' ) ) { goto error; } incChar(str); goto end; error: freeCharPtr( &mayor ); end: return mayor; }
/** * 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; }