Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 7374 in orxonox.OLD for trunk/src/lib/shell


Ignore:
Timestamp:
Apr 26, 2006, 3:28:55 AM (19 years ago)
Author:
bensch
Message:

orxonox/trunk: added new Files shell_completion_plugin for the new Plugin Structure.
Also created the first namespace: OrxShell

Location:
trunk/src/lib/shell
Files:
13 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/shell/Makefile.am

    r5639 r7374  
    44noinst_LIBRARIES = libORXshell.a
    55
    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
     6libORXshell_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
    1214
    1315
    14 noinst_HEADERS= shell.h \
     16noinst_HEADERS= \
     17                shell.h \
    1518                shell_buffer.h \
    1619                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  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell.h"
     
    3333#include <stdio.h>
    3434
    35 using namespace std;
     35namespace OrxShell
     36{
    3637
    3738SHELL_COMMAND(clear, Shell, clear)
     
    132133  this->setRelCoorSoft2D(0, 0, 5);
    133134
    134   list<std::string>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer().end();
     135  std::list<std::string>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer().end();
    135136  bool top = false;
    136137  for (std::list<Text*>::iterator text = this->bufferText.begin(); text != this->bufferText.end(); ++text)
     
    378379  }
    379380  // redisplay the buffers
    380   list<std::string>::const_iterator it = this->bufferIterator;
     381  std::list<std::string>::const_iterator it = this->bufferIterator;
    381382  if (it == ShellBuffer::getInstance()->getBuffer().end())
    382383  {
     
    518519//   PRINTF(3)("This is the Test for one String '%s' and one Float '%f'\n",s , f);
    519520// }
     521
     522}
  • trunk/src/lib/shell/shell.h

    r7341 r7374  
    2424class Material;
    2525
    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 {
     26namespace 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  {
    4548
    4649  public:
     
    104107    int                         bufferOffset;           //!< how many lines from the bottom up we display the Buffer.
    105108    std::list<std::string>::const_iterator  bufferIterator;         //!< used to move through and print the Buffer
    106 };
     109  };
     110
     111}
    107112
    108113#endif /* _SHELL_H */
  • trunk/src/lib/shell/shell_buffer.cc

    r7316 r7374  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell_buffer.h"
     
    2222#include "stdlibincl.h"
    2323
    24 using namespace std;
     24namespace OrxShell
     25{
    2526
    2627
     
    189190  PRINT(3)("Debugging output to console (not this shell)\n");
    190191
    191   list<std::string>::const_iterator bufferLine;
     192  std::list<std::string>::const_iterator bufferLine;
    192193  for (bufferLine = this->buffer.begin(); bufferLine != this->buffer.end(); bufferLine++)
    193194    printf((*bufferLine).c_str());
    194195}
     196
     197}
  • trunk/src/lib/shell/shell_buffer.h

    r7329 r7374  
    1414#define      SHELL_BUFFER_SIZE       16384         //!< The Size of the input-buffers (should be large enough to carry any kind of input)
    1515
    16 // FORWARD DECLARATION
    17 class Shell;
     16namespace OrxShell
     17{
     18  // FORWARD DECLARATION
     19  class Shell;
    1820
    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  {
    2224
    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 */
     30inline static bool isInstanciated() { return (ShellBuffer::singletonRef == NULL)?false:true; };
    2531
    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);
    3234
    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; };
    3545
    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;
    4847
    4948  private:
     
    6362
    6463    static SDL_mutex*        bufferMutex;                        //!< Only one thread may write into the ShellBuffer at a time.
    65 };
     64  };
     65
     66}
    6667
    6768#endif /* _SHELL_BUFFER_H */
  • trunk/src/lib/shell/shell_command.cc

    r7340 r7374  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell_command.h"
     
    2828#include <string.h>
    2929
    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)
     30namespace OrxShell
    3931{
    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    {
    86125      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;
    93133      for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++)
    94134      {
    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)
    246186            {
    247               (*(*cmdIT)->executor)(objectPointer, inputSplits.getSubSet(fktPos+1).join()); /// TODO CHECK IF OK
     187              (*(*alias)->getCommand()->executor)(objectList->front(), inputSplits.getSubSet(1).join()); /// TODO CHECK IF OK
    248188              return true;
    249189            }
    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
    256361}
    257 
    258 /**
    259  * lets a command be described
    260  * @param description the description of the Given command
    261  */
    262 ShellCommand* ShellCommand::describe(const std::string& description)
    263 {
    264   if (this == NULL)
    265     return NULL;
    266   else
    267   {
    268     this->description = description;
    269     return this;
    270   }
    271 }
    272 
    273 /**
    274  * adds an Alias to this Command
    275  * @param alias the name of the Alias to set
    276  * @returns itself
    277  */
    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   else
    288   {
    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 executor
    301  * @param value0 the first default value
    302  * @param value1 the second default value
    303  * @param value2 the third default value
    304  * @param value3 the fourth default value
    305  * @param value4 the fifth default value
    306  */
    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 Commands
    321  */
    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       /// FIXME
    340       /*      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 String
    352  * @param parameter the Parameter we have.
    353  * @returns the Name of the Parameter at Hand
    354  */
    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  
    1616
    1717
    18 // FORWARD DECLARATION
    19 class ShellCommandClass;
    20 class ShellCommandAlias;
     18namespace OrxShell
     19{
     20  // FORWARD DECLARATION
     21  class ShellCommandClass;
     22  class ShellCommandAlias;
    2123
    22 /**
    23  * an easy to use Macro to create a Command
    24  * @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 call
    27  *
    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)
    3739#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))
    3941
    40 /**
    41  * an easy to use Macro to create a Command
    42  * @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 call
    45  *
    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   */
    5355#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))
    5557
    5658
    5759
    58 //! a baseClass for all possible ShellCommands
    59 class ShellCommand : public BaseObject
    60 {
    61   friend class ShellCommandClass;
     60  //! a baseClass for all possible ShellCommands
     61  class ShellCommand : public BaseObject
     62  {
     63    friend class ShellCommandClass;
    6264  public:
    6365    static bool execute (const std::string& executionString);
     
    8991    Executor*                        executor;                             //!< The Executor, that really executes the Function.
    9092
    91 };
     93  };
    9294
    93 //! A Class, that handles aliases.
    94 class ShellCommandAlias
    95 {
    96   friend class ShellCommand;
     95  //! A Class, that handles aliases.
     96  class ShellCommandAlias
     97  {
     98    friend class ShellCommand;
    9799  public:
    98100    /** @returns the Name of the Alias. */
     
    108110    std::string     aliasName;       //!< the name of the Alias
    109111    ShellCommand*   command;         //!< a pointer to the command, this alias executes.
    110 };
     112  };
     113
     114}
    111115
    112116#endif /* _SHELL_COMMAND_H */
  • trunk/src/lib/shell/shell_command_class.cc

    r7221 r7374  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell_command_class.h"
     
    2727#include <string.h>
    2828
    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)
     29namespace OrxShell
    4030{
    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
    109162    std::list<ShellCommandClass*>::iterator classIT;
    110163    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
    125221}
    126 
    127 /**
    128  * checks if a Class is already registered to the Commands' class-stack
    129  * @param className the Name of the Class to check for
    130  * @returns the CommandClass if found, NULL otherwise
    131  */
    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 CommandClass
    153  * @param className the name of the CommandClass
    154  * @returns the CommandClass if found, or a new CommandClass if not
    155  */
    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 ShellCommandClass
    186  * @param className: the Class of Commands to show help about
    187  */
    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           /// FIXME
    203           /*          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   else
    215   {
    216     PRINTF(1)("List of commandClasses does not exist");
    217   }
    218 }
    219 
  • trunk/src/lib/shell/shell_command_class.h

    r7221 r7374  
    1111
    1212
    13 // FORWARD DECLARATION
     13namespace OrxShell
     14{
     15  // FORWARD DECLARATION
     16  class ShellCommand;
     17  class ShellCommandAlias;
    1418
    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;
    2523
    2624  public:
     
    4846    static std::list<ShellCommandClass*>*  commandClassList;          //!< A list of Classes
    4947    static std::list<ShellCommandAlias*>*  aliasList;                 //!< An Alias to A Command. (only for classes with one Instance)
    50 };
     48  };
     49
     50}
    5151
    5252#endif /* _SHELL_COMMAND_H */
  • trunk/src/lib/shell/shell_completion.cc

    r7373 r7374  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell_completion.h"
    1919#include "shell_command_class.h"
    2020
    21 #include "shell_input.h"
    2221#include "shell_command.h"
    2322
     
    2625#include "debug.h"
    2726
    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)
     27namespace OrxShell
    5128{
    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)
    9898      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    }
    106137    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
    122348}
    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   }
    137   else
    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 };
  • trunk/src/lib/shell/shell_completion.h

    r7373 r7374  
    1616// FORWARD DECLARATION
    1717class BaseObject;
    18 class ShellInput;
    19 #ifndef NULL
    20 #define NULL 0            //!< a pointer to NULL
    21 #endif
     18
     19namespace 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();
    2243
    2344
    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);
    2754
    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 = "");
    3658
    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.
    4272  };
    4373
    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}
    7775
    7876#endif /* _SHELL_COMPLETION_H */
  • trunk/src/lib/shell/shell_completion_plugin.cc

    r7373 r7374  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    18 #include "shell_completion.h"
     18#include "shell_completion_plugin.h"
    1919#include "shell_command_class.h"
    2020
    21 #include "shell_input.h"
    2221#include "shell_command.h"
    2322
     
    2625#include "debug.h"
    2726
    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 { }
     27namespace OrxShell
     28{
    4229
    4330
    4431
    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.
     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};
    5340
    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       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     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   }
    137   else
    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 };
  • trunk/src/lib/shell/shell_completion_plugin.h

    r7373 r7374  
    11/*!
    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 */
    85
    9 #ifndef _SHELL_COMPLETION_H
    10 #define _SHELL_COMPLETION_H
     6#ifndef _SHELL_COMPLETION_PLUGIN_H
     7#define _SHELL_COMPLETION_PLUGIN_H
    118
     9#include <list>
    1210#include <vector>
    13 #include <list>
    1411#include <string>
    1512
    16 // FORWARD DECLARATION
    17 class BaseObject;
    18 class ShellInput;
    19 #ifndef NULL
    20 #define NULL 0            //!< a pointer to NULL
    21 #endif
     13namespace 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  };
    2236
    2337
    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
    3940  {
    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    {};
    4245  };
    4346
    44 public:
    45   ShellCompletion();
    46   virtual ~ShellCompletion();
     47
     48  //! A class for Completing the an InputString.
     49  class ShellCompletionPlugin
     50  {
     51  public:
     52    ShellCompletionPlugin();
    4753
    4854
    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  };
    5856
    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  
    1414*/
    1515
    16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
     16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SHELL
    1717
    1818#include "shell_input.h"
     
    3131
    3232
    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
     36namespace OrxShell
    4537{
    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  }
    68353
    69354}
    70 
    71 /**
    72  * @brief standard deconstructor
    73  */
    74 ShellInput::~ShellInput ()
    75 {
    76 }
    77 
    78 /**
    79  * @brief sets the Repeate-delay and rate
    80  * @param repeatDelay the Delay it takes, to repeate a key
    81  * @param repeatRate the rate to repeate a pressed key
    82  */
    83 void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
    84 {
    85   this->repeatDelay = repeatDelay;
    86   this->repeatRate = repeatRate;
    87 }
    88 
    89 /**
    90  * @brief deletes the InputLine
    91  */
    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 text
    100  * @param text the new Text to set as InputLine
    101  */
    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 inputLine
    111  * @param character the character to add to the inputLine
    112  */
    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 inputLine
    127  * @param characters a \\0 terminated char-array to add to the InputLine
    128  */
    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 InputLine
    143  * @param characterCount the count of Characters to remove from the input Line
    144  */
    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 inputLine
    161  * @return true if the command was commited successfully, false otherwise
    162  */
    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 List
    173   if (this->historyScrolling)
    174   {
    175     this->history.pop_back();
    176     this->historyScrolling = false;
    177   }
    178 
    179   // adding the new Command to the History
    180   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 STD
    208       return;
    209     else */
    210     {
    211       this->flush();
    212       this->setInputText(prevElem);
    213     }
    214   }
    215 }
    216 
    217 /**
    218  * @brief moves one entry down in the history
    219  */
    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 STD
    228       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 Shell
    240  */
    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 ShellInput
    263  * @param dt the time passed since the last update
    264  */
    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 event
    294  * @param event the Event happened
    295  */
    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 key
    334     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  
    1616#include <list>
    1717
    18 // FORWARD DECLARATION
    19 class ShellCompletion;
     18namespace OrxShell
     19{
     20  // FORWARD DECLARATION
     21  class ShellCompletion;
    2022
    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  {
    2932
    30  public:
    31   ShellInput();
    32   virtual ~ShellInput();
     33  public:
     34    ShellInput();
     35    virtual ~ShellInput();
    3336
    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; };
    3639
    37   // InputLine
    38   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();
    4548
    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();
    5053
    51   void help(const std::string& className = "", const std::string& function = "");
     54    void help(const std::string& className = "", const std::string& function = "");
    5255
    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);
    5558
    56  private:
     59  private:
    5760    // HANDLING TEXT INPUT
    58    ShellCompletion                   completion;       //!< The Completion Interface.
     61    ShellCompletion                   completion;       //!< The Completion Interface.
    5962
    60    std::string                       inputLine;        //!< the Char-Array of the Buffer
    61    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.
    6568
    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}
    7176
    7277#endif /* _SHELL_INPUT_H */
Note: See TracChangeset for help on using the changeset viewer.