Пример #1
0
ClassAd *ClassAdXMLParser::
ParseClassAd(ClassAd *classad_in)
{
	bool             in_classad;
	ClassAd          *classad = NULL;
	ClassAd          *local_ad = NULL;
	XMLLexer::Token  token;

	classad = NULL;
	in_classad = false;

	while (lexer.PeekToken(&token)) {
		if (!in_classad) {
			lexer.ConsumeToken(NULL);
			if (   token.token_type == XMLLexer::tokenType_Tag 
				&& token.tag_id     == XMLLexer::tagID_ClassAd) {
				
				// We have a ClassAd tag
				if (token.tag_type   == XMLLexer::tagType_Start) {
					in_classad = true;
					if ( classad_in ) {
						classad_in->Clear();
						classad = classad_in;
					} else {
						local_ad = new ClassAd();
						classad = local_ad;
					}
					classad->DisableDirtyTracking();
				} else {
					// We're done, return the ClassAd we got, if any.
                    in_classad = false;
					break;
				}
			}
		} else {
			if (token.token_type == XMLLexer::tokenType_Tag) {
			  if (token.tag_id   == XMLLexer::tagID_Attribute) {
			    if (token.tag_type == XMLLexer::tagType_Invalid) {
				  delete local_ad;
			      return NULL;
			    } else if( token.tag_type == XMLLexer::tagType_Start) {
					string attribute_name;
					ExprTree *tree;
					
					tree = ParseAttribute(attribute_name);
					if (tree != NULL) {
						classad->Insert(attribute_name, tree);
					}
					else {
					  delete local_ad;
					  return NULL;
					}
			    } else {
					lexer.ConsumeToken(NULL);
				}
              } else if (token.tag_id   == XMLLexer::tagID_ClassAd) {
                  lexer.ConsumeToken(NULL);
                  if (token.tag_type == XMLLexer::tagType_End) {
                      in_classad = false;
                      break;
                  } else {
                      // This is invalid, but we'll just ignore it.
                  }
			  } else if (   token.tag_id != XMLLexer::tagID_XML
							  && token.tag_id != XMLLexer::tagID_XMLStylesheet
							  && token.tag_id != XMLLexer::tagID_Doctype
							  && token.tag_id != XMLLexer::tagID_ClassAds) {
					// We got a non-attribute, non-xml thingy within a 
					// ClassAd. That must be an error, but we'll just skip
					// it in the hopes of recovering.
					lexer.ConsumeToken(NULL);
					break;
				}
			} else {
				lexer.ConsumeToken(NULL);
			}
		}
	}
	if (classad != NULL) {
		classad->EnableDirtyTracking();
	}
	return classad;
}
Пример #2
0
//  ClassAd       ::= '[' AttributeList ']'
//  AttributeList ::= (epsilon)
//                  | Attribute ';' AttributeList
//  Attribute     ::= Identifier '=' Expression
bool ClassAdParser::
parseClassAd( ClassAd &ad , bool full )
{
    Lexer::TokenType 	tt;
    Lexer::TokenValue	tv;
    ExprTree			*tree = NULL;
    string				s;

    ad.Clear( );
    ad.DisableDirtyTracking();

    if( ( tt = lexer.ConsumeToken() ) != Lexer::LEX_OPEN_BOX ) return false;
    tt = lexer.PeekToken();
    while( tt != Lexer::LEX_CLOSE_BOX ) {
        // Get the name of the expression
        tt = lexer.ConsumeToken( &tv );
        if( tt == Lexer::LEX_SEMICOLON ) {
            // We allow empty expressions, so if someone give a double semicolon, it doesn't
            // hurt. Technically it's not right, but we shouldn't make users pay the price for
            // a meaningless mistake. See condor-support #1881 for a user that was bitten by this.
            continue;
        }
        if( tt != Lexer::LEX_IDENTIFIER ) {
            CondorErrno = ERR_PARSE_ERROR;
            CondorErrMsg = "while parsing classad:  expected LEX_IDENTIFIER "
                           " but got " + string( Lexer::strLexToken( tt ) );
            return false;
        }

        // consume the intermediate '='
        if( ( tt = lexer.ConsumeToken() ) != Lexer::LEX_BOUND_TO ) {
            CondorErrno = ERR_PARSE_ERROR;
            CondorErrMsg = "while parsing classad:  expected LEX_BOUND_TO "
                           " but got " + string( Lexer::strLexToken( tt ) );
            return false;
        }

        // parse the expression
        parseExpression( tree );
        if( tree == NULL ) {
            return false;
        }

        // insert the attribute into the classad
        tv.GetStringValue( s );
        if( !ad.Insert( s, tree ) ) {
            delete tree;
            return false;
        }

        // the next token must be a ';' or a ']'
        tt = lexer.PeekToken();
        if( tt != Lexer::LEX_SEMICOLON && tt != Lexer::LEX_CLOSE_BOX ) {
            CondorErrno = ERR_PARSE_ERROR;
            CondorErrMsg = "while parsing classad:  expected LEX_SEMICOLON or "
                           "LEX_CLOSE_BOX but got " + string( Lexer::strLexToken( tt ) );
            return( false );
        }

        // Slurp up any extra semicolons. This does not duplicate the work at the top of the loop
        // because it accounts for the case where the last expression has extra semicolons,
        // while the first case accounts for optional beginning semicolons.
        while( tt == Lexer::LEX_SEMICOLON ) {
            lexer.ConsumeToken();
            tt = lexer.PeekToken();
        }
    }

    lexer.ConsumeToken();

    // if a full parse was requested, ensure that input is exhausted
    if( full && ( lexer.ConsumeToken() != Lexer::LEX_END_OF_INPUT ) ) {
        CondorErrno = ERR_PARSE_ERROR;
        CondorErrMsg = "while parsing classad:  expected LEX_END_OF_INPUT for "
                       "full parse but got " + string( Lexer::strLexToken( tt ) );
        return false;
    }

    ad.EnableDirtyTracking();
    return true;
}