Changeset 1351
- Timestamp:
- May 22, 2008, 1:18:18 AM (17 years ago)
- Location:
- code/branches/console/src/core
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/console/src/core/CommandEvaluation.cc
r1341 r1351 29 29 #include "CommandEvaluation.h" 30 30 #include "ConsoleCommand.h" 31 #include "Debug.h" 31 32 32 33 namespace orxonox … … 34 35 CommandEvaluation::CommandEvaluation() 35 36 { 36 this->processedCommand_ = ""; 37 this->initialize(""); 38 this->state_ = CS_Uninitialized; 39 } 40 41 void CommandEvaluation::initialize(const std::string& command) 42 { 43 this->bNewCommand_ = true; 44 45 this->originalCommand_ = command; 46 this->command_ = command; 47 this->originalCommandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 48 this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 49 37 50 this->additionalParameter_ = ""; 38 51 52 this->bEvaluatedParams_ = false; 53 54 this->listOfPossibleFunctionClasses_.clear(); 55 this->listOfPossibleFunctions_.clear(); 56 39 57 this->functionclass_ = 0; 40 this->configvalueclass_ = 0;41 this->shortcut_ = 0;42 58 this->function_ = 0; 43 this->configvalue_ = 0;44 this->key_ = 0;45 59 46 60 this->errorMessage_ = ""; 47 this->state_ = CS_Uninitialized; 48 61 this->state_ = CS_Empty; 62 } 63 64 bool CommandEvaluation::isValid() const 65 { 66 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished) 67 { 68 return this->function_; 69 } 70 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished) 71 { 72 return (this->functionclass_ && this->function_); 73 } 74 else 75 { 76 return false; 77 } 78 } 79 80 bool CommandEvaluation::execute() const 81 { 82 if (!this->isValid()) 83 return false; 84 85 if (this->bEvaluatedParams_ && this->function_) 86 { 87 COUT(4) << "CE_execute (evaluation): " << this->function_->getName() << " " << this->param_[0] << " " << this->param_[1] << " " << this->param_[2] << " " << this->param_[3] << " " << this->param_[4] << std::endl; 88 (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]); 89 return true; 90 } 91 92 COUT(4) << "CE_execute: " << this->originalCommand_ << "\n"; 93 94 unsigned int startindex = this->getStartindex(); 95 if (this->originalCommandTokens_.size() > startindex) 96 return evaluation.shortcut_->parse(removeSlashes(this->originalCommandTokens_.subSet(startindex).join() + evaluation.getAdditionalParameter())); 97 else 98 return evaluation.shortcut_->parse(removeSlashes(evaluation.additionalParameter_)); 99 } 100 101 std::string CommandEvaluation::complete() const 102 { 103 switch (this->state_) 104 { 105 case CS_Empty: 106 std::list<std::pair<const std::string*, const std::string*> > temp; 107 if (evaluation.state_ == CS_Empty) 108 { 109 temp.insert(temp.end(), this->listOfPossibleFunctions_.begin(), this->listOfPossibleFunctions_.end()); 110 temp.insert(temp.end(), this->listOfPossibleFunctionClasses_.begin(), this->listOfPossibleFunctionClasses_.end()); 111 } 112 return (CommandEvaluation::getCommonBegin(temp)); 113 break; 114 case CS_Shortcut_Params: 115 if (this->function_) 116 return (this->function_->getName() + " "); 117 break; 118 case CS_Shortcut_Finished: 119 if (this->function_) 120 { 121 if (this->function_->getParamCount() == 0) 122 return (this->function_->getName()); 123 else if (this->originalCommandTokens_.size() > 1) 124 return (this->function_->getName() + " " + this->originalCommandTokens_.subSet(1).join()); 125 } 126 break; 127 case CS_Function: 128 if (this->functionclass_) 129 return (this->functionclass_->getName() + " " + CommandEvaluation::getCommonBegin(this->listOfPossibleFunctions_)); 130 break; 131 case CS_Function_Params: 132 if (this->functionclass_ && this->function_) 133 return (this->functionclass_->getName() + " " + this->function_->getName() + " "); 134 break; 135 case CS_Function_Finished: 136 if (this->functionclass_ && this->function_) 137 { 138 if (this->function_->getParamCount() == 0) 139 return (this->functionclass_->getName() + " " + this->unction_->getName()); 140 else if (this->originalCommandTokens_.size() > 2) 141 return (this->functionclass_->getName() + " " + this->function_->getName() + " " + this->originalCommandTokens_.subSet(2).join()); 142 } 143 break; 144 } 145 146 return this->originalCommand_; 147 } 148 149 std::string CommandEvaluation::hint() const 150 { 151 switch (this->state_) 152 { 153 case CS_Empty: 154 return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandExecutor::dump(this->listOfPossibleFunctionClasses_)); 155 break; 156 case CS_Function: 157 return CommandEvaluation::dump(this->listOfPossibleFunctions_); 158 break; 159 case CS_Shortcut_Params: 160 case CS_Shortcut_Finished: 161 case CS_Function_Params: 162 case CS_Function_Finished: 163 if (this->function_) 164 return CommandEvaluation::dump(this->function_); 165 break; 166 case CS_Error: 167 return this->errorMessage_; 168 break; 169 } 170 171 return ""; 172 } 173 174 void CommandEvaluation::evaluateParams() 175 { 49 176 this->bEvaluatedParams_ = false; 50 177 this->evaluatedExecutor_ = 0; 51 }52 53 KeybindMode CommandEvaluation::getKeybindMode()54 {55 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)56 {57 // if (this->shortcut_ != 0)58 // return this->shortcut_->getKeybindMode();59 }60 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)61 {62 // if (this->function_ != 0)63 // return this->function_->getKeybindMode();64 }65 else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)66 {67 // return KeybindMode::onPress;68 }69 else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)70 {71 // return KeybindMode::onPress;72 }73 else74 {75 // return KeybindMode::onPress;76 }77 // FIXME: Had to insert a return statement78 return (KeybindMode)0;79 }80 81 bool CommandEvaluation::isValid() const82 {83 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)84 {85 return this->shortcut_;86 }87 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)88 {89 return (this->functionclass_ && this->function_);90 }91 else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)92 {93 return (this->configvalueclass_ && this->configvalue_);94 }95 else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)96 {97 return this->key_;98 }99 else100 {101 return false;102 }103 }104 105 void CommandEvaluation::evaluateParams()106 {107 this->bEvaluatedParams_ = false;108 this->evaluatedExecutor_ = 0;109 178 110 179 for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++) 111 180 this->param_[i] = MT_null; 112 181 182 if (!this->isValid()) 183 return; 184 185 unsigned int startindex = this->getStartindex(); 186 187 if (this->originalCommandTokens_.size() <= startindex) 188 { 189 if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " ")) 190 { 191 this->bEvaluatedParams_ = true; 192 this->evaluatedExecutor_ = this->function_; 193 } 194 } 195 else if (this->originalCommandTokens_.size() > startindex) 196 { 197 if (this->function_->evaluate(this->originalCommandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " ")) 198 { 199 this->bEvaluatedParams_ = true; 200 this->evaluatedExecutor_ = this->function_; 201 } 202 } 203 } 204 205 void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiTypeMath param) 206 { 207 if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS) 208 this->param_[index] = param; 209 } 210 211 MultiTypeMath CommandEvaluation::getEvaluatedParameter(unsigned int index) const 212 { 213 if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS) 214 return this->param_[index]; 215 216 return MT_null; 217 } 218 219 bool CommandEvaluation::hasReturnvalue() const 220 { 221 if (this->function_) 222 return this->function_->hasReturnvalue(); 223 224 return MT_null; 225 } 226 227 MultiTypeMath CommandEvaluation::getReturnvalue() const 228 { 229 if (this->function_) 230 return this->function_->getReturnvalue(); 231 232 return MultiTypeMath(); 233 } 234 235 236 unsigned int CommandEvaluation::getStartindex() const 237 { 113 238 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished) 114 { 115 if (this->shortcut_) 239 return 1; 240 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished) 241 return 2; 242 else 243 return 0; 244 } 245 246 std::string CommandEvaluation::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list) 247 { 248 if (list.size() == 0) 249 { 250 return ""; 251 } 252 else if (list.size() == 1) 253 { 254 return ((*(*list.begin()).first) + " "); 255 } 256 else 257 { 258 std::string output = ""; 259 for (unsigned int i = 0; true; i++) 116 260 { 117 if (this->tokens_.size() <= 1) 261 char temp = 0; 262 for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it) 118 263 { 119 if ( this->shortcut_->evaluate(this->getAdditionalParameter(), this->param_, " "))264 if ((*(*it).first).size() > i) 120 265 { 121 this->bEvaluatedParams_ = true; 122 this->evaluatedExecutor_ = this->shortcut_; 266 if (it == list.begin()) 267 { 268 temp = (*(*it).first)[i]; 269 } 270 else 271 { 272 if (temp != (*(*it).first)[i]) 273 return output; 274 } 275 } 276 else 277 { 278 return output; 123 279 } 124 280 } 125 else if (this->tokens_.size() > 1) 126 { 127 if (this->shortcut_->evaluate(this->tokens_.subSet(1).join() + this->getAdditionalParameter(), this->param_, " ")) 128 { 129 this->bEvaluatedParams_ = true; 130 this->evaluatedExecutor_ = this->shortcut_; 131 } 132 } 281 output += temp; 133 282 } 134 } 135 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished) 136 { 137 if (this->function_) 138 { 139 if (this->tokens_.size() <= 2) 140 { 141 if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " ")) 142 { 143 this->bEvaluatedParams_ = true; 144 this->evaluatedExecutor_ = this->function_; 145 } 146 } 147 else if (this->tokens_.size() > 2) 148 { 149 if (this->function_->evaluate(this->tokens_.subSet(2).join() + this->getAdditionalParameter(), this->param_, " ")) 150 { 151 this->bEvaluatedParams_ = true; 152 this->evaluatedExecutor_ = this->function_; 153 } 154 } 155 } 156 } 157 } 158 159 void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiTypeMath param) 160 { 161 if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS) 162 this->param_[index] = param; 163 } 164 165 MultiTypeMath CommandEvaluation::getEvaluatedParameter(unsigned int index) const 166 { 167 if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS) 168 return this->param_[index]; 169 170 return MT_null; 171 } 172 173 bool CommandEvaluation::hasReturnvalue() const 174 { 175 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished) 176 { 177 if (this->shortcut_) 178 return this->shortcut_->hasReturnvalue(); 179 } 180 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished) 181 { 182 if (this->function_) 183 return this->function_->hasReturnvalue(); 184 } 185 186 return MT_null; 187 } 188 189 MultiTypeMath CommandEvaluation::getReturnvalue() const 190 { 191 if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished) 192 { 193 if (this->shortcut_) 194 return this->shortcut_->getReturnvalue(); 195 } 196 else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished) 197 { 198 if (this->function_) 199 return this->function_->getReturnvalue(); 200 } 201 202 return MT_null; 283 return output; 284 } 285 } 286 287 std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list) 288 { 289 std::string output = ""; 290 for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it) 291 { 292 if (it != list.begin()) 293 output += " "; 294 295 output += *(*it).second; 296 } 297 return output; 298 } 299 300 std::string CommandEvaluation::dump(const ConsoleCommand* command) 301 { 302 std::string output = ""; 303 for (unsigned int i = 0; i < command->getParamCount(); i++) 304 { 305 if (i != 0) 306 output += " "; 307 308 if (command->defaultValueSet(i)) 309 output += "["; 310 else 311 output += "{"; 312 313 output += command->getTypenameParam(i); 314 315 if (command->defaultValueSet(i)) 316 output += "=" + command->getDefaultValue(i).toString() + "]"; 317 else 318 output += "}"; 319 } 320 return output; 203 321 } 204 322 } -
code/branches/console/src/core/CommandEvaluation.h
r1341 r1351 44 44 CS_Uninitialized, 45 45 CS_Empty, 46 CS_FunctionClass_Or_Shortcut _Or_Keyword,46 CS_FunctionClass_Or_Shortcut, 47 47 CS_Shortcut_Params, 48 48 CS_Shortcut_Finished, … … 50 50 CS_Function_Params, 51 51 CS_Function_Finished, 52 CS_ConfigValueClass,53 CS_ConfigValue,54 CS_ConfigValueType,55 CS_ConfigValueFinished,56 CS_KeybindKey,57 CS_KeybindCommand,58 CS_KeybindFinished,59 52 CS_Error 60 53 }; 61 54 62 enum KeybindMode {}; // temporary63 64 55 class _CoreExport CommandEvaluation 65 56 { 66 friend class CommandExecutor;67 68 57 public: 69 58 CommandEvaluation(); 70 59 71 KeybindMode getKeybindMode(); 60 void initialize(const std::string& command); 61 62 void execute() const; 63 std::string complete() const; 64 std::string hint() const; 65 void evaluateParams(); 66 72 67 bool isValid() const; 68 69 inline Identifier* getIdentifier() const 70 { return this->functionclass_; } 71 inline void setIdentifier(Identifier* identifier) 72 { this->functionclass_ = identifier; } 73 inline ConsoleCommand* getFunction() const 74 { return this->function_; } 75 inline void setFunction(ConsoleCommand* command) 76 { this->function_ = command; } 77 78 inline const std::string& getOriginalCommand() const 79 { return this->originalCommand_; } 80 inline const std::string& getCommand() const 81 { return this->command_; } 82 inline void setCommand(const std::string& command) 83 { this->command_ = command; } 84 inline const CommandState& getState() const 85 { return this->state_; } 86 inline void setState(CommandState state) 87 { this->state_ = state; } 88 inline SubString& getOriginalTokens() 89 { return this->originalCommandTokens_; } 90 inline SubString& getTokens() 91 { return this->commandTokens_; } 92 inline void setTokens(const std::string& command) 93 { this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); } 94 inline const std::string& getError() const 95 { return this->errorMessage_; } 96 inline void setError(const std::string& error) 97 { this->errorMessage_ = error; } 98 inline bool isNewCommand() const 99 { return this->bNewCommand_; } 100 inline void setNewCommand(bool bNewCommand) 101 { this->bNewCommand_ = bNewCommand; } 102 103 inline std::list<std::pair<const std::string*, const std::string*> >& getListOfPossibleFunctionClasses() 104 { return this->listOfPossibleFunctionClasses_; } 105 inline std::list<std::pair<const std::string*, const std::string*> >& getListOfPossibleFunctions() 106 { return this->listOfPossibleFunctions_; } 73 107 74 108 inline void setAdditionalParameter(const std::string& param) … … 80 114 MultiTypeMath getEvaluatedParameter(unsigned int index) const; 81 115 82 void evaluateParams();83 84 116 bool hasReturnvalue() const; 85 117 MultiTypeMath getReturnvalue() const; 86 118 87 119 private: 88 std::string processedCommand_; 89 SubString tokens_; 120 unsigned int getStartindex() const; 121 static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list); 122 static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list); 123 static std::string dump(const ConsoleCommand* command); 124 125 126 bool bNewCommand_; 127 128 std::string originalCommand_; 129 std::string command_; 130 SubString originalCommandTokens_; 131 SubString commandTokens_; 90 132 std::string additionalParameter_; 91 133 92 134 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctionClasses_; 93 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleShortcuts_;94 135 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_; 95 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValueClasses_;96 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValues_;97 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleKeys_;98 136 99 137 Identifier* functionclass_; 100 Identifier* configvalueclass_;101 ConsoleCommand* shortcut_;102 138 ConsoleCommand* function_; 103 ConfigValueContainer* configvalue_;104 ConfigValueContainer* key_;105 139 106 140 std::string errorMessage_; … … 109 143 bool bEvaluatedParams_; 110 144 MultiTypeMath param_[5]; 111 ConsoleCommand* evaluatedExecutor_;112 145 }; 113 146 } -
code/branches/console/src/core/CommandExecutor.cc
r1341 r1351 34 34 #include "Language.h" 35 35 #include "Debug.h" 36 #include "Executor.h"37 #include "ConfigValueContainer.h"38 36 #include "TclBind.h" 39 40 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE "set"41 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY "tset"42 #define COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND "bind"43 37 44 38 namespace orxonox 45 39 { 46 SetConsoleCommandShortcutGeneric(keyword1, createExecutor((FunctorStatic*)0, "set")).setAccessLevel(AccessLevel::User);47 SetConsoleCommandShortcutGeneric(keyword2, createExecutor((FunctorStatic*)0, "tset")).setAccessLevel(AccessLevel::User);48 SetConsoleCommandShortcutGeneric(keyword3, createExecutor((FunctorStatic*)0, "bind")).setAccessLevel(AccessLevel::User);49 50 40 CommandExecutor& CommandExecutor::getInstance() 51 41 { … … 102 92 { 103 93 if (useTcl) 104 { 105 // std::string temp = getLowercase(removeTrailingWhitespaces(command)); 106 // if (!(temp.substr(0, 16) == "tclthreadmanager" || temp.substr(0, 10) == "tclexecute" || temp.substr(0, 8) == "tclquery")) 107 return TclBind::eval(command); 108 } 109 110 if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized)) 94 return TclBind::eval(command); 95 96 if ((CommandExecutor::getEvaluation().getCommand() != command) || (CommandExecutor::getEvaluation().getState() == CS_Uninitialized)) 111 97 CommandExecutor::parse(command); 112 98 113 return CommandExecutor::execute(CommandExecutor::getEvaluation()); 114 } 115 116 117 bool CommandExecutor::execute(const CommandEvaluation& evaluation) 118 { 119 SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 120 121 if (evaluation.bEvaluatedParams_ && evaluation.evaluatedExecutor_) 122 { 123 COUT(4) << "CE_execute (evaluation): " << evaluation.evaluatedExecutor_->getName() << " " << evaluation.param_[0] << " " << evaluation.param_[1] << " " << evaluation.param_[2] << " " << evaluation.param_[3] << " " << evaluation.param_[4] << std::endl; 124 (*evaluation.evaluatedExecutor_)(evaluation.param_[0], evaluation.param_[1], evaluation.param_[2], evaluation.param_[3], evaluation.param_[4]); 125 return true; 126 } 127 128 COUT(4) << "CE_execute: " << evaluation.processedCommand_ << "\n"; 129 switch (evaluation.state_) 130 { 131 case CS_Uninitialized: 132 break; 133 case CS_Empty: 134 break; 135 case CS_FunctionClass_Or_Shortcut_Or_Keyword: 136 break; 137 case CS_Shortcut_Params: 138 // not enough parameters but lets hope there are some additional parameters and go on 139 case CS_Shortcut_Finished: 140 // call the shortcut 141 if (evaluation.shortcut_) 142 { 143 if (tokens.size() >= 2) 144 return evaluation.shortcut_->parse(removeSlashes(tokens.subSet(1).join() + evaluation.getAdditionalParameter())); 145 else 146 return evaluation.shortcut_->parse(removeSlashes(evaluation.additionalParameter_)); 147 } 148 break; 149 case CS_Function: 150 break; 151 case CS_Function_Params: 152 // not enough parameters but lets hope there are some additional parameters and go on 153 case CS_Function_Finished: 154 // call the shortcut 155 if (evaluation.function_) 156 { 157 if (tokens.size() >= 3) 158 return evaluation.function_->parse(removeSlashes(tokens.subSet(2).join() + evaluation.getAdditionalParameter())); 159 else 160 return evaluation.function_->parse(removeSlashes(evaluation.additionalParameter_)); 161 } 162 break; 163 case CS_ConfigValueClass: 164 break; 165 case CS_ConfigValue: 166 break; 167 case CS_ConfigValueType: 168 // not enough parameters but lets hope there are some additional parameters and go on 169 case CS_ConfigValueFinished: 170 // set the config value 171 if (evaluation.configvalue_) 172 { 173 if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)) 174 { 175 if (tokens.size() >= 4) 176 return evaluation.configvalue_->set(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter())); 177 else 178 return evaluation.configvalue_->set(removeSlashes(evaluation.additionalParameter_)); 179 } 180 else if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) 181 { 182 if (tokens.size() >= 4) 183 return evaluation.configvalue_->tset(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter())); 184 else 185 return evaluation.configvalue_->tset(removeSlashes(evaluation.additionalParameter_)); 186 } 187 } 188 break; 189 case CS_KeybindKey: 190 break; 191 case CS_KeybindCommand: 192 // not enough parameters but lets hope there are some additional parameters and go on 193 case CS_KeybindFinished: 194 // set the keybind 195 // ...todo 196 break; 197 case CS_Error: 198 break; 199 } 200 201 return false; 99 return CommandExecutor::getEvaluation().execute(); 202 100 } 203 101 204 102 std::string CommandExecutor::complete(const std::string& command) 205 103 { 206 if ((CommandExecutor::getEvaluation(). processedCommand_ != command) || (CommandExecutor::getEvaluation().state_== CS_Uninitialized))104 if ((CommandExecutor::getEvaluation().getCommand() != command) || (CommandExecutor::getEvaluation().getState() == CS_Uninitialized)) 207 105 CommandExecutor::parse(command); 208 106 209 return CommandExecutor::complete(CommandExecutor::getEvaluation()); 210 } 211 212 std::string CommandExecutor::complete(const CommandEvaluation& evaluation) 213 { 214 SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 215 216 std::list<std::pair<const std::string*, const std::string*> > temp; 217 if (evaluation.state_ == CS_Empty) 218 { 219 temp.insert(temp.end(), evaluation.listOfPossibleShortcuts_.begin(), evaluation.listOfPossibleShortcuts_.end()); 220 temp.insert(temp.end(), evaluation.listOfPossibleFunctionClasses_.begin(), evaluation.listOfPossibleFunctionClasses_.end()); 221 } 222 223 switch (evaluation.state_) 224 { 225 case CS_Uninitialized: 226 break; 227 case CS_Empty: 228 return (CommandExecutor::getCommonBegin(temp)); 229 break; 230 case CS_FunctionClass_Or_Shortcut_Or_Keyword: 231 break; 232 case CS_Shortcut_Params: 233 if (evaluation.shortcut_) 234 return (evaluation.shortcut_->getName() + " "); 235 break; 236 case CS_Shortcut_Finished: 237 if (evaluation.shortcut_) 238 { 239 if (evaluation.shortcut_->getParamCount() == 0) 240 return (evaluation.shortcut_->getName()); 241 else if (tokens.size() >= 2) 242 return (evaluation.shortcut_->getName() + " " + tokens.subSet(1).join()); 243 } 244 break; 245 case CS_Function: 246 if (evaluation.functionclass_) 247 return (evaluation.functionclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleFunctions_)); 248 break; 249 case CS_Function_Params: 250 if (evaluation.functionclass_ && evaluation.function_) 251 return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " "); 252 break; 253 case CS_Function_Finished: 254 if (evaluation.functionclass_ && evaluation.function_) 255 { 256 if (evaluation.function_->getParamCount() == 0) 257 return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName()); 258 else if (tokens.size() >= 3) 259 return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " " + tokens.subSet(2).join()); 260 } 261 break; 262 case CS_ConfigValueClass: 263 if (tokens.size() >= 1) 264 return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValueClasses_)); 265 break; 266 case CS_ConfigValue: 267 if ((tokens.size() >= 1) && evaluation.configvalueclass_) 268 return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValues_)); 269 break; 270 case CS_ConfigValueType: 271 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_) 272 return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " "); 273 break; 274 case CS_ConfigValueFinished: 275 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_ && (tokens.size() >= 4)) 276 return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " " + tokens.subSet(3).join()); 277 break; 278 case CS_KeybindKey: 279 if (tokens.size() >= 1) 280 return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleKeys_)); 281 break; 282 case CS_KeybindCommand: 283 if ((evaluation.processedCommand_.size() >= 1) && (evaluation.processedCommand_[evaluation.processedCommand_.size() - 1] != ' ')) 284 return (evaluation.processedCommand_ + " "); 285 break; 286 case CS_KeybindFinished: 287 break; 288 case CS_Error: 289 break; 290 } 291 292 return evaluation.processedCommand_; 107 return CommandExecutor::getEvaluation().complete(); 293 108 } 294 109 295 110 std::string CommandExecutor::hint(const std::string& command) 296 111 { 297 if ((CommandExecutor::getEvaluation(). processedCommand_ != command) || (CommandExecutor::getEvaluation().state_== CS_Uninitialized))112 if ((CommandExecutor::getEvaluation().getCommand() != command) || (CommandExecutor::getEvaluation().getState() == CS_Uninitialized)) 298 113 CommandExecutor::parse(command); 299 114 300 return CommandExecutor::hint(CommandExecutor::getEvaluation()); 301 } 302 303 std::string CommandExecutor::hint(const CommandEvaluation& evaluation) 304 { 305 SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 306 307 switch (evaluation.state_) 308 { 309 case CS_Uninitialized: 310 break; 311 case CS_Empty: 312 return (CommandExecutor::dump(evaluation.listOfPossibleShortcuts_) + "\n" + CommandExecutor::dump(evaluation.listOfPossibleFunctionClasses_)); 313 break; 314 case CS_FunctionClass_Or_Shortcut_Or_Keyword: 315 break; 316 case CS_Shortcut_Params: 317 if (evaluation.shortcut_) 318 return CommandExecutor::dump(evaluation.shortcut_); 319 break; 320 case CS_Shortcut_Finished: 321 if (evaluation.shortcut_) 322 return CommandExecutor::dump(evaluation.shortcut_); 323 break; 324 case CS_Function: 325 return CommandExecutor::dump(evaluation.listOfPossibleFunctions_); 326 break; 327 case CS_Function_Params: 328 if (evaluation.function_) 329 return CommandExecutor::dump(evaluation.function_); 330 break; 331 case CS_Function_Finished: 332 if (evaluation.function_) 333 return CommandExecutor::dump(evaluation.function_); 334 break; 335 case CS_ConfigValueClass: 336 return CommandExecutor::dump(evaluation.listOfPossibleConfigValueClasses_); 337 break; 338 case CS_ConfigValue: 339 return CommandExecutor::dump(evaluation.listOfPossibleConfigValues_); 340 break; 341 case CS_ConfigValueType: 342 if (evaluation.configvalue_) 343 return CommandExecutor::dump(evaluation.configvalue_); 344 break; 345 case CS_ConfigValueFinished: 346 if (evaluation.configvalue_) 347 return CommandExecutor::dump(evaluation.configvalue_); 348 break; 349 case CS_KeybindKey: 350 return CommandExecutor::dump(evaluation.listOfPossibleKeys_); 351 break; 352 case CS_KeybindCommand: 353 if (evaluation.key_) 354 return CommandExecutor::dump(evaluation.key_); 355 break; 356 case CS_KeybindFinished: 357 if (evaluation.key_) 358 return CommandExecutor::dump(evaluation.key_); 359 break; 360 case CS_Error: 361 return CommandExecutor::getEvaluation().errorMessage_; 362 break; 363 } 364 365 return ""; 115 return CommandExecutor::getEvaluation().hint(); 366 116 } 367 117 … … 369 119 { 370 120 CommandExecutor::parse(command, true); 371 372 if (CommandExecutor::getEvaluation().tokens_.size() > 0)373 {374 std::string lastToken;375 lastToken = CommandExecutor::getEvaluation().tokens_[CommandExecutor::getEvaluation().tokens_.size() - 1];376 lastToken = lastToken.substr(0, lastToken.size() - 1);377 CommandExecutor::getEvaluation().tokens_.pop_back();378 CommandExecutor::getEvaluation().tokens_.append(SubString(lastToken, " ", "", true, '\0', false, '\0', false, '\0', '\0', false, '\0'));379 }380 381 121 CommandExecutor::getEvaluation().evaluateParams(); 382 122 return CommandExecutor::getEvaluation(); … … 385 125 void CommandExecutor::parse(const std::string& command, bool bInitialize) 386 126 { 387 CommandExecutor::getEvaluation().tokens_.split((command + COMMAND_EXECUTOR_CURSOR), " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');388 CommandExecutor::getEvaluation().processedCommand_ = command;389 390 127 if (bInitialize) 391 CommandExecutor::initialize(command); 392 393 switch (CommandExecutor::getEvaluation().state_) 394 { 395 case CS_Uninitialized: 396 // Impossible 397 break; 398 case CS_Empty: 399 if (CommandExecutor::argumentsGiven() == 0) 400 { 401 // We want a hint for the first token 402 // Check if there is already a perfect match 403 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0)); 404 CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0)); 405 406 if ((CommandExecutor::getEvaluation().functionclass_) || (CommandExecutor::getEvaluation().shortcut_)) 407 { 408 // Yes, there is a class or a shortcut with the searched name 409 // Add a whitespace and continue parsing 410 CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword; 411 CommandExecutor::parse(command + " ", false); 412 return; 413 } 414 415 // No perfect match: Create the lists of all possible classes and shortcuts and return 416 CommandExecutor::createListOfPossibleFunctionClasses(CommandExecutor::getToken(0)); 417 CommandExecutor::createListOfPossibleShortcuts(CommandExecutor::getToken(0)); 418 419 // Check if there's only one possiblility 420 if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 1) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 0)) 421 { 422 // There's only one possible class 423 CommandExecutor::getEvaluation().state_ = CS_Function; 424 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first); 425 CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first + " ", false); 426 return; 427 } 428 else if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 0) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 1)) 429 { 430 if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) 431 && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY) 432 && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)) 433 { 434 // There's only one possible shortcut 435 CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params; 436 CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first); 437 } 438 else if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) 439 || (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) 440 { 441 // It's the 'set' or 'tset' keyword 442 CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass; 443 } 444 else if (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) 445 { 446 // It's the 'bind' keyword 447 CommandExecutor::getEvaluation().state_ = CS_KeybindKey; 448 } 449 450 CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first + " ", false); 451 return; 452 } 453 454 // It's ambiguous 455 return; 456 } 457 else 458 { 459 // There is at least one argument: Check if it's a shortcut, a classname or a special keyword 460 CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword; 461 CommandExecutor::parse(command, false); 462 return; 463 } 464 break; 465 case CS_FunctionClass_Or_Shortcut_Or_Keyword: 466 if (CommandExecutor::argumentsGiven() >= 1) 467 { 468 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) 469 { 470 // We want to set a config value 471 CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass; 472 CommandExecutor::parse(command, false); 473 return; 474 } 475 else if (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) 476 { 477 // We want to set a keybinding 478 CommandExecutor::getEvaluation().state_ = CS_KeybindKey; 479 CommandExecutor::parse(command, false); 480 return; 481 } 482 483 if (!CommandExecutor::getEvaluation().functionclass_) 484 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0)); 485 if (!CommandExecutor::getEvaluation().shortcut_) 486 CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0)); 487 488 if ((!CommandExecutor::getEvaluation().functionclass_) && (!CommandExecutor::getEvaluation().shortcut_)) 489 { 490 // Argument 1 seems to be wrong 491 AddLanguageEntry("CommandExecutor::NoSuchCommandOrClassName", "No such command or classname"); 492 CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(0) + ": " + GetLocalisation("CommandExecutor::NoSuchCommandOrClassName")); 493 CommandExecutor::getEvaluation().state_ = CS_Error; 494 return; 495 } 496 else if (CommandExecutor::getEvaluation().shortcut_) 497 { 498 // Argument 1 is a shortcut: Return the needed parameter types 499 CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params; 500 CommandExecutor::parse(command, false); 501 return; 502 } 503 else 504 { 505 // Argument 1 is a classname: Return the possible functions 506 CommandExecutor::getEvaluation().state_ = CS_Function; 507 CommandExecutor::parse(command, false); 508 return; 509 } 510 } 511 else 512 { 513 CommandExecutor::getEvaluation().state_ = CS_Error; 514 return; 515 } 516 break; 517 case CS_Shortcut_Params: 518 if (CommandExecutor::getEvaluation().shortcut_) 519 { 520 // Valid command 521 // Check if there are enough parameters 522 if (CommandExecutor::enoughParametersGiven(1, CommandExecutor::getEvaluation().shortcut_)) 523 { 524 CommandExecutor::getEvaluation().state_ = CS_Shortcut_Finished; 525 return; 526 } 527 } 528 else 529 { 530 // Something is wrong 531 CommandExecutor::getEvaluation().state_ = CS_Error; 532 return; 533 } 534 break; 535 case CS_Function: 536 if (CommandExecutor::getEvaluation().functionclass_) 537 { 538 // We have a valid classname 539 // Check if there is a second argument 540 if (CommandExecutor::argumentsGiven() >= 2) 541 { 542 // There is a second argument: Check if it's a valid functionname 543 CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_); 544 if (!CommandExecutor::getEvaluation().function_) 545 { 546 // Argument 2 seems to be wrong 547 AddLanguageEntry("CommandExecutor::NoSuchFunctionnameIn", "No such functionname in"); 548 CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchFunctionnameIn") + " " + CommandExecutor::getEvaluation().functionclass_->getName()); 549 CommandExecutor::getEvaluation().state_ = CS_Error; 550 return; 551 } 552 else 553 { 554 // Argument 2 seems to be a valid functionname: Get the parameters 555 CommandExecutor::getEvaluation().state_ = CS_Function_Params; 556 CommandExecutor::parse(command, false); 557 return; 558 } 559 } 560 else 561 { 562 // There is no finished second argument 563 // Check if there's already a perfect match 564 if (CommandExecutor::getEvaluation().tokens_.size() >= 2) 565 { 566 CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_); 567 if (CommandExecutor::getEvaluation().function_) 568 { 569 // There is a perfect match: Add a whitespace and continue parsing 570 CommandExecutor::getEvaluation().state_ = CS_Function_Params; 571 CommandExecutor::parse(command + " ", false); 572 return; 573 } 574 } 575 576 // No perfect match: Create the list of all possible functions and return 577 CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_); 578 579 // Check if there's only one possiblility 580 if (CommandExecutor::getEvaluation().listOfPossibleFunctions_.size() == 1) 581 { 582 // There's only one possible function 583 CommandExecutor::getEvaluation().state_ = CS_Function_Params; 584 CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(*(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first, CommandExecutor::getEvaluation().functionclass_); 585 CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first + " ", false); 586 return; 587 } 588 589 // It's ambiguous 590 return; 591 } 592 } 593 else 594 { 595 CommandExecutor::getEvaluation().state_ = CS_Error; 596 return; 597 } 598 break; 599 case CS_Function_Params: 600 if (CommandExecutor::getEvaluation().functionclass_ && CommandExecutor::getEvaluation().function_) 601 { 602 // Valid command 603 // Check if there are enough parameters 604 if (CommandExecutor::enoughParametersGiven(2, CommandExecutor::getEvaluation().function_)) 605 { 606 CommandExecutor::getEvaluation().state_ = CS_Function_Finished; 607 return; 608 } 609 } 610 else 611 { 612 // Something is wrong 613 CommandExecutor::getEvaluation().state_ = CS_Error; 614 return; 615 } 616 break; 617 case CS_ConfigValueClass: 618 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))) 619 { 620 // We want to set a config value 621 // Check if there is a second argument 622 if (CommandExecutor::argumentsGiven() >= 2) 623 { 624 // There is a second argument: Check if it's a valid classname 625 CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1)); 626 if (!CommandExecutor::getEvaluation().configvalueclass_) 627 { 628 // Argument 2 seems to be wrong 629 AddLanguageEntry("CommandExecutor::NoSuchClassWithConfigValues", "No such class with config values"); 630 CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchClassWithConfigValues")); 631 CommandExecutor::getEvaluation().state_ = CS_Error; 632 return; 633 } 634 else 635 { 636 // Argument 2 seems to be a valid classname: Search for possible config values 637 CommandExecutor::getEvaluation().state_ = CS_ConfigValue; 638 CommandExecutor::parse(command, false); 639 return; 640 } 641 } 642 else 643 { 644 // There's no finished second argument 645 // Check if there's already a perfect match 646 if (CommandExecutor::getEvaluation().tokens_.size() >= 2) 647 { 648 CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1)); 649 if (CommandExecutor::getEvaluation().configvalueclass_) 650 { 651 // There is a perfect match: Add a whitespace and continue parsing 652 CommandExecutor::getEvaluation().state_ = CS_ConfigValue; 653 CommandExecutor::parse(command + " ", false); 654 return; 655 } 656 } 657 658 // No perfect match: Create the list of all possible classnames and return 659 CommandExecutor::createListOfPossibleConfigValueClasses(CommandExecutor::getToken(1)); 660 661 // Check if there's only one possiblility 662 if (CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.size() == 1) 663 { 664 // There's only one possible classname 665 CommandExecutor::getEvaluation().state_ = CS_ConfigValue; 666 CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first); 667 CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first + " ", false); 668 return; 669 } 670 671 // It's ambiguous 672 return; 673 } 674 } 675 else 676 { 677 // Something is wrong 678 CommandExecutor::getEvaluation().state_ = CS_Error; 679 return; 680 } 681 break; 682 case CS_ConfigValue: 683 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getEvaluation().configvalueclass_)) 684 { 685 // Check if there is a third argument 686 if (CommandExecutor::argumentsGiven() >= 3) 687 { 688 // There is a third argument: Check if it's a valid config value 689 CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_); 690 if (!CommandExecutor::getEvaluation().configvalue_) 691 { 692 // Argument 3 seems to be wrong 693 AddLanguageEntry("CommandExecutor::NoSuchConfigValueIn", "No such config value in"); 694 CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(2) + ": " + GetLocalisation("CommandExecutor::NoSuchConfigValueIn") + " " + CommandExecutor::getEvaluation().configvalueclass_->getName()); 695 CommandExecutor::getEvaluation().state_ = CS_Error; 696 return; 697 } 698 else 699 { 700 // Argument 3 seems to be a valid config value: Get the type 701 CommandExecutor::getEvaluation().state_ = CS_ConfigValueType; 702 CommandExecutor::parse(command, false); 703 return; 704 } 705 } 706 else 707 { 708 // There is no finished third argument 709 // Check if there's already a perfect match 710 if (CommandExecutor::getEvaluation().tokens_.size() >= 3) 711 { 712 CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_); 713 if (CommandExecutor::getEvaluation().configvalue_) 714 { 715 // There is a perfect match: Add a whitespace and continue parsing 716 CommandExecutor::getEvaluation().state_ = CS_ConfigValueType; 717 CommandExecutor::parse(command + " ", false); 718 return; 719 } 720 } 721 722 // No perfect match: Create the list of all possible config values 723 CommandExecutor::createListOfPossibleConfigValues(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_); 724 725 // Check if there's only one possiblility 726 if (CommandExecutor::getEvaluation().listOfPossibleConfigValues_.size() == 1) 727 { 728 // There's only one possible config value 729 CommandExecutor::getEvaluation().state_ = CS_ConfigValueType; 730 CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first, CommandExecutor::getEvaluation().configvalueclass_); 731 CommandExecutor::parse(CommandExecutor::getToken(0) + " " + CommandExecutor::getToken(1) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first + " ", false); 732 return; 733 } 734 735 // It's ambiguous 736 return; 737 } 738 } 739 else 740 { 741 // Something is wrong 742 CommandExecutor::getEvaluation().state_ = CS_Error; 743 return; 744 } 745 break; 746 case CS_ConfigValueType: 747 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && CommandExecutor::getEvaluation().configvalueclass_ && CommandExecutor::getEvaluation().configvalue_) 748 { 749 // Valid command 750 // Check if there are enough parameters 751 if ((CommandExecutor::getEvaluation().tokens_.size() >= 4) && (CommandExecutor::getEvaluation().tokens_[3] != COMMAND_EXECUTOR_CURSOR)) 752 { 753 CommandExecutor::getEvaluation().state_ = CS_ConfigValueFinished; 754 return; 755 } 756 } 757 else 758 { 759 // Something is wrong 760 CommandExecutor::getEvaluation().state_ = CS_Error; 761 return; 762 } 763 break; 764 case CS_KeybindKey: 765 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)) 766 { 767 // todo 768 } 769 else 770 { 771 // Something is wrong 772 CommandExecutor::getEvaluation().state_ = CS_Error; 773 return; 774 } 775 break; 776 case CS_KeybindCommand: 777 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) && (false)) // todo 778 { 779 // Valid command 780 // Check if there are enough parameters 781 if (CommandExecutor::getEvaluation().tokens_.size() >= 3) 782 { 783 CommandExecutor::getEvaluation().state_ = CS_KeybindFinished; 784 return; 785 } 786 787 } 788 else 789 { 790 // Something is wrong 791 CommandExecutor::getEvaluation().state_ = CS_Error; 792 return; 793 } 794 break; 795 case CS_Shortcut_Finished: 796 // Nothing to do 797 break; 798 case CS_Function_Finished: 799 // Nothing to do 800 break; 801 case CS_ConfigValueFinished: 802 // Nothing to do 803 break; 804 case CS_KeybindFinished: 805 // Nothing to do 806 break; 807 case CS_Error: 808 // This is bad 809 break; 810 } 811 } 812 813 void CommandExecutor::initialize(const std::string& command) 814 { 815 CommandExecutor::getEvaluation().processedCommand_ = command; 816 CommandExecutor::getEvaluation().additionalParameter_ = ""; 817 818 CommandExecutor::getEvaluation().bEvaluatedParams_ = false; 819 CommandExecutor::getEvaluation().evaluatedExecutor_ = 0; 820 821 CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.clear(); 822 CommandExecutor::getEvaluation().listOfPossibleShortcuts_.clear(); 823 CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear(); 824 CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.clear(); 825 CommandExecutor::getEvaluation().listOfPossibleConfigValues_.clear(); 826 CommandExecutor::getEvaluation().listOfPossibleKeys_.clear(); 827 828 CommandExecutor::getEvaluation().functionclass_ = 0; 829 CommandExecutor::getEvaluation().configvalueclass_ = 0; 830 CommandExecutor::getEvaluation().shortcut_ = 0; 831 CommandExecutor::getEvaluation().function_ = 0; 832 CommandExecutor::getEvaluation().configvalue_ = 0; 833 CommandExecutor::getEvaluation().key_ = 0; 834 835 CommandExecutor::getEvaluation().errorMessage_ = ""; 836 CommandExecutor::getEvaluation().state_ = CS_Empty; 837 } 838 839 bool CommandExecutor::argumentsGiven(unsigned int num) 128 CommandExecutor::getEvaluation().initialize(command); 129 else 130 CommandExecutor::getEvaluation().setNewCommand(false); 131 132 CommandExecutor::getEvaluation().setTokens(command + COMMAND_EXECUTOR_CURSOR); 133 CommandExecutor::getEvaluation().setCommand(command); 134 135 switch (CommandExecutor::getEvaluation().getState()) 136 { 137 } 138 } 139 140 bool CommandExecutor::argumentsFinished(unsigned int num) 141 { 142 return (CommandExecutor::argumentsFinished() >= num); 143 } 144 145 unsigned int CommandExecutor::argumentsFinished() 840 146 { 841 147 // Because we added a cursor we have +1 arguments 842 // There are num arguments given if there are at least num arguments + one cursor 843 return (CommandExecutor::getEvaluation().tokens_.size() >= (num + 1)); 148 if (CommandExecutor::getEvaluation().getTokens().size() >= 1) 149 return (CommandExecutor::getEvaluation().getTokens().size() - 1); 150 else 151 return 0; 152 } 153 154 std::string CommandExecutor::getToken(unsigned int index) 155 { 156 if ((index >= 0) && index < (CommandExecutor::getEvaluation().getOriginalTokens().size())) 157 return CommandExecutor::getEvaluation().getOriginalTokens()[index]; 158 else 159 return ""; 844 160 } 845 161 846 162 unsigned int CommandExecutor::argumentsGiven() 847 163 { 848 // Because we added a cursor we have +1 arguments 849 if (CommandExecutor::getEvaluation().tokens_.size() >= 1) 850 return (CommandExecutor::getEvaluation().tokens_.size() - 1); 851 else 852 return 0; 853 } 854 855 std::string CommandExecutor::getToken(unsigned int index) 856 { 857 if ((index >= 0) && (index < (CommandExecutor::getEvaluation().tokens_.size() - 1))) 858 return CommandExecutor::getEvaluation().tokens_[index]; 859 else if (index == (CommandExecutor::getEvaluation().tokens_.size() - 1)) 860 return CommandExecutor::getEvaluation().tokens_[index].substr(0, CommandExecutor::getEvaluation().tokens_[index].size() - 1); 861 else 862 return ""; 863 } 864 865 bool CommandExecutor::enoughParametersGiven(unsigned int head, Executor* executor) 866 { 867 unsigned int neededParams = head + executor->getParamCount(); 868 /* 869 for (unsigned int i = executor->getParamCount() - 1; i >= 0; i--) 870 { 871 if (executor->defaultValueSet(i)) 872 neededParams--; 873 else 874 break; 875 } 876 */ 877 return ((CommandExecutor::getEvaluation().tokens_.size() >= neededParams) && (CommandExecutor::getEvaluation().tokens_[neededParams - 1] != COMMAND_EXECUTOR_CURSOR)); 164 return CommandExecutor::getEvaluation().getOriginalTokens().size(); 165 } 166 167 bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command, unsigned int head) 168 { 169 return (CommandExecutor::argumentsGiven() >= (head + command->getParamCount())); 878 170 } 879 171 … … 881 173 { 882 174 for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it) 883 {884 175 if ((*it).second->hasConsoleCommands()) 885 {886 176 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 887 { 888 CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 889 } 890 } 891 } 892 893 CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.sort(CommandExecutor::compareStringsInList); 894 } 895 896 void CommandExecutor::createListOfPossibleShortcuts(const std::string& fragment) 897 { 898 for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it) 899 { 900 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 901 { 902 CommandExecutor::getEvaluation().listOfPossibleShortcuts_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 903 } 904 } 905 906 CommandExecutor::getEvaluation().listOfPossibleShortcuts_.sort(CommandExecutor::compareStringsInList); 177 CommandExecutor::getEvaluation().getListOfPossibleFunctionClasses().push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 178 179 CommandExecutor::getEvaluation().getListOfPossibleFunctionClasses().sort(CommandExecutor::compareStringsInList); 907 180 } 908 181 909 182 void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier) 910 183 { 911 for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it) 912 { 913 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 914 { 915 CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 916 } 917 } 918 919 CommandExecutor::getEvaluation().listOfPossibleFunctions_.sort(CommandExecutor::compareStringsInList); 920 } 921 922 void CommandExecutor::createListOfPossibleConfigValueClasses(const std::string& fragment) 923 { 924 for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it) 925 { 926 if ((*it).second->hasConfigValues()) 927 { 184 if (!identifier) 185 { 186 for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it) 928 187 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 929 { 930 CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 931 } 932 } 933 } 934 935 CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.sort(CommandExecutor::compareStringsInList); 936 } 937 938 void CommandExecutor::createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier) 939 { 940 for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMapBegin(); it != identifier->getLowercaseConfigValueMapEnd(); ++it) 941 { 942 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 943 { 944 CommandExecutor::getEvaluation().listOfPossibleConfigValues_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 945 } 946 } 947 948 CommandExecutor::getEvaluation().listOfPossibleConfigValues_.sort(CommandExecutor::compareStringsInList); 949 } 950 951 void CommandExecutor::createListOfPossibleKeys(const std::string& fragment) 952 { 953 // todo 954 955 CommandExecutor::getEvaluation().listOfPossibleKeys_.sort(CommandExecutor::compareStringsInList); 956 } 957 958 bool CommandExecutor::compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second) 959 { 960 return ((*first.first) < (*second.first)); 961 } 962 963 Identifier* CommandExecutor::getIdentifierOfPossibleFunctionClass(const std::string& name) 188 CommandExecutor::getEvaluation().getListOfPossibleFunctions().push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 189 } 190 else 191 { 192 for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it) 193 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "") 194 CommandExecutor::getEvaluation().getListOfPossibleFunctions().push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName())); 195 } 196 CommandExecutor::getEvaluation().getListOfPossibleFunctions().sort(CommandExecutor::compareStringsInList); 197 } 198 199 Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name) 964 200 { 965 201 std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name)); … … 970 206 } 971 207 972 ConsoleCommand* CommandExecutor::getExecutorOfPossibleShortcut(const std::string& name) 973 { 974 std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name)); 975 if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd()) 976 return (*it).second; 977 208 ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier) 209 { 210 if (!identifier) 211 { 212 std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name)); 213 if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd()) 214 return (*it).second; 215 } 216 else 217 { 218 std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name)); 219 if (it != identifier->getLowercaseConsoleCommandMapEnd()) 220 return (*it).second; 221 } 978 222 return 0; 979 223 } 980 224 981 ConsoleCommand* CommandExecutor::getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier) 982 { 983 std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name)); 984 if (it != identifier->getLowercaseConsoleCommandMapEnd()) 985 return (*it).second; 986 987 return 0; 988 } 989 990 Identifier* CommandExecutor::getIdentifierOfPossibleConfigValueClass(const std::string& name) 991 { 992 std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name)); 993 if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConfigValues()) 994 return (*it).second; 995 996 return 0; 997 } 998 999 ConfigValueContainer* CommandExecutor::getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier) 1000 { 1001 std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMap().find(getLowercase(name)); 1002 if (it != identifier->getLowercaseConfigValueMapEnd()) 1003 { 1004 return (*it).second; 1005 } 1006 1007 return 0; 1008 } 1009 1010 ConfigValueContainer* CommandExecutor::getContainerOfPossibleKey(const std::string& name) 1011 { 1012 // todo 1013 1014 return 0; 1015 } 1016 1017 std::string CommandExecutor::dump(const std::list<std::pair<const std::string*, const std::string*> >& list) 1018 { 1019 std::string output = ""; 1020 for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it) 1021 { 1022 if (it != list.begin()) 1023 output += " "; 1024 1025 output += *(*it).second; 1026 } 1027 return output; 1028 } 1029 1030 std::string CommandExecutor::dump(const ConsoleCommand* command) 1031 { 1032 std::string output = ""; 1033 for (unsigned int i = 0; i < command->getParamCount(); i++) 1034 { 1035 if (i != 0) 1036 output += " "; 1037 1038 if (command->defaultValueSet(i)) 1039 output += "["; 1040 else 1041 output += "{"; 1042 1043 output += command->getTypenameParam(i); 1044 1045 if (command->defaultValueSet(i)) 1046 output += "=" + command->getDefaultValue(i).toString() + "]"; 1047 else 1048 output += "}"; 1049 } 1050 return output; 1051 } 1052 1053 std::string CommandExecutor::dump(const ConfigValueContainer* container) 1054 { 1055 AddLanguageEntry("CommandExecutor::oldvalue", "old value"); 1056 if (!container->isVector()) 1057 return ("{" + container->getTypename() + "} (" + GetLocalisation("CommandExecutor::oldvalue") + ": " + container->toString() + ")"); 1058 else 1059 return ("(vector<" + container->getTypename() + ">) (size: " + getConvertedValue<unsigned int, std::string>(container->getVectorSize()) + ")"); 1060 } 1061 1062 std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list) 1063 { 1064 if (list.size() == 0) 1065 { 1066 return ""; 1067 } 1068 else if (list.size() == 1) 1069 { 1070 return ((*(*list.begin()).first) + " "); 1071 } 1072 else 1073 { 1074 std::string output = ""; 1075 for (unsigned int i = 0; true; i++) 1076 { 1077 char temp = 0; 1078 for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it) 1079 { 1080 if ((*(*it).first).size() > i) 1081 { 1082 if (it == list.begin()) 1083 { 1084 temp = (*(*it).first)[i]; 1085 } 1086 else 1087 { 1088 if (temp != (*(*it).first)[i]) 1089 return output; 1090 } 1091 } 1092 else 1093 { 1094 return output; 1095 } 1096 } 1097 output += temp; 1098 } 1099 return output; 1100 } 225 bool CommandExecutor::compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second) 226 { 227 return ((*first.first) < (*second.first)); 1101 228 } 1102 229 } -
code/branches/console/src/core/CommandExecutor.h
r1341 r1351 44 44 public: 45 45 static bool execute(const std::string& command, bool useTcl = true); 46 static bool execute(const CommandEvaluation& evaluation);47 48 46 static std::string complete(const std::string& command); 49 static std::string complete(const CommandEvaluation& evaluation);50 51 47 static std::string hint(const std::string& command); 52 static std::string hint(const CommandEvaluation& evaluation);53 48 54 49 static CommandEvaluation evaluate(const std::string& command); 55 56 50 static const CommandEvaluation& getLastEvaluation(); 57 51 … … 83 77 84 78 static void parse(const std::string& command, bool bInitialize = true); 85 static void initialize(const std::string& command);86 79 87 static bool argumentsGiven(unsigned int num); 80 static bool argumentsFinished(unsigned int num); 81 static unsigned int argumentsFinished(); 88 82 static unsigned int argumentsGiven(); 89 83 static bool enoughArgumentsGiven(ConsoleCommand* command, unsigned int head); 90 84 static std::string getToken(unsigned int index); 91 85 92 static bool enoughParametersGiven(unsigned int head, Executor* executor); 86 static void createListOfPossibleFunctionClasses(const std::string& fragment); 87 static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier = 0); 93 88 94 static void createListOfPossibleShortcuts(const std::string& fragment); 95 static void createListOfPossibleFunctionClasses(const std::string& fragment); 96 static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier); 97 static void createListOfPossibleConfigValueClasses(const std::string& fragment); 98 static void createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier); 99 static void createListOfPossibleKeys(const std::string& fragment); 89 static Identifier* getPossibleIdentifier(const std::string& name); 90 static ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0); 100 91 101 92 static bool compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second); 102 93 103 static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);104 static std::string dump(const ConsoleCommand* command);105 static std::string dump(const ConfigValueContainer* container);106 107 static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);108 109 static Identifier* getIdentifierOfPossibleFunctionClass(const std::string& name);110 static ConsoleCommand* getExecutorOfPossibleShortcut(const std::string& name);111 static ConsoleCommand* getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier);112 static Identifier* getIdentifierOfPossibleConfigValueClass(const std::string& name);113 static ConfigValueContainer* getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier);114 static ConfigValueContainer* getContainerOfPossibleKey(const std::string& name);115 94 116 95 CommandEvaluation evaluation_; 117 118 96 std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_; 119 97 std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_LC_;
Note: See TracChangeset
for help on using the changeset viewer.