Changeset 7374 in orxonox.OLD for trunk/src/lib/shell/shell_command.cc
- Timestamp:
- Apr 26, 2006, 3:28:55 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/shell/shell_command.cc
r7340 r7374 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL 17 17 18 18 #include "shell_command.h" … … 28 28 #include <string.h> 29 29 30 using namespace std; 31 32 /** 33 * constructs and registers a new Command 34 * @param commandName the name of the Command 35 * @param className the name of the class to apply this command to 36 * @param paramCount the count of parameters this command takes 37 */ 38 ShellCommand::ShellCommand(const std::string& commandName, const std::string& className, const Executor& executor) 30 namespace OrxShell 39 31 { 40 this->setClassID(CL_SHELL_COMMAND, "ShellCommand"); 41 PRINTF(5)("create shellcommand %s %s\n", commandName, className); 42 this->setName(commandName); 43 this->executor = executor.clone(); 44 this->executor->setName(commandName); 45 46 // this->classID = classID; 47 this->shellClass = ShellCommandClass::getCommandClass(className); //ClassList::IDToString(classID); 48 if (this->shellClass != NULL) 49 this->shellClass->commandList.push_back(this); 50 } 51 52 /** 53 * deconstructs a ShellCommand 54 */ 55 ShellCommand::~ShellCommand() 56 { 57 if (this->alias != NULL && ShellCommandClass::aliasList != NULL) 58 { 59 ShellCommandClass::aliasList->remove(this->alias); 60 delete this->alias; 61 } 62 delete this->executor; 63 } 64 65 /** 66 * registers a new ShellCommand 67 */ 68 ShellCommand* ShellCommand::registerCommand(const std::string& commandName, const std::string& className, const Executor& executor) 69 { 70 if (ShellCommand::isRegistered(commandName, className)) 71 return NULL; 72 else 73 return new ShellCommand(commandName, className, executor); 74 75 } 76 77 /** 78 * unregister an existing commandName 79 * @param className the name of the Class the command belongs to. 80 * @param commandName the name of the command itself 81 */ 82 void ShellCommand::unregisterCommand(const std::string& commandName, const std::string& className) 83 { 84 /// FIXME 85 /* if (ShellCommandClass::commandClassList == NULL) 32 33 /** 34 * constructs and registers a new Command 35 * @param commandName the name of the Command 36 * @param className the name of the class to apply this command to 37 * @param paramCount the count of parameters this command takes 38 */ 39 ShellCommand::ShellCommand(const std::string& commandName, const std::string& className, const Executor& executor) 40 { 41 this->setClassID(CL_SHELL_COMMAND, "ShellCommand"); 42 PRINTF(5)("create shellcommand %s %s\n", commandName, className); 43 this->setName(commandName); 44 this->executor = executor.clone(); 45 this->executor->setName(commandName); 46 47 // this->classID = classID; 48 this->shellClass = ShellCommandClass::getCommandClass(className); //ClassList::IDToString(classID); 49 if (this->shellClass != NULL) 50 this->shellClass->commandList.push_back(this); 51 } 52 53 /** 54 * deconstructs a ShellCommand 55 */ 56 ShellCommand::~ShellCommand() 57 { 58 if (this->alias != NULL && ShellCommandClass::aliasList != NULL) 59 { 60 ShellCommandClass::aliasList->remove(this->alias); 61 delete this->alias; 62 } 63 delete this->executor; 64 } 65 66 /** 67 * registers a new ShellCommand 68 */ 69 ShellCommand* ShellCommand::registerCommand(const std::string& commandName, const std::string& className, const Executor& executor) 70 { 71 if (ShellCommand::isRegistered(commandName, className)) 72 return NULL; 73 else 74 return new ShellCommand(commandName, className, executor); 75 76 } 77 78 /** 79 * unregister an existing commandName 80 * @param className the name of the Class the command belongs to. 81 * @param commandName the name of the command itself 82 */ 83 void ShellCommand::unregisterCommand(const std::string& commandName, const std::string& className) 84 { 85 /// FIXME 86 /* if (ShellCommandClass::commandClassList == NULL) 87 ShellCommandClass::initCommandClassList(); 88 89 const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className); 90 91 if (checkClass != NULL) 92 { 93 std::list<ShellCommand*>::iterator elem; 94 for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++) 95 { 96 if (!strcmp(commandName, (*elem)->getName())) 97 { 98 delete (*elem); 99 checkClass->commandList.remove(*elem); 100 break; 101 } 102 } 103 104 if (checkClass->commandList->size() == 0) 105 { 106 ShellCommandClass::commandClassList->remove(checkClass); 107 delete checkClass; 108 } 109 }*/ 110 } 111 112 /** 113 * checks if a command has already been registered. 114 * @param commandName the name of the Command 115 * @param className the name of the Class the command should apply to. 116 * @returns true, if the command is registered/false otherwise 117 * 118 * This is used internally, to see, if we have multiple command subscriptions. 119 * This is checked in the registerCommand-function. 120 */ 121 bool ShellCommand::isRegistered(const std::string& commandName, const std::string& className) 122 { 123 if (ShellCommandClass::commandClassList == NULL) 124 { 86 125 ShellCommandClass::initCommandClassList(); 87 88 const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className); 89 90 if (checkClass != NULL) 91 { 92 std::list<ShellCommand*>::iterator elem; 126 return false; 127 } 128 129 const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className); 130 if (checkClass != NULL) 131 { 132 std::list<ShellCommand*>::const_iterator elem; 93 133 for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++) 94 134 { 95 if (!strcmp(commandName, (*elem)->getName())) 96 { 97 delete (*elem); 98 checkClass->commandList.remove(*elem); 99 break; 100 } 101 } 102 103 if (checkClass->commandList->size() == 0) 104 { 105 ShellCommandClass::commandClassList->remove(checkClass); 106 delete checkClass; 107 } 108 }*/ 109 } 110 111 /** 112 * checks if a command has already been registered. 113 * @param commandName the name of the Command 114 * @param className the name of the Class the command should apply to. 115 * @returns true, if the command is registered/false otherwise 116 * 117 * This is used internally, to see, if we have multiple command subscriptions. 118 * This is checked in the registerCommand-function. 119 */ 120 bool ShellCommand::isRegistered(const std::string& commandName, const std::string& className) 121 { 122 if (ShellCommandClass::commandClassList == NULL) 123 { 124 ShellCommandClass::initCommandClassList(); 125 return false; 126 } 127 128 const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className); 129 if (checkClass != NULL) 130 { 131 std::list<ShellCommand*>::const_iterator elem; 132 for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++) 133 { 134 if (commandName == (*elem)->getName()) 135 { 136 PRINTF(2)("Command '%s::%s' already registered\n", className.c_str(), commandName.c_str()); 137 return true; 138 } 139 } 140 return false; 141 } 142 else 143 return false; 144 } 145 146 147 /** 148 * executes commands 149 * @param executionString the string containing the following input 150 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]] 151 * @return true on success, false otherwise. 152 */ 153 bool ShellCommand::execute(const std::string& executionString) 154 { 155 if (ShellCommandClass::commandClassList == NULL) 156 return false; 157 158 long classID = CL_NULL; //< the classID retrieved from the Class. 159 ShellCommandClass* commandClass = NULL; //< the command class this command applies to. 160 const std::list<BaseObject*>* objectList = NULL; //< the list of Objects stored in classID 161 BaseObject* objectPointer = NULL; //< a pointer to th Object to Execute the command on 162 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 163 // long completeType = SHELLC_NONE; //< the Type we'd like to complete. 164 SubString inputSplits(executionString, SubString::WhiteSpacesWithComma); 165 166 167 // if we do not have any input return 168 if (inputSplits.empty()) 169 return false; 170 171 // if we only have one input (!MUST BE AN ALIAS) 172 if (inputSplits.size() >= 1) 173 { 174 // CHECK FOR ALIAS 175 if (ShellCommandClass::aliasList != NULL) 176 { 177 list<ShellCommandAlias*>::iterator alias; 178 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++ ) 179 { 180 if (inputSplits.getString(0) == (*alias)->getName() && (*alias)->getCommand() != NULL && 181 (*alias)->getCommand()->shellClass != NULL ) 182 { 183 objectList = ClassList::getList((*alias)->getCommand()->shellClass->getName()); 184 if (objectList != NULL) 185 { 186 (*(*alias)->getCommand()->executor)(objectList->front(), inputSplits.getSubSet(1).join()); /// TODO CHECK IF OK 187 return true; 188 } 189 /// TODO CHECK FOR STATIC functions. 190 } 191 } 192 } 193 194 // looking for a Matching Class 195 if (likely(ShellCommandClass::commandClassList != NULL)) 196 { 197 list<ShellCommandClass*>::iterator commandClassIT; 198 for (commandClassIT = ShellCommandClass::commandClassList->begin(); commandClassIT != ShellCommandClass::commandClassList->end(); commandClassIT++) 199 { 200 if ((*commandClassIT)->getName() && inputSplits[0] == (*commandClassIT)->getName()) 201 { 202 //elemCL->getName(); 203 classID = ClassList::StringToID((*commandClassIT)->getName()); 204 commandClass = (*commandClassIT); 205 objectList = ClassList::getList((ClassID)classID); 206 break; 207 } 208 } 209 } 210 211 // Second Agument. (either Object, or Function) 212 if (commandClass != NULL && inputSplits.size() >= 2) 213 { 214 int fktPos = 1; // The position of the Function (either at pos 1, or 2) 215 // If we have an ObjectList. 216 if (objectList != NULL) 217 { 218 // Checking for a Match in the Objects of classID (else take the first) 219 list<BaseObject*>::const_iterator object; 220 for (object = objectList->begin(); object != objectList->end(); object++) 221 { 222 if ((*object)->getName() != NULL && inputSplits[1] == (*object)->getName()) 223 { 224 objectPointer = (*object); 225 fktPos = 2; 226 break; 227 } 228 } 229 230 // if we did not find an Object with matching name, take the first. 231 if (objectPointer == NULL) 232 objectPointer = objectList->front(); 233 } 234 235 // match a function. 236 if (commandClass != NULL && (fktPos == 1 || (fktPos == 2 && inputSplits.size() >= 3))) 237 { 238 list<ShellCommand*>::iterator cmdIT; 239 for (cmdIT = commandClass->commandList.begin(); cmdIT != commandClass->commandList.end(); cmdIT++) 240 { 241 if (inputSplits[fktPos] == (*cmdIT)->getName()) 242 { 243 if (objectPointer == NULL && (*cmdIT)->executor->getType() & Executor_Objective) 244 return false; 245 else 135 if (commandName == (*elem)->getName()) 136 { 137 PRINTF(2)("Command '%s::%s' already registered\n", className.c_str(), commandName.c_str()); 138 return true; 139 } 140 } 141 return false; 142 } 143 else 144 return false; 145 } 146 147 148 /** 149 * executes commands 150 * @param executionString the string containing the following input 151 * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]] 152 * @return true on success, false otherwise. 153 */ 154 bool ShellCommand::execute(const std::string& executionString) 155 { 156 if (ShellCommandClass::commandClassList == NULL) 157 return false; 158 159 long classID = CL_NULL; //< the classID retrieved from the Class. 160 ShellCommandClass* commandClass = NULL; //< the command class this command applies to. 161 const std::list<BaseObject*>* objectList = NULL; //< the list of Objects stored in classID 162 BaseObject* objectPointer = NULL; //< a pointer to th Object to Execute the command on 163 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 164 // long completeType = SHELLC_NONE; //< the Type we'd like to complete. 165 SubString inputSplits(executionString, SubString::WhiteSpacesWithComma); 166 167 168 // if we do not have any input return 169 if (inputSplits.empty()) 170 return false; 171 172 // if we only have one input (!MUST BE AN ALIAS) 173 if (inputSplits.size() >= 1) 174 { 175 // CHECK FOR ALIAS 176 if (ShellCommandClass::aliasList != NULL) 177 { 178 std::list<ShellCommandAlias*>::iterator alias; 179 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++ ) 180 { 181 if (inputSplits.getString(0) == (*alias)->getName() && (*alias)->getCommand() != NULL && 182 (*alias)->getCommand()->shellClass != NULL ) 183 { 184 objectList = ClassList::getList((*alias)->getCommand()->shellClass->getName()); 185 if (objectList != NULL) 246 186 { 247 (*(* cmdIT)->executor)(objectPointer, inputSplits.getSubSet(fktPos+1).join()); /// TODO CHECK IF OK187 (*(*alias)->getCommand()->executor)(objectList->front(), inputSplits.getSubSet(1).join()); /// TODO CHECK IF OK 248 188 return true; 249 189 } 250 } 251 } 252 } 253 } 254 } 255 return false; 190 /// TODO CHECK FOR STATIC functions. 191 } 192 } 193 } 194 195 // looking for a Matching Class 196 if (likely(ShellCommandClass::commandClassList != NULL)) 197 { 198 std::list<ShellCommandClass*>::iterator commandClassIT; 199 for (commandClassIT = ShellCommandClass::commandClassList->begin(); commandClassIT != ShellCommandClass::commandClassList->end(); commandClassIT++) 200 { 201 if ((*commandClassIT)->getName() && inputSplits[0] == (*commandClassIT)->getName()) 202 { 203 //elemCL->getName(); 204 classID = ClassList::StringToID((*commandClassIT)->getName()); 205 commandClass = (*commandClassIT); 206 objectList = ClassList::getList((ClassID)classID); 207 break; 208 } 209 } 210 } 211 212 // Second Agument. (either Object, or Function) 213 if (commandClass != NULL && inputSplits.size() >= 2) 214 { 215 int fktPos = 1; // The position of the Function (either at pos 1, or 2) 216 // If we have an ObjectList. 217 if (objectList != NULL) 218 { 219 // Checking for a Match in the Objects of classID (else take the first) 220 std::list<BaseObject*>::const_iterator object; 221 for (object = objectList->begin(); object != objectList->end(); object++) 222 { 223 if ((*object)->getName() != NULL && inputSplits[1] == (*object)->getName()) 224 { 225 objectPointer = (*object); 226 fktPos = 2; 227 break; 228 } 229 } 230 231 // if we did not find an Object with matching name, take the first. 232 if (objectPointer == NULL) 233 objectPointer = objectList->front(); 234 } 235 236 // match a function. 237 if (commandClass != NULL && (fktPos == 1 || (fktPos == 2 && inputSplits.size() >= 3))) 238 { 239 std::list<ShellCommand*>::iterator cmdIT; 240 for (cmdIT = commandClass->commandList.begin(); cmdIT != commandClass->commandList.end(); cmdIT++) 241 { 242 if (inputSplits[fktPos] == (*cmdIT)->getName()) 243 { 244 if (objectPointer == NULL && (*cmdIT)->executor->getType() & Executor_Objective) 245 return false; 246 else 247 { 248 (*(*cmdIT)->executor)(objectPointer, inputSplits.getSubSet(fktPos+1).join()); /// TODO CHECK IF OK 249 return true; 250 } 251 } 252 } 253 } 254 } 255 } 256 return false; 257 } 258 259 /** 260 * lets a command be described 261 * @param description the description of the Given command 262 */ 263 ShellCommand* ShellCommand::describe(const std::string& description) 264 { 265 if (this == NULL) 266 return NULL; 267 else 268 { 269 this->description = description; 270 return this; 271 } 272 } 273 274 /** 275 * adds an Alias to this Command 276 * @param alias the name of the Alias to set 277 * @returns itself 278 */ 279 ShellCommand* ShellCommand::setAlias(const std::string& alias) 280 { 281 if (this == NULL) 282 return NULL; 283 284 if (this->alias != NULL) 285 { 286 PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getName(), this->shellClass->getName()); 287 } 288 else 289 { 290 if (ShellCommandClass::aliasList == NULL) 291 ShellCommandClass::aliasList = new std::list<ShellCommandAlias*>; 292 293 ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this); 294 ShellCommandClass::aliasList->push_back(aliasCMD); 295 this->alias = aliasCMD; 296 } 297 return this; 298 } 299 300 /** 301 * @brief set the default values of the executor 302 * @param value0 the first default value 303 * @param value1 the second default value 304 * @param value2 the third default value 305 * @param value3 the fourth default value 306 * @param value4 the fifth default value 307 */ 308 ShellCommand* ShellCommand::defaultValues(const MultiType& value0, const MultiType& value1, 309 const MultiType& value2, const MultiType& value3, 310 const MultiType& value4) 311 { 312 if (this == NULL || this->executor == NULL) 313 return NULL; 314 315 this->executor->defaultValues(value0, value1, value2, value3, value4); 316 317 return this; 318 } 319 320 /** 321 * prints out nice information about the Shells Commands 322 */ 323 void ShellCommand::debug() 324 { 325 if (ShellCommandClass::commandClassList == NULL) 326 { 327 PRINT(0)("No Command registered.\n"); 328 return; 329 } 330 331 std::list<ShellCommandClass*>::iterator classIT; 332 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++) 333 { 334 PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className.c_str(), (*classIT)->commandList.size()); 335 336 std::list<ShellCommand*>::iterator cmdIT; 337 for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++) 338 { 339 PRINT(0)(" command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount()); 340 /// FIXME 341 /* for (unsigned int i = 0; i< elem->paramCount; i++) 342 printf("%s ", ShellCommand::paramToString(elem->parameters[i]));*/ 343 if (!(*cmdIT)->description.empty()) 344 printf("- %s", (*cmdIT)->description.c_str()); 345 printf("\n"); 346 347 } 348 } 349 } 350 351 /** 352 * converts a Parameter to a String 353 * @param parameter the Parameter we have. 354 * @returns the Name of the Parameter at Hand 355 */ 356 const char* ShellCommand::paramToString(long parameter) 357 { 358 return MultiType::MultiTypeToString((MT_Type)parameter); 359 } 360 256 361 } 257 258 /**259 * lets a command be described260 * @param description the description of the Given command261 */262 ShellCommand* ShellCommand::describe(const std::string& description)263 {264 if (this == NULL)265 return NULL;266 else267 {268 this->description = description;269 return this;270 }271 }272 273 /**274 * adds an Alias to this Command275 * @param alias the name of the Alias to set276 * @returns itself277 */278 ShellCommand* ShellCommand::setAlias(const std::string& alias)279 {280 if (this == NULL)281 return NULL;282 283 if (this->alias != NULL)284 {285 PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getName(), this->shellClass->getName());286 }287 else288 {289 if (ShellCommandClass::aliasList == NULL)290 ShellCommandClass::aliasList = new std::list<ShellCommandAlias*>;291 292 ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this);293 ShellCommandClass::aliasList->push_back(aliasCMD);294 this->alias = aliasCMD;295 }296 return this;297 }298 299 /**300 * @brief set the default values of the executor301 * @param value0 the first default value302 * @param value1 the second default value303 * @param value2 the third default value304 * @param value3 the fourth default value305 * @param value4 the fifth default value306 */307 ShellCommand* ShellCommand::defaultValues(const MultiType& value0, const MultiType& value1,308 const MultiType& value2, const MultiType& value3,309 const MultiType& value4)310 {311 if (this == NULL || this->executor == NULL)312 return NULL;313 314 this->executor->defaultValues(value0, value1, value2, value3, value4);315 316 return this;317 }318 319 /**320 * prints out nice information about the Shells Commands321 */322 void ShellCommand::debug()323 {324 if (ShellCommandClass::commandClassList == NULL)325 {326 PRINT(0)("No Command registered.\n");327 return;328 }329 330 list<ShellCommandClass*>::iterator classIT;331 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)332 {333 PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className.c_str(), (*classIT)->commandList.size());334 335 list<ShellCommand*>::iterator cmdIT;336 for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++)337 {338 PRINT(0)(" command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount());339 /// FIXME340 /* for (unsigned int i = 0; i< elem->paramCount; i++)341 printf("%s ", ShellCommand::paramToString(elem->parameters[i]));*/342 if (!(*cmdIT)->description.empty())343 printf("- %s", (*cmdIT)->description.c_str());344 printf("\n");345 346 }347 }348 }349 350 /**351 * converts a Parameter to a String352 * @param parameter the Parameter we have.353 * @returns the Name of the Parameter at Hand354 */355 const char* ShellCommand::paramToString(long parameter)356 {357 return MultiType::MultiTypeToString((MT_Type)parameter);358 }
Note: See TracChangeset
for help on using the changeset viewer.