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; }
bool ConfigOptionsDialog::SetProfileData(const ConfigToken &setProfile, ConfigHeaderValue & headerToken) { uint i; // If this is the plugins header if(headerToken.headerName == CONFIG_PLUGINS_HEADER_NAME) { // Process from the plugins array for(i=0; i<pluginGridValues.size(); i++) { // If there is a child with the plugin name const ConfigToken * childToken = setProfile.GetChildToken(pluginGridValues[i].headerName); if(childToken) { // Set the Plugin as enabled for(uint pluginValue=0; pluginValue<pluginGridValues[i].childSelectArray.size(); pluginValue++) { // Set the plugin enabled flag to true if(pluginGridValues[i].childSelectArray[pluginValue].typeName == CONFIG_PLUGIN_ENABLE_NAME) { pluginGridValues[i].childSelectArray[pluginValue].isValueDisplayed = true; pluginGridValues[i].childSelectArray[pluginValue].defaultValue.clear(); pluginGridValues[i].childSelectArray[pluginValue].defaultValue.push_back(CONFIG_PLUGIN_TOKEN_TRUE); break; } } // Recurse if(!SetProfileData(*childToken, pluginGridValues[i])) { return false; } } } return true; } // Loop for all read tokens for(i=0; i<headerToken.childSelectArray.size(); i++) { // Find the token in the config data const ConfigToken * childToken = setProfile.GetChildToken(headerToken.childSelectArray[i].typeName); if(childToken) { // Get the new defaults vector<string> newValues; childToken->GetArray(childToken->GetNumValues(), newValues); // Check the new values if(newValues.size() == 0) { wxLogError("SetProfileData - Empty value for token %s", headerToken.childSelectArray[i].typeName.c_str()); return false; } // Check if there are a different number of values than the existing defaults if(newValues.size() != headerToken.childSelectArray[i].defaultValue.size()) { headerToken.childSelectArray[i].isValueDisplayed = true; } else { // Loop and check if any of the new values are different from the default string for(uint cmpIndex=0; cmpIndex<newValues.size(); cmpIndex++) { // Find the first string that does not match if(newValues[cmpIndex] != headerToken.childSelectArray[i].defaultValue[cmpIndex]) { headerToken.childSelectArray[i].isValueDisplayed = true; break; } } } // Assign the new values as the defaults headerToken.childSelectArray[i].defaultValue = newValues; } } // Loop for all child header tokens for(i=0; i<headerToken.childHeaderArray.size(); i++) { // If there is a child with the header name const ConfigToken * childToken = setProfile.GetChildToken(headerToken.childHeaderArray[i].headerName); if(childToken) { // Recurse if(!SetProfileData(*childToken, headerToken.childHeaderArray[i])) { return false; } } } return true; }
bool ConfigOptionsDialog::GetDisplayConfigData(ConfigToken & newConfigData, const ConfigHeaderValue & headerValue, const string & parentNamePath) const { // Loop for all values uint i=0; for(i=0; i<headerValue.childSelectArray.size(); i++) { // Create the new value child token ConfigToken newChildToken(headerValue.childSelectArray[i].typeName); // Create the property name string propertyName = parentNamePath + string(".") + newChildToken.GetName(); // Get the values from the dialog vector<string> newChildValues; wxPGId propID = propGrid->GetPropertyByName(propertyName.c_str()); if(GetPropGridSelectValue(headerValue.childSelectArray[i], propID, newChildValues)) { // Set the new token values newChildToken.SetValueArray(newChildValues); } else { wxLogError("GetDisplayConfigData - Unable to get property %s", propertyName.c_str()); } // If the value has an "ignore value" option set if(headerValue.childSelectArray[i].useIgnoreValue) { // If the value dose not match the ignore value, add the child token if(newChildValues.size() > 0 && newChildValues[0] != headerValue.childSelectArray[i].ignoreIfValueEquals) { newConfigData.AddChild(newChildToken); } } else { // Add the new token to then header newConfigData.AddChild(newChildToken); } } // Loop for all children of the header for(i=0; i<headerValue.childHeaderArray.size(); i++) { // Add a child token ConfigToken newChildToken(headerValue.childHeaderArray[i].headerName); // Calculate the new header path string childHeaderPath = parentNamePath + string(".") + newChildToken.GetName(); // Recurse if(!GetDisplayConfigData(newChildToken, headerValue.childHeaderArray[i], childHeaderPath)) { return false; } // Add to the output newConfigData.AddChild(newChildToken); } // If this is the plugins header, loop over the plugins if(headerValue.headerName == CONFIG_PLUGINS_HEADER_NAME) { for(i=0; i<pluginGridValues.size(); i++) { // Add a child token ConfigToken newChildToken(pluginGridValues[i].headerName); // Calculate the new header path string childHeaderPath = parentNamePath + string(".") + newChildToken.GetName(); // Recurse if(!GetDisplayConfigData(newChildToken, pluginGridValues[i], childHeaderPath)) { return false; } // For plugins, check if the enabled flag is set const ConfigToken * pluginEnabledToken = newChildToken.GetChildToken(CONFIG_PLUGIN_ENABLE_NAME); if(pluginEnabledToken && pluginEnabledToken->GetNumValues() == 1) { // Check if the flag is true string enableFlagStr; pluginEnabledToken->Get(enableFlagStr); if(enableFlagStr == CONFIG_PLUGIN_TOKEN_TRUE) { // Remove the flag token newChildToken.RemoveChild(CONFIG_PLUGIN_ENABLE_NAME); pluginEnabledToken = NULL; // Set the plugin path vector<string> pluginLoadArray; pluginLoadArray.push_back(pluginGridValues[i].pluginLoadString); newChildToken.SetValueArray(pluginLoadArray); // Add to the output newConfigData.AddChild(newChildToken); } } } } return true; }
void ConfigOptionsDialog::OnButtonSaveAs(wxCommandEvent& event) { // Get the profile data ConfigToken saveConfigData; if(!GetDisplayConfigData(saveConfigData)) { wxLogError("Unable to get config data"); return; } // Convert the token data to a string string stlConfigString; for(uint childNum =0;childNum < saveConfigData.GetNumChildren(); childNum++) { //Convert each child back to raw config string data const ConfigToken * childData = saveConfigData.GetChildToken(childNum); if(childData) { string retString; if(ConfigParser::GenerateConfigString(childData, retString)) { stlConfigString += retString; } else { wxLogError("Unable to generate GLIntercept configuration file data"); return; } } } wxString saveConfigString = stlConfigString.c_str(); wxStandardPaths stdPaths; wxFileName dirProcess; // Get the main profile directory dirProcess.AssignDir(stdPaths.GetDataDir()); dirProcess.AppendDir("Profiles"); wxString profileDir = dirProcess.GetPath(); // Open the profile save dialog wxFileDialog fileDialog(this, _T("Save profile as"), profileDir, _T(""), _T("GLIntercept Profile (*.xni)|*.xni|Any (*.*)|*.*"), wxSAVE | wxOVERWRITE_PROMPT ); if (fileDialog.ShowModal() != wxID_OK) { return; } wxFile configWrite; if(!configWrite.Open(fileDialog.GetPath(), wxFile::write)) { wxLogError("Unable to open config file (%s)", fileDialog.GetPath().c_str()); return; } if(!configWrite.Write(saveConfigString)) { wxLogError("Unable to write to config file (%s)", fileDialog.GetPath().c_str()); return; } // Flag that a config was saved isConfigSaved = true; }
bool MainDialog::GetSaveProfileString(bool copySystemLib, wxString &retString) const { wxStandardPaths stdPaths; // Get the current selected profile ConfigToken saveProfile; if(!GetCurrentProfile(saveProfile)) { wxLogError("No GLIntercept profile selected"); return false; } // Get the profile name (if any) string profileName = "*Unknown*"; { // Get the profile name if it exists const ConfigToken * profileNameToken = saveProfile.GetChildToken("ProfileName"); if(profileNameToken) { profileNameToken->Get(profileName); } // Remove the profile/description tokens saveProfile.RemoveChild("ProfileName"); saveProfile.RemoveChild("ProfileDescription"); } // If copying the OpenGL system library if(copySystemLib) { // Get the input files token (or create it) ConfigToken * sourceInputFilesToken = GetCreateChildToken(saveProfile, "InputFiles"); if(sourceInputFilesToken) { // Get the system lib token (or create it) ConfigToken * syslibToken = GetCreateChildToken(*sourceInputFilesToken, "GLSystemLib"); if(syslibToken) { // Set the new override system lib name vector<string> newSystemLibName; newSystemLibName.push_back("opengl32.orig.dll"); // Override the existing library name syslibToken->SetValueArray(newSystemLibName); } } } // Replace any string that start with %InstallPath% with the current path UpdateTokenValues(saveProfile, "%InstallPath%", stdPaths.GetDataDir().c_str()); // Generate the config string from the profile string stlConfigString; for(uint childNum =0;childNum < saveProfile.GetNumChildren(); childNum++) { //Convert each child back to raw config string data const ConfigToken * childData = saveProfile.GetChildToken(childNum); if(childData) { string retString; if(ConfigParser::GenerateConfigString(childData, retString)) { stlConfigString += retString; } else { wxLogError("Unable to generate GLIntercept configuration file data"); return false; } } } // Add a header comment retString.Printf("/*\n* GLIntercept config file generated by GLIConfig.\n* Configuration based on profile \"%s\".\n*/\n\n", profileName.c_str()); retString += stlConfigString.c_str(); return true; }