Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 5639 in orxonox.OLD for trunk/src/lib/shell/shell_command_class.cc


Ignore:
Timestamp:
Nov 18, 2005, 7:21:32 PM (18 years ago)
Author:
bensch
Message:

orxonox/trunk: splitted shell_command into shell_command and shell_command_class

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/lib/shell/shell_command_class.cc

    r5637 r5639  
    1616//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
    1717
     18#include "shell_command_class.h"
     19
    1820#include "shell_command.h"
    1921
     
    2224#include "class_list.h"
    2325
    24 #include "key_names.h"
    25 #include <stdarg.h>
    2626#include <stdio.h>
    2727#include <string.h>
    2828
    2929using namespace std;
     30
     31tList<ShellCommandClass>* ShellCommandClass::commandClassList = NULL;
     32tList<ShellCommandAlias>* ShellCommandClass::aliasList = NULL;
    3033
    3134/**
     
    259262}
    260263
    261 tList<ShellCommandClass>* ShellCommandClass::commandClassList = NULL;
    262 tList<ShellCommandAlias>* ShellCommandClass::aliasList = NULL;
    263 
    264 
    265 
    266 
    267 
    268 
    269 
    270 
    271 
    272 
    273 ////////////////////////
    274 // SHELL COMMAND BASE //
    275 ////////////////////////
    276 /**
    277  * constructs and registers a new Command
    278  * @param commandName the name of the Command
    279  * @param className the name of the class to apply this command to
    280  * @param paramCount the count of parameters this command takes
    281  */
    282 ShellCommand::ShellCommand(const char* commandName, const char* className, Executor* executor)
    283 {
    284   this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
    285   this->setName(commandName);
    286   this->description = NULL;
    287   this->alias = NULL;
    288 
    289 //  this->classID = classID;
    290   this->shellClass = ShellCommandClass::getCommandClass(className); //ClassList::IDToString(classID);
    291   if (this->shellClass != NULL)
    292     this->shellClass->commandList->add(this);
    293   // handling parameters, and storing them:
    294   if (paramCount > FUNCTOR_MAX_ARGUMENTS)
    295     paramCount = FUNCTOR_MAX_ARGUMENTS;
    296   this->paramCount = paramCount;
    297   this->parameters = new unsigned int[paramCount];
    298   this->defaultValue = new MultiType[paramCount];
    299 
    300   this->executor = executor;
    301 }
    302 
    303 /**
    304  * deconstructs a ShellCommand
    305  */
    306 ShellCommand::~ShellCommand()
    307 {
    308   delete[] this->parameters;
    309   delete[] this->defaultValue;
    310   if (this->alias != NULL && ShellCommandClass::aliasList != NULL)
    311   {
    312     ShellCommandClass::aliasList->remove(this->alias);
    313     delete this->alias;
    314   }
    315 }
    316 
    317 /**
    318  * registers a new ShellCommand
    319  */
    320 ShellCommand* ShellCommand::registerCommand(const char* commandName, const char* className, Executor* executor)
    321 {
    322   if (ShellCommand::isRegistered(commandName, className, executor))
    323     return NULL;
    324   else
    325     return new ShellCommand(commandName, className, executor);
    326 
    327 }
    328 
    329 
    330 
    331 
    332 /**
    333  * unregister an existing commandName
    334  * @param className the name of the Class the command belongs to.
    335  * @param commandName the name of the command itself
    336  */
    337 void ShellCommand::unregisterCommand(const char* commandName, const char* className)
    338 {
    339   if (ShellCommandClass::commandClassList == NULL)
    340     ShellCommandClass::initCommandClassList();
    341 
    342  const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
    343 
    344  if (checkClass != NULL)
    345   {
    346     tIterator<ShellCommand>* iterator = checkClass->commandList->getIterator();
    347     ShellCommand* elem = iterator->firstElement();
    348     while(elem != NULL)
    349     {
    350       if (!strcmp(commandName, elem->getName()))
    351       {
    352         checkClass->commandList->remove(elem);
    353         delete elem;
    354         break;
    355       }
    356       elem = iterator->nextElement();
    357     }
    358     delete iterator;
    359 
    360     if (checkClass->commandList->getSize() == 0)
    361     {
    362       ShellCommandClass::commandClassList->remove(checkClass);
    363       delete checkClass;
    364     }
    365   }
    366 }
    367 
    368 /**
    369  * checks if a command has already been registered.
    370  * @param commandName the name of the Command
    371  * @param className the name of the Class the command should apply to.
    372  * @param paramCount how many arguments the Command takes
    373  * @returns true, if the command is registered/false otherwise
    374  *
    375  * This is used internally, to see, if we have multiple command subscriptions.
    376  * This is checked in the registerCommand-function.
    377  */
    378 bool ShellCommand::isRegistered(const char* commandName, const char* className, Executor* executor)
    379 {
    380   if (ShellCommandClass::commandClassList == NULL)
    381   {
    382     ShellCommandClass::initCommandClassList();
    383     return false;
    384   }
    385 
    386   const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
    387   if (checkClass != NULL)
    388   {
    389     tIterator<ShellCommand>* iterator = checkClass->commandList->getIterator();
    390     ShellCommand* elem = iterator->firstElement();
    391     while(elem != NULL)
    392    {
    393      if (!strcmp(commandName, elem->getName()))
    394      {
    395        PRINTF(2)("Command already registered\n");
    396        delete iterator;
    397        return true;
    398       }
    399      elem = iterator->nextElement();
    400    }
    401    delete iterator;
    402    return false;
    403   }
    404   else
    405     return false;
    406 }
    407 
    408 
    409 /**
    410  * executes commands
    411  * @param executionString the string containing the following input
    412  * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
    413  * @return true on success, false otherwise.
    414  */
    415 bool ShellCommand::execute(const char* executionString)
    416 {
    417   if (ShellCommandClass::commandClassList == NULL)
    418     return false;
    419 
    420   long classID = CL_NULL;                 //< the classID retrieved from the Class.
    421   ShellCommandClass* commandClass = NULL; //< the command class this command applies to.
    422   tList<BaseObject>* objectList = NULL;   //< the list of Objects stored in classID
    423   BaseObject* objectPointer = NULL;       //< a pointer to th Object to Execute the command on
    424   bool emptyComplete = false;             //< if the completion input is empty string. e.g ""
    425   unsigned int fktPos = 1;                //< the position of the function (needed for finding it)
    426 //  long completeType = SHELLC_NONE;      //< the Type we'd like to complete.
    427   SubString inputSplits(executionString, true);
    428 
    429   if (inputSplits.getCount() == 0)
    430     return false;
    431   if (inputSplits.getCount() >= 1)
    432   {
    433     // CHECK FOR ALIAS
    434     if (ShellCommandClass::aliasList != NULL)
    435     {
    436       tIterator<ShellCommandAlias>* itAL = ShellCommandClass::aliasList->getIterator();
    437       ShellCommandAlias* elemAL = itAL->firstElement();
    438       while(elemAL != NULL)
    439       {
    440         if (elemAL->getName() != NULL && !strcmp(elemAL->getName(), inputSplits.getString(0)) && elemAL->getCommand() != NULL &&
    441             elemAL->getCommand()->shellClass != NULL )
    442         {
    443           objectList = ClassList::getList(elemAL->getCommand()->shellClass->getName());
    444           if (objectList != NULL)
    445           {
    446             if (inputSplits.getCount() > 1)
    447               elemAL->getCommand()->executor->execute(objectList->firstElement(), executionString+inputSplits.getOffset(1));
    448             else
    449               elemAL->getCommand()->executor->execute(objectList->firstElement(), "");
    450             delete itAL;
    451             return true;
    452           }
    453         }
    454         elemAL = itAL->nextElement();
    455       }
    456       delete itAL;
    457     }
    458     // looking for a Matching Class
    459     if (likely(ShellCommandClass::commandClassList != NULL))
    460     {
    461       tIterator<ShellCommandClass>* itCL = ShellCommandClass::commandClassList->getIterator();
    462       ShellCommandClass* elemCL = itCL->firstElement();
    463       while(elemCL != NULL)
    464       {
    465         if (elemCL->getName() && !strcasecmp(inputSplits.getString(0), elemCL->getName()))
    466         {
    467           //elemCL->getName();
    468           classID = ClassList::StringToID(elemCL->getName());
    469           commandClass = elemCL;
    470           objectList = ClassList::getList(classID);
    471           break;
    472         }
    473         elemCL = itCL->nextElement();
    474       }
    475       delete itCL;
    476     }
    477 
    478     if (commandClass != NULL && inputSplits.getCount() >= 2)
    479     {
    480       if (objectList != NULL)
    481       {
    482         // Checking for a Match in the Objects of classID (else take the first)
    483         tIterator<BaseObject>* itBO = objectList->getIterator();
    484         BaseObject* enumBO = itBO->firstElement();
    485         while(enumBO)
    486         {
    487           if (enumBO->getName() != NULL && !strcasecmp(enumBO->getName(), inputSplits.getString(1)))
    488           {
    489             objectPointer = enumBO;
    490             fktPos = 2;
    491             break;
    492           }
    493           enumBO = itBO->nextElement();
    494          }
    495          delete itBO;
    496 
    497       //
    498         if (objectPointer == NULL)
    499           objectPointer = objectList->firstElement();
    500       }
    501       // match a function.
    502       if (commandClass != NULL && (fktPos == 1 || (fktPos == 2 && inputSplits.getCount() >= 3)))
    503       {
    504         tIterator<ShellCommand>* itCMD = commandClass->commandList->getIterator();
    505         ShellCommand* enumCMD = itCMD->firstElement();
    506         while (enumCMD != NULL)
    507         {
    508           if (!strcmp(enumCMD->getName(), inputSplits.getString(fktPos)))
    509           {
    510             if (objectPointer == NULL && enumCMD->functorType == ShellCommand_Objective)
    511             {
    512               delete itCMD;
    513               return false;
    514             }
    515             if (inputSplits.getCount() > fktPos+1)
    516               enumCMD->executor->execute(objectPointer, executionString+inputSplits.getOffset(fktPos +1));
    517             else
    518               enumCMD->executor->execute(objectPointer, "");
    519             delete itCMD;
    520             return true;
    521           }
    522 
    523           enumCMD = itCMD->nextElement();
    524         }
    525         delete itCMD;
    526       }
    527     }
    528   }
    529 }
    530 
    531 /**
    532  * lets a command be described
    533  * @param description the description of the Given command
    534  */
    535 ShellCommand* ShellCommand::describe(const char* description)
    536 {
    537   if (this == NULL)
    538     return NULL;
    539  else
    540  {
    541    this->description = description;
    542    return this;
    543  }
    544 }
    545 
    546 /**
    547  * adds an Alias to this Command
    548  * @param alias the name of the Alias to set
    549  * @returns itself
    550  */
    551 ShellCommand* ShellCommand::setAlias(const char* alias)
    552 {
    553   if (this == NULL)
    554     return NULL;
    555 
    556   if (this->alias != NULL)
    557   {
    558     PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getName(), this->shellClass->getName());
    559   }
    560   else
    561   {
    562     if (ShellCommandClass::aliasList == NULL)
    563       ShellCommandClass::aliasList = new tList<ShellCommandAlias>;
    564 
    565     ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this);
    566     ShellCommandClass::aliasList->add(aliasCMD);
    567     this->alias = aliasCMD;
    568   }
    569   return this;
    570 }
    571 
    572 /**
    573  * sets default Values of the Commands
    574  * @param count how many default Values to set.
    575  * @param ... the default Values in order. They will be cast to the right type
    576  * @returns itself
    577  *
    578  * Be aware, that when you use this Function, you !!MUST!! match the input as
    579  * count, [EXACTLY THE SAME AS IF YOU WOULD CALL THE FUNCTION UP TO count ARGUMENTS]
    580  */
    581 ShellCommand* ShellCommand::defaultValues(unsigned int count, ...)
    582 {
    583   if (this == NULL)
    584     return NULL;
    585   if (count == 0)
    586     return this;
    587   if (count > this->paramCount)
    588     count = this->paramCount;
    589 
    590   va_list defaultList;
    591   va_start(defaultList, count);
    592 
    593   for (unsigned int i = 0; i < count; i++)
    594   {
    595 
    596 
    597     switch (this->parameters[i])
    598     {
    599       case MT_BOOL:
    600         this->defaultValue[i].setInt(va_arg(defaultList, int));
    601         break;
    602       case MT_CHAR:
    603         this->defaultValue[i].setChar((char)va_arg(defaultList, int));
    604         break;
    605       case MT_STRING:
    606         this->defaultValue[i].setString(va_arg(defaultList, char*));
    607         break;
    608       case MT_INT:
    609         this->defaultValue[i].setInt(va_arg(defaultList, int));
    610         break;
    611 /*      case MT_UINT:
    612         this->defaultValue[i].setInt((int)va_arg(defaultList, unsigned int));
    613         break;*/
    614       case MT_FLOAT:
    615         this->defaultValue[i].setFloat(va_arg(defaultList, double));
    616         break;
    617 /*      case MT_LONG:
    618         this->defaultValue[i].setInt((int) va_arg(defaultList, long));
    619         break;*/
    620       default:
    621         break;
    622     }
    623   }
    624   return this;
    625 }
    626 
    627 /**
    628  * prints out nice information about the Shells Commands
    629  */
    630 void ShellCommand::debug()
    631 {
    632   if (ShellCommandClass::commandClassList == NULL)
    633   {
    634     PRINT(0)("No Command registered.\n");
    635     return;
    636   }
    637 
    638   tIterator<ShellCommandClass>* iteratorCL = ShellCommandClass::commandClassList->getIterator();
    639   ShellCommandClass* elemCL = iteratorCL->firstElement();
    640   while(elemCL != NULL)
    641   {
    642     PRINT(0)("Class:'%s' registered %d commands: \n", elemCL->className, elemCL->commandList->getSize());
    643     tIterator<ShellCommand>* iterator = elemCL->commandList->getIterator();
    644     const ShellCommand* elem = iterator->firstElement();
    645     while(elem != NULL)
    646     {
    647       PRINT(0)("  command:'%s' : params:%d: ", elem->getName(), elem->paramCount);
    648       for (unsigned int i = 0; i< elem->paramCount; i++)
    649        printf("%s ", ShellCommand::paramToString(elem->parameters[i]));
    650       if (elem->description != NULL)
    651        printf("- %s", elem->description);
    652       printf("\n");
    653 
    654       elem = iterator->nextElement();
    655     }
    656     delete iterator;
    657     elemCL = iteratorCL->nextElement();
    658   }
    659   delete iteratorCL;
    660 }
    661 
    662 /**
    663  * converts a Parameter to a String
    664  * @param parameter the Parameter we have.
    665  * @returns the Name of the Parameter at Hand
    666  */
    667 const char* ShellCommand::paramToString(long parameter)
    668 {
    669   return MultiType::MultiTypeToString((MT_Type)parameter);
    670 // FIXME
    671   /*  switch (parameter)
    672   {
    673     case ParameterBool:
    674       return "BOOL";
    675       break;
    676     case ParameterChar:
    677       return "CHAR";
    678       break;
    679     case ParameterString:
    680       return "STRING";
    681       break;
    682     case ParameterInt:
    683       return "INT";
    684       break;
    685     case ParameterUInt:
    686       return "UINT";
    687       break;
    688     case ParameterFloat:
    689       return "FLOAT";
    690       break;
    691     case ParameterLong:
    692       return "LONG";
    693       break;
    694     default:
    695       return "NULL";
    696       break;
    697   }*/
    698 }
Note: See TracChangeset for help on using the changeset viewer.