Changeset 7374 in orxonox.OLD for trunk/src/lib/shell
- Timestamp:
- Apr 26, 2006, 3:28:55 AM (19 years ago)
- Location:
- trunk/src/lib/shell
- Files:
-
- 13 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/shell/Makefile.am
r5639 r7374 4 4 noinst_LIBRARIES = libORXshell.a 5 5 6 libORXshell_a_SOURCES = shell.cc \ 7 shell_buffer.cc \ 8 shell_input.cc \ 9 shell_command.cc \ 10 shell_command_class.cc \ 11 shell_completion.cc 6 libORXshell_a_SOURCES = \ 7 shell.cc \ 8 shell_buffer.cc \ 9 shell_input.cc \ 10 shell_command.cc \ 11 shell_command_class.cc \ 12 shell_completion.cc \ 13 shell_completion_plugin.cc 12 14 13 15 14 noinst_HEADERS= shell.h \ 16 noinst_HEADERS= \ 17 shell.h \ 15 18 shell_buffer.h \ 16 19 shell_input.h \ 17 shell_command.h \ 18 shell_command_class.h \ 19 shell_completion.h 20 shell_command.h \ 21 shell_command_class.h \ 22 shell_completion.h \ 23 shell_completion_plugin.h -
trunk/src/lib/shell/shell.cc
r7342 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.h" … … 33 33 #include <stdio.h> 34 34 35 using namespace std; 35 namespace OrxShell 36 { 36 37 37 38 SHELL_COMMAND(clear, Shell, clear) … … 132 133 this->setRelCoorSoft2D(0, 0, 5); 133 134 134 list<std::string>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer().end();135 std::list<std::string>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer().end(); 135 136 bool top = false; 136 137 for (std::list<Text*>::iterator text = this->bufferText.begin(); text != this->bufferText.end(); ++text) … … 378 379 } 379 380 // redisplay the buffers 380 list<std::string>::const_iterator it = this->bufferIterator;381 std::list<std::string>::const_iterator it = this->bufferIterator; 381 382 if (it == ShellBuffer::getInstance()->getBuffer().end()) 382 383 { … … 518 519 // PRINTF(3)("This is the Test for one String '%s' and one Float '%f'\n",s , f); 519 520 // } 521 522 } -
trunk/src/lib/shell/shell.h
r7341 r7374 24 24 class Material; 25 25 26 //! A class that is able to redirect all output to a openGL-Shell, and that one can use to input some commands 27 /** 28 * the major idea is, that all the Output can be redirected to the Shell, 29 * and does not have to be displayed to the opening Shell, this is good, 30 * for developers using Windows, where all output is otherwise redirected 31 * to stdout.txt 32 * 33 * Furthermore the Shell should enable us, to input some simple commands 34 * Each Class can check itself in to the Shell, and listen for commands. 35 * 36 * more info: @see ShellCommand 37 * @see shell_command.h 38 * @see shell_buffer.h 39 * @see shell_input.h 40 * 41 * !! note in order to keep shellbuffer to a minimal (it is included with 42 * !! debug.h) Display of it inside the Shell is located here !! 43 */ 44 class Shell : public Element2D, public EventListener { 26 namespace OrxShell 27 { 28 //! A class that is able to redirect all output to a openGL-Shell, and that one can use to input some commands 29 /** 30 * the major idea is, that all the Output can be redirected to the Shell, 31 * and does not have to be displayed to the opening Shell, this is good, 32 * for developers using Windows, where all output is otherwise redirected 33 * to stdout.txt 34 * 35 * Furthermore the Shell should enable us, to input some simple commands 36 * Each Class can check itself in to the Shell, and listen for commands. 37 * 38 * more info: @see ShellCommand 39 * @see shell_command.h 40 * @see shell_buffer.h 41 * @see shell_input.h 42 * 43 * !! note in order to keep shellbuffer to a minimal (it is included with 44 * !! debug.h) Display of it inside the Shell is located here !! 45 */ 46 class Shell : public Element2D, public EventListener 47 { 45 48 46 49 public: … … 104 107 int bufferOffset; //!< how many lines from the bottom up we display the Buffer. 105 108 std::list<std::string>::const_iterator bufferIterator; //!< used to move through and print the Buffer 106 }; 109 }; 110 111 } 107 112 108 113 #endif /* _SHELL_H */ -
trunk/src/lib/shell/shell_buffer.cc
r7316 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_buffer.h" … … 22 22 #include "stdlibincl.h" 23 23 24 using namespace std; 24 namespace OrxShell 25 { 25 26 26 27 … … 189 190 PRINT(3)("Debugging output to console (not this shell)\n"); 190 191 191 list<std::string>::const_iterator bufferLine;192 std::list<std::string>::const_iterator bufferLine; 192 193 for (bufferLine = this->buffer.begin(); bufferLine != this->buffer.end(); bufferLine++) 193 194 printf((*bufferLine).c_str()); 194 195 } 196 197 } -
trunk/src/lib/shell/shell_buffer.h
r7329 r7374 14 14 #define SHELL_BUFFER_SIZE 16384 //!< The Size of the input-buffers (should be large enough to carry any kind of input) 15 15 16 // FORWARD DECLARATION 17 class Shell; 16 namespace OrxShell 17 { 18 // FORWARD DECLARATION 19 class Shell; 18 20 19 #ifndef NULL 20 #define NULL 0 //!< a pointer to NULL 21 #endif 21 //! A class handling output from orxonox via debug.h 22 class ShellBuffer 23 { 22 24 23 //! A class handling output from orxonox via debug.h 24 class ShellBuffer { 25 public: 26 virtual ~ShellBuffer(); 27 /** @returns a Pointer to the only object of this Class */ 28 inline static ShellBuffer* getInstance() { if (!ShellBuffer::singletonRef) ShellBuffer::singletonRef = new ShellBuffer(); return ShellBuffer::singletonRef; }; 29 /** @returns true if this class is instanciated, false otherwise */ 30 inline static bool isInstanciated() { return (ShellBuffer::singletonRef == NULL)?false:true; }; 25 31 26 public: 27 virtual ~ShellBuffer(); 28 /** @returns a Pointer to the only object of this Class */ 29 inline static ShellBuffer* getInstance() { if (!ShellBuffer::singletonRef) ShellBuffer::singletonRef = new ShellBuffer(); return ShellBuffer::singletonRef; }; 30 /** @returns true if this class is instanciated, false otherwise */ 31 inline static bool isInstanciated() { return (ShellBuffer::singletonRef == NULL)?false:true; }; 32 void registerShell(Shell* shell); 33 void unregisterShell(Shell* shell); 32 34 33 void registerShell(Shell* shell); 34 void unregisterShell(Shell* shell); 35 // BUFFER // 36 /** @param bufferSize the new Buffer-Size */ 37 void setBufferSize(unsigned int bufferSize) { this->bufferSize = bufferSize; }; 38 void flush(); 39 static bool addBufferLineStatic(const char* line, ...); 40 void addBufferLine(const char* line, va_list arg); 41 /** @returns the List of stings from the Buffer */ 42 const std::list<std::string>& getBuffer() const { return this->buffer; }; 43 /** @returns the Count of lines processed by the Shell. */ 44 inline long getLineCount() const { return this->lineCount; }; 35 45 36 // BUFFER // 37 /** @param bufferSize the new Buffer-Size */ 38 void setBufferSize(unsigned int bufferSize) { this->bufferSize = bufferSize; }; 39 void flush(); 40 static bool addBufferLineStatic(const char* line, ...); 41 void addBufferLine(const char* line, va_list arg); 42 /** @returns the List of stings from the Buffer */ 43 const std::list<std::string>& getBuffer() const { return this->buffer; }; 44 /** @returns the Count of lines processed by the Shell. */ 45 inline long getLineCount() const { return this->lineCount; }; 46 47 void debug() const; 46 void debug() const; 48 47 49 48 private: … … 63 62 64 63 static SDL_mutex* bufferMutex; //!< Only one thread may write into the ShellBuffer at a time. 65 }; 64 }; 65 66 } 66 67 67 68 #endif /* _SHELL_BUFFER_H */ -
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 } -
trunk/src/lib/shell/shell_command.h
r7368 r7374 16 16 17 17 18 // FORWARD DECLARATION 19 class ShellCommandClass; 20 class ShellCommandAlias; 18 namespace OrxShell 19 { 20 // FORWARD DECLARATION 21 class ShellCommandClass; 22 class ShellCommandAlias; 21 23 22 /**23 * an easy to use Macro to create a Command24 * @param command the name of the command (without "" around the string)25 * @param class the name of the class to apply this command to (without the "" around the string)26 * @param function the function to call27 *28 * MEANING:29 * ShellCommand* someUniqueVarName =30 * ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);31 *32 * In the Shell you would call this Command using:33 * $ ClassName [ObjectName] commandNameInShell [parameters]34 */35 //#define SHELL_COMMAND(command, class, function) \36 // ShellCommand* shell_command_##class##_##command = ShellCommand<class>::registerCommand(#command, #class, &class::function)24 /** 25 * an easy to use Macro to create a Command 26 * @param command the name of the command (without "" around the string) 27 * @param class the name of the class to apply this command to (without the "" around the string) 28 * @param function the function to call 29 * 30 * MEANING: 31 * ShellCommand* someUniqueVarName = 32 * ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall); 33 * 34 * In the Shell you would call this Command using: 35 * $ ClassName [ObjectName] commandNameInShell [parameters] 36 */ 37 //#define SHELL_COMMAND(command, class, function) \ 38 // ShellCommand* shell_command_##class##_##command = ShellCommand<class>::registerCommand(#command, #class, &class::function) 37 39 #define SHELL_COMMAND(command, class, function) \ 38 ShellCommand* shell_command_##class##_##command =ShellCommand::registerCommand(#command, #class, ExecutorObjective<class>(&class::function))40 OrxShell::ShellCommand* shell_command_##class##_##command = OrxShell::ShellCommand::registerCommand(#command, #class, ExecutorObjective<class>(&class::function)) 39 41 40 /**41 * an easy to use Macro to create a Command42 * @param command the name of the command (without "" around the string)43 * @param class the name of the class to apply this command to (without the "" around the string)44 * @param function the function to call45 *46 * MEANING:47 * ShellCommand* someUniqueVarName =48 * ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);49 *50 * In the Shell you would call this Command using:51 * $ ClassName [ObjectName] commandNameInShell [parameters]52 */42 /** 43 * an easy to use Macro to create a Command 44 * @param command the name of the command (without "" around the string) 45 * @param class the name of the class to apply this command to (without the "" around the string) 46 * @param function the function to call 47 * 48 * MEANING: 49 * ShellCommand* someUniqueVarName = 50 * ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall); 51 * 52 * In the Shell you would call this Command using: 53 * $ ClassName [ObjectName] commandNameInShell [parameters] 54 */ 53 55 #define SHELL_COMMAND_STATIC(command, class, function) \ 54 ShellCommand* shell_command_##class##_##command =ShellCommand::registerCommand(#command, #class, ExecutorStatic<class>(function))56 OrxShell::ShellCommand* shell_command_##class##_##command = OrxShell::ShellCommand::registerCommand(#command, #class, ExecutorStatic<class>(function)) 55 57 56 58 57 59 58 //! a baseClass for all possible ShellCommands59 class ShellCommand : public BaseObject60 {61 friend class ShellCommandClass;60 //! a baseClass for all possible ShellCommands 61 class ShellCommand : public BaseObject 62 { 63 friend class ShellCommandClass; 62 64 public: 63 65 static bool execute (const std::string& executionString); … … 89 91 Executor* executor; //!< The Executor, that really executes the Function. 90 92 91 };93 }; 92 94 93 //! A Class, that handles aliases.94 class ShellCommandAlias95 {96 friend class ShellCommand;95 //! A Class, that handles aliases. 96 class ShellCommandAlias 97 { 98 friend class ShellCommand; 97 99 public: 98 100 /** @returns the Name of the Alias. */ … … 108 110 std::string aliasName; //!< the name of the Alias 109 111 ShellCommand* command; //!< a pointer to the command, this alias executes. 110 }; 112 }; 113 114 } 111 115 112 116 #endif /* _SHELL_COMMAND_H */ -
trunk/src/lib/shell/shell_command_class.cc
r7221 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_class.h" … … 27 27 #include <string.h> 28 28 29 using namespace std; 30 31 std::list<ShellCommandClass*>* ShellCommandClass::commandClassList = NULL; 32 std::list<ShellCommandAlias*>* ShellCommandClass::aliasList = NULL; 33 34 /** 35 * creates a new ShellCommandClass 36 * @param className the Name of the command-class to create 37 */ 38 ShellCommandClass::ShellCommandClass(const std::string& className) 39 : className(className) 29 namespace OrxShell 40 30 { 41 this->setClassID(CL_SHELL_COMMAND_CLASS, "ShellCommandClass"); 42 this->setName(className); 43 44 this->classID = CL_NULL; 45 46 ShellCommandClass::commandClassList->push_back(this); 47 } 48 49 /** 50 * destructs the shellCommandClass again 51 */ 52 ShellCommandClass::~ShellCommandClass() 53 { 54 while(this->commandList.size() > 0) 55 { 56 delete this->commandList.front(); 57 this->commandList.pop_front(); 58 } 59 } 60 61 /** 62 * collects the Commands registered to some class. 63 * @param className the name of the Class to collect the Commands from. 64 * @param stringList a List to paste the Commands into. 65 * @returns true on success, false otherwise 66 */ 67 bool ShellCommandClass::getCommandListOfClass(const std::string& className, std::list<std::string>* stringList) 68 { 69 if (stringList == NULL) 70 return false; 71 72 list<ShellCommandClass*>::iterator elem; 73 for(elem = ShellCommandClass::commandClassList->begin(); elem != ShellCommandClass::commandClassList->end(); elem++) 74 { 75 if (className == (*elem)->getName()) 76 { 77 list<ShellCommand*>::iterator command; 78 for(command = (*elem)->commandList.begin(); command != (*elem)->commandList.end(); command++) 79 stringList->push_back((*command)->getName()); 80 } 81 } 82 return true; 83 } 84 85 /** 86 * collects the Aliases registered to the ShellCommands 87 * @param stringList a List to paste the Aliases into. 88 * @returns true on success, false otherwise 89 */ 90 bool ShellCommandClass::getCommandListOfAlias(std::list<std::string>* stringList) 91 { 92 if (stringList == NULL || ShellCommandClass::aliasList == NULL) 93 return false; 94 95 list<ShellCommandAlias*>::iterator alias; 96 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++) 97 stringList->push_back((*alias)->getName()); 98 return true; 99 } 100 101 /** 102 * unregisters all Commands that exist 103 */ 104 void ShellCommandClass::unregisterAllCommands() 105 { 106 if (ShellCommandClass::commandClassList != NULL) 107 { 108 // unregister all commands and Classes 31 32 std::list<ShellCommandClass*>* ShellCommandClass::commandClassList = NULL; 33 std::list<ShellCommandAlias*>* ShellCommandClass::aliasList = NULL; 34 35 /** 36 * creates a new ShellCommandClass 37 * @param className the Name of the command-class to create 38 */ 39 ShellCommandClass::ShellCommandClass(const std::string& className) 40 : className(className) 41 { 42 this->setClassID(CL_SHELL_COMMAND_CLASS, "ShellCommandClass"); 43 this->setName(className); 44 45 this->classID = CL_NULL; 46 47 ShellCommandClass::commandClassList->push_back(this); 48 } 49 50 /** 51 * destructs the shellCommandClass again 52 */ 53 ShellCommandClass::~ShellCommandClass() 54 { 55 while(this->commandList.size() > 0) 56 { 57 delete this->commandList.front(); 58 this->commandList.pop_front(); 59 } 60 } 61 62 /** 63 * collects the Commands registered to some class. 64 * @param className the name of the Class to collect the Commands from. 65 * @param stringList a List to paste the Commands into. 66 * @returns true on success, false otherwise 67 */ 68 bool ShellCommandClass::getCommandListOfClass(const std::string& className, std::list<std::string>* stringList) 69 { 70 if (stringList == NULL) 71 return false; 72 73 std::list<ShellCommandClass*>::iterator elem; 74 for(elem = ShellCommandClass::commandClassList->begin(); elem != ShellCommandClass::commandClassList->end(); elem++) 75 { 76 if (className == (*elem)->getName()) 77 { 78 std::list<ShellCommand*>::iterator command; 79 for(command = (*elem)->commandList.begin(); command != (*elem)->commandList.end(); command++) 80 stringList->push_back((*command)->getName()); 81 } 82 } 83 return true; 84 } 85 86 /** 87 * collects the Aliases registered to the ShellCommands 88 * @param stringList a List to paste the Aliases into. 89 * @returns true on success, false otherwise 90 */ 91 bool ShellCommandClass::getCommandListOfAlias(std::list<std::string>* stringList) 92 { 93 if (stringList == NULL || ShellCommandClass::aliasList == NULL) 94 return false; 95 96 std::list<ShellCommandAlias*>::iterator alias; 97 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++) 98 stringList->push_back((*alias)->getName()); 99 return true; 100 } 101 102 /** 103 * unregisters all Commands that exist 104 */ 105 void ShellCommandClass::unregisterAllCommands() 106 { 107 if (ShellCommandClass::commandClassList != NULL) 108 { 109 // unregister all commands and Classes 110 std::list<ShellCommandClass*>::iterator classIT; 111 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++) 112 delete (*classIT); 113 delete ShellCommandClass::commandClassList; 114 ShellCommandClass::commandClassList = NULL; 115 } 116 117 // unregister all aliases (there should be nothing to do here :)) 118 if (ShellCommandClass::aliasList != NULL) 119 { 120 std::list<ShellCommandAlias*>::iterator alias; 121 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++) 122 delete (*alias); 123 delete ShellCommandClass::aliasList; 124 ShellCommandClass::aliasList = NULL; 125 } 126 } 127 128 /** 129 * checks if a Class is already registered to the Commands' class-stack 130 * @param className the Name of the Class to check for 131 * @returns the CommandClass if found, NULL otherwise 132 */ 133 const ShellCommandClass* ShellCommandClass::isRegistered(const std::string& className) 134 { 135 if (ShellCommandClass::commandClassList == NULL) 136 initCommandClassList(); 137 138 std::list<ShellCommandClass*>::const_iterator classIT; 139 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++) 140 { 141 if (className == (*classIT)->className) 142 { 143 if ((*classIT)->classID == CL_NULL) 144 (*classIT)->classID = ClassList::StringToID(className); 145 146 return (*classIT); 147 } 148 } 149 return NULL; 150 } 151 152 /** 153 * searches for a CommandClass 154 * @param className the name of the CommandClass 155 * @returns the CommandClass if found, or a new CommandClass if not 156 */ 157 ShellCommandClass* ShellCommandClass::getCommandClass(const std::string& className) 158 { 159 if (ShellCommandClass::commandClassList == NULL) 160 initCommandClassList(); 161 109 162 std::list<ShellCommandClass*>::iterator classIT; 110 163 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++) 111 delete (*classIT); 112 delete ShellCommandClass::commandClassList; 113 ShellCommandClass::commandClassList = NULL; 114 } 115 116 // unregister all aliases (there should be nothing to do here :)) 117 if (ShellCommandClass::aliasList != NULL) 118 { 119 std::list<ShellCommandAlias*>::iterator alias; 120 for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++) 121 delete (*alias); 122 delete ShellCommandClass::aliasList; 123 ShellCommandClass::aliasList = NULL; 124 } 164 { 165 if (className == (*classIT)->className) 166 { 167 return (*classIT); 168 } 169 } 170 return new ShellCommandClass(className); 171 } 172 173 /** 174 * @brief initializes the CommandList (if it is NULL) 175 */ 176 void ShellCommandClass::initCommandClassList() 177 { 178 if (ShellCommandClass::commandClassList == NULL) 179 { 180 ShellCommandClass::commandClassList = new std::list<ShellCommandClass*>; 181 ShellCommand::registerCommand("debug", "ShellCommand", ExecutorStatic<ShellCommand>(ShellCommand::debug)); 182 } 183 } 184 185 /** 186 * @brief displays help about ShellCommandClass 187 * @param className: the Class of Commands to show help about 188 */ 189 void ShellCommandClass::help(const std::string& className) 190 { 191 if (likely(ShellCommandClass::commandClassList != NULL)) 192 { 193 std::list<ShellCommandClass*>::iterator classIT; 194 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++) 195 { 196 if (className == (*classIT)->className) 197 { 198 PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className.c_str(), (*classIT)->commandList.size()); 199 std::list<ShellCommand*>::const_iterator cmdIT; 200 for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++) 201 { 202 PRINT(0)(" command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount()); 203 /// FIXME 204 /* for (unsigned int i = 0; i< elem->paramCount; i++) 205 PRINT(0)("%s ", ShellCommand::paramToString(elem->parameters[i]));*/ 206 if (!(*cmdIT)->description.empty()) 207 PRINT(0)("- %s", (*cmdIT)->description.c_str()); 208 PRINT(0)("\n"); 209 } 210 return; 211 } 212 } 213 PRINTF(3)("Class %s not found in Command's classes\n", className.c_str()); 214 } 215 else 216 { 217 PRINTF(1)("List of commandClasses does not exist"); 218 } 219 } 220 125 221 } 126 127 /**128 * checks if a Class is already registered to the Commands' class-stack129 * @param className the Name of the Class to check for130 * @returns the CommandClass if found, NULL otherwise131 */132 const ShellCommandClass* ShellCommandClass::isRegistered(const std::string& className)133 {134 if (ShellCommandClass::commandClassList == NULL)135 initCommandClassList();136 137 list<ShellCommandClass*>::const_iterator classIT;138 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)139 {140 if (className == (*classIT)->className)141 {142 if ((*classIT)->classID == CL_NULL)143 (*classIT)->classID = ClassList::StringToID(className);144 145 return (*classIT);146 }147 }148 return NULL;149 }150 151 /**152 * searches for a CommandClass153 * @param className the name of the CommandClass154 * @returns the CommandClass if found, or a new CommandClass if not155 */156 ShellCommandClass* ShellCommandClass::getCommandClass(const std::string& className)157 {158 if (ShellCommandClass::commandClassList == NULL)159 initCommandClassList();160 161 list<ShellCommandClass*>::iterator classIT;162 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)163 {164 if (className == (*classIT)->className)165 {166 return (*classIT);167 }168 }169 return new ShellCommandClass(className);170 }171 172 /**173 * initializes the CommandList (if it is NULL)174 */175 void ShellCommandClass::initCommandClassList()176 {177 if (ShellCommandClass::commandClassList == NULL)178 {179 ShellCommandClass::commandClassList = new std::list<ShellCommandClass*>;180 ShellCommand::registerCommand("debug", "ShellCommand", ExecutorStatic<ShellCommand>(ShellCommand::debug));181 }182 }183 184 /**185 * displays help about ShellCommandClass186 * @param className: the Class of Commands to show help about187 */188 void ShellCommandClass::help(const std::string& className)189 {190 if (likely(ShellCommandClass::commandClassList != NULL))191 {192 list<ShellCommandClass*>::iterator classIT;193 for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)194 {195 if (className == (*classIT)->className)196 {197 PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className.c_str(), (*classIT)->commandList.size());198 list<ShellCommand*>::const_iterator cmdIT;199 for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++)200 {201 PRINT(0)(" command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount());202 /// FIXME203 /* for (unsigned int i = 0; i< elem->paramCount; i++)204 PRINT(0)("%s ", ShellCommand::paramToString(elem->parameters[i]));*/205 if (!(*cmdIT)->description.empty())206 PRINT(0)("- %s", (*cmdIT)->description.c_str());207 PRINT(0)("\n");208 }209 return;210 }211 }212 PRINTF(3)("Class %s not found in Command's classes\n", className.c_str());213 }214 else215 {216 PRINTF(1)("List of commandClasses does not exist");217 }218 }219 -
trunk/src/lib/shell/shell_command_class.h
r7221 r7374 11 11 12 12 13 // FORWARD DECLARATION 13 namespace OrxShell 14 { 15 // FORWARD DECLARATION 16 class ShellCommand; 17 class ShellCommandAlias; 14 18 15 //////////////// 16 // BASE CLASS // 17 //////////////// 18 class ShellCommand; 19 class ShellCommandAlias; 20 21 //! A class to hold all Classes that have (once) registered Commands. 22 class ShellCommandClass : public BaseObject 23 { 24 friend class ShellCommand; 19 //! A class to hold all Classes that have (once) registered Commands. 20 class ShellCommandClass : public BaseObject 21 { 22 friend class ShellCommand; 25 23 26 24 public: … … 48 46 static std::list<ShellCommandClass*>* commandClassList; //!< A list of Classes 49 47 static std::list<ShellCommandAlias*>* aliasList; //!< An Alias to A Command. (only for classes with one Instance) 50 }; 48 }; 49 50 } 51 51 52 52 #endif /* _SHELL_COMMAND_H */ -
trunk/src/lib/shell/shell_completion.cc
r7373 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_completion.h" 19 19 #include "shell_command_class.h" 20 20 21 #include "shell_input.h"22 21 #include "shell_command.h" 23 22 … … 26 25 #include "debug.h" 27 26 28 using namespace std; 29 30 /** 31 * @brief standard constructor 32 */ 33 ShellCompletion::ShellCompletion() 34 { } 35 36 37 /** 38 * @brief standard deconstructor 39 */ 40 ShellCompletion::~ShellCompletion () 41 { } 42 43 44 45 /** 46 * @brief autocompletes the Shell's inputLine 47 * @param input the input to complete. 48 * @returns true, if a result was found, false otherwise 49 */ 50 bool ShellCompletion::autoComplete(std::string& input) 27 namespace OrxShell 51 28 { 52 const char* completionLine; //< the inputLine we complete. 53 54 long classID; //< the classID retrieved from the Class. 55 const std::list<BaseObject*>* objectList; //< the list of Objects stored in classID 56 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 57 long completeType = NullCompletion; //< the Type we'd like to complete. 58 std::string completeString; //< the string to complete. 59 60 61 PRINTF(5)("AutoComplete on input\n"); 62 this->clearCompletionList(); 63 64 // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object 65 if (input[input.size()-1] == ' ') 66 emptyComplete = true; 67 68 // CREATE INPUTS 69 SubString inputSplits(input, SubString::WhiteSpacesWithComma); 70 71 // What String will be completed 72 if (emptyComplete == true) 73 completeString = ""; 74 else 75 completeString = inputSplits.getString(inputSplits.size()-1); 76 77 // CLASS COMPLETION 78 if (inputSplits.size() == 0) 79 { 80 completeType |= ClassCompletion; 81 completeType |= AliasCompletion; 82 } 83 else if (inputSplits.size() == 1 && emptyComplete == false) 84 { 85 completeType |= ClassCompletion; 86 completeType |= AliasCompletion; 87 } 88 89 // OBJECT/FUNCTION COMPLETIONS 90 else if ((inputSplits.size() == 1 && emptyComplete == true) || 91 (inputSplits.size() == 2 && emptyComplete == false)) 92 { 93 classID = ClassList::StringToID(inputSplits.getString(0)); 94 objectList = ClassList::getList((ClassID)classID); 95 if (classID != CL_NULL) 96 completeType |= ObjectCompletion; 97 //if (objectList != NULL && objectList->getSize() == 1) 29 30 /** 31 * @brief standard constructor 32 */ 33 ShellCompletion::ShellCompletion() 34 { } 35 36 37 /** 38 * @brief standard deconstructor 39 */ 40 ShellCompletion::~ShellCompletion () 41 { } 42 43 44 45 /** 46 * @brief autocompletes the Shell's inputLine 47 * @param input the input to complete. 48 * @returns true, if a result was found, false otherwise 49 */ 50 bool ShellCompletion::autoComplete(std::string& input) 51 { 52 const char* completionLine; //< the inputLine we complete. 53 54 long classID; //< the classID retrieved from the Class. 55 const std::list<BaseObject*>* objectList; //< the list of Objects stored in classID 56 bool emptyComplete = false; //< if the completion input is empty string. e.g "" 57 long completeType = NullCompletion; //< the Type we'd like to complete. 58 std::string completeString; //< the string to complete. 59 60 61 PRINTF(5)("AutoComplete on input\n"); 62 this->clearCompletionList(); 63 64 // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object 65 if (input[input.size()-1] == ' ') 66 emptyComplete = true; 67 68 // CREATE INPUTS 69 SubString inputSplits(input, SubString::WhiteSpacesWithComma); 70 71 // What String will be completed 72 if (emptyComplete == true) 73 completeString = ""; 74 else 75 completeString = inputSplits.getString(inputSplits.size()-1); 76 77 // CLASS COMPLETION 78 if (inputSplits.size() == 0) 79 { 80 completeType |= ClassCompletion; 81 completeType |= AliasCompletion; 82 } 83 else if (inputSplits.size() == 1 && emptyComplete == false) 84 { 85 completeType |= ClassCompletion; 86 completeType |= AliasCompletion; 87 } 88 89 // OBJECT/FUNCTION COMPLETIONS 90 else if ((inputSplits.size() == 1 && emptyComplete == true) || 91 (inputSplits.size() == 2 && emptyComplete == false)) 92 { 93 classID = ClassList::StringToID(inputSplits.getString(0)); 94 objectList = ClassList::getList((ClassID)classID); 95 if (classID != CL_NULL) 96 completeType |= ObjectCompletion; 97 //if (objectList != NULL && objectList->getSize() == 1) 98 98 completeType |= FunctionCompletion; 99 } 100 else if ((inputSplits.size() == 2 && emptyComplete == true) || 101 (inputSplits.size() == 3 && emptyComplete == false)) 102 { 103 classID = ClassList::StringToID(inputSplits.getString(0)); 104 if (classID == CL_NULL) 105 return false; 99 } 100 else if ((inputSplits.size() == 2 && emptyComplete == true) || 101 (inputSplits.size() == 3 && emptyComplete == false)) 102 { 103 classID = ClassList::StringToID(inputSplits.getString(0)); 104 if (classID == CL_NULL) 105 return false; 106 else 107 completeType |= FunctionCompletion; 108 } 109 110 if (completeType & ClassCompletion) 111 this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS); 112 if (completeType & ObjectCompletion) 113 this->objectComplete(completeString, classID); 114 if (completeType & FunctionCompletion) 115 this->functionComplete(completeString, inputSplits.getString(0)); 116 if (completeType & AliasCompletion) 117 this->aliasComplete(completeString); 118 119 120 this->generalComplete(input, completeString); 121 return true; 122 } 123 124 /** 125 * @brief autocompletes a className 126 * @param classBegin the Beginning of a String to autoComplete 127 * @return true on success, false otherwise 128 */ 129 bool ShellCompletion::classComplete(const std::string& classBegin) 130 { 131 const std::list<std::string>* clList = ClassList::getClassNames(); 132 if (clList != NULL) 133 { 134 if (!this->addToCompleteList(*clList, classBegin, ClassCompletion)) 135 return false; 136 } 106 137 else 107 completeType |= FunctionCompletion; 108 } 109 110 if (completeType & ClassCompletion) 111 this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS); 112 if (completeType & ObjectCompletion) 113 this->objectComplete(completeString, classID); 114 if (completeType & FunctionCompletion) 115 this->functionComplete(completeString, inputSplits.getString(0)); 116 if (completeType & AliasCompletion) 117 this->aliasComplete(completeString); 118 119 120 this->generalComplete(input, completeString); 121 return true; 138 return false; 139 return true; 140 } 141 142 /** 143 * @brief autocompletes an ObjectName 144 * @param objectBegin the beginning string of a Object 145 * @param classID the ID of the Class to search for. 146 * @return true on success, false otherwise 147 */ 148 bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID) 149 { 150 const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID); 151 if (boList != NULL) 152 { 153 CompletionType type = ObjectCompletion; 154 if (classID == CL_SHELL_COMMAND_CLASS) 155 type = ClassCompletion; 156 if (!this->addToCompleteList(*boList, objectBegin, type)) 157 return false; 158 } 159 else 160 return false; 161 return true; 162 } 163 164 /** 165 * @brief completes a Function 166 * @param functionBegin the beginning of the function String 167 * @param classID the class' ID to complete the function of 168 */ 169 bool ShellCompletion::functionComplete(const std::string& functionBegin, const std::string& className) 170 { 171 std::list<std::string> fktList; 172 ShellCommandClass::getCommandListOfClass(className, &fktList); 173 //printf("%s\n", boList->firstElement()->getName()); 174 if (!this->addToCompleteList(fktList, functionBegin, FunctionCompletion)) 175 return false; 176 return true; 177 } 178 179 /** 180 * @brief completes an Alias 181 * @param aliasBegin the beginning of the Alias-String to complete 182 * @returns true on succes, false if something went wrong 183 */ 184 bool ShellCompletion::aliasComplete(const std::string& aliasBegin) 185 { 186 std::list<std::string> aliasList; 187 ShellCommandClass::getCommandListOfAlias(&aliasList); 188 //printf("%s\n", boList->firstElement()->getName()); 189 if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion)) 190 return false; 191 return true; 192 } 193 194 195 /** 196 * @brief completes the inputline on grounds of an inputList 197 * @param input the Input to complete. 198 * @param begin the String to search in the inputList, and to extend with it. 199 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::" 200 * @param addBack what should be added at the end of the completion 201 * @param addFront what should be added to the front of one finished completion 202 * @return true if ok, false otherwise 203 */ 204 bool ShellCompletion::generalComplete(std::string& input, 205 const std::string& begin, const std::string& displayAs, 206 const std::string& addBack, const std::string& addFront) 207 { 208 if (completionList.size() == 0) 209 return false; 210 211 CompletionElement addElem = completionList.front(); 212 const std::string& addString = addElem.name; 213 unsigned int addLength = 0; 214 unsigned int inputLenght = begin.size(); 215 216 // Determin the longest Match 217 addLength = addString.size(); 218 219 CompletionType changeType = NullCompletion; 220 std::vector<CompletionElement>::iterator charIT; 221 for (charIT = completionList.begin(); charIT != completionList.end(); charIT++) 222 { 223 if ((*charIT).type != changeType) 224 { 225 if (changeType != NullCompletion) 226 PRINT(0)("\n"); 227 PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str()); 228 changeType = (*charIT).type; 229 } 230 PRINTF(0)("%s ", (*charIT).name.c_str()); 231 for (unsigned int i = inputLenght; i < addLength; i++) 232 if (addString[i] != (*charIT).name[i]) 233 { 234 addLength = i; 235 // break; 236 } 237 } 238 PRINT(0)("\n"); 239 240 if (addLength >= inputLenght) 241 { 242 std::string adder = addString; 243 adder.resize(addLength); 244 245 input.resize(input.size()-inputLenght); 246 input += adder; 247 248 if (completionList.size() == 1) 249 { 250 if ( addBack != "") 251 input += addBack; 252 input += ' '; 253 } 254 } 255 return true; 256 } 257 258 /** 259 * @brief searches for classes, which beginn with completionBegin 260 * @param inputList the List to parse through 261 * @param completionBegin the beginning string 262 * !! The strings MUST NOT be deleted !! 263 */ 264 bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type) 265 { 266 unsigned int searchLength = completionBegin.size(); 267 268 std::list<std::string>::const_iterator string; 269 for (string = inputList.begin(); string != inputList.end(); string++) 270 { 271 if ((*string).size() >= searchLength && 272 !nocaseCmp(*string, completionBegin, searchLength)) 273 { 274 printf ("%s\n", (*string).c_str()); 275 CompletionElement newElem; 276 newElem.name = (*string); 277 newElem.type = type; 278 this->completionList.push_back(newElem); 279 } 280 } 281 return true; 282 } 283 284 /** 285 * @brief searches for classes, which beginn with completionBegin 286 * @param inputList the List to parse through 287 * @param completionBegin the beginning string 288 * !! The strings MUST NOT be deleted !! 289 */ 290 bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type) 291 { 292 unsigned int searchLength = completionBegin.size(); 293 294 std::list<BaseObject*>::const_iterator bo; 295 for(bo = inputList.begin(); bo != inputList.end(); bo++) 296 { 297 if ((*bo)->getName() != NULL && 298 strlen((*bo)->getName()) >= searchLength && 299 !nocaseCmp((*bo)->getName(), completionBegin, searchLength)) 300 { 301 CompletionElement newElem; 302 newElem.name = (*bo)->getName(); 303 newElem.type = type; 304 this->completionList.push_back(newElem); 305 } 306 } 307 308 return true; 309 } 310 311 /** 312 * @brief deletes the Completion List. 313 * 314 * This is done at the beginning of each completion-run 315 */ 316 void ShellCompletion::clearCompletionList() 317 { 318 this->completionList.clear(); 319 } 320 321 const std::string& ShellCompletion::typeToString(CompletionType type) 322 { 323 switch (type) 324 { 325 default:// SHELLC_NONE 326 return typeNames[0]; 327 case ClassCompletion: 328 return typeNames[1]; 329 case ObjectCompletion: 330 return typeNames[2]; 331 case FunctionCompletion: 332 return typeNames[3]; 333 case AliasCompletion: 334 return typeNames[4]; 335 } 336 } 337 338 339 const std::string ShellCompletion::typeNames[] = 340 { 341 "error", 342 "class", 343 "object", 344 "function", 345 "alias" 346 }; 347 122 348 } 123 124 /**125 * @brief autocompletes a className126 * @param classBegin the Beginning of a String to autoComplete127 * @return true on success, false otherwise128 */129 bool ShellCompletion::classComplete(const std::string& classBegin)130 {131 const std::list<std::string>* clList = ClassList::getClassNames();132 if (clList != NULL)133 {134 if (!this->addToCompleteList(*clList, classBegin, ClassCompletion))135 return false;136 }137 else138 return false;139 return true;140 }141 142 /**143 * @brief autocompletes an ObjectName144 * @param objectBegin the beginning string of a Object145 * @param classID the ID of the Class to search for.146 * @return true on success, false otherwise147 */148 bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID)149 {150 const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);151 if (boList != NULL)152 {153 CompletionType type = ObjectCompletion;154 if (classID == CL_SHELL_COMMAND_CLASS)155 type = ClassCompletion;156 if (!this->addToCompleteList(*boList, objectBegin, type))157 return false;158 }159 else160 return false;161 return true;162 }163 164 /**165 * @brief completes a Function166 * @param functionBegin the beginning of the function String167 * @param classID the class' ID to complete the function of168 */169 bool ShellCompletion::functionComplete(const std::string& functionBegin, const std::string& className)170 {171 std::list<std::string> fktList;172 ShellCommandClass::getCommandListOfClass(className, &fktList);173 //printf("%s\n", boList->firstElement()->getName());174 if (!this->addToCompleteList(fktList, functionBegin, FunctionCompletion))175 return false;176 return true;177 }178 179 /**180 * @brief completes an Alias181 * @param aliasBegin the beginning of the Alias-String to complete182 * @returns true on succes, false if something went wrong183 */184 bool ShellCompletion::aliasComplete(const std::string& aliasBegin)185 {186 std::list<std::string> aliasList;187 ShellCommandClass::getCommandListOfAlias(&aliasList);188 //printf("%s\n", boList->firstElement()->getName());189 if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))190 return false;191 return true;192 }193 194 195 /**196 * @brief completes the inputline on grounds of an inputList197 * @param input the Input to complete.198 * @param begin the String to search in the inputList, and to extend with it.199 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"200 * @param addBack what should be added at the end of the completion201 * @param addFront what should be added to the front of one finished completion202 * @return true if ok, false otherwise203 */204 bool ShellCompletion::generalComplete(std::string& input,205 const std::string& begin, const std::string& displayAs,206 const std::string& addBack, const std::string& addFront)207 {208 if (completionList.size() == 0)209 return false;210 211 CompletionElement addElem = completionList.front();212 const std::string& addString = addElem.name;213 unsigned int addLength = 0;214 unsigned int inputLenght = begin.size();215 216 // Determin the longest Match217 addLength = addString.size();218 219 CompletionType changeType = NullCompletion;220 std::vector<CompletionElement>::iterator charIT;221 for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)222 {223 if ((*charIT).type != changeType)224 {225 if (changeType != NullCompletion)226 PRINT(0)("\n");227 PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());228 changeType = (*charIT).type;229 }230 PRINTF(0)("%s ", (*charIT).name.c_str());231 for (unsigned int i = inputLenght; i < addLength; i++)232 if (addString[i] != (*charIT).name[i])233 {234 addLength = i;235 // break;236 }237 }238 PRINT(0)("\n");239 240 if (addLength >= inputLenght)241 {242 std::string adder = addString;243 adder.resize(addLength);244 245 input.resize(input.size()-inputLenght);246 input += adder;247 248 if (completionList.size() == 1)249 {250 if ( addBack != "")251 input += addBack;252 input += ' ';253 }254 }255 return true;256 }257 258 /**259 * @brief searches for classes, which beginn with completionBegin260 * @param inputList the List to parse through261 * @param completionBegin the beginning string262 * !! The strings MUST NOT be deleted !!263 */264 bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)265 {266 unsigned int searchLength = completionBegin.size();267 268 std::list<std::string>::const_iterator string;269 for (string = inputList.begin(); string != inputList.end(); string++)270 {271 if ((*string).size() >= searchLength &&272 !nocaseCmp(*string, completionBegin, searchLength))273 {274 printf ("%s\n", (*string).c_str());275 CompletionElement newElem;276 newElem.name = (*string);277 newElem.type = type;278 this->completionList.push_back(newElem);279 }280 }281 return true;282 }283 284 /**285 * @brief searches for classes, which beginn with completionBegin286 * @param inputList the List to parse through287 * @param completionBegin the beginning string288 * !! The strings MUST NOT be deleted !!289 */290 bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)291 {292 unsigned int searchLength = completionBegin.size();293 294 std::list<BaseObject*>::const_iterator bo;295 for(bo = inputList.begin(); bo != inputList.end(); bo++)296 {297 if ((*bo)->getName() != NULL &&298 strlen((*bo)->getName()) >= searchLength &&299 !nocaseCmp((*bo)->getName(), completionBegin, searchLength))300 {301 CompletionElement newElem;302 newElem.name = (*bo)->getName();303 newElem.type = type;304 this->completionList.push_back(newElem);305 }306 }307 308 return true;309 }310 311 /**312 * @brief deletes the Completion List.313 *314 * This is done at the beginning of each completion-run315 */316 void ShellCompletion::clearCompletionList()317 {318 this->completionList.clear();319 }320 321 const std::string& ShellCompletion::typeToString(CompletionType type)322 {323 switch (type)324 {325 default:// SHELLC_NONE326 return typeNames[0];327 case ClassCompletion:328 return typeNames[1];329 case ObjectCompletion:330 return typeNames[2];331 case FunctionCompletion:332 return typeNames[3];333 case AliasCompletion:334 return typeNames[4];335 }336 }337 338 339 const std::string ShellCompletion::typeNames[] =340 {341 "error",342 "class",343 "object",344 "function",345 "alias"346 }; -
trunk/src/lib/shell/shell_completion.h
r7373 r7374 16 16 // FORWARD DECLARATION 17 17 class BaseObject; 18 class ShellInput; 19 #ifndef NULL 20 #define NULL 0 //!< a pointer to NULL 21 #endif 18 19 namespace OrxShell 20 { 21 //! A class for Completing the an InputString. 22 class ShellCompletion 23 { 24 //! an enumerator for different types the Shell can complete. 25 typedef enum { 26 NullCompletion = 0, 27 ClassCompletion = 1, 28 ObjectCompletion = 2, 29 FunctionCompletion = 4, 30 AliasCompletion = 8, 31 } CompletionType; 32 33 //! A struct for ShellElements (these are used as containers to identify an Input for what it is) 34 struct CompletionElement 35 { 36 std::string name; //!< the Name of the Element to be completed. 37 CompletionType type; //!< the type of the Element 38 }; 39 40 public: 41 ShellCompletion(); 42 virtual ~ShellCompletion(); 22 43 23 44 24 //! A class for Completing the an InputString. 25 class ShellCompletion 26 { 45 // Functions to produce the Complete Lists. 46 bool autoComplete(std::string& input); 47 bool classComplete(const std::string& classBegin); 48 // long classMatch(const char* input, unsigned int* length); 49 bool objectComplete(const std::string& objectBegin, long classID); 50 // bool objectMatch(const char* objectBegin, long classID, unsigned int* length); 51 bool functionComplete(const std::string& functionBegin, const std::string& className); 52 // bool functionMatch(const char* functionBegin, long classID, unsigned int* length); 53 bool aliasComplete(const std::string& aliasBegin); 27 54 28 //! an enumerator for different types the Shell can complete. 29 typedef enum { 30 NullCompletion = 0, 31 ClassCompletion = 1, 32 ObjectCompletion = 2, 33 FunctionCompletion = 4, 34 AliasCompletion = 8, 35 } CompletionType; 55 bool generalComplete(std::string& input, 56 const std::string& begin, const std::string& displayAs = "%s", 57 const std::string& addBack = "", const std::string& addFront = ""); 36 58 37 //! A struct for ShellElements (these are used as containers to identify an Input for what it is) 38 struct CompletionElement 39 { 40 std::string name; //!< the Name of the Element to be completed. 41 CompletionType type; //!< the type of the Element 59 60 bool addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 61 bool addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 62 void clearCompletionList(); 63 64 65 // Helpers. 66 static const std::string& ShellCompletion::typeToString(ShellCompletion::CompletionType type); 67 68 private: 69 std::vector<CompletionElement> completionList; //!< A list of completions, that are io. 70 71 static const std::string typeNames[]; //!< A list of Completion-Type-Names. 42 72 }; 43 73 44 public: 45 ShellCompletion(); 46 virtual ~ShellCompletion(); 47 48 49 // Functions to produce the Complete Lists. 50 bool autoComplete(std::string& input); 51 bool classComplete(const std::string& classBegin); 52 // long classMatch(const char* input, unsigned int* length); 53 bool objectComplete(const std::string& objectBegin, long classID); 54 // bool objectMatch(const char* objectBegin, long classID, unsigned int* length); 55 bool functionComplete(const std::string& functionBegin, const std::string& className); 56 // bool functionMatch(const char* functionBegin, long classID, unsigned int* length); 57 bool aliasComplete(const std::string& aliasBegin); 58 59 bool generalComplete(std::string& input, 60 const std::string& begin, const std::string& displayAs = "%s", 61 const std::string& addBack = "", const std::string& addFront = ""); 62 63 64 bool addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 65 bool addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 66 void clearCompletionList(); 67 68 69 // Helpers. 70 static const std::string& ShellCompletion::typeToString(ShellCompletion::CompletionType type); 71 72 private: 73 std::vector<CompletionElement> completionList; //!< A list of completions, that are io. 74 75 static const std::string typeNames[]; //!< A list of Completion-Type-Names. 76 }; 74 } 77 75 78 76 #endif /* _SHELL_COMPLETION_H */ -
trunk/src/lib/shell/shell_completion_plugin.cc
r7373 r7374 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL 17 17 18 #include "shell_completion .h"18 #include "shell_completion_plugin.h" 19 19 #include "shell_command_class.h" 20 20 21 #include "shell_input.h"22 21 #include "shell_command.h" 23 22 … … 26 25 #include "debug.h" 27 26 28 using namespace std; 29 30 /** 31 * @brief standard constructor 32 */ 33 ShellCompletion::ShellCompletion() 34 { } 35 36 37 /** 38 * @brief standard deconstructor 39 */ 40 ShellCompletion::~ShellCompletion () 41 { } 27 namespace OrxShell 28 { 42 29 43 30 44 31 45 /** 46 * @brief autocompletes the Shell's inputLine47 * @param input the input to complete.48 * @returns true, if a result was found, false otherwise49 */50 bool ShellCompletion::autoComplete(std::string& input) 51 { 52 const char* completionLine; //< the inputLine we complete. 32 void ShellCompletorStringArray::addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) 33 { 34 unsigned int inputLen = completionBegin.size(); 35 for (unsigned int i = 0; i < this->_size; ++i) 36 if (!nocaseCmp(this->_stringArray[i], completionBegin, inputLen)) 37 completionList.push_back(this->_stringArray[i]); 38 } 39 }; 53 40 54 long classID; //< the classID retrieved from the Class.55 const std::list<BaseObject*>* objectList; //< the list of Objects stored in classID56 bool emptyComplete = false; //< if the completion input is empty string. e.g ""57 long completeType = NullCompletion; //< the Type we'd like to complete.58 std::string completeString; //< the string to complete.59 60 61 PRINTF(5)("AutoComplete on input\n");62 this->clearCompletionList();63 64 // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object65 if (input[input.size()-1] == ' ')66 emptyComplete = true;67 68 // CREATE INPUTS69 SubString inputSplits(input, SubString::WhiteSpacesWithComma);70 71 // What String will be completed72 if (emptyComplete == true)73 completeString = "";74 else75 completeString = inputSplits.getString(inputSplits.size()-1);76 77 // CLASS COMPLETION78 if (inputSplits.size() == 0)79 {80 completeType |= ClassCompletion;81 completeType |= AliasCompletion;82 }83 else if (inputSplits.size() == 1 && emptyComplete == false)84 {85 completeType |= ClassCompletion;86 completeType |= AliasCompletion;87 }88 89 // OBJECT/FUNCTION COMPLETIONS90 else if ((inputSplits.size() == 1 && emptyComplete == true) ||91 (inputSplits.size() == 2 && emptyComplete == false))92 {93 classID = ClassList::StringToID(inputSplits.getString(0));94 objectList = ClassList::getList((ClassID)classID);95 if (classID != CL_NULL)96 completeType |= ObjectCompletion;97 //if (objectList != NULL && objectList->getSize() == 1)98 completeType |= FunctionCompletion;99 }100 else if ((inputSplits.size() == 2 && emptyComplete == true) ||101 (inputSplits.size() == 3 && emptyComplete == false))102 {103 classID = ClassList::StringToID(inputSplits.getString(0));104 if (classID == CL_NULL)105 return false;106 else107 completeType |= FunctionCompletion;108 }109 110 if (completeType & ClassCompletion)111 this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS);112 if (completeType & ObjectCompletion)113 this->objectComplete(completeString, classID);114 if (completeType & FunctionCompletion)115 this->functionComplete(completeString, inputSplits.getString(0));116 if (completeType & AliasCompletion)117 this->aliasComplete(completeString);118 119 120 this->generalComplete(input, completeString);121 return true;122 }123 124 /**125 * @brief autocompletes a className126 * @param classBegin the Beginning of a String to autoComplete127 * @return true on success, false otherwise128 */129 bool ShellCompletion::classComplete(const std::string& classBegin)130 {131 const std::list<std::string>* clList = ClassList::getClassNames();132 if (clList != NULL)133 {134 if (!this->addToCompleteList(*clList, classBegin, ClassCompletion))135 return false;136 }137 else138 return false;139 return true;140 }141 142 /**143 * @brief autocompletes an ObjectName144 * @param objectBegin the beginning string of a Object145 * @param classID the ID of the Class to search for.146 * @return true on success, false otherwise147 */148 bool ShellCompletion::objectComplete(const std::string& objectBegin, long classID)149 {150 const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);151 if (boList != NULL)152 {153 CompletionType type = ObjectCompletion;154 if (classID == CL_SHELL_COMMAND_CLASS)155 type = ClassCompletion;156 if (!this->addToCompleteList(*boList, objectBegin, type))157 return false;158 }159 else160 return false;161 return true;162 }163 164 /**165 * @brief completes a Function166 * @param functionBegin the beginning of the function String167 * @param classID the class' ID to complete the function of168 */169 bool ShellCompletion::functionComplete(const std::string& functionBegin, const std::string& className)170 {171 std::list<std::string> fktList;172 ShellCommandClass::getCommandListOfClass(className, &fktList);173 //printf("%s\n", boList->firstElement()->getName());174 if (!this->addToCompleteList(fktList, functionBegin, FunctionCompletion))175 return false;176 return true;177 }178 179 /**180 * @brief completes an Alias181 * @param aliasBegin the beginning of the Alias-String to complete182 * @returns true on succes, false if something went wrong183 */184 bool ShellCompletion::aliasComplete(const std::string& aliasBegin)185 {186 std::list<std::string> aliasList;187 ShellCommandClass::getCommandListOfAlias(&aliasList);188 //printf("%s\n", boList->firstElement()->getName());189 if (!this->addToCompleteList(aliasList, aliasBegin, AliasCompletion))190 return false;191 return true;192 }193 194 195 /**196 * @brief completes the inputline on grounds of an inputList197 * @param input the Input to complete.198 * @param begin the String to search in the inputList, and to extend with it.199 * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"200 * @param addBack what should be added at the end of the completion201 * @param addFront what should be added to the front of one finished completion202 * @return true if ok, false otherwise203 */204 bool ShellCompletion::generalComplete(std::string& input,205 const std::string& begin, const std::string& displayAs,206 const std::string& addBack, const std::string& addFront)207 {208 if (completionList.size() == 0)209 return false;210 211 CompletionElement addElem = completionList.front();212 const std::string& addString = addElem.name;213 unsigned int addLength = 0;214 unsigned int inputLenght = begin.size();215 216 // Determin the longest Match217 addLength = addString.size();218 219 CompletionType changeType = NullCompletion;220 std::vector<CompletionElement>::iterator charIT;221 for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)222 {223 if ((*charIT).type != changeType)224 {225 if (changeType != NullCompletion)226 PRINT(0)("\n");227 PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type).c_str());228 changeType = (*charIT).type;229 }230 PRINTF(0)("%s ", (*charIT).name.c_str());231 for (unsigned int i = inputLenght; i < addLength; i++)232 if (addString[i] != (*charIT).name[i])233 {234 addLength = i;235 // break;236 }237 }238 PRINT(0)("\n");239 240 if (addLength >= inputLenght)241 {242 std::string adder = addString;243 adder.resize(addLength);244 245 input.resize(input.size()-inputLenght);246 input += adder;247 248 if (completionList.size() == 1)249 {250 if ( addBack != "")251 input += addBack;252 input += ' ';253 }254 }255 return true;256 }257 258 /**259 * @brief searches for classes, which beginn with completionBegin260 * @param inputList the List to parse through261 * @param completionBegin the beginning string262 * !! The strings MUST NOT be deleted !!263 */264 bool ShellCompletion::addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, CompletionType type)265 {266 unsigned int searchLength = completionBegin.size();267 268 std::list<std::string>::const_iterator string;269 for (string = inputList.begin(); string != inputList.end(); string++)270 {271 if ((*string).size() >= searchLength &&272 !nocaseCmp(*string, completionBegin, searchLength))273 {274 printf ("%s\n", (*string).c_str());275 CompletionElement newElem;276 newElem.name = (*string);277 newElem.type = type;278 this->completionList.push_back(newElem);279 }280 }281 return true;282 }283 284 /**285 * @brief searches for classes, which beginn with completionBegin286 * @param inputList the List to parse through287 * @param completionBegin the beginning string288 * !! The strings MUST NOT be deleted !!289 */290 bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, CompletionType type)291 {292 unsigned int searchLength = completionBegin.size();293 294 std::list<BaseObject*>::const_iterator bo;295 for(bo = inputList.begin(); bo != inputList.end(); bo++)296 {297 if ((*bo)->getName() != NULL &&298 strlen((*bo)->getName()) >= searchLength &&299 !nocaseCmp((*bo)->getName(), completionBegin, searchLength))300 {301 CompletionElement newElem;302 newElem.name = (*bo)->getName();303 newElem.type = type;304 this->completionList.push_back(newElem);305 }306 }307 308 return true;309 }310 311 /**312 * @brief deletes the Completion List.313 *314 * This is done at the beginning of each completion-run315 */316 void ShellCompletion::clearCompletionList()317 {318 this->completionList.clear();319 }320 321 const std::string& ShellCompletion::typeToString(CompletionType type)322 {323 switch (type)324 {325 default:// SHELLC_NONE326 return typeNames[0];327 case ClassCompletion:328 return typeNames[1];329 case ObjectCompletion:330 return typeNames[2];331 case FunctionCompletion:332 return typeNames[3];333 case AliasCompletion:334 return typeNames[4];335 }336 }337 338 339 const std::string ShellCompletion::typeNames[] =340 {341 "error",342 "class",343 "object",344 "function",345 "alias"346 }; -
trunk/src/lib/shell/shell_completion_plugin.h
r7373 r7374 1 1 /*! 2 * @file shell_completion.h 3 * @brief The Shell Completion Tasks 4 * 5 * @todo if the second string is a Command, the third should not be completed! 6 * @todo also make some completion for registered (or special) Types 7 */ 2 * @file shell_completion_plugin.h 3 * @brief The Shell Completion Plugin 4 */ 8 5 9 #ifndef _SHELL_COMPLETION_ H10 #define _SHELL_COMPLETION_ H6 #ifndef _SHELL_COMPLETION_PLUGIN_H 7 #define _SHELL_COMPLETION_PLUGIN_H 11 8 9 #include <list> 12 10 #include <vector> 13 #include <list>14 11 #include <string> 15 12 16 // FORWARD DECLARATION 17 class BaseObject; 18 class ShellInput; 19 #ifndef NULL 20 #define NULL 0 //!< a pointer to NULL 21 #endif 13 namespace OrxShell 14 { 15 class ShellCompletor 16 { 17 public: 18 virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) = 0; 19 virtual ~ShellCompletor() { }; 20 21 protected: 22 ShellCompletor(); 23 }; 24 25 class ShellCompletorStringArray : public ShellCompletor 26 { 27 public: 28 ShellCompletorStringArray(const std::string* stringArray, unsigned int size) 29 : _stringArray(stringArray), _size(size) {}; 30 virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin); 31 32 private: 33 const std::string* _stringArray; 34 unsigned int _size; 35 }; 22 36 23 37 24 //! A class for Completing the an InputString. 25 class ShellCompletion 26 { 27 28 //! an enumerator for different types the Shell can complete. 29 typedef enum { 30 NullCompletion = 0, 31 ClassCompletion = 1, 32 ObjectCompletion = 2, 33 FunctionCompletion = 4, 34 AliasCompletion = 8, 35 } CompletionType; 36 37 //! A struct for ShellElements (these are used as containers to identify an Input for what it is) 38 struct CompletionElement 38 //! A Templated Completor 39 template<typename CLASS> class ShellCompletorTList : public ShellCompletor 39 40 { 40 std::string name; //!< the Name of the Element to be completed. 41 CompletionType type; //!< the type of the Element 41 public: 42 ShellCompletorTList(const std::list<CLASS*>& completionList); 43 virtual void addToCompleteList(std::vector<std::string>& completionList, const std::string& completionBegin) 44 {}; 42 45 }; 43 46 44 public: 45 ShellCompletion(); 46 virtual ~ShellCompletion(); 47 48 //! A class for Completing the an InputString. 49 class ShellCompletionPlugin 50 { 51 public: 52 ShellCompletionPlugin(); 47 53 48 54 49 // Functions to produce the Complete Lists. 50 bool autoComplete(std::string& input); 51 bool classComplete(const std::string& classBegin); 52 // long classMatch(const char* input, unsigned int* length); 53 bool objectComplete(const std::string& objectBegin, long classID); 54 // bool objectMatch(const char* objectBegin, long classID, unsigned int* length); 55 bool functionComplete(const std::string& functionBegin, const std::string& className); 56 // bool functionMatch(const char* functionBegin, long classID, unsigned int* length); 57 bool aliasComplete(const std::string& aliasBegin); 55 }; 58 56 59 bool generalComplete(std::string& input, 60 const std::string& begin, const std::string& displayAs = "%s", 61 const std::string& addBack = "", const std::string& addFront = ""); 62 63 64 bool addToCompleteList(const std::list<std::string>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 65 bool addToCompleteList(const std::list<BaseObject*>& inputList, const std::string& completionBegin, ShellCompletion::CompletionType type); 66 void clearCompletionList(); 67 68 69 // Helpers. 70 static const std::string& ShellCompletion::typeToString(ShellCompletion::CompletionType type); 71 72 private: 73 std::vector<CompletionElement> completionList; //!< A list of completions, that are io. 74 75 static const std::string typeNames[]; //!< A list of Completion-Type-Names. 76 }; 77 78 #endif /* _SHELL_COMPLETION_H */ 57 } 58 #endif /* _SHELL_COMPLETION_PLUGIN_H */ -
trunk/src/lib/shell/shell_input.cc
r7343 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_input.h" … … 31 31 32 32 33 using namespace std; 34 35 SHELL_COMMAND(help, ShellInput, help) 36 ->describe("retrieve some help about the input mode") 37 ->setAlias("help"); 38 39 /** 40 * constructor 41 * this also generates a ShellCompletion automatically. 42 */ 43 ShellInput::ShellInput () 44 : Text ("") 33 34 35 36 namespace OrxShell 45 37 { 46 this->pressedKey = SDLK_FIRST; 47 this->setClassID(CL_SHELL_INPUT, "ShellInput"); 48 49 this->inputLine = ""; 50 this->historyIT = this->history.begin(); 51 this->setHistoryLength(50); 52 this->historyScrolling = false; 53 this->delayed = 0; 54 this->setRepeatDelay(.3, .05); 55 56 // subscribe all keyboard commands to ES_SEHLL 57 EventHandler* evh = EventHandler::getInstance(); 58 for (int i = 1; i < SDLK_LAST; i++) 59 { 60 if (!evh->isSubscribed(ES_SHELL, i)) 61 evh->subscribe(this, ES_SHELL, i); 62 } 63 // unsubscribe unused TODO improve. 64 evh->unsubscribe(ES_SHELL, SDLK_BACKQUOTE); 65 evh->unsubscribe(ES_SHELL, SDLK_F12); 66 evh->unsubscribe(ES_SHELL, SDLK_PAGEUP); 67 evh->unsubscribe(ES_SHELL, SDLK_PAGEDOWN); 38 SHELL_COMMAND(help, ShellInput, help) 39 ->describe("retrieve some help about the input mode") 40 ->setAlias("help"); 41 42 43 /** 44 * @brief constructor 45 * this also generates a ShellCompletion automatically. 46 */ 47 ShellInput::ShellInput () 48 : Text ("") 49 { 50 this->pressedKey = SDLK_FIRST; 51 this->setClassID(CL_SHELL_INPUT, "ShellInput"); 52 53 this->inputLine = ""; 54 this->historyIT = this->history.begin(); 55 this->setHistoryLength(50); 56 this->historyScrolling = false; 57 this->delayed = 0; 58 this->setRepeatDelay(.3, .05); 59 60 // subscribe all keyboard commands to ES_SEHLL 61 EventHandler* evh = EventHandler::getInstance(); 62 for (int i = 1; i < SDLK_LAST; i++) 63 { 64 if (!evh->isSubscribed(ES_SHELL, i)) 65 evh->subscribe(this, ES_SHELL, i); 66 } 67 // unsubscribe unused TODO improve. 68 evh->unsubscribe(ES_SHELL, SDLK_BACKQUOTE); 69 evh->unsubscribe(ES_SHELL, SDLK_F12); 70 evh->unsubscribe(ES_SHELL, SDLK_PAGEUP); 71 evh->unsubscribe(ES_SHELL, SDLK_PAGEDOWN); 72 73 } 74 75 /** 76 * @brief standard deconstructor 77 */ 78 ShellInput::~ShellInput () 79 {} 80 81 /** 82 * @brief sets the Repeate-delay and rate 83 * @param repeatDelay the Delay it takes, to repeate a key 84 * @param repeatRate the rate to repeate a pressed key 85 */ 86 void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate) 87 { 88 this->repeatDelay = repeatDelay; 89 this->repeatRate = repeatRate; 90 } 91 92 /** 93 * @brief deletes the InputLine 94 */ 95 void ShellInput::flush() 96 { 97 this->inputLine.clear(); 98 this->setText(this->inputLine); 99 } 100 101 /** 102 * @brief sets the entire text of the InputLine to text 103 * @param text the new Text to set as InputLine 104 */ 105 void ShellInput::setInputText(const std::string& text) 106 { 107 this->inputLine = text; 108 this->setText(this->inputLine); 109 } 110 111 112 /** 113 * @brief adds one character to the inputLine 114 * @param character the character to add to the inputLine 115 */ 116 void ShellInput::addCharacter(char character) 117 { 118 if (this->historyScrolling) 119 { 120 this->history.pop_back(); 121 this->historyScrolling = false; 122 } 123 124 this->inputLine += character; 125 this->setText(this->inputLine); 126 } 127 128 /** 129 * @brief adds multiple Characters to thr inputLine 130 * @param characters a \\0 terminated char-array to add to the InputLine 131 */ 132 void ShellInput::addCharacters(const std::string& characters) 133 { 134 if (this->historyScrolling) 135 { 136 this->history.pop_back(); 137 this->historyScrolling = false; 138 } 139 140 this->inputLine += characters; 141 this->setText(this->inputLine); 142 } 143 144 /** 145 * @brief removes characterCount characters from the InputLine 146 * @param characterCount the count of Characters to remove from the input Line 147 */ 148 void ShellInput::removeCharacters(unsigned int characterCount) 149 { 150 if (this->historyScrolling) 151 { 152 this->history.pop_back(); 153 this->historyScrolling = false; 154 } 155 if (this->inputLine.size() < characterCount) 156 characterCount = this->inputLine.size(); 157 158 this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size()); 159 this->setText(this->inputLine); 160 } 161 162 /** 163 * @brief executes the command stored in the inputLine 164 * @return true if the command was commited successfully, false otherwise 165 */ 166 bool ShellInput::executeCommand() 167 { 168 ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str()); 169 170 if (this->inputLine.empty()) 171 return false; 172 173 ShellCommand::execute(this->inputLine); 174 175 // removing the eventually added Entry (from scrolling) to the List 176 if (this->historyScrolling) 177 { 178 this->history.pop_back(); 179 this->historyScrolling = false; 180 } 181 182 // adding the new Command to the History 183 this->history.push_back(this->inputLine); 184 if (this->history.size() > this->historyLength) 185 { 186 this->history.pop_front(); 187 } 188 189 this->flush(); 190 191 return true; 192 } 193 194 195 /** 196 * @brief moves one entry up in the history. 197 */ 198 void ShellInput::historyMoveUp() 199 { 200 if (!this->historyScrolling) 201 { 202 this->history.push_back(this->inputLine); 203 this->historyScrolling = true; 204 this->historyIT = --this->history.end(); 205 } 206 207 if(this->historyIT != this->history.begin()) 208 { 209 std::string prevElem = *(--this->historyIT); 210 /*if (prevElem == NULL) /// TODO STD 211 return; 212 else */ 213 { 214 this->flush(); 215 this->setInputText(prevElem); 216 } 217 } 218 } 219 220 /** 221 * @brief moves one entry down in the history 222 */ 223 void ShellInput::historyMoveDown() 224 { 225 if (!this->historyScrolling) 226 return; 227 if (!this->history.empty() && this->historyIT != --this->history.end()) 228 { 229 std::string nextElem = *(++this->historyIT); 230 /* if (nextElem == NULL) /// TODO FIX STD 231 return; 232 else */ 233 { 234 this->flush(); 235 this->setInputText(nextElem); 236 } 237 } 238 } 239 240 241 /** 242 * @brief prints out some nice help about the Shell 243 */ 244 void ShellInput::help(const std::string& className, const std::string& functionName) 245 { 246 printf("%s::%s\n", className.c_str(), functionName.c_str()); 247 248 if (className.empty()) 249 { 250 PRINT(0)("Help for the most important Shell-commands\n"); 251 PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n"); 252 PRINT(0)("input order:\n"); 253 PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]] or\n"); 254 PRINT(0)("Alias [parameter]\n"); 255 PRINT(0)("- Also try 'help className'"); 256 } 257 else if (!className.empty() && functionName.empty()) 258 { 259 ShellCommandClass::help(className); 260 //PRINTF(1)("%s::%s\n", className, functionName); 261 } 262 } 263 264 /** 265 * @brief ticks the ShellInput 266 * @param dt the time passed since the last update 267 */ 268 void ShellInput::tick(float dt) 269 { 270 if (this->delayed > 0.0) 271 this->delayed -= dt; 272 else if (this->pressedKey != SDLK_FIRST ) 273 { 274 this->delayed = this->repeatRate; 275 switch (this->pressedKey ) 276 { 277 case SDLK_BACKSPACE: 278 this->removeCharacters(1); 279 break; 280 case SDLK_UP: 281 this->historyMoveUp(); 282 break; 283 case SDLK_DOWN: 284 this->historyMoveDown(); 285 break; 286 default: 287 { 288 if (likely(pressedKey < 127)) 289 this->addCharacter(this->pressedKey); 290 } 291 } 292 } 293 } 294 295 /** 296 * @brief listens for some event 297 * @param event the Event happened 298 */ 299 void ShellInput::process(const Event &event) 300 { 301 if (event.bPressed) 302 { 303 PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type)); 304 if (event.type == SDLK_F1) 305 this->help(); 306 else if (event.type == SDLK_F2) 307 { 308 ;//this->debug(); 309 } 310 else if (event.type == SDLK_UP) 311 { 312 this->historyMoveUp(); 313 this->pressedKey = event.type; 314 } 315 else if (event.type == SDLK_DOWN) 316 { 317 this->historyMoveDown(); 318 this->pressedKey = event.type; 319 } 320 else if (event.type == SDLK_TAB) 321 { 322 this->completion.autoComplete(this->inputLine); 323 this->setText(this->inputLine); 324 } 325 else if (event.type == SDLK_BACKSPACE) 326 { 327 this->delayed = this->repeatDelay; 328 this->pressedKey = SDLK_BACKSPACE; 329 this->removeCharacters(1); 330 } 331 else if (event.type == SDLK_RETURN) 332 { 333 this->executeCommand(); 334 this->pressedKey = event.type; 335 } 336 // any other keyboard key 337 else if (likely(event.type < 127)) 338 { 339 this->addCharacter(event.x); 340 this->pressedKey = event.x; 341 } 342 this->delayed = this->repeatDelay; 343 } 344 else // if(!event.bPressed) 345 { 346 if (this->pressedKey == event.x || this->pressedKey == event.type) 347 { 348 this->pressedKey = 0; 349 this->delayed = 0.0; 350 } 351 } 352 } 68 353 69 354 } 70 71 /**72 * @brief standard deconstructor73 */74 ShellInput::~ShellInput ()75 {76 }77 78 /**79 * @brief sets the Repeate-delay and rate80 * @param repeatDelay the Delay it takes, to repeate a key81 * @param repeatRate the rate to repeate a pressed key82 */83 void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)84 {85 this->repeatDelay = repeatDelay;86 this->repeatRate = repeatRate;87 }88 89 /**90 * @brief deletes the InputLine91 */92 void ShellInput::flush()93 {94 this->inputLine.clear();95 this->setText(this->inputLine);96 }97 98 /**99 * @brief sets the entire text of the InputLine to text100 * @param text the new Text to set as InputLine101 */102 void ShellInput::setInputText(const std::string& text)103 {104 this->inputLine = text;105 this->setText(this->inputLine);106 }107 108 109 /**110 * @brief adds one character to the inputLine111 * @param character the character to add to the inputLine112 */113 void ShellInput::addCharacter(char character)114 {115 if (this->historyScrolling)116 {117 this->history.pop_back();118 this->historyScrolling = false;119 }120 121 this->inputLine += character;122 this->setText(this->inputLine);123 }124 125 /**126 * @brief adds multiple Characters to thr inputLine127 * @param characters a \\0 terminated char-array to add to the InputLine128 */129 void ShellInput::addCharacters(const std::string& characters)130 {131 if (this->historyScrolling)132 {133 this->history.pop_back();134 this->historyScrolling = false;135 }136 137 this->inputLine += characters;138 this->setText(this->inputLine);139 }140 141 /**142 * @brief removes characterCount characters from the InputLine143 * @param characterCount the count of Characters to remove from the input Line144 */145 void ShellInput::removeCharacters(unsigned int characterCount)146 {147 if (this->historyScrolling)148 {149 this->history.pop_back();150 this->historyScrolling = false;151 }152 if (this->inputLine.size() < characterCount)153 characterCount = this->inputLine.size();154 155 this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size());156 this->setText(this->inputLine);157 }158 159 /**160 * @brief executes the command stored in the inputLine161 * @return true if the command was commited successfully, false otherwise162 */163 bool ShellInput::executeCommand()164 {165 ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str());166 167 if (this->inputLine.empty())168 return false;169 170 ShellCommand::execute(this->inputLine);171 172 // removing the eventually added Entry (from scrolling) to the List173 if (this->historyScrolling)174 {175 this->history.pop_back();176 this->historyScrolling = false;177 }178 179 // adding the new Command to the History180 this->history.push_back(this->inputLine);181 if (this->history.size() > this->historyLength)182 {183 this->history.pop_front();184 }185 186 this->flush();187 188 return true;189 }190 191 192 /**193 * @brief moves one entry up in the history.194 */195 void ShellInput::historyMoveUp()196 {197 if (!this->historyScrolling)198 {199 this->history.push_back(this->inputLine);200 this->historyScrolling = true;201 this->historyIT = --this->history.end();202 }203 204 if(this->historyIT != this->history.begin())205 {206 std::string prevElem = *(--this->historyIT);207 /*if (prevElem == NULL) /// TODO STD208 return;209 else */210 {211 this->flush();212 this->setInputText(prevElem);213 }214 }215 }216 217 /**218 * @brief moves one entry down in the history219 */220 void ShellInput::historyMoveDown()221 {222 if (!this->historyScrolling)223 return;224 if (!this->history.empty() && this->historyIT != --this->history.end())225 {226 std::string nextElem = *(++this->historyIT);227 /* if (nextElem == NULL) /// TODO FIX STD228 return;229 else */230 {231 this->flush();232 this->setInputText(nextElem);233 }234 }235 }236 237 238 /**239 * @brief prints out some nice help about the Shell240 */241 void ShellInput::help(const std::string& className, const std::string& functionName)242 {243 printf("%s::%s\n", className.c_str(), functionName.c_str());244 245 if (className.empty())246 {247 PRINT(0)("Help for the most important Shell-commands\n");248 PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");249 PRINT(0)("input order:\n");250 PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]] or\n");251 PRINT(0)("Alias [parameter]\n");252 PRINT(0)("- Also try 'help className'");253 }254 else if (!className.empty() && functionName.empty())255 {256 ShellCommandClass::help(className);257 //PRINTF(1)("%s::%s\n", className, functionName);258 }259 }260 261 /**262 * @brief ticks the ShellInput263 * @param dt the time passed since the last update264 */265 void ShellInput::tick(float dt)266 {267 if (this->delayed > 0.0)268 this->delayed -= dt;269 else if (this->pressedKey != SDLK_FIRST )270 {271 this->delayed = this->repeatRate;272 switch (this->pressedKey )273 {274 case SDLK_BACKSPACE:275 this->removeCharacters(1);276 break;277 case SDLK_UP:278 this->historyMoveUp();279 break;280 case SDLK_DOWN:281 this->historyMoveDown();282 break;283 default:284 {285 if (likely(pressedKey < 127))286 this->addCharacter(this->pressedKey);287 }288 }289 }290 }291 292 /**293 * @brief listens for some event294 * @param event the Event happened295 */296 void ShellInput::process(const Event &event)297 {298 if (event.bPressed)299 {300 PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));301 if (event.type == SDLK_F1)302 this->help();303 else if (event.type == SDLK_F2)304 {305 ;//this->debug();306 }307 else if (event.type == SDLK_UP)308 {309 this->historyMoveUp();310 this->pressedKey = event.type;311 }312 else if (event.type == SDLK_DOWN)313 {314 this->historyMoveDown();315 this->pressedKey = event.type;316 }317 else if (event.type == SDLK_TAB)318 {319 this->completion.autoComplete(this->inputLine);320 this->setText(this->inputLine);321 }322 else if (event.type == SDLK_BACKSPACE)323 {324 this->delayed = this->repeatDelay;325 this->pressedKey = SDLK_BACKSPACE;326 this->removeCharacters(1);327 }328 else if (event.type == SDLK_RETURN)329 {330 this->executeCommand();331 this->pressedKey = event.type;332 }333 // any other keyboard key334 else if (likely(event.type < 127))335 {336 this->addCharacter(event.x);337 this->pressedKey = event.x;338 }339 this->delayed = this->repeatDelay;340 }341 else // if(!event.bPressed)342 {343 if (this->pressedKey == event.x || this->pressedKey == event.type)344 {345 this->pressedKey = 0;346 this->delayed = 0.0;347 }348 }349 } -
trunk/src/lib/shell/shell_input.h
r7343 r7374 16 16 #include <list> 17 17 18 // FORWARD DECLARATION 19 class ShellCompletion; 18 namespace OrxShell 19 { 20 // FORWARD DECLARATION 21 class ShellCompletion; 20 22 21 //! An InputLine for the Shell 22 /** 23 * The ShellInput has the ability to catch and display user input. 24 * The ShellInput is auto-completed after the user presses [TAB] 25 * The ShellInput is executed (and sent back to the Application) on Pressing [ENTER] 26 * [UP] and [DOWN] move through the history of allready given commands. 27 */ 28 class ShellInput : public Text, public EventListener { 23 //! An InputLine for the Shell 24 /** 25 * The ShellInput has the ability to catch and display user input. 26 * The ShellInput is auto-completed after the user presses [TAB] 27 * The ShellInput is executed (and sent back to the Application) on Pressing [ENTER] 28 * [UP] and [DOWN] move through the history of allready given commands. 29 */ 30 class ShellInput : public Text, public EventListener 31 { 29 32 30 public:31 ShellInput();32 virtual ~ShellInput();33 public: 34 ShellInput(); 35 virtual ~ShellInput(); 33 36 34 /** @returns the inputLine */35 const std::string& getInput() const { return this->inputLine; };37 /** @returns the inputLine */ 38 const std::string& getInput() const { return this->inputLine; }; 36 39 37 // InputLine38 void flush();39 void setInputText(const std::string& text);40 void addCharacter(char character);41 void addCharacters(const std::string& characters);42 void removeCharacters(unsigned int characterCount = 1);43 void setRepeatDelay(float repeatDelay, float repeatRate);44 bool executeCommand();40 // InputLine 41 void flush(); 42 void setInputText(const std::string& text); 43 void addCharacter(char character); 44 void addCharacters(const std::string& characters); 45 void removeCharacters(unsigned int characterCount = 1); 46 void setRepeatDelay(float repeatDelay, float repeatRate); 47 bool executeCommand(); 45 48 46 /** sets the count of the History's entries */47 void setHistoryLength(unsigned int historyLength) { this->historyLength = historyLength; };48 void historyMoveUp();49 void historyMoveDown();49 /** sets the count of the History's entries */ 50 void setHistoryLength(unsigned int historyLength) { this->historyLength = historyLength; }; 51 void historyMoveUp(); 52 void historyMoveDown(); 50 53 51 void help(const std::string& className = "", const std::string& function = "");54 void help(const std::string& className = "", const std::string& function = ""); 52 55 53 virtual void tick(float dt);54 virtual void process(const Event &event);56 virtual void tick(float dt); 57 virtual void process(const Event &event); 55 58 56 private:59 private: 57 60 // HANDLING TEXT INPUT 58 ShellCompletion completion; //!< The Completion Interface.61 ShellCompletion completion; //!< The Completion Interface. 59 62 60 std::string inputLine; //!< the Char-Array of the Buffer61 float repeatRate; //!< The Repeat-Delay.62 float repeatDelay; //!< The delay of the first Character of a given Character.63 float delayed; //!< how much of the delay is remaining.64 Uint16 pressedKey; //!< the pressed key that will be repeated.63 std::string inputLine; //!< the Char-Array of the Buffer 64 float repeatRate; //!< The Repeat-Delay. 65 float repeatDelay; //!< The delay of the first Character of a given Character. 66 float delayed; //!< how much of the delay is remaining. 67 Uint16 pressedKey; //!< the pressed key that will be repeated. 65 68 66 std::list<std::string> history; //!< The history of given commands. 67 std::list<std::string>::iterator historyIT; //!< The locator that tells us, where we are in the history. 68 unsigned int historyLength; //!< The maximum length of the InputHistory. 69 bool historyScrolling; //!< true if we are scrolling through the history. 70 }; 69 std::list<std::string> history; //!< The history of given commands. 70 std::list<std::string>::iterator historyIT; //!< The locator that tells us, where we are in the history. 71 unsigned int historyLength; //!< The maximum length of the InputHistory. 72 bool historyScrolling; //!< true if we are scrolling through the history. 73 }; 74 75 } 71 76 72 77 #endif /* _SHELL_INPUT_H */
Note: See TracChangeset
for help on using the changeset viewer.