bool ConfigParser::ParseString(const string &configString) { //Init the variables inComment = false; //Assign file and line counters lineCounter=1; fileName = "<Supplied String>"; string::size_type stringStart =0; string::size_type stringEnd =0; RawTokenArray rawTokens; string inputString; //Get a line from the input stream do { //Get the next line of input stringEnd = configString.find("\n",stringStart); if(stringEnd != string::npos) { //Get the sub string inputString.assign(configString,stringStart,stringEnd - stringStart); stringStart = stringEnd +1; } else { //Take the remainder of the string inputString.assign(configString,stringStart, configString.length() - stringStart); stringStart = configString.length(); } //Parse the line - return false on an error if(!ParseLine(inputString,rawTokens)) { LOGERR(("ConfigParser::ParseString - Line error in string line %u",lineCounter)); return false; } //Increment the line counter lineCounter++; }while(stringEnd != string::npos); //Check that all the section areas are completed if(inComment) { LOGERR(("ConfigParser::ParseString - Comment section not completed by end of string")); return false; } //Pass the raw tokens to a syntax checker and extract "real" tokens uint tokenStart =0; return ExtractTokens(rawTokens,tokenStart,NULL); }
static void MendDocument(Document *doc) { size_t nchars; Character **chars = ExtractCharacters(doc, &nchars); for (int i = 0; i < nchars; i++) ResetCharacterWidth(chars[i]); size_t ntokens; Token *tokens = ExtractTokens(doc, &ntokens); for (int i = 0; i < ntokens; i++) MendToken(&tokens[i]); doc->lines = CreateLines(tokens, ntokens, doc->page, &doc->nlines); }
bool ConfigParser::Parse(const string &fName) { //Init the variables inComment = false; //Assign file and line counters lineCounter=1; fileName = fName; //Open the file FILE * file = fopen(fileName.c_str(),"rt"); if(!file) { LOGERR(("ConfigParser::Parse - Unable to open file %s",fileName.c_str())); return false; } char inputString[1024]; RawTokenArray rawTokens; //Get a line from the input stream while(fgets(inputString,1024,file) != NULL) { //Parse the line - return false on an error if(!ParseLine(inputString,rawTokens)) { LOGERR(("ConfigParser::Parse - Line error in file %s Line %u",fileName.c_str(),lineCounter)); fclose(file); return false; } //Increment the line counter lineCounter++; } //Close the file fclose(file); //Check that all the section areas are completed if(inComment) { LOGERR(("ConfigParser::Parse - Comment section not completed by end of file %s",fileName.c_str())); return false; } //Pass the raw tokens to a syntax checker and extract "real" tokens uint tokenStart =0; bool retValue = ExtractTokens(rawTokens,tokenStart,NULL); /* Debug if(retValue) { string testString; for(uint i=0;i<rootToken.GetNumChildren()-1;i++) { string tokenStr; GenerateConfigString(rootToken.GetChildToken(i),tokenStr); testString += tokenStr; } ConfigParser testParser; testParser.ParseString(testString); if(!rootToken.Compare(&testParser.rootToken)) { LOGERR(("Compare does not match!")); } //LOGERR(("%s",testString.c_str())); }//*/ return retValue; }
bool ConfigParser::ExtractTokens(RawTokenArray &rawTokens, uint &tokenNum, ConfigToken *parent) { ConfigToken *currToken=NULL; bool inbracket = false; bool assignment= false; //NOTE: May have to use "proper" parser recursion if this gets much more complex //Loop for all tokens for(;tokenNum<rawTokens.size();tokenNum++) { string & tokenString = rawTokens[tokenNum].value; int commandChar = (int)tokenString.find_first_of(singleTokens.c_str()); //If this is a command character, process it if(commandChar == 0 && tokenString.length() == 1 && !rawTokens[tokenNum].isString) { if(tokenString == "{") { //Check that we are not in a bracket if(inbracket || !currToken || assignment) { LOGERR(("ConfigParser::ExtractTokens - Un-expected '{'")); return false; } //Recursive call tokenNum++; if(!ExtractTokens(rawTokens,tokenNum,currToken)) { LOGERR(("ConfigParser::ExtractTokens - Error in child block")); return false; } } else if(tokenString == "}") { //Check that we are not in a bracket and that there was a '{' if(inbracket || !parent || assignment) { LOGERR(("ConfigParser::ExtractTokens - Un-expected '}'")); return false; } return true; } else if(tokenString == "(") { if(inbracket || !assignment || !currToken) { LOGERR(("ConfigParser::ExtractTokens - Un-expected '('")); return false; } //Set bracket flag inbracket = true; } else if(tokenString == ")") { //Check for missing opening bracket if(!inbracket || !assignment || !currToken) { LOGERR(("ConfigParser::ExtractTokens - Un-expected ')'")); return false; } //Un-set bracket flag inbracket = false; assignment= false; } else if(tokenString == ",") { //NOTE: does not check for excess comma's (ie double or extra trailing commas) //Check for missing previous child and in a bracket if(!inbracket || !currToken || currToken->GetNumValues() == 0) { LOGERR(("ConfigParser::ExtractTokens - Un-expected ','")); return false; } } else if(tokenString == "=") { //Check for current token if(!currToken || assignment || inbracket) { LOGERR(("ConfigParser::ExtractTokens - Un-expected '='")); return false; } assignment=true; } else if(tokenString == ";") { //Check for current token if(!currToken || assignment || inbracket) { LOGERR(("ConfigParser::ExtractTokens - Un-expected ';'")); return false; } //The token is just a seperator, so do nothing } else { LOGERR(("ConfigParser::ExtractTokens - Unknown command '%s'",tokenString.c_str())); return false; } } //Process the non-command token else { //Else just create a new config token if(inbracket && currToken) { //Add a new value to the config token currToken->values.push_back(tokenString); } else if(assignment) { //Add a new value to the config token currToken->values.push_back(tokenString); //Flag that the assignment is complete assignment =false; } else { //Create a new token ConfigToken newToken; newToken.name = tokenString; //Either add to the parent or root ConfigToken * addToToken = &rootToken; if(parent) { addToToken = parent; } //Test if the child already exists ConfigToken * existingToken = const_cast<ConfigToken *>(addToToken->GetChildToken(tokenString)); if(existingToken == NULL) { //Add the token addToToken->children.push_back(newToken); currToken = &addToToken->children.back(); } else { //Cannot simply ignore as there may be children or ther values associated with the token LOGERR(("ConfigParser::ExtractTokens - Extra %s token -using last value",tokenString.c_str())); //Reset the token existingToken->Reset(); //Assign as the current token existingToken->name = tokenString; currToken = existingToken; } } } } //If this is not the root token, and we have processed all the data // there is a missing closing bracket if((parent != NULL || inbracket || assignment) && tokenNum>=rawTokens.size()) { //Missing closing bracket LOGERR(("ConfigParser::ExtractTokens - Un-expected end of tokens (end of file missing a '}' or a ')'?")); return false; } /* //Debug for(uint i=0;i<parsedTokens.size();i++) { LOGERR(("%s",parsedTokens[i].name.c_str())); } */ return true; }