Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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


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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 };
Note: See TracChangeset for help on using the changeset viewer.