- Timestamp:
- Aug 27, 2010, 2:41:03 PM (14 years ago)
- Location:
- code/branches/consolecommands3/src/libraries/core/command
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/consolecommands3/src/libraries/core/command/ArgumentCompletionFunctions.cc
r7203 r7228 39 39 #include "core/ConfigValueContainer.h" 40 40 #include "TclThreadManager.h" 41 #include "ConsoleCommand.h" 41 42 42 43 // Boost 1.36 has some issues with deprecated functions that have been omitted … … 54 55 { 55 56 return ArgumentCompletionList(); 57 } 58 59 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)() 60 { 61 ArgumentCompletionList groupList; 62 63 const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& commands = _ConsoleCommand::getCommands(); 64 for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group) 65 // todo: check if active / not hidden / not denied 66 groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first))); 67 68 std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.find(""); 69 if (it_group != commands.end()) 70 { 71 groupList.push_back(ArgumentCompletionListElement("\n")); 72 73 for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command) 74 // todo: check if active / not hidden / not denied 75 groupList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first))); 76 } 77 78 return groupList; 79 } 80 81 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group) 82 { 83 ArgumentCompletionList commandList; 84 85 std::string groupLC = getLowercase(group); 86 87 std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().begin(); 88 for ( ; it_group != _ConsoleCommand::getCommands().end(); ++it_group) 89 if (getLowercase(it_group->first) == groupLC) 90 break; 91 92 if (it_group != _ConsoleCommand::getCommands().end()) 93 { 94 for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command) 95 // todo: check if active / not hidden / not denied 96 commandList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first))); 97 } 98 99 return commandList; 56 100 } 57 101 -
code/branches/consolecommands3/src/libraries/core/command/ArgumentCompletionFunctions.h
r7203 r7228 53 53 { 54 54 ARGUMENT_COMPLETION_FUNCTION_DECLARATION(fallback)(); 55 ARGUMENT_COMPLETION_FUNCTION_DECLARATION(groupsandcommands)(); 56 ARGUMENT_COMPLETION_FUNCTION_DECLARATION(subcommands)(const std::string& fragment, const std::string& group); 55 57 ARGUMENT_COMPLETION_FUNCTION_DECLARATION(files)(const std::string& fragment); 56 58 ARGUMENT_COMPLETION_FUNCTION_DECLARATION(settingssections)(); -
code/branches/consolecommands3/src/libraries/core/command/ArgumentCompletionListElement.h
r7203 r7228 38 38 { 39 39 const int ACL_MODE_NORMAL = 1; 40 const int ACL_MODE_ LOWERCASE = 2;40 const int ACL_MODE_COMPARABLE = 2; 41 41 const int ACL_MODE_DISPLAY = 4; 42 42 … … 46 46 { 47 47 public: 48 ArgumentCompletionListElement(const std::string& normalcase) : mode_(ACL_MODE_NORMAL), normal Case_(normalcase) {}49 ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase) : mode_(ACL_MODE_NORMAL | ACL_MODE_ LOWERCASE), normalCase_(normalcase), lowerCase_(lowercase) {}50 ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase, const std::string& display) : mode_(ACL_MODE_NORMAL | ACL_MODE_ LOWERCASE | ACL_MODE_DISPLAY), normalCase_(normalcase), lowerCase_(lowercase), display_(display) {}48 ArgumentCompletionListElement(const std::string& normalcase) : mode_(ACL_MODE_NORMAL), normal_(normalcase) {} 49 ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase) : mode_(ACL_MODE_NORMAL | ACL_MODE_COMPARABLE), normal_(normalcase), comparable_(lowercase) {} 50 ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase, const std::string& display) : mode_(ACL_MODE_NORMAL | ACL_MODE_COMPARABLE | ACL_MODE_DISPLAY), normal_(normalcase), comparable_(lowercase), display_(display) {} 51 51 52 52 const std::string& getString() const 53 { return this->normal Case_; }53 { return this->normal_; } 54 54 const std::string& getComparable() const 55 { if (this->mode_ & ACL_MODE_LOWERCASE) { return this->lowerCase_; } else { return this->normalCase_; }}55 { return (this->mode_ & ACL_MODE_COMPARABLE) ? this->comparable_ : this->normal_; } 56 56 const std::string& getDisplay() const 57 { if (this->mode_ & ACL_MODE_DISPLAY) { return this->display_; } else { return this->normalCase_; }}57 { return (this->mode_ & ACL_MODE_DISPLAY) ? this->display_ : this->normal_; } 58 58 59 bool lowercaseComparison() const 60 { return (this->mode_ & ACL_MODE_LOWERCASE); } 59 bool hasComparable() const 60 { return (this->mode_ & ACL_MODE_COMPARABLE); } 61 bool hasDisplay() const 62 { return (this->mode_ & ACL_MODE_DISPLAY); } 61 63 62 64 bool operator<(const ArgumentCompletionListElement& other) const … … 65 67 private: 66 68 unsigned char mode_; 67 std::string normal Case_;68 std::string lowerCase_;69 std::string normal_; 70 std::string comparable_; 69 71 std::string display_; 70 72 }; -
code/branches/consolecommands3/src/libraries/core/command/CommandEvaluation.cc
r7221 r7228 29 29 #include "CommandEvaluation.h" 30 30 31 #include "util/Debug.h"32 31 #include "util/StringUtils.h" 33 #include " core/Identifier.h"32 #include "CommandExecutor.h" 34 33 #include "ConsoleCommand.h" 35 34 … … 39 38 { 40 39 this->initialize(""); 41 this->state_ = CommandState::Uninitialized;42 40 } 43 41 44 42 void CommandEvaluation::initialize(const std::string& command) 45 43 { 46 this->bNewCommand_ = true; 47 this->bCommandChanged_ = false; 48 this->originalCommand_ = command; 49 this->command_ = command; 50 this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 51 52 this->additionalParameter_.clear(); 53 54 this->bEvaluatedParams_ = false; 55 56 this->listOfPossibleIdentifiers_.clear(); 57 this->listOfPossibleFunctions_.clear(); 58 this->listOfPossibleArguments_.clear(); 59 60 this->functionclass_ = 0; 61 this->function_ = 0; 62 this->possibleArgument_.clear(); 63 this->argument_.clear(); 64 65 this->errorMessage_.clear(); 66 this->state_ = CommandState::Empty; 67 } 68 69 bool CommandEvaluation::execute() const 70 { 71 bool success; 72 this->query(&success); 73 return success; 74 } 75 76 MultiType CommandEvaluation::query(bool* success) const 77 { 78 if (success) 79 *success = false; 80 81 if (!this->function_ || !this->function_->isActive()) 44 this->execCommand_ = 0; 45 this->hintCommand_ = 0; 46 this->string_ = command; 47 this->execArgumentsOffset_ = 0; 48 this->hintArgumentsOffset_ = 0; 49 this->bPossibleArgumentsRetrieved_ = false; 50 this->possibleArguments_.clear(); 51 52 this->tokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 53 } 54 55 unsigned int CommandEvaluation::getNumberOfArguments() const 56 { 57 unsigned int count = this->tokens_.size(); 58 if (count > 0 && this->string_[this->string_.size() - 1] != ' ') 59 return count; 60 else 61 return count + 1; 62 } 63 64 const std::string& CommandEvaluation::getLastArgument() const 65 { 66 if (this->tokens_.size() > 0 && this->string_[this->string_.size() - 1] != ' ') 67 return this->tokens_.back(); 68 else 69 return BLANKSTRING; 70 } 71 72 const std::string& CommandEvaluation::getToken(unsigned int i) const 73 { 74 if (i < this->tokens_.size()) 75 return this->tokens_[i]; 76 else 77 return BLANKSTRING; 78 } 79 80 int CommandEvaluation::execute() const 81 { 82 int error; 83 this->query(&error); 84 return error; 85 } 86 87 MultiType CommandEvaluation::query(int* error) const 88 { 89 if (error) 90 { 91 *error = CommandExecutor::Success; 92 93 if (!this->execCommand_) 94 *error = CommandExecutor::Error; 95 else if (!this->execCommand_->isActive()) 96 *error = CommandExecutor::Deactivated; 97 else if (!this->execCommand_->hasAccess()) 98 *error = CommandExecutor::Denied; 99 100 if (*error != CommandExecutor::Success) 101 return MT_Type::Null; 102 } 103 104 if (this->execCommand_ && this->execCommand_->isActive() && this->execCommand_->hasAccess()) 105 return this->execCommand_->getExecutor()->parse(this->tokens_.subSet(this->execArgumentsOffset_).join(), error, " ", false); 106 else 82 107 return MT_Type::Null; 83 84 if (this->bEvaluatedParams_ && this->function_) 85 { 86 if (success) 87 *success = true; 88 COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << ' ' << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl; 89 return (*this->function_->getExecutor())(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]); 90 } 91 92 if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0) 93 { 94 COUT(4) << "CE_execute: " << this->command_ << "\n"; 95 96 unsigned int startindex = this->getStartindex(); 97 if (this->commandTokens_.size() > startindex) 98 return this->function_->getExecutor()->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()), success); 99 else 100 return this->function_->getExecutor()->parse(removeSlashes(this->additionalParameter_), success); 101 } 102 103 return MT_Type::Null; 104 } 105 106 const std::string& CommandEvaluation::complete() 107 { 108 if (!this->bNewCommand_) 109 { 110 switch (this->state_) 111 { 112 case CommandState::Uninitialized: 113 break; 114 case CommandState::Empty: 115 break; 116 case CommandState::ShortcutOrIdentifier: 117 if (this->function_) 108 } 109 110 std::string CommandEvaluation::complete() const 111 { 112 if (!this->hintCommand_ || !this->hintCommand_->isActive()) 113 return this->string_; 114 115 if (!this->bPossibleArgumentsRetrieved_) 116 this->retrievePossibleArguments(); 117 118 if (this->possibleArguments_.empty()) 119 { 120 return this->string_; 121 } 122 else 123 { 124 std::string output; 125 for (unsigned int i = 0; i < this->getNumberOfArguments() - 1; ++i) 126 output += this->getToken(i) + ' '; 127 128 output += CommandEvaluation::getCommonBegin(this->possibleArguments_); 129 return output; 130 } 131 } 132 133 std::string CommandEvaluation::hint() const 134 { 135 if (!this->hintCommand_ || !this->hintCommand_->isActive()) 136 return ""; 137 138 if (!this->bPossibleArgumentsRetrieved_) 139 this->retrievePossibleArguments(); 140 141 if (!this->possibleArguments_.empty()) 142 return CommandEvaluation::dump(this->possibleArguments_); 143 144 if (this->isValid()) 145 { 146 return CommandEvaluation::dump(this->hintCommand_); 147 } 148 else 149 { 150 if (this->getNumberOfArguments() > 2) 151 { 152 return std::string("Error: There is no command with name \"") + this->getToken(0) + " " + this->getToken(1) + "\"."; 153 } 154 else 155 { 156 std::string groupLC = getLowercase(this->getToken(0)); 157 std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().begin(); 158 for ( ; it_group != _ConsoleCommand::getCommands().end(); ++it_group) 159 if (getLowercase(it_group->first) == groupLC) 160 return std::string("Error: There is no command in group \"") + this->getToken(0) + "\" starting with \"" + this->getToken(1) + "\"."; 161 162 return std::string("Error: There is no command starting with \"") + this->getToken(0) + "\"."; 163 } 164 } 165 } 166 167 void CommandEvaluation::retrievePossibleArguments() const 168 { 169 this->bPossibleArgumentsRetrieved_ = true; 170 unsigned int argumentID = std::min(this->getNumberOfArguments() - this->hintArgumentsOffset_, this->hintCommand_->getExecutor()->getParamCount()); 171 ArgumentCompleter* ac = this->hintCommand_->getArgumentCompleter(argumentID - 1); 172 173 COUT(0) << "hint: args: " << this->getNumberOfArguments() << ", aID: " << argumentID << ", offset: " << this->hintArgumentsOffset_ << ", ac: " << ac << std::endl; 174 if (ac) 175 { 176 MultiType param[MAX_FUNCTOR_ARGUMENTS]; 177 178 for (size_t i = 0; i < argumentID; ++i) 179 { 180 param[i] = this->getToken(this->getNumberOfArguments() - i - 1); 181 COUT(0) << i << ": " << (this->getNumberOfArguments() - i - 1) << " -> " << this->getToken(this->getNumberOfArguments() - i - 1) << " / " << param[i] << std::endl; 182 } 183 184 COUT(0) << "hint: 1: " << param[0] << ", 2: " << param[1] << ", 3: " << param[2] << ", 4: " << param[3] << ", 5: " << param[4] << std::endl; 185 this->possibleArguments_ = (*ac)(param[0], param[1], param[2], param[3], param[4]); 186 187 CommandEvaluation::strip(this->possibleArguments_, param[0]); 188 } 189 } 190 191 /* static */ void CommandEvaluation::strip(ArgumentCompletionList& list, const std::string& fragment) 192 { 193 std::string fragmentLC = getLowercase(fragment); 194 195 for (ArgumentCompletionList::iterator it = list.begin(); it != list.end(); ) 196 { 197 const std::string& entry = it->getComparable(); 198 199 if (entry.size() < fragmentLC.size()) 200 { 201 list.erase(it++); 202 } 203 else 204 { 205 bool bErase = false; 206 for (size_t i = 0; i < fragmentLC.size(); ++i) 207 { 208 if (fragmentLC[i] != entry[i]) 118 209 { 119 if (this->function_->getExecutor()->getParamCount() == 0) 120 return (this->command_ = this->function_->getName()); 121 else 122 return (this->command_ = this->function_->getName() + ' '); 210 bErase = true; 211 break; 123 212 } 124 else if (this->functionclass_)125 return (this->command_ = this->functionclass_->getName() + ' ');126 break;127 case CommandState::Function:128 if (this->function_)129 {130 if (this->function_->getExecutor()->getParamCount() == 0)131 return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());132 else133 return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');134 }135 break;136 case CommandState::ParamPreparation:137 case CommandState::Params:138 {139 if (this->argument_.empty() && this->possibleArgument_.empty())140 break;141 142 unsigned int maxIndex = this->commandTokens_.size();143 if (this->command_[this->command_.size() - 1] != ' ')144 maxIndex -= 1;145 std::string whitespace;146 147 if (!this->possibleArgument_.empty())148 {149 this->argument_ = this->possibleArgument_;150 if (this->function_->getExecutor()->getParamCount() > (maxIndex + 1 - this->getStartindex()))151 whitespace = " ";152 }153 154 return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);155 break;156 213 } 157 case CommandState::Finished: 158 break; 159 case CommandState::Error: 160 break; 161 } 162 } 163 this->bNewCommand_ = false; 164 return this->command_; 165 } 166 167 std::string CommandEvaluation::hint() const 168 { 169 switch (this->state_) 170 { 171 case CommandState::Uninitialized: 172 break; 173 case CommandState::Empty: 174 case CommandState::ShortcutOrIdentifier: 175 if (this->listOfPossibleFunctions_.size() == 0) 176 return CommandEvaluation::dump(this->listOfPossibleIdentifiers_); 177 else if (this->listOfPossibleIdentifiers_.size() == 0) 178 return CommandEvaluation::dump(this->listOfPossibleFunctions_); 214 215 if (bErase) 216 list.erase(it++); 179 217 else 180 return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_)); 181 break; 182 case CommandState::Function: 183 return CommandEvaluation::dump(this->listOfPossibleFunctions_); 184 break; 185 case CommandState::ParamPreparation: 186 case CommandState::Params: 187 if (this->listOfPossibleArguments_.size() > 0) 188 return CommandEvaluation::dump(this->listOfPossibleArguments_); 189 else 190 return CommandEvaluation::dump(this->function_); 191 case CommandState::Finished: 192 if (this->function_) 193 return CommandEvaluation::dump(this->function_); 194 break; 195 case CommandState::Error: 196 return this->errorMessage_; 197 break; 198 } 199 200 return ""; 201 } 202 203 void CommandEvaluation::evaluateParams() 204 { 205 this->bEvaluatedParams_ = false; 206 207 for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++) 208 this->param_[i] = MT_Type::Null; 209 210 if (!this->function_) 211 return; 212 213 unsigned int startindex = this->getStartindex(); 214 215 if (this->commandTokens_.size() <= startindex) 216 { 217 if (this->function_->getBaseExecutor()->evaluate(this->getAdditionalParameter(), this->param_, " ")) 218 this->bEvaluatedParams_ = true; 219 } 220 else if (this->commandTokens_.size() > startindex) 221 { 222 if (this->function_->getBaseExecutor()->evaluate(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " ")) 223 this->bEvaluatedParams_ = true; 224 } 225 } 226 227 void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param) 228 { 229 if (index < MAX_FUNCTOR_ARGUMENTS) 230 this->param_[index] = param; 231 } 232 233 MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const 234 { 235 if (index < MAX_FUNCTOR_ARGUMENTS) 236 return this->param_[index]; 237 238 return MT_Type::Null; 239 } 240 241 unsigned int CommandEvaluation::getStartindex() const 242 { 243 if (this->functionclass_ && this->function_) 244 return 2; 245 else if (this->function_) 246 return 1; 247 else 248 return 0; 249 } 250 251 std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list) 218 ++it; 219 } 220 } 221 } 222 223 /* static */ std::string CommandEvaluation::dump(const ArgumentCompletionList& list) 252 224 { 253 225 std::string output; 254 for ( std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)226 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 255 227 { 256 228 if (it != list.begin()) 257 229 output += ' '; 258 230 259 output += *(it->second);231 output += it->getDisplay(); 260 232 } 261 233 return output; 262 234 } 263 235 264 std::string CommandEvaluation::dump(const ArgumentCompletionList& list) 265 { 266 std::string output; 267 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 268 { 269 if (it != list.begin()) 270 output += ' '; 271 272 output += it->getDisplay(); 273 } 274 return output; 275 } 276 277 std::string CommandEvaluation::dump(const _ConsoleCommand* command) 236 /* static */ std::string CommandEvaluation::dump(const _ConsoleCommand* command) 278 237 { 279 238 std::string output = command->getName(); … … 300 259 return output; 301 260 } 261 262 /* static */ std::string CommandEvaluation::getCommonBegin(const ArgumentCompletionList& list) 263 { 264 if (list.size() == 0) 265 { 266 return ""; 267 } 268 else if (list.size() == 1) 269 { 270 if (list.begin()->hasDisplay()) 271 return (list.begin()->getString()); 272 else 273 return (list.begin()->getString() + ' '); 274 } 275 else 276 { 277 std::string output; 278 for (unsigned int i = 0; true; i++) 279 { 280 char tempComparable = 0; 281 char temp = 0; 282 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 283 { 284 const std::string& argumentComparable = it->getComparable(); 285 const std::string& argument = it->getString(); 286 if (argument.size() > i) 287 { 288 if (it == list.begin()) 289 { 290 tempComparable = argumentComparable[i]; 291 temp = argument[i]; 292 } 293 else 294 { 295 if (tempComparable != argumentComparable[i]) 296 return output; 297 else if (temp != argument[i]) 298 temp = tempComparable; 299 } 300 } 301 else 302 { 303 return output; 304 } 305 } 306 output += temp; 307 } 308 return output; 309 } 310 } 302 311 } -
code/branches/consolecommands3/src/libraries/core/command/CommandEvaluation.h
r7221 r7228 33 33 34 34 #include <string> 35 #include <list>36 35 37 36 #include "ArgumentCompletionListElement.h" … … 41 40 namespace orxonox 42 41 { 43 namespace CommandState44 {45 enum Value46 {47 Uninitialized,48 Empty,49 ShortcutOrIdentifier,50 Function,51 ParamPreparation,52 Params,53 Finished,54 Error55 };56 }57 58 42 class _CoreExport CommandEvaluation 59 43 { … … 63 47 CommandEvaluation(); 64 48 49 int execute() const; 50 MultiType query(int* error = 0) const; 51 52 std::string complete() const; 53 std::string hint() const; 54 55 inline bool isValid() const 56 { return (this->execCommand_ != 0); } 57 58 inline _ConsoleCommand* getConsoleCommand() const 59 { return this->execCommand_; } 60 61 // void setEvaluatedParameter(unsigned int index, MultiType param); 62 // MultiType getEvaluatedParameter(unsigned int index) const; 63 64 private: 65 65 void initialize(const std::string& command); 66 66 67 bool execute() const; 68 MultiType query(bool* success = 0) const; 67 unsigned int getNumberOfArguments() const; 68 const std::string& getLastArgument() const; 69 const std::string& getToken(unsigned int i) const; 69 70 70 const std::string& complete(); 71 std::string hint() const; 72 void evaluateParams(); 71 void retrievePossibleArguments() const; 73 72 74 bool isValid() const 75 { return this->function_; } 73 static void strip(ArgumentCompletionList& list, const std::string& fragment); 76 74 77 inline _ConsoleCommand* getConsoleCommand() const78 { return this->function_; }79 inline const std::string& getOriginalCommand() const80 { return this->originalCommand_; }81 inline const std::string& getCommand() const82 { return this->command_; }83 84 inline void setAdditionalParameter(const std::string& param)85 { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }86 inline std::string getAdditionalParameter() const87 { return (!this->additionalParameter_.empty()) ? (' ' + this->additionalParameter_) : ""; }88 89 void setEvaluatedParameter(unsigned int index, MultiType param);90 MultiType getEvaluatedParameter(unsigned int index) const;91 92 private:93 unsigned int getStartindex() const;94 static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);95 75 static std::string dump(const ArgumentCompletionList& list); 96 76 static std::string dump(const _ConsoleCommand* command); 97 77 78 static std::string getCommonBegin(const ArgumentCompletionList& list); 98 79 99 bool bNewCommand_; 100 bool bCommandChanged_; 101 102 std::string originalCommand_; 103 std::string command_; 104 SubString commandTokens_; 105 std::string additionalParameter_; 106 107 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleIdentifiers_; 108 std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_; 109 ArgumentCompletionList listOfPossibleArguments_; 110 111 Identifier* functionclass_; 112 _ConsoleCommand* function_; 113 std::string possibleArgument_; 114 std::string argument_; 115 116 std::string errorMessage_; 117 CommandState::Value state_; 118 119 bool bEvaluatedParams_; 120 MultiType param_[5]; 80 _ConsoleCommand* execCommand_; 81 _ConsoleCommand* hintCommand_; 82 SubString tokens_; 83 std::string string_; 84 unsigned int execArgumentsOffset_; 85 unsigned int hintArgumentsOffset_; 86 mutable bool bPossibleArgumentsRetrieved_; 87 mutable ArgumentCompletionList possibleArguments_; 121 88 }; 122 89 } -
code/branches/consolecommands3/src/libraries/core/command/CommandExecutor.cc
r7221 r7228 29 29 #include "CommandExecutor.h" 30 30 31 #include "util/Debug.h"32 #include "util/StringUtils.h"33 #include "core/Identifier.h"34 #include "core/Language.h"35 31 #include "ConsoleCommand.h" 36 32 #include "TclBind.h" 33 #include "Shell.h" 37 34 38 35 namespace orxonox 39 36 { 40 CommandExecutor& CommandExecutor::getInstance() 37 static const std::string __CC_CommandExecutor_name = "CommandExecutor"; 38 static const std::string __CC_autocomplete_name = "autocomplete"; 39 40 _SetConsoleCommand(__CC_CommandExecutor_name, __CC_autocomplete_name, &CommandExecutor::_autocomplete) 41 .hide() 42 .argumentCompleter(0, autocompletion::groupsandcommands()) 43 .argumentCompleter(1, autocompletion::subcommands()); 44 45 /* static */ CommandExecutor& CommandExecutor::getInstance() 41 46 { 42 47 static CommandExecutor instance; … … 44 49 } 45 50 46 CommandEvaluation& CommandExecutor::getEvaluation()51 /* static */ int CommandExecutor::execute(const std::string& command, bool useTcl) 47 52 { 48 return CommandExecutor::getInstance().evaluation_; 53 int error; 54 CommandExecutor::queryMT(command, &error, useTcl); 55 return error; 49 56 } 50 57 51 bool CommandExecutor::execute(const std::string& command, bool useTcl)58 /* static */ MultiType CommandExecutor::queryMT(const std::string& command, int* error, bool useTcl) 52 59 { 53 60 if (useTcl) 54 { 55 bool success; 56 TclBind::eval(command, &success); 57 return success; 58 } 61 return TclBind::eval(command, error); 59 62 else 60 { 61 CommandExecutor::parseIfNeeded(command); 62 return CommandExecutor::getEvaluation().execute(); 63 } 63 return CommandExecutor::evaluate(command).query(error); 64 64 } 65 65 66 MultiType CommandExecutor::queryMT(const std::string& command, bool* success, bool useTcl)66 /* static */ std::string CommandExecutor::query(const std::string& command, int* error, bool useTcl) 67 67 { 68 if (useTcl) 69 { 70 return TclBind::eval(command, success); 71 } 72 else 73 { 74 CommandExecutor::parseIfNeeded(command); 75 return CommandExecutor::getEvaluation().query(success); 76 } 68 return CommandExecutor::queryMT(command, error, useTcl).getString(); 77 69 } 78 70 79 std::string CommandExecutor::query(const std::string& command, bool* success, bool useTcl)71 /* static */ CommandEvaluation CommandExecutor::evaluate(const std::string& command) 80 72 { 81 if (useTcl) 73 CommandEvaluation evaluation; 74 evaluation.initialize(command); 75 76 evaluation.hintCommand_ = _ConsoleCommand::getCommand(__CC_CommandExecutor_name, __CC_autocomplete_name); 77 78 if (evaluation.getNumberOfArguments() >= 1) 82 79 { 83 return TclBind::eval(command, success); 84 } 85 else 86 { 87 CommandExecutor::parseIfNeeded(command); 88 return CommandExecutor::getEvaluation().query(success).getString(); 89 } 90 } 91 92 std::string CommandExecutor::complete(const std::string& command) 93 { 94 CommandExecutor::parseIfNeeded(command); 95 return CommandExecutor::getEvaluation().complete(); 96 } 97 98 std::string CommandExecutor::hint(const std::string& command) 99 { 100 CommandExecutor::parseIfNeeded(command); 101 return CommandExecutor::getEvaluation().hint(); 102 } 103 104 CommandEvaluation CommandExecutor::evaluate(const std::string& command) 105 { 106 CommandExecutor::parse(command); 107 CommandExecutor::getEvaluation().evaluateParams(); 108 return CommandExecutor::getEvaluation(); 109 } 110 111 void CommandExecutor::parseIfNeeded(const std::string& command) 112 { 113 if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized) 114 { 115 CommandExecutor::parse(command); 116 } 117 else if (CommandExecutor::getEvaluation().originalCommand_ != command) 118 { 119 if (CommandExecutor::getEvaluation().command_ == command) 80 evaluation.execCommand_ = _ConsoleCommand::getCommandLC(evaluation.getToken(0)); 81 if (evaluation.execCommand_) 82 evaluation.execArgumentsOffset_ = 1; 83 else if (evaluation.getNumberOfArguments() >= 2) 120 84 { 121 CommandExecutor::parse(command); 122 CommandExecutor::getEvaluation().bNewCommand_ = false; 123 } 124 else 125 { 126 CommandExecutor::parse(command); 85 evaluation.execCommand_ = _ConsoleCommand::getCommandLC(evaluation.getToken(0), evaluation.getToken(1)); 86 if (evaluation.execCommand_) 87 evaluation.execArgumentsOffset_ = 2; 127 88 } 128 89 } 129 }130 90 131 void CommandExecutor::parse(const std::string& command, bool bInitialize) 132 { 133 if (bInitialize) 134 CommandExecutor::getEvaluation().initialize(command); 135 136 CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0'); 137 CommandExecutor::getEvaluation().command_ = command; 138 139 switch (CommandExecutor::getEvaluation().state_) 91 if (evaluation.execCommand_ && evaluation.getNumberOfArguments() > evaluation.execArgumentsOffset_) 140 92 { 141 case CommandState::Uninitialized: 142 { 143 // Impossible 144 break; 145 } 146 case CommandState::Empty: 147 { 148 if (CommandExecutor::argumentsGiven() == 0) 149 { 150 CommandExecutor::createListOfPossibleFunctions(""); 151 CommandExecutor::createListOfPossibleIdentifiers(""); 152 break; 153 } 154 else 155 { 156 CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier; 157 // Move on to next case 158 } 159 } 160 case CommandState::ShortcutOrIdentifier: 161 { 162 if (CommandExecutor::argumentsGiven() > 1) 163 { 164 // There's a finished first argument - check if it's a shortcut or a classname 165 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0)); 166 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0)); 167 168 if (CommandExecutor::getEvaluation().function_) 169 { 170 // It's a shortcut 171 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 172 CommandExecutor::getEvaluation().functionclass_ = 0; 173 // Move on to next case 174 } 175 else if (CommandExecutor::getEvaluation().functionclass_) 176 { 177 // It's a functionname 178 CommandExecutor::getEvaluation().state_ = CommandState::Function; 179 CommandExecutor::getEvaluation().function_ = 0; 180 // Move on to next case 181 } 182 else 183 { 184 // The first argument is bad 185 CommandExecutor::getEvaluation().state_ = CommandState::Error; 186 AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname"); 187 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + ' ' + GetLocalisation("commandexecutorunknownfirstargument") + '.'; 188 return; 189 } 190 } 191 else 192 { 193 // There's no finished first argument - search possible shortcuts or classnames 194 CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0)); 195 CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0)); 196 197 unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size(); 198 unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size(); 199 200 if (num_functions == 1 && num_identifiers == 0) 201 { 202 // It's a shortcut 203 const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first; 204 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname); 205 if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0))) 206 { 207 // Unfinished shortcut 208 CommandExecutor::getEvaluation().bCommandChanged_ = true; 209 } 210 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 211 CommandExecutor::getEvaluation().functionclass_ = 0; 212 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName(); 213 if (CommandExecutor::getEvaluation().function_->getExecutor()->getParamCount() > 0) 214 { 215 CommandExecutor::getEvaluation().command_ += ' '; 216 CommandExecutor::getEvaluation().bCommandChanged_ = true; 217 } 218 // Move on to next case 219 } 220 else if (num_identifiers == 1 && num_functions == 0) 221 { 222 // It's a classname 223 const std::string& classname = *CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()->first; 224 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname); 225 if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0))) 226 { 227 // Unfinished classname 228 CommandExecutor::getEvaluation().bCommandChanged_ = true; 229 } 230 CommandExecutor::getEvaluation().state_ = CommandState::Function; 231 CommandExecutor::getEvaluation().function_ = 0; 232 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' '; 233 // Move on to next case 234 } 235 else if (num_identifiers == 0 && num_functions == 0) 236 { 237 // No possibilities 238 CommandExecutor::getEvaluation().state_ = CommandState::Error; 239 AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with"); 240 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + ' ' + CommandExecutor::getArgument(0) + '.'; 241 return; 242 } 243 else 244 { 245 // There are several possiblilities 246 std::list<std::pair<const std::string*, const std::string*> > temp; 247 temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end()); 248 temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end()); 249 CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp); 250 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0)); 251 CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0)); 252 CommandExecutor::getEvaluation().bCommandChanged_ = true; 253 return; 254 } 255 } 256 } 257 case CommandState::Function: 258 { 259 if (CommandExecutor::getEvaluation().functionclass_) 260 { 261 // There is a classname - search for the commandname 262 if (CommandExecutor::argumentsGiven() > 2) 263 { 264 // There is a finished second argument - check if it's a commandname 265 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_); 266 267 if (CommandExecutor::getEvaluation().function_) 268 { 269 // It's a function 270 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 271 // Move on to next case 272 } 273 else 274 { 275 // The second argument is bad 276 CommandExecutor::getEvaluation().state_ = CommandState::Error; 277 AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of"); 278 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + "."; 279 return; 280 } 281 } 282 else 283 { 284 // There is no finished second argument - search for possibilities 285 CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_); 286 unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size(); 287 288 if (num_functions == 1) 289 { 290 // It's a function 291 const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first; 292 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_); 293 if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1))) 294 { 295 // Unfinished function 296 CommandExecutor::getEvaluation().bCommandChanged_ = true; 297 } 298 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 299 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getEvaluation().function_->getName(); 300 if (CommandExecutor::getEvaluation().function_->getExecutor()->getParamCount() > 0) 301 { 302 CommandExecutor::getEvaluation().command_ += ' '; 303 CommandExecutor::getEvaluation().bCommandChanged_ = true; 304 } 305 // Move on to next case 306 } 307 else if (num_functions == 0) 308 { 309 // No possibilities 310 CommandExecutor::getEvaluation().state_ = CommandState::Error; 311 AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with"); 312 CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + GetLocalisation("commandexecutorunknownsecondargumentstart") + ' ' + CommandExecutor::getArgument(1) + '.'; 313 return; 314 } 315 else 316 { 317 // There are several possibilities 318 CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_); 319 CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_); 320 CommandExecutor::getEvaluation().bCommandChanged_ = true; 321 return; 322 } 323 } 324 } 325 else 326 { 327 // There is no classname - move on to CommandState::ParamPreparation 328 } 329 } 330 case CommandState::ParamPreparation: 331 { 332 if (CommandExecutor::getEvaluation().function_->getExecutor()->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_)) 333 { 334 CommandExecutor::getEvaluation().state_ = CommandState::Finished; 335 return; 336 } 337 else 338 { 339 unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2; 340 if (CommandExecutor::getEvaluation().functionclass_) 341 argumentNumber -= 1; 342 343 CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber); 344 CommandExecutor::getEvaluation().state_ = CommandState::Params; 345 346 if (CommandExecutor::getEvaluation().bCommandChanged_) 347 { 348 // Don't do more than one change 349 return; 350 } 351 } 352 } 353 case CommandState::Params: 354 { 355 if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1) 356 { 357 // There is exactly one possible argument 358 CommandExecutor::getEvaluation().argument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString(); 359 CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString(); 360 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 361 return; 362 } 363 else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0) 364 { 365 // The user tries something new - we let him do 366 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 367 CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument(); 368 return; 369 } 370 else 371 { 372 // There are several possibilities 373 unsigned int argumentNumber = CommandExecutor::argumentsGiven(); 374 if (argumentNumber > 0) 375 --argumentNumber; 376 if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0) 377 --argumentNumber; 378 379 CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_); 380 CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber); 381 CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation; 382 return; 383 } 384 } 385 case CommandState::Finished: 386 { 387 // Nothing more to do 388 break; 389 } 390 case CommandState::Error: 391 { 392 // Bad, very bad 393 break; 394 } 395 } 396 } 397 398 unsigned int CommandExecutor::argumentsFinished() 399 { 400 unsigned int argumentsGiven = CommandExecutor::argumentsGiven(); 401 if (argumentsGiven > 0) 402 return argumentsGiven - 1; 403 else 404 return 0; 405 } 406 407 unsigned int CommandExecutor::argumentsGiven() 408 { 409 if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ') 410 return CommandExecutor::getEvaluation().commandTokens_.size() + 1; 411 else 412 return CommandExecutor::getEvaluation().commandTokens_.size(); 413 } 414 415 bool CommandExecutor::enoughArgumentsGiven(_ConsoleCommand* command) 416 { 417 if (CommandExecutor::getEvaluation().functionclass_) 418 return (CommandExecutor::argumentsGiven() > (2 + command->getExecutor()->getParamCount())); 419 else 420 return (CommandExecutor::argumentsGiven() > (1 + command->getExecutor()->getParamCount())); 421 } 422 423 const std::string& CommandExecutor::getArgument(unsigned int index) 424 { 425 if (index < (CommandExecutor::getEvaluation().commandTokens_.size())) 426 return CommandExecutor::getEvaluation().commandTokens_[index]; 427 else 428 return BLANKSTRING; 429 } 430 431 const std::string& CommandExecutor::getLastArgument() 432 { 433 return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1); 434 } 435 436 void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment) 437 { 438 /* 439 CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear(); 440 const std::string& lowercase = getLowercase(fragment); 441 for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMapBegin(); it != Identifier::getLowercaseStringIdentifierMapEnd(); ++it) 442 if (it->second->hasConsoleCommands()) 443 if (it->first.find(lowercase) == 0 || fragment.empty()) 444 CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName())); 445 */ 446 } 447 448 void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier) 449 { 450 /* 451 CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear(); 452 const std::string& lowercase = getLowercase(fragment); 453 if (!identifier) 454 { 455 for (std::map<std::string, _ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it) 456 if (it->first.find(lowercase) == 0 || fragment.empty()) 457 CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName())); 458 } 459 else 460 { 461 for (std::map<std::string, _ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it) 462 if (it->first.find(lowercase) == 0 || fragment.empty()) 463 CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName())); 464 } 465 */ 466 } 467 468 void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, _ConsoleCommand* command, unsigned int param) 469 { 470 /* 471 CommandExecutor::createArgumentCompletionList(command, param); 472 473 CommandExecutor::getEvaluation().listOfPossibleArguments_.clear(); 474 const std::string& lowercase = getLowercase(fragment); 475 for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it) 476 { 477 if (it->lowercaseComparison()) 478 { 479 if (it->getComparable().find(lowercase) == 0 || fragment.empty()) 480 CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it); 481 } 482 else 483 { 484 if (it->getComparable().find(fragment) == 0 || fragment.empty()) 485 CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it); 486 } 487 } 488 */ 489 } 490 491 Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name) 492 { 493 /* 494 const std::string& lowercase = getLowercase(name); 495 std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMap().find(lowercase); 496 if ((it != Identifier::getLowercaseStringIdentifierMapEnd()) && it->second->hasConsoleCommands()) 497 return it->second; 498 */ 499 return 0; 500 } 501 502 _ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier) 503 { 504 /* 505 const std::string& lowercase = getLowercase(name); 506 if (!identifier) 507 { 508 std::map<std::string, _ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase); 509 if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd()) 510 return it->second; 511 } 512 else 513 { 514 std::map<std::string, _ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase); 515 if (it != identifier->getLowercaseConsoleCommandMapEnd()) 516 return it->second; 517 } 518 */ 519 return 0; 520 } 521 522 const std::string& CommandExecutor::getPossibleArgument(const std::string& name, _ConsoleCommand* command, unsigned int param) 523 { 524 /* 525 CommandExecutor::createArgumentCompletionList(command, param); 526 527 const std::string& lowercase = getLowercase(name); 528 for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it) 529 { 530 if (it->lowercaseComparison()) 531 { 532 if (it->getComparable() == lowercase) 533 return it->getString(); 534 } 535 else 536 { 537 if (it->getComparable() == name) 538 return it->getString(); 539 } 540 } 541 */ 542 return BLANKSTRING; 543 } 544 545 void CommandExecutor::createArgumentCompletionList(_ConsoleCommand* command, unsigned int param) 546 { 547 /* 548 std::string params[5]; 549 550 unsigned int index = 0; 551 unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0); 552 553 for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i) 554 { 555 params[index] = CommandExecutor::getArgument(i); 556 ++index; 557 if (index >= 5) 558 break; 93 evaluation.hintCommand_ = evaluation.execCommand_; 94 evaluation.hintArgumentsOffset_ = evaluation.execArgumentsOffset_; 559 95 } 560 96 561 command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]); 562 */ 563 } 564 565 std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list) 566 { 567 if (list.size() == 0) 568 { 569 return ""; 570 } 571 else if (list.size() == 1) 572 { 573 return ((*list.begin()->first) + ' '); 574 } 575 else 576 { 577 std::string output; 578 for (unsigned int i = 0; true; i++) 579 { 580 char temp = 0; 581 for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it) 582 { 583 if (it->first->size() > i) 584 { 585 if (it == list.begin()) 586 { 587 temp = (*it->first)[i]; 588 } 589 else 590 { 591 if (temp != (*it->first)[i]) 592 return output; 593 } 594 } 595 else 596 { 597 return output; 598 } 599 } 600 output += temp; 601 } 602 return output; 603 } 604 } 605 606 std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list) 607 { 608 if (list.size() == 0) 609 { 610 return ""; 611 } 612 else if (list.size() == 1) 613 { 614 return (list.begin()->getComparable() + ' '); 615 } 616 else 617 { 618 std::string output; 619 for (unsigned int i = 0; true; i++) 620 { 621 char tempComparable = 0; 622 char temp = 0; 623 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 624 { 625 const std::string& argumentComparable = it->getComparable(); 626 const std::string& argument = it->getString(); 627 if (argument.size() > i) 628 { 629 if (it == list.begin()) 630 { 631 tempComparable = argumentComparable[i]; 632 temp = argument[i]; 633 } 634 else 635 { 636 if (tempComparable != argumentComparable[i]) 637 return output; 638 else if (temp != argument[i]) 639 temp = tempComparable; 640 } 641 } 642 else 643 { 644 return output; 645 } 646 } 647 output += temp; 648 } 649 return output; 650 } 97 return evaluation; 651 98 } 652 99 } -
code/branches/consolecommands3/src/libraries/core/command/CommandExecutor.h
r7221 r7228 32 32 #include "core/CorePrereqs.h" 33 33 34 #include <map>35 #include <set>36 34 #include <string> 37 35 … … 46 44 // tolua_end 47 45 public: 48 static boolexecute(const std::string& command, bool useTcl = true); // tolua_export46 static int execute(const std::string& command, bool useTcl = true); // tolua_export 49 47 50 static MultiType queryMT(const std::string& command, bool* success = 0, bool useTcl = true); 51 static std::string query(const std::string& command, bool* success = 0, bool useTcl = true); // tolua_export 52 53 static std::string complete(const std::string& command); 54 static std::string hint(const std::string& command); 48 static MultiType queryMT(const std::string& command, int* error = 0, bool useTcl = true); 49 static std::string query(const std::string& command, int* error = 0, bool useTcl = true); // tolua_export 55 50 56 51 static CommandEvaluation evaluate(const std::string& command); 52 53 static const int Success = 0; 54 static const int Error = 1; 55 static const int Incomplete = 2; 56 static const int Deactivated = 3; 57 static const int Denied = 4; 58 59 static void _autocomplete(const std::string& group, const std::string& name) {} 57 60 58 61 private: … … 62 65 63 66 static CommandExecutor& getInstance(); 64 static CommandEvaluation& getEvaluation();65 66 static void parseIfNeeded(const std::string& command);67 static void parse(const std::string& command, bool bInitialize = true);68 69 static unsigned int argumentsFinished();70 static unsigned int argumentsGiven();71 static bool enoughArgumentsGiven(_ConsoleCommand* command);72 static const std::string& getArgument(unsigned int index);73 static const std::string& getLastArgument();74 75 static void createListOfPossibleIdentifiers(const std::string& fragment);76 static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier = 0);77 static void createListOfPossibleArguments(const std::string& fragment, _ConsoleCommand* command, unsigned int param);78 79 static Identifier* getPossibleIdentifier(const std::string& name);80 static _ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0);81 static const std::string& getPossibleArgument(const std::string& name, _ConsoleCommand* command, unsigned int param);82 83 static void createArgumentCompletionList(_ConsoleCommand* command, unsigned int param);84 static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);85 static std::string getCommonBegin(const ArgumentCompletionList& list);86 87 CommandEvaluation evaluation_;88 67 }; // tolua_export 89 68 } // tolua_export -
code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.cc
r7222 r7228 30 30 31 31 #include "util/Convert.h" 32 #include "util/StringUtils.h" 32 33 #include "core/Language.h" 33 34 #include "core/GameMode.h" … … 398 399 } 399 400 400 /* static */ const_ConsoleCommand* _ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)401 /* static */ _ConsoleCommand* _ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError) 401 402 { 402 403 std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommandMap().find(group); … … 419 420 } 420 421 422 /* static */ _ConsoleCommand* _ConsoleCommand::getCommandLC(const std::string& group, const std::string& name, bool bPrintError) 423 { 424 std::string groupLC = getLowercase(group); 425 std::string nameLC = getLowercase(name); 426 427 std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommandMapLC().find(groupLC); 428 if (it_group != _ConsoleCommand::getCommandMapLC().end()) 429 { 430 std::map<std::string, _ConsoleCommand*>::const_iterator it_name = it_group->second.find(nameLC); 431 if (it_name != it_group->second.end()) 432 { 433 return it_name->second; 434 } 435 } 436 if (bPrintError) 437 { 438 if (group == "") 439 COUT(1) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl; 440 else 441 COUT(1) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl; 442 } 443 return 0; 444 } 445 421 446 /* static */ std::map<std::string, std::map<std::string, _ConsoleCommand*> >& _ConsoleCommand::getCommandMap() 422 447 { 423 448 static std::map<std::string, std::map<std::string, _ConsoleCommand*> > commandMap; 424 449 return commandMap; 450 } 451 452 /* static */ std::map<std::string, std::map<std::string, _ConsoleCommand*> >& _ConsoleCommand::getCommandMapLC() 453 { 454 static std::map<std::string, std::map<std::string, _ConsoleCommand*> > commandMapLC; 455 return commandMapLC; 425 456 } 426 457 … … 440 471 { 441 472 _ConsoleCommand::getCommandMap()[group][name] = command; 473 _ConsoleCommand::getCommandMapLC()[getLowercase(group)][getLowercase(name)] = command; 442 474 } 443 475 } … … 460 492 ++it_group; 461 493 } 494 495 for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::iterator it_group = _ConsoleCommand::getCommandMapLC().begin(); it_group != _ConsoleCommand::getCommandMapLC().end(); ) 496 { 497 for (std::map<std::string, _ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); ) 498 { 499 if (it_name->second == command) 500 it_group->second.erase(it_name++); 501 else 502 ++it_name; 503 } 504 505 if (it_group->second.empty()) 506 _ConsoleCommand::getCommandMapLC().erase(it_group++); 507 else 508 ++it_group; 509 } 462 510 } 463 511 -
code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h
r7222 r7228 329 329 static inline const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommands() 330 330 { return _ConsoleCommand::getCommandMap(); } 331 332 static inline const _ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false) 331 static inline const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandsLC() 332 { return _ConsoleCommand::getCommandMapLC(); } 333 334 static inline _ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false) 333 335 { return _ConsoleCommand::getCommand("", name, bPrintError); } 334 static const _ConsoleCommand* getCommand(const std::string& group, const std::string& name, bool bPrintError = false); 336 static inline _ConsoleCommand* getCommandLC(const std::string& name, bool bPrintError = false) 337 { return _ConsoleCommand::getCommandLC("", name, bPrintError); } 338 339 static _ConsoleCommand* getCommand(const std::string& group, const std::string& name, bool bPrintError = false); 340 static _ConsoleCommand* getCommandLC(const std::string& group, const std::string& name, bool bPrintError = false); 335 341 336 342 static void destroyAll(); … … 338 344 private: 339 345 static std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandMap(); 346 static std::map<std::string, std::map<std::string, _ConsoleCommand*> >& getCommandMapLC(); 347 340 348 static void registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command); 341 349 static void unregisterCommand(_ConsoleCommand* command); -
code/branches/consolecommands3/src/libraries/core/command/Executor.cc
r7212 r7228 36 36 #include "util/StringUtils.h" 37 37 #include "util/SubString.h" 38 #include "CommandExecutor.h" 38 39 39 40 namespace orxonox … … 49 50 } 50 51 51 MultiType Executor::parse(const std::string& params, bool* success, const std::string& delimiter) const52 { 53 if ( success)54 * success = true;52 MultiType Executor::parse(const std::string& params, int* error, const std::string& delimiter, bool bPrintError) const 53 { 54 if (error) 55 *error = CommandExecutor::Success; 55 56 56 57 unsigned int paramCount = this->functor_->getParamCount(); … … 76 77 else 77 78 { 78 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl; 79 if (success) 80 *success = false; 79 if (bPrintError) 80 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl; 81 if (error) 82 *error = CommandExecutor::Incomplete; 81 83 return MT_Type::Null; 82 84 } … … 90 92 if (this->defaultValue_[i].null()) 91 93 { 92 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl; 93 if (success) 94 *success = false; 94 if (bPrintError) 95 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << params << ")." << std::endl; 96 if (error) 97 *error = CommandExecutor::Incomplete; 95 98 return MT_Type::Null; 96 99 } -
code/branches/consolecommands3/src/libraries/core/command/Executor.h
r7214 r7228 59 59 { return (*this->functor_)(param1, param2, param3, param4, param5); } 60 60 61 MultiType parse(const std::string& params, bool* success = 0, const std::string& delimiter = " ") const;61 MultiType parse(const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const; 62 62 63 63 bool evaluate(const std::string& params, MultiType param[5], const std::string& delimiter = " ") const; … … 164 164 using Executor::parse; 165 165 166 MultiType parse(T* object, const std::string& params, bool* success = 0, const std::string& delimiter = " ") const166 MultiType parse(T* object, const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const 167 167 { 168 168 T* oldobject = this->functorMember_->getObject(); 169 169 170 170 this->functorMember_->setObject(object); 171 const MultiType& result = this->Executor::parse(params, success, delimiter);171 const MultiType& result = this->Executor::parse(params, error, delimiter, bPrintError); 172 172 this->functorMember_->setObject(oldobject); 173 173 … … 175 175 } 176 176 177 MultiType parse(const T* object, const std::string& params, bool* success = 0, const std::string& delimiter = " ") const177 MultiType parse(const T* object, const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const 178 178 { 179 179 T* oldobject = this->functorMember_->getObject(); 180 180 181 181 this->functorMember_->setObject(object); 182 const MultiType& result = this->Executor::parse(params, success, delimiter);182 const MultiType& result = this->Executor::parse(params, error, delimiter, bPrintError); 183 183 this->functorMember_->setObjects(oldobject); 184 184 -
code/branches/consolecommands3/src/libraries/core/command/Shell.cc
r7219 r7228 315 315 this->updateListeners<&ShellListener::executed>(); 316 316 317 bool success; 318 const std::string& result = CommandExecutor::query(this->inputBuffer_->get(), &success); 319 if (!success) 320 { 321 this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\"." << std::endl; 317 int error; 318 const std::string& result = CommandExecutor::query(this->inputBuffer_->get(), &error); 319 if (error) 320 { 321 switch (error) 322 { 323 case CommandExecutor::Error: this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", command doesn't exist. (S)" << std::endl; break; 324 case CommandExecutor::Incomplete: this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", not enough arguments given. (S)" << std::endl; break; 325 case CommandExecutor::Deactivated: this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", command is not active. (S)" << std::endl; break; 326 case CommandExecutor::Denied: this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", access denied. (S)" << std::endl; break; 327 } 322 328 this->outputChanged(Error); 323 329 } … … 333 339 void Shell::hintAndComplete() 334 340 { 335 this->inputBuffer_->set(CommandExecutor:: complete(this->inputBuffer_->get()));336 this->outputBuffer_ << CommandExecutor:: hint(this->inputBuffer_->get()) << std::endl;341 this->inputBuffer_->set(CommandExecutor::evaluate(this->inputBuffer_->get()).complete()); 342 this->outputBuffer_ << CommandExecutor::evaluate(this->inputBuffer_->get()).hint() << std::endl; 337 343 this->outputChanged(Hint); 338 344 -
code/branches/consolecommands3/src/libraries/core/command/TclBind.cc
r7219 r7228 134 134 const std::string& command = stripEnclosingBraces(args.get()); 135 135 136 bool success; 137 const std::string& result = CommandExecutor::query(command, &success, false); 138 if (!success) 139 { 140 COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl; 136 int error; 137 const std::string& result = CommandExecutor::query(command, &error, false); 138 switch (error) 139 { 140 case CommandExecutor::Error: COUT(1) << "Error: Can't execute command \"" << command << "\", command doesn't exist. (B)" << std::endl; break; 141 case CommandExecutor::Incomplete: COUT(1) << "Error: Can't execute command \"" << command << "\", not enough arguments given. (B)" << std::endl; break; 142 case CommandExecutor::Deactivated: COUT(1) << "Error: Can't execute command \"" << command << "\", command is not active. (B)" << std::endl; break; 143 case CommandExecutor::Denied: COUT(1) << "Error: Can't execute command \"" << command << "\", access denied. (B)" << std::endl; break; 141 144 } 142 145 … … 149 152 const std::string& command = stripEnclosingBraces(args.get()); 150 153 151 if ( !CommandExecutor::execute(command, false))154 if (CommandExecutor::execute(command, false)) 152 155 { 153 156 COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl; … … 180 183 } 181 184 182 std::string TclBind::eval(const std::string& tclcode, bool* success)183 { 184 if ( success)185 * success = true;185 std::string TclBind::eval(const std::string& tclcode, int* error) 186 { 187 if (error) 188 *error = CommandExecutor::Success; 186 189 187 190 try … … 192 195 { COUT(1) << "Tcl error: " << e.what() << std::endl; } 193 196 194 if ( success)195 * success = false;197 if (error) 198 *error = CommandExecutor::Error; 196 199 return ""; 197 200 } -
code/branches/consolecommands3/src/libraries/core/command/TclBind.h
r7203 r7228 59 59 static void tcl_execute(Tcl::object const &args); 60 60 61 static std::string eval(const std::string& tclcode, bool* success= 0);61 static std::string eval(const std::string& tclcode, int* error = 0); 62 62 63 63 private: -
code/branches/consolecommands3/src/libraries/core/command/TclThreadManager.cc
r7219 r7228 439 439 // It's a query to the CommandExecutor 440 440 TclThreadManager::debug("TclThread_query -> CE: " + command); 441 bool success; 442 output = CommandExecutor::query(command, &success, false); 443 if (!success) 444 TclThreadManager::error("Error: Can't execute command \"" + command + "\"!"); 441 int error; 442 output = CommandExecutor::query(command, &error, false); 443 switch (error) 444 { 445 case CommandExecutor::Error: TclThreadManager::error("Error: Can't execute command \"" + command + "\", command doesn't exist. (T)"); break; 446 case CommandExecutor::Incomplete: TclThreadManager::error("Error: Can't execute command \"" + command + "\", not enough arguments given. (T)"); break; 447 case CommandExecutor::Deactivated: TclThreadManager::error("Error: Can't execute command \"" + command + "\", command is not active. (T)"); break; 448 case CommandExecutor::Denied: TclThreadManager::error("Error: Can't execute command \"" + command + "\", access denied. (T)"); break; 449 } 445 450 } 446 451 else
Note: See TracChangeset
for help on using the changeset viewer.